From c9775753b24060ce2ea8a227cf07227ecd60d2c8 Mon Sep 17 00:00:00 2001 From: souvikdas95 Date: Fri, 14 Jul 2017 21:28:08 +0530 Subject: [PATCH 1/7] Initial Commit --- .gitignore | 25 + LICENSE_BOOST.txt | 23 + LICENSE_Clp.txt | 3 + LICENSE_CoinUtils.txt | 239 + LICENSE_Ipopt.txt | 87 + LICENSE_MUMPS.txt | 44 + LICENSE_ORTOOLS.txt | 202 + LICENSE_Osi.txt | 239 + builder.sce | 55 + demos/Checkdims.dem.sce | 19 + demos/Checklhs.dem.sce | 48 + demos/Checkrhs.dem.sce | 72 + demos/Checktype.dem.sce | 33 + demos/Checkvector.dem.sce | 22 + demos/Filterdims.dem.sce | 19 + demos/Optimization_Toolbox.dem.gateway.sce | 13 + demos/fmaxflow.dem.sce | 76 + demos/fshortestpath.dem.sce | 64 + demos/jssp.dem.sce | 57 + demos/linsum.dem.sce | 19 + demos/min_cost_flow.dem.sce | 33 + demos/qcqpglob.dem.sce | 34 + demos/tsp.dem.sce | 94 + demos/vrp.dem.sce | 81 + etc/Optimization_Toolbox.quit | 52 + etc/Optimization_Toolbox.start | 82 + etc/README.rst | 14 + help/builder_help.sce | 5 + help/en_US/Checkdims.xml | 88 + help/en_US/Checklhs.xml | 112 + help/en_US/Checkrhs.xml | 135 + help/en_US/Checktype.xml | 100 + help/en_US/Checkvector.xml | 91 + help/en_US/Filterdims.xml | 88 + help/en_US/README.rst | 6 + help/en_US/build_help.sce | 5 + help/en_US/fmaxflow.xml | 183 + help/en_US/fshortestpath.xml | 180 + help/en_US/jssp.xml | 158 + help/en_US/linsum.xml | 86 + help/en_US/min_cost_flow.xml | 116 + help/en_US/qcqpglob.xml | 147 + help/en_US/tsp.xml | 221 + help/en_US/vrp.xml | 249 + macros/Checkdims.sci | 56 + macros/Checklhs.sci | 79 + macros/Checkrhs.sci | 102 + macros/Checktype.sci | 65 + macros/Checkvector.sci | 63 + macros/Filterdims.sci | 60 + macros/buildmacros.sce | 1 + macros/fmaxflow.sci | 270 + macros/fshortestpath.sci | 303 + macros/jssp.sci | 432 + macros/linsum.sci | 79 + macros/min_cost_flow.sci | 140 + macros/names | 14 + macros/qcqpglob.sci | 212 + macros/tsp.sci | 373 + macros/vrp.sci | 1183 ++ sci_gateway/builder_gateway.sce | 7 + sci_gateway/cpp/builder_gateway_cpp.sce | 145 + sci_gateway/cpp/misc.hpp | 20 + .../cpp/sci_BellmanFord_shortestPath.cpp | 424 + sci_gateway/cpp/sci_iofunc.cpp | 450 + sci_gateway/cpp/sci_iofunc.hpp | 24 + sci_gateway/cpp/sci_jssp.cpp | 754 + sci_gateway/cpp/sci_linear_sum_assignment.cpp | 103 + sci_gateway/cpp/sci_max_flow.cpp | 345 + sci_gateway/cpp/sci_min_cost_flow.cpp | 148 + sci_gateway/cpp/sci_qcqpglob.cpp | 514 + sci_gateway/cpp/sci_tsp.cpp | 367 + sci_gateway/cpp/sci_vrp.cpp | 1360 ++ .../fmaxflow/fmaxflow_capacities_dim.sce | 15 + .../fmaxflow/fmaxflow_capacities_integral.sce | 16 + .../fmaxflow/fmaxflow_endnodes_dim.sce | 17 + .../fmaxflow/fmaxflow_endnodes_integral.sce | 14 + .../fmaxflow/fmaxflow_equalvectorlength.sce | 17 + .../fmaxflow/fmaxflow_input1.sce | 13 + .../fmaxflow/fmaxflow_input2.sce | 13 + .../fmaxflow/fmaxflow_nopath.sce | 26 + .../fmaxflow/fmaxflow_output1.sce | 15 + .../fmaxflow/fmaxflow_output2.sce | 13 + .../fmaxflow/fmaxflow_sourceChk.sce | 14 + .../fmaxflow/fmaxflow_st_dim.sce | 16 + .../fmaxflow_startendnodes_integral.sce | 15 + .../fmaxflow/fmaxflow_startnodes_dim.sce | 15 + .../fmaxflow/fmaxflow_startnodes_integral.sce | 14 + .../fmaxflow/fmaxflow_targetChk.sce | 14 + .../fshortestpath_discondist_dim.sce | 18 + .../fshortestpath_discondist_integral.sce | 18 + .../fshortestpath_endnodes_dim.sce | 17 + .../fshortestpath_endnodes_integral.sce | 14 + .../fshortestpath_equalvectorlength.sce | 14 + .../fshortestpath/fshortestpath_input1.sce | 15 + .../fshortestpath/fshortestpath_input2.sce | 15 + .../fshortestpath/fshortestpath_nopath1.sce | 16 + .../fshortestpath/fshortestpath_nopath2.sce | 11 + .../fshortestpath/fshortestpath_nopath3.sce | 11 + .../fshortestpath/fshortestpath_output1.sce | 16 + .../fshortestpath/fshortestpath_output2.sce | 13 + .../fshortestpath/fshortestpath_sourceChk.sce | 16 + .../fshortestpath/fshortestpath_st_dim.sce | 17 + .../fshortestpath_startend_integral.sce | 16 + .../fshortestpath_startnodes_dim.sce | 15 + .../fshortestpath_startnodes_integral.sce | 15 + .../fshortestpath/fshortestpath_targetChk.sce | 14 + .../fshortestpath_weights_dim.sce | 18 + .../fshortestpath_weights_integral.sce | 15 + .../jssp/jssp_duration_valid.sce | 27 + .../jssp/jssp_endbefore_valid.sce | 28 + .../jssp/jssp_firsttask_mode1.sce | 25 + tests/general_tests/jssp/jssp_inputargs.sce | 26 + tests/general_tests/jssp/jssp_jmode_dims.sce | 26 + tests/general_tests/jssp/jssp_jmode_int.sce | 27 + tests/general_tests/jssp/jssp_jmode_type.sce | 28 + tests/general_tests/jssp/jssp_jmode_valid.sce | 27 + .../jssp/jssp_jobindices_valid.sce | 27 + tests/general_tests/jssp/jssp_jobs_dims.sce | 26 + tests/general_tests/jssp/jssp_jobs_int.sce | 27 + tests/general_tests/jssp/jssp_jobs_type.sce | 30 + .../jssp/jssp_lasttask_mode1.sce | 27 + .../jssp/jssp_machineindices_valid.sce | 28 + .../general_tests/jssp/jssp_machines_dims.sce | 27 + .../general_tests/jssp/jssp_machines_int.sce | 29 + .../general_tests/jssp/jssp_machines_type.sce | 28 + tests/general_tests/jssp/jssp_outputargs.sce | 24 + .../jssp/jssp_startafter_valid.sce | 27 + tests/general_tests/jssp/jssp_tasks_dims.sce | 26 + tests/general_tests/jssp/jssp_tasks_int.sce | 27 + tests/general_tests/jssp/jssp_tasks_type.sce | 28 + .../jssp/jssp_timelimit_dims.sce | 26 + .../general_tests/jssp/jssp_timelimit_int.sce | 28 + .../jssp/jssp_timelimit_type.sce | 30 + .../jssp/jssp_timelimit_valid.sce | 29 + tests/general_tests/linsum/linsum_t1.sce | 6 + tests/general_tests/linsum/linsum_t2.sce | 6 + tests/general_tests/linsum/linsum_t3.sce | 6 + tests/general_tests/linsum/linsum_t4.sce | 6 + tests/general_tests/linsum/linsum_t5.sce | 6 + tests/general_tests/linsum/linsum_t6.sce | 6 + tests/general_tests/linsum/linsum_t7.sce | 6 + tests/general_tests/linsum/linsum_t8.sce | 6 + tests/general_tests/linsum/linsum_t9.sce | 6 + .../min_cost_flow/min_cost_flow_t1.sce | 9 + .../min_cost_flow/min_cost_flow_t10.sce | 9 + .../min_cost_flow/min_cost_flow_t11.sce | 9 + .../min_cost_flow/min_cost_flow_t12.sce | 9 + .../min_cost_flow/min_cost_flow_t13.sce | 9 + .../min_cost_flow/min_cost_flow_t14.sce | 9 + .../min_cost_flow/min_cost_flow_t15.sce | 9 + .../min_cost_flow/min_cost_flow_t16.sce | 9 + .../min_cost_flow/min_cost_flow_t17.sce | 9 + .../min_cost_flow/min_cost_flow_t2.sce | 9 + .../min_cost_flow/min_cost_flow_t3.sce | 9 + .../min_cost_flow/min_cost_flow_t4.sce | 9 + .../min_cost_flow/min_cost_flow_t5.sce | 9 + .../min_cost_flow/min_cost_flow_t6.sce | 9 + .../min_cost_flow/min_cost_flow_t7.sce | 9 + .../min_cost_flow/min_cost_flow_t8.sce | 9 + .../min_cost_flow/min_cost_flow_t9.sce | 9 + tests/general_tests/tsp/tsp_adj_diag.sce | 20 + tests/general_tests/tsp/tsp_adj_dims.sce | 20 + tests/general_tests/tsp/tsp_adj_integral.sce | 22 + tests/general_tests/tsp/tsp_adj_type.sce | 20 + tests/general_tests/tsp/tsp_input1.sce | 17 + tests/general_tests/tsp/tsp_input2.sce | 19 + tests/general_tests/tsp/tsp_labels_dims1.sce | 22 + tests/general_tests/tsp/tsp_labels_dims2.sce | 21 + tests/general_tests/tsp/tsp_labels_dims3.sce | 21 + tests/general_tests/tsp/tsp_labels_type.sce | 20 + tests/general_tests/tsp/tsp_labels_unique.sce | 19 + tests/general_tests/tsp/tsp_output1.sce | 19 + tests/general_tests/tsp/tsp_output2.sce | 18 + .../tsp/tsp_startnode_integral.sce | 21 + .../general_tests/tsp/tsp_startnode_type.sce | 21 + .../general_tests/tsp/tsp_startnode_valid.sce | 20 + .../general_tests/tsp/tsp_startnodes_dims.sce | 19 + tests/general_tests/vrp/vrp_adj_dim.sce | 59 + tests/general_tests/vrp/vrp_adj_int.sce | 60 + tests/general_tests/vrp/vrp_adj_type.sce | 60 + .../vrp/vrp_adjdiagonal_zero.sce | 60 + .../vrp/vrp_demand_lt_vehiclecapacity.sce | 74 + tests/general_tests/vrp/vrp_demands_dim.sce | 56 + tests/general_tests/vrp/vrp_demands_int.sce | 61 + .../vrp/vrp_demands_nonnegative.sce | 72 + tests/general_tests/vrp/vrp_demands_type.sce | 61 + .../vrp/vrp_depotdemand_zero.sce | 72 + .../vrp/vrp_fuelcapacity_dim.sce | 61 + .../vrp/vrp_fuelcapacity_int.sce | 59 + .../vrp/vrp_fuelcapacity_positive.sce | 75 + .../vrp/vrp_fuelcapacity_specified.sce | 72 + .../vrp/vrp_fuelcapacity_type.sce | 60 + .../vrp/vrp_grouppenalty_dim.sci | 64 + .../vrp/vrp_grouppenalty_int.sce | 61 + ...vrp_grouppenalty_nonnegative_or_minus1.sce | 73 + .../vrp/vrp_grouppenalty_type.sce | 60 + tests/general_tests/vrp/vrp_groups_int.sce | 60 + .../general_tests/vrp/vrp_groups_norepeat.sce | 60 + tests/general_tests/vrp/vrp_groups_type.sce | 60 + .../vrp/vrp_groupsindices_valid.sce | 76 + tests/general_tests/vrp/vrp_labels_dim.sce | 58 + tests/general_tests/vrp/vrp_labels_type.sce | 62 + .../vrp/vrp_maxvehiclecapacity_dim.sce | 56 + .../vrp/vrp_maxvehiclecapacity_int.sce | 60 + .../vrp/vrp_maxvehiclecapacity_positive.sce | 73 + .../vrp/vrp_maxvehiclecapacity_type.sce | 61 + tests/general_tests/vrp/vrp_penalty_dim.sce | 60 + tests/general_tests/vrp/vrp_penalty_int.sce | 62 + .../general_tests/vrp/vrp_penalty_nodepot.sce | 59 + .../vrp/vrp_penalty_nonnegative.sce | 60 + tests/general_tests/vrp/vrp_penalty_type.sce | 59 + .../vrp/vrp_penaltyindices_valid.sce | 74 + .../general_tests/vrp/vrp_refuelflag_dim.sce | 61 + .../general_tests/vrp/vrp_refuelflag_int.sce | 59 + .../general_tests/vrp/vrp_refuelflag_type.sce | 61 + .../vrp/vrp_refuelflag_valid.sce | 60 + .../general_tests/vrp/vrp_refuelnodes_dim.sce | 63 + .../general_tests/vrp/vrp_refuelnodes_int.sce | 58 + .../vrp/vrp_refuelnodes_type.sce | 60 + .../vrp/vrp_refuelnodes_valid.sce | 60 + .../general_tests/vrp/vrp_servicetime_dim.sce | 58 + .../vrp/vrp_servicetime_gtzero.sce | 74 + .../general_tests/vrp/vrp_servicetime_int.sce | 62 + .../vrp/vrp_servicetime_type.sce | 61 + tests/general_tests/vrp/vrp_speeds_dim.sce | 97 + tests/general_tests/vrp/vrp_speeds_int.sce | 61 + .../general_tests/vrp/vrp_speeds_positive.sce | 73 + tests/general_tests/vrp/vrp_speeds_type.sce | 62 + tests/general_tests/vrp/vrp_start_dim.sce | 58 + tests/general_tests/vrp/vrp_start_int.sce | 59 + tests/general_tests/vrp/vrp_start_type.sce | 62 + .../general_tests/vrp/vrp_startnode_valid.sce | 73 + tests/general_tests/vrp/vrp_timelimit_dim.sce | 71 + tests/general_tests/vrp/vrp_timelimit_int.sce | 61 + .../vrp/vrp_timelimit_positive.sce | 74 + .../general_tests/vrp/vrp_timelimit_type.sce | 60 + .../general_tests/vrp/vrp_timewindows_dim.sce | 65 + .../vrp/vrp_timewindows_ends_gt_starts.sce | 69 + .../general_tests/vrp/vrp_timewindows_int.sce | 72 + .../vrp_timewindows_nonnegative_or_minus1.sce | 73 + .../vrp/vrp_timewindows_type.sce | 72 + .../vrp/vrp_totaldemands_lt_totalcapacity.sce | 75 + tests/general_tests/vrp/vrp_uniquelabels.sce | 59 + .../vrp_vehiclecapacity_if_capacitated.sce | 75 + tests/general_tests/vrp/vrp_vehicles_dim.sce | 58 + tests/general_tests/vrp/vrp_vehicles_int.sce | 60 + .../vrp/vrp_vehicles_positive.sce | 74 + tests/general_tests/vrp/vrp_vehicles_type.sce | 61 + .../vrp/vrp_waitingtimes_dim.sce | 64 + .../vrp/vrp_waitingtimes_int.sce | 60 + .../vrp/vrp_waitingtimes_nonnegative.sce | 59 + .../vrp/vrp_waitingtimes_type.sce | 59 + tests/unit_tests/fmaxflow.dia.ref | 78 + tests/unit_tests/fmaxflow.tst | 73 + tests/unit_tests/fshortestpath.dia.ref | 69 + tests/unit_tests/fshortestpath.tst | 68 + tests/unit_tests/jssp.dia.ref | 78 + tests/unit_tests/jssp.tst | 81 + tests/unit_tests/linsum.dia.ref | 65 + tests/unit_tests/linsum.tst | 69 + tests/unit_tests/min_cost_flow.dia.ref | 78 + tests/unit_tests/min_cost_flow.tst | 85 + tests/unit_tests/tsp.dia.ref | 70 + tests/unit_tests/tsp.tst | 78 + tests/unit_tests/vrp.dia.ref | 78 + tests/unit_tests/vrp.tst | 90 + thirdparty/.gitignore | 1 + thirdparty/linux/include/boost/assert.hpp | 85 + .../linux/include/boost/checked_delete.hpp | 17 + thirdparty/linux/include/boost/config.hpp | 67 + .../boost/config/abi/borland_prefix.hpp | 27 + .../boost/config/abi/borland_suffix.hpp | 12 + .../include/boost/config/abi/msvc_prefix.hpp | 22 + .../include/boost/config/abi/msvc_suffix.hpp | 8 + .../linux/include/boost/config/abi_prefix.hpp | 25 + .../linux/include/boost/config/abi_suffix.hpp | 27 + .../linux/include/boost/config/auto_link.hpp | 439 + .../include/boost/config/compiler/borland.hpp | 319 + .../include/boost/config/compiler/clang.hpp | 304 + .../boost/config/compiler/codegear.hpp | 221 + .../include/boost/config/compiler/comeau.hpp | 59 + .../boost/config/compiler/common_edg.hpp | 144 + .../boost/config/compiler/compaq_cxx.hpp | 19 + .../include/boost/config/compiler/cray.hpp | 93 + .../boost/config/compiler/digitalmars.hpp | 125 + .../include/boost/config/compiler/gcc.hpp | 328 + .../include/boost/config/compiler/gcc_xml.hpp | 96 + .../boost/config/compiler/greenhills.hpp | 28 + .../include/boost/config/compiler/hp_acc.hpp | 146 + .../include/boost/config/compiler/intel.hpp | 552 + .../include/boost/config/compiler/kai.hpp | 33 + .../boost/config/compiler/metrowerks.hpp | 180 + .../include/boost/config/compiler/mpw.hpp | 122 + .../include/boost/config/compiler/nvcc.hpp | 32 + .../boost/config/compiler/pathscale.hpp | 115 + .../include/boost/config/compiler/pgi.hpp | 156 + .../boost/config/compiler/sgi_mipspro.hpp | 29 + .../boost/config/compiler/sunpro_cc.hpp | 198 + .../include/boost/config/compiler/vacpp.hpp | 163 + .../include/boost/config/compiler/visualc.hpp | 303 + .../include/boost/config/compiler/xlcpp.hpp | 262 + .../include/boost/config/no_tr1/cmath.hpp | 28 + .../include/boost/config/no_tr1/complex.hpp | 28 + .../boost/config/no_tr1/functional.hpp | 28 + .../include/boost/config/no_tr1/memory.hpp | 28 + .../include/boost/config/no_tr1/utility.hpp | 28 + .../include/boost/config/platform/aix.hpp | 33 + .../include/boost/config/platform/amigaos.hpp | 15 + .../include/boost/config/platform/beos.hpp | 26 + .../include/boost/config/platform/bsd.hpp | 86 + .../boost/config/platform/cloudabi.hpp | 18 + .../include/boost/config/platform/cray.hpp | 18 + .../include/boost/config/platform/cygwin.hpp | 58 + .../include/boost/config/platform/haiku.hpp | 31 + .../include/boost/config/platform/hpux.hpp | 87 + .../include/boost/config/platform/irix.hpp | 31 + .../include/boost/config/platform/linux.hpp | 105 + .../include/boost/config/platform/macos.hpp | 87 + .../include/boost/config/platform/qnxnto.hpp | 31 + .../include/boost/config/platform/solaris.hpp | 31 + .../include/boost/config/platform/symbian.hpp | 97 + .../include/boost/config/platform/vms.hpp | 25 + .../include/boost/config/platform/vxworks.hpp | 369 + .../include/boost/config/platform/win32.hpp | 90 + .../include/boost/config/posix_features.hpp | 95 + .../include/boost/config/requires_threads.hpp | 92 + .../boost/config/select_compiler_config.hpp | 148 + .../boost/config/select_platform_config.hpp | 137 + .../boost/config/select_stdlib_config.hpp | 105 + .../boost/config/stdlib/dinkumware.hpp | 209 + .../include/boost/config/stdlib/libcomo.hpp | 90 + .../include/boost/config/stdlib/libcpp.hpp | 113 + .../boost/config/stdlib/libstdcpp3.hpp | 314 + .../include/boost/config/stdlib/modena.hpp | 76 + .../linux/include/boost/config/stdlib/msl.hpp | 95 + .../include/boost/config/stdlib/roguewave.hpp | 205 + .../linux/include/boost/config/stdlib/sgi.hpp | 165 + .../include/boost/config/stdlib/stlport.hpp | 255 + .../include/boost/config/stdlib/vacpp.hpp | 71 + .../linux/include/boost/config/suffix.hpp | 1017 ++ .../linux/include/boost/config/user.hpp | 133 + .../include/boost/config/warning_disable.hpp | 47 + .../linux/include/boost/core/addressof.hpp | 162 + .../include/boost/core/checked_delete.hpp | 69 + .../linux/include/boost/core/demangle.hpp | 131 + .../linux/include/boost/core/typeinfo.hpp | 151 + thirdparty/linux/include/boost/cstdint.hpp | 546 + .../linux/include/boost/current_function.hpp | 75 + .../boost/detail/lightweight_mutex.hpp | 22 + .../include/boost/detail/sp_typeinfo.hpp | 36 + .../linux/include/boost/detail/workaround.hpp | 267 + .../include/boost/exception/exception.hpp | 521 + thirdparty/linux/include/boost/limits.hpp | 146 + thirdparty/linux/include/boost/predef.h | 24 + .../linux/include/boost/predef/architecture.h | 32 + .../include/boost/predef/architecture/alpha.h | 59 + .../include/boost/predef/architecture/arm.h | 70 + .../boost/predef/architecture/blackfin.h | 46 + .../boost/predef/architecture/convex.h | 65 + .../include/boost/predef/architecture/ia64.h | 49 + .../include/boost/predef/architecture/m68k.h | 82 + .../include/boost/predef/architecture/mips.h | 73 + .../boost/predef/architecture/parisc.h | 64 + .../include/boost/predef/architecture/ppc.h | 72 + .../boost/predef/architecture/pyramid.h | 42 + .../include/boost/predef/architecture/rs6k.h | 56 + .../include/boost/predef/architecture/sparc.h | 54 + .../boost/predef/architecture/superh.h | 67 + .../boost/predef/architecture/sys370.h | 43 + .../boost/predef/architecture/sys390.h | 43 + .../include/boost/predef/architecture/x86.h | 38 + .../boost/predef/architecture/x86/32.h | 87 + .../boost/predef/architecture/x86/64.h | 50 + .../include/boost/predef/architecture/z.h | 42 + .../linux/include/boost/predef/compiler.h | 43 + .../include/boost/predef/compiler/borland.h | 63 + .../include/boost/predef/compiler/clang.h | 56 + .../include/boost/predef/compiler/comeau.h | 61 + .../include/boost/predef/compiler/compaq.h | 66 + .../include/boost/predef/compiler/diab.h | 56 + .../boost/predef/compiler/digitalmars.h | 56 + .../include/boost/predef/compiler/dignus.h | 56 + .../linux/include/boost/predef/compiler/edg.h | 56 + .../include/boost/predef/compiler/ekopath.h | 57 + .../linux/include/boost/predef/compiler/gcc.h | 68 + .../include/boost/predef/compiler/gcc_xml.h | 53 + .../boost/predef/compiler/greenhills.h | 66 + .../include/boost/predef/compiler/hp_acc.h | 61 + .../linux/include/boost/predef/compiler/iar.h | 56 + .../linux/include/boost/predef/compiler/ibm.h | 72 + .../include/boost/predef/compiler/intel.h | 65 + .../linux/include/boost/predef/compiler/kai.h | 56 + .../include/boost/predef/compiler/llvm.h | 57 + .../include/boost/predef/compiler/metaware.h | 53 + .../boost/predef/compiler/metrowerks.h | 77 + .../include/boost/predef/compiler/microtec.h | 53 + .../linux/include/boost/predef/compiler/mpw.h | 63 + .../include/boost/predef/compiler/palm.h | 56 + .../linux/include/boost/predef/compiler/pgi.h | 60 + .../boost/predef/compiler/sgi_mipspro.h | 66 + .../include/boost/predef/compiler/sunpro.h | 76 + .../include/boost/predef/compiler/tendra.h | 53 + .../include/boost/predef/compiler/visualc.h | 91 + .../include/boost/predef/compiler/watcom.h | 56 + .../include/boost/predef/detail/_cassert.h | 17 + .../include/boost/predef/detail/_exception.h | 15 + .../boost/predef/detail/comp_detected.h | 10 + .../include/boost/predef/detail/os_detected.h | 10 + .../boost/predef/detail/platform_detected.h | 10 + .../linux/include/boost/predef/detail/test.h | 17 + .../linux/include/boost/predef/hardware.h | 16 + .../include/boost/predef/hardware/simd.h | 119 + .../include/boost/predef/hardware/simd/arm.h | 57 + .../boost/predef/hardware/simd/arm/versions.h | 32 + .../include/boost/predef/hardware/simd/ppc.h | 69 + .../boost/predef/hardware/simd/ppc/versions.h | 51 + .../include/boost/predef/hardware/simd/x86.h | 123 + .../boost/predef/hardware/simd/x86/versions.h | 129 + .../boost/predef/hardware/simd/x86_amd.h | 87 + .../predef/hardware/simd/x86_amd/versions.h | 51 + .../linux/include/boost/predef/language.h | 17 + .../include/boost/predef/language/objc.h | 42 + .../include/boost/predef/language/stdc.h | 53 + .../include/boost/predef/language/stdcpp.h | 121 + .../linux/include/boost/predef/library.h | 16 + .../linux/include/boost/predef/library/c.h | 20 + .../include/boost/predef/library/c/_prefix.h | 13 + .../include/boost/predef/library/c/gnu.h | 61 + .../linux/include/boost/predef/library/c/uc.h | 47 + .../include/boost/predef/library/c/vms.h | 47 + .../include/boost/predef/library/c/zos.h | 56 + .../linux/include/boost/predef/library/std.h | 25 + .../boost/predef/library/std/_prefix.h | 23 + .../include/boost/predef/library/std/cxx.h | 46 + .../boost/predef/library/std/dinkumware.h | 52 + .../boost/predef/library/std/libcomo.h | 47 + .../include/boost/predef/library/std/modena.h | 45 + .../include/boost/predef/library/std/msl.h | 53 + .../boost/predef/library/std/roguewave.h | 56 + .../include/boost/predef/library/std/sgi.h | 51 + .../boost/predef/library/std/stdcpp3.h | 53 + .../boost/predef/library/std/stlport.h | 59 + .../include/boost/predef/library/std/vacpp.h | 44 + thirdparty/linux/include/boost/predef/make.h | 89 + thirdparty/linux/include/boost/predef/os.h | 33 + .../linux/include/boost/predef/os/aix.h | 66 + .../linux/include/boost/predef/os/amigaos.h | 46 + .../linux/include/boost/predef/os/android.h | 45 + .../linux/include/boost/predef/os/beos.h | 45 + .../linux/include/boost/predef/os/bsd.h | 103 + .../linux/include/boost/predef/os/bsd/bsdi.h | 48 + .../include/boost/predef/os/bsd/dragonfly.h | 50 + .../linux/include/boost/predef/os/bsd/free.h | 60 + .../linux/include/boost/predef/os/bsd/net.h | 84 + .../linux/include/boost/predef/os/bsd/open.h | 171 + .../linux/include/boost/predef/os/cygwin.h | 45 + .../linux/include/boost/predef/os/haiku.h | 46 + .../linux/include/boost/predef/os/hpux.h | 47 + .../linux/include/boost/predef/os/ios.h | 51 + .../linux/include/boost/predef/os/irix.h | 46 + .../linux/include/boost/predef/os/linux.h | 46 + .../linux/include/boost/predef/os/macos.h | 65 + .../linux/include/boost/predef/os/os400.h | 45 + .../linux/include/boost/predef/os/qnxnto.h | 59 + .../linux/include/boost/predef/os/solaris.h | 46 + .../linux/include/boost/predef/os/unix.h | 76 + .../linux/include/boost/predef/os/vms.h | 52 + .../linux/include/boost/predef/os/windows.h | 51 + thirdparty/linux/include/boost/predef/other.h | 16 + .../linux/include/boost/predef/other/endian.h | 204 + .../linux/include/boost/predef/platform.h | 21 + .../include/boost/predef/platform/mingw.h | 69 + .../boost/predef/platform/windows_desktop.h | 45 + .../boost/predef/platform/windows_phone.h | 43 + .../boost/predef/platform/windows_runtime.h | 45 + .../boost/predef/platform/windows_store.h | 43 + .../linux/include/boost/predef/version.h | 15 + .../include/boost/predef/version_number.h | 53 + thirdparty/linux/include/boost/shared_ptr.hpp | 19 + .../include/boost/smart_ptr/bad_weak_ptr.hpp | 68 + .../smart_ptr/detail/lightweight_mutex.hpp | 42 + .../boost/smart_ptr/detail/lwm_nop.hpp | 37 + .../boost/smart_ptr/detail/lwm_pthreads.hpp | 87 + .../boost/smart_ptr/detail/lwm_win32_cs.hpp | 119 + .../boost/smart_ptr/detail/operator_bool.hpp | 64 + .../smart_ptr/detail/quick_allocator.hpp | 199 + .../boost/smart_ptr/detail/shared_count.hpp | 709 + .../boost/smart_ptr/detail/sp_convertible.hpp | 92 + .../smart_ptr/detail/sp_counted_base.hpp | 96 + .../detail/sp_counted_base_acc_ia64.hpp | 151 + .../smart_ptr/detail/sp_counted_base_aix.hpp | 143 + .../detail/sp_counted_base_clang.hpp | 149 + .../detail/sp_counted_base_cw_ppc.hpp | 171 + .../detail/sp_counted_base_gcc_ia64.hpp | 158 + .../detail/sp_counted_base_gcc_mips.hpp | 182 + .../detail/sp_counted_base_gcc_ppc.hpp | 182 + .../detail/sp_counted_base_gcc_sparc.hpp | 167 + .../detail/sp_counted_base_gcc_x86.hpp | 174 + .../smart_ptr/detail/sp_counted_base_nt.hpp | 108 + .../smart_ptr/detail/sp_counted_base_pt.hpp | 137 + .../detail/sp_counted_base_snc_ps3.hpp | 162 + .../smart_ptr/detail/sp_counted_base_spin.hpp | 132 + .../detail/sp_counted_base_std_atomic.hpp | 137 + .../smart_ptr/detail/sp_counted_base_sync.hpp | 156 + .../detail/sp_counted_base_vacpp_ppc.hpp | 151 + .../smart_ptr/detail/sp_counted_base_w32.hpp | 131 + .../smart_ptr/detail/sp_counted_impl.hpp | 271 + .../detail/sp_disable_deprecated.hpp | 40 + .../boost/smart_ptr/detail/sp_has_sync.hpp | 69 + .../boost/smart_ptr/detail/sp_interlocked.hpp | 163 + .../boost/smart_ptr/detail/sp_nullptr_t.hpp | 45 + .../boost/smart_ptr/detail/spinlock.hpp | 68 + .../smart_ptr/detail/spinlock_gcc_arm.hpp | 121 + .../boost/smart_ptr/detail/spinlock_nt.hpp | 89 + .../boost/smart_ptr/detail/spinlock_pool.hpp | 91 + .../boost/smart_ptr/detail/spinlock_pt.hpp | 79 + .../smart_ptr/detail/spinlock_std_atomic.hpp | 83 + .../boost/smart_ptr/detail/spinlock_sync.hpp | 87 + .../boost/smart_ptr/detail/spinlock_w32.hpp | 113 + .../boost/smart_ptr/detail/yield_k.hpp | 177 + .../include/boost/smart_ptr/shared_ptr.hpp | 1094 ++ .../linux/include/boost/static_assert.hpp | 180 + .../linux/include/boost/throw_exception.hpp | 102 + .../type_traits/add_lvalue_reference.hpp | 27 + .../boost/type_traits/add_reference.hpp | 59 + .../type_traits/add_rvalue_reference.hpp | 64 + .../boost/type_traits/alignment_of.hpp | 119 + .../include/boost/type_traits/conditional.hpp | 20 + .../include/boost/type_traits/declval.hpp | 44 + .../boost/type_traits/detail/config.hpp | 72 + .../detail/is_function_ptr_helper.hpp | 176 + .../detail/is_function_ptr_tester.hpp | 449 + .../detail/is_mem_fun_pointer_impl.hpp | 723 + .../detail/is_mem_fun_pointer_tester.hpp | 1800 ++ .../boost/type_traits/detail/yes_no_type.hpp | 26 + .../boost/type_traits/integral_constant.hpp | 106 + .../include/boost/type_traits/intrinsics.hpp | 380 + .../include/boost/type_traits/is_abstract.hpp | 150 + .../boost/type_traits/is_arithmetic.hpp | 22 + .../include/boost/type_traits/is_array.hpp | 43 + .../include/boost/type_traits/is_class.hpp | 114 + .../boost/type_traits/is_convertible.hpp | 488 + .../include/boost/type_traits/is_enum.hpp | 166 + .../boost/type_traits/is_floating_point.hpp | 30 + .../include/boost/type_traits/is_function.hpp | 102 + .../include/boost/type_traits/is_integral.hpp | 89 + .../boost/type_traits/is_lvalue_reference.hpp | 50 + .../is_member_function_pointer.hpp | 120 + .../boost/type_traits/is_member_pointer.hpp | 45 + .../include/boost/type_traits/is_pod.hpp | 59 + .../include/boost/type_traits/is_pointer.hpp | 47 + .../boost/type_traits/is_polymorphic.hpp | 122 + .../boost/type_traits/is_reference.hpp | 30 + .../boost/type_traits/is_rvalue_reference.hpp | 25 + .../include/boost/type_traits/is_same.hpp | 41 + .../include/boost/type_traits/is_scalar.hpp | 27 + .../include/boost/type_traits/is_union.hpp | 31 + .../include/boost/type_traits/is_void.hpp | 26 + .../include/boost/type_traits/is_volatile.hpp | 46 + .../include/boost/type_traits/remove_cv.hpp | 40 + .../boost/type_traits/remove_reference.hpp | 54 + .../boost/type_traits/type_with_alignment.hpp | 261 + thirdparty/linux/include/boost/version.hpp | 32 + .../linux/include/coin/CbcOrClpParam.cpp | 4134 +++++ .../linux/include/coin/CbcOrClpParam.hpp | 532 + .../linux/include/coin/ClpCholeskyBase.hpp | 294 + .../linux/include/coin/ClpCholeskyDense.hpp | 162 + thirdparty/linux/include/coin/ClpConfig.h | 17 + .../linux/include/coin/ClpConstraint.hpp | 125 + .../include/coin/ClpConstraintLinear.hpp | 110 + .../include/coin/ClpConstraintQuadratic.hpp | 119 + .../linux/include/coin/ClpDualRowDantzig.hpp | 71 + .../linux/include/coin/ClpDualRowPivot.hpp | 129 + .../linux/include/coin/ClpDualRowSteepest.hpp | 153 + .../linux/include/coin/ClpDummyMatrix.hpp | 183 + .../include/coin/ClpDynamicExampleMatrix.hpp | 186 + .../linux/include/coin/ClpDynamicMatrix.hpp | 381 + .../linux/include/coin/ClpEventHandler.hpp | 187 + .../linux/include/coin/ClpFactorization.hpp | 432 + .../include/coin/ClpGubDynamicMatrix.hpp | 247 + .../linux/include/coin/ClpGubMatrix.hpp | 358 + thirdparty/linux/include/coin/ClpInterior.hpp | 570 + .../linux/include/coin/ClpLinearObjective.hpp | 103 + .../linux/include/coin/ClpMatrixBase.hpp | 524 + thirdparty/linux/include/coin/ClpMessage.hpp | 131 + thirdparty/linux/include/coin/ClpModel.hpp | 1307 ++ .../linux/include/coin/ClpNetworkMatrix.hpp | 229 + thirdparty/linux/include/coin/ClpNode.hpp | 349 + .../linux/include/coin/ClpNonLinearCost.hpp | 401 + .../linux/include/coin/ClpObjective.hpp | 134 + .../linux/include/coin/ClpPackedMatrix.hpp | 638 + .../linux/include/coin/ClpParameters.hpp | 126 + thirdparty/linux/include/coin/ClpPdcoBase.hpp | 103 + .../include/coin/ClpPlusMinusOneMatrix.hpp | 290 + thirdparty/linux/include/coin/ClpPresolve.hpp | 299 + .../include/coin/ClpPrimalColumnDantzig.hpp | 72 + .../include/coin/ClpPrimalColumnPivot.hpp | 155 + .../include/coin/ClpPrimalColumnSteepest.hpp | 247 + .../include/coin/ClpQuadraticObjective.hpp | 155 + thirdparty/linux/include/coin/ClpSimplex.hpp | 1797 ++ .../linux/include/coin/ClpSimplexDual.hpp | 300 + .../include/coin/ClpSimplexNonlinear.hpp | 117 + .../linux/include/coin/ClpSimplexOther.hpp | 277 + .../linux/include/coin/ClpSimplexPrimal.hpp | 244 + thirdparty/linux/include/coin/ClpSolve.hpp | 446 + .../linux/include/coin/Clp_C_Interface.h | 525 + thirdparty/linux/include/coin/CoinAlloc.hpp | 176 + thirdparty/linux/include/coin/CoinBuild.hpp | 149 + .../include/coin/CoinDenseFactorization.hpp | 419 + .../linux/include/coin/CoinDenseVector.hpp | 383 + .../linux/include/coin/CoinDistance.hpp | 48 + thirdparty/linux/include/coin/CoinError.hpp | 257 + .../linux/include/coin/CoinFactorization.hpp | 2044 +++ thirdparty/linux/include/coin/CoinFileIO.hpp | 166 + thirdparty/linux/include/coin/CoinFinite.hpp | 34 + .../linux/include/coin/CoinFloatEqual.hpp | 177 + .../include/coin/CoinHelperFunctions.hpp | 1111 ++ .../linux/include/coin/CoinIndexedVector.hpp | 1164 ++ thirdparty/linux/include/coin/CoinLpIO.hpp | 805 + thirdparty/linux/include/coin/CoinMessage.hpp | 96 + .../linux/include/coin/CoinMessageHandler.hpp | 666 + thirdparty/linux/include/coin/CoinModel.hpp | 1054 ++ .../linux/include/coin/CoinModelUseful.hpp | 441 + thirdparty/linux/include/coin/CoinMpsIO.hpp | 1056 ++ .../include/coin/CoinOslFactorization.hpp | 280 + .../linux/include/coin/CoinPackedMatrix.hpp | 947 + .../linux/include/coin/CoinPackedVector.hpp | 657 + .../include/coin/CoinPackedVectorBase.hpp | 269 + thirdparty/linux/include/coin/CoinParam.hpp | 644 + thirdparty/linux/include/coin/CoinPragma.hpp | 26 + .../include/coin/CoinPresolveDoubleton.hpp | 73 + .../linux/include/coin/CoinPresolveDual.hpp | 85 + .../linux/include/coin/CoinPresolveDupcol.hpp | 226 + .../linux/include/coin/CoinPresolveEmpty.hpp | 116 + .../linux/include/coin/CoinPresolveFixed.hpp | 181 + .../include/coin/CoinPresolveForcing.hpp | 61 + .../include/coin/CoinPresolveImpliedFree.hpp | 60 + .../include/coin/CoinPresolveIsolated.hpp | 51 + .../linux/include/coin/CoinPresolveMatrix.hpp | 1842 ++ .../include/coin/CoinPresolveMonitor.hpp | 105 + .../include/coin/CoinPresolvePsdebug.hpp | 166 + .../include/coin/CoinPresolveSingleton.hpp | 112 + .../linux/include/coin/CoinPresolveSubst.hpp | 101 + .../include/coin/CoinPresolveTighten.hpp | 55 + .../include/coin/CoinPresolveTripleton.hpp | 66 + .../include/coin/CoinPresolveUseless.hpp | 63 + .../linux/include/coin/CoinPresolveZeros.hpp | 60 + .../linux/include/coin/CoinRational.hpp | 44 + .../linux/include/coin/CoinSearchTree.hpp | 465 + .../include/coin/CoinShallowPackedVector.hpp | 148 + thirdparty/linux/include/coin/CoinSignal.hpp | 117 + .../include/coin/CoinSimpFactorization.hpp | 431 + .../linux/include/coin/CoinSmartPtr.hpp | 528 + .../linux/include/coin/CoinSnapshot.hpp | 476 + thirdparty/linux/include/coin/CoinSort.hpp | 678 + .../include/coin/CoinStructuredModel.hpp | 247 + thirdparty/linux/include/coin/CoinTime.hpp | 310 + thirdparty/linux/include/coin/CoinTypes.hpp | 64 + thirdparty/linux/include/coin/CoinUtility.hpp | 19 + .../linux/include/coin/CoinUtilsConfig.h | 34 + .../linux/include/coin/CoinWarmStart.hpp | 58 + .../linux/include/coin/CoinWarmStartBasis.hpp | 456 + .../linux/include/coin/CoinWarmStartDual.hpp | 166 + .../include/coin/CoinWarmStartPrimalDual.hpp | 211 + .../include/coin/CoinWarmStartVector.hpp | 488 + .../linux/include/coin/Coin_C_defines.h | 115 + thirdparty/linux/include/coin/HSLLoader.h | 378 + thirdparty/linux/include/coin/Idiot.hpp | 298 + .../linux/include/coin/IpAlgBuilder.hpp | 360 + .../linux/include/coin/IpAlgStrategy.hpp | 185 + thirdparty/linux/include/coin/IpAlgTypes.hpp | 66 + .../linux/include/coin/IpAugSystemSolver.hpp | 200 + thirdparty/linux/include/coin/IpBlas.hpp | 78 + .../linux/include/coin/IpCachedResults.hpp | 779 + .../linux/include/coin/IpCompoundMatrix.hpp | 340 + .../include/coin/IpCompoundSymMatrix.hpp | 283 + .../linux/include/coin/IpCompoundVector.hpp | 339 + thirdparty/linux/include/coin/IpConvCheck.hpp | 87 + thirdparty/linux/include/coin/IpDebug.hpp | 150 + .../linux/include/coin/IpDenseVector.hpp | 550 + .../linux/include/coin/IpDiagMatrix.hpp | 141 + .../linux/include/coin/IpEqMultCalculator.hpp | 64 + thirdparty/linux/include/coin/IpException.hpp | 147 + .../linux/include/coin/IpExpansionMatrix.hpp | 212 + .../linux/include/coin/IpGenTMatrix.hpp | 264 + .../linux/include/coin/IpHessianUpdater.hpp | 65 + .../linux/include/coin/IpIdentityMatrix.hpp | 149 + thirdparty/linux/include/coin/IpIpoptAlg.hpp | 224 + .../linux/include/coin/IpIpoptApplication.hpp | 296 + .../coin/IpIpoptCalculatedQuantities.hpp | 751 + thirdparty/linux/include/coin/IpIpoptData.hpp | 819 + thirdparty/linux/include/coin/IpIpoptNLP.hpp | 261 + .../include/coin/IpIterateInitializer.hpp | 64 + .../linux/include/coin/IpIteratesVector.hpp | 689 + .../linux/include/coin/IpIterationOutput.hpp | 71 + .../linux/include/coin/IpJournalist.hpp | 497 + thirdparty/linux/include/coin/IpLapack.hpp | 55 + .../linux/include/coin/IpLineSearch.hpp | 96 + thirdparty/linux/include/coin/IpMatrix.hpp | 345 + thirdparty/linux/include/coin/IpMuUpdate.hpp | 69 + thirdparty/linux/include/coin/IpNLP.hpp | 243 + .../linux/include/coin/IpNLPScaling.hpp | 451 + thirdparty/linux/include/coin/IpObserver.hpp | 366 + .../linux/include/coin/IpOptionsList.hpp | 289 + .../linux/include/coin/IpOrigIpoptNLP.hpp | 488 + .../linux/include/coin/IpPDSystemSolver.hpp | 130 + .../linux/include/coin/IpReferenced.hpp | 258 + .../linux/include/coin/IpRegOptions.hpp | 658 + thirdparty/linux/include/coin/IpReturnCodes.h | 18 + .../linux/include/coin/IpReturnCodes.hpp | 21 + .../linux/include/coin/IpReturnCodes.inc | 70 + .../linux/include/coin/IpReturnCodes_inc.h | 46 + .../linux/include/coin/IpScaledMatrix.hpp | 254 + .../include/coin/IpSearchDirCalculator.hpp | 65 + thirdparty/linux/include/coin/IpSmartPtr.hpp | 734 + .../linux/include/coin/IpSolveStatistics.hpp | 150 + .../linux/include/coin/IpStdCInterface.h | 271 + .../linux/include/coin/IpSumSymMatrix.hpp | 152 + .../linux/include/coin/IpSymLinearSolver.hpp | 130 + thirdparty/linux/include/coin/IpSymMatrix.hpp | 162 + .../linux/include/coin/IpSymScaledMatrix.hpp | 230 + .../linux/include/coin/IpSymTMatrix.hpp | 253 + thirdparty/linux/include/coin/IpTNLP.hpp | 301 + .../linux/include/coin/IpTNLPAdapter.hpp | 427 + .../linux/include/coin/IpTNLPReducer.hpp | 180 + .../linux/include/coin/IpTaggedObject.hpp | 162 + thirdparty/linux/include/coin/IpTimedTask.hpp | 146 + .../linux/include/coin/IpTimingStatistics.hpp | 213 + .../linux/include/coin/IpTripletHelper.hpp | 135 + thirdparty/linux/include/coin/IpTypes.hpp | 28 + thirdparty/linux/include/coin/IpUtils.hpp | 128 + thirdparty/linux/include/coin/IpVector.hpp | 774 + .../linux/include/coin/IpZeroSymMatrix.hpp | 135 + thirdparty/linux/include/coin/IpoptConfig.h | 22 + thirdparty/linux/include/coin/OsiAuxInfo.hpp | 206 + .../linux/include/coin/OsiBranchingObject.hpp | 1005 ++ .../linux/include/coin/OsiChooseVariable.hpp | 534 + .../include/coin/OsiClpSolverInterface.hpp | 1509 ++ thirdparty/linux/include/coin/OsiColCut.hpp | 324 + .../linux/include/coin/OsiCollections.hpp | 35 + thirdparty/linux/include/coin/OsiConfig.h | 19 + thirdparty/linux/include/coin/OsiCut.hpp | 245 + thirdparty/linux/include/coin/OsiCuts.hpp | 474 + thirdparty/linux/include/coin/OsiPresolve.hpp | 252 + thirdparty/linux/include/coin/OsiRowCut.hpp | 331 + .../linux/include/coin/OsiRowCutDebugger.hpp | 187 + .../linux/include/coin/OsiSolverBranch.hpp | 152 + .../linux/include/coin/OsiSolverInterface.hpp | 2143 +++ .../include/coin/OsiSolverParameters.hpp | 142 + .../linux/include/coin/OsiUnitTests.hpp | 374 + thirdparty/linux/include/coin/PardisoLoader.h | 41 + .../linux/include/coin/ThirdParty/dmumps_c.h | 159 + .../include/coin/ThirdParty/mumps_c_types.h | 92 + .../include/coin/ThirdParty/mumps_compat.h | 78 + .../linux/include/coin/ThirdParty/mumps_mpi.h | 77 + thirdparty/linux/include/gflags/gflags.h | 606 + .../linux/include/gflags/gflags_completions.h | 121 + .../linux/include/gflags/gflags_declare.h | 153 + .../linux/include/gflags/gflags_gflags.h | 102 + .../linux/include/google/protobuf/any.h | 107 + .../linux/include/google/protobuf/any.pb.h | 258 + .../linux/include/google/protobuf/any.proto | 140 + .../linux/include/google/protobuf/api.pb.h | 996 ++ .../linux/include/google/protobuf/api.proto | 202 + .../linux/include/google/protobuf/arena.h | 925 + .../include/google/protobuf/arenastring.h | 314 + .../google/protobuf/compiler/code_generator.h | 176 + .../compiler/command_line_interface.h | 394 + .../protobuf/compiler/cpp/cpp_generator.h | 72 + .../compiler/csharp/csharp_generator.h | 58 + .../protobuf/compiler/csharp/csharp_names.h | 103 + .../google/protobuf/compiler/importer.h | 326 + .../protobuf/compiler/java/java_generator.h | 72 + .../protobuf/compiler/java/java_names.h | 87 + .../compiler/javanano/javanano_generator.h | 72 + .../protobuf/compiler/js/js_generator.h | 281 + .../objectivec/objectivec_generator.h | 61 + .../compiler/objectivec/objectivec_helpers.h | 269 + .../include/google/protobuf/compiler/parser.h | 569 + .../include/google/protobuf/compiler/plugin.h | 90 + .../google/protobuf/compiler/plugin.pb.h | 830 + .../google/protobuf/compiler/plugin.proto | 150 + .../compiler/python/python_generator.h | 174 + .../protobuf/compiler/ruby/ruby_generator.h | 58 + .../include/google/protobuf/descriptor.h | 1919 ++ .../include/google/protobuf/descriptor.pb.h | 8002 +++++++++ .../include/google/protobuf/descriptor.proto | 813 + .../google/protobuf/descriptor_database.h | 369 + .../include/google/protobuf/duration.pb.h | 176 + .../include/google/protobuf/duration.proto | 98 + .../include/google/protobuf/dynamic_message.h | 152 + .../linux/include/google/protobuf/empty.pb.h | 147 + .../linux/include/google/protobuf/empty.proto | 53 + .../include/google/protobuf/extension_set.h | 1318 ++ .../include/google/protobuf/field_mask.pb.h | 206 + .../include/google/protobuf/field_mask.proto | 246 + .../protobuf/generated_enum_reflection.h | 88 + .../google/protobuf/generated_enum_util.h | 46 + .../protobuf/generated_message_reflection.h | 683 + .../google/protobuf/generated_message_util.h | 127 + .../include/google/protobuf/io/coded_stream.h | 1367 ++ .../include/google/protobuf/io/gzip_stream.h | 209 + .../include/google/protobuf/io/printer.h | 353 + .../linux/include/google/protobuf/io/strtod.h | 55 + .../include/google/protobuf/io/tokenizer.h | 411 + .../google/protobuf/io/zero_copy_stream.h | 248 + .../protobuf/io/zero_copy_stream_impl.h | 358 + .../protobuf/io/zero_copy_stream_impl_lite.h | 410 + .../linux/include/google/protobuf/map.h | 1742 ++ .../linux/include/google/protobuf/map_entry.h | 310 + .../include/google/protobuf/map_entry_lite.h | 568 + .../linux/include/google/protobuf/map_field.h | 397 + .../include/google/protobuf/map_field_inl.h | 489 + .../include/google/protobuf/map_field_lite.h | 278 + .../google/protobuf/map_type_handler.h | 743 + .../linux/include/google/protobuf/message.h | 1150 ++ .../include/google/protobuf/message_lite.h | 296 + .../linux/include/google/protobuf/metadata.h | 163 + .../include/google/protobuf/reflection.h | 600 + .../include/google/protobuf/reflection_ops.h | 81 + .../include/google/protobuf/repeated_field.h | 2481 +++ .../linux/include/google/protobuf/service.h | 292 + .../google/protobuf/source_context.pb.h | 190 + .../google/protobuf/source_context.proto | 48 + .../linux/include/google/protobuf/struct.pb.h | 781 + .../include/google/protobuf/struct.proto | 96 + .../protobuf/stubs/atomic_sequence_num.h | 54 + .../include/google/protobuf/stubs/atomicops.h | 246 + .../stubs/atomicops_internals_arm64_gcc.h | 325 + .../stubs/atomicops_internals_arm_gcc.h | 151 + .../stubs/atomicops_internals_arm_qnx.h | 146 + .../atomicops_internals_atomicword_compat.h | 122 + .../stubs/atomicops_internals_generic_gcc.h | 155 + .../stubs/atomicops_internals_macosx.h | 225 + .../stubs/atomicops_internals_mips_gcc.h | 313 + .../stubs/atomicops_internals_pnacl.h | 231 + .../stubs/atomicops_internals_power.h | 440 + .../stubs/atomicops_internals_ppc_gcc.h | 155 + .../stubs/atomicops_internals_solaris.h | 188 + .../protobuf/stubs/atomicops_internals_tsan.h | 219 + .../stubs/atomicops_internals_x86_gcc.h | 293 + .../stubs/atomicops_internals_x86_msvc.h | 150 + .../google/protobuf/stubs/bytestream.h | 348 + .../include/google/protobuf/stubs/callback.h | 546 + .../include/google/protobuf/stubs/casts.h | 133 + .../include/google/protobuf/stubs/common.h | 225 + .../include/google/protobuf/stubs/fastmem.h | 152 + .../include/google/protobuf/stubs/hash.h | 438 + .../include/google/protobuf/stubs/logging.h | 237 + .../include/google/protobuf/stubs/macros.h | 168 + .../include/google/protobuf/stubs/mutex.h | 148 + .../include/google/protobuf/stubs/once.h | 167 + .../google/protobuf/stubs/platform_macros.h | 125 + .../include/google/protobuf/stubs/port.h | 393 + .../google/protobuf/stubs/scoped_ptr.h | 236 + .../google/protobuf/stubs/shared_ptr.h | 470 + .../include/google/protobuf/stubs/singleton.h | 68 + .../include/google/protobuf/stubs/status.h | 116 + .../include/google/protobuf/stubs/stl_util.h | 121 + .../google/protobuf/stubs/stringpiece.h | 483 + .../google/protobuf/stubs/template_util.h | 138 + .../google/protobuf/stubs/type_traits.h | 364 + .../include/google/protobuf/text_format.h | 517 + .../include/google/protobuf/timestamp.pb.h | 189 + .../include/google/protobuf/timestamp.proto | 111 + .../linux/include/google/protobuf/type.pb.h | 1751 ++ .../linux/include/google/protobuf/type.proto | 180 + .../google/protobuf/unknown_field_set.h | 346 + .../google/protobuf/util/field_comparator.h | 259 + .../google/protobuf/util/field_mask_util.h | 193 + .../include/google/protobuf/util/json_util.h | 190 + .../protobuf/util/message_differencer.h | 849 + .../include/google/protobuf/util/time_util.h | 293 + .../google/protobuf/util/type_resolver.h | 75 + .../google/protobuf/util/type_resolver_util.h | 52 + .../include/google/protobuf/wire_format.h | 337 + .../google/protobuf/wire_format_lite.h | 724 + .../google/protobuf/wire_format_lite_inl.h | 876 + .../include/google/protobuf/wrappers.pb.h | 1216 ++ .../include/google/protobuf/wrappers.proto | 119 + .../linux/include/minotaur/AMPLHessian.h | 99 + .../linux/include/minotaur/AMPLInterface.h | 359 + .../linux/include/minotaur/AMPLJacobian.h | 123 + .../minotaur/AMPLNonlinearFunction.cpp | 165 + .../linux/include/minotaur/ActiveNodeStore.h | 99 + .../linux/include/minotaur/BndProcessor.h | 150 + .../linux/include/minotaur/BqpdEngine.h | 352 + thirdparty/linux/include/minotaur/BrCand.h | 129 + thirdparty/linux/include/minotaur/BrVarCand.h | 73 + thirdparty/linux/include/minotaur/Branch.h | 173 + .../linux/include/minotaur/BranchAndBound.h | 299 + thirdparty/linux/include/minotaur/Brancher.h | 98 + thirdparty/linux/include/minotaur/CGraph.h | 266 + thirdparty/linux/include/minotaur/CNode.h | 430 + .../linux/include/minotaur/Constraint.h | 223 + .../include/minotaur/CoverCutGenerator.h | 387 + thirdparty/linux/include/minotaur/CutInfo.h | 114 + .../linux/include/minotaur/CutManager.h | 173 + .../linux/include/minotaur/CxQuadHandler.h | 353 + .../linux/include/minotaur/CxUnivarHandler.h | 285 + thirdparty/linux/include/minotaur/Eigen.h | 249 + thirdparty/linux/include/minotaur/Engine.h | 203 + .../linux/include/minotaur/EngineFactory.h | 70 + .../linux/include/minotaur/Environment.h | 170 + thirdparty/linux/include/minotaur/Exception.h | 34 + .../linux/include/minotaur/FeasibilityPump.h | 253 + .../linux/include/minotaur/FilterSQPEngine.h | 345 + thirdparty/linux/include/minotaur/Function.h | 263 + thirdparty/linux/include/minotaur/Handler.h | 325 + .../linux/include/minotaur/HessianOfLag.h | 144 + thirdparty/linux/include/minotaur/Heuristic.h | 61 + .../linux/include/minotaur/IntVarHandler.h | 139 + thirdparty/linux/include/minotaur/Interrupt.h | 80 + .../linux/include/minotaur/IpoptEngine.h | 341 + .../linux/include/minotaur/IpoptEngineTnlp.h | 142 + thirdparty/linux/include/minotaur/Iterate.h | 43 + thirdparty/linux/include/minotaur/Jacobian.h | 125 + .../linux/include/minotaur/KnapCovHandler.h | 175 + .../linux/include/minotaur/KnapsackList.h | 82 + .../linux/include/minotaur/LGCIGenerator.h | 363 + thirdparty/linux/include/minotaur/LPEngine.h | 54 + .../linux/include/minotaur/LPRelaxation.h | 58 + .../linux/include/minotaur/LexicoBrancher.h | 88 + thirdparty/linux/include/minotaur/LinBil.h | 128 + thirdparty/linux/include/minotaur/LinConMod.h | 98 + .../linux/include/minotaur/LinFeasPump.h | 175 + thirdparty/linux/include/minotaur/LinMods.h | 93 + thirdparty/linux/include/minotaur/LinearCut.h | 90 + .../linux/include/minotaur/LinearFunction.h | 253 + .../linux/include/minotaur/LinearHandler.h | 278 + thirdparty/linux/include/minotaur/Logger.h | 96 + .../linux/include/minotaur/MINLPDiving.h | 339 + .../linux/include/minotaur/MaxFreqBrancher.h | 137 + .../linux/include/minotaur/MaxVioBrancher.h | 99 + .../linux/include/minotaur/MinotaurCFortran.h | 16 + .../linux/include/minotaur/MinotaurConfig.h | 16 + .../linux/include/minotaur/MinotaurDeconfig.h | 45 + .../linux/include/minotaur/Modification.h | 82 + .../linux/include/minotaur/MsProcessor.h | 230 + .../minotaur/MultilinearTermsHandler.h | 315 + thirdparty/linux/include/minotaur/NLPEngine.h | 61 + .../linux/include/minotaur/NLPMultiStart.h | 120 + .../linux/include/minotaur/NLPRelaxation.h | 66 + .../linux/include/minotaur/NlPresHandler.h | 182 + thirdparty/linux/include/minotaur/Node.h | 298 + thirdparty/linux/include/minotaur/NodeHeap.h | 110 + .../linux/include/minotaur/NodeIncRelaxer.h | 113 + .../linux/include/minotaur/NodeProcessor.h | 116 + .../linux/include/minotaur/NodeRelaxer.h | 95 + thirdparty/linux/include/minotaur/NodeStack.h | 94 + .../include/minotaur/NonlinearFunction.h | 292 + thirdparty/linux/include/minotaur/Objective.h | 214 + thirdparty/linux/include/minotaur/OpCode.h | 67 + .../linux/include/minotaur/Operations.h | 100 + thirdparty/linux/include/minotaur/Option.h | 248 + .../linux/include/minotaur/OsiLPEngine.h | 272 + .../linux/include/minotaur/PCBProcessor.h | 193 + .../linux/include/minotaur/ParBndProcessor.h | 157 + .../include/minotaur/ParBranchAndBound.h | 401 + .../include/minotaur/ParNodeIncRelaxer.h | 114 + .../linux/include/minotaur/ParTreeManager.h | 255 + thirdparty/linux/include/minotaur/PerspCon.h | 140 + .../include/minotaur/PerspCutGenerator.h | 231 + .../linux/include/minotaur/PerspCutHandler.h | 171 + .../include/minotaur/PolynomialFunction.h | 344 + .../linux/include/minotaur/PreAuxVars.h | 57 + .../linux/include/minotaur/PreDelVars.h | 56 + thirdparty/linux/include/minotaur/PreMod.h | 50 + .../linux/include/minotaur/PreSubstVars.h | 63 + thirdparty/linux/include/minotaur/Presolver.h | 151 + .../linux/include/minotaur/ProbStructure.h | 120 + thirdparty/linux/include/minotaur/Problem.h | 678 + .../linux/include/minotaur/ProblemSize.h | 122 + thirdparty/linux/include/minotaur/QGHandler.h | 290 + .../linux/include/minotaur/QGHandlerPDE.h | 290 + .../linux/include/minotaur/QPDProcessor.h | 280 + .../linux/include/minotaur/QPDRelaxer.h | 91 + thirdparty/linux/include/minotaur/QPEngine.h | 49 + .../linux/include/minotaur/QuadHandler.h | 390 + .../include/minotaur/QuadraticFunction.h | 291 + .../linux/include/minotaur/RandomBrancher.h | 86 + .../linux/include/minotaur/Relaxation.h | 98 + .../include/minotaur/ReliabilityBrancher.h | 353 + thirdparty/linux/include/minotaur/SOS.h | 80 + .../linux/include/minotaur/SOS1Handler.h | 135 + .../linux/include/minotaur/SOS2Handler.h | 143 + thirdparty/linux/include/minotaur/SOSBrCand.h | 88 + thirdparty/linux/include/minotaur/SecantMod.h | 88 + .../linux/include/minotaur/SimpleCutMan.h | 131 + .../include/minotaur/SimpleTransformer.h | 140 + thirdparty/linux/include/minotaur/Solution.h | 128 + .../linux/include/minotaur/SolutionPool.h | 117 + thirdparty/linux/include/minotaur/Timer.h | 185 + thirdparty/linux/include/minotaur/TransPoly.h | 272 + thirdparty/linux/include/minotaur/TransSep.h | 233 + .../linux/include/minotaur/Transformer.h | 259 + .../linux/include/minotaur/TreeManager.h | 242 + thirdparty/linux/include/minotaur/Types.h | 486 + thirdparty/linux/include/minotaur/Variable.h | 195 + thirdparty/linux/include/minotaur/Version.h | 22 + thirdparty/linux/include/minotaur/WarmStart.h | 75 + thirdparty/linux/include/minotaur/YEqCGs.h | 49 + thirdparty/linux/include/minotaur/YEqLFs.h | 51 + .../linux/include/minotaur/YEqMonomial.h | 57 + thirdparty/linux/include/minotaur/YEqUCGs.h | 53 + thirdparty/linux/include/minotaur/YEqVars.h | 52 + .../algorithms/dense_doubly_linked_list.h | 96 + .../ortools/algorithms/dynamic_partition.h | 344 + .../ortools/algorithms/dynamic_permutation.h | 133 + .../algorithms/find_graph_symmetries.h | 336 + .../include/ortools/algorithms/hungarian.h | 55 + .../ortools/algorithms/knapsack_solver.h | 599 + .../ortools/algorithms/sparse_permutation.h | 132 + .../linux/include/ortools/base/accurate_sum.h | 48 + .../base/adjustable_priority_queue-inl.h | 19 + .../ortools/base/adjustable_priority_queue.h | 140 + .../linux/include/ortools/base/basictypes.h | 22 + .../linux/include/ortools/base/bitmap.h | 86 + .../linux/include/ortools/base/callback.h | 14508 ++++++++++++++++ thirdparty/linux/include/ortools/base/casts.h | 31 + .../linux/include/ortools/base/cleanup.h | 42 + .../include/ortools/base/commandlineflags.h | 19 + .../include/ortools/base/encodingutils.h | 37 + thirdparty/linux/include/ortools/base/file.h | 146 + .../include/ortools/base/filelinereader.h | 52 + thirdparty/linux/include/ortools/base/hash.h | 149 + .../linux/include/ortools/base/int_type.h | 339 + .../ortools/base/int_type_indexed_vector.h | 207 + .../include/ortools/base/integral_types.h | 126 + .../include/ortools/base/iterator_adaptors.h | 39 + .../linux/include/ortools/base/jniutil.h | 66 + thirdparty/linux/include/ortools/base/join.h | 145 + .../linux/include/ortools/base/logging.h | 172 + .../linux/include/ortools/base/macros.h | 53 + .../linux/include/ortools/base/map_util.h | 177 + .../linux/include/ortools/base/mathutil.h | 119 + .../linux/include/ortools/base/murmur.h | 28 + thirdparty/linux/include/ortools/base/mutex.h | 72 + .../linux/include/ortools/base/numbers.h | 34 + thirdparty/linux/include/ortools/base/port.h | 34 + .../linux/include/ortools/base/python-swig.h | 370 + .../linux/include/ortools/base/random.h | 109 + .../linux/include/ortools/base/recordio.h | 135 + .../linux/include/ortools/base/small_map.h | 20 + .../include/ortools/base/small_ordered_set.h | 20 + .../linux/include/ortools/base/sparsetable.h | 71 + thirdparty/linux/include/ortools/base/split.h | 90 + .../linux/include/ortools/base/status.h | 65 + .../linux/include/ortools/base/statusor.h | 53 + .../linux/include/ortools/base/stl_util.h | 120 + .../linux/include/ortools/base/stringpiece.h | 170 + .../include/ortools/base/stringpiece_utils.h | 33 + .../linux/include/ortools/base/stringprintf.h | 26 + .../base/strongly_connected_components.h | 194 + .../linux/include/ortools/base/strtoint.h | 61 + .../linux/include/ortools/base/strutil.h | 33 + .../include/ortools/base/synchronization.h | 52 + .../linux/include/ortools/base/sysinfo.h | 24 + .../include/ortools/base/thorough_hash.h | 53 + .../linux/include/ortools/base/threadpool.h | 45 + .../linux/include/ortools/base/time_support.h | 45 + thirdparty/linux/include/ortools/base/timer.h | 105 + .../linux/include/ortools/base/typeid.h | 24 + .../linux/include/ortools/bop/bop_base.h | 280 + thirdparty/linux/include/ortools/bop/bop_fs.h | 156 + .../linux/include/ortools/bop/bop_lns.h | 182 + thirdparty/linux/include/ortools/bop/bop_ls.h | 635 + .../include/ortools/bop/bop_parameters.pb.h | 1822 ++ .../linux/include/ortools/bop/bop_portfolio.h | 202 + .../linux/include/ortools/bop/bop_solution.h | 112 + .../linux/include/ortools/bop/bop_solver.h | 104 + .../linux/include/ortools/bop/bop_types.h | 89 + .../linux/include/ortools/bop/bop_util.h | 90 + .../include/ortools/bop/complete_optimizer.h | 73 + .../include/ortools/bop/integral_solver.h | 75 + .../ortools/constraint_solver/assignment.pb.h | 1356 ++ .../constraint_solver/constraint_solver.h | 5388 ++++++ .../constraint_solver/constraint_solveri.h | 2784 +++ .../constraint_solver/demon_profiler.pb.h | 587 + .../ortools/constraint_solver/hybrid.h | 40 + .../ortools/constraint_solver/model.pb.h | 2785 +++ .../ortools/constraint_solver/routing.h | 2216 +++ .../constraint_solver/routing_enums.pb.h | 376 + .../ortools/constraint_solver/routing_flags.h | 84 + .../constraint_solver/routing_neighborhoods.h | 313 + .../constraint_solver/routing_parameters.pb.h | 1131 ++ .../ortools/constraint_solver/routing_types.h | 49 + .../constraint_solver/sat_constraint.h | 289 + .../constraint_solver/search_limit.pb.h | 258 + .../constraint_solver/solver_parameters.pb.h | 894 + .../ortools/glop/basis_representation.h | 370 + .../include/ortools/glop/dual_edge_norms.h | 127 + .../include/ortools/glop/entering_variable.h | 152 + .../include/ortools/glop/initial_basis.h | 122 + .../linux/include/ortools/glop/lp_solver.h | 279 + .../include/ortools/glop/lu_factorization.h | 306 + .../linux/include/ortools/glop/markowitz.h | 435 + .../include/ortools/glop/parameters.pb.h | 1913 ++ .../linux/include/ortools/glop/preprocessor.h | 999 ++ .../include/ortools/glop/primal_edge_norms.h | 210 + .../include/ortools/glop/rank_one_update.h | 250 + .../include/ortools/glop/reduced_costs.h | 297 + .../include/ortools/glop/revised_simplex.h | 826 + .../linux/include/ortools/glop/status.h | 97 + .../linux/include/ortools/glop/update_row.h | 155 + .../include/ortools/glop/variable_values.h | 140 + .../include/ortools/glop/variables_info.h | 128 + .../linux/include/ortools/graph/assignment.h | 130 + .../include/ortools/graph/christofides.h | 300 + .../linux/include/ortools/graph/cliques.h | 561 + .../include/ortools/graph/connectivity.h | 171 + .../linux/include/ortools/graph/ebert_graph.h | 2123 +++ .../include/ortools/graph/eulerian_path.h | 150 + .../include/ortools/graph/flow_problem.pb.h | 708 + .../linux/include/ortools/graph/graph.h | 2249 +++ .../linux/include/ortools/graph/graphs.h | 79 + .../include/ortools/graph/hamiltonian_path.h | 1020 ++ thirdparty/linux/include/ortools/graph/io.h | 283 + .../include/ortools/graph/linear_assignment.h | 1482 ++ .../linux/include/ortools/graph/max_flow.h | 709 + .../include/ortools/graph/min_cost_flow.h | 621 + .../ortools/graph/minimum_spanning_tree.h | 182 + .../ortools/graph/one_tree_lower_bound.h | 487 + .../include/ortools/graph/shortestpaths.h | 70 + thirdparty/linux/include/ortools/graph/util.h | 305 + .../ortools/linear_solver/glop_utils.h | 32 + .../ortools/linear_solver/linear_expr.h | 178 + .../ortools/linear_solver/linear_solver.h | 1375 ++ .../ortools/linear_solver/linear_solver.pb.h | 2532 +++ .../ortools/linear_solver/model_exporter.h | 203 + .../ortools/linear_solver/model_validator.h | 43 + .../include/ortools/sat/boolean_problem.h | 132 + .../include/ortools/sat/boolean_problem.pb.h | 1194 ++ thirdparty/linux/include/ortools/sat/clause.h | 461 + .../include/ortools/sat/cp_constraints.h | 480 + .../linux/include/ortools/sat/cumulative.h | 59 + .../linux/include/ortools/sat/disjunctive.h | 214 + thirdparty/linux/include/ortools/sat/drat.h | 98 + .../linux/include/ortools/sat/encoding.h | 195 + .../linux/include/ortools/sat/flow_costs.h | 134 + .../linux/include/ortools/sat/integer.h | 1155 ++ .../linux/include/ortools/sat/integer_expr.h | 543 + .../linux/include/ortools/sat/intervals.h | 479 + .../sat/linear_programming_constraint.h | 178 + .../linux/include/ortools/sat/lp_utils.h | 60 + thirdparty/linux/include/ortools/sat/model.h | 157 + .../linux/include/ortools/sat/no_cycle.h | 184 + .../linux/include/ortools/sat/optimization.h | 165 + .../include/ortools/sat/overload_checker.h | 158 + .../linux/include/ortools/sat/pb_constraint.h | 710 + .../linux/include/ortools/sat/precedences.h | 496 + .../linux/include/ortools/sat/sat_base.h | 600 + .../include/ortools/sat/sat_parameters.pb.h | 2961 ++++ .../linux/include/ortools/sat/sat_solver.h | 1149 ++ .../include/ortools/sat/simplification.h | 380 + .../linux/include/ortools/sat/symmetry.h | 154 + thirdparty/linux/include/ortools/sat/table.h | 58 + .../linux/include/ortools/sat/theta_tree.h | 198 + .../linux/include/ortools/sat/timetable.h | 179 + .../ortools/sat/timetable_edgefinding.h | 197 + thirdparty/linux/include/ortools/sat/util.h | 29 + .../linux/include/ortools/util/bitset.h | 836 + .../linux/include/ortools/util/cached_log.h | 50 + .../linux/include/ortools/util/filelineiter.h | 137 + .../linux/include/ortools/util/fp_utils.h | 277 + .../ortools/util/functions_swig_helpers.h | 89 + .../util/functions_swig_test_helpers.h | 74 + .../linux/include/ortools/util/graph_export.h | 59 + .../linux/include/ortools/util/iterators.h | 179 + .../ortools/util/monoid_operation_tree.h | 251 + .../linux/include/ortools/util/permutation.h | 217 + .../ortools/util/piecewise_linear_function.h | 283 + .../linux/include/ortools/util/proto_tools.h | 43 + .../ortools/util/range_minimum_query.h | 173 + .../ortools/util/range_query_function.h | 84 + .../ortools/util/rational_approximation.h | 37 + .../linux/include/ortools/util/rcpsp_parser.h | 177 + .../include/ortools/util/return_macros.h | 32 + thirdparty/linux/include/ortools/util/rev.h | 270 + .../linux/include/ortools/util/running_stat.h | 193 + .../ortools/util/saturated_arithmetic.h | 241 + thirdparty/linux/include/ortools/util/sort.h | 136 + .../ortools/util/sorted_interval_list.h | 216 + thirdparty/linux/include/ortools/util/stats.h | 358 + .../linux/include/ortools/util/string_array.h | 64 + .../linux/include/ortools/util/time_limit.h | 360 + .../linux/include/ortools/util/tuple_set.h | 425 + .../linux/include/ortools/util/vector_map.h | 113 + .../include/ortools/util/vector_or_function.h | 96 + .../linux/include/ortools/util/xml_helper.h | 62 + .../linux/include/ortools/util/zvector.h | 171 + thirdparty/linux/lib/x64/libClp.so | 1 + thirdparty/linux/lib/x64/libClp.so.1 | 1 + thirdparty/linux/lib/x64/libClp.so.1.13.9 | Bin 0 -> 1942800 bytes thirdparty/linux/lib/x64/libClpSolver.so | 1 + thirdparty/linux/lib/x64/libClpSolver.so.1 | 1 + .../linux/lib/x64/libClpSolver.so.1.13.9 | Bin 0 -> 417408 bytes thirdparty/linux/lib/x64/libCoinUtils.so | 1 + thirdparty/linux/lib/x64/libCoinUtils.so.3 | 1 + .../linux/lib/x64/libCoinUtils.so.3.10.11 | Bin 0 -> 1469312 bytes thirdparty/linux/lib/x64/libOsi.so | 1 + thirdparty/linux/lib/x64/libOsi.so.1 | 1 + thirdparty/linux/lib/x64/libOsi.so.1.12.6 | Bin 0 -> 405200 bytes thirdparty/linux/lib/x64/libOsiClp.so | 1 + thirdparty/linux/lib/x64/libOsiClp.so.1 | 1 + thirdparty/linux/lib/x64/libOsiClp.so.1.13.9 | Bin 0 -> 358160 bytes thirdparty/linux/lib/x64/libcoinmumps.so | 1 + thirdparty/linux/lib/x64/libcoinmumps.so.1 | 1 + .../linux/lib/x64/libcoinmumps.so.1.6.0 | Bin 0 -> 1647272 bytes thirdparty/linux/lib/x64/libcvrptw_lib.so | Bin 0 -> 38200 bytes thirdparty/linux/lib/x64/libdimacs.so | Bin 0 -> 13696 bytes thirdparty/linux/lib/x64/libfap.so | Bin 0 -> 118488 bytes thirdparty/linux/lib/x64/libipopt.so | 1 + thirdparty/linux/lib/x64/libipopt.so.1 | 1 + thirdparty/linux/lib/x64/libipopt.so.1.10.7 | Bin 0 -> 2919920 bytes thirdparty/linux/lib/x64/libjniortools.so | Bin 0 -> 1740360 bytes thirdparty/linux/lib/x64/libminotaur.so | Bin 0 -> 3268072 bytes thirdparty/linux/lib/x64/libmntrengfac.so | Bin 0 -> 24672 bytes thirdparty/linux/lib/x64/libmntripopt.so | Bin 0 -> 106040 bytes thirdparty/linux/lib/x64/libmntrosilp.so | Bin 0 -> 62272 bytes thirdparty/linux/lib/x64/libortools.so | Bin 0 -> 28468240 bytes thirdparty/windows/include/boost/assert.hpp | 85 + .../windows/include/boost/checked_delete.hpp | 17 + thirdparty/windows/include/boost/config.hpp | 67 + .../boost/config/abi/borland_prefix.hpp | 27 + .../boost/config/abi/borland_suffix.hpp | 12 + .../include/boost/config/abi/msvc_prefix.hpp | 22 + .../include/boost/config/abi/msvc_suffix.hpp | 8 + .../include/boost/config/abi_prefix.hpp | 25 + .../include/boost/config/abi_suffix.hpp | 27 + .../include/boost/config/auto_link.hpp | 439 + .../include/boost/config/compiler/borland.hpp | 319 + .../include/boost/config/compiler/clang.hpp | 304 + .../boost/config/compiler/codegear.hpp | 221 + .../include/boost/config/compiler/comeau.hpp | 59 + .../boost/config/compiler/common_edg.hpp | 144 + .../boost/config/compiler/compaq_cxx.hpp | 19 + .../include/boost/config/compiler/cray.hpp | 93 + .../boost/config/compiler/digitalmars.hpp | 125 + .../include/boost/config/compiler/gcc.hpp | 328 + .../include/boost/config/compiler/gcc_xml.hpp | 96 + .../boost/config/compiler/greenhills.hpp | 28 + .../include/boost/config/compiler/hp_acc.hpp | 146 + .../include/boost/config/compiler/intel.hpp | 552 + .../include/boost/config/compiler/kai.hpp | 33 + .../boost/config/compiler/metrowerks.hpp | 180 + .../include/boost/config/compiler/mpw.hpp | 122 + .../include/boost/config/compiler/nvcc.hpp | 32 + .../boost/config/compiler/pathscale.hpp | 115 + .../include/boost/config/compiler/pgi.hpp | 156 + .../boost/config/compiler/sgi_mipspro.hpp | 29 + .../boost/config/compiler/sunpro_cc.hpp | 198 + .../include/boost/config/compiler/vacpp.hpp | 163 + .../include/boost/config/compiler/visualc.hpp | 303 + .../include/boost/config/compiler/xlcpp.hpp | 262 + .../include/boost/config/no_tr1/cmath.hpp | 28 + .../include/boost/config/no_tr1/complex.hpp | 28 + .../boost/config/no_tr1/functional.hpp | 28 + .../include/boost/config/no_tr1/memory.hpp | 28 + .../include/boost/config/no_tr1/utility.hpp | 28 + .../include/boost/config/platform/aix.hpp | 33 + .../include/boost/config/platform/amigaos.hpp | 15 + .../include/boost/config/platform/beos.hpp | 26 + .../include/boost/config/platform/bsd.hpp | 86 + .../boost/config/platform/cloudabi.hpp | 18 + .../include/boost/config/platform/cray.hpp | 18 + .../include/boost/config/platform/cygwin.hpp | 58 + .../include/boost/config/platform/haiku.hpp | 31 + .../include/boost/config/platform/hpux.hpp | 87 + .../include/boost/config/platform/irix.hpp | 31 + .../include/boost/config/platform/linux.hpp | 105 + .../include/boost/config/platform/macos.hpp | 87 + .../include/boost/config/platform/qnxnto.hpp | 31 + .../include/boost/config/platform/solaris.hpp | 31 + .../include/boost/config/platform/symbian.hpp | 97 + .../include/boost/config/platform/vms.hpp | 25 + .../include/boost/config/platform/vxworks.hpp | 369 + .../include/boost/config/platform/win32.hpp | 90 + .../include/boost/config/posix_features.hpp | 95 + .../include/boost/config/requires_threads.hpp | 92 + .../boost/config/select_compiler_config.hpp | 148 + .../boost/config/select_platform_config.hpp | 137 + .../boost/config/select_stdlib_config.hpp | 105 + .../boost/config/stdlib/dinkumware.hpp | 209 + .../include/boost/config/stdlib/libcomo.hpp | 90 + .../include/boost/config/stdlib/libcpp.hpp | 113 + .../boost/config/stdlib/libstdcpp3.hpp | 314 + .../include/boost/config/stdlib/modena.hpp | 76 + .../include/boost/config/stdlib/msl.hpp | 95 + .../include/boost/config/stdlib/roguewave.hpp | 205 + .../include/boost/config/stdlib/sgi.hpp | 165 + .../include/boost/config/stdlib/stlport.hpp | 255 + .../include/boost/config/stdlib/vacpp.hpp | 71 + .../windows/include/boost/config/suffix.hpp | 1017 ++ .../windows/include/boost/config/user.hpp | 133 + .../include/boost/config/warning_disable.hpp | 47 + .../windows/include/boost/core/addressof.hpp | 162 + .../include/boost/core/checked_delete.hpp | 69 + .../windows/include/boost/core/demangle.hpp | 131 + .../windows/include/boost/core/typeinfo.hpp | 151 + thirdparty/windows/include/boost/cstdint.hpp | 546 + .../include/boost/current_function.hpp | 75 + .../boost/detail/lightweight_mutex.hpp | 22 + .../include/boost/detail/sp_typeinfo.hpp | 36 + .../include/boost/detail/workaround.hpp | 267 + .../include/boost/exception/exception.hpp | 521 + thirdparty/windows/include/boost/limits.hpp | 146 + thirdparty/windows/include/boost/predef.h | 24 + .../include/boost/predef/architecture.h | 32 + .../include/boost/predef/architecture/alpha.h | 59 + .../include/boost/predef/architecture/arm.h | 70 + .../boost/predef/architecture/blackfin.h | 46 + .../boost/predef/architecture/convex.h | 65 + .../include/boost/predef/architecture/ia64.h | 49 + .../include/boost/predef/architecture/m68k.h | 82 + .../include/boost/predef/architecture/mips.h | 73 + .../boost/predef/architecture/parisc.h | 64 + .../include/boost/predef/architecture/ppc.h | 72 + .../boost/predef/architecture/pyramid.h | 42 + .../include/boost/predef/architecture/rs6k.h | 56 + .../include/boost/predef/architecture/sparc.h | 54 + .../boost/predef/architecture/superh.h | 67 + .../boost/predef/architecture/sys370.h | 43 + .../boost/predef/architecture/sys390.h | 43 + .../include/boost/predef/architecture/x86.h | 38 + .../boost/predef/architecture/x86/32.h | 87 + .../boost/predef/architecture/x86/64.h | 50 + .../include/boost/predef/architecture/z.h | 42 + .../windows/include/boost/predef/compiler.h | 43 + .../include/boost/predef/compiler/borland.h | 63 + .../include/boost/predef/compiler/clang.h | 56 + .../include/boost/predef/compiler/comeau.h | 61 + .../include/boost/predef/compiler/compaq.h | 66 + .../include/boost/predef/compiler/diab.h | 56 + .../boost/predef/compiler/digitalmars.h | 56 + .../include/boost/predef/compiler/dignus.h | 56 + .../include/boost/predef/compiler/edg.h | 56 + .../include/boost/predef/compiler/ekopath.h | 57 + .../include/boost/predef/compiler/gcc.h | 68 + .../include/boost/predef/compiler/gcc_xml.h | 53 + .../boost/predef/compiler/greenhills.h | 66 + .../include/boost/predef/compiler/hp_acc.h | 61 + .../include/boost/predef/compiler/iar.h | 56 + .../include/boost/predef/compiler/ibm.h | 72 + .../include/boost/predef/compiler/intel.h | 65 + .../include/boost/predef/compiler/kai.h | 56 + .../include/boost/predef/compiler/llvm.h | 57 + .../include/boost/predef/compiler/metaware.h | 53 + .../boost/predef/compiler/metrowerks.h | 77 + .../include/boost/predef/compiler/microtec.h | 53 + .../include/boost/predef/compiler/mpw.h | 63 + .../include/boost/predef/compiler/palm.h | 56 + .../include/boost/predef/compiler/pgi.h | 60 + .../boost/predef/compiler/sgi_mipspro.h | 66 + .../include/boost/predef/compiler/sunpro.h | 76 + .../include/boost/predef/compiler/tendra.h | 53 + .../include/boost/predef/compiler/visualc.h | 91 + .../include/boost/predef/compiler/watcom.h | 56 + .../include/boost/predef/detail/_cassert.h | 17 + .../include/boost/predef/detail/_exception.h | 15 + .../boost/predef/detail/comp_detected.h | 10 + .../include/boost/predef/detail/os_detected.h | 10 + .../boost/predef/detail/platform_detected.h | 10 + .../include/boost/predef/detail/test.h | 17 + .../windows/include/boost/predef/hardware.h | 16 + .../include/boost/predef/hardware/simd.h | 119 + .../include/boost/predef/hardware/simd/arm.h | 57 + .../boost/predef/hardware/simd/arm/versions.h | 32 + .../include/boost/predef/hardware/simd/ppc.h | 69 + .../boost/predef/hardware/simd/ppc/versions.h | 51 + .../include/boost/predef/hardware/simd/x86.h | 123 + .../boost/predef/hardware/simd/x86/versions.h | 129 + .../boost/predef/hardware/simd/x86_amd.h | 87 + .../predef/hardware/simd/x86_amd/versions.h | 51 + .../windows/include/boost/predef/language.h | 17 + .../include/boost/predef/language/objc.h | 42 + .../include/boost/predef/language/stdc.h | 53 + .../include/boost/predef/language/stdcpp.h | 121 + .../windows/include/boost/predef/library.h | 16 + .../windows/include/boost/predef/library/c.h | 20 + .../include/boost/predef/library/c/_prefix.h | 13 + .../include/boost/predef/library/c/gnu.h | 61 + .../include/boost/predef/library/c/uc.h | 47 + .../include/boost/predef/library/c/vms.h | 47 + .../include/boost/predef/library/c/zos.h | 56 + .../include/boost/predef/library/std.h | 25 + .../boost/predef/library/std/_prefix.h | 23 + .../include/boost/predef/library/std/cxx.h | 46 + .../boost/predef/library/std/dinkumware.h | 52 + .../boost/predef/library/std/libcomo.h | 47 + .../include/boost/predef/library/std/modena.h | 45 + .../include/boost/predef/library/std/msl.h | 53 + .../boost/predef/library/std/roguewave.h | 56 + .../include/boost/predef/library/std/sgi.h | 51 + .../boost/predef/library/std/stdcpp3.h | 53 + .../boost/predef/library/std/stlport.h | 59 + .../include/boost/predef/library/std/vacpp.h | 44 + .../windows/include/boost/predef/make.h | 89 + thirdparty/windows/include/boost/predef/os.h | 33 + .../windows/include/boost/predef/os/aix.h | 66 + .../windows/include/boost/predef/os/amigaos.h | 46 + .../windows/include/boost/predef/os/android.h | 45 + .../windows/include/boost/predef/os/beos.h | 45 + .../windows/include/boost/predef/os/bsd.h | 103 + .../include/boost/predef/os/bsd/bsdi.h | 48 + .../include/boost/predef/os/bsd/dragonfly.h | 50 + .../include/boost/predef/os/bsd/free.h | 60 + .../windows/include/boost/predef/os/bsd/net.h | 84 + .../include/boost/predef/os/bsd/open.h | 171 + .../windows/include/boost/predef/os/cygwin.h | 45 + .../windows/include/boost/predef/os/haiku.h | 46 + .../windows/include/boost/predef/os/hpux.h | 47 + .../windows/include/boost/predef/os/ios.h | 51 + .../windows/include/boost/predef/os/irix.h | 46 + .../windows/include/boost/predef/os/linux.h | 46 + .../windows/include/boost/predef/os/macos.h | 65 + .../windows/include/boost/predef/os/os400.h | 45 + .../windows/include/boost/predef/os/qnxnto.h | 59 + .../windows/include/boost/predef/os/solaris.h | 46 + .../windows/include/boost/predef/os/unix.h | 76 + .../windows/include/boost/predef/os/vms.h | 52 + .../windows/include/boost/predef/os/windows.h | 51 + .../windows/include/boost/predef/other.h | 16 + .../include/boost/predef/other/endian.h | 204 + .../windows/include/boost/predef/platform.h | 21 + .../include/boost/predef/platform/mingw.h | 69 + .../boost/predef/platform/windows_desktop.h | 45 + .../boost/predef/platform/windows_phone.h | 43 + .../boost/predef/platform/windows_runtime.h | 45 + .../boost/predef/platform/windows_store.h | 43 + .../windows/include/boost/predef/version.h | 15 + .../include/boost/predef/version_number.h | 53 + .../windows/include/boost/shared_ptr.hpp | 19 + .../include/boost/smart_ptr/bad_weak_ptr.hpp | 68 + .../smart_ptr/detail/lightweight_mutex.hpp | 42 + .../boost/smart_ptr/detail/lwm_nop.hpp | 37 + .../boost/smart_ptr/detail/lwm_pthreads.hpp | 87 + .../boost/smart_ptr/detail/lwm_win32_cs.hpp | 119 + .../boost/smart_ptr/detail/operator_bool.hpp | 64 + .../smart_ptr/detail/quick_allocator.hpp | 199 + .../boost/smart_ptr/detail/shared_count.hpp | 709 + .../boost/smart_ptr/detail/sp_convertible.hpp | 92 + .../smart_ptr/detail/sp_counted_base.hpp | 96 + .../detail/sp_counted_base_acc_ia64.hpp | 151 + .../smart_ptr/detail/sp_counted_base_aix.hpp | 143 + .../detail/sp_counted_base_clang.hpp | 149 + .../detail/sp_counted_base_cw_ppc.hpp | 171 + .../detail/sp_counted_base_gcc_ia64.hpp | 158 + .../detail/sp_counted_base_gcc_mips.hpp | 182 + .../detail/sp_counted_base_gcc_ppc.hpp | 182 + .../detail/sp_counted_base_gcc_sparc.hpp | 167 + .../detail/sp_counted_base_gcc_x86.hpp | 174 + .../smart_ptr/detail/sp_counted_base_nt.hpp | 108 + .../smart_ptr/detail/sp_counted_base_pt.hpp | 137 + .../detail/sp_counted_base_snc_ps3.hpp | 162 + .../smart_ptr/detail/sp_counted_base_spin.hpp | 132 + .../detail/sp_counted_base_std_atomic.hpp | 137 + .../smart_ptr/detail/sp_counted_base_sync.hpp | 156 + .../detail/sp_counted_base_vacpp_ppc.hpp | 151 + .../smart_ptr/detail/sp_counted_base_w32.hpp | 131 + .../smart_ptr/detail/sp_counted_impl.hpp | 271 + .../detail/sp_disable_deprecated.hpp | 40 + .../boost/smart_ptr/detail/sp_has_sync.hpp | 69 + .../boost/smart_ptr/detail/sp_interlocked.hpp | 163 + .../boost/smart_ptr/detail/sp_nullptr_t.hpp | 45 + .../boost/smart_ptr/detail/spinlock.hpp | 68 + .../smart_ptr/detail/spinlock_gcc_arm.hpp | 121 + .../boost/smart_ptr/detail/spinlock_nt.hpp | 89 + .../boost/smart_ptr/detail/spinlock_pool.hpp | 91 + .../boost/smart_ptr/detail/spinlock_pt.hpp | 79 + .../smart_ptr/detail/spinlock_std_atomic.hpp | 83 + .../boost/smart_ptr/detail/spinlock_sync.hpp | 87 + .../boost/smart_ptr/detail/spinlock_w32.hpp | 113 + .../boost/smart_ptr/detail/yield_k.hpp | 177 + .../include/boost/smart_ptr/shared_ptr.hpp | 1094 ++ .../windows/include/boost/static_assert.hpp | 180 + .../windows/include/boost/throw_exception.hpp | 102 + .../type_traits/add_lvalue_reference.hpp | 27 + .../boost/type_traits/add_reference.hpp | 59 + .../type_traits/add_rvalue_reference.hpp | 64 + .../boost/type_traits/alignment_of.hpp | 119 + .../include/boost/type_traits/conditional.hpp | 20 + .../include/boost/type_traits/declval.hpp | 44 + .../boost/type_traits/detail/config.hpp | 72 + .../detail/is_function_ptr_helper.hpp | 176 + .../detail/is_function_ptr_tester.hpp | 449 + .../detail/is_mem_fun_pointer_impl.hpp | 723 + .../detail/is_mem_fun_pointer_tester.hpp | 1800 ++ .../boost/type_traits/detail/yes_no_type.hpp | 26 + .../boost/type_traits/integral_constant.hpp | 106 + .../include/boost/type_traits/intrinsics.hpp | 380 + .../include/boost/type_traits/is_abstract.hpp | 150 + .../boost/type_traits/is_arithmetic.hpp | 22 + .../include/boost/type_traits/is_array.hpp | 43 + .../include/boost/type_traits/is_class.hpp | 114 + .../boost/type_traits/is_convertible.hpp | 488 + .../include/boost/type_traits/is_enum.hpp | 166 + .../boost/type_traits/is_floating_point.hpp | 30 + .../include/boost/type_traits/is_function.hpp | 102 + .../include/boost/type_traits/is_integral.hpp | 89 + .../boost/type_traits/is_lvalue_reference.hpp | 50 + .../is_member_function_pointer.hpp | 120 + .../boost/type_traits/is_member_pointer.hpp | 45 + .../include/boost/type_traits/is_pod.hpp | 59 + .../include/boost/type_traits/is_pointer.hpp | 47 + .../boost/type_traits/is_polymorphic.hpp | 122 + .../boost/type_traits/is_reference.hpp | 30 + .../boost/type_traits/is_rvalue_reference.hpp | 25 + .../include/boost/type_traits/is_same.hpp | 41 + .../include/boost/type_traits/is_scalar.hpp | 27 + .../include/boost/type_traits/is_union.hpp | 31 + .../include/boost/type_traits/is_void.hpp | 26 + .../include/boost/type_traits/is_volatile.hpp | 46 + .../include/boost/type_traits/remove_cv.hpp | 40 + .../boost/type_traits/remove_reference.hpp | 54 + .../boost/type_traits/type_with_alignment.hpp | 261 + thirdparty/windows/include/boost/version.hpp | 32 + .../windows/include/coin/CbcOrClpParam.cpp | 4134 +++++ .../windows/include/coin/CbcOrClpParam.hpp | 532 + .../windows/include/coin/ClpCholeskyBase.hpp | 294 + .../windows/include/coin/ClpCholeskyDense.hpp | 162 + thirdparty/windows/include/coin/ClpConfig.h | 17 + .../windows/include/coin/ClpConstraint.hpp | 125 + .../include/coin/ClpConstraintLinear.hpp | 110 + .../include/coin/ClpConstraintQuadratic.hpp | 119 + .../include/coin/ClpDualRowDantzig.hpp | 71 + .../windows/include/coin/ClpDualRowPivot.hpp | 129 + .../include/coin/ClpDualRowSteepest.hpp | 153 + .../windows/include/coin/ClpDummyMatrix.hpp | 183 + .../include/coin/ClpDynamicExampleMatrix.hpp | 186 + .../windows/include/coin/ClpDynamicMatrix.hpp | 381 + .../windows/include/coin/ClpEventHandler.hpp | 187 + .../windows/include/coin/ClpFactorization.hpp | 432 + .../include/coin/ClpGubDynamicMatrix.hpp | 247 + .../windows/include/coin/ClpGubMatrix.hpp | 358 + .../windows/include/coin/ClpInterior.hpp | 570 + .../include/coin/ClpLinearObjective.hpp | 103 + .../windows/include/coin/ClpMatrixBase.hpp | 524 + .../windows/include/coin/ClpMessage.hpp | 131 + thirdparty/windows/include/coin/ClpModel.hpp | 1307 ++ .../windows/include/coin/ClpNetworkMatrix.hpp | 229 + thirdparty/windows/include/coin/ClpNode.hpp | 349 + .../windows/include/coin/ClpNonLinearCost.hpp | 401 + .../windows/include/coin/ClpObjective.hpp | 134 + .../windows/include/coin/ClpPackedMatrix.hpp | 638 + .../windows/include/coin/ClpParameters.hpp | 126 + .../windows/include/coin/ClpPdcoBase.hpp | 103 + .../include/coin/ClpPlusMinusOneMatrix.hpp | 290 + .../windows/include/coin/ClpPresolve.hpp | 299 + .../include/coin/ClpPrimalColumnDantzig.hpp | 72 + .../include/coin/ClpPrimalColumnPivot.hpp | 155 + .../include/coin/ClpPrimalColumnSteepest.hpp | 247 + .../include/coin/ClpQuadraticObjective.hpp | 155 + .../windows/include/coin/ClpSimplex.hpp | 1797 ++ .../windows/include/coin/ClpSimplexDual.hpp | 300 + .../include/coin/ClpSimplexNonlinear.hpp | 117 + .../windows/include/coin/ClpSimplexOther.hpp | 277 + .../windows/include/coin/ClpSimplexPrimal.hpp | 244 + thirdparty/windows/include/coin/ClpSolve.hpp | 446 + .../windows/include/coin/Clp_C_Interface.h | 525 + thirdparty/windows/include/coin/CoinAlloc.hpp | 176 + thirdparty/windows/include/coin/CoinBuild.hpp | 149 + .../include/coin/CoinDenseFactorization.hpp | 419 + .../windows/include/coin/CoinDenseVector.hpp | 383 + .../windows/include/coin/CoinDistance.hpp | 48 + thirdparty/windows/include/coin/CoinError.hpp | 257 + .../include/coin/CoinFactorization.hpp | 2044 +++ .../windows/include/coin/CoinFileIO.hpp | 166 + .../windows/include/coin/CoinFinite.hpp | 34 + .../windows/include/coin/CoinFloatEqual.hpp | 177 + .../include/coin/CoinHelperFunctions.hpp | 1111 ++ .../include/coin/CoinIndexedVector.hpp | 1164 ++ thirdparty/windows/include/coin/CoinLpIO.hpp | 805 + .../windows/include/coin/CoinMessage.hpp | 96 + .../include/coin/CoinMessageHandler.hpp | 666 + thirdparty/windows/include/coin/CoinModel.hpp | 1054 ++ .../windows/include/coin/CoinModelUseful.hpp | 441 + thirdparty/windows/include/coin/CoinMpsIO.hpp | 1056 ++ .../include/coin/CoinOslFactorization.hpp | 280 + .../windows/include/coin/CoinPackedMatrix.hpp | 947 + .../windows/include/coin/CoinPackedVector.hpp | 657 + .../include/coin/CoinPackedVectorBase.hpp | 269 + thirdparty/windows/include/coin/CoinParam.hpp | 644 + .../windows/include/coin/CoinPragma.hpp | 26 + .../include/coin/CoinPresolveDoubleton.hpp | 73 + .../windows/include/coin/CoinPresolveDual.hpp | 85 + .../include/coin/CoinPresolveDupcol.hpp | 226 + .../include/coin/CoinPresolveEmpty.hpp | 116 + .../include/coin/CoinPresolveFixed.hpp | 181 + .../include/coin/CoinPresolveForcing.hpp | 61 + .../include/coin/CoinPresolveImpliedFree.hpp | 60 + .../include/coin/CoinPresolveIsolated.hpp | 51 + .../include/coin/CoinPresolveMatrix.hpp | 1842 ++ .../include/coin/CoinPresolveMonitor.hpp | 105 + .../include/coin/CoinPresolvePsdebug.hpp | 166 + .../include/coin/CoinPresolveSingleton.hpp | 112 + .../include/coin/CoinPresolveSubst.hpp | 101 + .../include/coin/CoinPresolveTighten.hpp | 55 + .../include/coin/CoinPresolveTripleton.hpp | 66 + .../include/coin/CoinPresolveUseless.hpp | 63 + .../include/coin/CoinPresolveZeros.hpp | 60 + .../windows/include/coin/CoinRational.hpp | 44 + .../windows/include/coin/CoinSearchTree.hpp | 465 + .../include/coin/CoinShallowPackedVector.hpp | 148 + .../windows/include/coin/CoinSignal.hpp | 117 + .../include/coin/CoinSimpFactorization.hpp | 431 + .../windows/include/coin/CoinSmartPtr.hpp | 528 + .../windows/include/coin/CoinSnapshot.hpp | 476 + thirdparty/windows/include/coin/CoinSort.hpp | 678 + .../include/coin/CoinStructuredModel.hpp | 247 + thirdparty/windows/include/coin/CoinTime.hpp | 310 + thirdparty/windows/include/coin/CoinTypes.hpp | 64 + .../windows/include/coin/CoinUtility.hpp | 19 + .../windows/include/coin/CoinUtilsConfig.h | 34 + .../windows/include/coin/CoinWarmStart.hpp | 58 + .../include/coin/CoinWarmStartBasis.hpp | 456 + .../include/coin/CoinWarmStartDual.hpp | 166 + .../include/coin/CoinWarmStartPrimalDual.hpp | 211 + .../include/coin/CoinWarmStartVector.hpp | 488 + .../windows/include/coin/Coin_C_defines.h | 115 + thirdparty/windows/include/coin/HSLLoader.h | 378 + thirdparty/windows/include/coin/Idiot.hpp | 298 + .../windows/include/coin/IpAlgBuilder.hpp | 360 + .../windows/include/coin/IpAlgStrategy.hpp | 185 + .../windows/include/coin/IpAlgTypes.hpp | 66 + .../include/coin/IpAugSystemSolver.hpp | 200 + thirdparty/windows/include/coin/IpBlas.hpp | 78 + .../windows/include/coin/IpCachedResults.hpp | 779 + .../windows/include/coin/IpCompoundMatrix.hpp | 340 + .../include/coin/IpCompoundSymMatrix.hpp | 283 + .../windows/include/coin/IpCompoundVector.hpp | 339 + .../windows/include/coin/IpConvCheck.hpp | 87 + thirdparty/windows/include/coin/IpDebug.hpp | 150 + .../windows/include/coin/IpDenseVector.hpp | 550 + .../windows/include/coin/IpDiagMatrix.hpp | 141 + .../include/coin/IpEqMultCalculator.hpp | 64 + .../windows/include/coin/IpException.hpp | 147 + .../include/coin/IpExpansionMatrix.hpp | 212 + .../windows/include/coin/IpGenTMatrix.hpp | 264 + .../windows/include/coin/IpHessianUpdater.hpp | 65 + .../windows/include/coin/IpIdentityMatrix.hpp | 149 + .../windows/include/coin/IpIpoptAlg.hpp | 224 + .../include/coin/IpIpoptApplication.hpp | 296 + .../coin/IpIpoptCalculatedQuantities.hpp | 751 + .../windows/include/coin/IpIpoptData.hpp | 819 + .../windows/include/coin/IpIpoptNLP.hpp | 261 + .../include/coin/IpIterateInitializer.hpp | 64 + .../windows/include/coin/IpIteratesVector.hpp | 689 + .../include/coin/IpIterationOutput.hpp | 71 + .../windows/include/coin/IpJournalist.hpp | 497 + thirdparty/windows/include/coin/IpLapack.hpp | 55 + .../windows/include/coin/IpLineSearch.hpp | 96 + thirdparty/windows/include/coin/IpMatrix.hpp | 345 + .../windows/include/coin/IpMuUpdate.hpp | 69 + thirdparty/windows/include/coin/IpNLP.hpp | 243 + .../windows/include/coin/IpNLPScaling.hpp | 451 + .../windows/include/coin/IpObserver.hpp | 366 + .../windows/include/coin/IpOptionsList.hpp | 289 + .../windows/include/coin/IpOrigIpoptNLP.hpp | 488 + .../windows/include/coin/IpPDSystemSolver.hpp | 130 + .../windows/include/coin/IpReferenced.hpp | 258 + .../windows/include/coin/IpRegOptions.hpp | 658 + .../windows/include/coin/IpReturnCodes.h | 18 + .../windows/include/coin/IpReturnCodes.hpp | 21 + .../windows/include/coin/IpReturnCodes.inc | 70 + .../windows/include/coin/IpReturnCodes_inc.h | 46 + .../windows/include/coin/IpScaledMatrix.hpp | 254 + .../include/coin/IpSearchDirCalculator.hpp | 65 + .../windows/include/coin/IpSmartPtr.hpp | 734 + .../include/coin/IpSolveStatistics.hpp | 150 + .../windows/include/coin/IpStdCInterface.h | 271 + .../windows/include/coin/IpSumSymMatrix.hpp | 152 + .../include/coin/IpSymLinearSolver.hpp | 130 + .../windows/include/coin/IpSymMatrix.hpp | 162 + .../include/coin/IpSymScaledMatrix.hpp | 230 + .../windows/include/coin/IpSymTMatrix.hpp | 253 + thirdparty/windows/include/coin/IpTNLP.hpp | 301 + .../windows/include/coin/IpTNLPAdapter.hpp | 427 + .../windows/include/coin/IpTNLPReducer.hpp | 180 + .../windows/include/coin/IpTaggedObject.hpp | 162 + .../windows/include/coin/IpTimedTask.hpp | 146 + .../include/coin/IpTimingStatistics.hpp | 213 + .../windows/include/coin/IpTripletHelper.hpp | 135 + thirdparty/windows/include/coin/IpTypes.hpp | 28 + thirdparty/windows/include/coin/IpUtils.hpp | 128 + thirdparty/windows/include/coin/IpVector.hpp | 774 + .../windows/include/coin/IpZeroSymMatrix.hpp | 135 + thirdparty/windows/include/coin/IpoptConfig.h | 22 + .../windows/include/coin/OsiAuxInfo.hpp | 206 + .../include/coin/OsiBranchingObject.hpp | 1005 ++ .../include/coin/OsiChooseVariable.hpp | 534 + .../include/coin/OsiClpSolverInterface.hpp | 1509 ++ thirdparty/windows/include/coin/OsiColCut.hpp | 324 + .../windows/include/coin/OsiCollections.hpp | 35 + thirdparty/windows/include/coin/OsiConfig.h | 19 + thirdparty/windows/include/coin/OsiCut.hpp | 245 + thirdparty/windows/include/coin/OsiCuts.hpp | 474 + .../windows/include/coin/OsiPresolve.hpp | 252 + thirdparty/windows/include/coin/OsiRowCut.hpp | 331 + .../include/coin/OsiRowCutDebugger.hpp | 187 + .../windows/include/coin/OsiSolverBranch.hpp | 152 + .../include/coin/OsiSolverInterface.hpp | 2143 +++ .../include/coin/OsiSolverParameters.hpp | 142 + .../windows/include/coin/OsiUnitTests.hpp | 374 + .../windows/include/coin/PardisoLoader.h | 41 + .../include/coin/ThirdParty/dmumps_c.h | 159 + .../include/coin/ThirdParty/mumps_c_types.h | 92 + .../include/coin/ThirdParty/mumps_compat.h | 78 + .../include/coin/ThirdParty/mumps_mpi.h | 77 + .../windows/include/minotaur/AMPLHessian.h | 99 + .../windows/include/minotaur/AMPLInterface.h | 359 + .../windows/include/minotaur/AMPLJacobian.h | 123 + .../minotaur/AMPLNonlinearFunction.cpp | 165 + .../include/minotaur/ActiveNodeStore.h | 99 + .../windows/include/minotaur/BndProcessor.h | 150 + .../windows/include/minotaur/BqpdEngine.h | 352 + thirdparty/windows/include/minotaur/BrCand.h | 129 + .../windows/include/minotaur/BrVarCand.h | 73 + thirdparty/windows/include/minotaur/Branch.h | 173 + .../windows/include/minotaur/BranchAndBound.h | 299 + .../windows/include/minotaur/Brancher.h | 98 + thirdparty/windows/include/minotaur/CGraph.h | 266 + thirdparty/windows/include/minotaur/CNode.h | 430 + .../windows/include/minotaur/Constraint.h | 223 + .../include/minotaur/CoverCutGenerator.h | 387 + thirdparty/windows/include/minotaur/CutInfo.h | 114 + .../windows/include/minotaur/CutManager.h | 173 + .../windows/include/minotaur/CxQuadHandler.h | 353 + .../include/minotaur/CxUnivarHandler.h | 285 + thirdparty/windows/include/minotaur/Eigen.h | 249 + thirdparty/windows/include/minotaur/Engine.h | 203 + .../windows/include/minotaur/EngineFactory.h | 70 + .../windows/include/minotaur/Environment.h | 170 + .../windows/include/minotaur/Exception.h | 34 + .../include/minotaur/FeasibilityPump.h | 253 + .../include/minotaur/FilterSQPEngine.h | 345 + .../windows/include/minotaur/Function.h | 263 + thirdparty/windows/include/minotaur/Handler.h | 325 + .../windows/include/minotaur/HessianOfLag.h | 144 + .../windows/include/minotaur/Heuristic.h | 61 + .../windows/include/minotaur/IntVarHandler.h | 139 + .../windows/include/minotaur/Interrupt.h | 80 + .../windows/include/minotaur/IpoptEngine.h | 341 + .../include/minotaur/IpoptEngineTnlp.h | 142 + thirdparty/windows/include/minotaur/Iterate.h | 43 + .../windows/include/minotaur/Jacobian.h | 125 + .../windows/include/minotaur/KnapCovHandler.h | 175 + .../windows/include/minotaur/KnapsackList.h | 82 + .../windows/include/minotaur/LGCIGenerator.h | 363 + .../windows/include/minotaur/LPEngine.h | 54 + .../windows/include/minotaur/LPRelaxation.h | 58 + .../windows/include/minotaur/LexicoBrancher.h | 88 + thirdparty/windows/include/minotaur/LinBil.h | 128 + .../windows/include/minotaur/LinConMod.h | 98 + .../windows/include/minotaur/LinFeasPump.h | 175 + thirdparty/windows/include/minotaur/LinMods.h | 93 + .../windows/include/minotaur/LinearCut.h | 90 + .../windows/include/minotaur/LinearFunction.h | 253 + .../windows/include/minotaur/LinearHandler.h | 278 + thirdparty/windows/include/minotaur/Logger.h | 96 + .../windows/include/minotaur/MINLPDiving.h | 339 + .../include/minotaur/MaxFreqBrancher.h | 137 + .../windows/include/minotaur/MaxVioBrancher.h | 99 + .../include/minotaur/MinotaurCFortran.h | 16 + .../windows/include/minotaur/MinotaurConfig.h | 16 + .../include/minotaur/MinotaurDeconfig.h | 45 + .../windows/include/minotaur/Modification.h | 82 + .../windows/include/minotaur/MsProcessor.h | 230 + .../minotaur/MultilinearTermsHandler.h | 315 + .../windows/include/minotaur/NLPEngine.h | 61 + .../windows/include/minotaur/NLPMultiStart.h | 120 + .../windows/include/minotaur/NLPRelaxation.h | 66 + .../windows/include/minotaur/NlPresHandler.h | 182 + thirdparty/windows/include/minotaur/Node.h | 298 + .../windows/include/minotaur/NodeHeap.h | 110 + .../windows/include/minotaur/NodeIncRelaxer.h | 113 + .../windows/include/minotaur/NodeProcessor.h | 116 + .../windows/include/minotaur/NodeRelaxer.h | 95 + .../windows/include/minotaur/NodeStack.h | 94 + .../include/minotaur/NonlinearFunction.h | 292 + .../windows/include/minotaur/Objective.h | 214 + thirdparty/windows/include/minotaur/OpCode.h | 67 + .../windows/include/minotaur/Operations.h | 100 + thirdparty/windows/include/minotaur/Option.h | 248 + .../windows/include/minotaur/OsiLPEngine.h | 272 + .../windows/include/minotaur/PCBProcessor.h | 193 + .../include/minotaur/ParBndProcessor.h | 157 + .../include/minotaur/ParBranchAndBound.h | 401 + .../include/minotaur/ParNodeIncRelaxer.h | 114 + .../windows/include/minotaur/ParTreeManager.h | 255 + .../windows/include/minotaur/PerspCon.h | 140 + .../include/minotaur/PerspCutGenerator.h | 231 + .../include/minotaur/PerspCutHandler.h | 171 + .../include/minotaur/PolynomialFunction.h | 344 + .../windows/include/minotaur/PreAuxVars.h | 57 + .../windows/include/minotaur/PreDelVars.h | 56 + thirdparty/windows/include/minotaur/PreMod.h | 50 + .../windows/include/minotaur/PreSubstVars.h | 63 + .../windows/include/minotaur/Presolver.h | 151 + .../windows/include/minotaur/ProbStructure.h | 120 + thirdparty/windows/include/minotaur/Problem.h | 678 + .../windows/include/minotaur/ProblemSize.h | 122 + .../windows/include/minotaur/QGHandler.h | 290 + .../windows/include/minotaur/QGHandlerPDE.h | 290 + .../windows/include/minotaur/QPDProcessor.h | 280 + .../windows/include/minotaur/QPDRelaxer.h | 91 + .../windows/include/minotaur/QPEngine.h | 49 + .../windows/include/minotaur/QuadHandler.h | 390 + .../include/minotaur/QuadraticFunction.h | 291 + .../windows/include/minotaur/RandomBrancher.h | 86 + .../windows/include/minotaur/Relaxation.h | 98 + .../include/minotaur/ReliabilityBrancher.h | 353 + thirdparty/windows/include/minotaur/SOS.h | 80 + .../windows/include/minotaur/SOS1Handler.h | 135 + .../windows/include/minotaur/SOS2Handler.h | 143 + .../windows/include/minotaur/SOSBrCand.h | 88 + .../windows/include/minotaur/SecantMod.h | 88 + .../windows/include/minotaur/SimpleCutMan.h | 131 + .../include/minotaur/SimpleTransformer.h | 140 + .../windows/include/minotaur/Solution.h | 128 + .../windows/include/minotaur/SolutionPool.h | 117 + thirdparty/windows/include/minotaur/Timer.h | 185 + .../windows/include/minotaur/TransPoly.h | 272 + .../windows/include/minotaur/TransSep.h | 233 + .../windows/include/minotaur/Transformer.h | 259 + .../windows/include/minotaur/TreeManager.h | 242 + thirdparty/windows/include/minotaur/Types.h | 486 + .../windows/include/minotaur/Variable.h | 195 + thirdparty/windows/include/minotaur/Version.h | 22 + .../windows/include/minotaur/WarmStart.h | 75 + thirdparty/windows/include/minotaur/YEqCGs.h | 49 + thirdparty/windows/include/minotaur/YEqLFs.h | 51 + .../windows/include/minotaur/YEqMonomial.h | 57 + thirdparty/windows/include/minotaur/YEqUCGs.h | 53 + thirdparty/windows/include/minotaur/YEqVars.h | 52 + 1836 files changed, 394170 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE_BOOST.txt create mode 100644 LICENSE_Clp.txt create mode 100644 LICENSE_CoinUtils.txt create mode 100644 LICENSE_Ipopt.txt create mode 100644 LICENSE_MUMPS.txt create mode 100644 LICENSE_ORTOOLS.txt create mode 100644 LICENSE_Osi.txt create mode 100644 builder.sce create mode 100644 demos/Checkdims.dem.sce create mode 100644 demos/Checklhs.dem.sce create mode 100644 demos/Checkrhs.dem.sce create mode 100644 demos/Checktype.dem.sce create mode 100644 demos/Checkvector.dem.sce create mode 100644 demos/Filterdims.dem.sce create mode 100644 demos/Optimization_Toolbox.dem.gateway.sce create mode 100644 demos/fmaxflow.dem.sce create mode 100644 demos/fshortestpath.dem.sce create mode 100644 demos/jssp.dem.sce create mode 100644 demos/linsum.dem.sce create mode 100644 demos/min_cost_flow.dem.sce create mode 100644 demos/qcqpglob.dem.sce create mode 100644 demos/tsp.dem.sce create mode 100644 demos/vrp.dem.sce create mode 100644 etc/Optimization_Toolbox.quit create mode 100644 etc/Optimization_Toolbox.start create mode 100644 etc/README.rst create mode 100644 help/builder_help.sce create mode 100644 help/en_US/Checkdims.xml create mode 100644 help/en_US/Checklhs.xml create mode 100644 help/en_US/Checkrhs.xml create mode 100644 help/en_US/Checktype.xml create mode 100644 help/en_US/Checkvector.xml create mode 100644 help/en_US/Filterdims.xml create mode 100644 help/en_US/README.rst create mode 100644 help/en_US/build_help.sce create mode 100644 help/en_US/fmaxflow.xml create mode 100644 help/en_US/fshortestpath.xml create mode 100644 help/en_US/jssp.xml create mode 100644 help/en_US/linsum.xml create mode 100644 help/en_US/min_cost_flow.xml create mode 100644 help/en_US/qcqpglob.xml create mode 100644 help/en_US/tsp.xml create mode 100644 help/en_US/vrp.xml create mode 100644 macros/Checkdims.sci create mode 100644 macros/Checklhs.sci create mode 100644 macros/Checkrhs.sci create mode 100644 macros/Checktype.sci create mode 100644 macros/Checkvector.sci create mode 100644 macros/Filterdims.sci create mode 100644 macros/buildmacros.sce create mode 100644 macros/fmaxflow.sci create mode 100644 macros/fshortestpath.sci create mode 100644 macros/jssp.sci create mode 100644 macros/linsum.sci create mode 100644 macros/min_cost_flow.sci create mode 100644 macros/names create mode 100644 macros/qcqpglob.sci create mode 100644 macros/tsp.sci create mode 100644 macros/vrp.sci create mode 100644 sci_gateway/builder_gateway.sce create mode 100644 sci_gateway/cpp/builder_gateway_cpp.sce create mode 100644 sci_gateway/cpp/misc.hpp create mode 100644 sci_gateway/cpp/sci_BellmanFord_shortestPath.cpp create mode 100644 sci_gateway/cpp/sci_iofunc.cpp create mode 100644 sci_gateway/cpp/sci_iofunc.hpp create mode 100755 sci_gateway/cpp/sci_jssp.cpp create mode 100644 sci_gateway/cpp/sci_linear_sum_assignment.cpp create mode 100755 sci_gateway/cpp/sci_max_flow.cpp create mode 100644 sci_gateway/cpp/sci_min_cost_flow.cpp create mode 100644 sci_gateway/cpp/sci_qcqpglob.cpp create mode 100644 sci_gateway/cpp/sci_tsp.cpp create mode 100644 sci_gateway/cpp/sci_vrp.cpp create mode 100644 tests/general_tests/fmaxflow/fmaxflow_capacities_dim.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_capacities_integral.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_endnodes_dim.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_endnodes_integral.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_equalvectorlength.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_input1.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_input2.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_nopath.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_output1.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_output2.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_sourceChk.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_st_dim.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_startendnodes_integral.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_startnodes_dim.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_startnodes_integral.sce create mode 100644 tests/general_tests/fmaxflow/fmaxflow_targetChk.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_discondist_dim.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_discondist_integral.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_endnodes_dim.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_endnodes_integral.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_equalvectorlength.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_input1.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_input2.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_nopath1.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_nopath2.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_nopath3.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_output1.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_output2.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_sourceChk.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_st_dim.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_startend_integral.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_startnodes_dim.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_startnodes_integral.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_targetChk.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_weights_dim.sce create mode 100644 tests/general_tests/fshortestpath/fshortestpath_weights_integral.sce create mode 100644 tests/general_tests/jssp/jssp_duration_valid.sce create mode 100644 tests/general_tests/jssp/jssp_endbefore_valid.sce create mode 100644 tests/general_tests/jssp/jssp_firsttask_mode1.sce create mode 100644 tests/general_tests/jssp/jssp_inputargs.sce create mode 100644 tests/general_tests/jssp/jssp_jmode_dims.sce create mode 100644 tests/general_tests/jssp/jssp_jmode_int.sce create mode 100644 tests/general_tests/jssp/jssp_jmode_type.sce create mode 100644 tests/general_tests/jssp/jssp_jmode_valid.sce create mode 100644 tests/general_tests/jssp/jssp_jobindices_valid.sce create mode 100644 tests/general_tests/jssp/jssp_jobs_dims.sce create mode 100644 tests/general_tests/jssp/jssp_jobs_int.sce create mode 100644 tests/general_tests/jssp/jssp_jobs_type.sce create mode 100644 tests/general_tests/jssp/jssp_lasttask_mode1.sce create mode 100644 tests/general_tests/jssp/jssp_machineindices_valid.sce create mode 100644 tests/general_tests/jssp/jssp_machines_dims.sce create mode 100644 tests/general_tests/jssp/jssp_machines_int.sce create mode 100644 tests/general_tests/jssp/jssp_machines_type.sce create mode 100644 tests/general_tests/jssp/jssp_outputargs.sce create mode 100644 tests/general_tests/jssp/jssp_startafter_valid.sce create mode 100644 tests/general_tests/jssp/jssp_tasks_dims.sce create mode 100644 tests/general_tests/jssp/jssp_tasks_int.sce create mode 100644 tests/general_tests/jssp/jssp_tasks_type.sce create mode 100644 tests/general_tests/jssp/jssp_timelimit_dims.sce create mode 100644 tests/general_tests/jssp/jssp_timelimit_int.sce create mode 100644 tests/general_tests/jssp/jssp_timelimit_type.sce create mode 100644 tests/general_tests/jssp/jssp_timelimit_valid.sce create mode 100644 tests/general_tests/linsum/linsum_t1.sce create mode 100644 tests/general_tests/linsum/linsum_t2.sce create mode 100644 tests/general_tests/linsum/linsum_t3.sce create mode 100644 tests/general_tests/linsum/linsum_t4.sce create mode 100644 tests/general_tests/linsum/linsum_t5.sce create mode 100644 tests/general_tests/linsum/linsum_t6.sce create mode 100644 tests/general_tests/linsum/linsum_t7.sce create mode 100644 tests/general_tests/linsum/linsum_t8.sce create mode 100644 tests/general_tests/linsum/linsum_t9.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t1.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t10.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t11.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t12.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t13.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t14.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t15.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t16.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t17.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t2.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t3.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t4.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t5.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t6.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t7.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t8.sce create mode 100644 tests/general_tests/min_cost_flow/min_cost_flow_t9.sce create mode 100644 tests/general_tests/tsp/tsp_adj_diag.sce create mode 100644 tests/general_tests/tsp/tsp_adj_dims.sce create mode 100644 tests/general_tests/tsp/tsp_adj_integral.sce create mode 100644 tests/general_tests/tsp/tsp_adj_type.sce create mode 100644 tests/general_tests/tsp/tsp_input1.sce create mode 100644 tests/general_tests/tsp/tsp_input2.sce create mode 100644 tests/general_tests/tsp/tsp_labels_dims1.sce create mode 100644 tests/general_tests/tsp/tsp_labels_dims2.sce create mode 100644 tests/general_tests/tsp/tsp_labels_dims3.sce create mode 100644 tests/general_tests/tsp/tsp_labels_type.sce create mode 100644 tests/general_tests/tsp/tsp_labels_unique.sce create mode 100644 tests/general_tests/tsp/tsp_output1.sce create mode 100644 tests/general_tests/tsp/tsp_output2.sce create mode 100644 tests/general_tests/tsp/tsp_startnode_integral.sce create mode 100644 tests/general_tests/tsp/tsp_startnode_type.sce create mode 100644 tests/general_tests/tsp/tsp_startnode_valid.sce create mode 100644 tests/general_tests/tsp/tsp_startnodes_dims.sce create mode 100644 tests/general_tests/vrp/vrp_adj_dim.sce create mode 100644 tests/general_tests/vrp/vrp_adj_int.sce create mode 100644 tests/general_tests/vrp/vrp_adj_type.sce create mode 100644 tests/general_tests/vrp/vrp_adjdiagonal_zero.sce create mode 100644 tests/general_tests/vrp/vrp_demand_lt_vehiclecapacity.sce create mode 100644 tests/general_tests/vrp/vrp_demands_dim.sce create mode 100644 tests/general_tests/vrp/vrp_demands_int.sce create mode 100644 tests/general_tests/vrp/vrp_demands_nonnegative.sce create mode 100644 tests/general_tests/vrp/vrp_demands_type.sce create mode 100644 tests/general_tests/vrp/vrp_depotdemand_zero.sce create mode 100644 tests/general_tests/vrp/vrp_fuelcapacity_dim.sce create mode 100644 tests/general_tests/vrp/vrp_fuelcapacity_int.sce create mode 100644 tests/general_tests/vrp/vrp_fuelcapacity_positive.sce create mode 100644 tests/general_tests/vrp/vrp_fuelcapacity_specified.sce create mode 100644 tests/general_tests/vrp/vrp_fuelcapacity_type.sce create mode 100644 tests/general_tests/vrp/vrp_grouppenalty_dim.sci create mode 100644 tests/general_tests/vrp/vrp_grouppenalty_int.sce create mode 100644 tests/general_tests/vrp/vrp_grouppenalty_nonnegative_or_minus1.sce create mode 100644 tests/general_tests/vrp/vrp_grouppenalty_type.sce create mode 100644 tests/general_tests/vrp/vrp_groups_int.sce create mode 100644 tests/general_tests/vrp/vrp_groups_norepeat.sce create mode 100644 tests/general_tests/vrp/vrp_groups_type.sce create mode 100644 tests/general_tests/vrp/vrp_groupsindices_valid.sce create mode 100644 tests/general_tests/vrp/vrp_labels_dim.sce create mode 100644 tests/general_tests/vrp/vrp_labels_type.sce create mode 100644 tests/general_tests/vrp/vrp_maxvehiclecapacity_dim.sce create mode 100644 tests/general_tests/vrp/vrp_maxvehiclecapacity_int.sce create mode 100644 tests/general_tests/vrp/vrp_maxvehiclecapacity_positive.sce create mode 100644 tests/general_tests/vrp/vrp_maxvehiclecapacity_type.sce create mode 100644 tests/general_tests/vrp/vrp_penalty_dim.sce create mode 100644 tests/general_tests/vrp/vrp_penalty_int.sce create mode 100644 tests/general_tests/vrp/vrp_penalty_nodepot.sce create mode 100644 tests/general_tests/vrp/vrp_penalty_nonnegative.sce create mode 100644 tests/general_tests/vrp/vrp_penalty_type.sce create mode 100644 tests/general_tests/vrp/vrp_penaltyindices_valid.sce create mode 100644 tests/general_tests/vrp/vrp_refuelflag_dim.sce create mode 100644 tests/general_tests/vrp/vrp_refuelflag_int.sce create mode 100644 tests/general_tests/vrp/vrp_refuelflag_type.sce create mode 100644 tests/general_tests/vrp/vrp_refuelflag_valid.sce create mode 100644 tests/general_tests/vrp/vrp_refuelnodes_dim.sce create mode 100644 tests/general_tests/vrp/vrp_refuelnodes_int.sce create mode 100644 tests/general_tests/vrp/vrp_refuelnodes_type.sce create mode 100644 tests/general_tests/vrp/vrp_refuelnodes_valid.sce create mode 100644 tests/general_tests/vrp/vrp_servicetime_dim.sce create mode 100644 tests/general_tests/vrp/vrp_servicetime_gtzero.sce create mode 100644 tests/general_tests/vrp/vrp_servicetime_int.sce create mode 100644 tests/general_tests/vrp/vrp_servicetime_type.sce create mode 100644 tests/general_tests/vrp/vrp_speeds_dim.sce create mode 100644 tests/general_tests/vrp/vrp_speeds_int.sce create mode 100644 tests/general_tests/vrp/vrp_speeds_positive.sce create mode 100644 tests/general_tests/vrp/vrp_speeds_type.sce create mode 100644 tests/general_tests/vrp/vrp_start_dim.sce create mode 100644 tests/general_tests/vrp/vrp_start_int.sce create mode 100644 tests/general_tests/vrp/vrp_start_type.sce create mode 100644 tests/general_tests/vrp/vrp_startnode_valid.sce create mode 100644 tests/general_tests/vrp/vrp_timelimit_dim.sce create mode 100644 tests/general_tests/vrp/vrp_timelimit_int.sce create mode 100644 tests/general_tests/vrp/vrp_timelimit_positive.sce create mode 100644 tests/general_tests/vrp/vrp_timelimit_type.sce create mode 100644 tests/general_tests/vrp/vrp_timewindows_dim.sce create mode 100644 tests/general_tests/vrp/vrp_timewindows_ends_gt_starts.sce create mode 100644 tests/general_tests/vrp/vrp_timewindows_int.sce create mode 100644 tests/general_tests/vrp/vrp_timewindows_nonnegative_or_minus1.sce create mode 100644 tests/general_tests/vrp/vrp_timewindows_type.sce create mode 100644 tests/general_tests/vrp/vrp_totaldemands_lt_totalcapacity.sce create mode 100644 tests/general_tests/vrp/vrp_uniquelabels.sce create mode 100644 tests/general_tests/vrp/vrp_vehiclecapacity_if_capacitated.sce create mode 100644 tests/general_tests/vrp/vrp_vehicles_dim.sce create mode 100644 tests/general_tests/vrp/vrp_vehicles_int.sce create mode 100644 tests/general_tests/vrp/vrp_vehicles_positive.sce create mode 100644 tests/general_tests/vrp/vrp_vehicles_type.sce create mode 100644 tests/general_tests/vrp/vrp_waitingtimes_dim.sce create mode 100644 tests/general_tests/vrp/vrp_waitingtimes_int.sce create mode 100644 tests/general_tests/vrp/vrp_waitingtimes_nonnegative.sce create mode 100644 tests/general_tests/vrp/vrp_waitingtimes_type.sce create mode 100644 tests/unit_tests/fmaxflow.dia.ref create mode 100644 tests/unit_tests/fmaxflow.tst create mode 100644 tests/unit_tests/fshortestpath.dia.ref create mode 100644 tests/unit_tests/fshortestpath.tst create mode 100644 tests/unit_tests/jssp.dia.ref create mode 100644 tests/unit_tests/jssp.tst create mode 100644 tests/unit_tests/linsum.dia.ref create mode 100644 tests/unit_tests/linsum.tst create mode 100644 tests/unit_tests/min_cost_flow.dia.ref create mode 100644 tests/unit_tests/min_cost_flow.tst create mode 100644 tests/unit_tests/tsp.dia.ref create mode 100644 tests/unit_tests/tsp.tst create mode 100644 tests/unit_tests/vrp.dia.ref create mode 100644 tests/unit_tests/vrp.tst create mode 100644 thirdparty/.gitignore create mode 100644 thirdparty/linux/include/boost/assert.hpp create mode 100644 thirdparty/linux/include/boost/checked_delete.hpp create mode 100644 thirdparty/linux/include/boost/config.hpp create mode 100644 thirdparty/linux/include/boost/config/abi/borland_prefix.hpp create mode 100644 thirdparty/linux/include/boost/config/abi/borland_suffix.hpp create mode 100644 thirdparty/linux/include/boost/config/abi/msvc_prefix.hpp create mode 100644 thirdparty/linux/include/boost/config/abi/msvc_suffix.hpp create mode 100644 thirdparty/linux/include/boost/config/abi_prefix.hpp create mode 100644 thirdparty/linux/include/boost/config/abi_suffix.hpp create mode 100644 thirdparty/linux/include/boost/config/auto_link.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/borland.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/clang.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/codegear.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/comeau.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/common_edg.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/compaq_cxx.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/cray.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/digitalmars.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/gcc.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/gcc_xml.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/greenhills.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/hp_acc.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/intel.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/kai.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/metrowerks.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/mpw.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/nvcc.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/pathscale.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/pgi.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/sgi_mipspro.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/sunpro_cc.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/vacpp.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/visualc.hpp create mode 100644 thirdparty/linux/include/boost/config/compiler/xlcpp.hpp create mode 100644 thirdparty/linux/include/boost/config/no_tr1/cmath.hpp create mode 100644 thirdparty/linux/include/boost/config/no_tr1/complex.hpp create mode 100644 thirdparty/linux/include/boost/config/no_tr1/functional.hpp create mode 100644 thirdparty/linux/include/boost/config/no_tr1/memory.hpp create mode 100644 thirdparty/linux/include/boost/config/no_tr1/utility.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/aix.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/amigaos.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/beos.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/bsd.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/cloudabi.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/cray.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/cygwin.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/haiku.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/hpux.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/irix.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/linux.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/macos.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/qnxnto.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/solaris.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/symbian.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/vms.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/vxworks.hpp create mode 100644 thirdparty/linux/include/boost/config/platform/win32.hpp create mode 100644 thirdparty/linux/include/boost/config/posix_features.hpp create mode 100644 thirdparty/linux/include/boost/config/requires_threads.hpp create mode 100644 thirdparty/linux/include/boost/config/select_compiler_config.hpp create mode 100644 thirdparty/linux/include/boost/config/select_platform_config.hpp create mode 100644 thirdparty/linux/include/boost/config/select_stdlib_config.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/dinkumware.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/libcomo.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/libcpp.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/libstdcpp3.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/modena.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/msl.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/roguewave.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/sgi.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/stlport.hpp create mode 100644 thirdparty/linux/include/boost/config/stdlib/vacpp.hpp create mode 100644 thirdparty/linux/include/boost/config/suffix.hpp create mode 100644 thirdparty/linux/include/boost/config/user.hpp create mode 100644 thirdparty/linux/include/boost/config/warning_disable.hpp create mode 100644 thirdparty/linux/include/boost/core/addressof.hpp create mode 100644 thirdparty/linux/include/boost/core/checked_delete.hpp create mode 100644 thirdparty/linux/include/boost/core/demangle.hpp create mode 100644 thirdparty/linux/include/boost/core/typeinfo.hpp create mode 100644 thirdparty/linux/include/boost/cstdint.hpp create mode 100644 thirdparty/linux/include/boost/current_function.hpp create mode 100644 thirdparty/linux/include/boost/detail/lightweight_mutex.hpp create mode 100644 thirdparty/linux/include/boost/detail/sp_typeinfo.hpp create mode 100644 thirdparty/linux/include/boost/detail/workaround.hpp create mode 100644 thirdparty/linux/include/boost/exception/exception.hpp create mode 100644 thirdparty/linux/include/boost/limits.hpp create mode 100644 thirdparty/linux/include/boost/predef.h create mode 100644 thirdparty/linux/include/boost/predef/architecture.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/alpha.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/arm.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/blackfin.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/convex.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/ia64.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/m68k.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/mips.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/parisc.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/ppc.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/pyramid.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/rs6k.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/sparc.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/superh.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/sys370.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/sys390.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/x86.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/x86/32.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/x86/64.h create mode 100644 thirdparty/linux/include/boost/predef/architecture/z.h create mode 100644 thirdparty/linux/include/boost/predef/compiler.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/borland.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/clang.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/comeau.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/compaq.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/diab.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/digitalmars.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/dignus.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/edg.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/ekopath.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/gcc.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/gcc_xml.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/greenhills.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/hp_acc.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/iar.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/ibm.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/intel.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/kai.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/llvm.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/metaware.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/metrowerks.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/microtec.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/mpw.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/palm.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/pgi.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/sgi_mipspro.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/sunpro.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/tendra.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/visualc.h create mode 100644 thirdparty/linux/include/boost/predef/compiler/watcom.h create mode 100644 thirdparty/linux/include/boost/predef/detail/_cassert.h create mode 100644 thirdparty/linux/include/boost/predef/detail/_exception.h create mode 100644 thirdparty/linux/include/boost/predef/detail/comp_detected.h create mode 100644 thirdparty/linux/include/boost/predef/detail/os_detected.h create mode 100644 thirdparty/linux/include/boost/predef/detail/platform_detected.h create mode 100644 thirdparty/linux/include/boost/predef/detail/test.h create mode 100644 thirdparty/linux/include/boost/predef/hardware.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd/arm.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd/arm/versions.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd/ppc.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd/ppc/versions.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd/x86.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd/x86/versions.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd/x86_amd.h create mode 100644 thirdparty/linux/include/boost/predef/hardware/simd/x86_amd/versions.h create mode 100644 thirdparty/linux/include/boost/predef/language.h create mode 100644 thirdparty/linux/include/boost/predef/language/objc.h create mode 100644 thirdparty/linux/include/boost/predef/language/stdc.h create mode 100644 thirdparty/linux/include/boost/predef/language/stdcpp.h create mode 100644 thirdparty/linux/include/boost/predef/library.h create mode 100644 thirdparty/linux/include/boost/predef/library/c.h create mode 100644 thirdparty/linux/include/boost/predef/library/c/_prefix.h create mode 100644 thirdparty/linux/include/boost/predef/library/c/gnu.h create mode 100644 thirdparty/linux/include/boost/predef/library/c/uc.h create mode 100644 thirdparty/linux/include/boost/predef/library/c/vms.h create mode 100644 thirdparty/linux/include/boost/predef/library/c/zos.h create mode 100644 thirdparty/linux/include/boost/predef/library/std.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/_prefix.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/cxx.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/dinkumware.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/libcomo.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/modena.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/msl.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/roguewave.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/sgi.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/stdcpp3.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/stlport.h create mode 100644 thirdparty/linux/include/boost/predef/library/std/vacpp.h create mode 100644 thirdparty/linux/include/boost/predef/make.h create mode 100644 thirdparty/linux/include/boost/predef/os.h create mode 100644 thirdparty/linux/include/boost/predef/os/aix.h create mode 100644 thirdparty/linux/include/boost/predef/os/amigaos.h create mode 100644 thirdparty/linux/include/boost/predef/os/android.h create mode 100644 thirdparty/linux/include/boost/predef/os/beos.h create mode 100644 thirdparty/linux/include/boost/predef/os/bsd.h create mode 100644 thirdparty/linux/include/boost/predef/os/bsd/bsdi.h create mode 100644 thirdparty/linux/include/boost/predef/os/bsd/dragonfly.h create mode 100644 thirdparty/linux/include/boost/predef/os/bsd/free.h create mode 100644 thirdparty/linux/include/boost/predef/os/bsd/net.h create mode 100644 thirdparty/linux/include/boost/predef/os/bsd/open.h create mode 100644 thirdparty/linux/include/boost/predef/os/cygwin.h create mode 100644 thirdparty/linux/include/boost/predef/os/haiku.h create mode 100644 thirdparty/linux/include/boost/predef/os/hpux.h create mode 100644 thirdparty/linux/include/boost/predef/os/ios.h create mode 100644 thirdparty/linux/include/boost/predef/os/irix.h create mode 100644 thirdparty/linux/include/boost/predef/os/linux.h create mode 100644 thirdparty/linux/include/boost/predef/os/macos.h create mode 100644 thirdparty/linux/include/boost/predef/os/os400.h create mode 100644 thirdparty/linux/include/boost/predef/os/qnxnto.h create mode 100644 thirdparty/linux/include/boost/predef/os/solaris.h create mode 100644 thirdparty/linux/include/boost/predef/os/unix.h create mode 100644 thirdparty/linux/include/boost/predef/os/vms.h create mode 100644 thirdparty/linux/include/boost/predef/os/windows.h create mode 100644 thirdparty/linux/include/boost/predef/other.h create mode 100644 thirdparty/linux/include/boost/predef/other/endian.h create mode 100644 thirdparty/linux/include/boost/predef/platform.h create mode 100644 thirdparty/linux/include/boost/predef/platform/mingw.h create mode 100644 thirdparty/linux/include/boost/predef/platform/windows_desktop.h create mode 100644 thirdparty/linux/include/boost/predef/platform/windows_phone.h create mode 100644 thirdparty/linux/include/boost/predef/platform/windows_runtime.h create mode 100644 thirdparty/linux/include/boost/predef/platform/windows_store.h create mode 100644 thirdparty/linux/include/boost/predef/version.h create mode 100644 thirdparty/linux/include/boost/predef/version_number.h create mode 100644 thirdparty/linux/include/boost/shared_ptr.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/bad_weak_ptr.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/lightweight_mutex.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/lwm_nop.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/lwm_pthreads.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/lwm_win32_cs.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/operator_bool.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/quick_allocator.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/shared_count.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_convertible.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_impl.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_has_sync.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_interlocked.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/sp_nullptr_t.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/spinlock.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/spinlock_nt.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/spinlock_pool.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/spinlock_pt.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/spinlock_sync.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/spinlock_w32.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/detail/yield_k.hpp create mode 100644 thirdparty/linux/include/boost/smart_ptr/shared_ptr.hpp create mode 100644 thirdparty/linux/include/boost/static_assert.hpp create mode 100644 thirdparty/linux/include/boost/throw_exception.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/add_lvalue_reference.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/add_reference.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/add_rvalue_reference.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/alignment_of.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/conditional.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/declval.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/detail/config.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/detail/is_function_ptr_helper.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/detail/is_function_ptr_tester.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/detail/yes_no_type.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/integral_constant.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/intrinsics.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_abstract.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_arithmetic.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_array.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_class.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_convertible.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_enum.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_floating_point.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_function.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_integral.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_lvalue_reference.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_member_function_pointer.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_member_pointer.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_pod.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_pointer.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_polymorphic.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_reference.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_rvalue_reference.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_same.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_scalar.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_union.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_void.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/is_volatile.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/remove_cv.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/remove_reference.hpp create mode 100644 thirdparty/linux/include/boost/type_traits/type_with_alignment.hpp create mode 100644 thirdparty/linux/include/boost/version.hpp create mode 100644 thirdparty/linux/include/coin/CbcOrClpParam.cpp create mode 100644 thirdparty/linux/include/coin/CbcOrClpParam.hpp create mode 100644 thirdparty/linux/include/coin/ClpCholeskyBase.hpp create mode 100644 thirdparty/linux/include/coin/ClpCholeskyDense.hpp create mode 100644 thirdparty/linux/include/coin/ClpConfig.h create mode 100644 thirdparty/linux/include/coin/ClpConstraint.hpp create mode 100644 thirdparty/linux/include/coin/ClpConstraintLinear.hpp create mode 100644 thirdparty/linux/include/coin/ClpConstraintQuadratic.hpp create mode 100644 thirdparty/linux/include/coin/ClpDualRowDantzig.hpp create mode 100644 thirdparty/linux/include/coin/ClpDualRowPivot.hpp create mode 100644 thirdparty/linux/include/coin/ClpDualRowSteepest.hpp create mode 100644 thirdparty/linux/include/coin/ClpDummyMatrix.hpp create mode 100644 thirdparty/linux/include/coin/ClpDynamicExampleMatrix.hpp create mode 100644 thirdparty/linux/include/coin/ClpDynamicMatrix.hpp create mode 100644 thirdparty/linux/include/coin/ClpEventHandler.hpp create mode 100644 thirdparty/linux/include/coin/ClpFactorization.hpp create mode 100644 thirdparty/linux/include/coin/ClpGubDynamicMatrix.hpp create mode 100644 thirdparty/linux/include/coin/ClpGubMatrix.hpp create mode 100644 thirdparty/linux/include/coin/ClpInterior.hpp create mode 100644 thirdparty/linux/include/coin/ClpLinearObjective.hpp create mode 100644 thirdparty/linux/include/coin/ClpMatrixBase.hpp create mode 100644 thirdparty/linux/include/coin/ClpMessage.hpp create mode 100644 thirdparty/linux/include/coin/ClpModel.hpp create mode 100644 thirdparty/linux/include/coin/ClpNetworkMatrix.hpp create mode 100644 thirdparty/linux/include/coin/ClpNode.hpp create mode 100644 thirdparty/linux/include/coin/ClpNonLinearCost.hpp create mode 100644 thirdparty/linux/include/coin/ClpObjective.hpp create mode 100644 thirdparty/linux/include/coin/ClpPackedMatrix.hpp create mode 100644 thirdparty/linux/include/coin/ClpParameters.hpp create mode 100644 thirdparty/linux/include/coin/ClpPdcoBase.hpp create mode 100644 thirdparty/linux/include/coin/ClpPlusMinusOneMatrix.hpp create mode 100644 thirdparty/linux/include/coin/ClpPresolve.hpp create mode 100644 thirdparty/linux/include/coin/ClpPrimalColumnDantzig.hpp create mode 100644 thirdparty/linux/include/coin/ClpPrimalColumnPivot.hpp create mode 100644 thirdparty/linux/include/coin/ClpPrimalColumnSteepest.hpp create mode 100644 thirdparty/linux/include/coin/ClpQuadraticObjective.hpp create mode 100644 thirdparty/linux/include/coin/ClpSimplex.hpp create mode 100644 thirdparty/linux/include/coin/ClpSimplexDual.hpp create mode 100644 thirdparty/linux/include/coin/ClpSimplexNonlinear.hpp create mode 100644 thirdparty/linux/include/coin/ClpSimplexOther.hpp create mode 100644 thirdparty/linux/include/coin/ClpSimplexPrimal.hpp create mode 100644 thirdparty/linux/include/coin/ClpSolve.hpp create mode 100644 thirdparty/linux/include/coin/Clp_C_Interface.h create mode 100644 thirdparty/linux/include/coin/CoinAlloc.hpp create mode 100644 thirdparty/linux/include/coin/CoinBuild.hpp create mode 100644 thirdparty/linux/include/coin/CoinDenseFactorization.hpp create mode 100644 thirdparty/linux/include/coin/CoinDenseVector.hpp create mode 100644 thirdparty/linux/include/coin/CoinDistance.hpp create mode 100644 thirdparty/linux/include/coin/CoinError.hpp create mode 100644 thirdparty/linux/include/coin/CoinFactorization.hpp create mode 100644 thirdparty/linux/include/coin/CoinFileIO.hpp create mode 100644 thirdparty/linux/include/coin/CoinFinite.hpp create mode 100644 thirdparty/linux/include/coin/CoinFloatEqual.hpp create mode 100644 thirdparty/linux/include/coin/CoinHelperFunctions.hpp create mode 100644 thirdparty/linux/include/coin/CoinIndexedVector.hpp create mode 100644 thirdparty/linux/include/coin/CoinLpIO.hpp create mode 100644 thirdparty/linux/include/coin/CoinMessage.hpp create mode 100644 thirdparty/linux/include/coin/CoinMessageHandler.hpp create mode 100644 thirdparty/linux/include/coin/CoinModel.hpp create mode 100644 thirdparty/linux/include/coin/CoinModelUseful.hpp create mode 100644 thirdparty/linux/include/coin/CoinMpsIO.hpp create mode 100644 thirdparty/linux/include/coin/CoinOslFactorization.hpp create mode 100644 thirdparty/linux/include/coin/CoinPackedMatrix.hpp create mode 100644 thirdparty/linux/include/coin/CoinPackedVector.hpp create mode 100644 thirdparty/linux/include/coin/CoinPackedVectorBase.hpp create mode 100644 thirdparty/linux/include/coin/CoinParam.hpp create mode 100644 thirdparty/linux/include/coin/CoinPragma.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveDoubleton.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveDual.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveDupcol.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveEmpty.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveFixed.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveForcing.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveImpliedFree.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveIsolated.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveMatrix.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveMonitor.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolvePsdebug.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveSingleton.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveSubst.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveTighten.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveTripleton.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveUseless.hpp create mode 100644 thirdparty/linux/include/coin/CoinPresolveZeros.hpp create mode 100644 thirdparty/linux/include/coin/CoinRational.hpp create mode 100644 thirdparty/linux/include/coin/CoinSearchTree.hpp create mode 100644 thirdparty/linux/include/coin/CoinShallowPackedVector.hpp create mode 100644 thirdparty/linux/include/coin/CoinSignal.hpp create mode 100644 thirdparty/linux/include/coin/CoinSimpFactorization.hpp create mode 100644 thirdparty/linux/include/coin/CoinSmartPtr.hpp create mode 100644 thirdparty/linux/include/coin/CoinSnapshot.hpp create mode 100644 thirdparty/linux/include/coin/CoinSort.hpp create mode 100644 thirdparty/linux/include/coin/CoinStructuredModel.hpp create mode 100644 thirdparty/linux/include/coin/CoinTime.hpp create mode 100644 thirdparty/linux/include/coin/CoinTypes.hpp create mode 100644 thirdparty/linux/include/coin/CoinUtility.hpp create mode 100644 thirdparty/linux/include/coin/CoinUtilsConfig.h create mode 100644 thirdparty/linux/include/coin/CoinWarmStart.hpp create mode 100644 thirdparty/linux/include/coin/CoinWarmStartBasis.hpp create mode 100644 thirdparty/linux/include/coin/CoinWarmStartDual.hpp create mode 100644 thirdparty/linux/include/coin/CoinWarmStartPrimalDual.hpp create mode 100644 thirdparty/linux/include/coin/CoinWarmStartVector.hpp create mode 100644 thirdparty/linux/include/coin/Coin_C_defines.h create mode 100644 thirdparty/linux/include/coin/HSLLoader.h create mode 100644 thirdparty/linux/include/coin/Idiot.hpp create mode 100644 thirdparty/linux/include/coin/IpAlgBuilder.hpp create mode 100644 thirdparty/linux/include/coin/IpAlgStrategy.hpp create mode 100644 thirdparty/linux/include/coin/IpAlgTypes.hpp create mode 100644 thirdparty/linux/include/coin/IpAugSystemSolver.hpp create mode 100644 thirdparty/linux/include/coin/IpBlas.hpp create mode 100644 thirdparty/linux/include/coin/IpCachedResults.hpp create mode 100644 thirdparty/linux/include/coin/IpCompoundMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpCompoundSymMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpCompoundVector.hpp create mode 100644 thirdparty/linux/include/coin/IpConvCheck.hpp create mode 100644 thirdparty/linux/include/coin/IpDebug.hpp create mode 100644 thirdparty/linux/include/coin/IpDenseVector.hpp create mode 100644 thirdparty/linux/include/coin/IpDiagMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpEqMultCalculator.hpp create mode 100644 thirdparty/linux/include/coin/IpException.hpp create mode 100644 thirdparty/linux/include/coin/IpExpansionMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpGenTMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpHessianUpdater.hpp create mode 100644 thirdparty/linux/include/coin/IpIdentityMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpIpoptAlg.hpp create mode 100644 thirdparty/linux/include/coin/IpIpoptApplication.hpp create mode 100644 thirdparty/linux/include/coin/IpIpoptCalculatedQuantities.hpp create mode 100644 thirdparty/linux/include/coin/IpIpoptData.hpp create mode 100644 thirdparty/linux/include/coin/IpIpoptNLP.hpp create mode 100644 thirdparty/linux/include/coin/IpIterateInitializer.hpp create mode 100644 thirdparty/linux/include/coin/IpIteratesVector.hpp create mode 100644 thirdparty/linux/include/coin/IpIterationOutput.hpp create mode 100644 thirdparty/linux/include/coin/IpJournalist.hpp create mode 100644 thirdparty/linux/include/coin/IpLapack.hpp create mode 100644 thirdparty/linux/include/coin/IpLineSearch.hpp create mode 100644 thirdparty/linux/include/coin/IpMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpMuUpdate.hpp create mode 100644 thirdparty/linux/include/coin/IpNLP.hpp create mode 100644 thirdparty/linux/include/coin/IpNLPScaling.hpp create mode 100644 thirdparty/linux/include/coin/IpObserver.hpp create mode 100644 thirdparty/linux/include/coin/IpOptionsList.hpp create mode 100644 thirdparty/linux/include/coin/IpOrigIpoptNLP.hpp create mode 100644 thirdparty/linux/include/coin/IpPDSystemSolver.hpp create mode 100644 thirdparty/linux/include/coin/IpReferenced.hpp create mode 100644 thirdparty/linux/include/coin/IpRegOptions.hpp create mode 100644 thirdparty/linux/include/coin/IpReturnCodes.h create mode 100644 thirdparty/linux/include/coin/IpReturnCodes.hpp create mode 100644 thirdparty/linux/include/coin/IpReturnCodes.inc create mode 100644 thirdparty/linux/include/coin/IpReturnCodes_inc.h create mode 100644 thirdparty/linux/include/coin/IpScaledMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpSearchDirCalculator.hpp create mode 100644 thirdparty/linux/include/coin/IpSmartPtr.hpp create mode 100644 thirdparty/linux/include/coin/IpSolveStatistics.hpp create mode 100644 thirdparty/linux/include/coin/IpStdCInterface.h create mode 100644 thirdparty/linux/include/coin/IpSumSymMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpSymLinearSolver.hpp create mode 100644 thirdparty/linux/include/coin/IpSymMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpSymScaledMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpSymTMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpTNLP.hpp create mode 100644 thirdparty/linux/include/coin/IpTNLPAdapter.hpp create mode 100644 thirdparty/linux/include/coin/IpTNLPReducer.hpp create mode 100644 thirdparty/linux/include/coin/IpTaggedObject.hpp create mode 100644 thirdparty/linux/include/coin/IpTimedTask.hpp create mode 100644 thirdparty/linux/include/coin/IpTimingStatistics.hpp create mode 100644 thirdparty/linux/include/coin/IpTripletHelper.hpp create mode 100644 thirdparty/linux/include/coin/IpTypes.hpp create mode 100644 thirdparty/linux/include/coin/IpUtils.hpp create mode 100644 thirdparty/linux/include/coin/IpVector.hpp create mode 100644 thirdparty/linux/include/coin/IpZeroSymMatrix.hpp create mode 100644 thirdparty/linux/include/coin/IpoptConfig.h create mode 100644 thirdparty/linux/include/coin/OsiAuxInfo.hpp create mode 100644 thirdparty/linux/include/coin/OsiBranchingObject.hpp create mode 100644 thirdparty/linux/include/coin/OsiChooseVariable.hpp create mode 100644 thirdparty/linux/include/coin/OsiClpSolverInterface.hpp create mode 100644 thirdparty/linux/include/coin/OsiColCut.hpp create mode 100644 thirdparty/linux/include/coin/OsiCollections.hpp create mode 100644 thirdparty/linux/include/coin/OsiConfig.h create mode 100644 thirdparty/linux/include/coin/OsiCut.hpp create mode 100644 thirdparty/linux/include/coin/OsiCuts.hpp create mode 100644 thirdparty/linux/include/coin/OsiPresolve.hpp create mode 100644 thirdparty/linux/include/coin/OsiRowCut.hpp create mode 100644 thirdparty/linux/include/coin/OsiRowCutDebugger.hpp create mode 100644 thirdparty/linux/include/coin/OsiSolverBranch.hpp create mode 100644 thirdparty/linux/include/coin/OsiSolverInterface.hpp create mode 100644 thirdparty/linux/include/coin/OsiSolverParameters.hpp create mode 100644 thirdparty/linux/include/coin/OsiUnitTests.hpp create mode 100644 thirdparty/linux/include/coin/PardisoLoader.h create mode 100644 thirdparty/linux/include/coin/ThirdParty/dmumps_c.h create mode 100644 thirdparty/linux/include/coin/ThirdParty/mumps_c_types.h create mode 100644 thirdparty/linux/include/coin/ThirdParty/mumps_compat.h create mode 100644 thirdparty/linux/include/coin/ThirdParty/mumps_mpi.h create mode 100644 thirdparty/linux/include/gflags/gflags.h create mode 100644 thirdparty/linux/include/gflags/gflags_completions.h create mode 100644 thirdparty/linux/include/gflags/gflags_declare.h create mode 100644 thirdparty/linux/include/gflags/gflags_gflags.h create mode 100644 thirdparty/linux/include/google/protobuf/any.h create mode 100644 thirdparty/linux/include/google/protobuf/any.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/any.proto create mode 100644 thirdparty/linux/include/google/protobuf/api.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/api.proto create mode 100644 thirdparty/linux/include/google/protobuf/arena.h create mode 100644 thirdparty/linux/include/google/protobuf/arenastring.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/code_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/command_line_interface.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/cpp/cpp_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/csharp/csharp_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/csharp/csharp_names.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/importer.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/java/java_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/java/java_names.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/javanano/javanano_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/js/js_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/objectivec/objectivec_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/objectivec/objectivec_helpers.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/parser.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/plugin.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/plugin.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/plugin.proto create mode 100644 thirdparty/linux/include/google/protobuf/compiler/python/python_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/compiler/ruby/ruby_generator.h create mode 100644 thirdparty/linux/include/google/protobuf/descriptor.h create mode 100644 thirdparty/linux/include/google/protobuf/descriptor.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/descriptor.proto create mode 100644 thirdparty/linux/include/google/protobuf/descriptor_database.h create mode 100644 thirdparty/linux/include/google/protobuf/duration.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/duration.proto create mode 100644 thirdparty/linux/include/google/protobuf/dynamic_message.h create mode 100644 thirdparty/linux/include/google/protobuf/empty.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/empty.proto create mode 100644 thirdparty/linux/include/google/protobuf/extension_set.h create mode 100644 thirdparty/linux/include/google/protobuf/field_mask.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/field_mask.proto create mode 100644 thirdparty/linux/include/google/protobuf/generated_enum_reflection.h create mode 100644 thirdparty/linux/include/google/protobuf/generated_enum_util.h create mode 100644 thirdparty/linux/include/google/protobuf/generated_message_reflection.h create mode 100644 thirdparty/linux/include/google/protobuf/generated_message_util.h create mode 100644 thirdparty/linux/include/google/protobuf/io/coded_stream.h create mode 100644 thirdparty/linux/include/google/protobuf/io/gzip_stream.h create mode 100644 thirdparty/linux/include/google/protobuf/io/printer.h create mode 100644 thirdparty/linux/include/google/protobuf/io/strtod.h create mode 100644 thirdparty/linux/include/google/protobuf/io/tokenizer.h create mode 100644 thirdparty/linux/include/google/protobuf/io/zero_copy_stream.h create mode 100644 thirdparty/linux/include/google/protobuf/io/zero_copy_stream_impl.h create mode 100644 thirdparty/linux/include/google/protobuf/io/zero_copy_stream_impl_lite.h create mode 100644 thirdparty/linux/include/google/protobuf/map.h create mode 100644 thirdparty/linux/include/google/protobuf/map_entry.h create mode 100644 thirdparty/linux/include/google/protobuf/map_entry_lite.h create mode 100644 thirdparty/linux/include/google/protobuf/map_field.h create mode 100644 thirdparty/linux/include/google/protobuf/map_field_inl.h create mode 100644 thirdparty/linux/include/google/protobuf/map_field_lite.h create mode 100644 thirdparty/linux/include/google/protobuf/map_type_handler.h create mode 100644 thirdparty/linux/include/google/protobuf/message.h create mode 100644 thirdparty/linux/include/google/protobuf/message_lite.h create mode 100644 thirdparty/linux/include/google/protobuf/metadata.h create mode 100644 thirdparty/linux/include/google/protobuf/reflection.h create mode 100644 thirdparty/linux/include/google/protobuf/reflection_ops.h create mode 100644 thirdparty/linux/include/google/protobuf/repeated_field.h create mode 100644 thirdparty/linux/include/google/protobuf/service.h create mode 100644 thirdparty/linux/include/google/protobuf/source_context.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/source_context.proto create mode 100644 thirdparty/linux/include/google/protobuf/struct.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/struct.proto create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomic_sequence_num.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm64_gcc.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm_gcc.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm_qnx.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_atomicword_compat.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_generic_gcc.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_macosx.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_mips_gcc.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_pnacl.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_power.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_ppc_gcc.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_solaris.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_tsan.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_x86_gcc.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_x86_msvc.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/bytestream.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/callback.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/casts.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/common.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/fastmem.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/hash.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/logging.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/macros.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/mutex.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/once.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/platform_macros.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/port.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/scoped_ptr.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/shared_ptr.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/singleton.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/status.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/stl_util.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/stringpiece.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/template_util.h create mode 100644 thirdparty/linux/include/google/protobuf/stubs/type_traits.h create mode 100644 thirdparty/linux/include/google/protobuf/text_format.h create mode 100644 thirdparty/linux/include/google/protobuf/timestamp.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/timestamp.proto create mode 100644 thirdparty/linux/include/google/protobuf/type.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/type.proto create mode 100644 thirdparty/linux/include/google/protobuf/unknown_field_set.h create mode 100644 thirdparty/linux/include/google/protobuf/util/field_comparator.h create mode 100644 thirdparty/linux/include/google/protobuf/util/field_mask_util.h create mode 100644 thirdparty/linux/include/google/protobuf/util/json_util.h create mode 100644 thirdparty/linux/include/google/protobuf/util/message_differencer.h create mode 100644 thirdparty/linux/include/google/protobuf/util/time_util.h create mode 100644 thirdparty/linux/include/google/protobuf/util/type_resolver.h create mode 100644 thirdparty/linux/include/google/protobuf/util/type_resolver_util.h create mode 100644 thirdparty/linux/include/google/protobuf/wire_format.h create mode 100644 thirdparty/linux/include/google/protobuf/wire_format_lite.h create mode 100644 thirdparty/linux/include/google/protobuf/wire_format_lite_inl.h create mode 100644 thirdparty/linux/include/google/protobuf/wrappers.pb.h create mode 100644 thirdparty/linux/include/google/protobuf/wrappers.proto create mode 100644 thirdparty/linux/include/minotaur/AMPLHessian.h create mode 100644 thirdparty/linux/include/minotaur/AMPLInterface.h create mode 100644 thirdparty/linux/include/minotaur/AMPLJacobian.h create mode 100644 thirdparty/linux/include/minotaur/AMPLNonlinearFunction.cpp create mode 100644 thirdparty/linux/include/minotaur/ActiveNodeStore.h create mode 100644 thirdparty/linux/include/minotaur/BndProcessor.h create mode 100644 thirdparty/linux/include/minotaur/BqpdEngine.h create mode 100644 thirdparty/linux/include/minotaur/BrCand.h create mode 100644 thirdparty/linux/include/minotaur/BrVarCand.h create mode 100644 thirdparty/linux/include/minotaur/Branch.h create mode 100644 thirdparty/linux/include/minotaur/BranchAndBound.h create mode 100644 thirdparty/linux/include/minotaur/Brancher.h create mode 100644 thirdparty/linux/include/minotaur/CGraph.h create mode 100644 thirdparty/linux/include/minotaur/CNode.h create mode 100644 thirdparty/linux/include/minotaur/Constraint.h create mode 100644 thirdparty/linux/include/minotaur/CoverCutGenerator.h create mode 100644 thirdparty/linux/include/minotaur/CutInfo.h create mode 100644 thirdparty/linux/include/minotaur/CutManager.h create mode 100644 thirdparty/linux/include/minotaur/CxQuadHandler.h create mode 100644 thirdparty/linux/include/minotaur/CxUnivarHandler.h create mode 100644 thirdparty/linux/include/minotaur/Eigen.h create mode 100644 thirdparty/linux/include/minotaur/Engine.h create mode 100644 thirdparty/linux/include/minotaur/EngineFactory.h create mode 100644 thirdparty/linux/include/minotaur/Environment.h create mode 100644 thirdparty/linux/include/minotaur/Exception.h create mode 100644 thirdparty/linux/include/minotaur/FeasibilityPump.h create mode 100644 thirdparty/linux/include/minotaur/FilterSQPEngine.h create mode 100644 thirdparty/linux/include/minotaur/Function.h create mode 100644 thirdparty/linux/include/minotaur/Handler.h create mode 100644 thirdparty/linux/include/minotaur/HessianOfLag.h create mode 100644 thirdparty/linux/include/minotaur/Heuristic.h create mode 100644 thirdparty/linux/include/minotaur/IntVarHandler.h create mode 100644 thirdparty/linux/include/minotaur/Interrupt.h create mode 100644 thirdparty/linux/include/minotaur/IpoptEngine.h create mode 100644 thirdparty/linux/include/minotaur/IpoptEngineTnlp.h create mode 100644 thirdparty/linux/include/minotaur/Iterate.h create mode 100644 thirdparty/linux/include/minotaur/Jacobian.h create mode 100644 thirdparty/linux/include/minotaur/KnapCovHandler.h create mode 100644 thirdparty/linux/include/minotaur/KnapsackList.h create mode 100644 thirdparty/linux/include/minotaur/LGCIGenerator.h create mode 100644 thirdparty/linux/include/minotaur/LPEngine.h create mode 100644 thirdparty/linux/include/minotaur/LPRelaxation.h create mode 100644 thirdparty/linux/include/minotaur/LexicoBrancher.h create mode 100644 thirdparty/linux/include/minotaur/LinBil.h create mode 100644 thirdparty/linux/include/minotaur/LinConMod.h create mode 100644 thirdparty/linux/include/minotaur/LinFeasPump.h create mode 100644 thirdparty/linux/include/minotaur/LinMods.h create mode 100644 thirdparty/linux/include/minotaur/LinearCut.h create mode 100644 thirdparty/linux/include/minotaur/LinearFunction.h create mode 100644 thirdparty/linux/include/minotaur/LinearHandler.h create mode 100644 thirdparty/linux/include/minotaur/Logger.h create mode 100644 thirdparty/linux/include/minotaur/MINLPDiving.h create mode 100644 thirdparty/linux/include/minotaur/MaxFreqBrancher.h create mode 100644 thirdparty/linux/include/minotaur/MaxVioBrancher.h create mode 100644 thirdparty/linux/include/minotaur/MinotaurCFortran.h create mode 100644 thirdparty/linux/include/minotaur/MinotaurConfig.h create mode 100644 thirdparty/linux/include/minotaur/MinotaurDeconfig.h create mode 100644 thirdparty/linux/include/minotaur/Modification.h create mode 100644 thirdparty/linux/include/minotaur/MsProcessor.h create mode 100644 thirdparty/linux/include/minotaur/MultilinearTermsHandler.h create mode 100644 thirdparty/linux/include/minotaur/NLPEngine.h create mode 100644 thirdparty/linux/include/minotaur/NLPMultiStart.h create mode 100644 thirdparty/linux/include/minotaur/NLPRelaxation.h create mode 100644 thirdparty/linux/include/minotaur/NlPresHandler.h create mode 100644 thirdparty/linux/include/minotaur/Node.h create mode 100644 thirdparty/linux/include/minotaur/NodeHeap.h create mode 100644 thirdparty/linux/include/minotaur/NodeIncRelaxer.h create mode 100644 thirdparty/linux/include/minotaur/NodeProcessor.h create mode 100644 thirdparty/linux/include/minotaur/NodeRelaxer.h create mode 100644 thirdparty/linux/include/minotaur/NodeStack.h create mode 100644 thirdparty/linux/include/minotaur/NonlinearFunction.h create mode 100644 thirdparty/linux/include/minotaur/Objective.h create mode 100644 thirdparty/linux/include/minotaur/OpCode.h create mode 100644 thirdparty/linux/include/minotaur/Operations.h create mode 100644 thirdparty/linux/include/minotaur/Option.h create mode 100644 thirdparty/linux/include/minotaur/OsiLPEngine.h create mode 100644 thirdparty/linux/include/minotaur/PCBProcessor.h create mode 100644 thirdparty/linux/include/minotaur/ParBndProcessor.h create mode 100644 thirdparty/linux/include/minotaur/ParBranchAndBound.h create mode 100644 thirdparty/linux/include/minotaur/ParNodeIncRelaxer.h create mode 100644 thirdparty/linux/include/minotaur/ParTreeManager.h create mode 100644 thirdparty/linux/include/minotaur/PerspCon.h create mode 100644 thirdparty/linux/include/minotaur/PerspCutGenerator.h create mode 100644 thirdparty/linux/include/minotaur/PerspCutHandler.h create mode 100644 thirdparty/linux/include/minotaur/PolynomialFunction.h create mode 100644 thirdparty/linux/include/minotaur/PreAuxVars.h create mode 100644 thirdparty/linux/include/minotaur/PreDelVars.h create mode 100644 thirdparty/linux/include/minotaur/PreMod.h create mode 100644 thirdparty/linux/include/minotaur/PreSubstVars.h create mode 100644 thirdparty/linux/include/minotaur/Presolver.h create mode 100644 thirdparty/linux/include/minotaur/ProbStructure.h create mode 100644 thirdparty/linux/include/minotaur/Problem.h create mode 100644 thirdparty/linux/include/minotaur/ProblemSize.h create mode 100644 thirdparty/linux/include/minotaur/QGHandler.h create mode 100644 thirdparty/linux/include/minotaur/QGHandlerPDE.h create mode 100644 thirdparty/linux/include/minotaur/QPDProcessor.h create mode 100644 thirdparty/linux/include/minotaur/QPDRelaxer.h create mode 100644 thirdparty/linux/include/minotaur/QPEngine.h create mode 100644 thirdparty/linux/include/minotaur/QuadHandler.h create mode 100644 thirdparty/linux/include/minotaur/QuadraticFunction.h create mode 100644 thirdparty/linux/include/minotaur/RandomBrancher.h create mode 100644 thirdparty/linux/include/minotaur/Relaxation.h create mode 100644 thirdparty/linux/include/minotaur/ReliabilityBrancher.h create mode 100644 thirdparty/linux/include/minotaur/SOS.h create mode 100644 thirdparty/linux/include/minotaur/SOS1Handler.h create mode 100644 thirdparty/linux/include/minotaur/SOS2Handler.h create mode 100644 thirdparty/linux/include/minotaur/SOSBrCand.h create mode 100644 thirdparty/linux/include/minotaur/SecantMod.h create mode 100644 thirdparty/linux/include/minotaur/SimpleCutMan.h create mode 100644 thirdparty/linux/include/minotaur/SimpleTransformer.h create mode 100644 thirdparty/linux/include/minotaur/Solution.h create mode 100644 thirdparty/linux/include/minotaur/SolutionPool.h create mode 100644 thirdparty/linux/include/minotaur/Timer.h create mode 100644 thirdparty/linux/include/minotaur/TransPoly.h create mode 100644 thirdparty/linux/include/minotaur/TransSep.h create mode 100644 thirdparty/linux/include/minotaur/Transformer.h create mode 100644 thirdparty/linux/include/minotaur/TreeManager.h create mode 100644 thirdparty/linux/include/minotaur/Types.h create mode 100644 thirdparty/linux/include/minotaur/Variable.h create mode 100644 thirdparty/linux/include/minotaur/Version.h create mode 100644 thirdparty/linux/include/minotaur/WarmStart.h create mode 100644 thirdparty/linux/include/minotaur/YEqCGs.h create mode 100644 thirdparty/linux/include/minotaur/YEqLFs.h create mode 100644 thirdparty/linux/include/minotaur/YEqMonomial.h create mode 100644 thirdparty/linux/include/minotaur/YEqUCGs.h create mode 100644 thirdparty/linux/include/minotaur/YEqVars.h create mode 100644 thirdparty/linux/include/ortools/algorithms/dense_doubly_linked_list.h create mode 100644 thirdparty/linux/include/ortools/algorithms/dynamic_partition.h create mode 100644 thirdparty/linux/include/ortools/algorithms/dynamic_permutation.h create mode 100644 thirdparty/linux/include/ortools/algorithms/find_graph_symmetries.h create mode 100644 thirdparty/linux/include/ortools/algorithms/hungarian.h create mode 100644 thirdparty/linux/include/ortools/algorithms/knapsack_solver.h create mode 100644 thirdparty/linux/include/ortools/algorithms/sparse_permutation.h create mode 100644 thirdparty/linux/include/ortools/base/accurate_sum.h create mode 100644 thirdparty/linux/include/ortools/base/adjustable_priority_queue-inl.h create mode 100644 thirdparty/linux/include/ortools/base/adjustable_priority_queue.h create mode 100644 thirdparty/linux/include/ortools/base/basictypes.h create mode 100644 thirdparty/linux/include/ortools/base/bitmap.h create mode 100644 thirdparty/linux/include/ortools/base/callback.h create mode 100644 thirdparty/linux/include/ortools/base/casts.h create mode 100644 thirdparty/linux/include/ortools/base/cleanup.h create mode 100644 thirdparty/linux/include/ortools/base/commandlineflags.h create mode 100644 thirdparty/linux/include/ortools/base/encodingutils.h create mode 100644 thirdparty/linux/include/ortools/base/file.h create mode 100644 thirdparty/linux/include/ortools/base/filelinereader.h create mode 100644 thirdparty/linux/include/ortools/base/hash.h create mode 100755 thirdparty/linux/include/ortools/base/int_type.h create mode 100755 thirdparty/linux/include/ortools/base/int_type_indexed_vector.h create mode 100644 thirdparty/linux/include/ortools/base/integral_types.h create mode 100644 thirdparty/linux/include/ortools/base/iterator_adaptors.h create mode 100644 thirdparty/linux/include/ortools/base/jniutil.h create mode 100644 thirdparty/linux/include/ortools/base/join.h create mode 100644 thirdparty/linux/include/ortools/base/logging.h create mode 100644 thirdparty/linux/include/ortools/base/macros.h create mode 100644 thirdparty/linux/include/ortools/base/map_util.h create mode 100644 thirdparty/linux/include/ortools/base/mathutil.h create mode 100644 thirdparty/linux/include/ortools/base/murmur.h create mode 100644 thirdparty/linux/include/ortools/base/mutex.h create mode 100644 thirdparty/linux/include/ortools/base/numbers.h create mode 100644 thirdparty/linux/include/ortools/base/port.h create mode 100644 thirdparty/linux/include/ortools/base/python-swig.h create mode 100644 thirdparty/linux/include/ortools/base/random.h create mode 100644 thirdparty/linux/include/ortools/base/recordio.h create mode 100644 thirdparty/linux/include/ortools/base/small_map.h create mode 100644 thirdparty/linux/include/ortools/base/small_ordered_set.h create mode 100644 thirdparty/linux/include/ortools/base/sparsetable.h create mode 100644 thirdparty/linux/include/ortools/base/split.h create mode 100644 thirdparty/linux/include/ortools/base/status.h create mode 100644 thirdparty/linux/include/ortools/base/statusor.h create mode 100644 thirdparty/linux/include/ortools/base/stl_util.h create mode 100644 thirdparty/linux/include/ortools/base/stringpiece.h create mode 100644 thirdparty/linux/include/ortools/base/stringpiece_utils.h create mode 100644 thirdparty/linux/include/ortools/base/stringprintf.h create mode 100644 thirdparty/linux/include/ortools/base/strongly_connected_components.h create mode 100644 thirdparty/linux/include/ortools/base/strtoint.h create mode 100644 thirdparty/linux/include/ortools/base/strutil.h create mode 100644 thirdparty/linux/include/ortools/base/synchronization.h create mode 100644 thirdparty/linux/include/ortools/base/sysinfo.h create mode 100644 thirdparty/linux/include/ortools/base/thorough_hash.h create mode 100644 thirdparty/linux/include/ortools/base/threadpool.h create mode 100644 thirdparty/linux/include/ortools/base/time_support.h create mode 100644 thirdparty/linux/include/ortools/base/timer.h create mode 100644 thirdparty/linux/include/ortools/base/typeid.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_base.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_fs.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_lns.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_ls.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_parameters.pb.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_portfolio.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_solution.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_solver.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_types.h create mode 100644 thirdparty/linux/include/ortools/bop/bop_util.h create mode 100644 thirdparty/linux/include/ortools/bop/complete_optimizer.h create mode 100644 thirdparty/linux/include/ortools/bop/integral_solver.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/assignment.pb.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/constraint_solver.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/constraint_solveri.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/demon_profiler.pb.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/hybrid.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/model.pb.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/routing.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/routing_enums.pb.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/routing_flags.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/routing_neighborhoods.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/routing_parameters.pb.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/routing_types.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/sat_constraint.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/search_limit.pb.h create mode 100644 thirdparty/linux/include/ortools/constraint_solver/solver_parameters.pb.h create mode 100644 thirdparty/linux/include/ortools/glop/basis_representation.h create mode 100644 thirdparty/linux/include/ortools/glop/dual_edge_norms.h create mode 100644 thirdparty/linux/include/ortools/glop/entering_variable.h create mode 100644 thirdparty/linux/include/ortools/glop/initial_basis.h create mode 100644 thirdparty/linux/include/ortools/glop/lp_solver.h create mode 100644 thirdparty/linux/include/ortools/glop/lu_factorization.h create mode 100644 thirdparty/linux/include/ortools/glop/markowitz.h create mode 100644 thirdparty/linux/include/ortools/glop/parameters.pb.h create mode 100644 thirdparty/linux/include/ortools/glop/preprocessor.h create mode 100644 thirdparty/linux/include/ortools/glop/primal_edge_norms.h create mode 100644 thirdparty/linux/include/ortools/glop/rank_one_update.h create mode 100644 thirdparty/linux/include/ortools/glop/reduced_costs.h create mode 100644 thirdparty/linux/include/ortools/glop/revised_simplex.h create mode 100644 thirdparty/linux/include/ortools/glop/status.h create mode 100644 thirdparty/linux/include/ortools/glop/update_row.h create mode 100644 thirdparty/linux/include/ortools/glop/variable_values.h create mode 100644 thirdparty/linux/include/ortools/glop/variables_info.h create mode 100644 thirdparty/linux/include/ortools/graph/assignment.h create mode 100644 thirdparty/linux/include/ortools/graph/christofides.h create mode 100644 thirdparty/linux/include/ortools/graph/cliques.h create mode 100644 thirdparty/linux/include/ortools/graph/connectivity.h create mode 100644 thirdparty/linux/include/ortools/graph/ebert_graph.h create mode 100644 thirdparty/linux/include/ortools/graph/eulerian_path.h create mode 100644 thirdparty/linux/include/ortools/graph/flow_problem.pb.h create mode 100644 thirdparty/linux/include/ortools/graph/graph.h create mode 100644 thirdparty/linux/include/ortools/graph/graphs.h create mode 100644 thirdparty/linux/include/ortools/graph/hamiltonian_path.h create mode 100644 thirdparty/linux/include/ortools/graph/io.h create mode 100644 thirdparty/linux/include/ortools/graph/linear_assignment.h create mode 100644 thirdparty/linux/include/ortools/graph/max_flow.h create mode 100644 thirdparty/linux/include/ortools/graph/min_cost_flow.h create mode 100644 thirdparty/linux/include/ortools/graph/minimum_spanning_tree.h create mode 100644 thirdparty/linux/include/ortools/graph/one_tree_lower_bound.h create mode 100644 thirdparty/linux/include/ortools/graph/shortestpaths.h create mode 100644 thirdparty/linux/include/ortools/graph/util.h create mode 100644 thirdparty/linux/include/ortools/linear_solver/glop_utils.h create mode 100644 thirdparty/linux/include/ortools/linear_solver/linear_expr.h create mode 100644 thirdparty/linux/include/ortools/linear_solver/linear_solver.h create mode 100644 thirdparty/linux/include/ortools/linear_solver/linear_solver.pb.h create mode 100644 thirdparty/linux/include/ortools/linear_solver/model_exporter.h create mode 100644 thirdparty/linux/include/ortools/linear_solver/model_validator.h create mode 100644 thirdparty/linux/include/ortools/sat/boolean_problem.h create mode 100644 thirdparty/linux/include/ortools/sat/boolean_problem.pb.h create mode 100644 thirdparty/linux/include/ortools/sat/clause.h create mode 100644 thirdparty/linux/include/ortools/sat/cp_constraints.h create mode 100644 thirdparty/linux/include/ortools/sat/cumulative.h create mode 100644 thirdparty/linux/include/ortools/sat/disjunctive.h create mode 100644 thirdparty/linux/include/ortools/sat/drat.h create mode 100644 thirdparty/linux/include/ortools/sat/encoding.h create mode 100644 thirdparty/linux/include/ortools/sat/flow_costs.h create mode 100644 thirdparty/linux/include/ortools/sat/integer.h create mode 100644 thirdparty/linux/include/ortools/sat/integer_expr.h create mode 100644 thirdparty/linux/include/ortools/sat/intervals.h create mode 100644 thirdparty/linux/include/ortools/sat/linear_programming_constraint.h create mode 100644 thirdparty/linux/include/ortools/sat/lp_utils.h create mode 100644 thirdparty/linux/include/ortools/sat/model.h create mode 100644 thirdparty/linux/include/ortools/sat/no_cycle.h create mode 100644 thirdparty/linux/include/ortools/sat/optimization.h create mode 100644 thirdparty/linux/include/ortools/sat/overload_checker.h create mode 100644 thirdparty/linux/include/ortools/sat/pb_constraint.h create mode 100644 thirdparty/linux/include/ortools/sat/precedences.h create mode 100644 thirdparty/linux/include/ortools/sat/sat_base.h create mode 100644 thirdparty/linux/include/ortools/sat/sat_parameters.pb.h create mode 100644 thirdparty/linux/include/ortools/sat/sat_solver.h create mode 100644 thirdparty/linux/include/ortools/sat/simplification.h create mode 100644 thirdparty/linux/include/ortools/sat/symmetry.h create mode 100644 thirdparty/linux/include/ortools/sat/table.h create mode 100644 thirdparty/linux/include/ortools/sat/theta_tree.h create mode 100644 thirdparty/linux/include/ortools/sat/timetable.h create mode 100644 thirdparty/linux/include/ortools/sat/timetable_edgefinding.h create mode 100644 thirdparty/linux/include/ortools/sat/util.h create mode 100644 thirdparty/linux/include/ortools/util/bitset.h create mode 100644 thirdparty/linux/include/ortools/util/cached_log.h create mode 100644 thirdparty/linux/include/ortools/util/filelineiter.h create mode 100644 thirdparty/linux/include/ortools/util/fp_utils.h create mode 100644 thirdparty/linux/include/ortools/util/functions_swig_helpers.h create mode 100644 thirdparty/linux/include/ortools/util/functions_swig_test_helpers.h create mode 100644 thirdparty/linux/include/ortools/util/graph_export.h create mode 100644 thirdparty/linux/include/ortools/util/iterators.h create mode 100644 thirdparty/linux/include/ortools/util/monoid_operation_tree.h create mode 100644 thirdparty/linux/include/ortools/util/permutation.h create mode 100644 thirdparty/linux/include/ortools/util/piecewise_linear_function.h create mode 100644 thirdparty/linux/include/ortools/util/proto_tools.h create mode 100644 thirdparty/linux/include/ortools/util/range_minimum_query.h create mode 100644 thirdparty/linux/include/ortools/util/range_query_function.h create mode 100644 thirdparty/linux/include/ortools/util/rational_approximation.h create mode 100644 thirdparty/linux/include/ortools/util/rcpsp_parser.h create mode 100644 thirdparty/linux/include/ortools/util/return_macros.h create mode 100644 thirdparty/linux/include/ortools/util/rev.h create mode 100644 thirdparty/linux/include/ortools/util/running_stat.h create mode 100644 thirdparty/linux/include/ortools/util/saturated_arithmetic.h create mode 100644 thirdparty/linux/include/ortools/util/sort.h create mode 100644 thirdparty/linux/include/ortools/util/sorted_interval_list.h create mode 100644 thirdparty/linux/include/ortools/util/stats.h create mode 100644 thirdparty/linux/include/ortools/util/string_array.h create mode 100644 thirdparty/linux/include/ortools/util/time_limit.h create mode 100644 thirdparty/linux/include/ortools/util/tuple_set.h create mode 100644 thirdparty/linux/include/ortools/util/vector_map.h create mode 100644 thirdparty/linux/include/ortools/util/vector_or_function.h create mode 100644 thirdparty/linux/include/ortools/util/xml_helper.h create mode 100644 thirdparty/linux/include/ortools/util/zvector.h create mode 120000 thirdparty/linux/lib/x64/libClp.so create mode 120000 thirdparty/linux/lib/x64/libClp.so.1 create mode 100755 thirdparty/linux/lib/x64/libClp.so.1.13.9 create mode 120000 thirdparty/linux/lib/x64/libClpSolver.so create mode 120000 thirdparty/linux/lib/x64/libClpSolver.so.1 create mode 100755 thirdparty/linux/lib/x64/libClpSolver.so.1.13.9 create mode 120000 thirdparty/linux/lib/x64/libCoinUtils.so create mode 120000 thirdparty/linux/lib/x64/libCoinUtils.so.3 create mode 100755 thirdparty/linux/lib/x64/libCoinUtils.so.3.10.11 create mode 120000 thirdparty/linux/lib/x64/libOsi.so create mode 120000 thirdparty/linux/lib/x64/libOsi.so.1 create mode 100755 thirdparty/linux/lib/x64/libOsi.so.1.12.6 create mode 120000 thirdparty/linux/lib/x64/libOsiClp.so create mode 120000 thirdparty/linux/lib/x64/libOsiClp.so.1 create mode 100755 thirdparty/linux/lib/x64/libOsiClp.so.1.13.9 create mode 120000 thirdparty/linux/lib/x64/libcoinmumps.so create mode 120000 thirdparty/linux/lib/x64/libcoinmumps.so.1 create mode 100755 thirdparty/linux/lib/x64/libcoinmumps.so.1.6.0 create mode 100755 thirdparty/linux/lib/x64/libcvrptw_lib.so create mode 100755 thirdparty/linux/lib/x64/libdimacs.so create mode 100755 thirdparty/linux/lib/x64/libfap.so create mode 120000 thirdparty/linux/lib/x64/libipopt.so create mode 120000 thirdparty/linux/lib/x64/libipopt.so.1 create mode 100755 thirdparty/linux/lib/x64/libipopt.so.1.10.7 create mode 100755 thirdparty/linux/lib/x64/libjniortools.so create mode 100644 thirdparty/linux/lib/x64/libminotaur.so create mode 100644 thirdparty/linux/lib/x64/libmntrengfac.so create mode 100644 thirdparty/linux/lib/x64/libmntripopt.so create mode 100644 thirdparty/linux/lib/x64/libmntrosilp.so create mode 100755 thirdparty/linux/lib/x64/libortools.so create mode 100644 thirdparty/windows/include/boost/assert.hpp create mode 100644 thirdparty/windows/include/boost/checked_delete.hpp create mode 100644 thirdparty/windows/include/boost/config.hpp create mode 100644 thirdparty/windows/include/boost/config/abi/borland_prefix.hpp create mode 100644 thirdparty/windows/include/boost/config/abi/borland_suffix.hpp create mode 100644 thirdparty/windows/include/boost/config/abi/msvc_prefix.hpp create mode 100644 thirdparty/windows/include/boost/config/abi/msvc_suffix.hpp create mode 100644 thirdparty/windows/include/boost/config/abi_prefix.hpp create mode 100644 thirdparty/windows/include/boost/config/abi_suffix.hpp create mode 100644 thirdparty/windows/include/boost/config/auto_link.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/borland.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/clang.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/codegear.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/comeau.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/common_edg.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/compaq_cxx.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/cray.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/digitalmars.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/gcc.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/gcc_xml.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/greenhills.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/hp_acc.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/intel.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/kai.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/metrowerks.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/mpw.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/nvcc.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/pathscale.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/pgi.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/sgi_mipspro.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/sunpro_cc.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/vacpp.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/visualc.hpp create mode 100644 thirdparty/windows/include/boost/config/compiler/xlcpp.hpp create mode 100644 thirdparty/windows/include/boost/config/no_tr1/cmath.hpp create mode 100644 thirdparty/windows/include/boost/config/no_tr1/complex.hpp create mode 100644 thirdparty/windows/include/boost/config/no_tr1/functional.hpp create mode 100644 thirdparty/windows/include/boost/config/no_tr1/memory.hpp create mode 100644 thirdparty/windows/include/boost/config/no_tr1/utility.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/aix.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/amigaos.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/beos.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/bsd.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/cloudabi.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/cray.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/cygwin.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/haiku.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/hpux.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/irix.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/linux.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/macos.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/qnxnto.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/solaris.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/symbian.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/vms.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/vxworks.hpp create mode 100644 thirdparty/windows/include/boost/config/platform/win32.hpp create mode 100644 thirdparty/windows/include/boost/config/posix_features.hpp create mode 100644 thirdparty/windows/include/boost/config/requires_threads.hpp create mode 100644 thirdparty/windows/include/boost/config/select_compiler_config.hpp create mode 100644 thirdparty/windows/include/boost/config/select_platform_config.hpp create mode 100644 thirdparty/windows/include/boost/config/select_stdlib_config.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/dinkumware.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/libcomo.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/libcpp.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/libstdcpp3.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/modena.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/msl.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/roguewave.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/sgi.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/stlport.hpp create mode 100644 thirdparty/windows/include/boost/config/stdlib/vacpp.hpp create mode 100644 thirdparty/windows/include/boost/config/suffix.hpp create mode 100644 thirdparty/windows/include/boost/config/user.hpp create mode 100644 thirdparty/windows/include/boost/config/warning_disable.hpp create mode 100644 thirdparty/windows/include/boost/core/addressof.hpp create mode 100644 thirdparty/windows/include/boost/core/checked_delete.hpp create mode 100644 thirdparty/windows/include/boost/core/demangle.hpp create mode 100644 thirdparty/windows/include/boost/core/typeinfo.hpp create mode 100644 thirdparty/windows/include/boost/cstdint.hpp create mode 100644 thirdparty/windows/include/boost/current_function.hpp create mode 100644 thirdparty/windows/include/boost/detail/lightweight_mutex.hpp create mode 100644 thirdparty/windows/include/boost/detail/sp_typeinfo.hpp create mode 100644 thirdparty/windows/include/boost/detail/workaround.hpp create mode 100644 thirdparty/windows/include/boost/exception/exception.hpp create mode 100644 thirdparty/windows/include/boost/limits.hpp create mode 100644 thirdparty/windows/include/boost/predef.h create mode 100644 thirdparty/windows/include/boost/predef/architecture.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/alpha.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/arm.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/blackfin.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/convex.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/ia64.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/m68k.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/mips.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/parisc.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/ppc.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/pyramid.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/rs6k.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/sparc.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/superh.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/sys370.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/sys390.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/x86.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/x86/32.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/x86/64.h create mode 100644 thirdparty/windows/include/boost/predef/architecture/z.h create mode 100644 thirdparty/windows/include/boost/predef/compiler.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/borland.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/clang.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/comeau.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/compaq.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/diab.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/digitalmars.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/dignus.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/edg.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/ekopath.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/gcc.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/gcc_xml.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/greenhills.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/hp_acc.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/iar.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/ibm.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/intel.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/kai.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/llvm.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/metaware.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/metrowerks.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/microtec.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/mpw.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/palm.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/pgi.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/sgi_mipspro.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/sunpro.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/tendra.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/visualc.h create mode 100644 thirdparty/windows/include/boost/predef/compiler/watcom.h create mode 100644 thirdparty/windows/include/boost/predef/detail/_cassert.h create mode 100644 thirdparty/windows/include/boost/predef/detail/_exception.h create mode 100644 thirdparty/windows/include/boost/predef/detail/comp_detected.h create mode 100644 thirdparty/windows/include/boost/predef/detail/os_detected.h create mode 100644 thirdparty/windows/include/boost/predef/detail/platform_detected.h create mode 100644 thirdparty/windows/include/boost/predef/detail/test.h create mode 100644 thirdparty/windows/include/boost/predef/hardware.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd/arm.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd/arm/versions.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd/ppc.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd/ppc/versions.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd/x86.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd/x86/versions.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd/x86_amd.h create mode 100644 thirdparty/windows/include/boost/predef/hardware/simd/x86_amd/versions.h create mode 100644 thirdparty/windows/include/boost/predef/language.h create mode 100644 thirdparty/windows/include/boost/predef/language/objc.h create mode 100644 thirdparty/windows/include/boost/predef/language/stdc.h create mode 100644 thirdparty/windows/include/boost/predef/language/stdcpp.h create mode 100644 thirdparty/windows/include/boost/predef/library.h create mode 100644 thirdparty/windows/include/boost/predef/library/c.h create mode 100644 thirdparty/windows/include/boost/predef/library/c/_prefix.h create mode 100644 thirdparty/windows/include/boost/predef/library/c/gnu.h create mode 100644 thirdparty/windows/include/boost/predef/library/c/uc.h create mode 100644 thirdparty/windows/include/boost/predef/library/c/vms.h create mode 100644 thirdparty/windows/include/boost/predef/library/c/zos.h create mode 100644 thirdparty/windows/include/boost/predef/library/std.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/_prefix.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/cxx.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/dinkumware.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/libcomo.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/modena.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/msl.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/roguewave.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/sgi.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/stdcpp3.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/stlport.h create mode 100644 thirdparty/windows/include/boost/predef/library/std/vacpp.h create mode 100644 thirdparty/windows/include/boost/predef/make.h create mode 100644 thirdparty/windows/include/boost/predef/os.h create mode 100644 thirdparty/windows/include/boost/predef/os/aix.h create mode 100644 thirdparty/windows/include/boost/predef/os/amigaos.h create mode 100644 thirdparty/windows/include/boost/predef/os/android.h create mode 100644 thirdparty/windows/include/boost/predef/os/beos.h create mode 100644 thirdparty/windows/include/boost/predef/os/bsd.h create mode 100644 thirdparty/windows/include/boost/predef/os/bsd/bsdi.h create mode 100644 thirdparty/windows/include/boost/predef/os/bsd/dragonfly.h create mode 100644 thirdparty/windows/include/boost/predef/os/bsd/free.h create mode 100644 thirdparty/windows/include/boost/predef/os/bsd/net.h create mode 100644 thirdparty/windows/include/boost/predef/os/bsd/open.h create mode 100644 thirdparty/windows/include/boost/predef/os/cygwin.h create mode 100644 thirdparty/windows/include/boost/predef/os/haiku.h create mode 100644 thirdparty/windows/include/boost/predef/os/hpux.h create mode 100644 thirdparty/windows/include/boost/predef/os/ios.h create mode 100644 thirdparty/windows/include/boost/predef/os/irix.h create mode 100644 thirdparty/windows/include/boost/predef/os/linux.h create mode 100644 thirdparty/windows/include/boost/predef/os/macos.h create mode 100644 thirdparty/windows/include/boost/predef/os/os400.h create mode 100644 thirdparty/windows/include/boost/predef/os/qnxnto.h create mode 100644 thirdparty/windows/include/boost/predef/os/solaris.h create mode 100644 thirdparty/windows/include/boost/predef/os/unix.h create mode 100644 thirdparty/windows/include/boost/predef/os/vms.h create mode 100644 thirdparty/windows/include/boost/predef/os/windows.h create mode 100644 thirdparty/windows/include/boost/predef/other.h create mode 100644 thirdparty/windows/include/boost/predef/other/endian.h create mode 100644 thirdparty/windows/include/boost/predef/platform.h create mode 100644 thirdparty/windows/include/boost/predef/platform/mingw.h create mode 100644 thirdparty/windows/include/boost/predef/platform/windows_desktop.h create mode 100644 thirdparty/windows/include/boost/predef/platform/windows_phone.h create mode 100644 thirdparty/windows/include/boost/predef/platform/windows_runtime.h create mode 100644 thirdparty/windows/include/boost/predef/platform/windows_store.h create mode 100644 thirdparty/windows/include/boost/predef/version.h create mode 100644 thirdparty/windows/include/boost/predef/version_number.h create mode 100644 thirdparty/windows/include/boost/shared_ptr.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/bad_weak_ptr.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/lightweight_mutex.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/lwm_nop.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/lwm_pthreads.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/lwm_win32_cs.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/operator_bool.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/quick_allocator.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/shared_count.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_convertible.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_counted_impl.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_has_sync.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_interlocked.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/sp_nullptr_t.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/spinlock.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/spinlock_nt.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/spinlock_pool.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/spinlock_pt.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/spinlock_sync.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/spinlock_w32.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/detail/yield_k.hpp create mode 100644 thirdparty/windows/include/boost/smart_ptr/shared_ptr.hpp create mode 100644 thirdparty/windows/include/boost/static_assert.hpp create mode 100644 thirdparty/windows/include/boost/throw_exception.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/add_lvalue_reference.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/add_reference.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/add_rvalue_reference.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/alignment_of.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/conditional.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/declval.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/detail/config.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/detail/is_function_ptr_helper.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/detail/is_function_ptr_tester.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/detail/yes_no_type.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/integral_constant.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/intrinsics.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_abstract.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_arithmetic.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_array.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_class.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_convertible.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_enum.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_floating_point.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_function.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_integral.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_lvalue_reference.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_member_function_pointer.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_member_pointer.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_pod.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_pointer.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_polymorphic.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_reference.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_rvalue_reference.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_same.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_scalar.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_union.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_void.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/is_volatile.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/remove_cv.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/remove_reference.hpp create mode 100644 thirdparty/windows/include/boost/type_traits/type_with_alignment.hpp create mode 100644 thirdparty/windows/include/boost/version.hpp create mode 100644 thirdparty/windows/include/coin/CbcOrClpParam.cpp create mode 100644 thirdparty/windows/include/coin/CbcOrClpParam.hpp create mode 100644 thirdparty/windows/include/coin/ClpCholeskyBase.hpp create mode 100644 thirdparty/windows/include/coin/ClpCholeskyDense.hpp create mode 100644 thirdparty/windows/include/coin/ClpConfig.h create mode 100644 thirdparty/windows/include/coin/ClpConstraint.hpp create mode 100644 thirdparty/windows/include/coin/ClpConstraintLinear.hpp create mode 100644 thirdparty/windows/include/coin/ClpConstraintQuadratic.hpp create mode 100644 thirdparty/windows/include/coin/ClpDualRowDantzig.hpp create mode 100644 thirdparty/windows/include/coin/ClpDualRowPivot.hpp create mode 100644 thirdparty/windows/include/coin/ClpDualRowSteepest.hpp create mode 100644 thirdparty/windows/include/coin/ClpDummyMatrix.hpp create mode 100644 thirdparty/windows/include/coin/ClpDynamicExampleMatrix.hpp create mode 100644 thirdparty/windows/include/coin/ClpDynamicMatrix.hpp create mode 100644 thirdparty/windows/include/coin/ClpEventHandler.hpp create mode 100644 thirdparty/windows/include/coin/ClpFactorization.hpp create mode 100644 thirdparty/windows/include/coin/ClpGubDynamicMatrix.hpp create mode 100644 thirdparty/windows/include/coin/ClpGubMatrix.hpp create mode 100644 thirdparty/windows/include/coin/ClpInterior.hpp create mode 100644 thirdparty/windows/include/coin/ClpLinearObjective.hpp create mode 100644 thirdparty/windows/include/coin/ClpMatrixBase.hpp create mode 100644 thirdparty/windows/include/coin/ClpMessage.hpp create mode 100644 thirdparty/windows/include/coin/ClpModel.hpp create mode 100644 thirdparty/windows/include/coin/ClpNetworkMatrix.hpp create mode 100644 thirdparty/windows/include/coin/ClpNode.hpp create mode 100644 thirdparty/windows/include/coin/ClpNonLinearCost.hpp create mode 100644 thirdparty/windows/include/coin/ClpObjective.hpp create mode 100644 thirdparty/windows/include/coin/ClpPackedMatrix.hpp create mode 100644 thirdparty/windows/include/coin/ClpParameters.hpp create mode 100644 thirdparty/windows/include/coin/ClpPdcoBase.hpp create mode 100644 thirdparty/windows/include/coin/ClpPlusMinusOneMatrix.hpp create mode 100644 thirdparty/windows/include/coin/ClpPresolve.hpp create mode 100644 thirdparty/windows/include/coin/ClpPrimalColumnDantzig.hpp create mode 100644 thirdparty/windows/include/coin/ClpPrimalColumnPivot.hpp create mode 100644 thirdparty/windows/include/coin/ClpPrimalColumnSteepest.hpp create mode 100644 thirdparty/windows/include/coin/ClpQuadraticObjective.hpp create mode 100644 thirdparty/windows/include/coin/ClpSimplex.hpp create mode 100644 thirdparty/windows/include/coin/ClpSimplexDual.hpp create mode 100644 thirdparty/windows/include/coin/ClpSimplexNonlinear.hpp create mode 100644 thirdparty/windows/include/coin/ClpSimplexOther.hpp create mode 100644 thirdparty/windows/include/coin/ClpSimplexPrimal.hpp create mode 100644 thirdparty/windows/include/coin/ClpSolve.hpp create mode 100644 thirdparty/windows/include/coin/Clp_C_Interface.h create mode 100644 thirdparty/windows/include/coin/CoinAlloc.hpp create mode 100644 thirdparty/windows/include/coin/CoinBuild.hpp create mode 100644 thirdparty/windows/include/coin/CoinDenseFactorization.hpp create mode 100644 thirdparty/windows/include/coin/CoinDenseVector.hpp create mode 100644 thirdparty/windows/include/coin/CoinDistance.hpp create mode 100644 thirdparty/windows/include/coin/CoinError.hpp create mode 100644 thirdparty/windows/include/coin/CoinFactorization.hpp create mode 100644 thirdparty/windows/include/coin/CoinFileIO.hpp create mode 100644 thirdparty/windows/include/coin/CoinFinite.hpp create mode 100644 thirdparty/windows/include/coin/CoinFloatEqual.hpp create mode 100644 thirdparty/windows/include/coin/CoinHelperFunctions.hpp create mode 100644 thirdparty/windows/include/coin/CoinIndexedVector.hpp create mode 100644 thirdparty/windows/include/coin/CoinLpIO.hpp create mode 100644 thirdparty/windows/include/coin/CoinMessage.hpp create mode 100644 thirdparty/windows/include/coin/CoinMessageHandler.hpp create mode 100644 thirdparty/windows/include/coin/CoinModel.hpp create mode 100644 thirdparty/windows/include/coin/CoinModelUseful.hpp create mode 100644 thirdparty/windows/include/coin/CoinMpsIO.hpp create mode 100644 thirdparty/windows/include/coin/CoinOslFactorization.hpp create mode 100644 thirdparty/windows/include/coin/CoinPackedMatrix.hpp create mode 100644 thirdparty/windows/include/coin/CoinPackedVector.hpp create mode 100644 thirdparty/windows/include/coin/CoinPackedVectorBase.hpp create mode 100644 thirdparty/windows/include/coin/CoinParam.hpp create mode 100644 thirdparty/windows/include/coin/CoinPragma.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveDoubleton.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveDual.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveDupcol.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveEmpty.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveFixed.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveForcing.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveImpliedFree.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveIsolated.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveMatrix.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveMonitor.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolvePsdebug.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveSingleton.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveSubst.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveTighten.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveTripleton.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveUseless.hpp create mode 100644 thirdparty/windows/include/coin/CoinPresolveZeros.hpp create mode 100644 thirdparty/windows/include/coin/CoinRational.hpp create mode 100644 thirdparty/windows/include/coin/CoinSearchTree.hpp create mode 100644 thirdparty/windows/include/coin/CoinShallowPackedVector.hpp create mode 100644 thirdparty/windows/include/coin/CoinSignal.hpp create mode 100644 thirdparty/windows/include/coin/CoinSimpFactorization.hpp create mode 100644 thirdparty/windows/include/coin/CoinSmartPtr.hpp create mode 100644 thirdparty/windows/include/coin/CoinSnapshot.hpp create mode 100644 thirdparty/windows/include/coin/CoinSort.hpp create mode 100644 thirdparty/windows/include/coin/CoinStructuredModel.hpp create mode 100644 thirdparty/windows/include/coin/CoinTime.hpp create mode 100644 thirdparty/windows/include/coin/CoinTypes.hpp create mode 100644 thirdparty/windows/include/coin/CoinUtility.hpp create mode 100644 thirdparty/windows/include/coin/CoinUtilsConfig.h create mode 100644 thirdparty/windows/include/coin/CoinWarmStart.hpp create mode 100644 thirdparty/windows/include/coin/CoinWarmStartBasis.hpp create mode 100644 thirdparty/windows/include/coin/CoinWarmStartDual.hpp create mode 100644 thirdparty/windows/include/coin/CoinWarmStartPrimalDual.hpp create mode 100644 thirdparty/windows/include/coin/CoinWarmStartVector.hpp create mode 100644 thirdparty/windows/include/coin/Coin_C_defines.h create mode 100644 thirdparty/windows/include/coin/HSLLoader.h create mode 100644 thirdparty/windows/include/coin/Idiot.hpp create mode 100644 thirdparty/windows/include/coin/IpAlgBuilder.hpp create mode 100644 thirdparty/windows/include/coin/IpAlgStrategy.hpp create mode 100644 thirdparty/windows/include/coin/IpAlgTypes.hpp create mode 100644 thirdparty/windows/include/coin/IpAugSystemSolver.hpp create mode 100644 thirdparty/windows/include/coin/IpBlas.hpp create mode 100644 thirdparty/windows/include/coin/IpCachedResults.hpp create mode 100644 thirdparty/windows/include/coin/IpCompoundMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpCompoundSymMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpCompoundVector.hpp create mode 100644 thirdparty/windows/include/coin/IpConvCheck.hpp create mode 100644 thirdparty/windows/include/coin/IpDebug.hpp create mode 100644 thirdparty/windows/include/coin/IpDenseVector.hpp create mode 100644 thirdparty/windows/include/coin/IpDiagMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpEqMultCalculator.hpp create mode 100644 thirdparty/windows/include/coin/IpException.hpp create mode 100644 thirdparty/windows/include/coin/IpExpansionMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpGenTMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpHessianUpdater.hpp create mode 100644 thirdparty/windows/include/coin/IpIdentityMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpIpoptAlg.hpp create mode 100644 thirdparty/windows/include/coin/IpIpoptApplication.hpp create mode 100644 thirdparty/windows/include/coin/IpIpoptCalculatedQuantities.hpp create mode 100644 thirdparty/windows/include/coin/IpIpoptData.hpp create mode 100644 thirdparty/windows/include/coin/IpIpoptNLP.hpp create mode 100644 thirdparty/windows/include/coin/IpIterateInitializer.hpp create mode 100644 thirdparty/windows/include/coin/IpIteratesVector.hpp create mode 100644 thirdparty/windows/include/coin/IpIterationOutput.hpp create mode 100644 thirdparty/windows/include/coin/IpJournalist.hpp create mode 100644 thirdparty/windows/include/coin/IpLapack.hpp create mode 100644 thirdparty/windows/include/coin/IpLineSearch.hpp create mode 100644 thirdparty/windows/include/coin/IpMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpMuUpdate.hpp create mode 100644 thirdparty/windows/include/coin/IpNLP.hpp create mode 100644 thirdparty/windows/include/coin/IpNLPScaling.hpp create mode 100644 thirdparty/windows/include/coin/IpObserver.hpp create mode 100644 thirdparty/windows/include/coin/IpOptionsList.hpp create mode 100644 thirdparty/windows/include/coin/IpOrigIpoptNLP.hpp create mode 100644 thirdparty/windows/include/coin/IpPDSystemSolver.hpp create mode 100644 thirdparty/windows/include/coin/IpReferenced.hpp create mode 100644 thirdparty/windows/include/coin/IpRegOptions.hpp create mode 100644 thirdparty/windows/include/coin/IpReturnCodes.h create mode 100644 thirdparty/windows/include/coin/IpReturnCodes.hpp create mode 100644 thirdparty/windows/include/coin/IpReturnCodes.inc create mode 100644 thirdparty/windows/include/coin/IpReturnCodes_inc.h create mode 100644 thirdparty/windows/include/coin/IpScaledMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpSearchDirCalculator.hpp create mode 100644 thirdparty/windows/include/coin/IpSmartPtr.hpp create mode 100644 thirdparty/windows/include/coin/IpSolveStatistics.hpp create mode 100644 thirdparty/windows/include/coin/IpStdCInterface.h create mode 100644 thirdparty/windows/include/coin/IpSumSymMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpSymLinearSolver.hpp create mode 100644 thirdparty/windows/include/coin/IpSymMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpSymScaledMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpSymTMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpTNLP.hpp create mode 100644 thirdparty/windows/include/coin/IpTNLPAdapter.hpp create mode 100644 thirdparty/windows/include/coin/IpTNLPReducer.hpp create mode 100644 thirdparty/windows/include/coin/IpTaggedObject.hpp create mode 100644 thirdparty/windows/include/coin/IpTimedTask.hpp create mode 100644 thirdparty/windows/include/coin/IpTimingStatistics.hpp create mode 100644 thirdparty/windows/include/coin/IpTripletHelper.hpp create mode 100644 thirdparty/windows/include/coin/IpTypes.hpp create mode 100644 thirdparty/windows/include/coin/IpUtils.hpp create mode 100644 thirdparty/windows/include/coin/IpVector.hpp create mode 100644 thirdparty/windows/include/coin/IpZeroSymMatrix.hpp create mode 100644 thirdparty/windows/include/coin/IpoptConfig.h create mode 100644 thirdparty/windows/include/coin/OsiAuxInfo.hpp create mode 100644 thirdparty/windows/include/coin/OsiBranchingObject.hpp create mode 100644 thirdparty/windows/include/coin/OsiChooseVariable.hpp create mode 100644 thirdparty/windows/include/coin/OsiClpSolverInterface.hpp create mode 100644 thirdparty/windows/include/coin/OsiColCut.hpp create mode 100644 thirdparty/windows/include/coin/OsiCollections.hpp create mode 100644 thirdparty/windows/include/coin/OsiConfig.h create mode 100644 thirdparty/windows/include/coin/OsiCut.hpp create mode 100644 thirdparty/windows/include/coin/OsiCuts.hpp create mode 100644 thirdparty/windows/include/coin/OsiPresolve.hpp create mode 100644 thirdparty/windows/include/coin/OsiRowCut.hpp create mode 100644 thirdparty/windows/include/coin/OsiRowCutDebugger.hpp create mode 100644 thirdparty/windows/include/coin/OsiSolverBranch.hpp create mode 100644 thirdparty/windows/include/coin/OsiSolverInterface.hpp create mode 100644 thirdparty/windows/include/coin/OsiSolverParameters.hpp create mode 100644 thirdparty/windows/include/coin/OsiUnitTests.hpp create mode 100644 thirdparty/windows/include/coin/PardisoLoader.h create mode 100644 thirdparty/windows/include/coin/ThirdParty/dmumps_c.h create mode 100644 thirdparty/windows/include/coin/ThirdParty/mumps_c_types.h create mode 100644 thirdparty/windows/include/coin/ThirdParty/mumps_compat.h create mode 100644 thirdparty/windows/include/coin/ThirdParty/mumps_mpi.h create mode 100644 thirdparty/windows/include/minotaur/AMPLHessian.h create mode 100644 thirdparty/windows/include/minotaur/AMPLInterface.h create mode 100644 thirdparty/windows/include/minotaur/AMPLJacobian.h create mode 100644 thirdparty/windows/include/minotaur/AMPLNonlinearFunction.cpp create mode 100644 thirdparty/windows/include/minotaur/ActiveNodeStore.h create mode 100644 thirdparty/windows/include/minotaur/BndProcessor.h create mode 100644 thirdparty/windows/include/minotaur/BqpdEngine.h create mode 100644 thirdparty/windows/include/minotaur/BrCand.h create mode 100644 thirdparty/windows/include/minotaur/BrVarCand.h create mode 100644 thirdparty/windows/include/minotaur/Branch.h create mode 100644 thirdparty/windows/include/minotaur/BranchAndBound.h create mode 100644 thirdparty/windows/include/minotaur/Brancher.h create mode 100644 thirdparty/windows/include/minotaur/CGraph.h create mode 100644 thirdparty/windows/include/minotaur/CNode.h create mode 100644 thirdparty/windows/include/minotaur/Constraint.h create mode 100644 thirdparty/windows/include/minotaur/CoverCutGenerator.h create mode 100644 thirdparty/windows/include/minotaur/CutInfo.h create mode 100644 thirdparty/windows/include/minotaur/CutManager.h create mode 100644 thirdparty/windows/include/minotaur/CxQuadHandler.h create mode 100644 thirdparty/windows/include/minotaur/CxUnivarHandler.h create mode 100644 thirdparty/windows/include/minotaur/Eigen.h create mode 100644 thirdparty/windows/include/minotaur/Engine.h create mode 100644 thirdparty/windows/include/minotaur/EngineFactory.h create mode 100644 thirdparty/windows/include/minotaur/Environment.h create mode 100644 thirdparty/windows/include/minotaur/Exception.h create mode 100644 thirdparty/windows/include/minotaur/FeasibilityPump.h create mode 100644 thirdparty/windows/include/minotaur/FilterSQPEngine.h create mode 100644 thirdparty/windows/include/minotaur/Function.h create mode 100644 thirdparty/windows/include/minotaur/Handler.h create mode 100644 thirdparty/windows/include/minotaur/HessianOfLag.h create mode 100644 thirdparty/windows/include/minotaur/Heuristic.h create mode 100644 thirdparty/windows/include/minotaur/IntVarHandler.h create mode 100644 thirdparty/windows/include/minotaur/Interrupt.h create mode 100644 thirdparty/windows/include/minotaur/IpoptEngine.h create mode 100644 thirdparty/windows/include/minotaur/IpoptEngineTnlp.h create mode 100644 thirdparty/windows/include/minotaur/Iterate.h create mode 100644 thirdparty/windows/include/minotaur/Jacobian.h create mode 100644 thirdparty/windows/include/minotaur/KnapCovHandler.h create mode 100644 thirdparty/windows/include/minotaur/KnapsackList.h create mode 100644 thirdparty/windows/include/minotaur/LGCIGenerator.h create mode 100644 thirdparty/windows/include/minotaur/LPEngine.h create mode 100644 thirdparty/windows/include/minotaur/LPRelaxation.h create mode 100644 thirdparty/windows/include/minotaur/LexicoBrancher.h create mode 100644 thirdparty/windows/include/minotaur/LinBil.h create mode 100644 thirdparty/windows/include/minotaur/LinConMod.h create mode 100644 thirdparty/windows/include/minotaur/LinFeasPump.h create mode 100644 thirdparty/windows/include/minotaur/LinMods.h create mode 100644 thirdparty/windows/include/minotaur/LinearCut.h create mode 100644 thirdparty/windows/include/minotaur/LinearFunction.h create mode 100644 thirdparty/windows/include/minotaur/LinearHandler.h create mode 100644 thirdparty/windows/include/minotaur/Logger.h create mode 100644 thirdparty/windows/include/minotaur/MINLPDiving.h create mode 100644 thirdparty/windows/include/minotaur/MaxFreqBrancher.h create mode 100644 thirdparty/windows/include/minotaur/MaxVioBrancher.h create mode 100644 thirdparty/windows/include/minotaur/MinotaurCFortran.h create mode 100644 thirdparty/windows/include/minotaur/MinotaurConfig.h create mode 100644 thirdparty/windows/include/minotaur/MinotaurDeconfig.h create mode 100644 thirdparty/windows/include/minotaur/Modification.h create mode 100644 thirdparty/windows/include/minotaur/MsProcessor.h create mode 100644 thirdparty/windows/include/minotaur/MultilinearTermsHandler.h create mode 100644 thirdparty/windows/include/minotaur/NLPEngine.h create mode 100644 thirdparty/windows/include/minotaur/NLPMultiStart.h create mode 100644 thirdparty/windows/include/minotaur/NLPRelaxation.h create mode 100644 thirdparty/windows/include/minotaur/NlPresHandler.h create mode 100644 thirdparty/windows/include/minotaur/Node.h create mode 100644 thirdparty/windows/include/minotaur/NodeHeap.h create mode 100644 thirdparty/windows/include/minotaur/NodeIncRelaxer.h create mode 100644 thirdparty/windows/include/minotaur/NodeProcessor.h create mode 100644 thirdparty/windows/include/minotaur/NodeRelaxer.h create mode 100644 thirdparty/windows/include/minotaur/NodeStack.h create mode 100644 thirdparty/windows/include/minotaur/NonlinearFunction.h create mode 100644 thirdparty/windows/include/minotaur/Objective.h create mode 100644 thirdparty/windows/include/minotaur/OpCode.h create mode 100644 thirdparty/windows/include/minotaur/Operations.h create mode 100644 thirdparty/windows/include/minotaur/Option.h create mode 100644 thirdparty/windows/include/minotaur/OsiLPEngine.h create mode 100644 thirdparty/windows/include/minotaur/PCBProcessor.h create mode 100644 thirdparty/windows/include/minotaur/ParBndProcessor.h create mode 100644 thirdparty/windows/include/minotaur/ParBranchAndBound.h create mode 100644 thirdparty/windows/include/minotaur/ParNodeIncRelaxer.h create mode 100644 thirdparty/windows/include/minotaur/ParTreeManager.h create mode 100644 thirdparty/windows/include/minotaur/PerspCon.h create mode 100644 thirdparty/windows/include/minotaur/PerspCutGenerator.h create mode 100644 thirdparty/windows/include/minotaur/PerspCutHandler.h create mode 100644 thirdparty/windows/include/minotaur/PolynomialFunction.h create mode 100644 thirdparty/windows/include/minotaur/PreAuxVars.h create mode 100644 thirdparty/windows/include/minotaur/PreDelVars.h create mode 100644 thirdparty/windows/include/minotaur/PreMod.h create mode 100644 thirdparty/windows/include/minotaur/PreSubstVars.h create mode 100644 thirdparty/windows/include/minotaur/Presolver.h create mode 100644 thirdparty/windows/include/minotaur/ProbStructure.h create mode 100644 thirdparty/windows/include/minotaur/Problem.h create mode 100644 thirdparty/windows/include/minotaur/ProblemSize.h create mode 100644 thirdparty/windows/include/minotaur/QGHandler.h create mode 100644 thirdparty/windows/include/minotaur/QGHandlerPDE.h create mode 100644 thirdparty/windows/include/minotaur/QPDProcessor.h create mode 100644 thirdparty/windows/include/minotaur/QPDRelaxer.h create mode 100644 thirdparty/windows/include/minotaur/QPEngine.h create mode 100644 thirdparty/windows/include/minotaur/QuadHandler.h create mode 100644 thirdparty/windows/include/minotaur/QuadraticFunction.h create mode 100644 thirdparty/windows/include/minotaur/RandomBrancher.h create mode 100644 thirdparty/windows/include/minotaur/Relaxation.h create mode 100644 thirdparty/windows/include/minotaur/ReliabilityBrancher.h create mode 100644 thirdparty/windows/include/minotaur/SOS.h create mode 100644 thirdparty/windows/include/minotaur/SOS1Handler.h create mode 100644 thirdparty/windows/include/minotaur/SOS2Handler.h create mode 100644 thirdparty/windows/include/minotaur/SOSBrCand.h create mode 100644 thirdparty/windows/include/minotaur/SecantMod.h create mode 100644 thirdparty/windows/include/minotaur/SimpleCutMan.h create mode 100644 thirdparty/windows/include/minotaur/SimpleTransformer.h create mode 100644 thirdparty/windows/include/minotaur/Solution.h create mode 100644 thirdparty/windows/include/minotaur/SolutionPool.h create mode 100644 thirdparty/windows/include/minotaur/Timer.h create mode 100644 thirdparty/windows/include/minotaur/TransPoly.h create mode 100644 thirdparty/windows/include/minotaur/TransSep.h create mode 100644 thirdparty/windows/include/minotaur/Transformer.h create mode 100644 thirdparty/windows/include/minotaur/TreeManager.h create mode 100644 thirdparty/windows/include/minotaur/Types.h create mode 100644 thirdparty/windows/include/minotaur/Variable.h create mode 100644 thirdparty/windows/include/minotaur/Version.h create mode 100644 thirdparty/windows/include/minotaur/WarmStart.h create mode 100644 thirdparty/windows/include/minotaur/YEqCGs.h create mode 100644 thirdparty/windows/include/minotaur/YEqLFs.h create mode 100644 thirdparty/windows/include/minotaur/YEqMonomial.h create mode 100644 thirdparty/windows/include/minotaur/YEqUCGs.h create mode 100644 thirdparty/windows/include/minotaur/YEqVars.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6382fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# +# Generated files +# +loader.sce +unloader.sce +cleaner.sce +loader_gateway.sce +cleaner_gateway.sce +jar/ +*.dll +*.so +*.def +*.obj +*.bin +libOptimization_Toolbox_*.* +macros/lib +Makelib.mak +master_help.xml +scilab_*_help +*.sln +*.vcxproj +*.vcxproj.filters +*.vfproj +locales/en_US/ +locales/fr_FR/ diff --git a/LICENSE_BOOST.txt b/LICENSE_BOOST.txt new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/LICENSE_BOOST.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/LICENSE_Clp.txt b/LICENSE_Clp.txt new file mode 100644 index 0000000..b6be057 --- /dev/null +++ b/LICENSE_Clp.txt @@ -0,0 +1,3 @@ +For licensing information for files in this directory, please see the +comments in the header of each file. For licensing of files in each of +the subdirectories, please see the LICENSE file in that subdirectory. diff --git a/LICENSE_CoinUtils.txt b/LICENSE_CoinUtils.txt new file mode 100644 index 0000000..744d6f3 --- /dev/null +++ b/LICENSE_CoinUtils.txt @@ -0,0 +1,239 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE +PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION +OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate + from and are distributed by that particular Contributor. A + Contribution 'originates' from a Contributor if it was added to + the Program by such Contributor itself or anyone acting on such + Contributor's behalf. Contributions do not include additions to + the Program which: (i) are separate modules of software + distributed in conjunction with the Program under their own + license agreement, and (ii) are not derivative works of the + Program. + +"Contributor" means any person or entity that distributes the +Program. + +"Licensed Patents" mean patent claims licensable by a Contributor +which are necessarily infringed by the use or sale of its +Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with +this Agreement. + +"Recipient" means anyone who receives the Program under this +Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free copyright +license to reproduce, prepare derivative works of, publicly display, +publicly perform, distribute and sublicense the Contribution of such +Contributor, if any, and such derivative works, in source code and +object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free patent +license under Licensed Patents to make, use, sell, offer to sell, +import and otherwise transfer the Contribution of such Contributor, +if any, in source code and object code form. This patent license +shall apply to the combination of the Contribution and the Program +if, at the time the Contribution is added by the Contributor, such +addition of the Contribution causes such combination to be covered +by the Licensed Patents. The patent license shall not apply to any +other combinations which include the Contribution. No hardware per +se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the +licenses to its Contributions set forth herein, no assurances are +provided by any Contributor that the Program does not infringe the +patent or other intellectual property rights of any other +entity. Each Contributor disclaims any liability to Recipient for +claims brought by any other entity based on infringement of +intellectual property rights or otherwise. As a condition to +exercising the rights and licenses granted hereunder, each Recipient +hereby assumes sole responsibility to secure any other intellectual +property rights needed, if any. For example, if a third party patent +license is required to allow Recipient to distribute the Program, it +is Recipient's responsibility to acquire that license before +distributing the Program. + +d) Each Contributor represents that to its knowledge it has +sufficient copyright rights in its Contribution, if any, to grant +the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code +form under its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; + and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and + fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) states that any provisions which differ from this + Agreement are offered by that Contributor alone and not by + any other party; and + + iv) states that source code for the Program is available + from such Contributor, and informs licensees how to obtain + it in a reasonable manner on or through a medium customarily + used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of + the Program. + +Contributors may not remove or alter any copyright notices contained +within the Program. + +Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent +Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain +responsibilities with respect to end users, business partners and +the like. While this license is intended to facilitate the +commercial use of the Program, the Contributor who includes the +Program in a commercial product offering should do so in a manner +which does not create potential liability for other +Contributors. Therefore, if a Contributor includes the Program in a +commercial product offering, such Contributor ("Commercial +Contributor") hereby agrees to defend and indemnify every other +Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and +other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the +Program in a commercial product offering. The obligations in this +section do not apply to any claims or Losses relating to any actual +or alleged intellectual property infringement. In order to qualify, +an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial +Contributor to control, and cooperate with the Commercial +Contributor in, the defense and any related settlement +negotiations. The Indemnified Contributor may participate in any +such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's +responsibility alone. Under this section, the Commercial Contributor +would have to defend claims against the other Contributors related +to those performance claims and warranties, and if a court requires +any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS +PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, +ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient +is solely responsible for determining the appropriateness of using +and distributing the Program and assumes all risks associated with +its exercise of rights under this Agreement , including but not +limited to the risks and costs of program errors, compliance with +applicable laws, damage to or loss of data, programs or equipment, +and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT +NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability +of the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to +the minimum extent necessary to make such provision valid and +enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that +the Program itself (excluding combinations of the Program with other +software or hardware) infringes such Recipient's patent(s), then +such Recipient's rights granted under Section 2(b) shall terminate +as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably +practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall +continue and survive. + +Everyone is permitted to copy and distribute copies of this +Agreement, but in order to avoid inconsistency the Agreement is +copyrighted and may only be modified in the following manner. The +Agreement Steward reserves the right to publish new versions +(including revisions) of this Agreement from time to time. No one +other than the Agreement Steward has the right to modify this +Agreement. The Eclipse Foundation is the initial Agreement +Steward. The Eclipse Foundation may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each +new version of the Agreement will be given a distinguishing version +number. The Program (including Contributions) may always be +distributed subject to the version of the Agreement under which it +was received. In addition, after a new version of the Agreement is +published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as +expressly stated in Sections 2(a) and 2(b) above, Recipient receives +no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly +granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and +the intellectual property laws of the United States of America. No +party to this Agreement will bring a legal action under this +Agreement more than one year after the cause of action arose. Each +party waives its rights to a jury trial in any resulting litigation. diff --git a/LICENSE_Ipopt.txt b/LICENSE_Ipopt.txt new file mode 100644 index 0000000..16cc69a --- /dev/null +++ b/LICENSE_Ipopt.txt @@ -0,0 +1,87 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and + +b) in the case of each subsequent Contributor: + +i) changes to the Program, and + +ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. + +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and + +b) its license agreement: + +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; + +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; + +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and + +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and + +b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. diff --git a/LICENSE_MUMPS.txt b/LICENSE_MUMPS.txt new file mode 100644 index 0000000..5512849 --- /dev/null +++ b/LICENSE_MUMPS.txt @@ -0,0 +1,44 @@ + + This version of MUMPS is provided to you free of charge. It is public + domain, based on public domain software developed during the Esprit IV + European project PARASOL (1996-1999). Since this first public domain + version in 1999, research and developments have been supported by the + following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + INRIA, and University of Bordeaux. + + The MUMPS team at the moment of releasing this version includes + Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + Ucar and Clement Weisbecker. + + We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + have been contributing to this project. + + Up-to-date copies of the MUMPS package can be obtained + from the Web pages: + http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + + + THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + + + User documentation of any code that uses this software can + include this complete notice. You can acknowledge (using + references [1] and [2]) the contribution of this package + in any scientific publication dependent upon the use of the + package. You shall use reasonable endeavours to notify + the authors of the package of this publication. + + [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + A fully asynchronous multifrontal solver using distributed dynamic + scheduling, SIAM Journal of Matrix Analysis and Applications, + Vol 23, No 1, pp 15-41 (2001). + + [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + S. Pralet, Hybrid scheduling for the parallel solution of linear + systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + diff --git a/LICENSE_ORTOOLS.txt b/LICENSE_ORTOOLS.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE_ORTOOLS.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE_Osi.txt b/LICENSE_Osi.txt new file mode 100644 index 0000000..744d6f3 --- /dev/null +++ b/LICENSE_Osi.txt @@ -0,0 +1,239 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE +PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION +OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate + from and are distributed by that particular Contributor. A + Contribution 'originates' from a Contributor if it was added to + the Program by such Contributor itself or anyone acting on such + Contributor's behalf. Contributions do not include additions to + the Program which: (i) are separate modules of software + distributed in conjunction with the Program under their own + license agreement, and (ii) are not derivative works of the + Program. + +"Contributor" means any person or entity that distributes the +Program. + +"Licensed Patents" mean patent claims licensable by a Contributor +which are necessarily infringed by the use or sale of its +Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with +this Agreement. + +"Recipient" means anyone who receives the Program under this +Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free copyright +license to reproduce, prepare derivative works of, publicly display, +publicly perform, distribute and sublicense the Contribution of such +Contributor, if any, and such derivative works, in source code and +object code form. + +b) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free patent +license under Licensed Patents to make, use, sell, offer to sell, +import and otherwise transfer the Contribution of such Contributor, +if any, in source code and object code form. This patent license +shall apply to the combination of the Contribution and the Program +if, at the time the Contribution is added by the Contributor, such +addition of the Contribution causes such combination to be covered +by the Licensed Patents. The patent license shall not apply to any +other combinations which include the Contribution. No hardware per +se is licensed hereunder. + +c) Recipient understands that although each Contributor grants the +licenses to its Contributions set forth herein, no assurances are +provided by any Contributor that the Program does not infringe the +patent or other intellectual property rights of any other +entity. Each Contributor disclaims any liability to Recipient for +claims brought by any other entity based on infringement of +intellectual property rights or otherwise. As a condition to +exercising the rights and licenses granted hereunder, each Recipient +hereby assumes sole responsibility to secure any other intellectual +property rights needed, if any. For example, if a third party patent +license is required to allow Recipient to distribute the Program, it +is Recipient's responsibility to acquire that license before +distributing the Program. + +d) Each Contributor represents that to its knowledge it has +sufficient copyright rights in its Contribution, if any, to grant +the copyright license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code +form under its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; + and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and + fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) states that any provisions which differ from this + Agreement are offered by that Contributor alone and not by + any other party; and + + iv) states that source code for the Program is available + from such Contributor, and informs licensees how to obtain + it in a reasonable manner on or through a medium customarily + used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of + the Program. + +Contributors may not remove or alter any copyright notices contained +within the Program. + +Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent +Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain +responsibilities with respect to end users, business partners and +the like. While this license is intended to facilitate the +commercial use of the Program, the Contributor who includes the +Program in a commercial product offering should do so in a manner +which does not create potential liability for other +Contributors. Therefore, if a Contributor includes the Program in a +commercial product offering, such Contributor ("Commercial +Contributor") hereby agrees to defend and indemnify every other +Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and +other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the +Program in a commercial product offering. The obligations in this +section do not apply to any claims or Losses relating to any actual +or alleged intellectual property infringement. In order to qualify, +an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial +Contributor to control, and cooperate with the Commercial +Contributor in, the defense and any related settlement +negotiations. The Indemnified Contributor may participate in any +such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's +responsibility alone. Under this section, the Commercial Contributor +would have to defend claims against the other Contributors related +to those performance claims and warranties, and if a court requires +any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS +PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, +ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient +is solely responsible for determining the appropriateness of using +and distributing the Program and assumes all risks associated with +its exercise of rights under this Agreement , including but not +limited to the risks and costs of program errors, compliance with +applicable laws, damage to or loss of data, programs or equipment, +and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT +NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability +of the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to +the minimum extent necessary to make such provision valid and +enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that +the Program itself (excluding combinations of the Program with other +software or hardware) infringes such Recipient's patent(s), then +such Recipient's rights granted under Section 2(b) shall terminate +as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably +practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall +continue and survive. + +Everyone is permitted to copy and distribute copies of this +Agreement, but in order to avoid inconsistency the Agreement is +copyrighted and may only be modified in the following manner. The +Agreement Steward reserves the right to publish new versions +(including revisions) of this Agreement from time to time. No one +other than the Agreement Steward has the right to modify this +Agreement. The Eclipse Foundation is the initial Agreement +Steward. The Eclipse Foundation may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each +new version of the Agreement will be given a distinguishing version +number. The Program (including Contributions) may always be +distributed subject to the version of the Agreement under which it +was received. In addition, after a new version of the Agreement is +published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as +expressly stated in Sections 2(a) and 2(b) above, Recipient receives +no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly +granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and +the intellectual property laws of the United States of America. No +party to this Agreement will bring a legal action under this +Agreement more than one year after the cause of action arose. Each +party waives its rights to a jury trial in any resulting litigation. diff --git a/builder.sce b/builder.sce new file mode 100644 index 0000000..a1e8336 --- /dev/null +++ b/builder.sce @@ -0,0 +1,55 @@ +verboseMode = ilib_verbose(); +ilib_verbose(0); + +TOOLBOX_NAME = "Optimization_Toolbox"; +TOOLBOX_TITLE = "Optimization Toolbox"; + +function main_builder() + + toolbox_dir = get_absolute_file_path("builder.sce"); + + // Check Scilab version + try + v = getversion("scilab"); + catch + error(gettext("Scilab 5.3 or more is required.")); + end + if v(1) < 5 & v(2) < 3 then + // new API in scilab 5.3 + error(gettext("Scilab 5.3 or more is required.")); + end + + // Check modules_manager module availability + if ~isdef("tbx_build_loader") then + error(msprintf(gettext("%s module not installed."), "modules_manager")); + end + + // Build Macros, Source and Gateway + tbx_builder_macros(toolbox_dir); + // tbx_builder_src(toolbox_dir); + tbx_builder_gateway(toolbox_dir); + + // Clear old Help & Demo files + fmnames = mopen("macros" + filesep() + "names", "r"); + mnames = mgetl(fmnames); + for i = 1:size(mnames, "r") + mdelete("help" + filesep() + "en_US" + filesep() + mnames(i) + ".xml"); + mdelete("demos" + filesep() + mnames(i) + ".dem.sce"); + end + mclose(fmnames); + + // Generate and Build Help + help_from_sci("macros", "help" + filesep() + "en_US", "demos"); + tbx_builder_help(toolbox_dir); + + // Build Loader & Cleaner + tbx_build_loader(TOOLBOX_NAME, toolbox_dir); + tbx_build_cleaner(TOOLBOX_NAME, toolbox_dir); + +endfunction + +main_builder(); + +ilib_verbose(verboseMode); + +clear main_builder, TOOLBOX_NAME, TOOLBOX_TITLE, verboseMode; diff --git a/demos/Checkdims.dem.sce b/demos/Checkdims.dem.sce new file mode 100644 index 0000000..cc330cf --- /dev/null +++ b/demos/Checkdims.dem.sce @@ -0,0 +1,19 @@ +mode(1) +// +// Demo of Checkdims.sci +// + +// The function takes a 2 x 3 matrix of doubles. +function y = myfunction ( x ) +Checkdims ( "myfunction" , x , "x" , 1 , [2 3] ) +y = x +endfunction +// Calling sequences which work +y = myfunction ( ones(2,3) ) +y = myfunction ( zeros(2,3) ) +// Calling sequences which generate an error +y = myfunction ( ones(1,3) ) +y = myfunction ( zeros(2,4) ) +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/Checklhs.dem.sce b/demos/Checklhs.dem.sce new file mode 100644 index 0000000..d8af9e6 --- /dev/null +++ b/demos/Checklhs.dem.sce @@ -0,0 +1,48 @@ +mode(1) +// +// Demo of Checklhs.sci +// + +// The function takes 3 input arguments and 1/2 output arguments +function varargout = myfunction ( x1 , x2 , x3 ) +[lhs, rhs] = argn() +Checkrhs ( "myfunction" , rhs , 3 : 3 ) +Checklhs ( "myfunction" , lhs , 1 : 2 ) +y1 = x1 + x2 +y2 = x2 + x3 +varargout(1) = y1 +if ( lhs == 2 ) then +varargout(2) = y2 +end +endfunction +// Calling sequences which work +myfunction ( 1 , 2 , 3 ) +y1 = myfunction ( 1 , 2 , 3 ) +[ y1 , y2 ] = myfunction ( 1 , 2 , 3 ) +// Calling sequences which generate an error +[ y1 , y2 , y3 ] = myfunction ( 1 , 2 , 3 ) +halt() // Press return to continue + +// The function takes 1 or 3 output arguments, but not 2 +function varargout = myfunction ( x1 , x2 , x3 ) +[lhs, rhs] = argn() +Checkrhs ( "myfunction" , rhs , 3 : 3 ) +Checklhs ( "myfunction" , lhs , [1 3] ) +y1 = x1 + x2 +y2 = x2 + x3 +y3 = x1 + x3 +varargout(1) = y1 +if ( lhs == 3 ) then +varargout(2) = y2 +varargout(3) = y3 +end +endfunction +// Calling sequences which work +myfunction ( 1 , 2 , 3 ) +y1 = myfunction ( 1 , 2 , 3 ) +[ y1 , y2 , y3 ] = myfunction ( 1 , 2 , 3 ) +// Calling sequences which generate an error +[y1 , y2] = myfunction ( 1 , 2 , 3 ) +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/Checkrhs.dem.sce b/demos/Checkrhs.dem.sce new file mode 100644 index 0000000..c0f3967 --- /dev/null +++ b/demos/Checkrhs.dem.sce @@ -0,0 +1,72 @@ +mode(1) +// +// Demo of Checkrhs.sci +// + +// The function takes 2/3 input arguments and 1 output arguments +function y = myfunction ( varargin ) +[lhs, rhs] = argn() +Checkrhs ( "myfunction" , rhs , 2:3 ) +Checklhs ( "myfunction" , lhs , 1 ) +x1 = varargin(1) +x2 = varargin(2) +if ( rhs >= 3 ) then +x3 = varargin(3) +else +x3 = 2 +end +y = x1 + x2 + x3 +endfunction +// Calling sequences which work +y = myfunction ( 1 , 2 ) +y = myfunction ( 1 , 2 , 3 ) +// Calling sequences which generate an error +y = myfunction ( 1 ) +y = myfunction ( 1 , 2 , 3 , 4 ) +halt() // Press return to continue + +// The function takes 2 or 4 input arguments, but not 3 +function y = myfunction ( varargin ) +[lhs, rhs] = argn() +Checkrhs ( "myfunction" , rhs , [2 4] ) +Checklhs ( "myfunction" , lhs , 1 ) +x1 = varargin(1) +x2 = varargin(2) +if ( rhs >= 3 ) then +x3 = varargin(3) +x4 = varargin(4) +else +x3 = 2 +x4 = 3 +end +y = x1 + x2 + x3 + x4 +endfunction +// Calling sequences which work +y = myfunction ( 1 , 2 ) +y = myfunction ( 1 , 2 , 3 , 4 ) +// Calling sequences which generate an error +y = myfunction ( 1 ) +y = myfunction ( 1 , 2 , 3 ) +y = myfunction ( 1 , 2 , 3 , 4, 5 ) +halt() // Press return to continue + +// The function takes 2 input arguments and 0/1 output arguments. +// Notice that if the checkrhs function is not called, +// the variable x2 might be used from the user's context, +// that is, if the caller has defined the variable x2, it +// is used in the callee. +// Here, we want to avoid this. +function y = myfunction ( x1 , x2 ) +[lhs, rhs] = argn() +Checkrhs ( "myfunction" , rhs , 2 ) +Checklhs ( "myfunction" , lhs , [0 1] ) +y = x1 + x2 +endfunction +// Calling sequences which work +y = myfunction ( 1 , 2 ) +// Calling sequences which generate an error +y = myfunction ( 1 ) +y = myfunction ( 1 , 2 , 3 ) +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/Checktype.dem.sce b/demos/Checktype.dem.sce new file mode 100644 index 0000000..76a5edd --- /dev/null +++ b/demos/Checktype.dem.sce @@ -0,0 +1,33 @@ +mode(1) +// +// Demo of Checktype.sci +// + +// The function takes a string argument. +function myfunction ( x ) +Checktype ( "myfunction" , x , "x" , 1 , "string" ) +disp("This is a string") +endfunction +// Calling sequences which work +myfunction ( "Scilab" ) +// Calling sequences which generate an error +myfunction ( 123456 ) +halt() // Press return to continue + +// The function takes a string or a matrix of doubles argument. +function myfunction ( x ) +Checktype ( "myfunction" , x , "x" , 1 , [ "string" "constant" ] ) +if ( typeof(x) == "string" ) then +disp("This is a matrix of strings") +else +disp("This is a matrix of doubles") +end +endfunction +// Calling sequences which work +myfunction ( "Scilab" ) +myfunction ( 123456 ) +// Calling sequences which generate an error +myfunction ( uint8(2) ) +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/Checkvector.dem.sce b/demos/Checkvector.dem.sce new file mode 100644 index 0000000..689802e --- /dev/null +++ b/demos/Checkvector.dem.sce @@ -0,0 +1,22 @@ +mode(1) +// +// Demo of Checkvector.sci +// + +// The function takes a vector of 3 doubles. +function y = myfunction ( x ) +Checkvector ( "myfunction" , x , "x" , 1 , 3 ) +y = x +endfunction +// Calling sequences which work +y = myfunction ( ones(1,3) ) +y = myfunction ( zeros(3,1) ) +// Calling sequences which generate an error +// The following are not vectors +y = myfunction ( ones(2,3) ) +y = myfunction ( zeros(3,2) ) +// The following have the wrong number of entries +y = myfunction ( ones(1,3) ) +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/Filterdims.dem.sce b/demos/Filterdims.dem.sce new file mode 100644 index 0000000..a14d7d6 --- /dev/null +++ b/demos/Filterdims.dem.sce @@ -0,0 +1,19 @@ +mode(1) +// +// Demo of Filterdims.sci +// + +// The function takes a 2 x 3 matrix of doubles. +function y = myfunction ( x ) +Filterdims ( "myfunction" , x , "x" , 1 , [2 3] ) +y = x +endfunction +// Calling sequences which work +y = myfunction ( ones(2,3) ) +y = myfunction ( zeros(2,3) ) +// Calling sequences which generate an error +y = myfunction ( ones(1,3) ) +y = myfunction ( zeros(2,4) ) +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/Optimization_Toolbox.dem.gateway.sce b/demos/Optimization_Toolbox.dem.gateway.sce new file mode 100644 index 0000000..b33d2c4 --- /dev/null +++ b/demos/Optimization_Toolbox.dem.gateway.sce @@ -0,0 +1,13 @@ +function subdemolist = demo_gateway() + + demopath = get_absolute_file_path(TOOLBOX_NAME + ".dem.gateway.sce"); + + subdemolist = ["qcqpglob", "qcqpglob.dem.sce"]; + + subdemolist(:,2) = demopath + subdemolist(:,2); + +endfunction + +subdemolist = demo_gateway(); + +clear demo_gateway; diff --git a/demos/fmaxflow.dem.sce b/demos/fmaxflow.dem.sce new file mode 100644 index 0000000..bc44661 --- /dev/null +++ b/demos/fmaxflow.dem.sce @@ -0,0 +1,76 @@ +mode(1) +// +// Demo of fmaxflow.sci +// + +halt() // Press return to continue + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3] +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4] +capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20] +st=[0,4] +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st) +// Press Enter to continue +//Output +//Max flow = 60 +//Arc Flow Capacity +//0->1 20 20 +//0->2 30 30 +//0->3 10 10 +//1->2 0 40 +//1->4 20 30 +//2->3 10 10 +//2->4 20 20 +//3->2 0 5 +//3->4 20 20 +halt() // Press return to continue + +//An optimal solution was found +// status = +// +// 0 +// arcflows = +// +// 20 30 10 0 20 10 20 0 20 +// maxflow = +// +// 60 +halt() // Press return to continue + +halt() // Press return to continue + +halt() // Press return to continue + +start_nodes = [1, 1, 2, 2, 3, 3, 0] +end_nodes = [2, 4, 3, 4, 2, 4, 5] +capacities = [40, 30, 10, 20, 5, 20, 50] +st=[0,4] +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st) +//Press Enter to continue +// Output +// Max flow = 0 +//Arc Flow Capacity +//1->2 0 40 +//1->4 0 30 +//2->3 0 10 +//2->4 0 20 +//3->2 0 5 +//3->4 0 20 +//0->5 0 50 +halt() // Press return to continue + +//There is no path connecting the specified source node : 0 and the specified target node : 4 +// status = +// +// 0 +// arcflows = +// +// [] +// maxflow = +// +// 0 +halt() // Press return to continue + +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/fshortestpath.dem.sce b/demos/fshortestpath.dem.sce new file mode 100644 index 0000000..93d4b4b --- /dev/null +++ b/demos/fshortestpath.dem.sce @@ -0,0 +1,64 @@ +mode(1) +// +// Demo of fshortestpath.sci +// + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3] +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4] +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20] +st=[0,4] +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) +//Press Enter to continue +//Output : +//Shortest path from start-node:0 to end-node:4 is : +//0 -> 3 -> 4 +//Minumum cost (using the said path) :- 30.000000 +halt() // Press return to continue + +halt() // Press return to continue + +specifying disconnected-distance +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3] +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4] +weights = [20, 30, 10, 10, 30, 10, 20, 5, 30] +st=[0,4] +disconnected_distance=30 +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) +//Press Enter to continue +//Output +//Shortest path from start-node:0 to end-node:4 is : +//0 -> 3 -> 2 -> 4 +//Minumum cost (using the said path) :- 35.000000 +//Shortest/Lowest Cost Path found. +halt() // Press return to continue + +halt() // Press return to continue + +start_nodes = [1, 1, 2, 2, 3, 3, 0] +end_nodes = [2, 4, 3, 4, 2, 4, 5] +weights = [40, 30, 10, 20, 5, 20, 30] +st=[0,4] +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) +//Press Enter to continue +//No path connecting start-node: 0 and end-node=: 4. +//No Solution![0 , 4] +halt() // Press return to continue + +halt() // Press return to continue + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; +st=[0,3] +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) +//Press Enter to continue +//Output +//Shortest path from start-node:0 to end-node:3 is : +//0 -> 1 -> 2 -> 3 +//Minumum cost (using the said path) :- 22.000000 +// Shortest/Lowest Cost Path found. +halt() // Press return to continue + +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/jssp.dem.sce b/demos/jssp.dem.sce new file mode 100644 index 0000000..f9b7390 --- /dev/null +++ b/demos/jssp.dem.sce @@ -0,0 +1,57 @@ +mode(1) +// +// Demo of jssp.sci +// + +//INPUT : +halt() // Press return to continue + +machines = 3; +halt() // Press return to continue + +jobs = 3; +halt() // Press return to continue + +jssp_mode = 0; +halt() // Press return to continue + +tasks=[ 1 1 3; +1 2 2; +1 3 2; +2 1 2; +2 3 1; +2 2 4; +3 2 4; +3 3 3; +]; +halt() // Press return to continue + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); +halt() // Press return to continue + +//INPUT: +halt() // Press return to continue + +machines = 2; +halt() // Press return to continue + +jobs = 5; +halt() // Press return to continue + +jssp_mode = 0; +halt() // Press return to continue + +tasks = [1 1 13; +1 2 3; +2 1 2; +2 2 5; +3 1 1; +3 2 3; +4 1 4; +4 2 6; +5 1 5; +5 2 7]; +halt() // Press return to continue + +[makespan, schedule, status] = jssp (machines, jobs, jssp_mode, tasks, []); +//========= E N D === O F === D E M O =========// diff --git a/demos/linsum.dem.sce b/demos/linsum.dem.sce new file mode 100644 index 0000000..28c90a1 --- /dev/null +++ b/demos/linsum.dem.sce @@ -0,0 +1,19 @@ +mode(1) +// +// Demo of linsum.sci +// + +//Ref : +//http://www.hungarianalgorithm.com/examplehungarianalgorithm.php +halt() // Press return to continue + +kNumLeftNodes = 4; +kNumRightNodes = 4; +kCost = [82, 83, 69, 92; 77, 37, 49, 92; 11, 69, 5, 86; 8, 9, 98, 23]; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); +cost +assignment +status +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/min_cost_flow.dem.sce b/demos/min_cost_flow.dem.sce new file mode 100644 index 0000000..864f7da --- /dev/null +++ b/demos/min_cost_flow.dem.sce @@ -0,0 +1,33 @@ +mode(1) +// +// Demo of min_cost_flow.sci +// + +//Ref : Example 2 : +//http://www.yourarticlelibrary.com/ergonomics/operation-research/checking-for-optimality-transportation-problem/34743/ +halt() // Press return to continue + +// Before balancing (Infeasible): +kNumSources = 4; +kNumTargets = 4; +kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; +kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); +halt() // Press return to continue + +// After balancing (Optimal): +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); +cost +flow +status +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/qcqpglob.dem.sce b/demos/qcqpglob.dem.sce new file mode 100644 index 0000000..433861b --- /dev/null +++ b/demos/qcqpglob.dem.sce @@ -0,0 +1,34 @@ +mode(1) +// +// Demo of qcqpglob.sci +// + +// Sample Only +// Min. Z = 100 - x^2 + 2 * y^2 - 3 * x * y + 4 * x - 5 * y +// Subject to: +// 60 >= x^2 + y^2 - x - y >= -100 +// -10 <= x <= 6 +// -10 <= y <= 6 +halt() // Press return to continue + +n = 2; +m = 1; +h_obj = [-2, -1; -2, 4]; +f_obj = [4, -5]; +c_obj = 100; +h_con = list(); +h_con(1) = [2, 0; 0, 2]; +f_con = list(); +f_con(1) = [-1, -1]; +lb_con = [-100]; +ub_con = [60]; +maxcputime = 600; +lb_var = [-10, -10]; +ub_var = [6, 6]; +[kSoln, kSolnVector, status] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var, maxcputime); +kSoln +kSolnVector +status +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/tsp.dem.sce b/demos/tsp.dem.sce new file mode 100644 index 0000000..16dbb3f --- /dev/null +++ b/demos/tsp.dem.sce @@ -0,0 +1,94 @@ +mode(1) +// +// Demo of tsp.sci +// + +halt() // Press return to continue + +adj=[0 10 50 45; +10 0 25 25; +50 25 0 40; +45 25 40 0]; +halt() // Press return to continue + +start_node=1; +halt() // Press return to continue + +[mincost,path,status]=tsp(adj,start_node); +//Press ENTER to continue +halt() // Press return to continue + +//OUTPUT : +//'ROUTING_SUCCESS' ; An optimal solution was found +//Minimum cost -> 120 +//Optimal Path :- +//1 ->2 ->3 ->4 ->1 +halt() // Press return to continue + +halt() // Press return to continue + +adj=[0 10 15 20; +10 0 35 25; +15 35 0 30; +20 25 30 0]; +halt() // Press return to continue + +start_node=1; +halt() // Press return to continue + +labels=['A' 'B' 'C' 'D']; +[mincost,path,status]=tsp(adj,start_node,labels); +//Press ENTER to continue +// +//OUTPUT : +//'ROUTING_SUCCESS' ; An optimal solution was found +//Minimum cost -> 80 +//Optimal Path :- +// A (1) -> B (2) -> D (4) -> C (3) ->A (1) +halt() // Press return to continue + +halt() // Press return to continue + +adj=[0 1 2 1 1; +1 0 1 2 1; +2 1 0 1 2; +1 2 1 0 2; +1 1 2 2 0]; +halt() // Press return to continue + +start_node=1; +halt() // Press return to continue + +labels=['alpha' 'beta' 'gamma' 'theta' 'sigma']; +halt() // Press return to continue + +[mincost,path,status]=tsp(adj,start_node,labels); +Press ENTER to continue +halt() // Press return to continue + +//OUTPUT : +//'ROUTING_SUCCESS' ; An optimal solution was found +//Minimum cost -> 5 +//Optimal Path :- +// alpha (1) -> sigma (5) -> beta (2) -> gamma (3) -> theta (4) ->alpha (1) +halt() // Press return to continue + +halt() // Press return to continue + +adj=[0 10 -1 -2; +10 0 35 25; +-1 35 0 30; +-1 25 30 0]; +halt() // Press return to continue + +start_node=1; +halt() // Press return to continue + +[mincost,path,status]=tsp(adj,start_node); +//Press ENTER to continue +// +//OUTPUT : +//'ROUTING_FAIL' ; No optimal solution was found. No path starting and ending at the specified 'start node'(1) found. +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/demos/vrp.dem.sce b/demos/vrp.dem.sce new file mode 100644 index 0000000..f6d22a8 --- /dev/null +++ b/demos/vrp.dem.sce @@ -0,0 +1,81 @@ +mode(1) +// +// Demo of vrp.sci +// + +//INPUT: +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; +2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; +713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; +1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; +1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; +1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; +2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; +213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; +2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; +875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; +1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; +2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; +1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; +halt() // Press return to continue + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; +halt() // Press return to continue + +start = 1; +halt() // Press return to continue + +vehicles = 3; +halt() // Press return to continue + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; +halt() // Press return to continue + +service_time_per_demand=3; +halt() // Press return to continue + +max_vehicle_capacity = 60; +halt() // Press return to continue + +[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand); +halt() // Press return to continue + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; +2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; +713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; +1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; +1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; +1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; +2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; +213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; +2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; +875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; +1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; +2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; +1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; +halt() // Press return to continue + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; +halt() // Press return to continue + +start = [] ; +halt() // Press return to continue + +vehicles = 3; +halt() // Press return to continue + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; +halt() // Press return to continue + +service_time_per_demand=3; +halt() // Press return to continue + +max_vehicle_capacity = 60; +halt() // Press return to continue + +[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand); +halt() // Press return to continue + +halt() // Press return to continue + +//========= E N D === O F === D E M O =========// diff --git a/etc/Optimization_Toolbox.quit b/etc/Optimization_Toolbox.quit new file mode 100644 index 0000000..fa8521b --- /dev/null +++ b/etc/Optimization_Toolbox.quit @@ -0,0 +1,52 @@ +if ( isdef("toolbox_optimization") <> %t ) then + warning("Toolbox is not loaded. Please load to proceed!"); +end + +verboseMode = ilib_verbose(); +ilib_verbose(0); + +function quitModule() + + TOOLBOX_NAME = "Optimization_Toolbox"; + TOOLBOX_TITLE = "Optimization Toolbox"; + + mprintf("Stop " + TOOLBOX_NAME + "\n"); + + etc_tlbx = get_absolute_file_path(TOOLBOX_NAME + ".quit"); + etc_tlbx = getshortpathname(etc_tlbx); + root_tlbx = strncpy( etc_tlbx, length(etc_tlbx) - 5 ); // length("\etc\") = 5 + + // Unlink Libraries + [bOK, ilib] = c_link("lib" + TOOLBOX_NAME + "_cpp"); + if bOK then + ulink(ilib); + end + [bOK, ilib] = c_link("lib" + TOOLBOX_NAME + "_c"); + if bOK then + ulink(ilib); + end + [bOK, ilib] = c_link("lib" + TOOLBOX_NAME + "_java"); + if bOK then + ulink(ilib); + end + [bOK, ilib] = c_link("lib" + TOOLBOX_NAME + "_fortran"); + if bOK then + ulink(ilib); + end + if isdef("optimization_libs") then + ulink(optimization_libs); + end + + // Remove Preferences GUI + // ============================================================================= + if getscilabmode() == "STD" then + removeModulePreferences(root_tlbx); + end + +endfunction + +quitModule(); + +ilib_verbose(verboseMode); + +clear quitModule toolbox_optimization optimization_libs TOOLBOX_NAME TOOLBOX_TITLE verboseMode; diff --git a/etc/Optimization_Toolbox.start b/etc/Optimization_Toolbox.start new file mode 100644 index 0000000..699ae40 --- /dev/null +++ b/etc/Optimization_Toolbox.start @@ -0,0 +1,82 @@ +if isdef("toolbox_optimization") then + error("Toolbox is already loaded. Please unload to proceed!"); +end + +verboseMode = ilib_verbose(); +ilib_verbose(0); + +TOOLBOX_NAME = "Optimization_Toolbox"; +TOOLBOX_TITLE = "Optimization Toolbox"; + +if (isdef("optimization_libs") <> %t) then + optimization_libs = []; +end + +function [toolbox_optimization, optimization_libs] = startModule() + + mprintf("Start " + TOOLBOX_NAME + "\n"); + + etc_tlbx = get_absolute_file_path(TOOLBOX_NAME + ".start"); + etc_tlbx = getshortpathname(etc_tlbx); + root_tlbx = strncpy( etc_tlbx, length(etc_tlbx) - 5 ); // length("\etc\") = 5 + + // Load Macros + mprintf("\tLoad macros\n"); + pathmacros = pathconvert( root_tlbx ) + "macros" + filesep(); + toolbox_optimization = lib(pathmacros); + + // Load Libraries + mprintf("\tLoad Libraries\n"); + [a, opt] = getversion(); + ARCH = opt(2); + if getos()=="Windows" then + // MSVS Shared DLL don't provide Native Support to Scilab. + else + lib_path = root_tlbx + filesep() + "thirdparty" + filesep() + "linux" + filesep() + "lib" + filesep() + ARCH + filesep(); + optimization_libs($+1) = link(lib_path + "libCoinUtils.so"); + optimization_libs($+1) = link(lib_path + "libOsi.so"); + optimization_libs($+1) = link(lib_path + "libClp.so"); + optimization_libs($+1) = link(lib_path + "libOsiClp.so"); + optimization_libs($+1) = link(lib_path + "libClpSolver.so"); + optimization_libs($+1) = link(lib_path + "libcoinmumps.so"); + optimization_libs($+1) = link(lib_path + "libipopt.so"); + optimization_libs($+1) = link(lib_path + "libminotaur.so"); + optimization_libs($+1) = link(lib_path + "libmntrosilp.so"); + optimization_libs($+1) = link(lib_path + "libmntripopt.so"); + optimization_libs($+1) = link(lib_path + "libmntrengfac.so"); + optimization_libs($+1) = link(lib_path + "libortools.so"); + optimization_libs($+1) = link(lib_path + "libcvrptw_lib.so"); + optimization_libs($+1) = link(lib_path + "libdimacs.so"); + optimization_libs($+1) = link(lib_path + "libfap.so"); + optimization_libs($+1) = link(lib_path + "libjniortools.so"); + end + + // Load Gateway + mprintf("\tLoad Gateway\n"); + exec(pathconvert(root_tlbx + filesep() + "sci_gateway" + filesep() + "loader_gateway.sce", %f)); + + // Load and add help chapter + // ============================================================================= + if or(getscilabmode() == ["NW";"STD"]) then + mprintf("\tLoad help\n"); + path_addchapter = pathconvert(root_tlbx + filesep() + "jar"); + if ( isdir(path_addchapter) <> [] ) then + add_help_chapter(TOOLBOX_NAME, path_addchapter, %F); + end + end + + // Load demos + // ============================================================================= + if or(getscilabmode() == ["NW";"STD"]) then + mprintf("\tLoad demos\n"); + pathdemos = pathconvert(root_tlbx + filesep() + "demos" + filesep() + TOOLBOX_NAME + ".dem.gateway.sce", %F, %T); + add_demo(TOOLBOX_NAME, pathdemos); + end + +endfunction + +toolbox_optimization = startModule(); + +ilib_verbose(verboseMode); + +clear startModule TOOLBOX_NAME TOOLBOX_TITLE verboseMode; diff --git a/etc/README.rst b/etc/README.rst new file mode 100644 index 0000000..2ffc09f --- /dev/null +++ b/etc/README.rst @@ -0,0 +1,14 @@ +DEMOS Files +=========== + +Start and exit files of the toolbox. + +.start +------- + +It will run a script when loader.sce is run from root toolbox directory. It will run loader files in all of the directories and link to important library. + +.quit +------- + +It will run a script when unloader.sce is run from root toolbox directory. It will unlink all of the important library. diff --git a/help/builder_help.sce b/help/builder_help.sce new file mode 100644 index 0000000..e05af12 --- /dev/null +++ b/help/builder_help.sce @@ -0,0 +1,5 @@ +help_dir = get_absolute_file_path('builder_help.sce'); + +tbx_builder_help_lang("en_US", help_dir); + +clear help_dir; \ No newline at end of file diff --git a/help/en_US/Checkdims.xml b/help/en_US/Checkdims.xml new file mode 100644 index 0000000..df27a6e --- /dev/null +++ b/help/en_US/Checkdims.xml @@ -0,0 +1,88 @@ + + + + + + + + Checkdims + Generates an error if the variable has not the required size. + + + + + Calling Sequence + + errmsg = Checkdims ( funname , var , varname , ivar , matdims ) + + + + + + Parameters + + funname : + a 1 x 1 matrix of strings, the name of the calling function. + var : + a 1 x 1 matrix of valid Scilab data type, the variable + varname : + a 1 x 1 matrix of string, the name of the variable + ivar : + a 1 x 1 matrix of floating point integers, the index of the input argument in the calling sequence + matdims : + 1 x 2 matrix of floating point integers, the number of rows, columns for the variable #ivar + errmsg : + a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + + + + + Description + +This function is designed to be used to design functions where +the input argument has a known shape. +This function cannot be use when var is a function, or more +generally, for any input argument for which the size function +does not work. +Last update : 05/08/2010. + + + + + + + Examples + + + + + Authors + + Michael Baudin - 2010 - DIGITEO + + + diff --git a/help/en_US/Checklhs.xml b/help/en_US/Checklhs.xml new file mode 100644 index 0000000..ce60ab8 --- /dev/null +++ b/help/en_US/Checklhs.xml @@ -0,0 +1,112 @@ + + + + + + + + Checklhs + Generates an error if the number of LHS is not in given set. + + + + + Calling Sequence + + errmsg = Checklhs ( funname , lhs , lhsset ) + + + + + + Parameters + + funname : + a 1 x 1 matrix of strings, the name of the calling function. + lhs : + a 1 x 1 matrix of floating point integers, the actual number of output arguments + lhsset : + a 1 x n or n x 1 matrix of floating point integers, the authorized number of output arguments + errmsg : + a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + + + + + Description + +This function is designed to be used to design functions with +variable number of output arguments. +Notice that it is useless to call this function if the +function definition does not use the varargout statement. +Notice that a function as a minimum of 1 output argument. +Last update : 29/07/2010. + + + + + + + Examples + + + + + Authors + + Michael Baudin - 2010 - DIGITEO + + + diff --git a/help/en_US/Checkrhs.xml b/help/en_US/Checkrhs.xml new file mode 100644 index 0000000..98e6244 --- /dev/null +++ b/help/en_US/Checkrhs.xml @@ -0,0 +1,135 @@ + + + + + + + + Checkrhs + Generates an error if the number of RHS is not in given set. + + + + + Calling Sequence + + errmsg = Checkrhs ( funname , rhs , rhsset ) + + + + + + Parameters + + funname : + a 1 x 1 matrix of strings, the name of the calling function. + rhs : + a 1 x 1 matrix of floating point integers, the actual number of input arguments + rhsset : + a 1 x n or n x 1 matrix of floating point integers, the authorized number of input arguments + errmsg : + a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + + + + + Description + +This function is designed to be used to design functions with +variable number of input arguments. +Notice that it is useless to call this function if the +function definition does not use the varargin statement. +Last update : 05/08/2010. +Last update : 29/07/2010. + + + + + + + Examples + = 3 ) then +x3 = varargin(3) +else +x3 = 2 +end +y = x1 + x2 + x3 +endfunction +// Calling sequences which work +y = myfunction ( 1 , 2 ) +y = myfunction ( 1 , 2 , 3 ) +// Calling sequences which generate an error +y = myfunction ( 1 ) +y = myfunction ( 1 , 2 , 3 , 4 ) + +// The function takes 2 or 4 input arguments, but not 3 +function y = myfunction ( varargin ) +[lhs, rhs] = argn() +Checkrhs ( "myfunction" , rhs , [2 4] ) +Checklhs ( "myfunction" , lhs , 1 ) +x1 = varargin(1) +x2 = varargin(2) +if ( rhs >= 3 ) then +x3 = varargin(3) +x4 = varargin(4) +else +x3 = 2 +x4 = 3 +end +y = x1 + x2 + x3 + x4 +endfunction +// Calling sequences which work +y = myfunction ( 1 , 2 ) +y = myfunction ( 1 , 2 , 3 , 4 ) +// Calling sequences which generate an error +y = myfunction ( 1 ) +y = myfunction ( 1 , 2 , 3 ) +y = myfunction ( 1 , 2 , 3 , 4, 5 ) + +// The function takes 2 input arguments and 0/1 output arguments. +// Notice that if the checkrhs function is not called, +// the variable x2 might be used from the user's context, +// that is, if the caller has defined the variable x2, it +// is used in the callee. +// Here, we want to avoid this. +function y = myfunction ( x1 , x2 ) +[lhs, rhs] = argn() +Checkrhs ( "myfunction" , rhs , 2 ) +Checklhs ( "myfunction" , lhs , [0 1] ) +y = x1 + x2 +endfunction +// Calling sequences which work +y = myfunction ( 1 , 2 ) +// Calling sequences which generate an error +y = myfunction ( 1 ) +y = myfunction ( 1 , 2 , 3 ) + + ]]> + + + + Authors + + Michael Baudin - 2010 - DIGITEO + + + diff --git a/help/en_US/Checktype.xml b/help/en_US/Checktype.xml new file mode 100644 index 0000000..4e0fb9a --- /dev/null +++ b/help/en_US/Checktype.xml @@ -0,0 +1,100 @@ + + + + + + + + Checktype + Generates an error if the given variable is not of expected type. + + + + + Calling Sequence + + errmsg = Checktype ( funname , var , varname , ivar , expectedtype ) + + + + + + Parameters + + funname : + a 1 x 1 matrix of strings, the name of the calling function. + var : + a 1 x 1 matrix of valid Scilab data type, the variable + varname : + a 1 x 1 matrix of string, the name of the variable + ivar : + a 1 x 1 matrix of floating point integers, the index of the input argument in the calling sequence + expectedtype : + a n x 1 or 1 x n matrix of strings, the available types for the variable #ivar + errmsg : + a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + + + + + Description + +This function is designed to be used to design functions with +input arguments with variable type. +We use the typeof function to compute the type of the variable: +see help typeof to get the list of all available values for expectedtype. +Last update : 29/07/2010. + + + + + + + Examples + + + + + Authors + + Michael Baudin - 2010 - DIGITEO + + + diff --git a/help/en_US/Checkvector.xml b/help/en_US/Checkvector.xml new file mode 100644 index 0000000..7357075 --- /dev/null +++ b/help/en_US/Checkvector.xml @@ -0,0 +1,91 @@ + + + + + + + + Checkvector + Generates an error if the variable is not a vector. + + + + + Calling Sequence + + errmsg = Checkvector ( funname , var , varname , ivar ) + + + + + + Parameters + + funname : + a 1 x 1 matrix of strings, the name of the calling function. + var : + a 1 x 1 matrix of valid Scilab data type, the variable + varname : + a 1 x 1 matrix of string, the name of the variable + ivar : + a 1 x 1 matrix of floating point integers, the index of the input argument in the calling sequence + nbval : + a 1 x 1 matrix of floating point integers, the number of entries in the vector. + errmsg : + a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + + + + + Description + +This function is designed to be used to design functions where +the input argument is a vector, that is, a matrix for which +nrows == 1 or ncols == 1. +This function cannot be use when var is a function, or more +generally, for any input argument for which the size function +does not work. + + + + + + + Examples + + + + + Authors + + Michael Baudin - 2010 - DIGITEO + + + diff --git a/help/en_US/Filterdims.xml b/help/en_US/Filterdims.xml new file mode 100644 index 0000000..5b7c2ae --- /dev/null +++ b/help/en_US/Filterdims.xml @@ -0,0 +1,88 @@ + + + + + + + + Filterdims + Generates an error if the variable has not the required size. + + + + + Calling Sequence + + errmsg = Filterdims ( funname , var , varname , ivar , matdims ) + + + + + + Parameters + + funname : + a 1 x 1 matrix of strings, the name of the calling function. + var : + a 1 x 1 matrix of valid Scilab data type, the variable + varname : + a 1 x 1 matrix of string, the name of the variable + ivar : + a 1 x 1 matrix of floating point integers, the index of the input argument in the calling sequence + matdims : + 1 x 2 matrix of floating point integers, the number of rows, columns for the variable #ivar + errmsg : + a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + + + + + Description + +This function is designed to be used to design functions where +the input argument has a known shape. +This function cannot be use when var is a function, or more +generally, for any input argument for which the size function +does not work. +Last update : 05/08/2010. + + + + + + + Examples + + + + + Authors + + Michael Baudin - 2010 - DIGITEO + + + diff --git a/help/en_US/README.rst b/help/en_US/README.rst new file mode 100644 index 0000000..95f8ace --- /dev/null +++ b/help/en_US/README.rst @@ -0,0 +1,6 @@ +Help XML +======== + +This directory contains all of help files in XML. These files are automatically generated by help_from_sci function by the help of comments in Macro. + +By the help of this we can generate html and jar files. diff --git a/help/en_US/build_help.sce b/help/en_US/build_help.sce new file mode 100644 index 0000000..e883024 --- /dev/null +++ b/help/en_US/build_help.sce @@ -0,0 +1,5 @@ +help_lang_dir = get_absolute_file_path("build_help.sce"); + +tbx_build_help(TOOLBOX_NAME, help_lang_dir); + +clear help_lang_dir; diff --git a/help/en_US/fmaxflow.xml b/help/en_US/fmaxflow.xml new file mode 100644 index 0000000..7f847fa --- /dev/null +++ b/help/en_US/fmaxflow.xml @@ -0,0 +1,183 @@ + + + + + + + + fmaxflow + Solves the graph max-flow problem(a linear optimization problem) using an implementation of the push-relabel algorithm + + + + + Calling Sequence + + [maxflow,arcflows]=fmaxflow(start_nodes,end_nodes,capacities,st) + [maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st) + + + + + + Parameters + + start_nodes : + a [1xn] vector (if the graph has 'n' arcs, for instance) of integral values which stores the numerical label of the start-nodes (tail-nodes) for each arc of the graph. + end_nodes : + a [1xn] vector of integral values which stores the value (numerical label) of the end-nodes(head-nodes) for each arc of the graph. + capacities : + a [1xn] vector of integral values which stores the capacities (max amount possible over a particular arc) of the respective arcs. Eg. The capacity at index 'i' of this matrix means the maximum amount possible over the arc defined by start_node[i]->end_node[i]. + st : + a [1x2] vector which stores the numerical-label (value) of the source node and the target node, respectively. + maxflow : + a double representing the Maximum total Flow possible(i.e. Solution) through the system in the optimal solution, should there be one. + arcflows : + a [1xn] vector of double (if the graph has 'n' arcs, for instance) which represents the actual flow through the respective arcs in the optimal solution of the problem, should one exist. + status : + status flag returned by the Google OR-tools MaxFlow Solver function (details below) + + + + + Description + + +\text{The \textbf{`Maximum-Flow' Problem } is a classic (linear) optimization problem for Flow Networks}^{*}\text{. Essentially a part of the class of \textbf{`Circulation Problems'}, it involves finding the maximum amount of flow possible from a specified (source) node to another (sink) node, in a given network.}\\ +\text{}\\ +^{*}\text{\underline{\textbf{Flow Network}} - A flow network (also called a `transportation network'), in graph theory, is essentially a directed graph with one (or more) \textbf{source} node(s) and one (or more) \textbf{sink} node(s) and several other standard nodes, connected by edges called \textbf{`arcs'}.}\\ +\text{\textbf{`Flow'} is any entity that circulates through the network, from the source to the sink. Eg. electric current in a printed circuit, water in a plumbing network, etc.}\\ +\text{}\\\\ +\text{}\\\\ +\text{\textbf{\underline{MATHEMATICAL STATEMENT} :}}\\ +\text{}\\ +\text{}\\ + + +\begin{math} +\text{Let } N= \left(V,E\right) \text{ be a network with } s,t \in V \text{ denoting the source and sink nodes in } N\text{, respectively.}\\\\ +\text{Let } c_{uv} \text{ or } c\left(u,v\right) \text{ denote the capacity of the arc between node } u \text{ and } v.\\ +\text{capacity is a mapping } c:V\to R^{+} \\\\ +\text{Let } f_{uv} \text{ or } f\left(u,v)\right) \text{ denotes the flow between node } u \text{ and } v, \text{such that :}\\ +\text{ 1. } f_{uv} \leq c_{uv} \quad \forall \quad (u,v) \in E.\\ +\text{ 2. } \sum_{u:(u,v)\in E} f_{uv} = \sum_{u:(v,u) \in E} f_{vu}\quad \forall \quad v \in V \backslash \{s,t\}\quad\text{; conservation of flow}\\\\\\ +\text{}\\ +\text{}\\ +\text{}\\ +\textbf{\underline{Objective} :} +\text{}\qquad\qquad\qquad Maximize \quad |f| = \sum_{v:(s,v) \in E}f_{sv} \text{,where }s\text{ is the source vertex for } N.\\\\ +\text{}\qquad\qquad\qquad\text{}\qquad\qquad\qquad |f| \text{ denotes the total amount of flow passing from the source to the sink}\\ +\end{math} +\text{}\\ +\text{}\\ +\text{}\\ +\text{}\\ + + + +status- the status of solution returned by the linked Google OR-Tools max-flow solver + +status=0 - OPTIMAL(An optimal solution was found) +status=1 - INT_OVERFLOW(There is a feasible flow > max possible flow) +status=2 - BAD_INPUT(The input is inconsistent) +status=3 - BAD_RESULT (There was an error) + + + + + + + + + + Examples + 1 20 20 +//0->2 30 30 +//0->3 10 10 +//1->2 0 40 +//1->4 20 30 +//2->3 10 10 +//2->4 20 20 +//3->2 0 5 +//3->4 20 20 + +//An optimal solution was found +// status = +// +// 0 +// arcflows = +// +// 20 30 10 0 20 10 20 0 20 +// maxflow = +// +// 60 + + + ]]> + + + + Examples + 2 0 40 +//1->4 0 30 +//2->3 0 10 +//2->4 0 20 +//3->2 0 5 +//3->4 0 20 +//0->5 0 50 + +//There is no path connecting the specified source node : 0 and the specified target node : 4 +// status = +// +// 0 +// arcflows = +// +// [] +// maxflow = +// +// 0 + + + ]]> + + + + Authors + + Samuel Wilson + + + diff --git a/help/en_US/fshortestpath.xml b/help/en_US/fshortestpath.xml new file mode 100644 index 0000000..5492475 --- /dev/null +++ b/help/en_US/fshortestpath.xml @@ -0,0 +1,180 @@ + + + + + + + + fshortestpath + Computes the shortest/minimum-cost path for a given graph using an implementation of the 'Bellman Ford' algorithm for weighted digraphs. + + + + + Calling Sequence + + [mincost,shortestpath]=fshortestpath(start_nodes,end_nodes,weights,st) + [mincost,shortestpath]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) + [mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + [mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) + + + + + + Parameters + + start_nodes : + a [1xn] vector (if the graph has 'n' arcs, for instance) of integral values which stores the numerical label of the start-nodes (tail-nodes) for each arc of the graph. + end_nodes : + a [1xn] vector of integral values which stores the numerical label of the end-nodes (head-nodes) for each arc of the graph. + weights : + a [1xn] vector of integral values which stores the weights/traversal costs for each of the edges/arcs of the given graph. Eg.-The weight at index 'i' of this vector refers to the cost/weight of the arc defined by start_node[i]->end_node[i]. + st : + a [1x2] vector which stores the numerical-label of the source node and the target node respectively. + disconnected_distance : + a singular integral value which indicates that all the weight values greater than or equal to itself essentially mean a non-existent arc/edge/path, i.e. those edges of the given graph will not be considered for the current test. (allows testing with different threshold values if need be) + mincost : + an integral value denoting the minimum possible cost incurred in traversing from the source node to the target node (summation of weights/costs of all the edges/arcs included in the shortest path, if any) + shortestpath : + Returns a vector containing the nodes(the numerical tags thereof) lying on the shortest path from source to target, if one exists. + flag : + flag variable indicating if there exists a path between the given source and target nodes(0-> no path exists; 1-> path exists(ipso facto, a minimal-cost path exists) + + + + + Description + +\text{A staple of graph theory, the \textbf{`Shortest Path' problem } vies to find the least-cost, hence ``shortest" path between any two given nodes in a \textbf{weighted digraph}}^{*}\text{. Essentially a linear programming problem at its core, it is one of the most studied optimization problems.} +\text{}\\ +\text{}\\ +\text{The routine uses an implementation of the `Bellman Ford single-source shortest path algorithm for weighted digraphs'(negative weights supported)} +\text{}\\ +\text{Bellman–Ford is based on the principle of relaxation, in which an approximation to the correct distance is gradually replaced by more accurate values until eventually reaching the optimum solution.\\The approximate distance to each vertex is always an overestimate of the true distance, and is replaced by the minimum of its old value with the length of a newly found path.\\Bellman–Ford algorithm, unlike the contemporary Dijkstra's shortest path algorithm, simply relaxes all the edges, and does this (|V|-1) times, where |V| is the number of vertices in the graph. In each of these repetitions, the number of vertices with correctly calculated distances grows, from which it follows that eventually all vertices will have their correct distances.\\This method allows the Bellman–Ford algorithm to be applied to a wider class of inputs than Dijkstra's algorithm(Dijkstra's doesn't support negative edges).\\ +Bellman–Ford runs in O(|V|.|E|) time, where |V| and |E| are the number of vertices and edges respectively.}\\ +\text{}\\ +\text{}\\ +\text{}\\ +^{*}\text{\underline{\textbf{Weighted Digraph}} : A weighted digraph is a graph in which each edge has a ``weight" associated with it. The \textbf{``weight" } is any quantity of practical significance to the problem, like distance, electrical resistance, etc. Moreover, the edges of the graph are directionally constrained, i.e. an edge from node `a' to node `b' entails neither the existence of an edge from node `b' to node `a' nor the same weight.}\\ +\text{}\\ +\text{}\\ +\text{}\\ +\text{\textbf{\underline{MATHEMATICAL STATEMENT} :}}\\ +\text{}\\ +\text{}\\ +\text{}\\ + + +\begin{math} +\text{Let } N= \left(V,E\right) \text{be a network with } s,t \in V \text{denoting the source and target nodes in } N\text{, respectively.}\\ +\text{Let } w_{ij} \text{ denote the cost for the edge } i \to j.\\\\ +\textbf{\underline{Objective} :} +\text{}\quad Maximize \quad \sum_{i,j \in A} w_{ij}x_{ij} \text{ ;}\\\\ +\text{ } \qquad \hspace{4em} \text{ Subject to } x \geq 0.\\ +\text{ }\qquad \hspace{4em} \text{ Also, } \sum_{j}x_{ij} - \sum_{j} x_{ji} = \begin{cases} +1, \quad if\text{ }i=s\text{;}\\ +-1, \quad if\text{ }i=t\text{;}\\ +0, \quad \text{ otherwise;}\\ +\end{cases} \quad \forall \quad i \text{ ;}\\ +\end{math} + + + + + + + + + + Examples + 3 -> 4 +//Minumum cost (using the said path) :- 30.000000 + + + ]]> + + + + Examples + 3 -> 2 -> 4 +//Minumum cost (using the said path) :- 35.000000 +//Shortest/Lowest Cost Path found. + + + ]]> + + + + Examples + + + + + Examples + 1 -> 2 -> 3 +//Minumum cost (using the said path) :- 22.000000 +// Shortest/Lowest Cost Path found. + + + ]]> + + + + Authors + + Samuel Wilson + + + diff --git a/help/en_US/jssp.xml b/help/en_US/jssp.xml new file mode 100644 index 0000000..6a9cae2 --- /dev/null +++ b/help/en_US/jssp.xml @@ -0,0 +1,158 @@ + + + + + + + + jssp + Solves the popular 'Job-Shop Scheduling Problem' (JSSP for short), which aims to find an optimal plan to schedule a given number of jobs, each composed of one or more tasks to be performed in some specific logical order, on a given number of machines. The routine makes use of the 'constraint-solver' library from the Google OR-Tools framework. + + + + + Calling Sequence + + [makespan,schedule] = jssp(machines, jobs, jmode, tasks) + [makespan, schedule] = jssp(machines, jobs, jmode, tasks, time_limit) + [makespan, schedule, status] = jssp(machines, jobs, jmode, tasks) + [makespan, schedule, status] = jssp(machines, jobs, jmode, tasks, time_limit) + + + + + + Parameters + + machines : + It is a single integral value specifying the total number of machines in the problem, on which the various tasks are to be scheduled. + jobs : + It is a single integral value specifying the total number of jobs in the problem. Each job is composed of one or more tasks which are to be scheduled on specific machines, in some logical order. + mode : + It is a single intergral value (either '0' or '1' only). It specifies one of the two modes for the solver, which are :-0-> Sequential - In this mode, the various tasks within a job are considered to be sequentially constrained i.e. task_1 must occur before task_2, task_2 before task_3 and so on.1-> Parallel - This mode allows the flexibility of some tasks being scheduled parallelly or independently of each other, if such a scenario is to be modelled. Eg. if a task 'x' can be performed any time after task_1 but must be performed before task_10. It requires 2 additional fields in the 'tasks' matrix, specifying 2 tasks (indices) between which the current task can be freely scheduled. One or both of these bounds can be done away with(no 'start_after' or 'end_before' constraints) by providing '-1' for the respective field.(These indices are the task indices WITHIN the job, ie.each job will have a task indexed '1', dor instance). + tasks : + It is an [AxB] matrix( A- total number of tasks in the problem. B- 3 or 5 depending on the mode). Each row corresponds to a task. The two variations are :-mode '0' -> An [Ax3] matrix. The 3 fields/columns are 'Job-Index', 'Machine-Index' and 'Task-Duration'. (The tasks for each job are ordered internally in the order they appear in this matrix)mode '1' -> An [Ax5] matrix. The 5 fields/columns are 'Job-Index, 'Machine-Index', 'Task-Duration', 'Start-After' and 'End-Before'. (order of the tasks doesn't matter in this case)\text{}\\\text{}\\\\More on the columns (let the current task(row) be 'x')'job-index' -> It is the index of the job to which 'x' belongs.'machine-index' -> It is the index of the machine on which 'x' is to be scheduled.'task-duration' -> It is the time required to perform 'x'.\text{}\\\text{}\\\\Only for mode '1' -'start-after' -> It is the index of the task, only after whose completion, 'x' can start.'end-before' -> It is the index of the task that can only start once 'x' is completed. + time_limit : + It is the maximum time (in milliseconds; integral value) for which the solver is allowed to run. If a solution is not found by then, a pertinent 'timed-out' error occurs.(Default Value - 10 seconds). Provide an empty matrix or omit the parameter if explicit time-limit is not required. + makespan : + It is the total duration of the schedule in the optimal solution, if one exists. + schedule : + Is is an [Ax5] matrix (A- no. of tasks) that gives the final schedule for the various tasks in the optimal solution, if one exists. The 5 fields/columns are 'Job-index', 'machine-index', 'task-duration', 'start-time' and 'end-time'. + status : + Is is an integral value representing the status of the solution as: '0'-> 'Solution Found' '1'-> 'Timed-out' - No solution was found within the specified/default time limit. '2'-> 'Problem-Infeasible' - No solution exists for the given problem. + + + + + Description + + +\text{The Job-Shop Scheduling Problem (also called the \textbf{Resource Scheduling Problem}) is a linear optimization problem in Computer Science and Operations Research which vies to schedule a number of jobs, each composed of one or more tasks, on a specific number of machines, minimizing the total time for the enite schedule, called the \textbf{makespan}.\\The order in which the various tasks in a job are performed and the machines on which they must be scheduled are received as inputs.\\This particular implementation supports two variations :}\\ +\text{}\\ +\text{1. \textbf{`Sequential Mode'}(mode 0) : In this mode, all the tasks in a job are considered to be sequentially constrained ie. task 2 cannot occur before task 1 finishes, and so on.}\\ +\text{2. \textbf{`Parallel/Arbitrary Mode'}(mode 1) : In this mode, tasks within a job can occur parallelly ie. the order is arbitrary sans 2 \textbf{optional bounds}. \\These 2 ``bound'' values are specified for each task. They are :}\\ +\qquad\text{ - \textbf{`start-after'} : This is the index of the task that must finish before the current task can start}\\ +\qquad\text{ - \textbf{`end-before'} : This is the index of the task that cannot start before the current task finishes}\\ +\text{}\\ +\text{}\\ +\text{}\\ +\text{\textbf{\underline{MATHEMATICAL\textbf{ }STATEMENT} :}}\\ +\text{}\\ +\text{}\\ +\text{}\\ + + + + +\begin{math} +\text{Let } M = \{M_{1}, M_{2},..., M_{m}\} \text{ and} \\ +\text{Let } J = \{J_{1}, J_{2},..., J_{j}\} \quad \text{be 2 finite sites representing the machines and the jobs respectively. }\\\\ +\end{math} +\text{(the tasks are abstracted for simplicity. So whenever a Job is scheduled on a machine, it is assumed, the next task to be performed is the one scheduled).}\\\\ +\begin{math} +\text{Let } X \text{ denote the set of assignment of all jobs on the machines}\\\\ +\text{Let } C \text{ be the \textbf{`cost function'} such that :}\\ +\text{}\\ +C:X \to [0, \infty^{+}] \quad \text{; which denotes the total processing time ie. makespan of schedule.}\\\\ +\textbf{\underline{Objective} :}\qquad \text{ To find an assignment of jobs }x \in X \text{ for which } C(x) \text{ is minimum, ie.}\\\\ +\text{ } \qquad \hspace{3em} \qquad \text{ } \text{ No }y \in X \text{ exists, such that } C(y) < C(x).\\ +\end{math} +\text{}\\ +\text{}\\ +\text{}\\ + + + + + + + + Examples + + + + + Examples + + + + + Authors + + Samuel Wilson + + + diff --git a/help/en_US/linsum.xml b/help/en_US/linsum.xml new file mode 100644 index 0000000..5ccef26 --- /dev/null +++ b/help/en_US/linsum.xml @@ -0,0 +1,86 @@ + + + + + + + + linsum + Solves problem with finding minimum cost of assignment + + + + + Calling Sequence + + [cost, assignment] = linsum(kNumLeftNodes, kNumRightNodes, kCost) + [cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost) + + + + + + Parameters + + kNumLeftNodes : + a double, Number of Left Nodes / Jobs + kNumRightNodes : + a double, Number of Right Nodes / Workers + kCost : + a matrix of double, kNumLeftNodes x kNumRightNodes, represents Cost of assigning a Job to a Worker + cost : + a double, Optimal (minimum) Cost + assignment : + a matrix of boolean, kNumLeftNodes x kNumRightNodes, represents Optimal Assignment for the Problem + status : + contains the exit flag of Solver. Currently 0 for Not Optimal, 1 for Optimal. + + + + + Description + +Find the minimum cost and assignment for a given set of jobs and workers + + +The routine uses Google ORtools for solving the quadratic problem, ORtools is a library written in C++. + + + + + + + Examples + + + + + Authors + + Souvik Das + + + diff --git a/help/en_US/min_cost_flow.xml b/help/en_US/min_cost_flow.xml new file mode 100644 index 0000000..6985c24 --- /dev/null +++ b/help/en_US/min_cost_flow.xml @@ -0,0 +1,116 @@ + + + + + + + + min_cost_flow + Solves problem with finding minimum cost of flow + + + + + Calling Sequence + + [cost, flow] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand) + [cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand) + + + + + + Parameters + + kNumSources : + a double, Number of Sources / Suppliers + kNumTargets : + a double, Number of Targets / Demanders + kCost : + a matrix of double, kNumSources x kNumTargets, represents Cost of flow from a Source to Target + kCapacity : + a matrix of double, kNumSources x kNumTargets, represents Capacity of flow from a Source to Target + kSupply : + a vector of double, length kNumSources, contains Supply Quantity of Suppliers + kDemand : + a vector of double, length kNumTargets, contains Demand Quantity of Demanders + cost : + a double, Optimal (minimum) Cost + flow : + a matrix of double, kNumSources x kNumTargets, represents Optimal Flow for the Problem + status : + contains the exit flag of Solver. See below + + + + + Description + +Find the minimum cost and flow for a given set of sources and targets with limit on capacity per flow + + +The routine uses Google ORtools for solving the quadratic problem, ORtools is a library written in C++. + + +The status allows to know the status of the optimization which is given back by ORtools. + +status=0 : Not Solved +status=1 : Optimal +status=2 : Feasible +status=3 : Infeasible +status=4 : Unbalanced +status=5 : Bad Result + + + + + + + + Examples + + + + + Authors + + Souvik Das + + + diff --git a/help/en_US/qcqpglob.xml b/help/en_US/qcqpglob.xml new file mode 100644 index 0000000..b70af3b --- /dev/null +++ b/help/en_US/qcqpglob.xml @@ -0,0 +1,147 @@ + + + + + + + + qcqpglob + Solves problem with Convex/Non-Convex Quadratically Constrained Quadratic Programming Problems with Global Optimization (GLOB) + + + + + Calling Sequence + + [kSoln, kSolnVector] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var); + [kSoln, kSolnVector, status] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var); + [kSoln, kSolnVector] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var, maxcputime); + [kSoln, kSolnVector, status] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var, maxcputime); + + + + + + Parameters + + n : + a double, represents number of Decision Variables + m : + a double, represents number of Constraints + h_obj : + a matrix of double, n x n, represents Coefficients of Quadratic in Objective Function + f_obj : + a vector of double, sized n, represents Coefficients of Linear in Objective Function + c_obj : + a double, represents Constant term in Objective Function + h_con : + an m sized list, contains matrices of double, n x n, represents Coefficients of Quadratic in Constraints + f_con : + an m sized list, contains vectors of double, sized n, represents Coefficients of Linear in Constraints + lb_con : + a vector of double, sized m, represents Lower Bound of Constraints + ub_con : + a vector of double, sized m, represents Upper Bound of Constraints + lb_var : + a vector of double, sized n, represents Lower Bound of Decision Variables + ub_var : + a vector of double, sized n, represents Upper Bound of Decision Variables + maxcputime : + a double, represents max. cpu time allotted to BnB Solver + kSoln : + a double, represents value of Objective Function at Optimal Point + kSolnVector : + a vector of double, sized n, represents values of Decision Variables at Optimal Point + status : + contains the exit flag of Solver. See below + + + + + Description + +Solves QCQP / Quadratically Constrained Quadratic Programming problems, especially those where local optimum is not the global optimum, i.e. when the problem is Non-Convex. Can solve Convex Problem as well. + + + +\begin{align} +& \text{minimize} && \tfrac12 x^\mathrm{T} H_0 x + f_0^\mathrm{T} x + c \\ +& \text{subject to} && {LB}_i \leq \tfrac12 x^\mathrm{T} H_i x + f_i^\mathrm{T} x \leq {UB}_i \quad \text{for } i = 1,\dots,m \\ +&&& Ax = b +\end{align}\\ + + + + +status=0 : Not started solving +status=1 : Started solving +status=2 : Restarted solving +status=3 : Optimal solution found +status=4 : Detected infeasibility +status=5 : Detected unboundedness of relaxation +status=6 : Reached limit on gap +status=7 : Reached limit on number of solutions +status=8 : Reached iteration limit +status=9 : Interrupted +status=10 : Reached time limit +status=11 : Reached the limit on number of solutions +status=12 : Finished for some other reason + + + +The routine uses Minotaur Library for solving the quadratic problem, Minotaur is a library written in C++. + + + + + + + Examples + = x^2 + y^2 - x - y >= -100 +// -10 <= x <= 6 +// -10 <= y <= 6 + +n = 2; +m = 1; +h_obj = [-2, -1; -2, 4]; +f_obj = [4, -5]; +c_obj = 100; +h_con = list(); +h_con(1) = [2, 0; 0, 2]; +f_con = list(); +f_con(1) = [-1, -1]; +lb_con = [-100]; +ub_con = [60]; +maxcputime = 600; +lb_var = [-10, -10]; +ub_var = [6, 6]; +[kSoln, kSolnVector, status] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var, maxcputime); +kSoln +kSolnVector +status + + ]]> + + + + Authors + + Souvik Das + + + diff --git a/help/en_US/tsp.xml b/help/en_US/tsp.xml new file mode 100644 index 0000000..e730c38 --- /dev/null +++ b/help/en_US/tsp.xml @@ -0,0 +1,221 @@ + + + + + + + + tsp + Solves the classic 'Travelling Salesman Problem' heuristically using the routing library from the Google-OR-tools framework. The algorithm first employs a cheapest path approach for an initial solution and then 'local search' heuristics to improve the initial solution toward an optimal one. + + + + + Calling Sequence + + [mincost,path]=tsp(adj_matrix,start_node) + [mincost,path]=tsp(adj_matrix,start_node,labels) + [mincost,path,status]=tsp(adj_matrix,start_node) + [mincost,path,status]=tsp(adj_matrix,start_node, labels) + + + + + + Parameters + + adj_matrix : + It is an [nxn] Adjacency Matrix of integral values, representing the graph (having 'n' nodes, for instance, numbered from '1' to 'n') for which the Travelling Saleman Problem is to be solved. Value adj_matrix(i,j) represents the cost of travelling from node 'i' to node 'j' of the given graph. Asymmetric graphs are also supported, where adj(i,j) <> adj(j,i). A negative value for cost (adj_matrix(i,j)) is simply interpreted as the absence of an edge from node 'i' to node 'j'. + start_node : + It is the index of the starting node. The optimal path must start and end at this node. + labels : + Optional functionality to provide string labels to the nodes of the graph. It is a [1xn] vector of strings. (labels(i) is the label given to the node 'i' of the graph + time_limit : + It is the maximum time (in milliseconds; integral value) for which the optimizer is allowed to run. If by the end of this time, the engine is unable to find even an initial solution, a timeout error status is returned. If, however, an initial solution is found, but not fully optimized yet (in the process of heuristically improving it), it will return the current solution, albeit not optimal, as the final solution. This value cannot be zero. Default : 1 second. + mincost : + It is an integral value denoting the minimum cost incurred by the "salesman" in traversing the optimal path according to the solution, should one exist.) + path : + It is a [1x(n+1)] vector containing indices of nodes in the order of the path to be followed in the optimal solution, should one exist. The first and the last values in this vector are equal to the 'start_node' index provided. + status : + It is the enumerated "flag" value returned by the Google OR tools Routing Library, indicating the status of the solution.(Details in the description) + + + + + Description + + +\text{The \textbf{`Travelling Salesman Problem' } is a classic optimization problem which, given a graph (wherein each edge has some cost/distance associated with it), and an arbitrary `starting node' , vies to find such a path over the said graph so as to visit every vertex exactly once and ending back at the `start\_node' \textbf{(Hamiltonian path) }, while minimizing the total cost/distance of the journey.\\This is aptly explained by the namesake analogy of a `salesman' who needs to decide upon a path through various cities (nodes) while minimizing his travel distance, hence the travel expenditures.\\Travelling salesman problem is essentially a special case of the \textbf{Vehicle Routing Problem}.\\This routine utlizes the 'Routing Model' from the Google OR Tools framework to solve the problem. A \textbf{`cheapest addition' } heuristic is applied to find the initial solution and then \textbf{`local search' } is used to improve it toward an optimal solution.\\\textbf{Asymmetric Travelling Saleman Problem } is also supported, where the cost of travelling from city `i' to city `j' is not the same as cost of travelling from city `j' to city `i' (In this case, the input adjacency matrix is simply not a symmetric matrix)}\\ +\text{}\\ +\text{}\\ +\text{}\\ +\text{\textbf{\underline{MATHEMATICAL\textbf{ }STATEMENT} :}}\\ +\text{}\\ +\text{}\\ +\text{}\\ + + + + +\begin{math} +\text{Let }x_{ij} = \begin{cases} +1 \quad \text{; if there exists a path from node i to j}\\ +0 \quad \text{; otherwise}\\ +\end{cases}\\\\ +\text{Let their be `n' nodes in the problem}\\ +\text{Let } c_{ij} \text{ be the distance from node i to node j}\\\\ +\text{Let }u_{i} \text{ be a dummy variable for } i=1,2,...,n \text{ ;}\\\\ +\textbf{\underline{Objective }:}\qquad Minimize \sum_{i=1}^{n} \sum_{j \neq i, j=1}^{n} c_{ij} x_{ij} \\\\ +\text{ Subject to :} +\text{ }\qquad 0 \leq x_{ij} \leq 1 \text{ ;} \qquad i,j = 1,2,...,n \text{ ;}\qquad \hspace{3em} \qquad (1)\\\\ +\text{ }\qquad \hspace{3em} \text{ } \qquad u_{i} \in Z \text{ ; }\qquad \qquad i = 1,2,...,n \text{ ; }\qquad \hspace{3em} \qquad \text{ }(2)\\\\ +\text{ }\qquad \hspace{3em} \text{ } \qquad \sum_{i=1,i\neq j}^{n} x_{ij}=1 \text{ ; } j=1,2,...,n \text{ ; } \qquad \hspace{3em} \qquad (3)\\\\ +\text{ }\qquad \hspace{3em} \text{ } \qquad \sum_{j=1,j\neq i}^{n} x_{ij}=1 \text{ ; } i=1,2,...,n \text{ ; } \qquad \hspace{3em} \qquad (4)\\\\ +\text{ }\qquad \hspace{3em} \text{ } \qquad u_{i} - u_{j} + n x_{ij} \leq n-1 \text{ ; }\qquad 2\leq i\neq j \leq n \text{ ; } \qquad (5)\\\\ +\text{ (3),(4) enforce that each node can only be arrived from exactly one other node.}\\\\ +\text{ (5) enforces that there's only a single tour connecting all the node ( Hamiltonian cycle) } +\end{math} +\text{}\\ +\text{}\\ +\text{}\\ +\text{}\\ + + + +Legend : + + +status - Integral value returned by the Google OR Tools Routing library, indicating the status of the solution for the current TSP + +status=0 - ROUTING_NOT_SOLVED (Before the solver is invoked) +status=1 - ROUTING_SUCCESS (TSP solved successfully(optimal solution found) +status=2 - ROUTING_FAIL(No solution found) +status=3 - ROUTING_FAIL_TIMEOUT (solution was taking too much time; Timed out) + + + +For more details, refer to : https://en.wikipedia.org/wiki/Travelling_salesman_problem + + +or to : https://developers.google.com/optimization/routing/tsp/tsp + + +The problem is also related to the HAMILTONIAN PATH problem : https://en.wikipedia.org/wiki/Hamiltonian_path + + + + + + + + + Examples + 120 +//Optimal Path :- +//1 ->2 ->3 ->4 ->1 + + ]]> + + + + Examples + 80 +//Optimal Path :- +// A (1) -> B (2) -> D (4) -> C (3) ->A (1) + + ]]> + + + + Examples + 5 +//Optimal Path :- +// alpha (1) -> sigma (5) -> beta (2) -> gamma (3) -> theta (4) ->alpha (1) + + ]]> + + + + Examples + + + + + Authors + + Samuel Wilson + + + diff --git a/help/en_US/vrp.xml b/help/en_US/vrp.xml new file mode 100644 index 0000000..e2aee08 --- /dev/null +++ b/help/en_US/vrp.xml @@ -0,0 +1,249 @@ + + + + + + + + vrp + Solves the classic 'Vehicle Routing Problem' (VRP for short) heuristically to find the optimal set of routes for a fleet of vehicles delivering goods or services to various locations. The routine makes use of the routing library from the Google-OR-Tools framework. The algorithm first employs a cheapest path approach for an initial naive solution and then 'local search' heuristics to improve it toward an optimal solution. + + + + + Calling Sequence + + [total_distance,routes] = vrp(adj_matrix,vehicles,start) + [total_distance,routes] = vrp(adj_matrix,vehicles,start,labels) + [total_distance,routes] = vrp(adj_matrix,vehicles,start,labels,demands,max_vehicle_capacity) + [total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand) + [total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows) + [total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds) + [total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times) + [total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times,refuel_flag,fuel_capacity,refuel_nodes) + [total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times,refuel_flag,fuel_capacity,refuel_nodes,penalty) + [total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times,refuel_flag,fuel_capacity,refuel_nodes,penalty,groups,group_penalty) + [total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times,refuel_flag,fuel_capacity,refuel_nodes,penalty,groups,group_penalty,time_limit) + [total_distance,routes,distances] = vrp(...) + [total_distance,routes,distances,total_time] = vrp(...) + [total_distance,routes,distances,total_time,times] = vrp(...) + [total_distance,routes,distances,total_time,times,status] = vrp(...) + + + + + + Parameters + + **NOTE : + for the sake of simplicity, henceforth 'v' would denote the number of vehicles in the problem and 'n', the number of nodes in the graph + adj_matrix : + It is an [nxn] matrix of integral values, representing the graph (nodes indexed from '1' to 'n') for which the given VRP is to be solved. adj_matrix[i][j] gives the distance from node 'i' to 'j'.(can be different from adj_matrix[j][i]; asymmetric VRP). A negative value indicates the absence of a path from 'i' to 'j'. + vehicles : + It is an integral value representing the number of vehicles in the fleet, such that we need to find a optimum route for each vehicle, to minimize the total distance and total time. + start : + It is a matrix of integral values, pertaining to the index of the starting node(s) or depot(s). The dimensions of this matrix is germane to the type of VRP given, hence determines the pertinent solution strategy. The variations are :-[1x1] - A single integral value - indicating a single depot. All vehicles start and end their journey at this node.[ ] - Empty Matrix - indicating that the vehicle routes can start and end at any node, defining a taxi-service-like scenario.[vx2] - An integral matrix specifying particular start and end nodes for each vehicle ( multiple depot case). start[x][0] -> Start node index for vehicle 'x' ; start[x][1] -> End node for vehicle 'x'. + labels : + Optional functionality to provide string labels to the nodes of the graph. It is a [1xn] vector of strings. + demands : + It is a [1xn] vector of integral values indicating the demands for the various nodes to be fulfiled by the vehicles. demands[x] denotes the demand of node 'x'. (Demands obviously cannot be negative). + max_vehicle_capacity : + It is an integral value specifying the maximum capacity of each vehicle (same for all). If capacitated VRP (demands specified), this has to be provided and must be POSITIVE. Can be '0' or empty matrix for non-capacitated VRP. + service_time_per_demand : + It a single integral value indicating the time required to service one unit of demand in capacitated VRP. + time_windows : + It is an [nx2] matrix of integral values specifying particular windows of time only within which the different nodes can be serviced. time_windows[x][0]->start of service window for node x ; time_windows[x][1]->end of service window for node 'x'. Can be empty if no time-window constraints. If provided, for a node with no such restriction, provide '0' and '-1'. Time starts from '0' for the model. + speeds : + It is a matrix of integral values specifying the speed of the vehicles. The variations are :- empty matrix - Indicates that transit times are to be ignored while minimizing total-time for the optimal route. [1x1] - single value - Same avg. speed for all vehicles between any two nodes. [nxn] - A matrix specifying different avg.speeds between different nodes. speed[x][y]-> Gives the average speed while going from node 'x' to node 'y'. (Asymmetric speeds supported) + waiting_times : + a [1xn] vector of integral values containing the waiting times, if any, at the nodes. Could be empty if no waiting constraints. + refuel_flag : + a single integral value indicating if fuel constraints are to be considered or not.(Default : '0') '0'->No fuel constraints '1' ->Fuel constraints to be included in the model. + fuel_capacity : + a single integral value specifying the fuel capacity of the vehicles under consideration (same for all). Need to be provided if refueling constraints active. Needs to be positive. + refuel_nodes : + It is a [1xA] vector of integral values (A-> no. of refuel nodes), containing the indices of refueling nodes. Could be empty indicating the absence of refuel nodes. + penalty : + It is an [Ax2] matrix containing the cost penalties for skipping certain optional nodes (A->no. of optional nodes). penalty[x][0]-> The index of the optional node ; penalty[x][1]-> The cost penalty associated with that node. + groups : + It is an [AxB] matrix of integral values specifying groups of nodes that must lie on the same vehicle route. A-> No. of groups. B-> Size of the largest group. Each row contains the indices of a separate group. Smaller groups are padded with '0's on the right. + group_penalty : + It is a single integral value specifying the cost penalty incurred if a node from a group is unable to be serviced by the same vehicle in the optimal solution. This value is mandatory if group constraints are included in the model. (The model tends to minimize total distance and total time, while amassing minimal cost penalties ( legible tradeoffs to minimize distance ). USE -1, if the groups are to be strictly imposed (cannot exclude a node from a group while vying to minimize distance). This value CAN be zero, indicating that grouping constraints are purely optional. Default value : -1. + time_limit : + It is the maximum time (in milliseconds; integral value) for which the optimizer is allowed to run. If by the end of this time, the engine is unable to find even an initial solution, a timeout error status is returned. If, however, an initial solution is found, but not fully optimized yet (in the process of heuristically improving it), it will return the current solution, albeit not optimal, as the final solution. This value cannot be zero. Default : 10 seconds. + total_distance : + It is the summation of the total distance for all the routes in the optimal solution, if any. + routes : + It is a [vxn] matrix containing the routes for the vehicles in the optimal solution, if any. (padded with 0's on the right) + distances : + It is a [1xv] vector containing the distances covered by the various routes in the optimal solution. + total_time : + It is the summation of the times taken by the various vehicles to complete their journeys. + times : + It is a [1xv] vector containing the individual times taken by the vehicles to complete their routes. + status : + It is the enumerated "flag" value returned by the Google OR tools Routing Library, indicating the status of the solution.(Details in the description) + + + + + Description + + +\text{The \textbf{`Vehicle Routing Problem' } is a combinatorial optimization and linear integer programming problem in graph theory.\\A superset of the well-known \textbf{Travelling Salesman Problem}, it vies to find an optimal set of non-overlapping routes for a fleet of vehicles (the anecdotal ``salesmen"), passing through a given set of cities(nodes in the graph) starting from one or more starting nodes called the \textbf{`depot(s)'}.\\In the pursuit of optimality, it tends to minimize the \textbf{total distance } across all the routes and/or other parameters specified by the user, like \textbf{`time'}, \textbf{`cost'}, etc.}\\ +\text{}\\ +\text{}\\ +\text{}\\ +\text{\textbf{\underline{MATHEMATICAL\textbf{ }STATEMENT} :}}\\ +\text{}\\ +\text{}\\ +\text{}\\ + + +\begin{math} +\text{Let } N= \left(V,E\right) \text{denote the specified graph}\\ +\text{Let } c_{ij} \text{ denote the distance from } i \to j.\\\\ +\textbf{\underline{Objective} : }\quad Minimize \quad \sum_{i \in V} \sum_{j \in V} c_{ij} x_{ij} \\\\\\ +\text{Subject to :} \qquad +\sum_{i\in V} x_{ij} = 1 \quad \forall \quad j \in V\backslash\{0\}\qquad (1) \\\\ +\text{}\\ +\text{}\qquad \hspace{3em} \qquad \sum_{j\in V} x_{ij} = 1 \quad \forall \quad i \in V\backslash\{0\}\qquad \text{ } (2) \\\\ +\text{}\\ +\text{}\qquad \hspace{3em} \qquad \sum_{i\in V} x_{i0} = K\quad \text{;} \qquad \hspace{3em} \qquad\text{ } (3)\\\\ +\text{}\\ +\text{}\qquad \hspace{3em} \qquad \sum_{j\in V} x_{0j} = K\quad \text{;} \qquad \hspace{3em} \qquad\text{ } (4)\\\\ +\text{}\\ +\text{}\qquad \hspace{3em} \qquad x_{ij} \in \{0,1\} \quad \forall \quad i,j \in V \text{ ; } \hspace{3em} \text{ } (5)\\\\ +\text{}\\ +\end{math} +\text{}\\ +\text{}\\ + + + + +\text{}\\ +\text{}\\ +\text{(1), (2) specify that exactly one arc enters and one arc leaves each node in the solution.}\\ +\text{}\\ +\text{(3), (4) specify that the total number of leaving the depot is equal to the total number entering it(single depot mode).} +\text{}\\ +\text{}\\ +\text{}\\ + + + +Legend : + + +status - Integral value returned by the Google OR Tools Routing library, indicating the status of the solution for the current VRP + +status=0 - ROUTING_NOT_SOLVED (Before the solver is invoked) +status=1 - ROUTING_SUCCESS (TSP solved successfully(optimal solution found) +status=2 - ROUTING_FAIL(No solution found) +status=3 - ROUTING_FAIL_TIMEOUT (solution was taking too long; Timed out) + + + +For more details, refer to : https://en.wikipedia.org/wiki/Vehicle_routing_problem + + +or to : https://developers.google.com/optimization/routing/tsp/vehicle_routing#cvrp + + +The problem is also related to the HAMILTONIAN PATH problem : https://en.wikipedia.org/wiki/Hamiltonian_path + + + + + + + + + Examples + + + + + Examples + + + + + Authors + + Samuel Wilson + + + diff --git a/macros/Checkdims.sci b/macros/Checkdims.sci new file mode 100644 index 0000000..0936222 --- /dev/null +++ b/macros/Checkdims.sci @@ -0,0 +1,56 @@ + +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the GNU LGPL license. + +function errmsg = Checkdims ( funname , var , varname , ivar , matdims ) + // Generates an error if the variable has not the required size. + // + // Calling Sequence + // errmsg = Checkdims ( funname , var , varname , ivar , matdims ) + // + // Parameters + // funname : a 1 x 1 matrix of strings, the name of the calling function. + // var : a 1 x 1 matrix of valid Scilab data type, the variable + // varname : a 1 x 1 matrix of string, the name of the variable + // ivar : a 1 x 1 matrix of floating point integers, the index of the input argument in the calling sequence + // matdims : 1 x 2 matrix of floating point integers, the number of rows, columns for the variable #ivar + // errmsg : a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + // + // Description + // This function is designed to be used to design functions where + // the input argument has a known shape. + // This function cannot be use when var is a function, or more + // generally, for any input argument for which the size function + // does not work. + // Last update : 05/08/2010. + // + // Examples + // // The function takes a 2 x 3 matrix of doubles. + // function y = myfunction ( x ) + // Checkdims ( "myfunction" , x , "x" , 1 , [2 3] ) + // y = x + // endfunction + // // Calling sequences which work + // y = myfunction ( ones(2,3) ) + // y = myfunction ( zeros(2,3) ) + // // Calling sequences which generate an error + // y = myfunction ( ones(1,3) ) + // y = myfunction ( zeros(2,4) ) + // + // Authors + // Michael Baudin - 2010 - DIGITEO + // + + [lhs,rhs]=argn() + Checkrhs ( funname , rhs , 5 ) + Checklhs ( funname , lhs , [0 1] ) + + errmsg = [] + if ( or ( size(var) <> matdims ) ) then + strexp = strcat(string(matdims)," ") + strcomp = strcat(string(size(var))," ") + errmsg = msprintf(gettext("%s: Expected size [%s] for input argument %s at input #%d, but got [%s] instead."), funname, strexp, varname , ivar , strcomp ); + error(errmsg) + end +endfunction diff --git a/macros/Checklhs.sci b/macros/Checklhs.sci new file mode 100644 index 0000000..fd47b0c --- /dev/null +++ b/macros/Checklhs.sci @@ -0,0 +1,79 @@ +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the GNU LGPL license. + +function errmsg = Checklhs ( funname , lhs , lhsset ) + // Generates an error if the number of LHS is not in given set. + // + // Calling Sequence + // errmsg = Checklhs ( funname , lhs , lhsset ) + // + // Parameters + // funname : a 1 x 1 matrix of strings, the name of the calling function. + // lhs : a 1 x 1 matrix of floating point integers, the actual number of output arguments + // lhsset : a 1 x n or n x 1 matrix of floating point integers, the authorized number of output arguments + // errmsg : a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + // + // Description + // This function is designed to be used to design functions with + // variable number of output arguments. + // Notice that it is useless to call this function if the + // function definition does not use the varargout statement. + // Notice that a function as a minimum of 1 output argument. + // Last update : 29/07/2010. + // + // Examples + // // The function takes 3 input arguments and 1/2 output arguments + // function varargout = myfunction ( x1 , x2 , x3 ) + // [lhs, rhs] = argn() + // Checkrhs ( "myfunction" , rhs , 3 : 3 ) + // Checklhs ( "myfunction" , lhs , 1 : 2 ) + // y1 = x1 + x2 + // y2 = x2 + x3 + // varargout(1) = y1 + // if ( lhs == 2 ) then + // varargout(2) = y2 + // end + // endfunction + // // Calling sequences which work + // myfunction ( 1 , 2 , 3 ) + // y1 = myfunction ( 1 , 2 , 3 ) + // [ y1 , y2 ] = myfunction ( 1 , 2 , 3 ) + // // Calling sequences which generate an error + // [ y1 , y2 , y3 ] = myfunction ( 1 , 2 , 3 ) + // + // // The function takes 1 or 3 output arguments, but not 2 + // function varargout = myfunction ( x1 , x2 , x3 ) + // [lhs, rhs] = argn() + // Checkrhs ( "myfunction" , rhs , 3 : 3 ) + // Checklhs ( "myfunction" , lhs , [1 3] ) + // y1 = x1 + x2 + // y2 = x2 + x3 + // y3 = x1 + x3 + // varargout(1) = y1 + // if ( lhs == 3 ) then + // varargout(2) = y2 + // varargout(3) = y3 + // end + // endfunction + // // Calling sequences which work + // myfunction ( 1 , 2 , 3 ) + // y1 = myfunction ( 1 , 2 , 3 ) + // [ y1 , y2 , y3 ] = myfunction ( 1 , 2 , 3 ) + // // Calling sequences which generate an error + // [y1 , y2] = myfunction ( 1 , 2 , 3 ) + // + // Authors + // Michael Baudin - 2010 - DIGITEO + // + + errmsg = [] + if ( and ( lhs <> lhsset ) ) then + lhsstr = strcat(string(lhsset)," ") + errmsg = msprintf(gettext("%s: Unexpected number of output arguments : %d provided while the expected number of output arguments should be in the set [%s]."), funname , lhs , lhsstr ); + error(errmsg) + end +endfunction + + + diff --git a/macros/Checkrhs.sci b/macros/Checkrhs.sci new file mode 100644 index 0000000..6b5cf5b --- /dev/null +++ b/macros/Checkrhs.sci @@ -0,0 +1,102 @@ +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the GNU LGPL license. + +function errmsg = Checkrhs ( funname , rhs , rhsset ) + // Generates an error if the number of RHS is not in given set. + // + // Calling Sequence + // errmsg = Checkrhs ( funname , rhs , rhsset ) + // + // Parameters + // funname : a 1 x 1 matrix of strings, the name of the calling function. + // rhs : a 1 x 1 matrix of floating point integers, the actual number of input arguments + // rhsset : a 1 x n or n x 1 matrix of floating point integers, the authorized number of input arguments + // errmsg : a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + // + // Description + // This function is designed to be used to design functions with + // variable number of input arguments. + // Notice that it is useless to call this function if the + // function definition does not use the varargin statement. + // Last update : 05/08/2010. + // Last update : 29/07/2010. + // + // Examples + // // The function takes 2/3 input arguments and 1 output arguments + // function y = myfunction ( varargin ) + // [lhs, rhs] = argn() + // Checkrhs ( "myfunction" , rhs , 2:3 ) + // Checklhs ( "myfunction" , lhs , 1 ) + // x1 = varargin(1) + // x2 = varargin(2) + // if ( rhs >= 3 ) then + // x3 = varargin(3) + // else + // x3 = 2 + // end + // y = x1 + x2 + x3 + // endfunction + // // Calling sequences which work + // y = myfunction ( 1 , 2 ) + // y = myfunction ( 1 , 2 , 3 ) + // // Calling sequences which generate an error + // y = myfunction ( 1 ) + // y = myfunction ( 1 , 2 , 3 , 4 ) + // + // // The function takes 2 or 4 input arguments, but not 3 + // function y = myfunction ( varargin ) + // [lhs, rhs] = argn() + // Checkrhs ( "myfunction" , rhs , [2 4] ) + // Checklhs ( "myfunction" , lhs , 1 ) + // x1 = varargin(1) + // x2 = varargin(2) + // if ( rhs >= 3 ) then + // x3 = varargin(3) + // x4 = varargin(4) + // else + // x3 = 2 + // x4 = 3 + // end + // y = x1 + x2 + x3 + x4 + // endfunction + // // Calling sequences which work + // y = myfunction ( 1 , 2 ) + // y = myfunction ( 1 , 2 , 3 , 4 ) + // // Calling sequences which generate an error + // y = myfunction ( 1 ) + // y = myfunction ( 1 , 2 , 3 ) + // y = myfunction ( 1 , 2 , 3 , 4, 5 ) + // + // // The function takes 2 input arguments and 0/1 output arguments. + // // Notice that if the checkrhs function is not called, + // // the variable x2 might be used from the user's context, + // // that is, if the caller has defined the variable x2, it + // // is used in the callee. + // // Here, we want to avoid this. + // function y = myfunction ( x1 , x2 ) + // [lhs, rhs] = argn() + // Checkrhs ( "myfunction" , rhs , 2 ) + // Checklhs ( "myfunction" , lhs , [0 1] ) + // y = x1 + x2 + // endfunction + // // Calling sequences which work + // y = myfunction ( 1 , 2 ) + // // Calling sequences which generate an error + // y = myfunction ( 1 ) + // y = myfunction ( 1 , 2 , 3 ) + // + // Authors + // Michael Baudin - 2010 - DIGITEO + // + + errmsg = [] + if ( and(rhs <> rhsset) ) then + rhsstr = strcat(string(rhsset)," ") + errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while the number of expected input arguments should be in the set [%s]."), funname , rhs , rhsstr ); + error(errmsg) + end +endfunction + + + diff --git a/macros/Checktype.sci b/macros/Checktype.sci new file mode 100644 index 0000000..3f50fa2 --- /dev/null +++ b/macros/Checktype.sci @@ -0,0 +1,65 @@ +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the GNU LGPL license. + +function errmsg = Checktype ( funname , var , varname , ivar , expectedtype ) + // Generates an error if the given variable is not of expected type. + // + // Calling Sequence + // errmsg = Checktype ( funname , var , varname , ivar , expectedtype ) + // + // Parameters + // funname : a 1 x 1 matrix of strings, the name of the calling function. + // var : a 1 x 1 matrix of valid Scilab data type, the variable + // varname : a 1 x 1 matrix of string, the name of the variable + // ivar : a 1 x 1 matrix of floating point integers, the index of the input argument in the calling sequence + // expectedtype : a n x 1 or 1 x n matrix of strings, the available types for the variable #ivar + // errmsg : a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + // + // Description + // This function is designed to be used to design functions with + // input arguments with variable type. + // We use the typeof function to compute the type of the variable: + // see help typeof to get the list of all available values for expectedtype. + // Last update : 29/07/2010. + // + // Examples + // // The function takes a string argument. + // function myfunction ( x ) + // Checktype ( "myfunction" , x , "x" , 1 , "string" ) + // disp("This is a string") + // endfunction + // // Calling sequences which work + // myfunction ( "Scilab" ) + // // Calling sequences which generate an error + // myfunction ( 123456 ) + // + // // The function takes a string or a matrix of doubles argument. + // function myfunction ( x ) + // Checktype ( "myfunction" , x , "x" , 1 , [ "string" "constant" ] ) + // if ( typeof(x) == "string" ) then + // disp("This is a matrix of strings") + // else + // disp("This is a matrix of doubles") + // end + // endfunction + // // Calling sequences which work + // myfunction ( "Scilab" ) + // myfunction ( 123456 ) + // // Calling sequences which generate an error + // myfunction ( uint8(2) ) + // + // Authors + // Michael Baudin - 2010 - DIGITEO + // + + errmsg = [] + if ( and ( typeof ( var ) <> expectedtype ) ) then + strexp = """" + strcat(expectedtype,""" or """) + """" + errmsg = msprintf(gettext("%s: Expected type [%s] for input argument %s at input #%d, but got ""%s"" instead."),funname, strexp, varname , ivar , typeof(var) ); + error(errmsg); + end +endfunction + + + diff --git a/macros/Checkvector.sci b/macros/Checkvector.sci new file mode 100644 index 0000000..76bdcc6 --- /dev/null +++ b/macros/Checkvector.sci @@ -0,0 +1,63 @@ +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the GNU LGPL license. + +function errmsg = Checkvector ( funname , var , varname , ivar , nbval ) + // Generates an error if the variable is not a vector. + // + // Calling Sequence + // errmsg = Checkvector ( funname , var , varname , ivar ) + // + // Parameters + // funname : a 1 x 1 matrix of strings, the name of the calling function. + // var : a 1 x 1 matrix of valid Scilab data type, the variable + // varname : a 1 x 1 matrix of string, the name of the variable + // ivar : a 1 x 1 matrix of floating point integers, the index of the input argument in the calling sequence + // nbval : a 1 x 1 matrix of floating point integers, the number of entries in the vector. + // errmsg : a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + // + // Description + // This function is designed to be used to design functions where + // the input argument is a vector, that is, a matrix for which + // nrows == 1 or ncols == 1. + // This function cannot be use when var is a function, or more + // generally, for any input argument for which the size function + // does not work. + // + // Examples + // // The function takes a vector of 3 doubles. + // function y = myfunction ( x ) + // Checkvector ( "myfunction" , x , "x" , 1 , 3 ) + // y = x + // endfunction + // // Calling sequences which work + // y = myfunction ( ones(1,3) ) + // y = myfunction ( zeros(3,1) ) + // // Calling sequences which generate an error + // // The following are not vectors + // y = myfunction ( ones(2,3) ) + // y = myfunction ( zeros(3,2) ) + // // The following have the wrong number of entries + // y = myfunction ( ones(1,3) ) + // + // Authors + // Michael Baudin - 2010 - DIGITEO + // + + errmsg = [] + nrows = size(var,"r") + ncols = size(var,"c") + if ( nrows <> 1 & ncols <> 1 ) then + strcomp = strcat(string(size(var))," ") + errmsg = msprintf(gettext("%s: Expected a vector matrix for input argument %s at input #%d, but got [%s] instead."), funname, varname , ivar , strcomp ); + error(errmsg) + end + if ( ( nrows == 1 & ncols <> nbval ) | ( ncols == 1 & nrows <> nbval ) ) then + strcomp = strcat(string(size(var))," ") + errmsg = msprintf(gettext("%s: Expected %d entries for input argument %s at input #%d, but current dimensions are [%s] instead."), funname, nbval , varname , ivar , strcomp ); + error(errmsg) + end +endfunction + + + diff --git a/macros/Filterdims.sci b/macros/Filterdims.sci new file mode 100644 index 0000000..49d2848 --- /dev/null +++ b/macros/Filterdims.sci @@ -0,0 +1,60 @@ + +// Copyright (C) 2010 - DIGITEO - Michael Baudin +// +// This file must be used under the terms of the GNU LGPL license. + +function var = Filterdims ( funname , var , varname , ivar , matdims ) + // Generates an error if the variable has not the required size. + // + // Calling Sequence + // errmsg = Filterdims ( funname , var , varname , ivar , matdims ) + // + // Parameters + // funname : a 1 x 1 matrix of strings, the name of the calling function. + // var : a 1 x 1 matrix of valid Scilab data type, the variable + // varname : a 1 x 1 matrix of string, the name of the variable + // ivar : a 1 x 1 matrix of floating point integers, the index of the input argument in the calling sequence + // matdims : 1 x 2 matrix of floating point integers, the number of rows, columns for the variable #ivar + // errmsg : a 1 x 1 matrix of strings, the error message. If there was no error, the error message is the empty matrix. + // + // Description + // This function is designed to be used to design functions where + // the input argument has a known shape. + // This function cannot be use when var is a function, or more + // generally, for any input argument for which the size function + // does not work. + // Last update : 05/08/2010. + // + // Examples + // // The function takes a 2 x 3 matrix of doubles. + // function y = myfunction ( x ) + // Filterdims ( "myfunction" , x , "x" , 1 , [2 3] ) + // y = x + // endfunction + // // Calling sequences which work + // y = myfunction ( ones(2,3) ) + // y = myfunction ( zeros(2,3) ) + // // Calling sequences which generate an error + // y = myfunction ( ones(1,3) ) + // y = myfunction ( zeros(2,4) ) + // + // Authors + // Michael Baudin - 2010 - DIGITEO + // + + [lhs,rhs]=argn() + Checkrhs ( funname , rhs , 5 ) + Checklhs ( funname , lhs , [0 1] ) + + if ( or ( size(var) <> matdims ) ) then + if ( ( typeof(var) == "constant" ) & ( size(var, 'r') <> size(var, 'c') ) & ( size(var') == matdims ) ) then + var = var'; + warning("Transposing vector/matrix ''" + varname + "'' to get compatible dimensions"); + return; + end + strexp = strcat(string(matdims)," ") + strcomp = strcat(string(size(var))," ") + errmsg = msprintf(gettext("%s: Expected size [%s] for input argument %s at input #%d, but got [%s] instead."), funname, strexp, varname , ivar , strcomp ); + error(errmsg) + end +endfunction diff --git a/macros/buildmacros.sce b/macros/buildmacros.sce new file mode 100644 index 0000000..b3bcd2e --- /dev/null +++ b/macros/buildmacros.sce @@ -0,0 +1 @@ +tbx_build_macros(TOOLBOX_NAME, get_absolute_file_path("buildmacros.sce")); diff --git a/macros/fmaxflow.sci b/macros/fmaxflow.sci new file mode 100644 index 0000000..0f72695 --- /dev/null +++ b/macros/fmaxflow.sci @@ -0,0 +1,270 @@ +function [maxflow,arcflows,status] = fmaxflow(varargin) + //Solves the graph max-flow problem(a linear optimization problem) using an implementation of the push-relabel algorithm + // + //Calling Sequence + //[maxflow,arcflows]=fmaxflow(start_nodes,end_nodes,capacities,st) + //[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st) + // + //Parameters + //start_nodes : a [1xn] vector (if the graph has 'n' arcs, for instance) of integral values which stores the numerical label of the start-nodes (tail-nodes) for each arc of the graph. + //end_nodes : a [1xn] vector of integral values which stores the value (numerical label) of the end-nodes(head-nodes) for each arc of the graph. + //capacities : a [1xn] vector of integral values which stores the capacities (max amount possible over a particular arc) of the respective arcs. Eg. The capacity at index 'i' of this matrix means the maximum amount possible over the arc defined by start_node[i]->end_node[i]. + //st : a [1x2] vector which stores the numerical-label (value) of the source node and the target node, respectively. + //maxflow : a double representing the Maximum total Flow possible(i.e. Solution) through the system in the optimal solution, should there be one. + //arcflows : a [1xn] vector of double (if the graph has 'n' arcs, for instance) which represents the actual flow through the respective arcs in the optimal solution of the problem, should one exist. + //status : status flag returned by the Google OR-tools MaxFlow Solver function (details below) + // + //Description + // + //\text{The \textbf{`Maximum-Flow' Problem } is a classic (linear) optimization problem for Flow Networks}^{*}\text{. Essentially a part of the class of \textbf{`Circulation Problems'}, it involves finding the maximum amount of flow possible from a specified (source) node to another (sink) node, in a given network.}\\ + //\text{}\\ + //^{*}\text{\underline{\textbf{Flow Network}} - A flow network (also called a `transportation network'), in graph theory, is essentially a directed graph with one (or more) \textbf{source} node(s) and one (or more) \textbf{sink} node(s) and several other standard nodes, connected by edges called \textbf{`arcs'}.}\\ + //\text{\textbf{`Flow'} is any entity that circulates through the network, from the source to the sink. Eg. electric current in a printed circuit, water in a plumbing network, etc.}\\ + //\text{}\\\\ + //\text{}\\\\ + //\text{\textbf{\underline{MATHEMATICAL STATEMENT} :}}\\ + //\text{}\\ + //\text{}\\ + // + // + //\begin{math} + //\text{Let } N= \left(V,E\right) \text{ be a network with } s,t \in V \text{ denoting the source and sink nodes in } N\text{, respectively.}\\\\ + //\text{Let } c_{uv} \text{ or } c\left(u,v\right) \text{ denote the capacity of the arc between node } u \text{ and } v.\\ + //\text{capacity is a mapping } c:V\to R^{+} \\\\ + //\text{Let } f_{uv} \text{ or } f\left(u,v)\right) \text{ denotes the flow between node } u \text{ and } v, \text{such that :}\\ + //\text{ 1. } f_{uv} \leq c_{uv} \quad \forall \quad (u,v) \in E.\\ + //\text{ 2. } \sum_{u:(u,v)\in E} f_{uv} = \sum_{u:(v,u) \in E} f_{vu}\quad \forall \quad v \in V \backslash \{s,t\}\quad\text{; conservation of flow}\\\\\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + //\textbf{\underline{Objective} :} + //\text{}\qquad\qquad\qquad Maximize \quad |f| = \sum_{v:(s,v) \in E}f_{sv} \text{,where }s\text{ is the source vertex for } N.\\\\ + //\text{}\qquad\qquad\qquad\text{}\qquad\qquad\qquad |f| \text{ denotes the total amount of flow passing from the source to the sink}\\ + //\end{math} + //\text{}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + // + // + //status- the status of solution returned by the linked Google OR-Tools max-flow solver + // + //status=0 - OPTIMAL(An optimal solution was found) + //status=1 - INT_OVERFLOW(There is a feasible flow > max possible flow) + //status=2 - BAD_INPUT(The input is inconsistent) + //status=3 - BAD_RESULT (There was an error) + // + // + // + //Examples + // + //start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3] + //end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4] + //capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20] + //st=[0,4] + //[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st) + //// Press Enter to continue + ////Output + ////Max flow = 60 + ////Arc Flow Capacity + ////0->1 20 20 + ////0->2 30 30 + ////0->3 10 10 + ////1->2 0 40 + ////1->4 20 30 + ////2->3 10 10 + ////2->4 20 20 + ////3->2 0 5 + ////3->4 20 20 + // + ////An optimal solution was found + //// status = + //// + //// 0 + //// arcflows = + //// + //// 20 30 10 0 20 10 20 0 20 + //// maxflow = + //// + //// 60 + // + // + //Examples + // + //start_nodes = [1, 1, 2, 2, 3, 3, 0] + //end_nodes = [2, 4, 3, 4, 2, 4, 5] + //capacities = [40, 30, 10, 20, 5, 20, 50] + //st=[0,4] + //[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st) + ////Press Enter to continue + //// Output + //// Max flow = 0 + ////Arc Flow Capacity + ////1->2 0 40 + ////1->4 0 30 + ////2->3 0 10 + ////2->4 0 20 + ////3->2 0 5 + ////3->4 0 20 + ////0->5 0 50 + // + ////There is no path connecting the specified source node : 0 and the specified target node : 4 + //// status = + //// + //// 0 + //// arcflows = + //// + //// [] + //// maxflow = + //// + //// 0 + // + // + //Authors + //Samuel Wilson + + + + //Checking the number of input and output arguments + + [lhs , rhs] = argn(); + + //Checking the number of input arguments entered by the user + + if (rhs<>4) then + errmsg=msprintf(gettext("%s : Wrong number of input arguments (%d). This function expects 4 arguments. Refer to help/FOT documentation for more details"),"fmaxflow",rhs); + error(errmsg); + end + + //Checking the number of output parameters specified by the user + + if(lhs<2 | lhs>3) then + errmsg=msprintf(gettext("%s : Wrong number of output arguments(%d). This function can deliver 2/3 outputs. Refer to help/FOT documentation for further details"),"fmaxflow",lhs); + error(errmsg); + end + + + //storing the input parameters + + start_nodes=varargin(1); + end_nodes=varargin(2); + capacities=varargin(3); + st=varargin(4); + + + //Checking the types of the input arguments + + Checktype("fmaxflow",start_nodes,"start_nodes",1,"constant"); + Checktype("fmaxflow",end_nodes,"end_nodes",2,"constant"); + Checktype("fmaxflow",capacities,"capacities",3,"constant"); + Checktype("fmaxflow",st,"st",4,"constant"); + + //Checking the dimensions of the input arguments + m1=size(start_nodes,"r"); + n1=size(start_nodes,"c"); + m2=size(end_nodes,"r"); + n2=size(end_nodes,"c"); + m3=size(capacities,"r"); + n3=size(capacities,"c"); + + + if (m1<>1) then + errmsg=msprintf(gettext("%s : Wrong Input Size. The input argument #1 is expected to be a matrix of dimension of the form 1xn (%dx%d obtained instead)"),"fmaxflow",m1,n1); + error(errmsg); + end + + if (m2<>1) then + errmsg=msprintf(gettext("%s : Wrong Input Size. The input argument #2 is expected to be a matrix of dimension of the form 1xn (%dx%d obtained instead)"),"fmaxflow",m2,n2); + error(errmsg); + end + + if (m3<>1) then + errmsg=msprintf(gettext("%s : Wrong Input Size. The input argument #3 is expected to be a matrix of dimension of the form 1xn (%dx%d obtained instead)"),"fmaxflow",m3,n3); + error(errmsg); + end + + if ((n1<>n2)|(n2<>n3)) then + errmsg=msprintf(gettext("%s : Unequal dimensions of the 3 input vectors (%d %d %d). The 3 are expected to be of equal lengths."),"fmaxflow",n1,n2,n3); + error(errmsg); + end + + Checkdims("fmaxflow",st,"st",4,[1 2]); + + clear ['n1' 'n2' 'n3' 'm1' 'm2' 'm3']; + + + + //checking if all the input values are indeed integral(no fractional part(or =0)) + //NOTE- x.0 is considered INTEGRAL! + + + if (~(and(start_nodes==(int(start_nodes))))) then + errmsg=msprintf(gettext("%s : The values in the ''start_nodes'' vector(input argument #%d) are expected to be integral.\n"),"fmaxflow",1); + error(errmsg); + end + + if (~(and(end_nodes==(int(end_nodes))))) then + errmsg=msprintf(gettext("%s : The values in the ''end_nodes'' vector(input argument #%d) are expected to be integral.\n"),"fmaxflow",2); + error(errmsg); + end + + if (~(and(capacities==(int(capacities))))) then + errmsg=msprintf(gettext("%s : The values in the ''capacities'' vector(input argument #%d) are expected to be integral.\n"),"fmaxflow",3); + error(errmsg); + end + + if (~(and(st==(int(st))))) then + errmsg=msprintf(gettext("%s : The source and target node value(s)(input argument #%d) are expected to be integral.\n"),"fmaxflow",4); + error(errmsg); + end + + + + + + + //Checking if the source and target node values are valid i.e. they are actual nodes in the specified graph or not + + if (~(or(st(1)==start_nodes))) then + errmsg=msprintf(gettext("%s : Invalid source node(%d)- The specified source node does not exist in the given graph\n"),"fmaxflow",st(1)); + error(errmsg); + end + + if (~(or(st(2)==end_nodes))) then + errmsg=msprintf(gettext("%s : Invalid target node(%d)- The specified target node does not exist in the given graph\n"),"fmaxflow",st(2)); + error(errmsg); + end + + + + //Solving the problem by invoking the gateway function + + [maxflow,arcflows,status]=MaxFlow(start_nodes,end_nodes,capacities,st); + + if (maxflow==0) then + printf("\nThere is no path connecting the specified source node : %d and the specified target node : %d\n",st(1),st(2)); + arcflows=[]; + else + select status + case 0 then + printf("\nAn optimal solution was found\n"); + case 1 then + printf("\nINT_OVERFLOW(There is a feasible flow > max possible flow)\n"); + case 2 then + printf("\nBAD_INPUT(The input is inconsistent)\n"); + case 3 then + printf("\nBAD_RESULT (There was an error)\n"); + else + printf("\nUnrecognized return status. Notify the toolox authors\n"); + break; + + end + end +endfunction + + + + + + + diff --git a/macros/fshortestpath.sci b/macros/fshortestpath.sci new file mode 100644 index 0000000..ab65f9d --- /dev/null +++ b/macros/fshortestpath.sci @@ -0,0 +1,303 @@ + + +function [mincost,shortestpath,flag]=fshortestpath(varargin) + //Computes the shortest/minimum-cost path for a given graph using an implementation of the 'Bellman Ford' algorithm for weighted digraphs. + // + //Calling Sequence + //[mincost,shortestpath]=fshortestpath(start_nodes,end_nodes,weights,st) + //[mincost,shortestpath]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) + //[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + //[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) + // + //Parameters + //start_nodes : a [1xn] vector (if the graph has 'n' arcs, for instance) of integral values which stores the numerical label of the start-nodes (tail-nodes) for each arc of the graph. + //end_nodes : a [1xn] vector of integral values which stores the numerical label of the end-nodes (head-nodes) for each arc of the graph. + //weights : a [1xn] vector of integral values which stores the weights/traversal costs for each of the edges/arcs of the given graph. Eg.-The weight at index 'i' of this vector refers to the cost/weight of the arc defined by start_node[i]->end_node[i]. + //st : a [1x2] vector which stores the numerical-label of the source node and the target node respectively. + //disconnected_distance : a singular integral value which indicates that all the weight values greater than or equal to itself essentially mean a non-existent arc/edge/path, i.e. those edges of the given graph will not be considered for the current test. (allows testing with different threshold values if need be) + //mincost : an integral value denoting the minimum possible cost incurred in traversing from the source node to the target node (summation of weights/costs of all the edges/arcs included in the shortest path, if any) + //shortestpath : Returns a vector containing the nodes(the numerical tags thereof) lying on the shortest path from source to target, if one exists. + //flag : flag variable indicating if there exists a path between the given source and target nodes(0-> no path exists; 1-> path exists(ipso facto, a minimal-cost path exists) + // + //Description + //\text{A staple of graph theory, the \textbf{`Shortest Path' problem } vies to find the least-cost, hence ``shortest" path between any two given nodes in a \textbf{weighted digraph}}^{*}\text{. Essentially a linear programming problem at its core, it is one of the most studied optimization problems.} + //\text{}\\ + //\text{}\\ + //\text{The routine uses an implementation of the `Bellman Ford single-source shortest path algorithm for weighted digraphs'(negative weights supported)} + //\text{}\\ + //\text{Bellman–Ford is based on the principle of relaxation, in which an approximation to the correct distance is gradually replaced by more accurate values until eventually reaching the optimum solution.\\The approximate distance to each vertex is always an overestimate of the true distance, and is replaced by the minimum of its old value with the length of a newly found path.\\Bellman–Ford algorithm, unlike the contemporary Dijkstra's shortest path algorithm, simply relaxes all the edges, and does this (|V|-1) times, where |V| is the number of vertices in the graph. In each of these repetitions, the number of vertices with correctly calculated distances grows, from which it follows that eventually all vertices will have their correct distances.\\This method allows the Bellman–Ford algorithm to be applied to a wider class of inputs than Dijkstra's algorithm(Dijkstra's doesn't support negative edges).\\ + //Bellman–Ford runs in O(|V|.|E|) time, where |V| and |E| are the number of vertices and edges respectively.}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + //^{*}\text{\underline{\textbf{Weighted Digraph}} : A weighted digraph is a graph in which each edge has a ``weight" associated with it. The \textbf{``weight" } is any quantity of practical significance to the problem, like distance, electrical resistance, etc. Moreover, the edges of the graph are directionally constrained, i.e. an edge from node `a' to node `b' entails neither the existence of an edge from node `b' to node `a' nor the same weight.}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + //\text{\textbf{\underline{MATHEMATICAL STATEMENT} :}}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + // + // + //\begin{math} + //\text{Let } N= \left(V,E\right) \text{be a network with } s,t \in V \text{denoting the source and target nodes in } N\text{, respectively.}\\ + //\text{Let } w_{ij} \text{ denote the cost for the edge } i \to j.\\\\ + //\textbf{\underline{Objective} :} + //\text{}\quad Maximize \quad \sum_{i,j \in A} w_{ij}x_{ij} \text{ ;}\\\\ + //\text{ } \qquad \hspace{4em} \text{ Subject to } x \geq 0.\\ + //\text{ }\qquad \hspace{4em} \text{ Also, } \sum_{j}x_{ij} - \sum_{j} x_{ji} = \begin{cases} + //1, \quad if\text{ }i=s\text{;}\\ + //-1, \quad if\text{ }i=t\text{;}\\ + //0, \quad \text{ otherwise;}\\ + //\end{cases} \quad \forall \quad i \text{ ;}\\ + //\end{math} + // + // + // + //Examples + //start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3] + //end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4] + //weights = [20, 30, 10, 40, 30, 10, 20, 5, 20] + //st=[0,4] + //[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + ////Press Enter to continue + ////Output : + ////Shortest path from start-node:0 to end-node:4 is : + ////0 -> 3 -> 4 + ////Minumum cost (using the said path) :- 30.000000 + // + // + //Examples + //specifying disconnected-distance + //start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3] + //end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4] + //weights = [20, 30, 10, 10, 30, 10, 20, 5, 30] + //st=[0,4] + //disconnected_distance=30 + //[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + ////Press Enter to continue + ////Output + ////Shortest path from start-node:0 to end-node:4 is : + ////0 -> 3 -> 2 -> 4 + ////Minumum cost (using the said path) :- 35.000000 + ////Shortest/Lowest Cost Path found. + // + // + //Examples + //start_nodes = [1, 1, 2, 2, 3, 3, 0] + //end_nodes = [2, 4, 3, 4, 2, 4, 5] + //weights = [40, 30, 10, 20, 5, 20, 30] + //st=[0,4] + //[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + ////Press Enter to continue + ////No path connecting start-node: 0 and end-node=: 4. + ////No Solution![0 , 4] + // + // + //Examples + //start_nodes=[ 0 0 1 1 2 4 5 4]; + //end_nodes= [ 1 5 2 5 3 3 4 2]; + //weights=[10 8 5 2 7 10 10 8]; + //st=[0,3] + //[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + ////Press Enter to continue + ////Output + ////Shortest path from start-node:0 to end-node:3 is : + ////0 -> 1 -> 2 -> 3 + ////Minumum cost (using the said path) :- 22.000000 + //// Shortest/Lowest Cost Path found. + // + // + //Authors + //Samuel Wilson + + + + //obtaining the number of input and output arguments + + [lhs,rhs]=argn(); + + + //checking the number of input arguments + + if (rhs<4 | rhs>5) then + errmsg=msprintf(gettext("%s : Number of input arguments is expected to be 4 or 5. Found %d. Refer to help/FOT documentation for more details.\n"),"fshortestpath",rhs); + error(errmsg); + end + + + //checking the number of output arguments + if (lhs<2 | lhs >3) then + errmsg=msprintf(gettext("%s : Unexpected number of output parameters( Found %d). This routine expects 2 or 3 output parameters. Refer to help/FOT documentation for more details.\n"),"fshortestpath",lhs); + error(errmsg); + end + + + //storing the input arguments + + start_nodes=varargin(1); + end_nodes=varargin(2); + weights=varargin(3); + st=varargin(4); + + + + // checking if the 'disconnected distance' is specified by the user and initilaizing it accordingly + if (rhs==5) then + disconnected_distance=varargin(5); + else + disconnected_distance=[2147483647]; + end + + + //checking the types of the input arguments + + Checktype("fshortestpath",start_nodes,"start_nodes",1,"constant"); + Checktype("fshortestpath",end_nodes,"end_nodes",2,"constant"); + Checktype("fshortestpath",weights,"weights",3,"constant"); + Checktype("fshortestpath",st,"st",4,"constant"); + + if (rhs == 5) then + Checktype("fshortestpath",disconnected_distance,"disconnected_distance",5,"constant"); + end + + + + //Checking the dimensions of the input arguments + + m1=size(start_nodes,"r"); + n1=size(start_nodes,"c"); + m2=size(end_nodes,"r"); + n2=size(end_nodes,"c"); + m3=size(weights,"r"); + n3=size(weights,"c"); + + if (m1<>1) then + errmsg=msprintf(gettext("%s : Wrong Input Size. The input argument #1 is expected to be a matrix of dimensions of the form 1xn (%dx%d obtained instead)"),"fshortestpath",m1,n1); + error(errmsg); + end + + if (m2<>1) then + errmsg=msprintf(gettext("%s : Wrong Input Size. The input argument #2 is expected to be a matrix of dimensions of the form 1xn (%dx%d obtained instead)"),"fshortestpath",m2,n2); + error(errmsg); + end + + if (m3<>1) then + errmsg=msprintf(gettext("%s : Wrong Input Size. The input argument #3 is expected to be a matrix of dimensions of the form 1xn (%dx%d obtained instead)"),"fshortestpath",m3,n3); + error(errmsg); + end + + if ((n1<>n2)|(n2<>n3)) then + errmsg=msprintf(gettext("%s : Unequal dimensions of the 3 input vectors (%d %d %d). The 3 are expected to be of equal lengths."),"fshortestpath",n1,n2,n3); + error(errmsg); + end + + Checkdims("fshortestpath",st,"st",4,[1 2]); + + if (rhs==5) then + Checkdims("fshortestpath",disconnected_distance,"disconnected_distance",5,[1 1]); + end + + clear ['n1' 'n2' 'n3' 'm1' 'm2' 'm3']; + + + //checking if all the input values are indeed integral(no fractional part(or =0)) + //NOTE- x.0 is considered INTEGRAL! + + + if (~(and(start_nodes==(int(start_nodes))))) then + errmsg=msprintf(gettext("%s : The values in the ''start_nodes'' vector(input argument #%d) are expected to be integral.\n"),"fshortestpath",1); + error(errmsg); + end + + if (~(and(end_nodes==(int(end_nodes))))) then + errmsg=msprintf(gettext("%s : The values in the ''end_nodes'' vector(input argument #%d) are expected to be integral.\n"),"fshortestpath",2); + error(errmsg); + end + + if (~(and(weights==(int(weights))))) then + errmsg=msprintf(gettext("%s : The values in the ''weights'' vector(input argument #%d) are expected to be integral.\n"),"fshortestpath",3); + error(errmsg); + end + + if (~(and(st==(int(st))))) then + errmsg=msprintf(gettext("%s : The source and target node value(s)(input argument #%d) are expected to be integral.\n"),"fshortestpath",4); + error(errmsg); + end + + + if (rhs==5) then + if (disconnected_distance<>(int(disconnected_distance))) then + errmsg=msprintf(gettext("%s : The ''disconnected distance'' value(input argument #%d) is expected to be integral.\n"),"fshortestpath",5); + error(errmsg) + end + + end + + + + + //Checking if the source and target node values are valid i.e. they are actual nodes in the specified graph or not + + if (~(or(st(1)==start_nodes))) then + errmsg=msprintf(gettext("%s : Invalid source node(%d)- The specified source node does not exist in the given graph\n"),"fshortestpath",st(1)); + error(errmsg); + end + + if (~(or(st(2)==end_nodes))) then + errmsg=msprintf(gettext("%s : Invalid target node(%d)- The specified target node does not exist in the given graph\n"),"fshortestpath",st(2)); + error(errmsg); + end + + + //Solving the problem by invoking the pertinent gateway function + + + [mincost,shortestpath,flag]=BellmanFordShortestPath(start_nodes,end_nodes,weights,st,disconnected_distance,1); + + + if (~exists('flag')) then + flag=0; + end + + if (rhs==5 & flag==0) then // disconnected_distance was specified by the user + [mincost2,shortestpath2,flag2]=BellmanFordShortestPath(start_nodes,end_nodes,weights,st,[2147483647],0); + flag=0; + if (~exists('flag2')) then + flag2=0; + end + clear 'mincost2' + clear 'shortestpath2' + end + + + select flag + case 0 then + printf("\nNo Solution![%d , %d] \n", st(1),st(2)); + mincost=[]; + shortestpath=[]; + if (rhs==5) then + + if (flag2==0) then + printf("No path exists(despite disregarding the specified ''disconnected_distance'' value. Please check the graph or the source/target\n"); + else + printf("No effective path exists with weights within the specified ''disconnected_distance''(i.e. there is at least 1 path between the given source and target which is not considered due to given constraint on the weight(disconected_distance)). Try increasing the thresholing value, if the problem allows.\n"); + end + end + + case 1 then + printf("\n Shortest/Lowest Cost Path found. \n"); + else + printf("\nUnrecognized return status. Notify the toolox authors\n"); + break; + + end +endfunction + + + + + + + diff --git a/macros/jssp.sci b/macros/jssp.sci new file mode 100644 index 0000000..601312b --- /dev/null +++ b/macros/jssp.sci @@ -0,0 +1,432 @@ +function [makespan, schedule, status] = jssp(varargin) + //Solves the popular 'Job-Shop Scheduling Problem' (JSSP for short), which aims to find an optimal plan to schedule a given number of jobs, each composed of one or more tasks to be performed in some specific logical order, on a given number of machines. The routine makes use of the 'constraint-solver' library from the Google OR-Tools framework. + // + //Calling Sequence + //[makespan,schedule] = jssp(machines, jobs, jmode, tasks) + //[makespan, schedule] = jssp(machines, jobs, jmode, tasks, time_limit) + //[makespan, schedule, status] = jssp(machines, jobs, jmode, tasks) + //[makespan, schedule, status] = jssp(machines, jobs, jmode, tasks, time_limit) + // + //Parameters + // + //machines : It is a single integral value specifying the total number of machines in the problem, on which the various tasks are to be scheduled. + //jobs : It is a single integral value specifying the total number of jobs in the problem. Each job is composed of one or more tasks which are to be scheduled on specific machines, in some logical order. + //mode : It is a single intergral value (either '0' or '1' only). It specifies one of the two modes for the solver, which are :-0-> Sequential - In this mode, the various tasks within a job are considered to be sequentially constrained i.e. task_1 must occur before task_2, task_2 before task_3 and so on.1-> Parallel - This mode allows the flexibility of some tasks being scheduled parallelly or independently of each other, if such a scenario is to be modelled. Eg. if a task 'x' can be performed any time after task_1 but must be performed before task_10. It requires 2 additional fields in the 'tasks' matrix, specifying 2 tasks (indices) between which the current task can be freely scheduled. One or both of these bounds can be done away with(no 'start_after' or 'end_before' constraints) by providing '-1' for the respective field.(These indices are the task indices WITHIN the job, ie.each job will have a task indexed '1', dor instance). + //tasks : It is an [AxB] matrix( A- total number of tasks in the problem. B- 3 or 5 depending on the mode). Each row corresponds to a task. The two variations are :-mode '0' -> An [Ax3] matrix. The 3 fields/columns are 'Job-Index', 'Machine-Index' and 'Task-Duration'. (The tasks for each job are ordered internally in the order they appear in this matrix)mode '1' -> An [Ax5] matrix. The 5 fields/columns are 'Job-Index, 'Machine-Index', 'Task-Duration', 'Start-After' and 'End-Before'. (order of the tasks doesn't matter in this case)\text{}\\\text{}\\\\More on the columns (let the current task(row) be 'x')'job-index' -> It is the index of the job to which 'x' belongs.'machine-index' -> It is the index of the machine on which 'x' is to be scheduled.'task-duration' -> It is the time required to perform 'x'.\text{}\\\text{}\\\\Only for mode '1' -'start-after' -> It is the index of the task, only after whose completion, 'x' can start.'end-before' -> It is the index of the task that can only start once 'x' is completed. + //time_limit : It is the maximum time (in milliseconds; integral value) for which the solver is allowed to run. If a solution is not found by then, a pertinent 'timed-out' error occurs.(Default Value - 10 seconds). Provide an empty matrix or omit the parameter if explicit time-limit is not required. + //makespan : It is the total duration of the schedule in the optimal solution, if one exists. + //schedule : Is is an [Ax5] matrix (A- no. of tasks) that gives the final schedule for the various tasks in the optimal solution, if one exists. The 5 fields/columns are 'Job-index', 'machine-index', 'task-duration', 'start-time' and 'end-time'. + //status : Is is an integral value representing the status of the solution as: '0'-> 'Solution Found' '1'-> 'Timed-out' - No solution was found within the specified/default time limit. '2'-> 'Problem-Infeasible' - No solution exists for the given problem. + //Description + // + //\text{The Job-Shop Scheduling Problem (also called the \textbf{Resource Scheduling Problem}) is a linear optimization problem in Computer Science and Operations Research which vies to schedule a number of jobs, each composed of one or more tasks, on a specific number of machines, minimizing the total time for the enite schedule, called the \textbf{makespan}.\\The order in which the various tasks in a job are performed and the machines on which they must be scheduled are received as inputs.\\This particular implementation supports two variations :}\\ + //\text{}\\ + //\text{1. \textbf{`Sequential Mode'}(mode 0) : In this mode, all the tasks in a job are considered to be sequentially constrained ie. task 2 cannot occur before task 1 finishes, and so on.}\\ + //\text{2. \textbf{`Parallel/Arbitrary Mode'}(mode 1) : In this mode, tasks within a job can occur parallelly ie. the order is arbitrary sans 2 \textbf{optional bounds}. \\These 2 ``bound'' values are specified for each task. They are :}\\ + //\qquad\text{ - \textbf{`start-after'} : This is the index of the task that must finish before the current task can start}\\ + //\qquad\text{ - \textbf{`end-before'} : This is the index of the task that cannot start before the current task finishes}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + //\text{\textbf{\underline{MATHEMATICAL\textbf{ }STATEMENT} :}}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + // + // + // + //\begin{math} + //\text{Let } M = \{M_{1}, M_{2},..., M_{m}\} \text{ and} \\ + //\text{Let } J = \{J_{1}, J_{2},..., J_{j}\} \quad \text{be 2 finite sites representing the machines and the jobs respectively. }\\\\ + //\end{math} + //\text{(the tasks are abstracted for simplicity. So whenever a Job is scheduled on a machine, it is assumed, the next task to be performed is the one scheduled).}\\\\ + //\begin{math} + //\text{Let } X \text{ denote the set of assignment of all jobs on the machines}\\\\ + //\text{Let } C \text{ be the \textbf{`cost function'} such that :}\\ + //\text{}\\ + //C:X \to [0, \infty^{+}] \quad \text{; which denotes the total processing time ie. makespan of schedule.}\\\\ + //\textbf{\underline{Objective} :}\qquad \text{ To find an assignment of jobs }x \in X \text{ for which } C(x) \text{ is minimum, ie.}\\\\ + //\text{ } \qquad \hspace{3em} \qquad \text{ } \text{ No }y \in X \text{ exists, such that } C(y) < C(x).\\ + //\end{math} + //\text{}\\ + //\text{}\\ + //\text{}\\ + // + // + //Examples + // //INPUT : + // + //machines = 3; + // + //jobs = 3; + // + //jssp_mode = 0; + // + //tasks=[ 1 1 3; + // 1 2 2; + // 1 3 2; + // 2 1 2; + // 2 3 1; + // 2 2 4; + // 3 2 4; + // 3 3 3; + // ]; + // + //[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); + // + //Examples + // //INPUT: + // + //machines = 2; + // + //jobs = 5; + // + //jssp_mode = 0; + // + //tasks = [1 1 13; + // 1 2 3; + // 2 1 2; + // 2 2 5; + // 3 1 1; + // 3 2 3; + // 4 1 4; + // 4 2 6; + // 5 1 5; + // 5 2 7]; + // + //[makespan, schedule, status] = jssp (machines, jobs, jssp_mode, tasks, []); + //Authors + //Samuel Wilson + + + + + //obtaining the number of inputs and outputs + + [lhs, rhs] = argn(); + + //checking the number of input arguments + + if ( rhs<4 | rhs>5) then + errmsg = msprintf(gettext("%s : Unexpected number of input arguments. ''4'' or ''5'' expected. Refer to help/FOT Documentation for more details.\n"),"jssp"); + error(errmsg); + end + + + //checking the number of output parameters + + if ( lhs<2 | lhs>3) then + errmsg = msprintf( gettext("%s : Unexpected number of output parameters. ''2'' or ''3'' expected. Refer to help/FOT Documentation for more details.\n"),"jssp"); + error(errmsg); + end + + + + //storing the input arguments + + machines = varargin(1); + jobs = varargin(2); + jmode = varargin(3); + tasks = varargin(4); + + if (rhs == 5) then + time_limit = varargin(5); + else + time_limit = []; // the gateway automatically uses default value upon receiving an empty matrix + end + + + + + //Checking the type of all input arguments + + Checktype("jssp",machines,"machines",1,"constant"); + Checktype("jssp",jobs,"jobs",2,"constant"); + Checktype("jssp",jmode,"jmode",3,"constant"); + Checktype("jssp",tasks,"tasks",4,"constant"); + Checktype("jssp",time_limit,"time_limit",5,"constant"); + + + + + ///////////Checking the dimensions of all the inputs/////////// + + + //checking 'machines' + + m=size(machines,"r"); + n=size(machines,"c"); + + if (m<>1 | n<>1) then + errmsg = msprintf(gettext("%s : Wrong dimensions for input argument #1 (''machines''). Single integral value [1x1] expected.\n"),"jssp"); + error(errmsg); + end + + + + //checking 'jobs' + + + m = size(jobs,"r"); + n = size(jobs, "c"); + + if ( m<>1 | n<>1) then + errmsg = msprintf(gettext("%s : Wrong dimensions for input argument #2 (''jobs''). Single integral value [1x1] expected.\n"),"jssp"); + error(errmsg); + end + + + //checking 'jmode' + + m = size(jmode, "r"); + n = size(jmode, "c"); + + if ( m<>1 | n<>1 ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for input argument #3 (''jmode''). Single integral value [1x1] expected.\n"),"jssp"); + error(errmsg); + end + + //checking jmode value as well(as 'twill be needed to check the dimensions of 'tasks' + + if ( jmode<>0 & jmode<>1) then + errmsg = msprintf(gettext("%s : Input argument #3(''jmode'') can only take the value ''0'' or ''1'' (details in help/FOT documentation).\n"),"jssp"); + error(errmsg); + end + + + + //checking 'tasks' + + m=size(tasks,"r"); + n=size(tasks,"c"); + + num_tasks = m; + + + if (jmode == 0) then + if ( n<>3 ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for input argument #4( ''tasks''). [%dx3] expected.\n"),"jssp",num_tasks); + error(errmsg); + end + + else + if ( n<>5 ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for input argument #4(''tasks''). [%dx5] expected.\n"),"jssp",num_tasks); + error(errmsg); + end + end + + + + //checking 'time_limit' + + m = size(time_limit,"r"); + n = size(time_limit,"c"); + + + if ( ~((m==0 & n==0) | (m==1 & n==1)) ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for input argument #5(''time_limit''). Single integral value [1x1] or an empty matrix expected.\n"),"jssp"); + error(errmsg); + end + + + + /////Dimensions verified///// + + + + ////////// Checking if all the inputs are integral (ie. No fractional part)(NOTE -> x.0 is considered inherently integral as fractional part is '0'////////////// + + //checking 'machines' + + if ( ~(and(machines==(int(machines)))) ) then + errmsg = msprintf(gettext("%s : Number of machines ( ''machines'' ; argument #1) is expected to be an integral value.\n"),"jssp"); + error(errmsg); + end + + + //checking 'jobs' + + if ( ~(and(jobs == (int(jobs)))) ) then + errmsg = msprintf(gettext("%s : Number of jobs ( ''jobs'' ; argument #2) is expected to be an integral value.\n"),"jssp"); + error(errmsg); + end + + + //jmode has already been checked for '0' or '1' value + + + //checking 'tasks' + + if ( ~(and(tasks == (int(tasks)))) ) then + errmsg = msprintf(gettext("%s : All the values in the ''tasks'' matrix (argument #4) are expected to be integral.\n"),"jssp"); + error(errmsg); + end + + + //checking 'time_limit' + + if ( ~(and(time_limit == (int(time_limit)))) ) then + errmsg = msprintf(gettext("%s : Time Limit ( ''time_limit'' ; argument #5 ) is expected to be an integral value.\n"),"jssp"); + error(errmsg); + end + + + //-----------------------------------------------LOGICAL CHECKS---------------------------------------------------------// + + + //checking if number of machines ('machines') is a valid(positive) value + + if ( machines < 1) then + errmsg = msprintf(gettext("%s : Invalid value for arguement #1 (''machines''). A positive, integral value expected.\n"),"jssp"); + error(errmsg); + end + + + //checking if the number of jobs ('jobs') is a valid(positive) value + + if ( jobs < 1) then + errmsg = msprintf(gettext("%s : Invalid value for argument #2 (''jobs''). A positive, integral value expected. \n"),"jssp"); + error(errmsg); + end + + //checking if the time-limt ('time_limit') is a valid(positive) value, if 'tis provided + + if ( rhs == 5) then + if ( time_limit <1) then + errmsg = msprintf(gettext("%s : Invalid value for argument #5 (''time_limit''). A positive, integral value expected. \n"),"jssp"); + error(errmsg); + end + end + + + //checking if no 'job' index values in the 'tasks' matrix are invalid + + if ( (or(tasks(:,1)< 1)) | (or(tasks(:,1)>jobs)) ) then + errmsg = msprintf(gettext("%s : One or more job-index values in the ''tasks'' matrix (argument #4) are invalid. Job indices can only take values from ''1'' to ''%d''.\n"),"jssp",jobs); + error(errmsg); + end + + + //checking if no 'machine' index values in the 'tasks' matrix are invalid + + if ( (or(tasks(:,2) < 1)) | (or(tasks(:,2) > machines)) ) then + errmsg = msprintf(gettext("%s : One or more machine-index values in the ''tasks'' matrix (argument #4) are invalid. Machine indices can only take values from ''1'' to ''%d''.\n"),"jssp",machines); + error(errmsg); + end + + + //checking if no 'duration' values in the 'tasks' matrix are invalid + + + if ( or(tasks(:,3) < 0) ) then + errmsg = msprintf(gettext("%s : One or more ''duration'' values in the ''tasks'' matrix (argument #4) are invalid. Duration values cannot be negative.\n"),"jssp"); + error(errmsg); + end + + + + + + + if ( jmode == 1) then + + for i = 1:size(tasks,"r") + + //checking if no 'start_after' values are invalid + + if ( ~((tasks(i,4) == -1 ) | ((tasks(i,4) > 0) & (tasks(i,4)<=(length(tasks(:,1) == i))))) ) then + errmsg = msprintf(gettext("%s : One or more job-index values in the ''start-after'' column ( column 4) in the ''tasks'' matrix (argument #4) are invalid. Expected - either ''-1'' or a value from ''1'' to ''%d''.\n"),"jssp",jobs); + error(errmsg); + end + + + //checking if no 'start_after' values are invalid + + if ( ~((tasks(i,5) == -1 ) | ((tasks(i,5) > 0) & (tasks(i,5)<=(length(tasks(:,1) == i))))) ) then + errmsg = msprintf(gettext("%s : One or more job-index values in the ''end-before'' column (column 5) in the ''tasks'' matrix (argument #4) are invalid. Expected - either ''-1'' or a value from ''1'' to ''%d''.\n"),"jssp",jobs); + error(errmsg); + end + + end + + end + + + + if ( jmode == 1) then + + for i = 1 : jobs + + // In case of mode '1', checking if each job has at least one task with no 'end-before' defined ie. open-ended(otherwise no task can be the last task in the schedule for that job, which is a logical fallacy. (Infeasible problem) + if ( ~(or(tasks(find(tasks(:,1) == i),5) == -1)) ) then + errmsg = msprintf(gettext("%s : At least one task in every job must be free from an ''end-before'' constraint ( = -1), to serve as a potential last task for that job. No such tasks found in job #%d.\n"),"jssp",i); + error(errmsg); + end + + + // also checking if each job has at least one task with no 'start-after' defined (otherwise no task can be the first task in the schedule for that job, which is a logical fallacy. (Infeasible problem) + if ( ~(or(tasks(find(tasks(:,1) == i),4) == -1)) ) then + errmsg = msprintf(gettext("%s : At least one task in every job must be free from a ''start-after'' constraint ( = -1), to serve as a potential first task for that job. No such tasks found in job #%d.\n"),"jssp",i); + error(errmsg); + end + + //Also checking for the condition where there's only one task free from 'start-after' and 'end-before' constraints. The model is still wrong as the same task cannot be both the first and last task for the job. + + temp = tasks(find(tasks(:,1) == i),:) + if ( (length(temp(:,4) == -1) == 1) & (length(temp(:,5 ) == -1) == 1) & ( length(find(temp(:,4)==-1 & temp(:,5)==-1)) ) ) then + errmsg = msprintf(gettext("%s : Only one task in job %d free from ''start-after'' and ''end-before'' constraints. Each job must have at least one potential first and one potential last task for the problem to be feasible.\n"),"jssp",i); + error(errmsg); + end + + + end + end + + + + + + + + //-----------------------------------------SOLUTION--------------------------------------------------------// + + + //solving the JSSP by calling the gateway function + + [makespan, schedule, status] = JSSP( machines, jobs, jmode, tasks, time_limit); + + + + select status + + case 0 then + + case 1 then + if (time_limit <> []) then + errmsg = msprintf(gettext("%s : ''TIMED_OUT'' : The solver failed to find an optimal solution within the specified time limit (%d milliseconds). Try specifying a longer limit, if the problem allows.\n"),"jssp",time_limit); + error(errmsg); + else + errmsg = msprintf(gettext("%s : ''TIMED_OUT'' : The solver failed to find an optimal solution within the default time limit (10 seconds). Try explicitly specifying a higher time-limit.\n"),"jssp"); + error(errmsg); + end + + case 2 then + errmsg = msprintf(gettext("%s : ''PROBLEM_INFEASIBLE'' : No solution exists for the specified problem. If solution expected, please check the inputs.\n"),"jssp"); + error(errmsg); + + else + printf("\nUnexpected return status. Notify the toolbox authors.\n"); + break; + + end + +endfunction + + + + + + + + diff --git a/macros/linsum.sci b/macros/linsum.sci new file mode 100644 index 0000000..bc344f5 --- /dev/null +++ b/macros/linsum.sci @@ -0,0 +1,79 @@ +function [cost, assignment, status] = linsum(varargin) + // Solves problem with finding minimum cost of assignment + // + // Calling Sequence + // [cost, assignment] = linsum(kNumLeftNodes, kNumRightNodes, kCost) + // [cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost) + // + // Parameters + // kNumLeftNodes : a double, Number of Left Nodes / Jobs + // kNumRightNodes : a double, Number of Right Nodes / Workers + // kCost : a matrix of double, kNumLeftNodes x kNumRightNodes, represents Cost of assigning a Job to a Worker + // cost : a double, Optimal (minimum) Cost + // assignment : a matrix of boolean, kNumLeftNodes x kNumRightNodes, represents Optimal Assignment for the Problem + // status : contains the exit flag of Solver. Currently 0 for Not Optimal, 1 for Optimal. + // + // Description + // Find the minimum cost and assignment for a given set of jobs and workers + // + // The routine uses Google ORtools for solving the quadratic problem, ORtools is a library written in C++. + // + // Examples + // //Ref : + // //http://www.hungarianalgorithm.com/examplehungarianalgorithm.php + // + // kNumLeftNodes = 4; + // kNumRightNodes = 4; + // kCost = [82, 83, 69, 92; 77, 37, 49, 92; 11, 69, 5, 86; 8, 9, 98, 23]; + // [cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); + // cost + // assignment + // status + // + // Authors + // Souvik Das + + [lhs, rhs] = argn(); + Checklhs("linsum", lhs, [2, 3]); + Checkrhs("linsum", rhs, 3); + + kNumLeftNodes = varargin(1); + kNumRightNodes = varargin(2); + kCost = varargin(3); + + Checktype("linsum", kNumLeftNodes, "kNumLeftNodes", 1, "constant"); + Checktype("linsum", kNumRightNodes, "kNumRightNodes", 2, "constant"); + + Checkdims("linsum", kNumLeftNodes, "kNumLeftNodes", 1, [1 1]); + Checkdims("linsum", kNumRightNodes, "kNumRightNodes", 2, [1 1]); + + if(kNumLeftNodes <= 0) then + errmsg = msprintf(gettext("%s: Number of Left Nodes should be > 0. Check input #1\n"), "linsum"); + error(errmsg); + end + + if(kNumRightNodes <= 0) then + errmsg = msprintf(gettext("%s: Number of Right Nodes should be > 0. Check input #2\n"), "linsum"); + error(errmsg); + end + + if(kNumLeftNodes <> kNumRightNodes) then + errmsg = msprintf(gettext("%s: Number of Left Nodes should be EQUAL to Number of Right Nodes\n"), "linsum"); + error(errmsg); + end + + Checktype("linsum", kCost, "kCost", 3, "constant"); + Checkdims("linsum", kCost, "kCost", 3, [kNumLeftNodes kNumRightNodes]); + + [cost, assignment, status] = solve_linsumassignment(kNumLeftNodes, kNumRightNodes, kCost); + + select status + case 0 then + printf("\nOptimal Solution not Found\n"); + case 1 then + printf("\nOptimal Solution Found.\n"); + else + printf("\nSomething went wrong. Retry later or Notify the Toolbox author(s)\n"); + break; + end +endfunction diff --git a/macros/min_cost_flow.sci b/macros/min_cost_flow.sci new file mode 100644 index 0000000..502e54e --- /dev/null +++ b/macros/min_cost_flow.sci @@ -0,0 +1,140 @@ +function [cost, flow, status] = min_cost_flow(varargin) + // Solves problem with finding minimum cost of flow + // + // Calling Sequence + // [cost, flow] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand) + // [cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand) + // + // Parameters + // kNumSources : a double, Number of Sources / Suppliers + // kNumTargets : a double, Number of Targets / Demanders + // kCost : a matrix of double, kNumSources x kNumTargets, represents Cost of flow from a Source to Target + // kCapacity : a matrix of double, kNumSources x kNumTargets, represents Capacity of flow from a Source to Target + // kSupply : a vector of double, length kNumSources, contains Supply Quantity of Suppliers + // kDemand : a vector of double, length kNumTargets, contains Demand Quantity of Demanders + // cost : a double, Optimal (minimum) Cost + // flow : a matrix of double, kNumSources x kNumTargets, represents Optimal Flow for the Problem + // status : contains the exit flag of Solver. See below + // + // Description + // Find the minimum cost and flow for a given set of sources and targets with limit on capacity per flow + // + // The routine uses Google ORtools for solving the quadratic problem, ORtools is a library written in C++. + // + // The status allows to know the status of the optimization which is given back by ORtools. + // + // status=0 : Not Solved + // status=1 : Optimal + // status=2 : Feasible + // status=3 : Infeasible + // status=4 : Unbalanced + // status=5 : Bad Result + // + // + // Examples + // //Ref : Example 2 : + // //http://www.yourarticlelibrary.com/ergonomics/operation-research/checking-for-optimality-transportation-problem/34743/ + // + // // Before balancing (Infeasible): + // kNumSources = 4; + // kNumTargets = 4; + // kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; + // kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; + // kSupply = [50, 70, 30, 50]; + // kDemand = [25, 35, 105, 20]; + // [cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); + // + // // After balancing (Optimal): + // kNumSources = 4; + // kNumTargets = 5; + // kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; + // kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; + // kSupply = [50, 70, 30, 50]; + // kDemand = [25, 35, 105, 20, 15]; + // [cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); + // cost + // flow + // status + // + // Authors + // Souvik Das + + [lhs, rhs] = argn(); + Checklhs("min_cost_flow", lhs, [2, 3]); + Checkrhs("min_cost_flow", rhs, 6); + + kNumSources = varargin(1); + kNumTargets = varargin(2); + kCost = varargin(3); + kCapacity = varargin(4); + kSupply = varargin(5); + kDemand = varargin(6); + + Checktype("min_cost_flow", kNumSources, "kNumSources", 1, "constant"); + Checktype("min_cost_flow", kNumTargets, "kNumTargets", 2, "constant"); + + Checkdims("min_cost_flow", kNumSources, "kNumSources", 1, [1 1]); + Checkdims("min_cost_flow", kNumTargets, "kNumTargets", 2, [1 1]); + + if(kNumSources <= 0) then + errmsg = msprintf(gettext("%s: Number of Sources should be > 0. Check input #1\n"), "min_cost_flow"); + error(errmsg); + end + + if(kNumTargets <= 0) then + errmsg = msprintf(gettext("%s: Number of Targets should be > 0. Check input #2\n"), "min_cost_flow"); + error(errmsg); + end + + Checktype("min_cost_flow", kCost, "kCost", 3, "constant"); + Checkdims("min_cost_flow", kCost, "kCost", 3, [kNumSources kNumTargets]); + + Checktype("min_cost_flow", kCapacity, "kCapacity", 4, "constant"); + Checkdims("min_cost_flow", kCapacity, "kCapacity", 4, [kNumSources kNumTargets]); + + if(or(kCapacity < 0) == %t) then + errmsg = msprintf(gettext("%s: Capacity should be >= 0. Check input #4\n"), "min_cost_flow"); + error(errmsg); + end + + Checktype("min_cost_flow", kSupply, "kSupply", 5, "constant"); + Checkdims("min_cost_flow", kSupply, "kSupply", 5, [1 kNumSources]); + + if(or(kSupply < 0) == %t) then + errmsg = msprintf(gettext("%s: Supply should be >= 0. Check input #5\n"), "min_cost_flow"); + error(errmsg); + end + + Checktype("min_cost_flow", kDemand, "kDemand", 6, "constant"); + Checkdims("min_cost_flow", kDemand, "kDemand", 6, [1 kNumTargets]); + + if(or(kDemand < 0) == %t) then + errmsg = msprintf(gettext("%s: Demand should be >= 0. Check input #6\n"), "min_cost_flow"); + error(errmsg); + end + + if(sum(kSupply) <> sum(kDemand)) then + errmsg = msprintf(gettext("%s: Unbalanced Supply and Demand\n"), "min_cost_flow"); + error(errmsg); + end + + [cost, flow, status] = solve_mincostflow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); + + select status + case 0 then + printf("\nProblem Not Solved.\n"); + case 1 then + printf("\nOptimal Solution Found.\n"); + case 2 then + printf("\nFeasible Solution Found.\n"); + case 3 then + printf("\nProblem is Infeasible.\n"); + case 4 then + printf("\nProblem is Unbalanced.\n"); + case 5 then + printf("\nBad Result. Retry later or Notify the Toolbox author(s)\n"); + else + printf("\nSomething went wrong. Retry later or Notify the Toolbox author(s)\n"); + break; + end +endfunction diff --git a/macros/names b/macros/names new file mode 100644 index 0000000..cc37b3e --- /dev/null +++ b/macros/names @@ -0,0 +1,14 @@ +Checkdims +Checklhs +Checkrhs +Checktype +Checkvector +Filterdims +fmaxflow +fshortestpath +jssp +linsum +min_cost_flow +qcqpglob +tsp +vrp diff --git a/macros/qcqpglob.sci b/macros/qcqpglob.sci new file mode 100644 index 0000000..bef7193 --- /dev/null +++ b/macros/qcqpglob.sci @@ -0,0 +1,212 @@ +function [kSoln, kSolnVector, status] = qcqpglob(varargin) + // Solves problem with Convex/Non-Convex Quadratically Constrained Quadratic Programming Problems with Global Optimization (GLOB) + // + // Calling Sequence + // [kSoln, kSolnVector] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var); + // [kSoln, kSolnVector, status] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var); + // [kSoln, kSolnVector] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var, maxcputime); + // [kSoln, kSolnVector, status] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var, maxcputime); + // + // Parameters + // n : a double, represents number of Decision Variables + // m : a double, represents number of Constraints + // h_obj : a matrix of double, n x n, represents Coefficients of Quadratic in Objective Function + // f_obj : a vector of double, sized n, represents Coefficients of Linear in Objective Function + // c_obj : a double, represents Constant term in Objective Function + // h_con : an m sized list, contains matrices of double, n x n, represents Coefficients of Quadratic in Constraints + // f_con : an m sized list, contains vectors of double, sized n, represents Coefficients of Linear in Constraints + // lb_con : a vector of double, sized m, represents Lower Bound of Constraints + // ub_con : a vector of double, sized m, represents Upper Bound of Constraints + // lb_var : a vector of double, sized n, represents Lower Bound of Decision Variables + // ub_var : a vector of double, sized n, represents Upper Bound of Decision Variables + // maxcputime : a double, represents max. cpu time allotted to BnB Solver + // kSoln : a double, represents value of Objective Function at Optimal Point + // kSolnVector : a vector of double, sized n, represents values of Decision Variables at Optimal Point + // status : contains the exit flag of Solver. See below + // + // Description + // Solves QCQP / Quadratically Constrained Quadratic Programming problems, especially those where local optimum is not the global optimum, i.e. when the problem is Non-Convex. Can solve Convex Problem as well. + // + // + // \begin{align} + // & \text{minimize} && \tfrac12 x^\mathrm{T} H_0 x + f_0^\mathrm{T} x + c \\ + // & \text{subject to} && {LB}_i \leq \tfrac12 x^\mathrm{T} H_i x + f_i^\mathrm{T} x \leq {UB}_i \quad \text{for } i = 1,\dots,m \\ + // &&& Ax = b + // \end{align}\\ + // + // + // + // status=0 : Not started solving + // status=1 : Started solving + // status=2 : Restarted solving + // status=3 : Optimal solution found + // status=4 : Detected infeasibility + // status=5 : Detected unboundedness of relaxation + // status=6 : Reached limit on gap + // status=7 : Reached limit on number of solutions + // status=8 : Reached iteration limit + // status=9 : Interrupted + // status=10 : Reached time limit + // status=11 : Reached the limit on number of solutions + // status=12 : Finished for some other reason + // + // + // The routine uses Minotaur Library for solving the quadratic problem, Minotaur is a library written in C++. + // + // Examples + // // Sample Only + // // Min. Z = 100 - x^2 + 2 * y^2 - 3 * x * y + 4 * x - 5 * y + // // Subject to: + // // 60 >= x^2 + y^2 - x - y >= -100 + // // -10 <= x <= 6 + // // -10 <= y <= 6 + // + // n = 2; + // m = 1; + // h_obj = [-2, -1; -2, 4]; + // f_obj = [4, -5]; + // c_obj = 100; + // h_con = list(); + // h_con(1) = [2, 0; 0, 2]; + // f_con = list(); + // f_con(1) = [-1, -1]; + // lb_con = [-100]; + // ub_con = [60]; + // maxcputime = 600; + // lb_var = [-10, -10]; + // ub_var = [6, 6]; + // [kSoln, kSolnVector, status] = qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var, maxcputime); + // kSoln + // kSolnVector + // status + // + // Authors + // Souvik Das + + // Validate Input & Output Arguments + [lhs, rhs] = argn(); + Checklhs("qcqpglob", lhs, [2 3]); + Checkrhs("qcqpglob", rhs, [11 12]); + + // Get Input + n = varargin(1); + m = varargin(2); + h_obj = varargin(3); + f_obj = varargin(4); + c_obj = varargin(5); + h_con = varargin(6); + f_con = varargin(7); + lb_con = varargin(8); + ub_con = varargin(9); + lb_var = varargin(10); + ub_var = varargin(11); + if(rhs > 11) then + maxcputime = varargin(12); + else + maxcputime = 600; // Default + end + + // Validate Input + Checktype("qcqpglob", n, "n", 1, "constant"); + Checkdims("qcqpglob", n, "n", 1, [1 1]); + if(n <= 0) then + errmsg = msprintf(gettext("%s: Number of Decision Variables should be > 0. Check input #1\n"), "qcqpglob"); + error(errmsg); + end + + Checktype("qcqpglob", m, "m", 2, "constant"); + Checkdims("qcqpglob", m, "m", 2, [1 1]); + if(m < 0) then + errmsg = msprintf(gettext("%s: Number of Constraints should be >= 0. Check input #2\n"), "qcqpglob"); + error(errmsg); + end + + Checktype("qcqpglob", h_obj, "h_obj", 3, "constant"); + Checkdims("qcqpglob", h_obj, "h_obj", 3, [n n]); + + Checktype("qcqpglob", f_obj, "f_obj", 4, "constant"); + f_obj = Filterdims("qcqpglob", f_obj, "f_obj", 4, [1 n]); + + Checktype("qcqpglob", c_obj, "c_obj", 5, "constant"); + Checkdims("qcqpglob", c_obj, "c_obj", 5, [1 1]); + + Checktype("qcqpglob", h_con, "h_con", 6, "list"); + Checkdims("qcqpglob", h_con, "h_con", 6, [m]); + for i = 1:m + Checktype("qcqpglob", h_con(i), "h_con(" + string(i) + ")", 6, "constant"); + Checkdims("qcqpglob", h_con(i), "h_con(" + string(i) + ")", 6, [n n]); + end + + Checktype("qcqpglob", f_con, "f_con", 7, "list"); + Checkdims("qcqpglob", f_con, "f_con", 7, [m]); + for i = 1:m + Checktype("qcqpglob", f_con(i), "f_con(" + string(i) + ")", 7, "constant"); + f_con(i) = Filterdims("qcqpglob", f_con(i), "f_con(" + string(i) + ")", 7, [1 n]); + end + + Checktype("qcqpglob", lb_con, "lb_con", 8, "constant"); + if(m <> 0) then + lb_con = Filterdims("qcqpglob", lb_con, "lb_con", 8, [1 m]); + else + lb_con = []; + end + + Checktype("qcqpglob", ub_con, "ub_con", 9, "constant"); + if(m <> 0) then + ub_con = Filterdims("qcqpglob", ub_con, "ub_con", 9, [1 m]); + else + ub_con = []; + end + + Checktype("qcqpglob", lb_var, "lb_var", 10, "constant"); + lb_var = Filterdims("qcqpglob", lb_var, "lb_var", 10, [1 n]); + + Checktype("qcqpglob", ub_var, "ub_var", 11, "constant"); + ub_var = Filterdims("qcqpglob", ub_var, "ub_var", 11, [1 n]); + + if(maxcputime <= 0) then + errmsg = msprintf(gettext("%s: ''maxcputime'' should be > 0. Check input #12"), "qcqpglob"); + error(errmsg); + end + + // Default Output + kSoln = 0; + kSolnVector = []; + status = 0; + + // Solve + [kSoln, kSolnVector, status] = solve_qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_var, maxcputime); + + // Print Status + select status + case 0 then + printf("\nNot started solving\n"); + case 1 then + printf("\nStarted solving\n"); + case 2 then + printf("\nRestarted solving\n"); + case 3 then + printf("\nOptimal solution found\n"); + case 4 then + printf("\nDetected infeasibility\n"); + case 5 then + printf("\nDetected unboundedness of relaxation\n"); + case 6 then + printf("\nReached limit on gap\n"); + case 7 then + printf("\nReached limit on number of solutions\n"); + case 8 then + printf("\nReached iteration limit\n"); + case 9 then + printf("\nInterrupted\n"); + case 10 then + printf("\nReached time limit\n"); + case 11 then + printf("\nReached the limit on number of solutions\n"); + case 12 then + printf("\nFinished for some other reason\n"); + else + printf("\nUnknown solve status\n"); + end + +endfunction \ No newline at end of file diff --git a/macros/tsp.sci b/macros/tsp.sci new file mode 100644 index 0000000..7480959 --- /dev/null +++ b/macros/tsp.sci @@ -0,0 +1,373 @@ +function [mincost,path,status] = tsp(varargin) + //Solves the classic 'Travelling Salesman Problem' heuristically using the routing library from the Google-OR-tools framework. The algorithm first employs a cheapest path approach for an initial solution and then 'local search' heuristics to improve the initial solution toward an optimal one. + // + //Calling Sequence + //[mincost,path]=tsp(adj_matrix,start_node) + //[mincost,path]=tsp(adj_matrix,start_node,labels) + //[mincost,path,status]=tsp(adj_matrix,start_node) + //[mincost,path,status]=tsp(adj_matrix,start_node, labels) + // + //Parameters + //adj_matrix : It is an [nxn] Adjacency Matrix of integral values, representing the graph (having 'n' nodes, for instance, numbered from '1' to 'n') for which the Travelling Saleman Problem is to be solved. Value adj_matrix(i,j) represents the cost of travelling from node 'i' to node 'j' of the given graph. Asymmetric graphs are also supported, where adj(i,j) <> adj(j,i). A negative value for cost (adj_matrix(i,j)) is simply interpreted as the absence of an edge from node 'i' to node 'j'. + //start_node : It is the index of the starting node. The optimal path must start and end at this node. + //labels : Optional functionality to provide string labels to the nodes of the graph. It is a [1xn] vector of strings. (labels(i) is the label given to the node 'i' of the graph + //time_limit : It is the maximum time (in milliseconds; integral value) for which the optimizer is allowed to run. If by the end of this time, the engine is unable to find even an initial solution, a timeout error status is returned. If, however, an initial solution is found, but not fully optimized yet (in the process of heuristically improving it), it will return the current solution, albeit not optimal, as the final solution. This value cannot be zero. Default : 1 second. + //mincost : It is an integral value denoting the minimum cost incurred by the "salesman" in traversing the optimal path according to the solution, should one exist.) + //path : It is a [1x(n+1)] vector containing indices of nodes in the order of the path to be followed in the optimal solution, should one exist. The first and the last values in this vector are equal to the 'start_node' index provided. + //status : It is the enumerated "flag" value returned by the Google OR tools Routing Library, indicating the status of the solution.(Details in the description) + // + //Description + // + //\text{The \textbf{`Travelling Salesman Problem' } is a classic optimization problem which, given a graph (wherein each edge has some cost/distance associated with it), and an arbitrary `starting node' , vies to find such a path over the said graph so as to visit every vertex exactly once and ending back at the `start\_node' \textbf{(Hamiltonian path) }, while minimizing the total cost/distance of the journey.\\This is aptly explained by the namesake analogy of a `salesman' who needs to decide upon a path through various cities (nodes) while minimizing his travel distance, hence the travel expenditures.\\Travelling salesman problem is essentially a special case of the \textbf{Vehicle Routing Problem}.\\This routine utlizes the 'Routing Model' from the Google OR Tools framework to solve the problem. A \textbf{`cheapest addition' } heuristic is applied to find the initial solution and then \textbf{`local search' } is used to improve it toward an optimal solution.\\\textbf{Asymmetric Travelling Saleman Problem } is also supported, where the cost of travelling from city `i' to city `j' is not the same as cost of travelling from city `j' to city `i' (In this case, the input adjacency matrix is simply not a symmetric matrix)}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + //\text{\textbf{\underline{MATHEMATICAL\textbf{ }STATEMENT} :}}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + // + // + // + //\begin{math} + //\text{Let }x_{ij} = \begin{cases} + //1 \quad \text{; if there exists a path from node i to j}\\ + //0 \quad \text{; otherwise}\\ + //\end{cases}\\\\ + //\text{Let their be `n' nodes in the problem}\\ + //\text{Let } c_{ij} \text{ be the distance from node i to node j}\\\\ + //\text{Let }u_{i} \text{ be a dummy variable for } i=1,2,...,n \text{ ;}\\\\ + //\textbf{\underline{Objective }:}\qquad Minimize \sum_{i=1}^{n} \sum_{j \neq i, j=1}^{n} c_{ij} x_{ij} \\\\ + //\text{ Subject to :} + //\text{ }\qquad 0 \leq x_{ij} \leq 1 \text{ ;} \qquad i,j = 1,2,...,n \text{ ;}\qquad \hspace{3em} \qquad (1)\\\\ + //\text{ }\qquad \hspace{3em} \text{ } \qquad u_{i} \in Z \text{ ; }\qquad \qquad i = 1,2,...,n \text{ ; }\qquad \hspace{3em} \qquad \text{ }(2)\\\\ + //\text{ }\qquad \hspace{3em} \text{ } \qquad \sum_{i=1,i\neq j}^{n} x_{ij}=1 \text{ ; } j=1,2,...,n \text{ ; } \qquad \hspace{3em} \qquad (3)\\\\ + //\text{ }\qquad \hspace{3em} \text{ } \qquad \sum_{j=1,j\neq i}^{n} x_{ij}=1 \text{ ; } i=1,2,...,n \text{ ; } \qquad \hspace{3em} \qquad (4)\\\\ + //\text{ }\qquad \hspace{3em} \text{ } \qquad u_{i} - u_{j} + n x_{ij} \leq n-1 \text{ ; }\qquad 2\leq i\neq j \leq n \text{ ; } \qquad (5)\\\\ + //\text{ (3),(4) enforce that each node can only be arrived from exactly one other node.}\\\\ + //\text{ (5) enforces that there's only a single tour connecting all the node ( Hamiltonian cycle) } + //\end{math} + //\text{}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + // + // + //Legend : + // + //status - Integral value returned by the Google OR Tools Routing library, indicating the status of the solution for the current TSP + // + //status=0 - ROUTING_NOT_SOLVED (Before the solver is invoked) + //status=1 - ROUTING_SUCCESS (TSP solved successfully(optimal solution found) + //status=2 - ROUTING_FAIL(No solution found) + //status=3 - ROUTING_FAIL_TIMEOUT (solution was taking too much time; Timed out) + // + // + // For more details, refer to : https://en.wikipedia.org/wiki/Travelling_salesman_problem + // + // or to : https://developers.google.com/optimization/routing/tsp/tsp + // + // The problem is also related to the HAMILTONIAN PATH problem : https://en.wikipedia.org/wiki/Hamiltonian_path + // + // + //Examples + // + //adj=[0 10 50 45; + //10 0 25 25; + //50 25 0 40; + //45 25 40 0]; + // + //start_node=1; + // + //[mincost,path,status]=tsp(adj,start_node); + ////Press ENTER to continue + // + ////OUTPUT : + ////'ROUTING_SUCCESS' ; An optimal solution was found + ////Minimum cost -> 120 + ////Optimal Path :- + ////1 ->2 ->3 ->4 ->1 + // + //Examples + // + //adj=[0 10 15 20; + //10 0 35 25; + //15 35 0 30; + //20 25 30 0]; + // + //start_node=1; + // + //labels=['A' 'B' 'C' 'D']; + //[mincost,path,status]=tsp(adj,start_node,labels); + ////Press ENTER to continue + //// + ////OUTPUT : + ////'ROUTING_SUCCESS' ; An optimal solution was found + ////Minimum cost -> 80 + ////Optimal Path :- + //// A (1) -> B (2) -> D (4) -> C (3) ->A (1) + // + //Examples + // + //adj=[0 1 2 1 1; + //1 0 1 2 1; + //2 1 0 1 2; + //1 2 1 0 2; + //1 1 2 2 0]; + // + //start_node=1; + // + //labels=['alpha' 'beta' 'gamma' 'theta' 'sigma']; + // + //[mincost,path,status]=tsp(adj,start_node,labels); + //Press ENTER to continue + // + ////OUTPUT : + ////'ROUTING_SUCCESS' ; An optimal solution was found + ////Minimum cost -> 5 + ////Optimal Path :- + //// alpha (1) -> sigma (5) -> beta (2) -> gamma (3) -> theta (4) ->alpha (1) + // + //Examples + // + //adj=[0 10 -1 -2; + //10 0 35 25; + //-1 35 0 30; + //-1 25 30 0]; + // + //start_node=1; + // + //[mincost,path,status]=tsp(adj,start_node); + ////Press ENTER to continue + //// + ////OUTPUT : + ////'ROUTING_FAIL' ; No optimal solution was found. No path starting and ending at the specified 'start node'(1) found. + // + //Authors + //Samuel Wilson + + + + + + + //obtaining the number of inputs and outputs + + [lhs,rhs]=argn(); + + + + //checking the number of input arguments + + if (rhs<2 | rhs>4) then + errmsg=msprintf(gettext("%s : Number of input arguments is expected to be 2 - 4. Found %d. Refer to help/FOT documentation for more details.\n"),"tsp",rhs); + error(errmsg); + end + + //checking the number of output arguments + + if (lhs<2 | lhs>3) then + errmsg=msprintf(gettext("%s : Number of output arguments is expected to be to 2 or 3. Found %d. Refer to the help/FOT documentation for more details.\n"),"tsp",lhs); + error(errmsg); + end + + + //storing the input arguments + + adj_matrix=varargin(1); + start_node=varargin(2); + + time_limit = 1000; + labels = ""; //NOTE- the size of labels ( ie. "") is actually '1', not '0' + + if (rhs > 2) then + if ( varargin(3)<>[] ) then + labels = varargin(3); + end + end + + if ( rhs > 3 ) then + if (varargin(4) <> []) then + time_limit = varargin(4); + end + end + + + + //checking the types of the input arguments + + Checktype("tsp",adj_matrix,"adj_matrix",1,"constant"); + Checktype("tsp",start_node,"start_node",2,"constant"); + + + if (rhs > 2) then + Checktype("tsp",labels,"labels",3,"string"); + end + + if ( rhs > 3) then + Checktype("tsp",time_limit,"time_limit",4,"constant"); + end + + + + //getting the number of rows and columns in the given adjacency matrix + m=size(adj_matrix,"r"); + n=size(adj_matrix,"c"); + + + //checking the dimensions of the adjacency matrix + if (m <> n) then + errmsg=msprintf(gettext("%s : The dimensions of the given adjacency matrix are erroneous [%d x %d]. Number of rows and columns has to be equal(square matrix) ( = no. of nodes in the graph).\n"),"tsp",m,n); + error(errmsg); + end + + + //checking if all the diagonal elements of the given adjacency matrix are zero + + if (~(and(diag(adj_matrix)==0))) then + errmsg=msprintf(gettext("%s : All leading diagonal elements of the adjacency matrix need to be 0\n"),"tsp"); + error(errmsg); + end + + + //checking if the 'start_node' value is a singular value(1 x 1 matrix) + if ((size(start_node,"r")>1) | (size(start_node,"c")>1)) then + errmsg=msprintf(gettext("%s : Invalid start_node index value. Singlular value indicating the index of the node from where the journey is to begin expected\n"),"tsp"); + error(errmsg); + end + + + + //Checking if all the values in the adjacency matrix and the start node index are integral(no fractional part(or =0)) + //NOTE- x.0 is considered INTEGRAL! + + if (~(and(adj_matrix==(int(adj_matrix))))) then + errmsg=msprintf(gettext("% s : All values in the adjacency matrix ( input argument #%d) are expected to be integral\n"),"tsp",1); + error(errmsg); + end + + if(~(and(start_node==(int(start_node))))) then + errmsg=msprintf(gettext("%s : The start_node index ( input argument #%d) is expected to be integral\n"),"tsp",2); + error(errmsg); + end + + + + + //checking if the value of the given 'start_node' is valid(exists in the graph) + if (start_node<=0 | start_node>m) then + errmsg=msprintf(gettext("%s : Invalid ''start node'' index (%d). It is expected to be between ''1'' and ''%d''(no. of nodes in the given graph).\n"),"tsp",start_node,m); + error(errmsg); + end + + + + + //checking the dimensions of the 'labels' matrix, if 'tis specified + + if (labels <> "") then + if ((size(labels,"r")>1) | (size(labels, "c")<> m)) then + if ((size(labels,"r")>1) & (~(size(labels,"c")<>m))) then + errmsg=msprintf(gettext("%s : The ''labels'' matrix (input argument #%d) must have only one row, ie., it must be vector\n"),"tsp",3); + elseif ((~(size(labels,"r")>1)) & (size(labels, "c")<> m)) then + errmsg=msprintf(gettext("%s : The number of elements ''labels'' vector (input argument #%d) must be equal to the number of nodes in the graph.(found %d)\n"),"tsp",3,size(labels,"c")); + else + errmsg=msprintf(gettext("%s : Invalid dimensions for ''labels'' vector(input argument #%d). [1 x %d] vector expected. (Found [%d x %d]. \n"),"tsp",3,m,size(labels,"r"),size(labels,"c")); + + end + error(errmsg); + end + end + + //checking if all the 'label' values are unique + if (labels <>"") then + if (length(labels) <> length(unique(labels))) then + errmsg=msprintf(gettext("%s : The entries in the ''label'' matrix should be unique ( no 2 nodes can have the same label)\n"),"tsp"); + error(errmsg); + end + end + + //Checking the dimensions of 'time_limit', if given + if ( rhs > 3 ) then + m = size(time_limit,"r"); + n = size(time_limit, "c"); + + if ( ~(m==1 & n==1) ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for input argument #4(''time_limit''). A single, positive, integral value expected.\n"),"tsp"); + error(errmsg); + end + + clear m; + clear n; + end + + + //Checking if the 'time-limit' value, if given, is valid(>0) and integral + + if ( rhs > 3) then + if( ~(and(time_limit ==(int(time_limit))))) then + errmsg = msprintf(gettext("%s : The time limit value (argument #4) is expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if ( ~(time_limit > 0) ) then + errmsg = msprintf(gettext("%s : The given time-limit is invalid. Positive Value expected.\n"),"tsp"); + error(errmsg); + end + end + + + //Solving the TSP by invoking the gateway function + + [mincost,path,status]=TSP(adj_matrix,(start_node-1), time_limit); // 'path' contains the C++ indices(i.e. starting from 0) + + + select status + case 0 then + printf("\n''ROUTING_NOT_SOLVED'' ; The solver-module invocation failed. If the problem persists, notify the toolbox authors.\n"); + case 1 then + printf("\n ''ROUTING_SUCCESS'' ; An optimal solution was found\n"); + printf("Minimum cost -> %d\n\n",mincost); + printf("Optimal Path :- \n"); + temp=size(path,"c"); + + if ( length(labels)<>0 ) then //labels were provided + for i = 1 : (temp-1) + printf(" %s (%d) ->",labels(path(i)+1),(path(i)+1)); + end + printf("%s (%d)",labels(path(temp)+1),(path(temp)+1)); + else + for i = 1 : (temp-1) + printf("%d ->",(path(i)+1)); + end + printf("%d ",(path(temp)+1)); + end + + clear 'temp'; + + case 2 then + printf("\n ''ROUTING_FAIL'' ; No optimal solution was found. No path starting and ending at the specified ''start node''(%d) found.\n", start_node); + + case 3 then + if ( path <> []) then + printf("\n''ROUTING_FAIL_TIMEOUT''\n ; The time limit was reached before the model converged to the optimal solution. The returned solution CAN be further optimized; Try increasing the time-limit for a better solution.\n"); + else + printf("\n''ROUTING_FAIL_TIMEOUT''\n ; No solution was found within the stipulated the time-limit. Try increasing the time-limit.\n"); + end + + else + printf("\nUnexpected return status. Notify the toolbox authors.\n"); + break; + + end + + endfunction + + + + + + + + + diff --git a/macros/vrp.sci b/macros/vrp.sci new file mode 100644 index 0000000..b5956b3 --- /dev/null +++ b/macros/vrp.sci @@ -0,0 +1,1183 @@ +function [total_distance,routes,distances,total_time,times,status] = vrp(varargin) + //Solves the classic 'Vehicle Routing Problem' (VRP for short) heuristically to find the optimal set of routes for a fleet of vehicles delivering goods or services to various locations. The routine makes use of the routing library from the Google-OR-Tools framework. The algorithm first employs a cheapest path approach for an initial naive solution and then 'local search' heuristics to improve it toward an optimal solution. + // + //Calling Sequence + //[total_distance,routes] = vrp(adj_matrix,vehicles,start) + //[total_distance,routes] = vrp(adj_matrix,vehicles,start,labels) + //[total_distance,routes] = vrp(adj_matrix,vehicles,start,labels,demands,max_vehicle_capacity) + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand) + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows) + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds) + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times) + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times,refuel_flag,fuel_capacity,refuel_nodes) + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times,refuel_flag,fuel_capacity,refuel_nodes,penalty) + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times,refuel_flag,fuel_capacity,refuel_nodes,penalty,groups,group_penalty) + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand,time_windows,speeds,waiting_times,refuel_flag,fuel_capacity,refuel_nodes,penalty,groups,group_penalty,time_limit) + //[total_distance,routes,distances] = vrp(...) + //[total_distance,routes,distances,total_time] = vrp(...) + //[total_distance,routes,distances,total_time,times] = vrp(...) + //[total_distance,routes,distances,total_time,times,status] = vrp(...) + // + //Parameters + // **NOTE : for the sake of simplicity, henceforth 'v' would denote the number of vehicles in the problem and 'n', the number of nodes in the graph + //adj_matrix : It is an [nxn] matrix of integral values, representing the graph (nodes indexed from '1' to 'n') for which the given VRP is to be solved. adj_matrix[i][j] gives the distance from node 'i' to 'j'.(can be different from adj_matrix[j][i]; asymmetric VRP). A negative value indicates the absence of a path from 'i' to 'j'. + //vehicles : It is an integral value representing the number of vehicles in the fleet, such that we need to find a optimum route for each vehicle, to minimize the total distance and total time. + //start : It is a matrix of integral values, pertaining to the index of the starting node(s) or depot(s). The dimensions of this matrix is germane to the type of VRP given, hence determines the pertinent solution strategy. The variations are :-[1x1] - A single integral value - indicating a single depot. All vehicles start and end their journey at this node.[ ] - Empty Matrix - indicating that the vehicle routes can start and end at any node, defining a taxi-service-like scenario.[vx2] - An integral matrix specifying particular start and end nodes for each vehicle ( multiple depot case). start[x][0] -> Start node index for vehicle 'x' ; start[x][1] -> End node for vehicle 'x'. + //labels : Optional functionality to provide string labels to the nodes of the graph. It is a [1xn] vector of strings. + //labels(i) is the label given to the node 'i' of the graph. Give an empty matrix if labels are not to be provided. + //demands : It is a [1xn] vector of integral values indicating the demands for the various nodes to be fulfiled by the vehicles. demands[x] denotes the demand of node 'x'. (Demands obviously cannot be negative). + //If empty, it denotes a non-capacitated VRP, with no demand constraints. + //max_vehicle_capacity : It is an integral value specifying the maximum capacity of each vehicle (same for all). If capacitated VRP (demands specified), this has to be provided and must be POSITIVE. Can be '0' or empty matrix for non-capacitated VRP. + //service_time_per_demand : It a single integral value indicating the time required to service one unit of demand in capacitated VRP. + //time_windows : It is an [nx2] matrix of integral values specifying particular windows of time only within which the different nodes can be serviced. time_windows[x][0]->start of service window for node x ; time_windows[x][1]->end of service window for node 'x'. Can be empty if no time-window constraints. If provided, for a node with no such restriction, provide '0' and '-1'. Time starts from '0' for the model. + //speeds : It is a matrix of integral values specifying the speed of the vehicles. The variations are :- empty matrix - Indicates that transit times are to be ignored while minimizing total-time for the optimal route. [1x1] - single value - Same avg. speed for all vehicles between any two nodes. [nxn] - A matrix specifying different avg.speeds between different nodes. speed[x][y]-> Gives the average speed while going from node 'x' to node 'y'. (Asymmetric speeds supported) + //waiting_times : a [1xn] vector of integral values containing the waiting times, if any, at the nodes. Could be empty if no waiting constraints. + //refuel_flag : a single integral value indicating if fuel constraints are to be considered or not.(Default : '0') '0'->No fuel constraints '1' ->Fuel constraints to be included in the model. + //fuel_capacity : a single integral value specifying the fuel capacity of the vehicles under consideration (same for all). Need to be provided if refueling constraints active. Needs to be positive. + //refuel_nodes : It is a [1xA] vector of integral values (A-> no. of refuel nodes), containing the indices of refueling nodes. Could be empty indicating the absence of refuel nodes. + //penalty : It is an [Ax2] matrix containing the cost penalties for skipping certain optional nodes (A->no. of optional nodes). penalty[x][0]-> The index of the optional node ; penalty[x][1]-> The cost penalty associated with that node. + //groups : It is an [AxB] matrix of integral values specifying groups of nodes that must lie on the same vehicle route. A-> No. of groups. B-> Size of the largest group. Each row contains the indices of a separate group. Smaller groups are padded with '0's on the right. + //group_penalty : It is a single integral value specifying the cost penalty incurred if a node from a group is unable to be serviced by the same vehicle in the optimal solution. This value is mandatory if group constraints are included in the model. (The model tends to minimize total distance and total time, while amassing minimal cost penalties ( legible tradeoffs to minimize distance ). USE -1, if the groups are to be strictly imposed (cannot exclude a node from a group while vying to minimize distance). This value CAN be zero, indicating that grouping constraints are purely optional. Default value : -1. + //time_limit : It is the maximum time (in milliseconds; integral value) for which the optimizer is allowed to run. If by the end of this time, the engine is unable to find even an initial solution, a timeout error status is returned. If, however, an initial solution is found, but not fully optimized yet (in the process of heuristically improving it), it will return the current solution, albeit not optimal, as the final solution. This value cannot be zero. Default : 10 seconds. + // + //total_distance : It is the summation of the total distance for all the routes in the optimal solution, if any. + //routes : It is a [vxn] matrix containing the routes for the vehicles in the optimal solution, if any. (padded with 0's on the right) + //distances : It is a [1xv] vector containing the distances covered by the various routes in the optimal solution. + //total_time : It is the summation of the times taken by the various vehicles to complete their journeys. + //times : It is a [1xv] vector containing the individual times taken by the vehicles to complete their routes. + //status : It is the enumerated "flag" value returned by the Google OR tools Routing Library, indicating the status of the solution.(Details in the description) + // + //Description + // + //\text{The \textbf{`Vehicle Routing Problem' } is a combinatorial optimization and linear integer programming problem in graph theory.\\A superset of the well-known \textbf{Travelling Salesman Problem}, it vies to find an optimal set of non-overlapping routes for a fleet of vehicles (the anecdotal ``salesmen"), passing through a given set of cities(nodes in the graph) starting from one or more starting nodes called the \textbf{`depot(s)'}.\\In the pursuit of optimality, it tends to minimize the \textbf{total distance } across all the routes and/or other parameters specified by the user, like \textbf{`time'}, \textbf{`cost'}, etc.}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + //\text{\textbf{\underline{MATHEMATICAL\textbf{ }STATEMENT} :}}\\ + //\text{}\\ + //\text{}\\ + //\text{}\\ + // + // + //\begin{math} + //\text{Let } N= \left(V,E\right) \text{denote the specified graph}\\ + //\text{Let } c_{ij} \text{ denote the distance from } i \to j.\\\\ + //\textbf{\underline{Objective} : }\quad Minimize \quad \sum_{i \in V} \sum_{j \in V} c_{ij} x_{ij} \\\\\\ + //\text{Subject to :} \qquad + //\sum_{i\in V} x_{ij} = 1 \quad \forall \quad j \in V\backslash\{0\}\qquad (1) \\\\ + //\text{}\\ + //\text{}\qquad \hspace{3em} \qquad \sum_{j\in V} x_{ij} = 1 \quad \forall \quad i \in V\backslash\{0\}\qquad \text{ } (2) \\\\ + //\text{}\\ + //\text{}\qquad \hspace{3em} \qquad \sum_{i\in V} x_{i0} = K\quad \text{;} \qquad \hspace{3em} \qquad\text{ } (3)\\\\ + //\text{}\\ + //\text{}\qquad \hspace{3em} \qquad \sum_{j\in V} x_{0j} = K\quad \text{;} \qquad \hspace{3em} \qquad\text{ } (4)\\\\ + //\text{}\\ + //\text{}\qquad \hspace{3em} \qquad x_{ij} \in \{0,1\} \quad \forall \quad i,j \in V \text{ ; } \hspace{3em} \text{ } (5)\\\\ + //\text{}\\ + //\end{math} + //\text{}\\ + //\text{}\\ + // + // + // + //\text{}\\ + //\text{}\\ + //\text{(1), (2) specify that exactly one arc enters and one arc leaves each node in the solution.}\\ + //\text{}\\ + //\text{(3), (4) specify that the total number of leaving the depot is equal to the total number entering it(single depot mode).} + //\text{}\\ + //\text{}\\ + //\text{}\\ + // + // + //Legend : + // + //status - Integral value returned by the Google OR Tools Routing library, indicating the status of the solution for the current VRP + // + //status=0 - ROUTING_NOT_SOLVED (Before the solver is invoked) + //status=1 - ROUTING_SUCCESS (TSP solved successfully(optimal solution found) + //status=2 - ROUTING_FAIL(No solution found) + //status=3 - ROUTING_FAIL_TIMEOUT (solution was taking too long; Timed out) + // + // + // For more details, refer to : https://en.wikipedia.org/wiki/Vehicle_routing_problem + // + // or to : https://developers.google.com/optimization/routing/tsp/vehicle_routing#cvrp + // + // The problem is also related to the HAMILTONIAN PATH problem : https://en.wikipedia.org/wiki/Hamiltonian_path + // + // + //Examples + // //INPUT: + //adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + // 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + // 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + // 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + // 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + // 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + // 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + // 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + // 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + // 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + // 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + // 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + // 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + // + //labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + // + //start = 1; + // + //vehicles = 3; + // + //demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + // + //service_time_per_demand=3; + // + //max_vehicle_capacity = 60; + // + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand); + // + //Examples + //adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + // 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + // 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + // 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + // 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + // 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + // 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + // 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + // 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + // 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + // 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + // 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + // 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + // + //labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + // + //start = [] ; + // + //vehicles = 3; + // + //demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + // + //service_time_per_demand=3; + // + //max_vehicle_capacity = 60; + // + //[total_distance,routes] = vrp(adj_matrix, vehicles,start,labels,demands,max_vehicle_capacity,service_time_per_demand); + // + // + //Authors + //Samuel Wilson + + + + + + + //obtaining the number of inputs and outputs + + [lhs,rhs]=argn(); + + + //checking the number of output arguments + + if (lhs < 2 | lhs > 6) then + errmsg = msprintf(gettext("%s : Number of output parameters is expected to be ''2'' to ''6''. Found %d. Refer to help/FOT Documentation for more details\n"),"vrp",lhs); + error(errmsg); + end + + + + + //checking the number of input arguments + + if (rhs < 3 | rhs > 17) then + errmsg = msprintf(gettext("%s : Number of input parameters is expected to be 3-16 (3,4,6,7,8,9,10,13,14, 16 or 17 only). Found %d. Refer to help/FOT Documentation for more details\n"),"vrp",rhs); + errro(errmsg); + end + + + //storing and further checking the number of input arguments + + adj_matrix = varargin(1); + vehicles = varargin(2); + start = varargin(3); + + + + ///////initializing all the optional parameters(before checking if corresponding input is provided)/////// + labels = ""; //NOTE- the size of labels ( ie. "") is actually '1', not '0' + demands = []; + max_vehicle_capacity = 0; + service_time_per_demand = 0; // default = 0, ie.service times to be ignored for time minimization + time_windows = []; + speeds = []; + waiting_times = []; + refuel_flag = 0; + fuel_capacity = []; + refuel_nodes = []; + penalty = []; + groups = []; + group_penalty=-1; // default = -1, ie. Grouping is strictly imposed. + time_limit = 10000; // default = empty, ie. No time limit imposed + + + + //Note, for an empty string a="", in scilab, 'length(a) returns 'zero' but the size if [1x1] + + + if (rhs > 3) then + if ( varargin(4)<>[] ) then + labels = varargin(4); + end + end + + + + + if (rhs > 4) then + if (rhs == 5) then + errmsg = msprintf(gettext("%s : Unexpected number of input arguments (5). ''Max Vehicle Capacity'' (argument #6) mandatory when ''demands'' (argument #5) specified.\n"),"vrp"); + error(errmsg); + else + demands = varargin(5); + max_vehicle_capacity = varargin(6); + end + end + + + if (rhs > 6) then + if (length(varargin(7))<>0) then + service_time_per_demand = varargin(7); + end + end + + + if (rhs > 7) then + time_windows = varargin(8); + end + + if (rhs > 8) then + speeds = varargin(9); + end + + if (rhs > 9) then + waiting_times = varargin(10); + end + + + if (rhs > 10) then + if (length(varargin(11)<>0)) then + refuel_flag = varargin(11); + end + + if ( rhs < 13) then + if ( refuel_flag == 1) then + errmsg = msprintf(gettext("%s : Unexpected number of input arguments (%d). Number of input parameters can be 3,4,6,7,8,9,10,13,14, 16 or 17 only. ''fuel_capacity'' (argument #12) and ''fuel_nodes'' (argument #13) are required to be given if ''refuel_flag'' (argument #10) is given. Refer to help/FOT Documentation for more details.\n"),"vrp",rhs); + error(errmsg); + end + else + fuel_capacity = varargin(12); + refuel_nodes = varargin(13); + + end + end + + if (rhs > 13) then + penalty = varargin(14); + end + + + if (rhs > 14) then + groups = varargin(15); + if (rhs < 16) then + errmsg = msprintf(gettext("%s : Unexpected number of input arguments (%d). Number of input parameters can only be 3,4,6,7,8,9,10,13,14, 16 or 17. ''group_penalty'' (argument #16) must be provided with ''groups'' (argument #15). Refer to help/FOT Documentation for more details.\n"),"vrp",rhs); + error(errmsg); + + else + if (length(varargin(16))<>0) then + group_penalty = varargin(16); + end + end + end + + if (rhs > 16) then + if (varargin(17) <> []) then + time_limit = varargin(17); + else + time_limit = 1000; + end + end + + //All inputs stored; optional inputs which weren't provided, initialized + + + + ////////Checking the type of all input arguments////// + + Checktype("vrp",adj_matrix,"adj_matrix",1,"constant"); + Checktype("vrp",vehicles,"vehicles",2,"constant"); + Checktype("vrp",start,"start",3,"constant"); + + //empty matrix is also of type - "constant" so we can directly check without conditions if the optional parameter was actually provided + + Checktype("vrp",labels,"labels",4,"string"); + Checktype("vrp",demands,"demands",5,"constant"); + Checktype("vrp",max_vehicle_capacity,"max_vehicle_capacity",6,"constant"); + Checktype("vrp",service_time_per_demand,"service_time_per_demand",7,"constant"); + Checktype("vrp",time_windows,"time_windows",8,"constant"); + Checktype("vrp",speeds,"speeds",9,"constant"); + Checktype("vrp",waiting_times,"waiting_times",10,"constant"); + Checktype("vrp",refuel_flag,"refuel_flag",11,"constant"); + Checktype("vrp",fuel_capacity,"fuel_capacity",12,"constant"); + Checktype("vrp",refuel_nodes,"refuel_nodes",13,"constant"); + Checktype("vrp",penalty,"penalty",14,"constant"); + Checktype("vrp",groups,"groups",15,"constant"); + Checktype("vrp",group_penalty,"group_penalty",16,"constant"); + Checktype("vrp",time_limit,"time_limit",17,"constant"); + + + + + ///////Checking the dimensions of all the inputs/////// + + //checking 'adj_matrix' + + m=size(adj_matrix,"r"); + n=size(adj_matrix,"c"); + + + if (m <> n) then + errmsg = msprintf(gettext("%s : The dimensions of the given adjacency matrix ''adj_matrix'' (argument #1) are erroneous [%d %d]. Number of rows and columns are to be equal (square matrix) (=no. of nodes of the graph). \n"),"vrp",m,n); + error(errmsg); + end + + nodes = m; //number of nodes in the graph + + + //checking 'vehicles' + + mode_flag= []; + + m = size(vehicles,"r"); + n = size(vehicles,"c"); + + + if ( ~(m==1 & n==1)) then + errmsg = msprintf(gettext("%s : Wrong dimensions [%dx%d] for input argument #2 ( ''vehicles''). Single integral value expected (ie. [1x1]).\n"),"vrp",m,n); + error(errmsg); + end + + + //checking 'start' and setting mode_flag accordingly + + m = size(start,"r"); + n = size(start,"c"); + + if ( (m == 1) & (n == 1) ) then + mode_flag = 0; + elseif ( (m == 0) & (n == 0) ) then + mode_flag = 1; + elseif ( (m == vehicles) & (n == 2) ) then + mode_flag = 2; + else + errmsg = msprintf(gettext("%s : Wrong dimensions for input argument #3 (''start''). Expected to be either [1x1], (empty matrix) or [vx2] ( v->number of vehicles). Refer to help/FOT Documentation for more details.\n"),"vrp"); + error(errmsg); + end + + + + //checking 'demands' + + m=size(demands,"r"); + n=size(demands,"c"); + + + if ( ~((m==0 & n==0) | (m==1 & n==nodes)) ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #5 (''demands''). Expected to be either an empty matrix or one with dimensions [1x%d]. \n"),"vrp",nodes); + error(errmsg); + end + + + + + //checking labels + + m=size(labels,"r"); + n=size(labels,"c"); + + + if ( labels <> "") then + if ( ~(m==1 & n==nodes) ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #4 ( ''labels''). Expected to be an empty matrix or one with dimensions [1x%d]. \n"),"vrp",nodes); + error(errmsg); + end + end + + + + //checking 'max_vehicle_capacity' + + m = size(max_vehicle_capacity,"r"); + n = size(max_vehicle_capacity,"c"); + + if ( ~((m==0 & n==0) | (m==1 & n==1)) ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #6 ( ''max_vehicle_capacity''). Expected to be either an empty matrix or a singular integral value[1x1].\n"),"vrp"); + error(errmsg); + end + + + + + //checking 'service_time_per_demand' + + m = size(service_time_per_demand,"r"); + n = size(service_time_per_demand,"c"); + + + if ( ~((m==1) & (n==1))) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #7 (''service_time_per_demand''). Expected to be either an empty matrix or a singular integral value[1x1].\n"),"vrp"); + error(errmsg); + end + + + + //checking 'time_windows' + + m = size(time_windows,"r"); + n = size(time_windows,"c"); + + if ( ~((m==0 & n==0) | (m==nodes & n==2))) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #8 (''time_windows''). Expected to be either an empty matrix or one with dimensions [%dx2].\n"),"vrp",nodes); + error(errmsg); + end + + + + + //checking 'speeds' + + m = size(speeds,"r"); + n = size(speeds,"c"); + + if ( ~((m==0 & n==0) | (m==1 & n==1) | (m==nodes & n==nodes))) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #9 ( ''speeds''). Expected to be either [1x1], [%dx%d] or an empty matrix.\n"),"vrp",nodes,nodes); + error(errmsg); + end + + + //checking 'waiting_times' + + m = size(waiting_times,"r"); + n = size(waiting_times,"c"); + + if ( ~((m==0 & n==0) | (m==1 & n==nodes)) ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #10 (''waiting_times''). Expected to be either an empty matrix or one with dimensions [1x%d].\n"),"vrp",nodes); + error(errmsg); + end + + + + //checking 'refuel_flag' + + m = size(refuel_flag,"r"); + n = size(refuel_flag,"c"); + + if ( ~(m==1 & n==1)) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #11 (''refuel_flag''). Expected either a singular 0/1 value or an empty matrix.\n"),"vrp"); + error(errmsg); + end + + + //checking 'fuel_capacity' + + m = size(fuel_capacity,"r"); + n = size(fuel_capacity,"c"); + + if ( refuel_flag == 1) then + if ( ~(m==1 & n==1)) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #12 (''fuel_capacity''). Expected a singular integral value.\n"),"vrp"); + error(errmsg); + end + else + if ( ~(m == 0 & n == 0) ) then + errmsg = msprintf(gettext("%s : Empty matrix expected for the input argument #12 (''fuel_capacity''), when ''refuel flag'' is 0.\n"),"vrp"); + error(errmsg); + end + end + + + + //checking 'refuel_nodes' + + m = size(refuel_nodes, "r"); + n = size(refuel_nodes,"c"); + + if ( refuel_flag == 1) + if ( ~((m==0 & n==0) | (m==1 & n<=nodes))) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #13 (''refuel_nodes''). Expected a vector or an empty matrix.\n"),"vrp"); + error(errmsg); + end + else + if ( ~(m == 0 & n == 0) ) then + errmsg = msprintf(gettext("%s : Empty matrix expected for the input argument #13 (''refuel_nodes''), when ''refuel flag'' is 0.\n"),"vrp"); + error(errmsg); + end + end + + + //checking 'penalty' + + m = size(penalty,"r"); + n = size(penalty,"c"); + + + if ( ~((m==0 & n==0) | (m<=nodes & n==2)) ) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #14 (''penalty''). Expected an [Ax2] matrix (A->number of skippable nodes) or an empty matrix. \n"),"vrp"); + error(errmsg); + end + + + //checking 'groups' + + m = size(groups,"r"); + n = size(groups,"c"); + + if ( ~((m==0 & n==0) | (m<=nodes & n<=nodes))) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #15 (''groups''). Expected an empty matrix or one whose size cannot exceed the number of nodes.\n"),"vrp"); + error(errmsg); + end + + + //checking 'group_penalty' + + m = size(group_penalty,"r"); + n = size(group_penalty,"c"); + + if ( ~(m==1 & n==1)) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #16 (''group_penalty''). Expected a singular integral value or an empty matrix.\n"),"vrp"); + error(errmsg); + end + + //checking 'time_limit' + + m = size(time_limit,"r"); + n = size(time_limit,"c"); + + + if ( ~((m==1 & n==1))) then + errmsg = msprintf(gettext("%s : Wrong dimensions for the input argument #17 (''time_limit''). Expected a singular, integral, positive value.\n"),"vrp"); + error(errmsg); + end + + + + /////Dimensions verified///// + + + + + + ///////Checking if all the inputs are integral(ie. No fractional part)(NOTE -> x.0 is considered inherently integral as fractional part is '0'//////// + + + if ( ~(and(adj_matrix==(int(adj_matrix))))) then + errmsg = msprintf(gettext("%s : All values in argument #1 (''adj_matrix'') are expected to be integral.\n"),"vrp"); + error(errmsg); + end + + + + if( ~(and(vehicles ==(int(vehicles))))) then + errmsg = msprintf(gettext("%s : Number of vehicles ( argument #2) is expected to be an integral value.\n"),"vrp"); + error(errmsg); + end + + + if( ~(and(start ==(int(start))))) then + errmsg = msprintf(gettext("%s : The value(s) for argument #3 ( ''start'') is (are) expected to be integral.\n"),"vrp"); + error(errmsg); + end + + + if( ~(and( demands==(int(demands))))) then + errmsg = msprintf(gettext("%s : All values in argument #5 (''demands'') are expected to be integral.\n"),"vrp"); + error(errmsg); + end + + + if( ~(and(max_vehicle_capacity == (int(max_vehicle_capacity))))) then + errmsg = msprintf(gettext("%s : Max Vehicle Capacity value (argument #6) is expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and(service_time_per_demand ==(int(service_time_per_demand))))) then + errmsg = msprintf(gettext("%s : The value for servive-time-per-demand (argument #7) is expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and( time_windows==(int(time_windows))))) then + errmsg = msprintf(gettext("%s : All values in argument #8 (''time_windows'') are expected to be integral.\n"),"vrp"); + error(errmsg); + end + + + if( ~(and(speeds ==(int(speeds))))) then + errmsg = msprintf(gettext("%s : The value(s) for argument #9 (''speeds'') is (are) expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and(waiting_times ==(int(waiting_times))))) then + errmsg = msprintf(gettext("%s : The values in argument #10 (''waiting_times'') are expected to be integral.\n"),"vrp"); + error(errmsg); + end + + + if( ~(and(refuel_flag ==(int(refuel_flag))))) then + errmsg = msprintf(gettext("%s : The Refuel Flag value (argument #11) is expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and(fuel_capacity==(int(fuel_capacity))))) then + errmsg = msprintf(gettext("%s : The fuel capacity value for the vehicles (argument #12) is expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and(refuel_nodes ==(int(refuel_nodes))))) then + errmsg = msprintf(gettext("%s : All values in argument #13 (''refuel_nodes'') are expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and(penalty ==(int(penalty))))) then + errmsg = msprintf(gettext("%s : All values in argument #14 (''penalty'') are expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and(groups==(int(groups))))) then + errmsg = msprintf(gettext("%s : All values in argument #15 (''groups'') are expected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and(group_penalty ==(int(group_penalty))))) then + errmsg = msprintf(gettext("%s : The group-penalty value (argument #16) is exected to be integral.\n"),"vrp"); + error(errmsg); + end + + if( ~(and(time_limit ==(int(time_limit))))) then + errmsg = msprintf(gettext("%s : The time limit value (argument #17) is expected to be integral.\n"),"vrp"); + error(errmsg); + end + + + + //-----------------------------------------------LOGICAL CHECKS---------------------------------------------------------// + + + ////////Checking 'adj_matrix' (argument #1) ///////// + + + //checking if all the diagonal values in adj_matrix are 0's + + if (~(and(diag(adj_matrix)==0))) then + errmsg=msprintf(gettext("%s : All leading diagonal elements of the adjacency matrix need to be 0\n"),"tsp"); + error(errmsg); + end + + + + ////////// Checking 'vehicles'(argument #2) ////////// + + //checking if the value of 'vehicles' is positive + + if ( ~(vehicles > 0) ) then + errmsg = msprintf(gettext("%s : The number of vehicles in the fleet must be a positive value.\n"),"vrp"); + error(errmsg); + end + + + ////////// Checking 'start'(argument #3) ////////// + + + //if 'start' ain't null, checking if all the values are valid indices (indices go from '1' to 'nodes') + if ( start<>[]) then + if ( (or(start>nodes)) | (or(start<1)) ) then // one or more index values exceed 'nodes' + if (length(start) <> 1) then + errmsg = msprintf(gettext("%s : One or more index values in ''start'' are invalid. Indices can only go from ''1'' to ''%d'' for the given problem\n"),"vrp",nodes); + else + errmsg = msprintf(gettext("%s : The given ''start'' value is not a valid node index. Indices can only go from ''1'' to ''%d'' for the given problem\n"),"vrp",nodes); + end + error(errmsg); + end + end + + + + + + ////////// Checking 'labels'(argument #4) ////////// + + if ( length(labels) <> (length(unique(labels))) ) then + errmsg = msprintf(gettext("%s : The entries in the ''label'' matrix need to be unique (no 2 nodes can have the same labels).\n"),"vrp"); + error(errmsg); + end + + + + + ////////// Checking 'max_vehicle_capacity'(argument #6) ////////// (needs to be checked before the demands) + + + //Checking if the max_vehicle_capacity value is specified(not empty matrix) is demands are given + + if (demands <> []) then + if ( max_vehicle_capacity == []) then + errmsg = msprintf(gettext("%s : For a capacitate VRP, the max_vehicle_capacity cannot be exclude(cannot be an empty matrix).\n"),"vrp"); + error(errmsg); + end + end + + + + //if the problem is a capacitated VRP(demands specified), checking if the value is positive + + + if (demands <> []) then + if ( max_vehicle_capacity<1) then + errmsg = msprintf(gettext("%s : The maximum-vehicle-capacity value needs to be positive.\n"),"vrp"); + error(errmsg); + end + end + + + + + + + + + + ////////// Checking 'demands'(argument #5) ////////// + + if ( demands <>[]) then + + //checking if no values are negative + + if ( or(demands<0)) then + errmsg = msprintf(gettext("%s : One or more values in the ''demands'' vector are negative.\n"),"vrp"); + error(errmsg); + end + + //checking if no demand value exceeds the max_vehicle_capacity value + + if ( or(demands > max_vehicle_capacity) ) then + errmsg = msprintf(gettext("%s : The demand values for one or more nodes exceed the maximum capacity for the vehicles in question, rendering them unserviceable.\n"),"vrp"); + error(errmsg); + end + + //checking that the total demand doesn't exceed the total capacity + + if ( (sum(demands))>(vehicles*max_vehicle_capacity) ) then + errmsg = msprintf(gettext("%s : The total demand exceeds the total capacity of the vehicles in the fleet. The scenario is inherently unserviceable.\n"),"vrp"); + error(errmsg); + end + //we do not consider the case of skip-penalties here as that is only a tradeoff vying for optimality, not an inherent mechanism to conpensate for the handicap of demands exceeding the capacity. The model is essentially impractical in this situation. + + + + //checking if the demand values for the depot(s) is(are) zero. + if (mode_flag == 0) then + if ( demands(start) <> 0 ) then + errmsg = msprintf(gettext("%s : The demand for the depot node has to be zero.\n"),"vrp"); + error(errmsg); + end + elseif (mode_flag == 2) then + deps = start(:,1); + for i = 1: length(deps) + if ( demands(deps(i)) <> 0 ) then + errmsg = msprintf(gettext("%s : The demand for all the depot (start) nodes must be zero.\n"),"vrp"); + end + end + clear deps; + end + + + + + + end + + + + + ////////// Checking 'service_time_per_demand'(argument #7) ////////// + + if ( service_time_per_demand < 0 ) then + errmsg = msprintf(gettext("%s : The value for argument #7 (''service_time_per_demand'') cannot be negative.\n"),"vrp"); + error(errmsg); + end + + + ////////// Checking 'time_windows'(argument #8) ////////// + + if ( time_windows<> []) then + + //converting all '-1's from the second column, if any, to INT_MAX + temp = time_windows(:,2); //seconds column extracted + + for i=1:nodes + if ( temp(i)=='-1' ) then + time_windows(i,2) = 2147483647; + end + end + + + //checking if all values are non-negative now + + if ( or(time_windows <0) ) then + errmsg = msprintf(gettext("%s : Values in ''time_windows'' matrix cannot be negative (except ''-1'' for end times indicating no upper bound for the corresponding node).\n"),"vrp"); + error(errmsg); + end + + + //checking if all the end times are greater than or equal to the corresponding start times + + if ( ~(and(time_windows(:,1)<=time_windows(:,2))) ) then + errmsg = msprintf(gettext("%s : Invalid time-window values : The end-time for service window for one or more nodes in less than the corresponding start-time.\n"),"vrp"); + error(errmsg); + end + + //checking if the windows are wide enough to be serviceable i.e. the window size if greater than or equal to the total service time. Service time is zero by default for when 'tis to be ignored in time minimization so we don't need to demarcate that case(0 will always be less than or equal to the window size(>=0)). This is only to be done is demands are given(ie.e 'tis a capacitated VRP) + +// if ( demands <> []) then +// if ( or((time_windows(:,2)-time_windows(:,1)) >= (((demands*service_time_per_demand)') + waiting_times)) ) then +// errmsg = msprintf(gettext("%s : The time-window for one or more nodes is not wide enough to be serviceable(i.e. the duration of the time-window is smaller than the time required to service that node.\n"),"vrp"); +// error(errmsg); +// end +// +// end + end + + + + + ////////// Checking 'speeds'(argument #9) ////////// + + if ( speeds <> []) then + if (length(speeds)==1) then + if (speeds(1,1)<1) then + errmsg = msprintf(gettext("%s : The avg.speeds value thus provided must be POSITIVE.\n"),"vrp"); + error(errmsg); + end + else //[nxn] matrix given + + //first off, all the diagonal values need to be zero + + if ( ~(and(diag(speeds) == 0)) ) then + errmsg = msprintf(gettext("%s : All the diagonal values in the given ''speeds'' matrix (argument #9) need to be ''0''.\n"),"vrp"); + error(errmsg); + end + + + for i = 1:nodes + for j = 1:nodes + if ( (speeds(i,j)<1) & (i<>j)) then + errmsg = msprintf(gettext("%s : Speed values need to be POSITIVE. \n"),"vrp"); + error(errmsg); + end + end + end + + end + + end + + + + + + + + ////////// Checking 'waiting_times'(argument #10) ////////// + + //checking if waiting times are non-negative + + if ( waiting_times <>[]) then + if ( or(waiting_times < 0) ) then + errmsg = msprintf(gettext("%s : Waiting time values cannot be negative. \n"),"vrp"); + error(errmsg); + end + + end + + + + + + ////////// Checking 'refuel_flag'(argument #11) ////////// + + //checking if the value is only either '0' or '1' + + if ( (refuel_flag<>1) & (refuel_flag<>0) ) then + errmsg= msprintf(gettext("%s : The refuel flag can only take the value ''0'' or ''1''. Check the FOT documentation for details.\n"),"vrp"); + error(errmsg); + end + + + + + + + ////////// Checking 'fuel_capacity'(argument #12) ////////// + + + //checking if the fuel_capacity value is positive + + if ( rhs > 10 ) then + if ( fuel_capacity<1 ) then + errmsg = msprintf(gettext("%s : Fuel Capacity value is expected to be positive.\n"),"vrp"); + error(errmsg); + end + end + + + + + ////////// Checking 'refuel_nodes'(argument #13) ////////// + + + //checking if all the indices are valid + + if ( refuel_nodes<>[]) then + if ( (or(refuel_nodes<1)) | (or(refuel_nodes>nodes)) ) then + errmsg = msprintf(gettext("%s : One or more fuel node index values are invalid. Valid indices for the current model - ''1'' to ''%d''. \n"),"vrp",nodes); + error(errmsg); + end + end + + + + + + ////////// Checking 'penalty'(argument #14) ////////// + + if ( penalty <> [] ) then + if ( (or(penalty(:,1)<1)) | (or(penalty(:,1)>nodes)) ) then + errmsg = msprintf(gettext("%s : One or more node indices provided in the ''penalty'' matrix ( argument #14) are invalid. Valid indices for the current model- ''1'' to ''%d''. \n"),"vrp",nodes); + error(errmsg); + end + + if ( or(penalty(:,2)<0) ) then + errmsg = msprintf(gettext("%s : Cost penalty values in the ''penalty'' matrix (argument #14) cannot be negative.\n"),"vrp"); + error(errmsg); + end + + + if ( start <> []) then + if ( length(start)==1 ) then + if ( or(penalty(:,1)==start) ) then + errmsg = msprintf(gettext("%s : The depot cannot be provided as an optional node.\n"),"vrp"); + error(errmsg); + end + else + for i= 1:(size(penalty,"r")) + if ( (or(start(:,1) == penalty(i,1))) | (or(start(:,2) == penalty(i,1))) ) then + errmsg = msprintf(gettext("%s Node of the start/end nodes can be specified as optional in the ''penalty'' matrix.\n"),"vrp"); + error(errmsg); + end + end + end + end + end + + + + + + ////////// Checking 'groups'(argument #15) ////////// + + if ( groups <>[] ) then + if ( (or(groups < 0)) | (or(groups>nodes)) ) then + errmsg = msprintf(gettext("%s : One or more node index values in argument #15 ( ''groups'') is invalid. Valid indices for this model - ''1'' to ''%d''.\n"),"vrp",nodes); + error(errmsg); + end + + + num_groups = size(groups,"r"); + groups_cols = size(groups,"c"); + + num_zeroes=0; + + for i = 1:num_groups + num_zeroes= num_zeroes + length(find(groups(i,:)==0)); + if ( ((min(find(groups(i,:)==0)))) <> [] ) then + if ( (groups_cols-length(find(groups(i,:)==0))+1) <> ((min(find(groups(i,:)==0)))) ) then // indicates that there's a zero somewhere between the other indices in the current group, i.e. an index of '0' is specified + errmsg = msprintf(gettext("%s : Index value for a node cannot be ''0''. Zero''s are only used for right-padding in the ''groups'' matrix. Check row %d.\n"),"vrp",i); + error(errmsg); + end + end + end + + + if ( num_zeroes == 0 ) then + if ( (length(unique(groups)))<>length(groups) ) then + errmsg = msprintf(gettext("%s : One or more node index values in the ''groups'' matrix (argument #15) are repeated. No index can occur twice in a group. Also, no node can be a part of 2 groups.\n"),"vrp"); + error(errmsg); + end + else + if ( (length(unique(groups)) + num_zeroes - 1) <> length(groups) ) then + errmsg = msprintf(gettext("%s : One or more node index values in the ''groups'' matrix (argument #15) are repeated. No index can occur twice in a group. Also, no node can be a part of 2 groups.\n"),"vrp"); + error(errmsg); + end + end + + clear num_zeroes; + clear num_groups; + clear groups_cols; + + end + + ////////// Checking 'group_penalty'(argument #16) ////////// + + + //checking if the value is permissible(-1,0, or positive) + + if ( group_penalty < -1 ) then + errmsg = msprintf(gettext("%s : Forbidden value for ''group_penalty'' (argument #16). Expected- -1, 0, or any positive value.\n"),"vrp"); + error(errmsg); + end + + + + ////////// Checking 'time_limit'(argument #17) ////////// + + + //checking is time limit positive + + if ( time_limit < 1 ) then + errmsg = msprintf(gettext("%s : Positive value expected for the ''time_limit'' (argument #17). \n"),"vrp"); + error(errmsg); + end + + + + //---------------------------------END OF LOGICAL CHECKS---------------------------------------------------// + + + + + + //-----------------------------------------SOLUTION--------------------------------------------------------// + + + //Solving the given VRP by calling the gateway function + + + [total_distance, routes, distances, total_time, times, status] = VRP(adj_matrix, vehicles, mode_flag, start, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds, waiting_times, refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + + select status + + case 0 then + printf("\n''ROUTING_NOT_SOLVED'' ; The solver-module invocation failed. If the problem persists, notify the toolbox authors.\n"); + case 1 then + + + if ( lhs > 5) then + printf( "Status :- %d\n",status); + end + printf("\n ''ROUTING_SUCCESS'' ; An optimal solution was found for the given model!\n"); + printf("Total Distance -> %d\n",total_distance); + + if ( lhs>3) then + printf("Total time -> %d\n",total_time); + end + + printf("\n Optimal Routes :- \n"); + + for i = 1:vehicles + temp = routes(i,:); + if ( find(temp==0)<>[]) then + temp = temp(1:(min(find(temp==0))-1)); // returns the row sans the zero padding, if any + end + + + if ( temp(1)==temp(2) ) then + printf("Vehicle #%d - Not Deployed!\n", i); + else + + printf("\n\n\nRoute for vehicle #%d : - \n",i); + + + tt=1; + + if ( length(labels)<>0) then + for j = 1 : (length(temp)-1) + printf(" %s (%d) ->", labels(temp(j)),temp(j)); + tt=j+1; + end + + if ( length(temp) == nodes ) then //when all nodes are mapped to a single route(or when no. of vehicles is '1') + printf(" %s (%d) ->",labels(temp(tt)),temp(tt)); + printf(" %s (%d) \n",labels(temp(1)),temp(1)); + else + printf(" %s (%d) \n",labels(temp(tt)),temp(tt)); + end + + + else + for j= 1 : (length(temp)-1) + printf(" %d ->", temp(j)); + end + if ( length(temp) == nodes ) then //when all nodes are mapped to a single route(or when no. of vehicles is '1') + printf(" %d ->",temp($)); + printf(" %d \n",temp(1)); + else + printf(" %d \n",temp($)); + end + + end + + + if ( lhs > 2) then + printf( "The total-distance for route #%d = %d\n",i,distances(i)); + + if ( lhs > 4) then + printf( " The time taken for route #%d = %d\n",i,times(i)); + end + + end + + end + + end + + clear 'temp'; + clear 'tt'; + + + + + case 2 then + printf("\n''ROUTING_FAIL''\n ; No optimal solution was found for the given model.\n"); + + case 3 then + if ( routes <> []) then + printf("\n''ROUTING_FAIL_TIMEOUT''\n ; The time limit was reached before the model converged to the optimal solution. The returned solution CAN be further optimized; Try increasing the time-limit for a better solution.\n"); + else + printf("\n''ROUTING_FAIL_TIMEOUT''\n ; No solution was found within the stipulated the time-limit. Try increasing the time-limit.\n"); + end + + else + printf("\nUnexpected return status. Notify the toolbox authors.\n"); + break; + + end + +endfunction + + + + + diff --git a/sci_gateway/builder_gateway.sce b/sci_gateway/builder_gateway.sce new file mode 100644 index 0000000..6fe5d0f --- /dev/null +++ b/sci_gateway/builder_gateway.sce @@ -0,0 +1,7 @@ +sci_gateway_dir = get_absolute_file_path('builder_gateway.sce'); + +tbx_builder_gateway_lang('cpp', sci_gateway_dir); + +tbx_build_gateway_loader(['cpp'], sci_gateway_dir); + +clear sci_gateway_dir; diff --git a/sci_gateway/cpp/builder_gateway_cpp.sce b/sci_gateway/cpp/builder_gateway_cpp.sce new file mode 100644 index 0000000..4998a24 --- /dev/null +++ b/sci_gateway/cpp/builder_gateway_cpp.sce @@ -0,0 +1,145 @@ +function startGateway() + + path_builder = get_absolute_file_path("builder_gateway_cpp.sce"); + + third_party_dir = path_builder + filesep() + ".." + filesep() + ".." + filesep() + "thirdparty"; + + // Library Name + if isdef("TOOLBOX_NAME") then + LIBRARY_NAME = TOOLBOX_NAME + "_cpp"; + else + LIBRARY_NAME = "Optimization_Toolbox_cpp"; + end + + // Function Names + FUNC_NAMES = [ + "solve_qcqpglob","sci_qcqpglob" + "solve_mincostflow","sci_min_cost_flow"; + "solve_linsumassignment","sci_linear_sum_assignment"; + "MaxFlow","sci_max_flow"; + "BellmanFordShortestPath","sci_BellmanFord_shortestPath"; + "TSP","sci_tsp"; + "VRP","sci_vrp"; + "JSSP","sci_jssp" + ]; + + // File Names + FILES = [ + "sci_iofunc.cpp", + "sci_qcqpglob.cpp", + "sci_min_cost_flow.cpp", + "sci_linear_sum_assignment.cpp", + "sci_max_flow.cpp", + "sci_BellmanFord_shortestPath.cpp", + "sci_tsp.cpp", + "sci_vrp.cpp", + "sci_jssp.cpp" + ]; + + // Get Platform Arch + [a, opt] = getversion(); + Arch = opt(2); + + // Default Compiler Flags + CXX_FLAGS = "-std=c++0x -D__USE_DEPRECATED_STACK_FUNCTIONS__ -w -fpermissive "; + LD_FLAGS = []; + + // OS Specific Compiler Configuration + if (getos() == "Windows") then + INC_DIR = third_party_dir + filesep() + "Windows" + filesep() + "include"; + LIB_DIR = third_party_dir + filesep() + "Windows" + filesep() + "lib" + filesep() + Arch; + + MINOTAUR_INC_DIR = INC_DIR + filesep() + "minotaur"; + + CXX_FLAGS = CXX_FLAGS + "-I""" + path_builder + """ "; + CXX_FLAGS = CXX_FLAGS + "-I""" + INC_DIR + """ "; + CXX_FLAGS = CXX_FLAGS + "-I""" + MINOTAUR_INC_DIR + """ "; + + LIB_COINUTILS = "libCoinUtils.lib"; + LIB_OSI = "libOsi.lib"; + LIB_CLP = "libClp.lib"; + LIB_OSICLP = "libOsiClp.lib"; + LIB_CLPSOLVER = "libClpSolver.lib"; + LIB_COINMUMPS = "libcoinmumps.lib"; + LIB_IPOPT = "libipopt.lib"; + LIB_MINOTAUR = "libminotaur.lib"; + LIB_MNTROSILP = "libmntrosilp.lib"; + LIB_MNTRIPOPT = "libmntripopt.lib"; + LIB_MNTRENGFAC = "libmntrengfac.lib"; + LIB_CVRPTW = "libcvrptw_lib.lib"; + LIB_DIMACS = "libdimacs.lib"; + LIB_FAP = "libfap.lib"; + LIB_JNIORTOOLS = "libjniortools.lib"; + LIB_ORTOOLS = "libortools.lib"; + + LD_FLAGS = LD_FLAGS + "/LIBPATH:""" + LIB_DIR + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_COINUTILS + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_OSI + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_CLP + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_OSICLP + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_CLPSOLVER + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_COINMUMPS + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_IPOPT + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_MINOTAUR + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_MNTROSILP + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_MNTRIPOPT + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_MNTRENGFAC + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_CVRPTW + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_DIMACS + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_FAP + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_JNIORTOOLS + """ "; + LD_FLAGS = LD_FLAGS + """" + LIB_ORTOOLS + """ "; + else + INC_DIR = third_party_dir + filesep() + "linux" + filesep() + "include"; + LIB_DIR = third_party_dir + filesep() + "linux" + filesep() + "lib" + filesep() + Arch; + + MINOTAUR_INC_DIR = INC_DIR + filesep() + "minotaur"; + + CXX_FLAGS = CXX_FLAGS + "-I""" + path_builder + """ "; + CXX_FLAGS = CXX_FLAGS + "-I""" + INC_DIR + """ "; + CXX_FLAGS = CXX_FLAGS + "-I""" + MINOTAUR_INC_DIR + """ "; + CXX_FLAGS = CXX_FLAGS + "-Wl,-rpath=""" + LIB_DIR + """ "; + + LIB_COINUTILS = "CoinUtils"; + LIB_OSI = "Osi"; + LIB_CLP = "Clp"; + LIB_OSICLP = "OsiClp"; + LIB_CLPSOLVER = "ClpSolver"; + LIB_COINMUMPS = "coinmumps"; + LIB_IPOPT = "ipopt"; + LIB_MINOTAUR = "minotaur"; + LIB_MNTROSILP = "mntrosilp"; + LIB_MNTRIPOPT = "mntripopt"; + LIB_MNTRENGFAC = "mntrengfac"; + LIB_CVRPTW = "cvrptw_lib"; + LIB_DIMACS = "dimacs"; + LIB_FAP = "fap"; + LIB_JNIORTOOLS = "jniortools"; + LIB_ORTOOLS = "ortools"; + + LD_FLAGS = LD_FLAGS + "-L""" + LIB_DIR + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_COINUTILS + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_OSI + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_CLP + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_OSICLP + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_CLPSOLVER + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_COINMUMPS + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_IPOPT + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_MINOTAUR + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_MNTROSILP + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_MNTRIPOPT + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_MNTRENGFAC + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_CVRPTW + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_DIMACS + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_FAP + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_JNIORTOOLS + """ "; + LD_FLAGS = LD_FLAGS + "-l""" + LIB_ORTOOLS + """ "; + end + + tbx_build_gateway(LIBRARY_NAME, FUNC_NAMES, FILES, path_builder, [], LD_FLAGS, CXX_FLAGS); + +endfunction + +startGateway(); + +clear startGateway; diff --git a/sci_gateway/cpp/misc.hpp b/sci_gateway/cpp/misc.hpp new file mode 100644 index 0000000..22051f5 --- /dev/null +++ b/sci_gateway/cpp/misc.hpp @@ -0,0 +1,20 @@ +#ifndef MISCHEADER +#define MISCHEADER + +#include + +template T* ArrConvertMajor(T* src, unsigned int rows, unsigned int cols) +{ + unsigned int i, j; + T* dest = (T*)malloc(sizeof(T) * rows * cols); + for(i = 0; i < rows; ++i) + { + for(j = 0; j < cols; ++j) + { + dest[i * cols + j] = src[j * rows + i]; + } + } + return dest; +} + +#endif //MISCHEADER diff --git a/sci_gateway/cpp/sci_BellmanFord_shortestPath.cpp b/sci_gateway/cpp/sci_BellmanFord_shortestPath.cpp new file mode 100644 index 0000000..98cbb10 --- /dev/null +++ b/sci_gateway/cpp/sci_BellmanFord_shortestPath.cpp @@ -0,0 +1,424 @@ +#include "ortools/graph/shortestpaths.h" +extern "C"{ +#include +#include +#include +#include +#include +#include +#include + +using namespace operations_research; + +/* +Naming suffixes(also, the respective order) for inputs :- +1->tails/start_nodes +2->heads/end_nodes +3->weights(for the arc head[i]->tail[i] +4->[source,target] +5->user-defined value for disconnected-distance(default is INT_MAX) +6->0/1 value indicating if output(messages and shortest path, if it exists) is to be displayed or not, i.e. 0->internal test(obscured from the user); 1-> user test, pertinent outputs expected. +*/ + +/* + +Naming suffixes(also, the respective order) for outputs :- +1->The minimun cost incurrred in reaching the end node(following the shortest path); NULL if the start and end nodes are not connection +2->The vector containing the shortest path from the start to the end node. empty vector if the start and end nodes are not connected + +*/ + +double *sp_piVar1=NULL,*sp_piVar2=NULL,*sp_piVar3=NULL,*sp_piVar4=NULL,*sp_piVar5=NULL, *sp_piVar6=NULL; +int sp_num_arcs; +int disconnected_distance=INT_MAX; + + +long long retrieve(int u, int v) // Returns the weight corresponding to the arc going from node u(tail) to node v(head). IF MORE THAN ONE ARCS JOINING THE SAME 2 NODES, THIS FUNCTION RETURNS THE SMALLER OF THE 2 WEIGHTS +{ + int temp=INT_MIN; + int flag=0; + + for(int i=0;itemp)) + { + temp=sp_piVar3[i]; + flag=1; + } + + if(flag) + return temp; + else + return disconnected_distance; + +} + + +int sci_BellmanFord_shortestPath(char *fname) +{ + + SciErr scierror; + + int iType1=0,iType2=0,iType3=0,iType4=0,iType5=0,iType6=0; + + int m1=0,n1=0,m2=0,n2=0,m3=0,n3=0,m4=0,n4=0,m5=0,n5=0,m6=0,n6=0; + + + int *piAddressVar1=NULL,*piAddressVar2=NULL,*piAddressVar3=NULL,*piAddressVar4=NULL,*piAddressVar5=NULL,*piAddressVar6=NULL; + + double *piReal1=NULL; + int *piReal2=NULL; + int flag; + + + int start_node; + int end_node; + + + std::vector nodes; + + + CheckInputArgument(pvApiCtx,6,6); + CheckOutputArgument(pvApiCtx,3,3); + + + + // GETTING ADDRESSES OF THE INPUT MATRICES + + scierror=getVarAddressFromPosition(pvApiCtx,1,&piAddressVar1); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + scierror=getVarAddressFromPosition(pvApiCtx,2,&piAddressVar2); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + scierror=getVarAddressFromPosition(pvApiCtx,3,&piAddressVar3); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,4,&piAddressVar4); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,5,&piAddressVar5); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,6,&piAddressVar6); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + + //GETTING AND CHECKING THE TYPES OF THE INPUT MATRICES + + scierror=getVarType(pvApiCtx,piAddressVar1,&iType1); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar2,&iType2); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar3,&iType3); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar4,&iType4); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar5,&iType5); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar6,&iType6); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + if(iType1!=sci_matrix ||iType2!=sci_matrix ||iType3!=sci_matrix ||iType4!=sci_matrix ||iType5!=sci_matrix||iType6!=sci_matrix) + { + + if(iType1!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #1. Matrix Expected.\n"); + + if(iType2!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #2. Matrix Expected.\n"); + + if(iType3!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #3. Matrix Expected.\n"); + + + if(iType4!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #4. Matrix Expected.\n"); + + if(iType5!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #5. Matrix Expected.\n"); + + if(iType6!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #6. Matrix Expected.\n"); + + return 0; + } + + + //GETTING ACTUAL MATRICES + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar1,&m1,&n1,&sp_piVar1); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar2,&m2,&n2,&sp_piVar2); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar3,&m3,&n3,&sp_piVar3); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar4,&m4,&n4,&sp_piVar4); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar5,&m5,&n5,&sp_piVar5); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar6,&m6,&n6,&sp_piVar6); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + //checking if the first 3 inputs are indeed 1-d arrays(in 1xn matrix form) + + if((m1!=1)||(m2!=1)||(m3!=1)) + { + Scierror(787,"Invalid Input(s)! The graph needs to be in the form of 3 arrays(1xn Matrices), viz tail[],head[],weight[]\n"); + return 0; + } + + //checking if the size of the 3 matrices describing the graph is equal + + if(n1!=n2||n1!=n3) + { + Scierror(788,"Wrong Input(s)! The input graph is erroneous. The three matrcies describing the graph aren't of the same size\n"); + return 0; + } + + //checking if the start node and end node values are of the correct form(1x2 matrix) + + if(m4!=1||n4!=2) + { + + Scierror(789,"Wrong Input #4! Required- a 1x2 matrix containing 2 values viz. the source and target nodes, in that order\n"); + return 0; + + } + + + //checking if the specified value for disconnected-distance is a 1x1 matrix(singular value) + if(m5!=1||n5!=1) + { + Scierror(789,"Wrong Input #5! Required - a singular value(integral) for the 'disconnected-distance'(i.e. any arcs/edges with weigths >=disconnected-distance are ignored i.e. no path. \n"); + return 0; + } + + + + //no check needed for argument 6 as it ain't a user provided value + + + sp_num_arcs=n1; + start_node=sp_piVar4[0]; + end_node=sp_piVar4[1]; + disconnected_distance=sp_piVar5[0]; + + int abstraction=sp_piVar6[0]; + + + + int sflag=0; + int eflag=0; + + //checking if the start node and end node values are valid(i.e. nodes corresponding to these values do indeed exist in the given graph or not) + + for(int i=0;(i=0;i--) + { + sciprint(" -> %d", nodes.at(i)); + cost+=retrieve(nodes.at(i+1),nodes.at(i)); + piReal2[nodes.size()-i-1]=nodes.at(i); + } + + sciprint("\n"); + + sciprint("Minumum cost (using the said path) :- %f\n",(piReal1[0]=cost)); + } + + + + scierror=createMatrixOfDouble(pvApiCtx,nbInputArgument(pvApiCtx)+1,1,1,piReal1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+2,1,nodes.size(),piReal2); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+3,1,1,&flag); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + + AssignOutputVariable(pvApiCtx,1)=nbInputArgument(pvApiCtx)+1; + AssignOutputVariable(pvApiCtx,2)=nbInputArgument(pvApiCtx)+2; + AssignOutputVariable(pvApiCtx,3)=nbInputArgument(pvApiCtx)+3; + +} + +} + + + + + \ No newline at end of file diff --git a/sci_gateway/cpp/sci_iofunc.cpp b/sci_gateway/cpp/sci_iofunc.cpp new file mode 100644 index 0000000..f02b23a --- /dev/null +++ b/sci_gateway/cpp/sci_iofunc.cpp @@ -0,0 +1,450 @@ +#include "api_scilab.h" +#include "Scierror.h" +#include "sciprint.h" +#include "BOOL.h" +#include + +#define isDoubleIntegerType(x, y) ((double)((y)x)==x) + +int getInt32FromScilab(int argNum, int* dest) +{ + SciErr sciErr; + int iRet = 0; + int *varAddress = NULL; + double inputDouble = 0; + const char errMsg[] = "Wrong type for input argument #%d: An Integer is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varAddress) || isVarComplex(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + iRet = getScalarDouble(pvApiCtx, varAddress, &inputDouble); + if(iRet || !isDoubleIntegerType(inputDouble, int)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + *dest = (int)inputDouble; + return 0; +} + +int getInt32MatrixFromScilab(int argNum, int *rows, int *cols, int **dest) +{ + SciErr sciErr; + int* varAddress = NULL; + double* destDouble = NULL; + const char errMsg[] = "Wrong type for input argument #%d: A matrix of Integer is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varAddress) || isVarComplex(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + sciErr = getMatrixOfDouble(pvApiCtx, varAddress, rows, cols, &destDouble); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + int i; + *dest = (int*)malloc(sizeof(int) * (*rows) * (*cols)); + for(i = 0; i < (*rows) * (*cols); ++i) + { + if(!isDoubleIntegerType(destDouble[i], int)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + (*dest)[i] = (int)destDouble[i]; + } + return 0; +} + +int getFixedSizeInt32MatrixFromScilab(int argNum, int rows, int cols, int **dest) +{ + SciErr sciErr; + int* varAddress = NULL; + int inputMatrixRows = 0, inputMatrixCols = 0; + double* destDouble = NULL; + const char errMsg[] = "Wrong type for input argument #%d: A matrix of Integer of size %d by %d is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varAddress) || isVarComplex(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum, rows, cols); + return 1; + } + sciErr = getMatrixOfDouble(pvApiCtx, varAddress, &inputMatrixRows, &inputMatrixCols, &destDouble); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if(inputMatrixRows != rows || inputMatrixCols != cols) + { + Scierror(errNum, errMsg, argNum, rows, cols); + return 1; + } + int i; + *dest = (int*)malloc(sizeof(int) * rows * cols); + for(i = 0; i < rows * cols; ++i) + { + if(!isDoubleIntegerType(destDouble[i], int)) + { + Scierror(errNum, errMsg, argNum, rows, cols); + return 1; + } + (*dest)[i] = (int)destDouble[i]; + } + return 0; +} + +int returnInt32ToScilab(int itemPos, int retVal) +{ + int iRet; + iRet = createScalarDouble(pvApiCtx, nbInputArgument(pvApiCtx)+itemPos, (double)retVal); + if(iRet) + { + AssignOutputVariable(pvApiCtx, itemPos) = 0; + return 1; + } + AssignOutputVariable(pvApiCtx, itemPos) = nbInputArgument(pvApiCtx)+itemPos; + return 0; +} + +int returnInt32MatrixToScilab(int itemPos, int rows, int cols, int *dest) +{ + SciErr sciErr; + double* destDouble = NULL; + int i; + destDouble = (double*)malloc(sizeof(double) * rows * cols); + for(i = 0; i < rows * cols; ++i) + { + destDouble[i] = (double)dest[i]; + } + sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + itemPos, rows, cols, destDouble); + free(destDouble); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + AssignOutputVariable(pvApiCtx, itemPos) = nbInputArgument(pvApiCtx)+itemPos; + return 0; +} + +int getInt64FromScilab(int argNum, long long* dest) +{ + SciErr sciErr; + int iRet = 0; + int *varAddress = NULL; + double inputDouble = 0; + const char errMsg[] = "Wrong type for input argument #%d: An Integer is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varAddress) || isVarComplex(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + iRet = getScalarDouble(pvApiCtx, varAddress, &inputDouble); + if(iRet || !isDoubleIntegerType(inputDouble, long long)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + *dest = (long long)inputDouble; + return 0; +} + +int getInt64MatrixFromScilab(int argNum, int *rows, int *cols, long long **dest) +{ + SciErr sciErr; + int* varAddress = NULL; + double* destDouble = NULL; + const char errMsg[] = "Wrong type for input argument #%d: A matrix of Integer is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varAddress) || isVarComplex(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + sciErr = getMatrixOfDouble(pvApiCtx, varAddress, rows, cols, &destDouble); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + int i; + *dest = (long long*)malloc(sizeof(long long) * (*rows) * (*cols)); + for(i = 0; i < (*rows) * (*cols); ++i) + { + if(!isDoubleIntegerType(destDouble[i], long long)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + (*dest)[i] = (long long)destDouble[i]; + } + return 0; +} + +int getFixedSizeInt64MatrixFromScilab(int argNum, int rows, int cols, long long** dest) +{ + SciErr sciErr; + int* varAddress = NULL; + int inputMatrixRows = 0, inputMatrixCols = 0; + double* destDouble = NULL; + const char errMsg[] = "Wrong type for input argument #%d: A matrix of Integer of size %d by %d is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varAddress) || isVarComplex(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum, rows, cols); + return 1; + } + sciErr = getMatrixOfDouble(pvApiCtx, varAddress, &inputMatrixRows, &inputMatrixCols, &destDouble); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if(inputMatrixRows != rows || inputMatrixCols != cols) + { + Scierror(errNum, errMsg, argNum, rows, cols); + return 1; + } + int i; + *dest = (long long*)malloc(sizeof(long long) * rows * cols); + for(i = 0; i < rows * cols; ++i) + { + if(!isDoubleIntegerType(destDouble[i], long long)) + { + Scierror(errNum, errMsg, argNum, rows, cols); + return 1; + } + (*dest)[i] = (long long)destDouble[i]; + } + return 0; +} + +int returnInt64ToScilab(int itemPos, long long retVal) +{ + int iRet; + iRet = createScalarDouble(pvApiCtx, nbInputArgument(pvApiCtx)+itemPos, (double)retVal); + if(iRet) + { + AssignOutputVariable(pvApiCtx, itemPos) = 0; + return 1; + } + AssignOutputVariable(pvApiCtx, itemPos) = nbInputArgument(pvApiCtx)+itemPos; + return 0; +} + +int returnInt64MatrixToScilab(int itemPos, int rows, int cols, long long *dest) +{ + SciErr sciErr; + double* destDouble = NULL; + int i; + destDouble = (double*)malloc(sizeof(double) * rows * cols); + for(i = 0; i < rows * cols; ++i) + { + destDouble[i] = (double)dest[i]; + } + sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + itemPos, rows, cols, destDouble); + free(destDouble); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + AssignOutputVariable(pvApiCtx, itemPos) = nbInputArgument(pvApiCtx)+itemPos; + return 0; +} + +int returnBooleanMatrixToScilab(int itemPos, int rows, int cols, BOOL* dest) +{ + SciErr sciErr; + sciErr = createMatrixOfBoolean(pvApiCtx, nbInputArgument(pvApiCtx) + itemPos, rows, cols, (const int*)dest); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + AssignOutputVariable(pvApiCtx, itemPos) = nbInputArgument(pvApiCtx)+itemPos; + return 0; +} + +int getDoubleFromScilab(int argNum, double* dest) +{ + SciErr sciErr; + int iRet = 0; + int *varAddress = NULL; + const char errMsg[] = "Wrong type for input argument #%d: An Integer is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varAddress) || isVarComplex(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum); + return 1; + } + iRet = getScalarDouble(pvApiCtx, varAddress, dest); + return 0; +} + +int getFixedSizeDoubleMatrixFromScilab(int argNum, int rows, int cols, double** dest) +{ + SciErr sciErr; + int* varAddress = NULL; + int inputMatrixRows = 0, inputMatrixCols = 0; + const char errMsg[] = "Wrong type for input argument #%d: A matrix of Double of size %d by %d is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varAddress) || isVarComplex(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum, rows, cols); + return 1; + } + sciErr = getMatrixOfDouble(pvApiCtx, varAddress, &inputMatrixRows, &inputMatrixCols, dest); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if(inputMatrixRows != rows || inputMatrixCols != cols) + { + Scierror(errNum, errMsg, argNum, rows, cols); + return 1; + } + return 0; +} + +int getFixedSizeListOfFixedSizeDoubleMatrixFromScilab(int argNum, int rows, int cols, double*** dest, int len) +{ + SciErr sciErr; + int i; + int* varAddress = NULL; + int* varItemAddress = NULL; + int inputMatrixRows = 0, inputMatrixCols = 0, inputListLen = 0; + const char errMsg[] = "Wrong type for input argument #%d: A List of length %d containing matrix of Double of size %d by %d is expected.\n"; + const int errNum = 999; + sciErr = getVarAddressFromPosition(pvApiCtx, argNum, &varAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isListType(pvApiCtx, varAddress)) + { + Scierror(errNum, errMsg, argNum, len, rows, cols); + return 1; + } + sciErr = getListItemNumber(pvApiCtx, varAddress, &inputListLen); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (inputListLen != len) + { + Scierror(errNum, errMsg, argNum, len, rows, cols); + return 1; + } + *dest = (double**)malloc(sizeof(double**) * len); + for(i = 1; i <= len; ++i) + { + sciErr = getListItemAddress(pvApiCtx, varAddress, i, &varItemAddress); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if (!isDoubleType(pvApiCtx, varItemAddress) || isVarComplex(pvApiCtx, varItemAddress)) + { + Scierror(errNum, errMsg, argNum, len, rows, cols); + return 1; + } + sciErr = getMatrixOfDouble(pvApiCtx, varItemAddress, &inputMatrixRows, &inputMatrixCols, &((*dest)[i - 1])); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + if(inputMatrixRows != rows || inputMatrixCols != cols) + { + Scierror(errNum, errMsg, argNum, len, rows, cols); + return 1; + } + } + return 0; +} + +int returnDoubleToScilab(int itemPos, double retVal) +{ + int iRet; + iRet = createScalarDouble(pvApiCtx, nbInputArgument(pvApiCtx)+itemPos,retVal); + if(iRet) + { + AssignOutputVariable(pvApiCtx, itemPos) = 0; + return 1; + } + AssignOutputVariable(pvApiCtx, itemPos) = nbInputArgument(pvApiCtx)+itemPos; + return 0; +} + +int returnDoubleMatrixToScilab(int itemPos, int rows, int cols, double *dest) +{ + SciErr sciErr; + sciErr = createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + itemPos, rows, cols, dest); + if (sciErr.iErr) + { + printError(&sciErr, 0); + return 1; + } + AssignOutputVariable(pvApiCtx, itemPos) = nbInputArgument(pvApiCtx)+itemPos; + return 0; +} \ No newline at end of file diff --git a/sci_gateway/cpp/sci_iofunc.hpp b/sci_gateway/cpp/sci_iofunc.hpp new file mode 100644 index 0000000..49e5341 --- /dev/null +++ b/sci_gateway/cpp/sci_iofunc.hpp @@ -0,0 +1,24 @@ +#ifndef SCI_IOFUNCHEADER +#define SCI_IOFUNCHEADER + +int getInt32FromScilab(int argNum, int* dest); +int getInt32MatrixFromScilab(int argNum, int* rows, int* cols, long** dest); +int getFixedSizeInt32MatrixFromScilab(int argNum, int rows, int cols, long** dest); +int returnInt32ToScilab(int itemPos, int retVal); +int returnInt32MatrixToScilab(int itemPos, int rows, int cols, int* dest); + +int getInt64FromScilab(int argNum, long long* dest); +int getInt64MatrixFromScilab(int argNum, int* rows, int* cols, long long** dest); +int getFixedSizeInt64MatrixFromScilab(int argNum, int rows, int cols, long long** dest); +int returnInt64ToScilab(int itemPos, long long retVal); +int returnInt64MatrixToScilab(int itemPos, int rows, int cols, long long* dest); + +int returnBooleanMatrixToScilab(int itemPos, int rows, int cols, BOOL *dest); + +int getDoubleFromScilab(int argNum, double* dest); +int getFixedSizeDoubleMatrixFromScilab(int argNum, int rows, int cols, double** dest); +int getFixedSizeListOfFixedSizeDoubleMatrixFromScilab(int argNum, int rows, int cols, double*** dest, int len); +int returnDoubleToScilab(int itemPos, double retVal); +int returnDoubleMatrixToScilab(int itemPos, int rows, int cols, double* dest); + +#endif //SCI_IOFUNCHEADER diff --git a/sci_gateway/cpp/sci_jssp.cpp b/sci_gateway/cpp/sci_jssp.cpp new file mode 100755 index 0000000..30f760a --- /dev/null +++ b/sci_gateway/cpp/sci_jssp.cpp @@ -0,0 +1,754 @@ +#include "ortools/base/commandlineflags.h" +#include "ortools/base/commandlineflags.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/join.h" +#include "ortools/base/stringprintf.h" +#include "ortools/constraint_solver/constraint_solver.h" + +extern "C" { + +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace operations_research; + + + +/* +Naming suffixes(also, the respective order) for inputs :- + +1-> "machines" -> Number of machines in the problem, on which the various tasks in the given jobs are to be scheduled. +2-> "jobs" ->Number of jobs in the problem. Each job consists of one or more tasks that are to be scheduled on the various machines. The tasks have certain ordering constraints that they have to follow(if mode is '0', all tasks follow a sequetial order, ie. task 1 must occur before task '2' can start adn so on. For mode '1', however, order ain't linear by default. Each task is given 2 task indices, first corresponding to the task only after whose completion, the task in question can start and the second idnex corresponding to the task which cannot start before the task in question ends. +3-> "mode" -> 0/1 values; 0-> sequential mode- All taks must occur in sequence, i.e. task 1 must end before task 2 can start and so on for all tasks WITHIN THE JOB in question. 1-> parallel mode - Some tasks can occur parallelly, or completely independent of each other. 2 additional constrains need to be specified for each task in this mode viz.(say, the task in question is 'x') one being the task after whose end 'x' can start and the other being the task which can only occur after 'x' has ended.('-1' if the corresponding restriction is not imposed, i.e. if the task can start whenever, the we give '-1' for the first argument. +4-> "tasks" -> The matrix containing details of all the tasks. Say, the number of tasks is 'A'. For mode '0' 'tis a [Ax3] matrix and for mode '1' 'tis a [Ax5] matrix. The first 3 columns are common to both cases. The 5 columns are - 'job_index' , 'machine_index', 'task_duration', 'start_after','end_before', in that ORDER. The last 2 are only applicable for mode '1'. +5-> "time_limit" -> The user-specified upper bound in milliseconds for which the solver will run. Solution obviously ain't guaranteed. Default value is 10000(10s). This value has to be greater than 0. + +*/ + +/* +Naming suffixes(also, the respective order) for outputs :- +1->"makespan" -> The total time taken to complete all the tasks, in the optimal solution, should one exist +2->"schedule" -> A schedule matrix [Ax5] (A- number of tasks). The first 3 columns are the same as in 'tasks' matrix in the inputs. The last two indicate the start and end times for the respective tasks, in the optimal solution, should one be found. +3->"status" -> 0->Solved. 1-> timed out. 2->problem infeasible. + +*/ + + + +struct TTask { + TTask(int j, int m, int d) : job_id(j), machine_id(m), duration(d) {} + int job_id; + int machine_id; + int duration; + }; + + +int **tasks=NULL; + +int machines; +int jobs; +int mode; + + + + + + + +int sci_jssp(char *fname) +{ + + + int time_limit= 10000; //default - 10s + + SciErr scierror; + + int iType1=0, iType2=0, iType3=0, iType4=0, iType5=0; + + int *piAddressVar1=NULL, *piAddressVar2=NULL, *piAddressVar3=NULL, *piAddressVar4=NULL, *piAddressVar5=NULL; + + double *jssp_piVar1=NULL, *jssp_piVar2=NULL, *jssp_piVar3=NULL, *jssp_piVar4=NULL, *jssp_piVar5=NULL; + + int m1=0,n1=0,m2=0,n2=0,m3=0,n3=0,m4=0,n4=0,m5=0,n5=0; + + int status; //output #3 + + + int num_tasks; + + + CheckInputArgument(pvApiCtx,5,5); + CheckOutputArgument(pvApiCtx,3,3); + + + //GETTING THE ADDRESSES OF THE INPUT MATRICES + + + scierror = getVarAddressFromPosition(pvApiCtx,1,&piAddressVar1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror = getVarAddressFromPosition(pvApiCtx,2,&piAddressVar2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror = getVarAddressFromPosition(pvApiCtx,3,&piAddressVar3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror = getVarAddressFromPosition(pvApiCtx,4,&piAddressVar4); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror = getVarAddressFromPosition(pvApiCtx,5,&piAddressVar5); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + //RETRIEVING AND CHECKING THE TYPES OF THE INPUTS + + + + scierror=getVarType(pvApiCtx,piAddressVar1,&iType1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar2,&iType2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar3,&iType3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar4,&iType4); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar5,&iType5); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + + if(iType1!=sci_matrix || iType2!=sci_matrix || iType3!=sci_matrix || iType4!=sci_matrix || iType5!=sci_matrix) + { + + if(iType1!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #1. Matrix Expected! \n"); + + if(iType2!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #2. Matrix Expected! \n"); + + if(iType3!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #3. Matrix Expected! \n"); + + if(iType4!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #4. Matrix Expected! \n"); + + if(iType5!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #5. Matrix Expected! \n"); + + return 0; + + } + + + + + + //GETTING THE ACTUAL INPUT MATRICES + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar1,&m1,&n1,&jssp_piVar1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar2,&m2,&n2,&jssp_piVar2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar3,&m3,&n3,&jssp_piVar3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar4,&m4,&n4,&jssp_piVar4); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar5,&m5,&n5,&jssp_piVar5); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + //////--------------------------LOGIC-------------------------------///////// + + + + //assignments + + num_tasks = m4; + + machines = jssp_piVar1[0]; + jobs = jssp_piVar2[0]; + + mode = jssp_piVar3[0]; + + if( m5!=0) + time_limit = jssp_piVar5[0]; + + + + // constructing the 'tasks' matrix + + tasks=(int **)malloc(sizeof(int*)*num_tasks); + + if( mode==0) + { + + for(int i=0;i > alltasks(jobs); + + for(int i=0;i > jobs_to_tasks(jobs); + std::vector< std::vector > machines_to_tasks(machines); + + + + + //Creating the solver + + Solver solver("Job-Shop"); + + + + //Creating the interval variables + + int absindex=-1; + + for(int i=0;iname()); + std::string token; + + std::getline(ss, token, ';'); + + int ind = std::stoi(token); //This is the index corresponding to the task (row) in the 'tasks' matrix + + + if(tasks[ind][3] !=-1) + { + IntervalVar* const t2 = jobs_to_tasks[i][tasks[ind][3]]; + + Constraint* const precedence = solver.MakeIntervalVarRelation(t1, Solver::STARTS_AFTER_END, t2); + + solver.AddConstraint(precedence); + } + + if(tasks[ind][4]!=-1) + { + IntervalVar* const t2 = jobs_to_tasks[i][tasks[ind][4]]; + + Constraint* const precedence =solver.MakeIntervalVarRelation( t2, Solver::STARTS_AFTER_END, t1); + + solver.AddConstraint(precedence); + + } + + } + } + + } + + + + //Creating the disjunctive constrains(NO tasks on the same machine can overlap) + //These constraints are stored in Sequence Variables - a separate sequence variable to be defined for each sequence constraint. So, in our model, no. of sequence variables = No. of Machines. + + std::vector sequences; + + for(int i=0;iMakeSequenceVar()); + + } + + + //Creating a vector of End-time expressions(and casting them into Interval Variables) for the various jobs( only the logically last tasks in each job are needed to generate this expression(to minimize) as the various tasks within the same job are already constrained by precendence. + //This vector is then fed to the solver + + std::vector ends; + + for(int i=0; iEndExpr()->Var()); + + } + else //in this case, we cannot be sure which will be last job in the job. So, we simply add all the potential tasks(those with 'end_before' values equal to '-1') to the 'ends' vector. Later on, the solver will pick the one with the latest end-time among these to minimize the same, for that particular solution + { + + for(int j=0;jname()); + + std::string token; + + std::getline(ss,token, ';'); + + int ind = std::stoi(token); + + if( tasks[ind][4]==-1) + ends.push_back(task->EndExpr()->Var()); + + } + + + + } + + } + + + + //Setting the objective for the solver + + IntVar* const objective_var = solver.MakeMax(ends)->Var(); //Basically, we single out the Maximum of all the end times for the jobs, for each solution - this is actually equal to the makespan for that solution and then feed THIS as the objective variable to be minimized across all the solutions. + + OptimizeVar* const objective_monitor = solver.MakeMinimize(objective_var, 1); + + + //Creating the Decision builder. Two decision builders, one to rank the tasks and one to minimize the objective variable, will be created. Then, one Min decion builder will be made to "compose" the decision builder tree, over these 2 decision builders + + DecisionBuilder* const sequence_phase = solver.MakePhase(sequences, Solver::SEQUENCE_DEFAULT); + + DecisionBuilder* const obj_phase = solver.MakePhase(objective_var, Solver::CHOOSE_FIRST_UNBOUND, Solver::ASSIGN_MIN_VALUE); + + // The main decision builder (ranks all tasks, then fixes the objective_variable) + + DecisionBuilder* const main_phase = solver.Compose( sequence_phase, obj_phase); + + + + + //Setting the time limit + + SearchLimit* limit = nullptr; + + limit = solver.MakeTimeLimit(time_limit); + + + + + //Defining the solution collectors + + SolutionCollector* const collector = solver.MakeLastSolutionCollector(); + + collector->Add(sequences); + + collector->AddObjective(objective_var); + + + + //adding the start and end times for each task( machine-wise) to the solution collector + + for(int i=0; isize(); + + for(int j=0; jInterval(j); + + collector->Add(ss->StartExpr()->Var()); + collector->Add(ss->EndExpr()->Var()); + + } + + } + + + + //Solving and returning values + + + //the solve() function returns true if a solution is obtained. It returns false if our model times out before we obtain a soluion. + + if(solver.Solve(main_phase, objective_monitor, limit, collector)) + { + //solution found + + int status = 0 ; //output #3 + + int makespan = collector->objective_value(0); + + int **schedule = (int **) malloc(sizeof(int*)*num_tasks); + + sciprint("Optimal Solution Found!\n"); + + sciprint("Optimal Makespan : %d\n", makespan); + + + + for(int i=0; iname().c_str()); + sciprint(":\t"); + + std::vector sequence = collector ->ForwardSequence(0,seq); + + + for(int j=0; jInterval(sequence[j]); //the integral representation of 'temp->name()' will give us the index of the task in the respective job(ie. if a job has 4 tasks, indexing for it will go from 0 to 3) + + std::istringstream ss(temp->name()); + + std::string token; + + std::getline(ss,token,';'); + + + int ind = std::stoi(token); + + schedule[ind][3]= collector->Value(0, temp->StartExpr()->Var()); + schedule[ind][4]= collector->Value(0, temp->EndExpr()->Var()); + + + std::getline(ss,token,';'); + sciprint("Job- %d, ",std::stoi(token) +1); + + std::getline(ss,token,';'); + sciprint("Task- %d",std::stoi(token) +1); + + sciprint("[%d, %d]\t",schedule[ind][3],schedule[ind][4]); + + + } + + IntervalVar* const temp = seq->Interval(sequence.back()); + + + std::istringstream ss (temp->name()); + + std::string token; + + std::getline(ss,token, ';'); + + int ind = std::stoi(token); + + schedule[ind][3] = collector->Value(0, temp->StartExpr()->Var()); + schedule[ind][4] = collector->Value(0, temp->EndExpr()->Var()); + + std::getline(ss, token, ';'); + sciprint("Job- %d, ",std::stoi(token) +1); + + std::getline(ss, token, ';'); + sciprint("Task- %d",std::stoi(token) +1); + + + sciprint("[%d, %d]\n",schedule[ind][3],schedule[ind][4]); + + } + + + //converting 'schedule' to a linear array (column major) + + int *scischedule = (int *)malloc(sizeof(int)*num_tasks*5); + + for(int i=0;i + #include + #include + #include + #include + + int sci_linear_sum_assignment(const char* fname, unsigned long fname_len); +} + +#include "sci_iofunc.hpp" + +using namespace operations_research; + +int sci_linear_sum_assignment(const char* fname, unsigned long fname_len) +{ + CheckInputArgument(pvApiCtx, 3, 3); + CheckOutputArgument(pvApiCtx, 2, 3); + + // Input Args + int kNumLeftNodes = 0; + int kNumRightNodes = 0; + long long* kCost = NULL; + + // Output Args + long long OptimalCost = 0; + BOOL* AssignmentMatrix = NULL; + int Status = 0; + + // Input from Scilab + if(getInt32FromScilab(1, &kNumLeftNodes)) + { + return 1; + } + if(getInt32FromScilab(2, &kNumRightNodes)) + { + return 1; + } + if(getFixedSizeInt64MatrixFromScilab(3, kNumLeftNodes, kNumRightNodes, &kCost)) + { + return 1; + } + + // Solve + ForwardStarGraph graph(kNumLeftNodes + kNumRightNodes, kNumLeftNodes * kNumRightNodes); + LinearSumAssignment obj(graph, kNumLeftNodes); + for (NodeIndex leftnode = 0; leftnode < kNumLeftNodes; ++leftnode) + { + for (NodeIndex rightnode = 0; rightnode < kNumRightNodes; ++rightnode) + { + ArcIndex arc = graph.AddArc(leftnode, kNumLeftNodes + rightnode); + // sciprint("Cost: %ld\n", kCost[rightnode * kNumLeftNodes + leftnode]); + // obj.SetArcCost(arc, kCost[leftnode * kNumRightNodes + rightnode]); + obj.SetArcCost(arc, kCost[rightnode * kNumLeftNodes + leftnode]); + } + } + Status = (int)(obj.ComputeAssignment()); + + // Format Solution + OptimalCost = (long long)obj.GetCost(); + AssignmentMatrix = (BOOL*)malloc(sizeof(BOOL) * kNumLeftNodes * kNumRightNodes); + for (int leftnode = 0; leftnode < kNumLeftNodes; ++leftnode) + { + for (int rightnode = 0; rightnode < kNumRightNodes; ++rightnode) + { + // AssignmentMatrix[leftnode * kNumRightNodes + rightnode] + AssignmentMatrix[rightnode * kNumLeftNodes + leftnode] = \ + (kNumLeftNodes + rightnode == (int)(obj.GetMate(leftnode))) ? TRUE : FALSE; + } + } + + // Output + if (returnInt64ToScilab(1, OptimalCost)) + { + return 1; + } + if (returnBooleanMatrixToScilab(2, kNumLeftNodes, kNumRightNodes, AssignmentMatrix)) + { + return 1; + } + if (returnInt32ToScilab(3, Status)) + { + return 1; + } + + // Cleanup + free(kCost); + free(AssignmentMatrix); + + return 0; +} \ No newline at end of file diff --git a/sci_gateway/cpp/sci_max_flow.cpp b/sci_gateway/cpp/sci_max_flow.cpp new file mode 100755 index 0000000..bc324f6 --- /dev/null +++ b/sci_gateway/cpp/sci_max_flow.cpp @@ -0,0 +1,345 @@ +#include "ortools/graph/max_flow.h" +extern "C" { +#include +#include +#include +#include +#include + +using namespace operations_research; + +int sci_max_flow(char *fname) //error check to check if values exceed 32 bit ints, before passing ???? +{ + SciErr scierror; + + int iType1=0; + int iType2=0; + int iType3=0; + int iType4=0; + + int m1=0,n1=0,m2=0,n2=0,m3=0,n3=0,m4=0,n4=0; + + double *pdVarOne=NULL,*pdVarTwo=NULL,*pdVarThree=NULL,*pdVarFour=NULL; + int *piAddressVarOne=NULL,*piAddressVarTwo=NULL,*piAddressVarThree=NULL,*piAddressVarFour=NULL; + + + int *pdblReal1; //actually FlowQuantity(enum value for int64); int used owing to no 64-bit support in scilab yet + int *pdblReal2; + + //CheckRhs(4,4); + //CheckLhs(0,2); + + CheckInputArgument(pvApiCtx,4,4); + CheckOutputArgument(pvApiCtx,3,3); + + //Getting Addresses of the input matrices + + scierror=getVarAddressFromPosition(pvApiCtx,1,&piAddressVarOne); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,2,&piAddressVarTwo); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,3,&piAddressVarThree); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,4,&piAddressVarFour); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + //Getting the input types and checking if they are matrices + + scierror=getVarType(pvApiCtx,piAddressVarOne,&iType1); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + + } + + if(iType1!=sci_matrix) + { + + Scierror(999,"%s : Wrong input argument type for argument #%d. Try Again!\n ",fname,1); + + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVarTwo,&iType2); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + if(iType2!=sci_matrix) + { + Scierror(999,"%s : Wrong input argument type for argument #%d. Try Again!\n",fname,2); + + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVarThree,&iType3); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + + } + + if(iType1!=sci_matrix) + { + + Scierror(999,"%s : Wrong input argument type for argument #%d. Try Again!\n ",fname,3); + + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVarFour,&iType4); + + if(scierror.iErr) + { + Scierror(999,"%s : Wrong input argument type for argument #%d. Try Again!\n",fname,4); + return 0; + } + + + + //Getting the actual matrices + + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVarOne,&m1,&n1,&pdVarOne); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVarTwo,&m2,&n2,&pdVarTwo); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVarThree,&m3,&n3,&pdVarThree); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVarFour,&m4,&n4,&pdVarFour); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + if((m1!=1)||(m2!=1)||(m3!=1)||(n1!=n2)||(n1!=n3)) //The three matrices need to be vectors(only one row) and must have the same size + { + Scierror(787,"Invalid Input(s)\n"); + return 0; + } + + + + + //pdVarOne ->array of start/tail nodes + //pdVarTwo ->array of end/head nodes + //pdVarThree ->array of capacities(corresponding to the arc index + //pdVarFour ->array(1x2) containing the indices of the source and destination nodes + + + + + SimpleMaxFlow smf; + SimpleMaxFlow::Status stat; + ArcIndex arcIndex=0; + + for(int i=0;i=smf.NumNodes()) + { + Scierror(788,"Invalid Source Index!\n"); + return 0; + } + + if(pdVarFour[1]>=smf.NumNodes()) + { + Scierror(788,"Invalid Destination Index!\n"); + return 0; + }*/ + + + int eflag=0,sflag=0; + + for(int i=0;(istores the max flow(1x1 matrix) + //pdblReal2 ->stores the flow for each arc in the optimal solution + + + //scierror=allocMatrixOfDouble(pvApiCtx,nbInputArgument(pvApiCtx)+1,1,1,&pdblReal1); + //scierror=allocMatrixOfDouble(pvApiCtx,nbInputArgument(pvApiCtx)+2,1,n1,&pdblReal2); + + pdblReal1=(int *)malloc(sizeof(int)); + + *pdblReal1=smf.OptimalFlow(); + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+1,1,1,pdblReal1); + + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + pdblReal2=(int *)malloc(sizeof(int)*smf.NumArcs()); + + for(int i=0;i%d\t%d\t%d\n",smf.Tail(i),smf.Head(i),smf.Flow(i),smf.Capacity(i)); //sciprint("%d->%d\t%lld\t%lld\n",smf.Tail(i),smf.Head(i),smf.Flow(i),smf.Capacity(i)); + + + //LhsVar(1)=5; + //LhsVar(2)=6; + + AssignOutputVariable(pvApiCtx,1)=nbInputArgument(pvApiCtx)+1; + AssignOutputVariable(pvApiCtx,2)=nbInputArgument(pvApiCtx)+2; + AssignOutputVariable(pvApiCtx,3)=nbInputArgument(pvApiCtx)+3; + + + //ReturnArguments(pvApiCtx); + + + + return 0; + + + +} +} + +/*using namespace operations_research; +int main() +{ + int start_nodes[] = {0, 0, 0, 1, 1, 2, 2, 3, 3}; + int end_nodes[] = {1, 2, 3, 2, 4, 3, 4, 2, 4}; + int capacities []= {20, 30, 10, 40, 30, 10, 20, 5, 20}; + + SimpleMaxFlow smf; + SimpleMaxFlow::Status stat; + ArcIndex arcIndex=0; + + int n=9; + + for(int i=0;i%d\t%d\t%d\n",smf.Tail(i),smf.Head(i),smf.Flow(i),smf.Capacity(i)); + + return 0; + + +}*/ + + + \ No newline at end of file diff --git a/sci_gateway/cpp/sci_min_cost_flow.cpp b/sci_gateway/cpp/sci_min_cost_flow.cpp new file mode 100644 index 0000000..7981869 --- /dev/null +++ b/sci_gateway/cpp/sci_min_cost_flow.cpp @@ -0,0 +1,148 @@ +/* + Sample: + + Source: Ex.2: http://www.yourarticlelibrary.com/ergonomics/operation-research/checking-for-optimality-transportation-problem/34743/ + + // Doesn't Work (Unbalanced) + a = 4; + b = 4; + c = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; + d = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; + e = [50, 70, 30, 50]; + f = [25, 35, 105, 20]; + [x, y] = solve_mincostflow(a, b, c, d, e, f); + + // Works (Balanced) + a = 4; + b = 5; + c = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; + d = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; + e = [50, 70, 30, 50]; + f = [25, 35, 105, 20, 15]; + [x, y] = solve_mincostflow(a, b, c, d, e, f); +*/ +#include "ortools/graph/min_cost_flow.h" + +extern "C"{ + #include + #include + #include + #include + #include + + int sci_min_cost_flow(const char* fname, unsigned long fname_len); +} + +#include "sci_iofunc.hpp" + +using namespace operations_research; + +int sci_min_cost_flow(const char* fname, unsigned long fname_len) +{ + CheckInputArgument(pvApiCtx, 6, 6); + CheckOutputArgument(pvApiCtx, 2, 3); + + // Input Args + int kNumSources = 0; + int kNumTargets = 0; + long long* kCost = NULL; + long long* kCapacity = NULL; + long long* kSupply = NULL; + long long* kDemand = NULL; + + // Output Args + long long OptimalCost = 0; + long long* FlowMatrix = NULL; + int Status = 0; + + // Input from Scilab + if(getInt32FromScilab(1, &kNumSources)) + { + return 1; + } + if(getInt32FromScilab(2, &kNumTargets)) + { + return 1; + } + if(getFixedSizeInt64MatrixFromScilab(3, kNumSources, kNumTargets, &kCost)) + { + return 1; + } + if(getFixedSizeInt64MatrixFromScilab(4, kNumSources, kNumTargets, &kCapacity)) + { + return 1; + } + if(getFixedSizeInt64MatrixFromScilab(5, 1, kNumSources, &kSupply)) + { + return 1; + } + if(getFixedSizeInt64MatrixFromScilab(6, 1, kNumTargets, &kDemand)) + { + return 1; + } + + // Solve + StarGraph graph(kNumSources + kNumTargets, kNumSources * kNumTargets); + MinCostFlow obj(&graph); + for (NodeIndex source = 0; source < kNumSources; ++source) + { + for (NodeIndex target = 0; target < kNumTargets; ++target) + { + ArcIndex arc = graph.AddArc(source, kNumSources + target); + // sciprint("Cost: %ld\n", kCost[target * kNumSources + source]); + // obj.SetArcUnitCost(arc, *kCost[source * kNumTargets + target]); + obj.SetArcUnitCost(arc, (CostValue)kCost[target * kNumSources + source]); + // sciprint("Capacity: %ld\n", kCapacity[target * kNumSources + source]); + // obj.SetArcCapacity(arc, *kCapacity[source * kNumTargets + target]); + obj.SetArcCapacity(arc, (FlowQuantity)kCapacity[target * kNumSources + source]); + } + } + for (NodeIndex source = 0; source < kNumSources; ++source) + { + // sciprint("Supply: %ld\n", kSupply[source]); + obj.SetNodeSupply(source, (FlowQuantity)(1 * kSupply[source])); + } + for (NodeIndex target = 0; target < kNumTargets; ++target) + { + // sciprint("Demand: %ld\n", kDemand[target]); + obj.SetNodeSupply(kNumSources + target, (FlowQuantity)(-1 * kDemand[target])); + } + obj.Solve(); + + // Format Solution + OptimalCost = (long long)obj.GetOptimalCost(); + FlowMatrix = (long long*)malloc(sizeof(long long) * kNumSources * kNumTargets); + for (int source = 0; source < kNumSources; ++source) + { + for (int target = 0; target < kNumTargets; ++target) + { + int arc = source * kNumTargets + target; + // FlowMatrix[source * kNumTargets + target] = (long long)(obj.Flow(arc)); + FlowMatrix[target * kNumSources + source] = (long long)(obj.Flow(arc)); + } + } + Status = (int)(obj.status()); + + // Output + if (returnInt64ToScilab(1, OptimalCost)) + { + return 1; + } + if (returnInt64MatrixToScilab(2, kNumSources, kNumTargets, FlowMatrix)) + { + return 1; + } + if (returnInt32ToScilab(3, Status)) + { + return 1; + } + + // Cleanup + free(kCost); + free(kCapacity); + free(kSupply); + free(kDemand); + free(FlowMatrix); + + return 0; +} \ No newline at end of file diff --git a/sci_gateway/cpp/sci_qcqpglob.cpp b/sci_gateway/cpp/sci_qcqpglob.cpp new file mode 100644 index 0000000..1e1a80e --- /dev/null +++ b/sci_gateway/cpp/sci_qcqpglob.cpp @@ -0,0 +1,514 @@ +// Glob QCQP Minotaur Scilab Interface Gateway +// +// qcqpglob(n, m, h_obj, f_obj, c_obj, h_con, f_con, lb_con, ub_con, lb_var, ub_bar, maxcputime); +// +// n -> no. of variables +// m -> no. of constraints +// h_obj -> n x n matrix +// f_obj -> n x 1 matrix or n-column-vector +// c_obj -> 1 x 1 constant +// h_con -> m sized list of n x n matrices or m x n x n 3D-matrix +// f_con -> m sized list of n-column-vector or m x n matrix +// lb_con -> m x 1 matrix or m-column-vector +// ub_con -> m x 1 matrix or m-column-vector +// lb_var -> n x 1 matrix or n-column-vector +// ub_var -> n x 1 matrix or n-column-vector +// maxcputime -> timeout in seconds for solving +// +// +#include + +#include "MinotaurConfig.h" +#include "BranchAndBound.h" +#include "Engine.h" +#include "EngineFactory.h" +#include "Environment.h" +#include "LexicoBrancher.h" +#include "LinearHandler.h" +#include "Logger.h" +#include "LPEngine.h" +#include "MaxVioBrancher.h" +#include "NodeIncRelaxer.h" +#include "NLPEngine.h" +#include "NLPMultiStart.h" +#include "NlPresHandler.h" +#include "Objective.h" +#include "Option.h" +#include "PCBProcessor.h" +#include "Presolver.h" +#include "ProblemSize.h" +#include "Problem.h" +#include "Relaxation.h" +#include "ReliabilityBrancher.h" +#include "SimpleTransformer.h" +#include "Solution.h" +#include "Timer.h" +#include "Transformer.h" +#include "TreeManager.h" +#include "CGraph.h" +#include "CNode.h" +#include "Variable.h" +#include "Function.h" +#include "LinearFunction.h" +#include "QuadraticFunction.h" + +extern "C"{ + #include + #include + #include + #include + #include + + int sci_qcqpglob(const char* fname, unsigned long fname_len); // Main +} + +#include "sci_iofunc.hpp" +#include "misc.hpp" + +using namespace Minotaur; + +// Declarations +int Transform(EnvPtr env, ProblemPtr p_orig, ProblemPtr &p_new, HandlerVector &handlers); +PresolverPtr CreatePresolver(ProblemPtr p, EnvPtr env, HandlerVector &handlers, size_t numVars = 0); +BranchAndBound* CreateBranchAndBound(EnvPtr env, ProblemPtr p, EnginePtr e, HandlerVector &handlers); +double* GetSolution(PresolverPtr pres, SolutionPtr sol, int n); +void GLOB_addObjective(ProblemPtr& p, double* H, double* f, double c); +void GLOB_addConstraint(ProblemPtr& p, double* H, double* f, double lb, double ub); + +// Definitions +int Transform(EnvPtr env, ProblemPtr p_orig, ProblemPtr &p_new, HandlerVector &handlers) +{ + // Init Vars + SimpTranPtr trans = SimpTranPtr(); // NULL + int status = 0; + + // Process + handlers.clear(); + trans = (SimpTranPtr) new SimpleTransformer(env, p_orig); + trans->reformulate(p_new, handlers, status); + + return status; +} + +PresolverPtr CreatePresolver(ProblemPtr p, EnvPtr env, HandlerVector &handlers, size_t numVars = 0) +{ + // Init Vars + PresolverPtr pres = PresolverPtr(); // NULL + LinearHandlerPtr lhandler = LinearHandlerPtr(); // NULL + NlPresHandlerPtr nlhand = NlPresHandlerPtr(); // NULL + + // Process + p->calculateSize(); + if (env->getOptions()->findBool("presolve")->getValue() == true) + { + if (env->getOptions()->findBool("lin_presolve")->getValue() == true) + { + lhandler = (LinearHandlerPtr) new LinearHandler(env, p); + handlers.push_back(lhandler); + + if (p->isQP() || + p->isQuadratic() || + p->isLinear() || + env->getOptions()->findBool("use_native_cgraph")->getValue() == true) + { + lhandler->setPreOptPurgeVars(true); + lhandler->setPreOptPurgeCons(true); + lhandler->setPreOptCoeffImp(true); + } + else + { + lhandler->setPreOptPurgeVars(false); + lhandler->setPreOptPurgeCons(false); + lhandler->setPreOptCoeffImp(false); + } + + if (numVars > 0) + { + lhandler->setPreOptDualFix(false); + } + else + { + lhandler->setPreOptDualFix(true); + } + } + + if (env->getOptions()->findBool("nl_presolve")->getValue() == true && + !p->isLinear() && + env->getOptions()->findBool("use_native_cgraph")->getValue() == true) + { + nlhand = (NlPresHandlerPtr) new NlPresHandler(env, p); + handlers.push_back(nlhand); + } + } + pres = (PresolverPtr) new Presolver(p, env, handlers); + + return pres; +} + +BranchAndBound* CreateBranchAndBound(EnvPtr env, ProblemPtr p, EnginePtr e, HandlerVector &handlers) +{ + // Init Vars + BranchAndBound* bab = new BranchAndBound(env, p); + PCBProcessorPtr nproc = PCBProcessorPtr(); // NULL + NodeIncRelaxerPtr nr = NodeIncRelaxerPtr(); // NULL + RelaxationPtr rel = RelaxationPtr(); // NULL + BrancherPtr br = BrancherPtr(); // NULL + + if (env->getOptions()->findString("brancher")->getValue() == "rel") + { + UInt t; + ReliabilityBrancherPtr rel_br = (ReliabilityBrancherPtr) new ReliabilityBrancher(env, handlers); + rel_br->setEngine(e); + t = (p->getSize()->ints + p->getSize()->bins)/10; + t = std::max(t, (UInt) 2); + t = std::min(t, (UInt) 4); + rel_br->setThresh(t); + t = (UInt) p->getSize()->ints + p->getSize()->bins/20+2; + t = std::min(t, (UInt) 10); + rel_br->setMaxDepth(t); + br = rel_br; + } + else if (env->getOptions()->findString("brancher")->getValue() == "maxvio") + { + MaxVioBrancherPtr mbr = (MaxVioBrancherPtr) new MaxVioBrancher(env, handlers); + br = mbr; + } + else if (env->getOptions()->findString("brancher")->getValue() == "lex") + { + LexicoBrancherPtr lbr = (LexicoBrancherPtr) new LexicoBrancher(env, handlers); + br = lbr; + } + + nproc = (PCBProcessorPtr) new PCBProcessor(env, e, handlers); + nproc->setBrancher(br); + bab->setNodeProcessor(nproc); + + nr = (NodeIncRelaxerPtr) new NodeIncRelaxer(env, handlers); + nr->setProblem(p); + nr->setRelaxation(rel); + nr->setEngine(e); + bab->setNodeRelaxer(nr); + bab->shouldCreateRoot(true); + + if (env->getOptions()->findBool("msheur")->getValue() == true && + (p->getSize()->bins == 0 && p->getSize()->ints == 0)) + { + EngineFactory* efac = new EngineFactory(env); + NLPEnginePtr nlp_e = efac->getNLPEngine(); + p->setNativeDer(); + NLPMSPtr ms_heur = (NLPMSPtr) new NLPMultiStart(env, p, nlp_e); + bab->addPreRootHeur(ms_heur); + delete efac; + } + + return bab; +} + +double* GetSolution(PresolverPtr pres, SolutionPtr sol, int n) +{ + const double* exSoln = NULL; + double* ret = NULL; + UInt i; + + if (sol != SolutionPtr()) + { + sol = pres->getPostSol(sol); + if (sol != SolutionPtr()) + { + exSoln = sol->getPrimal(); + ret = (double*)malloc(sizeof(double) * n); + for(i = 0; i < n; ++i) + ret[i] = exSoln[i]; + + return ret; + } + } + return NULL; +} + +void GLOB_addObjective(ProblemPtr& p, double* H, double* f, double c) +{ + VariableConstIterator vbeg = p->varsBegin(); + VariableConstIterator vend = p->varsEnd(); + CGraphPtr cg = CGraphPtr(); // NULL + FunctionPtr fun = FunctionPtr(); // NULL + + QuadraticFunctionPtr qf = (QuadraticFunctionPtr) new QuadraticFunction(H, vbeg, vend); + LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction(f, vbeg, vend, 1e-9); + + if(qf->getNumTerms() + lf->getNumTerms() == 0) + { + // Not an Objective! + return; + } + + if(qf->getNumTerms() == 0) + { + fun = (FunctionPtr) new Function(lf); + } + else + { + cg = (CGraphPtr) new CGraph(qf, lf); + cg->finalize(); + fun = (FunctionPtr) new Function(cg); + } + + p->newObjective(fun, c, Minimize); +} + +void GLOB_addConstraint(ProblemPtr& p, double* H, double* f, double lb, double ub) +{ + VariableConstIterator vbeg = p->varsBegin(); + VariableConstIterator vend = p->varsEnd(); + CGraphPtr cg = CGraphPtr(); // NULL + FunctionPtr fun = FunctionPtr(); // NULL + + QuadraticFunctionPtr qf = (QuadraticFunctionPtr) new QuadraticFunction(H, vbeg, vend); + LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction(f, vbeg, vend, 1e-9); + + if(qf->getNumTerms() + lf->getNumTerms() == 0) + { + // Not a Constraint! + return; + } + + if(qf->getNumTerms() == 0) + { + fun = (FunctionPtr) new Function(lf); + } + else + { + cg = (CGraphPtr) new CGraph(qf, lf); + cg->finalize(); + fun = (FunctionPtr) new Function(cg); + } + + p->newConstraint(fun, lb, ub); +} + +int sci_qcqpglob(const char* fname, unsigned long fname_len) +{ + ////////////////// + // Vars Declare // + ////////////////// + + // General Vars + UInt i, j; + + // Solver Vars + EnvPtr env = EnvPtr(); // NULL + HandlerVector handlers; + int err = 0; + ProblemPtr p_orig = ProblemPtr(); // NULL + ProblemPtr p_new = ProblemPtr(); // NULL + EngineFactory* efac = NULL; + LPEnginePtr lp_e = LPEnginePtr(); // NULL + BranchAndBound* bab = NULL; + SimpTranPtr trans = SimpTranPtr(); // NULL + PresolverPtr pres_orig = PresolverPtr(); // NULL + PresolverPtr pres_new = PresolverPtr(); // NULL + VarVector orig_v; + + // Input Vars + int n = 0; + int m = 0; + double* h_obj = NULL; + double* f_obj = NULL; + double c_obj = 0; + double** h_con = NULL; + double** f_con = NULL; + double* lb_con = NULL; + double* ub_con = NULL; + double* lb_var = NULL; + double* ub_var = NULL; + double maxcputime = 0; + + // Output Vars + double* kSolnVector = NULL; + double kSoln = 0; + int status = 0; + + // Extra Vars + double* h_obj_rowm = NULL; // Row Major + double** h_con_rowm = NULL; // Row Major + + ////////////////////// + // Scilab API Begin // + ////////////////////// + + // Check Arguments + CheckInputArgument(pvApiCtx, 12, 12); + CheckOutputArgument(pvApiCtx, 3, 3); + + // Input + if(getInt32FromScilab(1, &n)) + { + return 1; + } + if(getInt32FromScilab(2, &m)) + { + return 1; + } + if(getFixedSizeDoubleMatrixFromScilab(3, n, n, &h_obj)) + { + return 1; + } + if(getFixedSizeDoubleMatrixFromScilab(4, 1, n, &f_obj)) + { + return 1; + } + if(getDoubleFromScilab(5, &c_obj)) + { + return 1; + } + if(getFixedSizeListOfFixedSizeDoubleMatrixFromScilab(6, n, n, &h_con, m)) + { + return 1; + } + if(getFixedSizeListOfFixedSizeDoubleMatrixFromScilab(7, 1, n, &f_con, m)) + { + return 1; + } + if(getFixedSizeDoubleMatrixFromScilab(8, m ? 1 : 0, m, &lb_con)) + { + return 1; + } + if(getFixedSizeDoubleMatrixFromScilab(9, m ? 1 : 0, m, &ub_con)) + { + return 1; + } + if(getFixedSizeDoubleMatrixFromScilab(10, 1, n, &lb_var)) + { + return 1; + } + if(getFixedSizeDoubleMatrixFromScilab(11, 1, n, &ub_var)) + { + return 1; + } + if(getDoubleFromScilab(12, &maxcputime)) + { + return 1; + } + + // Convert Column Major to Row Major + h_obj_rowm = ArrConvertMajor(h_obj, n, n); + h_con_rowm = (double**)malloc(sizeof(double**) * m); + for(i = 0; i < m; ++i) + h_con_rowm[i] = ArrConvertMajor(h_con[i], n, n); + + //////////////////////////////// + // Setup Minotaur Environment // + //////////////////////////////// + + // Initialize Environment + env = (EnvPtr) new Environment(); + + // Set Fixed Options + env->getOptions()->findBool("use_native_cgraph")->setValue(true); + env->getOptions()->findBool("presolve")->setValue(true); + env->getOptions()->findBool("nl_presolve")->setValue(true); + env->getOptions()->findBool("lin_presolve")->setValue(true); + env->getOptions()->findString("brancher")->setValue("maxvio"); + env->getOptions()->findBool("msheur")->setValue(true); + env->getOptions()->findInt("pres_freq")->setValue(1); + env->getOptions()->findString("lp_engine")->setValue("OsiClp"); + env->getOptions()->findString("nlp_engine")->setValue("IPOPT"); + + // Set User-defined Options + env->getOptions()->findDouble("bnb_time_limit")->setValue(maxcputime); + + ////////////////// + // Read Problem // + ////////////////// + + // Declare Problem Pointer + p_orig = (ProblemPtr) new Problem(); + + // Add Variables + for(i = 0; i < n; ++i) + { + // Library Limits. Need Warning? + orig_v.push_back(p_orig->newVariable(std::max(lb_var[i], -1e6), std::min(ub_var[i], 1e6), Integer)); + } + + // Add Objective + GLOB_addObjective(p_orig, h_obj_rowm, f_obj, c_obj); + + // Add Constraints + for(i = 0; i < m; ++i) + { + GLOB_addConstraint(p_orig, h_con_rowm[i], f_con[i], lb_con[i], ub_con[i]); + } + + // Set Native Derivatives + p_orig->setNativeDer(); + + /////////// + // Solve // + /////////// + + // Start timer + env->startTimer(err); assert(err==0); + + // Presolve Original Problem + handlers.clear(); + pres_orig = CreatePresolver(p_orig, env, handlers, orig_v.size()); + if (env->getOptions()->findBool("presolve")->getValue() == true) + { + pres_orig->solve(); + } + handlers.clear(); + + // Transform (KKT & Reformulate) + err = Transform(env, p_orig, p_new, handlers); assert(0==err); + + // Presolve Transformed Problem + pres_new = (PresolverPtr) new Presolver(p_new, env, handlers); + pres_new->solve(); + + // Get LP Engine for Solving + efac = new EngineFactory(env); + lp_e = efac->getLPEngine(); + + // Create Branch and Bound Object + bab = CreateBranchAndBound(env, p_new, lp_e, handlers); + + // Start Solving + bab->solve(); + + // Get Solution + kSolnVector = GetSolution(pres_orig, bab->getSolution(), n); + kSoln = bab->getUb(); + kSoln += c_obj; // Problem with Library? + status = bab->getStatus(); + + // Clean + delete bab; + delete efac; + + //////////////////// + // Scilab API End // + //////////////////// + + // Output + if (returnDoubleToScilab(1, kSoln)) + { + return 1; + } + if (returnDoubleMatrixToScilab(2, 1, n, kSolnVector)) + { + return 1; + } + if (returnInt32ToScilab(3, status)) + { + return 1; + } + + // Cleanup + free(h_obj_rowm); + for(i = 0; i < m; ++i) + free(h_con_rowm[i]); + free(h_con_rowm); + + return 0; +} \ No newline at end of file diff --git a/sci_gateway/cpp/sci_tsp.cpp b/sci_gateway/cpp/sci_tsp.cpp new file mode 100644 index 0000000..a4774f2 --- /dev/null +++ b/sci_gateway/cpp/sci_tsp.cpp @@ -0,0 +1,367 @@ +#include "ortools/base/callback.h" +#include "ortools/base/commandlineflags.h" +#include "ortools/base/commandlineflags.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/join.h" +#include "ortools/base/join.h" +#include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_enums.pb.h" +#include "ortools/constraint_solver/routing_flags.h" + + + +extern "C"{ +#include +#include +#include +#include +#include +#include + + +using namespace operations_research; + + + + + +/* +Naming suffixes(also, the respective order) for inputs :- +1-> The adjacency matrix representing the graph(The cell values are the costs associated with the respective edge defined by (row index)->(column index) ) cost values>=0. Negative cost values simply mean 'no edge' i.e. no edge connects node 'i' to node 'j'(u-> row index; j-> column index) +2-> The index of the start node i.e the node from which the travelling salesman starts his journey(and also where the journey is to end) +3-> The time_limit for the solver(in milliseconds). +*/ + + +/* +Naming suffixes(also, the respective order) for outputs :- +1-> The total path cost(for the optimal route) (integral) +2-> The actual optimal path( as a [1xn] integral matrix(vector) where n is the number of tsp_nodes+1(as the starting node is included twice, once at the start and once at the end. +3-> The OR-Tools solution status (enum defined in 'routing.h') +*/ + + +double *tsp_piVar1=NULL,*tsp_piVar2=NULL,*tsp_piVar3=NULL; +int tsp_nodes; // stores the number of tsp_nodes in the specified graph + + + + +long long matrixIndex(RoutingModel::NodeIndex from, RoutingModel::NodeIndex to) +{ + return (to*tsp_nodes+from).value(); // As scilab stores matrices in Column-Major format +} + + +long long distance(RoutingModel::NodeIndex from, RoutingModel::NodeIndex to) +{ + + return tsp_piVar1[matrixIndex(from,to)]; + + +} + + + + +int sci_tsp(char *fname) +{ + + SciErr scierror; + + int iType1=0,iType2=0,iType3=0; + + int *piAddressVar1=NULL,*piAddressVar2=NULL,*piAddressVar3=NULL; + int m1=0,n1=0,m2=0,n2=0,m3=0,n3=0; + + int *piReal1=NULL,*piReal2=NULL,*piReal3=NULL; + int status; + + int time_limit; + + + CheckInputArgument(pvApiCtx,3,3); + CheckOutputArgument(pvApiCtx,3,3); + + + //GETTING THE ADDRESSES OF THE INPUT MATRICES + + + //first input matrix(adjacency matrix) + + scierror=getVarAddressFromPosition(pvApiCtx,1,&piAddressVar1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + //second input matrix([1x1] containing the index of the start node("depot")) + scierror=getVarAddressFromPosition(pvApiCtx,2,&piAddressVar2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,3,&piAddressVar3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + //RETRIEVING AND CHECKING THE TYPES OF THE INPUTS + + scierror=getVarType(pvApiCtx,piAddressVar1,&iType1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + scierror=getVarType(pvApiCtx,piAddressVar2,&iType2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar3,&iType3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + if(iType1!=sci_matrix||iType2!=sci_matrix||iType3!=sci_matrix) + { + if(iType1!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #1. Matrix Expected! \n"); + + if(iType2!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #2. Matric Expected! \n"); + + if(iType3!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #3. Matric Expected! \n"); + + return 0; + } + + + + //GETTING THE ACTUAL INPUT MATRICES + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar1,&m1,&n1,&tsp_piVar1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar2,&m2,&n2,&tsp_piVar2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar3,&m3,&n3,&tsp_piVar3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + //the adjacency matrix has to be a square matrix. Checking for the same + + if(m1!=n1) + { + Scierror(787,"Invalid/Erroneous Adjacency matrix size. Adjacency matrices need to be square matrices.\n"); + return 0; + } + + + + //Checking if the second input argument is a singular value(1x1 matrix) + + if(m2!=1||n2!=1) + { + Scierror(789,"Wrong input #2! Required- A singlular value for the index of the start-node(the node where the salesman begins his journey) \n"); + return 0; + + } + + + + //Checking if the 'start-node' index value is valid(existent in the adjacency matrix) + + if(tsp_piVar2[0]>=m1) + { + Scierror(791,"Invalid input #2! The index value for the 'start-node' doesn't exist in the given graph(The tsp_nodes are indexed from '0' to 'n-1'(n->no. of tsp_nodes, say). (Start-node index) < n \n"); + return 0; + } + + + if(m3!=0) + time_limit = tsp_piVar3[0]; + else + time_limit = 1000; + + tsp_nodes=m1; // no. of tsp_nodes in the graph + + + + //Initializing the Routing Model for TSP(default parameters and the specified starting node) + + RoutingModel routing(tsp_nodes,1,RoutingModel::NodeIndex(tsp_piVar2[0])); + + RoutingSearchParameters parameters=BuildSearchParametersFromFlags(); + parameters.set_first_solution_strategy(FirstSolutionStrategy::PATH_CHEAPEST_ARC); + + routing.SetArcCostEvaluatorOfAllVehicles(NewPermanentCallback(distance)); + + + parameters.set_time_limit_ms(time_limit); + + + //checking for proper initialization of the model + + if((status=routing.status())!=0) + { + Scierror(801,"Error initializing the Routing model\n"); + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+1,0,0,piReal1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+2,0,0,piReal2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+3,1,1,&status); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + AssignOutputVariable(pvApiCtx,1)=nbInputArgument(pvApiCtx)+1; + AssignOutputVariable(pvApiCtx,2)=nbInputArgument(pvApiCtx)+2; + AssignOutputVariable(pvApiCtx,3)=nbInputArgument(pvApiCtx)+3; + + + return 0; + + + + } + + //Solving the model + + const Assignment* solution=routing.SolveWithParameters(parameters); + + status=routing.status(); + + + if(solution==nullptr) // portends one of 3 situations viz. status(enum) values -> ROUTING_FAIL(no solution possible/found) , ROUTING_FAIL_TIMEOUT or ROUTING_INVALID(not possible in TSP as default parameters used for initialization) + { + + + //piReal1=(int *)malloc(0); + + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+1,0,0,piReal1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+2,0,0,piReal2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+3,1,1,&status); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + AssignOutputVariable(pvApiCtx,1)=nbInputArgument(pvApiCtx)+1; + AssignOutputVariable(pvApiCtx,2)=nbInputArgument(pvApiCtx)+2; + AssignOutputVariable(pvApiCtx,3)=nbInputArgument(pvApiCtx)+3; + + + return 0; + + // pertinent errors and their messages will be handled by the macro based on the status value + } + else // solution found + { + + + piReal1=(int *)malloc(sizeof(int)); + piReal2=(int *)malloc(sizeof(int)*(m1+1)); + + piReal1[0]=solution->ObjectiveValue(); + + int i=0; + + + for(int node=routing.Start(0);!routing.IsEnd(node);node=solution->Value(routing.NextVar(node)), i++) + piReal2[i]=routing.IndexToNode(node).value(); + + piReal2[i]=routing.IndexToNode(routing.End(0)).value(); + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+1,1,1,piReal1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+2,1,(m1+1),piReal2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+3,1,1,&status); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + AssignOutputVariable(pvApiCtx,1)=nbInputArgument(pvApiCtx)+1; + AssignOutputVariable(pvApiCtx,2)=nbInputArgument(pvApiCtx)+2; + AssignOutputVariable(pvApiCtx,3)=nbInputArgument(pvApiCtx)+3; + + return 0; + } + + + + +} +} + + + diff --git a/sci_gateway/cpp/sci_vrp.cpp b/sci_gateway/cpp/sci_vrp.cpp new file mode 100644 index 0000000..97f8797 --- /dev/null +++ b/sci_gateway/cpp/sci_vrp.cpp @@ -0,0 +1,1360 @@ +#include "ortools/base/callback.h" +#include "ortools/base/commandlineflags.h" +#include "ortools/base/commandlineflags.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/constraint_solver/routing.h" +#include "ortools/constraint_solver/routing_enums.pb.h" +#include "ortools/constraint_solver/routing_flags.h" + + + +extern "C"{ +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace operations_research; + + +//THIS MODEL TENDS TO MINIMIZE THE TOTAL DISTANCE COVERED BY ALL THE VEHICLES COMBINED WHILE ALSO MINIMIZING THE TOTAL TIME TAKEN FOR ALL THE TRIPS + + +/* (Note- for the sake of explanation, let the number of nodes be represented by 'n' and the number of vedicles in the fleet, by 'v') +Naming suffixes(also, the respective order) for inputs :- +1-> "adj_matrix" - The given Adjacency matrix representing the intended graph([nxn]). The cell values represent the distance between 2 nodes(cities/locations to be serviced), ie. (adj_matrix[i][j]) represents the disatnce between cities 'i' and 'j'. The solver also supports asymmetrix distances i.e. cases where the distance from node'i' to node'j' is not the same as distance from node'j' to node'i'. Also, negative distance values indicate the absence of an edge/path. ie. if adj[i][j]<0, then there's no path between nodes 'i' and 'j'. +2-> "vehicles" - The number of vehicles/routes in the given Vehicle Routing Problem +3-> "mode_flag"- Indicates the solver mode for the given problem. 3 modes possible : 0-> Single depot node- All vehicles start and end their routes at this node ; 1-> The vehicles can start and end their routes anywhere( modelling a taxi-service scenario) ; 2-> The start and end nodes are specified for all the vehicles by the user ) +4-> "start" - Matrix containing info about the start/depot node(s), depending on the mode in the current instance. [1x1] matrix(single numerical value) for mode '0'. Empty matrix(0x0 or []) for mode '1'. [vx2] matrix for mode '2'. +5-> "demands" - Matrix containing the demands of the different nodes that have to be met, in the capacitated VRP.[1xn] expected, but could be NULL([]) in case the problem is not a capacitated VRP(simple visitation problem). +6-> "max_vehicle_capacity" - In case of capacitated VRP, it is the maximum capacity of a vehicle(capacity and demands are to be of the same unit). It is the maximum total demand a vehicle can fulfil in it's route. +7-> "service_time_per_demand_unit" - It is the time required to satisfy a unit demand, i.e. if the node has a demand of 'x', then it will take a vehicle (servtime_per_demand*x) units of time to serve that node. It is '0' if the serive times of nodes are to be ignored in the time-constraint(time minimization) +8-> "time_windows" - A matrix ([nx2]) indicating the time windows for each node such that the node can only be serviced during that window. (can be NULL , if no time windows needed). If provided, then for any node that does not have a time-window constraint, this will have values, '0' and 'INT_MAX' for the row corresponding to that node. +9-> "speeds" - A matrix indicating the vehicle speeds. Options - 1.[1x1] matrix indicating a single avg. speed for all vehicles on all arcs. 2.NULL, if the transit times between the nodes are to be ignored, in the time minimization. 3.[nxn] matrix when the avg. speed of the vehicles is different between different nodes(different on differnt arcs). +10-> "waiting_time" - Matrix indicating the waiting times, if any, at the nodes. Either NULL, if no waiting times(or they are ot be ignored during time minimization) or a [1xn] matrix. +11-> "refuel_flag" - flag indicating if fuel constraint is to be considered for the given VRP; 0-> NO fuel constraints ; 1-> fuel constraints to be considered( fuel consumption is minimized with vehicles having a fixed fuel capacity and certain specified refueling nodes only. Each transit costs fuel(here, equal to the distance covered as fuel is assumed to be specified in terms of the units of distance(mileage, is you will) +12-> "fuel_capacity_per_vehicle" - If fuel constraint is considered, this indicates the fuel capacity of a vehicle(same for all vehicles). Initially, the amount of fuel in each vehicle is equal to this value. Each transit deducts a corresponding amount of fuel from this value, unless the current node is a refuel node, in which case the fuel supply is replenished. +13-> "fuel_nodes" - Matrix specifying the refuel node indices(if fuel constraint is to be considered i.e. refuel_flag==1). Expected -vector [1xA] where A is the number of fuel nodes. Could also be an empty matrix(or NULL) even when fuel constraints are considered, indicating a situation where the fuel is limited but there are no refueling nodes. +14-> "skip_penalties" - an [Ax2] matrix specifying the node index(first column) and the corresponding cost penalty associated if that node were to be skipped( It basically marks that node as optional, albeit with a monetary penalty. This could be NULL if no penalty constraints are specified i.e. ALL NODES ARE MANDATORY! +15-> "groups" - Matrix specifying node groups such that nodes in the same group have to be serviced by the same vehicle i.e. they must lie on the same route.( [AxB] matrix where A is the number of groups and B is the number of nodes in the largest group. Smaller group rows are padded with 0's on the right end(as Scilab does not support variable length rows in matrices) +16-> "same_vehicle_penalty" - single numerical value specifying the cost penalty if a certain node in a predefined group(see above) is unable to be serviced by the same vehicle(or it ain't optimal to do so). If =-1, it indicates that all groups are strictly imposed ie. we cannot optionally skip a node from a group as a tradeoff to optimize distance and time. +17-> "time_limit" - Time limit for the solver in milliseconds. It may or may not find a solution within the limit. If it does, it may not be the most optimal, but as optimal as the engine could optimize it within the limit given.( As it first finds a naive solution through a greedy strategy and then iteratively optimizes it heuristically toward an optimal solution) + +NOTE:- All indices specified in the inputs(eg. in 'start' matrices are actually Scilab indices, i.e. starting with '1'. Pertinent adjustments to be made. + + +*/ + + +/* +Naming suffixes(also, the respective order) for outputs :- +1->Total Distance- single numeric value +2->Total Time - single numeric value +3->Distance Matrix- [1xv] +4->Time Matrix -[1xv] +5->Vehicle routes - [vxn] matrix. As route will always be less than or equal to 'n', the routes will be padded with 0's on the right end(node indices returned are Scilab Indices(start with 1) so, 0's are not a problem for padding) +6->status flag -The OR-Tools solution status (enum defined in 'routing.h') +*/ + + + + +double *vrp_piVar1=NULL,*vrp_piVar2=NULL,*vrp_piVar3=NULL,*vrp_piVar4=NULL,*vrp_piVar5=NULL,*vrp_piVar6=NULL,*vrp_piVar7=NULL,*vrp_piVar8=NULL,*vrp_piVar9=NULL,*vrp_piVar10=NULL,*vrp_piVar11=NULL,*vrp_piVar12=NULL,*vrp_piVar13=NULL,*vrp_piVar14=NULL,*vrp_piVar15=NULL,*vrp_piVar16=NULL,*vrp_piVar17=NULL; +int nodes; //stores the number of nodes in the given graph(VRP) +int vehicles; //stores the number of vehicles/routes in the given VRP(input argument #2) +int mode_flag; //stores the mode flag value (input argument #3) + +int **start=NULL; + + +int **adj_matrix=NULL; +int *demands=NULL; + + +long long max_vehicle_capacity; + +long long service_time_per_demand_unit; + +const long long time_ub=INT_MAX; //upper bound on the total time a route can take(INT_MAX and not int64-max as 'tis the max that we can receive from scilab). Also, taken max possible to actually forego imposing any such limiation as we are also minimizing the total time taken by the route apart from the distance(Adding variable moinimized by the finalizer), thus rendering it pointless + + +int **time_windows=NULL; // [nx2] matrix, specifying the time windows for each node. If a node does not need a constraint of time windows, this has '0' for start time and 'INT_MAX' for end times(was input as '-1' but converted to INT_MAX before being fed to this gateway) + +int *waiting_times=NULL; + +int *fuel_nodes=NULL; //Depot nodes are NOT inehrently considered refuel nodes. THEY HAVE TO BE SPECIFIED IN THIS ARRAY IN ORDER TO BE CONSIDERED! [1xA] Vector expected(A-> number of refuel nodes) +int refuel_flag=0; //0->No refuelling constraints; 1->Refuelling to be considered; This could be '1' and the fuel_nodes array could still be empty(NULL) indicating that there will be fuel constraints but NO REFUELLING NODES!!!!. +int fuel_capacity_per_vehicle; // Only specified when refuelling is to be considered. + + +int **penalty=NULL; // Ax2 matrix( A-> no. of optional nodes with some penalties for skipping them); First column-> index of the optional node; Second column-> the corresponding penalty) + + // The speed variable is either a 1x1 matrix holding a single int value(avg.speed for all arcs) or an nxn matrix(double int pointer) when different speeds are speicified for different arcs +int **speeds=NULL; + + +int speeds_flag=0; //0-> No speed specified 1-> single avg speed; 2-> different speeds for different arcs + +int **groups=NULL; //AxB matrix, where each row indicated a new group of nodes that need to be on the same vehicle route. Each element of this matrix needs to be unique and the total number of elements(A*B) cannot exceed the total number of node('nodes) + +long long kSameVehiclePenalty=-1; //user input value- a penalty imposed if the nodes in a specified group cannot be put on the same route + +int time_limit; + +const char* kkTime = "Time"; +const char* kkCapacity = "Capacity"; +const char* kkFuel = "Fuel"; + + +//distance callback + +long long distancecallback(RoutingModel::NodeIndex from,RoutingModel::NodeIndex to) +{ + + return adj_matrix[from.value()][to.value()]; + +} + + +//negative distance callback(for refuelling mode) +long long negdistance(RoutingModel::NodeIndex from, RoutingModel::NodeIndex to) +{ + + return adj_matrix[from.value()][to.value()]<0?adj_matrix[from.value()][to.value()]:-adj_matrix[from.value()][to.value()]; // return negative if the value is initially negative(indicating no edge) + +} + + + +int isRefuelNode(int n,int size) //size-> number of values in the refuel_nodes array; +{ + // This method returns 1(true) if the node with index 'n' if a refuel node + + for(int i=0;i 1) When no speed is specified; 2)A single avg. speed is specified for all the edges/arcs ; 3) Separate avg. speeds are speeds are specified for each arc/edge of the given graph + +long long timecallback(RoutingModel::NodeIndex from, RoutingModel::NodeIndex to) +{ + long long temp=0; + + if(demands!=NULL && service_time_per_demand_unit!=0) + temp+=(service_time_per_demand_unit*demandscallback(from,to)); + + + if(speeds!=NULL) + { + if(speeds_flag==1) + temp+=(distancecallback(from,to)/ (speeds[0][0])); + else if(speeds_flag==2) + { + if(mode_flag==1) + temp+=(distancecallback(from,to)/speeds[from.value()-1][to.value()-1]); //accounting for the dummy node in mode '1' + else + temp+=(distancecallback(from,to)/speeds[from.value()][to.value()]); + } + } + + return temp; +} + + + + + +int sci_vrp(char *fname) +{ + + SciErr scierror; + + int iType1=0,iType2=0,iType3=0,iType4=0,iType5=0,iType6=0,iType7=0,iType8=0,iType9=0,iType10=0,iType11=0,iType12=0,iType13=0,iType14=0,iType15=0,iType16=0,iType17=0; + + int *piAddressVar1=NULL,*piAddressVar2=NULL,*piAddressVar3=NULL,*piAddressVar4=NULL,*piAddressVar5=NULL,*piAddressVar6=NULL,*piAddressVar7=NULL,*piAddressVar8=NULL,*piAddressVar9=NULL,*piAddressVar10=NULL,*piAddressVar11=NULL,*piAddressVar12=NULL,*piAddressVar13=NULL,*piAddressVar14=NULL,*piAddressVar15=NULL,*piAddressVar16=NULL,*piAddressVar17=NULL; + + int m1=0,m2=0,m3=0,m4=0,m5=0,m6=0,m7=0,m8=0,m9=0,m10=0,m11=0,m12=0,m13=0,m14=0,m15=0,m16=0,m17=0; + int n1=0,n2=0,n3=0,n4=0,n5=0,n6=0,n7=0,n8=0,n9=0,n10=0,n11=0,n12=0,n13=0,n14=0,n15=0,n16=0,n17=0; + + int status; //output #6 + + CheckInputArgument(pvApiCtx,17,17); + CheckOutputArgument(pvApiCtx,6,6); + + + + //GETTING THE ADDRESSES OF THE INPUT MATRICES + + + + + + + scierror=getVarAddressFromPosition(pvApiCtx,1,&piAddressVar1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,2,&piAddressVar2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,3,&piAddressVar3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,4,&piAddressVar4); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,5,&piAddressVar5); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,6,&piAddressVar6); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,7,&piAddressVar7); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,8,&piAddressVar8); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,9,&piAddressVar9); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,10,&piAddressVar10); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,11,&piAddressVar11); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,12,&piAddressVar12); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,13,&piAddressVar13); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,14,&piAddressVar14); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,15,&piAddressVar15); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,16,&piAddressVar16); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarAddressFromPosition(pvApiCtx,17,&piAddressVar17); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + + + //RETRIEVING AND CHECKING THE TYPES OF THE INPUTS + + + + scierror=getVarType(pvApiCtx,piAddressVar1,&iType1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar2,&iType2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar3,&iType3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar4,&iType4); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar5,&iType5); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar6,&iType6); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar7,&iType7); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar8,&iType8); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar9,&iType9); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar10,&iType10); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar11,&iType11); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar12,&iType12); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar13,&iType13); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar14,&iType14); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar15,&iType15); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar16,&iType16); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getVarType(pvApiCtx,piAddressVar17,&iType17); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + if(iType1!=sci_matrix || iType2!=sci_matrix || iType3!=sci_matrix || iType4!=sci_matrix || iType5!=sci_matrix || iType6!=sci_matrix || iType7!=sci_matrix || iType8!=sci_matrix || iType9!=sci_matrix || iType10!=sci_matrix || iType11!=sci_matrix || iType12!=sci_matrix || iType13!=sci_matrix || iType14!=sci_matrix || iType15!=sci_matrix || iType16!=sci_matrix|| iType17!=sci_matrix) + { + if(iType1!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #1. Matrix Expected! \n"); + + if(iType2!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #2. Matrix Expected! \n"); + + if(iType3!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #3. Matrix Expected! \n"); + + if(iType4!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #4. Matrix Expected! \n"); + + if(iType5!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #5. Matrix Expected! \n"); + + if(iType6!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #6. Matrix Expected! \n"); + + if(iType7!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #7. Matrix Expected! \n"); + + if(iType8!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #8. Matrix Expected! \n"); + + if(iType9!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #9. Matrix Expected! \n"); + + if(iType10!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #10. Matrix Expected! \n"); + + if(iType11!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #11. Matrix Expected! \n"); + + if(iType12!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #12. Matrix Expected! \n"); + + if(iType13!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #13. Matrix Expected! \n"); + + if(iType14!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #14. Matrix Expected! \n"); + + if(iType15!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #15. Matrix Expected! \n"); + + if(iType16!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #16. Matrix Expected! \n"); + + if(iType17!=sci_matrix) + Scierror(999,"Wrong Input Type for Argument #16. Matrix Expected! \n"); + + return 0; + + } + + + + //GETTING THE ACTUAL INPUT MATRICES + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar1,&m1,&n1,&vrp_piVar1); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar2,&m2,&n2,&vrp_piVar2); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar3,&m3,&n3,&vrp_piVar3); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar4,&m4,&n4,&vrp_piVar4); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar5,&m5,&n5,&vrp_piVar5); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar6,&m6,&n6,&vrp_piVar6); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar7,&m7,&n7,&vrp_piVar7); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar8,&m8,&n8,&vrp_piVar8); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar9,&m9,&n9,&vrp_piVar9); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar10,&m10,&n10,&vrp_piVar10); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar11,&m11,&n11,&vrp_piVar11); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar12,&m12,&n12,&vrp_piVar12); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar13,&m13,&n13,&vrp_piVar13); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar14,&m14,&n14,&vrp_piVar14); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar15,&m15,&n15,&vrp_piVar15); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar16,&m16,&n16,&vrp_piVar16); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=getMatrixOfDouble(pvApiCtx,piAddressVar17,&m17,&n17,&vrp_piVar17); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + + + + //////--------------------------LOGIC-------------------------------///////// + + + + //assignments + + RoutingModel *routing; //Will store the RoutingModel Object later + + vehicles=vrp_piVar2[0]; + mode_flag=vrp_piVar3[0]; + nodes=m1; + + if(mode_flag!=1) + { + start=(int **)malloc(sizeof(int *)*m4); + + for(int i=0;i0) // as it could be negative as well- to be ignored + total_distance+=vrp_piVar5[i]; + + + + + + std::vector< std::pair > start_end; // needed for mode '2' + + + + if(mode_flag==0) + { + + const RoutingModel::NodeIndex kDepot(start[0][0]-1); // subtract 1 to get the C++ index from the Scilab index + + + adj_matrix=(int **)malloc(sizeof(int *)*nodes); + + if(m5!=0) + demands=(int *)malloc(sizeof(int)*nodes); + + + + for(int i=0;i(RoutingModel::NodeIndex(start[i][0]-1),RoutingModel::NodeIndex(start[i][1]-1))); + + + routing= new RoutingModel(nodes,vehicles,start_end); + + + } + + + RoutingSearchParameters parameters=BuildSearchParametersFromFlags(); + + parameters.set_first_solution_strategy(FirstSolutionStrategy::PATH_CHEAPEST_ARC); + parameters.mutable_local_search_operators()->set_use_path_lns(false); + + if(m17!=0) + parameters.set_time_limit_ms(time_limit); + + + + + //Setting the distance function + + routing->SetArcCostEvaluatorOfAllVehicles(NewPermanentCallback(distancecallback)); + + + //Adding group constraints for sets of nodes to be on the same route(servicesd by the same vehicle) + + + if(groups!=NULL) + { + //indices given in the groups array are scvilab indices(start with 0). Pertinent Adjustment to be made if mode<>2 + + int x=sizeof(groups)/sizeof(groups[0]); //no. of rows i.e. the no. of groups + int y= sizeof(groups[0])/sizeof(int); // no. of columns. (different groups can be different sizes, but all padded with zeroes to equalize the number of columns) + + //normalizing and converting the given SameVehiclePenalty into a relative distance penalty value to be congrous with the 'distance interpretation' of our minimization model + + int count; + + + for(int i=0;i group; + for(int j=0;jAddSoftSameVehicleConstraint(group,0); + else if(kSameVehiclePenalty > 0) + routing->AddSoftSameVehicleConstraint(group,kSameVehiclePenalty); + + + + } + + } + + + //setting the speed flag + + if(speeds!=NULL) + { + //if(sizeof(speeds)==sizeof(int)) //single avg. speed case + if(m9==1 && n9==1) + speeds_flag=1; + else speeds_flag=2; + } + + + + //Adding the capacity dimension constraints + if(demands!=NULL) + { + const long long kNullCapacitySlack=0; + + routing->AddDimension(NewPermanentCallback(demandscallback),kNullCapacitySlack, max_vehicle_capacity, /* fix_start_cumul_to_zero */ true, kkCapacity); + + const RoutingDimension& capacity_dimension = routing->GetDimensionOrDie(kkCapacity); + } + + + + //Adding Time Dimension constraints + + routing->AddDimension(NewPermanentCallback(timecallback),time_ub,time_ub,true, kkTime); + + const RoutingDimension& time_dimension=routing->GetDimensionOrDie(kkTime); + + + + //Adding time windows + + if(time_windows!=NULL) + { + if(mode_flag==1) + { + time_dimension.CumulVar(0)->SetRange(0,INT_MAX); + for(int i=1;i<=nodes;i++) + time_dimension.CumulVar(i)->SetRange(time_windows[i-1][0],time_windows[i-1][1]); + } + else + { + for(int i=1;iSetRange(time_windows[i][0],time_windows[i][1]); + } + + + + } + + + //Adding Waiting Times + + if(waiting_times!=NULL) + { + if(mode_flag==1) + { + + time_dimension.SlackVar(0)->SetValue(0); + for(int i=1;i<=nodes;i++) + time_dimension.SlackVar(i)->SetValue(waiting_times[i-1]); + } + else + { + for(int i=0;iSetValue(waiting_times[i]); + } + + } + + + + + int num_penalty=m14; + + //converting the penalty values into relative distance values to be germane to the interpretation of our model that minimizes distance + + if(penalty!=NULL) + { + + int total_penalty=0; + + for(int i=0;i optnode(1,temp); + routing->AddDisjunction(optnode,penalty[i][1]); + } + + } + + + + + //Adding Refuelling parameters + //Depots are NOT assumed to be fuel nodes by default. + + if(refuel_flag) + { + int fsize=0; //number of refuel nodes + + if(fuel_nodes!=NULL) + fsize=n13; + + + routing->AddDimension(NewPermanentCallback(negdistance),fuel_capacity_per_vehicle,fuel_capacity_per_vehicle, /*fix_start_cumul_to_zero*/false,kkFuel); + + const RoutingDimension& fuel_dimension=routing->GetDimensionOrDie(kkFuel); + + for(int i=1;i<=nodes;i++) // As the 'fuel_nodes' array contains the SCILAB INDICES for the nodes + { + if(mode_flag==1) + { + if(!isRefuelNode(i,fsize)) + fuel_dimension.SlackVar(i)->SetValue(0); + + routing->AddVariableMinimizedByFinalizer(fuel_dimension.CumulVar(i)); + } + else + { + if(!isRefuelNode(i,fsize)) + fuel_dimension.SlackVar(i-1)->SetValue(0); + + routing->AddVariableMinimizedByFinalizer(fuel_dimension.CumulVar(i-1)); + } + + + } + + //sciprint("Slack - %d\n",fuel_dimension.SlackVar(1)); + //sciprint("Cumul - %d\n",fuel_dimension.CumulVar(1)); + + + + } + + + + //Solving the Model + + //status=routing->status(); + //sciprint("Status - %d\n",status); + + const Assignment * solution= routing->SolveWithParameters(parameters); + + + status=routing->status(); + + + if(solution==nullptr) // portends one of 3 situations viz. status(enum) values -> ROUTING_FAIL(no solution possible/found) , ROUTING_FAIL_TIMEOUT or ROUTING_INVALID(not possible in TSP as default parameters used for initialization) + { + scierror=createMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx)+1,0,0,NULL); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx)+2,0,0,NULL); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx)+3,0,0,NULL); + if(scierror.iErr) + { + printError(&scierror,0); + return 0;scierror=createMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx)+1,0,0,NULL); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + } + + scierror=createMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx)+4,0,0,NULL); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + scierror=createMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx)+5,0,0,NULL); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + scierror=createMatrixOfInteger32(pvApiCtx,nbInputArgument(pvApiCtx)+6,1,1,&status); + if(scierror.iErr) + { + printError(&scierror,0); + return 0; + } + + + } + else //solution found! + { + int total_time=0; //output #2 + + int total_distance=solution->ObjectiveValue(); //output #1 + + int *distances=(int *)malloc(sizeof(int)*vehicles); //output #3 + int *times=(int *)malloc(sizeof(int)*vehicles); //output #4 + + std::fill(distances,distances+sizeof(distances),0); + std::fill(times,times+sizeof(times),0); + + + int **routes=(int **)malloc(sizeof(int *)*vehicles); //[vxn] matrix ; output #5 ; Will have to converted to single dimensional array before mapping + + + + for(int i=0;iValue(routing->NextVar(routing->Start(i)));!routing->IsEnd(node);node=solution->Value(routing->NextVar(node)),j++) //skipping the first node(dummy) + { + routes[i][j]=routing->IndexToNode(node).value(); // Scilab indices(start with '1') as dummy node '0' was added + if(j!=0) + { + distances[i]+=distancecallback(RoutingModel::NodeIndex(routes[i][j-1]),RoutingModel::NodeIndex(routes[i][j])); + times[i]+=timecallback(RoutingModel::NodeIndex(routes[i][j-1]),RoutingModel::NodeIndex(routes[i][j])); + } + + } + + //padding with zeroes + for(int k=j;kStart(i);!routing->IsEnd(node);node=solution->Value(routing->NextVar(node)),j++) + { + routes[i][j]=(routing->IndexToNode(node).value()) +1; // '1' to be added to convert to the Scilab index convention(starting with '1') + + if(j!=0) + { + distances[i]+=distancecallback(RoutingModel::NodeIndex(routes[i][j-1]-1),RoutingModel::NodeIndex(routes[i][j]-1)); + times[i]+=timecallback(RoutingModel::NodeIndex(routes[i][j-1]-1),RoutingModel::NodeIndex(routes[i][j]-1)); + } + + + + } + + //mapping the last node + routes[i][j]=(routing->IndexToNode(routing->End(i)).value()) +1; + + //sciprint("\n\n\n Last :- %d\n\n\n",routes[i][j]); + + + //padding with zeroes + for(int k=j+1;k1 0 10 +//0->5 0 8 +//2->1 0 5 +//1->5 0 2 +//2->3 0 7 +//4->3 0 10 +//4->5 0 10 +//4->2 0 8 + +//There is no path connecting the specified source node : 0 and the specified target node : 3 + + + +[maxflow,arcflows,status] = fmaxflow(start_nodes,end_nodes,capacities,st); diff --git a/tests/general_tests/fmaxflow/fmaxflow_output1.sce b/tests/general_tests/fmaxflow/fmaxflow_output1.sce new file mode 100644 index 0000000..690c9d1 --- /dev/null +++ b/tests/general_tests/fmaxflow/fmaxflow_output1.sce @@ -0,0 +1,15 @@ +//Check for the admissible number of output parameters( 2 or 3) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + +//Error +//fmaxflow : Wrong number of output arguments(1). This function can deliver 2/3 outputs. Refer to help/FOT documentation for further details +//at line 158 of function fmaxflow called by : +//[maxflow] = fmaxflow(start_nodes,end_nodes,capacities,st); + + + +[maxflow] = fmaxflow(start_nodes,end_nodes,capacities,st); diff --git a/tests/general_tests/fmaxflow/fmaxflow_output2.sce b/tests/general_tests/fmaxflow/fmaxflow_output2.sce new file mode 100644 index 0000000..4591c4d --- /dev/null +++ b/tests/general_tests/fmaxflow/fmaxflow_output2.sce @@ -0,0 +1,13 @@ +//Check for the admissible number of output parameters( 2 or 3) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + + +//Error +//Wrong number of output arguments. + + +[maxflow,arcflows,status,bleh] = fmaxflow(start_nodes,end_nodes,capacities,st); diff --git a/tests/general_tests/fmaxflow/fmaxflow_sourceChk.sce b/tests/general_tests/fmaxflow/fmaxflow_sourceChk.sce new file mode 100644 index 0000000..ad413fd --- /dev/null +++ b/tests/general_tests/fmaxflow/fmaxflow_sourceChk.sce @@ -0,0 +1,14 @@ +//Check the existence of the specified source node in the given graph + + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +capacities=[10 8 5 2 7 10 10 8]; +st=[6,3]; // node 6 doesn't exist in the graph + +//Error +//fshortestpath : Invalid source node(6)- The specified source node does not exist in the given graph +//at line 215 of function fmaxflow called by : +//[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); + +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); diff --git a/tests/general_tests/fmaxflow/fmaxflow_st_dim.sce b/tests/general_tests/fmaxflow/fmaxflow_st_dim.sce new file mode 100644 index 0000000..bf9ca44 --- /dev/null +++ b/tests/general_tests/fmaxflow/fmaxflow_st_dim.sce @@ -0,0 +1,16 @@ +//Check for the dimensions of the row matrix/vector 'st'(representing the 2 values for source node and target node respectively)- expected dimensions - 1x2 + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4,5]; + +//Error +//fmaxflow: Expected size [1 2] for input argument st at input #4, but got [1 3] instead. +//at line 49 of function Checkdims called by : +//at line 206 of function fmaxflow called by : +//[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); + + +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); + diff --git a/tests/general_tests/fmaxflow/fmaxflow_startendnodes_integral.sce b/tests/general_tests/fmaxflow/fmaxflow_startendnodes_integral.sce new file mode 100644 index 0000000..ed25789 --- /dev/null +++ b/tests/general_tests/fmaxflow/fmaxflow_startendnodes_integral.sce @@ -0,0 +1,15 @@ +//Check if all the capacity values are integral(however, 'tis not mandatory for them to be stored in a matrix integer type) + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +capacities=[10 8 5 2 7 10 10 8]; + +st=[0.5 2.4] + +//Error +//fmaxflow : The source and target node value(s)(input argument #4) are expected to be integral. +//at line 232 of function fmaxflow called by : +//[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); + + +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); diff --git a/tests/general_tests/fmaxflow/fmaxflow_startnodes_dim.sce b/tests/general_tests/fmaxflow/fmaxflow_startnodes_dim.sce new file mode 100644 index 0000000..122c89c --- /dev/null +++ b/tests/general_tests/fmaxflow/fmaxflow_startnodes_dim.sce @@ -0,0 +1,15 @@ +//Check for the dimensions of the 'start_nodes' vector(expected - 1xn form matrix) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3; + 0, 0, 0, 0, 0, 0, 0, 0, 0]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + +//Error +//fmaxflow : Wrong Input Size. The input argument #1 is expected to be a matrix of dimension of the form 1xn (2x9 obtained instead) +//at line 188 of function fmaxflow called by : +//[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st) + + +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); diff --git a/tests/general_tests/fmaxflow/fmaxflow_startnodes_integral.sce b/tests/general_tests/fmaxflow/fmaxflow_startnodes_integral.sce new file mode 100644 index 0000000..23d6ecb --- /dev/null +++ b/tests/general_tests/fmaxflow/fmaxflow_startnodes_integral.sce @@ -0,0 +1,14 @@ +//Check if all the start nodes' values are integral(however, 'tis not mandatory to store them in a matrix integer type) + +start_nodes=[ 0.8 0.3 1.5 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +capacities=[10 8 5 2 7 10 10 8]; +st=[0,3]; + +//Error +//fmaxflow : The values in the 'start_nodes' vector(input argument #1) are expected to be integral. +//at line 217 of function fmaxflow called by : +//[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); + + +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); diff --git a/tests/general_tests/fmaxflow/fmaxflow_targetChk.sce b/tests/general_tests/fmaxflow/fmaxflow_targetChk.sce new file mode 100644 index 0000000..3159b5a --- /dev/null +++ b/tests/general_tests/fmaxflow/fmaxflow_targetChk.sce @@ -0,0 +1,14 @@ +//Check for the validity of the specified target node in the given graph + + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +capacities=[10 8 5 2 7 10 10 8]; +st=[0,9]; // node 9 doesn't exist in the graph + +//Error +//fshortestpath : Invalid target node(9)- The specified target node does not exist in the given graph +//at line 220 of function fmaxflow called by : +//[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); + +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); diff --git a/tests/general_tests/fshortestpath/fshortestpath_discondist_dim.sce b/tests/general_tests/fshortestpath/fshortestpath_discondist_dim.sce new file mode 100644 index 0000000..beb99c2 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_discondist_dim.sce @@ -0,0 +1,18 @@ +//Check if the value of 'disconnected_distance is a singular numerical value(1x1 matrix form) + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; +st=[0,3] + +disconnected_distance=[0,4] + +//Error +//fshortestpath: Expected size [1 1] for input argument disconnected_distance at input #5, but got [1 2] instead. +//at line 49 of function Checkdims called by : +//at line 144 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) + + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) diff --git a/tests/general_tests/fshortestpath/fshortestpath_discondist_integral.sce b/tests/general_tests/fshortestpath/fshortestpath_discondist_integral.sce new file mode 100644 index 0000000..979a227 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_discondist_integral.sce @@ -0,0 +1,18 @@ +//Check if the value of 'disconnected_distance' is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; +st=[0,3] + +disconnected_distance=5.3; + +//Error +//fshortestpath : The 'disconnected distance' value(input argument #5) is expected to be integral. +//at line 178 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) + + diff --git a/tests/general_tests/fshortestpath/fshortestpath_endnodes_dim.sce b/tests/general_tests/fshortestpath/fshortestpath_endnodes_dim.sce new file mode 100644 index 0000000..7bd3d41 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_endnodes_dim.sce @@ -0,0 +1,17 @@ +//Check the dimensions of the 'end_nodes' vector(expected - 1xn matrix) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4; + 1, 1, 1, 1, 1, 1, 1, 1, 1; + 7, 5, 3, 2, 7, 2, 1, 3, 5;]; +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + + +//Error +//fshortestpath : Wrong Input Size. The input argument #2 is expected to be a matrix of dimensions of the form 1xn (3x9 obtained instead) +//at line 128 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_endnodes_integral.sce b/tests/general_tests/fshortestpath/fshortestpath_endnodes_integral.sce new file mode 100644 index 0000000..2e00c13 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_endnodes_integral.sce @@ -0,0 +1,14 @@ +//Check if all the end nodes' values are integral(however, 'tis not mandatory to store them in a matrix integer type) + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5.5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; +st=[0,3]; + +//Error +//fshortestpath : The values in the 'end_nodes' vector(input argument #2) are expected to be integral. +//at line 161 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_equalvectorlength.sce b/tests/general_tests/fshortestpath/fshortestpath_equalvectorlength.sce new file mode 100644 index 0000000..9675198 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_equalvectorlength.sce @@ -0,0 +1,14 @@ +//Check to ensure that the 3 input vectors viz. 'start_nodes', 'end_nodes' and 'weights' are of equal length(as they define the arcs of the graph- each index across the 3 representing one unique arc) + +start_nodes=[ 0 0 1 1 2 4 5 4 6]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8 4]; +st=[0,3] + +//Error +//fshortestpath : Unequal dimensions of the 3 input vectors (9 8 9). The 3 are expected to be of equal lengths. +//at line 138 of function fshortestpath called by : +//[mincost,shortestpath,flag] = fshortestpath(start_nodes,end_nodes,weights,st); + + +[mincost,shortestpath,flag] = fshortestpath(start_nodes,end_nodes,weights,st); diff --git a/tests/general_tests/fshortestpath/fshortestpath_input1.sce b/tests/general_tests/fshortestpath/fshortestpath_input1.sce new file mode 100644 index 0000000..c75025a --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_input1.sce @@ -0,0 +1,15 @@ +//Check for the admissible number of input arguments(4-5) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + + +//Error +//fshortestpath : Number of input arguments is expected to be 4 or 5. Found 3. Refer to help/FOT documentation for more details. +//at line 71 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights) + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights); diff --git a/tests/general_tests/fshortestpath/fshortestpath_input2.sce b/tests/general_tests/fshortestpath/fshortestpath_input2.sce new file mode 100644 index 0000000..c8032b5 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_input2.sce @@ -0,0 +1,15 @@ +//Check for the admissible number of input arguments(4-5) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + +//Error +//fshortestpath : Number of input arguments is expected to be 4 or 5. Found 6. Refer to help/FOT documentation for more details. +//at line 71 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,40,1) + + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,40,1); diff --git a/tests/general_tests/fshortestpath/fshortestpath_nopath1.sce b/tests/general_tests/fshortestpath/fshortestpath_nopath1.sce new file mode 100644 index 0000000..89a5989 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_nopath1.sce @@ -0,0 +1,16 @@ +//Check to see if there is indeed a path between the specified source and target nodes in the given graph ( Here, no 'disconnected_distance' value is specified) + +start_nodes=[0 0 2 1 2 4 4 4] +end_nodes=[1 5 1 5 3 3 5 2] +weights=[10 8 5 2 7 10 10 8] +st=[0,3] + + +//Error +//No path connecting start-node: 0 and end-node=: 3. + +// No Solution![0 , 3] + + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_nopath2.sce b/tests/general_tests/fshortestpath/fshortestpath_nopath2.sce new file mode 100644 index 0000000..571c929 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_nopath2.sce @@ -0,0 +1,11 @@ +//Check to see if there is an actual path between the specified source and taget nodes. In this case, there IS a path but it is ignored due to the the weight value of one or more arcs being more than the threashold value('disconnected distance) specified by the user. The routine internally checks a second time without the restriction of the threashold to provide a pertinent error regarding the same. + +start_nodes=[ 0 0 0 1 1 2 2 3 3 ]; +end_nodes=[ 1 2 3 2 4 3 4 2 4 ]; +weights= [ 20 30 10 40 30 10 20 5 20 ]; +st= [ 0 4]; +disconnected_distance=20; + + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,disconnected_distance) diff --git a/tests/general_tests/fshortestpath/fshortestpath_nopath3.sce b/tests/general_tests/fshortestpath/fshortestpath_nopath3.sce new file mode 100644 index 0000000..af9a5d5 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_nopath3.sce @@ -0,0 +1,11 @@ +//Check to see if there is indeed a path between the specified source and target nodes in the given graph ( Here, a 'disconnected_distance' value is specified by the user, yet there is actually no path possible ie. the path ain't obscured due to thresholding by the 'disconnected_distance' value(double checks with max possible distance value and throws a pertinent error about the blockade of a path, if there was one) + +start_nodes=[0 0 2 1 2 4 4 4] +end_nodes=[1 5 1 5 3 3 5 2] +weights=[10 8 5 2 7 10 10 8] +st=[0,3] + + + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st,50) diff --git a/tests/general_tests/fshortestpath/fshortestpath_output1.sce b/tests/general_tests/fshortestpath/fshortestpath_output1.sce new file mode 100644 index 0000000..67ddd4e --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_output1.sce @@ -0,0 +1,16 @@ +//Check for the admissible number of output parameters( 2 or 3) + + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + +//Error +//fshortestpath : Unexpected number of output parameters( Found 1). This routine expects 2 or 3 output parameters. Refer to help/FOT documentation for more details. +//at line 78 of function fshortestpath called by : +//[mincost]=fshortestpath(start_nodes,end_nodes,weights,st); + + + +[mincost]=fshortestpath(start_nodes,end_nodes,weights,st); diff --git a/tests/general_tests/fshortestpath/fshortestpath_output2.sce b/tests/general_tests/fshortestpath/fshortestpath_output2.sce new file mode 100644 index 0000000..23b36fb --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_output2.sce @@ -0,0 +1,13 @@ +//Check for the admissible number of output parameters( 2 or 3) + + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + +//Error +//Wrong number of output arguments. + + +[mincost,shortestpath,flag,bleh]=fshortestpath(start_nodes,end_nodes,weights,st); diff --git a/tests/general_tests/fshortestpath/fshortestpath_sourceChk.sce b/tests/general_tests/fshortestpath/fshortestpath_sourceChk.sce new file mode 100644 index 0000000..94247bb --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_sourceChk.sce @@ -0,0 +1,16 @@ +//Check for the validity of the specified source node in the given graph + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; + +st=[6,4] + +//Error +//fshortestpath : Invalid source node(6)- The specified source node does not exist in the given graph +//at line 190 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_st_dim.sce b/tests/general_tests/fshortestpath/fshortestpath_st_dim.sce new file mode 100644 index 0000000..5ac8299 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_st_dim.sce @@ -0,0 +1,17 @@ +//Check the dimensions of input matrix 'st'(expected- 1x2 ; representing the source and target nodes respectively) + + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20]; + +st=[0,4,8]; + +//Error +//fshortestpath: Expected size [1 2] for input argument st at input #4, but got [1 3] instead. +//at line 49 of function Checkdims called by : +//at line 141 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_startend_integral.sce b/tests/general_tests/fshortestpath/fshortestpath_startend_integral.sce new file mode 100644 index 0000000..f2ecd6e --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_startend_integral.sce @@ -0,0 +1,16 @@ +//Check if start node and target node values are integral(however, 'tis not mandatory to store them in a matrix integer type) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20]; + +st=[0.4, 5.5] + + +//Error +//fshortestpath : The source and target node value(s)(input argument #4) are expected to be integral. +//at line 171 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_startnodes_dim.sce b/tests/general_tests/fshortestpath/fshortestpath_startnodes_dim.sce new file mode 100644 index 0000000..349388a --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_startnodes_dim.sce @@ -0,0 +1,15 @@ +//Check the dimensions of the 'start_nodes' vector(expected - 1xn matrix) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3; + 0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +st=[0,4]; + +//Error +//fshortestpath : Wrong Input Size. The input argument #1 is expected to be a matrix of dimensions of the form 1xn (2x9 obtained instead) +//at line 123 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_startnodes_integral.sce b/tests/general_tests/fshortestpath/fshortestpath_startnodes_integral.sce new file mode 100644 index 0000000..bdacd93 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_startnodes_integral.sce @@ -0,0 +1,15 @@ +//Check if all the start nodes' values are integral(however, 'tis not mandatory to store them in a matrix integer type) + +start_nodes=[ 0.8 0.3 1.5 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; +st=[0,3]; + +//Error +//fshortestpath : The values in the 'start_nodes' vector(input argument #1) are expected to be integral. +//at line 156 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_targetChk.sce b/tests/general_tests/fshortestpath/fshortestpath_targetChk.sce new file mode 100644 index 0000000..c95c9e8 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_targetChk.sce @@ -0,0 +1,14 @@ +//Check for the validity of the specified target node in the given graph + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; + +st=[1,7] + +//Error +//fshortestpath : Invalid target node(7)- The specified target node does not exist in the given graph +//at line 195 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_weights_dim.sce b/tests/general_tests/fshortestpath/fshortestpath_weights_dim.sce new file mode 100644 index 0000000..c31db7a --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_weights_dim.sce @@ -0,0 +1,18 @@ +//Check the dimensions of the 'weights' vector(expected- 1xn matrix) + +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; + +weights = [20, 30, 10, 40, 30, 10, 20, 5, 20; + 1, 1, 1, 1, 1, 1, 1, 1, 1; + 7, 5, 3, 2, 7, 2, 1, 3, 5]; +st=[0,4]; + +//Error +//fshortestpath : Wrong Input Size. The input argument #3 is expected to be a matrix of dimensions of the form 1xn (3x9 obtained instead) +//at line 133 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/fshortestpath/fshortestpath_weights_integral.sce b/tests/general_tests/fshortestpath/fshortestpath_weights_integral.sce new file mode 100644 index 0000000..0318d21 --- /dev/null +++ b/tests/general_tests/fshortestpath/fshortestpath_weights_integral.sce @@ -0,0 +1,15 @@ +//Check if all the end nodes' values are integral(however, 'tis not mandatory to store them in a matrix integer type) + +start_nodes=[ 0 0 1 1.0 2.0 4 5 4]; //x.0 is considered integral, so 'start_nodes' doesn't throw any error +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10.6 8.9 5 2 7.5 10 10 8]; +st=[0,3]; + + +//Error +//fshortestpath : The values in the 'weights' vector(input argument #3) are expected to be integral. +//at line 166 of function fshortestpath called by : +//[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) + + +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st) diff --git a/tests/general_tests/jssp/jssp_duration_valid.sce b/tests/general_tests/jssp/jssp_duration_valid.sce new file mode 100644 index 0000000..224a105 --- /dev/null +++ b/tests/general_tests/jssp/jssp_duration_valid.sce @@ -0,0 +1,27 @@ +//Check if all the duration values in the 'tasks' matrix are valid (Expected- nonnegative, integral values) + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 -1; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : One or more 'duration' values in the 'tasks' matrix (argument #4) are invalid. Duration values cannot be negative. +//at line 324 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_endbefore_valid.sce b/tests/general_tests/jssp/jssp_endbefore_valid.sce new file mode 100644 index 0000000..2edabba --- /dev/null +++ b/tests/general_tests/jssp/jssp_endbefore_valid.sce @@ -0,0 +1,28 @@ +//Check if the index values in the 'end-before' column (column 5) in 'tasks' matrix (only for mode '1'), are valid + +machines = 3; +jobs = 3; + +jssp_mode = 1; + +tasks=[ 1 1 3 -1 -1; + 1 2 2 -1 1; + 1 3 2 -1 -1; + 2 1 2 -1 21; + 2 3 1 -1 -1; + 2 2 4 -1 -1; + 3 2 4 --1 -1; + 3 3 3 -1 -1; + ]; + +time_limit = []; + + +//Error +// !--error 10000 +//jssp : One or more job-index values in the 'end-before' column (column 5) in the 'tasks' matrix (argument #4) are invalid. Expected - either '-1' or a value from '1' to '3'. +//at line 348 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_firsttask_mode1.sce b/tests/general_tests/jssp/jssp_firsttask_mode1.sce new file mode 100644 index 0000000..f12bf95 --- /dev/null +++ b/tests/general_tests/jssp/jssp_firsttask_mode1.sce @@ -0,0 +1,25 @@ +//For mode '1', checking if there's one task eligible to be the very first task in the schedule + +machines = 2; +jobs = 5; +jssp_mode = 1; + +tasks = [1 1 13 1 -1; + 1 2 3 1 -1; + 2 1 2 1 -1; + 2 2 5 1 -1; + 3 1 1 1 -1; + 3 2 3 1 -1; + 4 1 4 1 -1; + 4 2 6 1 -1; + 5 1 5 1 -1; + 5 2 7 1 -1]; + +time_limit = []; + +//Error +//jssp : At least one task in every job must be free from a 'start-after' constraint ( = -1), to serve as a potential first task for that job. No such tasks found in job #1. +//at line 371 of function jssp called by : +//[makespan, schedule, status] = jssp (machines, jobs, jssp_mode, tasks, time_limit); + +[makespan, schedule, status] = jssp (machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_inputargs.sce b/tests/general_tests/jssp/jssp_inputargs.sce new file mode 100644 index 0000000..2c71567 --- /dev/null +++ b/tests/general_tests/jssp/jssp_inputargs.sce @@ -0,0 +1,26 @@ +//Check if the number of input arguments is correct/permissible + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +bleh = [1]; + +//Error +// !--error 10000 +//jssp : Unexpected number of input arguments. '4' or '5' expected. Refer to help/FOT Documentation for more details. +//at line 112 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, [], bleh); + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, [], bleh); diff --git a/tests/general_tests/jssp/jssp_jmode_dims.sce b/tests/general_tests/jssp/jssp_jmode_dims.sce new file mode 100644 index 0000000..9e18b47 --- /dev/null +++ b/tests/general_tests/jssp/jssp_jmode_dims.sce @@ -0,0 +1,26 @@ +//Check if the dimensions of 'jmode' are correct (Expected - Singular , 0/1 value) + +machines = 3; +jobs = 3; + +jssp_mode = [0 1]; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + + +//Error +// !--error 10000 +//jssp : Wrong dimensions for input argument #3 ('jmode'). Single integral value [1x1] expected. +//at line 186 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); diff --git a/tests/general_tests/jssp/jssp_jmode_int.sce b/tests/general_tests/jssp/jssp_jmode_int.sce new file mode 100644 index 0000000..4dcae1f --- /dev/null +++ b/tests/general_tests/jssp/jssp_jmode_int.sce @@ -0,0 +1,27 @@ +//Check if the value of 'machines' is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +machines = 3; +jobs = 3; + +jssp_mode = 0.1; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : Input argument #3('jmode') can only take the value '0' or '1' (details in help/FOT documentation). +//at line 193 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_jmode_type.sce b/tests/general_tests/jssp/jssp_jmode_type.sce new file mode 100644 index 0000000..1644269 --- /dev/null +++ b/tests/general_tests/jssp/jssp_jmode_type.sce @@ -0,0 +1,28 @@ +//Check if 'jmode' is of the correct type + +machines = 3; +jobs = 3; + +jssp_mode = "0"; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp: Expected type ["constant"] for input argument jmode at input #3, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 145 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_jmode_valid.sce b/tests/general_tests/jssp/jssp_jmode_valid.sce new file mode 100644 index 0000000..f290fbe --- /dev/null +++ b/tests/general_tests/jssp/jssp_jmode_valid.sce @@ -0,0 +1,27 @@ +//Check if the 'jmode' value is valid (Expected - only integral '0' or '1') + +machines = 3; +jobs = 3; + +jssp_mode = 2; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : Input argument #3('jmode') can only take the value '0' or '1' (details in help/FOT documentation). +//at line 193 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_jobindices_valid.sce b/tests/general_tests/jssp/jssp_jobindices_valid.sce new file mode 100644 index 0000000..ef0166b --- /dev/null +++ b/tests/general_tests/jssp/jssp_jobindices_valid.sce @@ -0,0 +1,27 @@ +//Checking if all the job-indices in the 'tasks' matrix (column 1) are valid + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 4 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : One or more job-index values in the 'tasks' matrix (argument #4) are invalid. Job indices can only take values from '1' to '3'. +//at line 307 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_jobs_dims.sce b/tests/general_tests/jssp/jssp_jobs_dims.sce new file mode 100644 index 0000000..5895ac7 --- /dev/null +++ b/tests/general_tests/jssp/jssp_jobs_dims.sce @@ -0,0 +1,26 @@ +//Check if the dimensions of 'jobs' is correct( Expected- Singular, integral value) + +machines = 3; +jobs = []; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + + + +//Error +// !--error 10000 +//jssp : Wrong dimensions for input argument #2 ('jobs'). Single integral value [1x1] expected. +//at line 175 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); diff --git a/tests/general_tests/jssp/jssp_jobs_int.sce b/tests/general_tests/jssp/jssp_jobs_int.sce new file mode 100644 index 0000000..f90c4b8 --- /dev/null +++ b/tests/general_tests/jssp/jssp_jobs_int.sce @@ -0,0 +1,27 @@ +//Check if the value of 'jobs' is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +machines = 3; +jobs = 3.00001; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : Number of jobs ( 'jobs' ; argument #2) is expected to be an integral value. +//at line 252 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_jobs_type.sce b/tests/general_tests/jssp/jssp_jobs_type.sce new file mode 100644 index 0000000..edb3074 --- /dev/null +++ b/tests/general_tests/jssp/jssp_jobs_type.sce @@ -0,0 +1,30 @@ +//Checking if 'jobs' is of the correct type + +machines = 3; +jobs = "3"; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp: Expected type ["constant"] for input argument jobs at input #2, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 144 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + diff --git a/tests/general_tests/jssp/jssp_lasttask_mode1.sce b/tests/general_tests/jssp/jssp_lasttask_mode1.sce new file mode 100644 index 0000000..25f7eb8 --- /dev/null +++ b/tests/general_tests/jssp/jssp_lasttask_mode1.sce @@ -0,0 +1,27 @@ +//For mode '1', checking if there's one task eligible to be the very last task in the schedule + +machines = 2; +jobs = 5; +jssp_mode = 1; + +tasks = [1 1 13 -1 1; + 1 2 3 -1 1; + 2 1 2 -1 1; + 2 2 5 -1 1; + 3 1 1 -1 1; + 3 2 3 -1 1; + 4 1 4 -1 1; + 4 2 6 -1 1; + 5 1 5 -1 1; + 5 2 7 -1 1]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : At least one task in every job must be free from an 'end-before' constraint ( = -1), to serve as a potential last task for that job. No such tasks found in job #1. +//at line 364 of function jssp called by : +//[makespan, schedule, status] = jssp (machines, jobs, jssp_mode, tasks, time_limit); +// + +[makespan, schedule, status] = jssp (machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_machineindices_valid.sce b/tests/general_tests/jssp/jssp_machineindices_valid.sce new file mode 100644 index 0000000..d34ca6d --- /dev/null +++ b/tests/general_tests/jssp/jssp_machineindices_valid.sce @@ -0,0 +1,28 @@ +//Checking if all the machine-indices in the 'tasks' matrix (column 1) are valid + + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 4 2; + 1 3 2; + 2 6 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : One or more machine-index values in the 'tasks' matrix (argument #4) are invalid. Machine indices can only take values from '1' to '3'. +//at line 315 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_machines_dims.sce b/tests/general_tests/jssp/jssp_machines_dims.sce new file mode 100644 index 0000000..621a9d2 --- /dev/null +++ b/tests/general_tests/jssp/jssp_machines_dims.sce @@ -0,0 +1,27 @@ +//Check if the dimensions of 'machines' is correct(Expected- Single, integral value) + +machines = [3 1]; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +//Error +// !--error 10000 +//jssp : Wrong dimensions for input argument #1 ('machines'). Single integral value [1x1] expected. +//at line 162 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); +// + + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); diff --git a/tests/general_tests/jssp/jssp_machines_int.sce b/tests/general_tests/jssp/jssp_machines_int.sce new file mode 100644 index 0000000..44c7df6 --- /dev/null +++ b/tests/general_tests/jssp/jssp_machines_int.sce @@ -0,0 +1,29 @@ +//Check if the value of 'machines' is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +machines = 3.1; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : Number of machines ( 'machines' ; argument #1) is expected to be an integral value. +//at line 244 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); +// + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_machines_type.sce b/tests/general_tests/jssp/jssp_machines_type.sce new file mode 100644 index 0000000..af3724f --- /dev/null +++ b/tests/general_tests/jssp/jssp_machines_type.sce @@ -0,0 +1,28 @@ +//Check if 'machines' is of the correct type + +machines = list(3); +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp: Expected type ["constant"] for input argument machines at input #1, but got "list" instead. +//at line 56 of function Checktype called by : +//at line 143 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_outputargs.sce b/tests/general_tests/jssp/jssp_outputargs.sce new file mode 100644 index 0000000..158fd00 --- /dev/null +++ b/tests/general_tests/jssp/jssp_outputargs.sce @@ -0,0 +1,24 @@ +//Check if the number of output arguments is correct/permissible + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + + + +//Error +//!--error 59 +//Wrong number of output arguments. + +[makespan, schedule, status, redundancy] = jssp(machines, jobs, jssp_mode, tasks, []); diff --git a/tests/general_tests/jssp/jssp_startafter_valid.sce b/tests/general_tests/jssp/jssp_startafter_valid.sce new file mode 100644 index 0000000..da93a37 --- /dev/null +++ b/tests/general_tests/jssp/jssp_startafter_valid.sce @@ -0,0 +1,27 @@ +//Check if the index values in the 'start-after' column (column 4) in 'tasks' matrix (only for mode '1'), are valid + +machines = 3; +jobs = 3; + +jssp_mode = 1; + +tasks=[ 1 1 3 -1 -1; + 1 2 2 -1 1; + 1 3 2 -1 -1; + 2 1 2 -1 -1; + 2 3 1 -1 -1; + 2 2 4 -1 -1; + 3 2 4 -100 -1; + 3 3 3 -1 -1; + ]; + +time_limit = []; + + +//Error +// !--error 10000 +//jssp : One or more job-index values in the 'start-after' column ( column 4) in the 'tasks' matrix (argument #4) are invalid. Expected - either '-1' or a value from '1' to '3'. +//at line 340 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_tasks_dims.sce b/tests/general_tests/jssp/jssp_tasks_dims.sce new file mode 100644 index 0000000..1812f52 --- /dev/null +++ b/tests/general_tests/jssp/jssp_tasks_dims.sce @@ -0,0 +1,26 @@ +//Check if the dimensions of the 'tasks' matrix are correct ( Expected - a 3-column matrix for mode '0' and a 5-column matrix for mode '1') + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3 1; + 1 2 2 1; + 1 3 2 1; + 2 1 2 1; + 2 3 1 1; + 2 2 4 1; + 3 2 4 1; + 3 3 3 1; + ]; + +//Error +// !--error 10000 +//jssp : Wrong dimensions for input argument #4( 'tasks'). [8x3] expected. +//at line 209 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); + + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); diff --git a/tests/general_tests/jssp/jssp_tasks_int.sce b/tests/general_tests/jssp/jssp_tasks_int.sce new file mode 100644 index 0000000..a2f4e09 --- /dev/null +++ b/tests/general_tests/jssp/jssp_tasks_int.sce @@ -0,0 +1,27 @@ +//Check if all the values of the adjacency matrix - 'adj_matrix' are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2.01 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = []; + +//Error +// !--error 10000 +//jssp : All the values in the 'tasks' matrix (argument #4) are expected to be integral. +//at line 263 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_tasks_type.sce b/tests/general_tests/jssp/jssp_tasks_type.sce new file mode 100644 index 0000000..125b654 --- /dev/null +++ b/tests/general_tests/jssp/jssp_tasks_type.sce @@ -0,0 +1,28 @@ +//Check if 'tasks' is of the correct type + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=list([ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]); + +time_limit = []; + +//Error +// !--error 10000 +//jssp: Expected type ["constant"] for input argument tasks at input #4, but got "list" instead. +//at line 56 of function Checktype called by : +//at line 146 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_timelimit_dims.sce b/tests/general_tests/jssp/jssp_timelimit_dims.sce new file mode 100644 index 0000000..8d81e72 --- /dev/null +++ b/tests/general_tests/jssp/jssp_timelimit_dims.sce @@ -0,0 +1,26 @@ +//Check if the dimension of 'time_limit' , if provided, are correct (Expected - Singular, integral, positive value) +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = [1 3]; + +//Error +// !--error 10000 +//jssp : Wrong dimensions for input argument #5('time_limit'). Single integral value [1x1] or an empty matrix expected. +//at line 229 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_timelimit_int.sce b/tests/general_tests/jssp/jssp_timelimit_int.sce new file mode 100644 index 0000000..dd2b07d --- /dev/null +++ b/tests/general_tests/jssp/jssp_timelimit_int.sce @@ -0,0 +1,28 @@ +//Check if the value of 'time_limit', if provided, is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = 100.90; + + +//Error +// !--error 10000 +//jssp : Time Limit ( 'time_limit' ; argument #5 ) is expected to be an integral value. +//at line 271 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); +// + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_timelimit_type.sce b/tests/general_tests/jssp/jssp_timelimit_type.sce new file mode 100644 index 0000000..a38a090 --- /dev/null +++ b/tests/general_tests/jssp/jssp_timelimit_type.sce @@ -0,0 +1,30 @@ +//Check if 'time_limit' is of the correct type + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +time_limit = "1000"; + + +//Error +// !--error 10000 +//jssp: Expected type ["constant"] for input argument time_limit at input #5, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 147 of function jssp called by : +//[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); +// + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/jssp/jssp_timelimit_valid.sce b/tests/general_tests/jssp/jssp_timelimit_valid.sce new file mode 100644 index 0000000..5902f5b --- /dev/null +++ b/tests/general_tests/jssp/jssp_timelimit_valid.sce @@ -0,0 +1,29 @@ +//Check if the value of 'time_limit' is valid ( Expected- Positive integral value) + + + +machines = 2; +jobs = 5; +jssp_mode = 0; + +tasks = [1 1 13; + 1 2 3; + 2 1 2; + 2 2 5; + 3 1 1; + 3 2 3; + 4 1 4; + 4 2 6; + 5 1 5; + 5 2 7]; + +time_limit = 0; + + +//Error +// !--error 10000 +//jssp : Invalid value for argument #5 ('time_limit'). A positive, integral value expected. +//at line 298 of function jssp called by : +//[makespan, schedule, status] = jssp (machines, jobs, jssp_mode, tasks, time_limit); + +[makespan, schedule, status] = jssp (machines, jobs, jssp_mode, tasks, time_limit); diff --git a/tests/general_tests/linsum/linsum_t1.sce b/tests/general_tests/linsum/linsum_t1.sce new file mode 100644 index 0000000..29b3cd5 --- /dev/null +++ b/tests/general_tests/linsum/linsum_t1.sce @@ -0,0 +1,6 @@ +// Number of Left Nodes should be > 0. Check input #1 + +kNumLeftNodes = -1; +kNumRightNodes = 4; +kCost = [82, 83, 69, 92; 77, 37, 49, 92; 11, 69, 5, 86; 8, 9, 98, 23]; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); diff --git a/tests/general_tests/linsum/linsum_t2.sce b/tests/general_tests/linsum/linsum_t2.sce new file mode 100644 index 0000000..0383168 --- /dev/null +++ b/tests/general_tests/linsum/linsum_t2.sce @@ -0,0 +1,6 @@ +// Number of Right Nodes should be > 0. Check input #1 + +kNumLeftNodes = 4; +kNumRightNodes = -1; +kCost = [82, 83, 69, 92; 77, 37, 49, 92; 11, 69, 5, 86; 8, 9, 98, 23]; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); diff --git a/tests/general_tests/linsum/linsum_t3.sce b/tests/general_tests/linsum/linsum_t3.sce new file mode 100644 index 0000000..04e8f0e --- /dev/null +++ b/tests/general_tests/linsum/linsum_t3.sce @@ -0,0 +1,6 @@ +// Number of Left Nodes should be EQUAL to Number of Right Nodes + +kNumLeftNodes = 4; +kNumRightNodes = 5; +kCost = [82, 83, 69, 92, 0; 77, 37, 49, 92, 0; 11, 69, 5, 86, 0; 8, 9, 98, 23, 0]; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); diff --git a/tests/general_tests/linsum/linsum_t4.sce b/tests/general_tests/linsum/linsum_t4.sce new file mode 100644 index 0000000..fedf49b --- /dev/null +++ b/tests/general_tests/linsum/linsum_t4.sce @@ -0,0 +1,6 @@ +// Expected type ["constant"] for input argument kNumSources at input #1, but got "string" instead. + +kNumLeftNodes = '4'; +kNumRightNodes = 5; +kCost = [82, 83, 69, 92, 0; 77, 37, 49, 92, 0; 11, 69, 5, 86, 0; 8, 9, 98, 23, 0]; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); diff --git a/tests/general_tests/linsum/linsum_t5.sce b/tests/general_tests/linsum/linsum_t5.sce new file mode 100644 index 0000000..08ae1df --- /dev/null +++ b/tests/general_tests/linsum/linsum_t5.sce @@ -0,0 +1,6 @@ +// Expected type ["constant"] for input argument kNumRightNodes at input #2, but got "string" instead. + +kNumLeftNodes = 4; +kNumRightNodes = '5'; +kCost = [82, 83, 69, 92, 0; 77, 37, 49, 92, 0; 11, 69, 5, 86, 0; 8, 9, 98, 23, 0]; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); diff --git a/tests/general_tests/linsum/linsum_t6.sce b/tests/general_tests/linsum/linsum_t6.sce new file mode 100644 index 0000000..8bd7d79 --- /dev/null +++ b/tests/general_tests/linsum/linsum_t6.sce @@ -0,0 +1,6 @@ +// Expected type ["constant"] for input argument kCost at input #3, but got "string" instead. + +kNumLeftNodes = 4; +kNumRightNodes = 5; +kCost = ['82', '83', '69', '92', '0'; '77', '37', '49', '92', '0'; '11', '69', '5', '86', '0'; '8', '9', '98', '23', '0']; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); diff --git a/tests/general_tests/linsum/linsum_t7.sce b/tests/general_tests/linsum/linsum_t7.sce new file mode 100644 index 0000000..ceea9db --- /dev/null +++ b/tests/general_tests/linsum/linsum_t7.sce @@ -0,0 +1,6 @@ +// Unexpected number of input arguments : 2 provided while the number of expected input arguments should be in the set [3] + +kNumLeftNodes = 4; +kNumRightNodes = 4; +kCost = [82, 83, 69, 92; 77, 37, 49, 92; 11, 69, 5, 86; 8, 9, 98, 23]; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes); // <--- diff --git a/tests/general_tests/linsum/linsum_t8.sce b/tests/general_tests/linsum/linsum_t8.sce new file mode 100644 index 0000000..8951a18 --- /dev/null +++ b/tests/general_tests/linsum/linsum_t8.sce @@ -0,0 +1,6 @@ +// Expected size [4 4] for input argument kCost at input #3, but got [4 3] instead + +kNumLeftNodes = 4; +kNumRightNodes = 4; +kCost = [82, 83, 69; 77, 37, 49; 11, 69, 5; 8, 9, 98]; +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); diff --git a/tests/general_tests/linsum/linsum_t9.sce b/tests/general_tests/linsum/linsum_t9.sce new file mode 100644 index 0000000..2dd8e98 --- /dev/null +++ b/tests/general_tests/linsum/linsum_t9.sce @@ -0,0 +1,6 @@ +// Unexpected number of output arguments : 1 provided while the expected number of output arguments should be in the set [2 3]. + +kNumLeftNodes = 4; +kNumRightNodes = 4; +kCost = [82, 83, 69, 100; 77, 37, 49, 100; 11, 69, 5, 100; 8, 9, 98, 100]; +linsum(kNumLeftNodes, kNumRightNodes, kCost); // <--- diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t1.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t1.sce new file mode 100644 index 0000000..69d26e5 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t1.sce @@ -0,0 +1,9 @@ +// Number of Sources should be > 0. Check input #1 + +kNumSources = -1; +kNumTargets = 4; +kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; +kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t10.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t10.sce new file mode 100644 index 0000000..07b70ee --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t10.sce @@ -0,0 +1,9 @@ +// Expected type ["constant"] for input argument kSupply at input #5, but got "string" instead. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = ['50', '70', '30', '50']; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t11.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t11.sce new file mode 100644 index 0000000..c44f685 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t11.sce @@ -0,0 +1,9 @@ +// Expected type ["constant"] for input argument kDemand at input #6, but got "string" instead. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = ['25', '35', '105', '20', '15']; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t12.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t12.sce new file mode 100644 index 0000000..65cbbc4 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t12.sce @@ -0,0 +1,9 @@ +// Unexpected number of output arguments : 1 provided while the expected number of output arguments should be in the set [2 3]. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); // <--- diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t13.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t13.sce new file mode 100644 index 0000000..5ab2fc3 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t13.sce @@ -0,0 +1,9 @@ +// Expected size [4 5] for input argument kCost at input #3, but got [4 4] instead. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; // <--- +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t14.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t14.sce new file mode 100644 index 0000000..2356b01 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t14.sce @@ -0,0 +1,9 @@ +// Expected size [4 5] for input argument kCapacity at input #4, but got [4 4] instead. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; // <--- +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t15.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t15.sce new file mode 100644 index 0000000..eab0015 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t15.sce @@ -0,0 +1,9 @@ +// Expected size [1 4] for input argument kSupply at input #5, but got [1 3] instead. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t16.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t16.sce new file mode 100644 index 0000000..64d2a60 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t16.sce @@ -0,0 +1,9 @@ +// Expected size [1 5] for input argument kDemand at input #6, but got [1 4] instead. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t17.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t17.sce new file mode 100644 index 0000000..cb8da0f --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t17.sce @@ -0,0 +1,9 @@ +// Unexpected number of input arguments : 4 provided while the number of expected input arguments should be in the set [6]. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t2.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t2.sce new file mode 100644 index 0000000..a6cd6e7 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t2.sce @@ -0,0 +1,9 @@ +// Number of Targets should be > 0. Check input #2 + +kNumSources = 4; +kNumTargets = -1; +kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; +kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t3.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t3.sce new file mode 100644 index 0000000..67607f1 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t3.sce @@ -0,0 +1,9 @@ +// Capacity should be >= 0. Check input #4 + +kNumSources = 4; +kNumTargets = 4; +kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; +kCapacity = [-1, 200, 200, 200; 200, -1, 200, 200; 200, 200, 200, -1; 200, 200, 200, -1]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t4.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t4.sce new file mode 100644 index 0000000..85ee391 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t4.sce @@ -0,0 +1,9 @@ +// Supply should be >= 0. Check input #5 + +kNumSources = 4; +kNumTargets = 4; +kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; +kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; +kSupply = [50, -1, 30, 50]; +kDemand = [25, 35, 105, 20]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t5.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t5.sce new file mode 100644 index 0000000..ff630b6 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t5.sce @@ -0,0 +1,9 @@ +// Demand should be >= 0. Check input #6 + +kNumSources = 4; +kNumTargets = 4; +kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; +kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, -1, 105, 20]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t6.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t6.sce new file mode 100644 index 0000000..38c9aa0 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t6.sce @@ -0,0 +1,9 @@ +// Expected type ["constant"] for input argument kNumSources at input #1, but got "string" instead. + +kNumSources = '4'; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t7.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t7.sce new file mode 100644 index 0000000..73f8ed4 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t7.sce @@ -0,0 +1,9 @@ +// Expected type ["constant"] for input argument kNumTargets at input #2, but got "string" instead. + +kNumSources = 4; +kNumTargets = '5'; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t8.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t8.sce new file mode 100644 index 0000000..65d461c --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t8.sce @@ -0,0 +1,9 @@ +// Expected type ["constant"] for input argument kCost at input #3, but got "string" instead. + +kNumSources = 4; +kNumTargets = 5; +kCost = ['4', '6', '8', '13', '0'; '13', '11', '10', '8', '0'; '14', '4', '10', '13', '0'; '9', '11', '13', '8', '0']; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/min_cost_flow/min_cost_flow_t9.sce b/tests/general_tests/min_cost_flow/min_cost_flow_t9.sce new file mode 100644 index 0000000..c56e208 --- /dev/null +++ b/tests/general_tests/min_cost_flow/min_cost_flow_t9.sce @@ -0,0 +1,9 @@ +// Expected type ["constant"] for input argument kCapacity at input #4, but got "string" instead. + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = ['200', '200', '200', '200', '200'; '200', '200', '200', '200', '200'; '200', '200', '200', '200', '200'; '200', '200', '200', '200', '200']; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); diff --git a/tests/general_tests/tsp/tsp_adj_diag.sce b/tests/general_tests/tsp/tsp_adj_diag.sce new file mode 100644 index 0000000..b595ec4 --- /dev/null +++ b/tests/general_tests/tsp/tsp_adj_diag.sce @@ -0,0 +1,20 @@ +//Check if all the diagonal elements of the given adjacency matrix are '0' +adj = [0 10 15 20; + 10 1 35 25; + 15 35 0 30; + 20 25 30 0;]; + +start_node=1; + +labels=['A' 'B' 'C' 'D']; + + +//Error +//tsp : All leading diagonal elements of the adjacency matrix need to be 0 +//at line 138 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + + +[mincost,path,status]=tsp(adj,start_node,labels); + diff --git a/tests/general_tests/tsp/tsp_adj_dims.sce b/tests/general_tests/tsp/tsp_adj_dims.sce new file mode 100644 index 0000000..596ab11 --- /dev/null +++ b/tests/general_tests/tsp/tsp_adj_dims.sce @@ -0,0 +1,20 @@ +//Check if the dimensions of the adjacency matrix are corrent( [n x n] expected ; n-> number of nodes in the graph) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0; + 13 23 10 10]; + +start_node=1; + +labels=['A' 'B' 'C' 'D']; + +//Error +//tsp : The dimensions of the given adjacency matrix are erroneous [5 x 4]. Number of rows and columns has to be equal(square matrix) ( = no. of nodes in the graph). +//at line 130 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_adj_integral.sce b/tests/general_tests/tsp/tsp_adj_integral.sce new file mode 100644 index 0000000..1b0dd3a --- /dev/null +++ b/tests/general_tests/tsp/tsp_adj_integral.sce @@ -0,0 +1,22 @@ +//Check if all the values of the adjacency matrix are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +adj = [0 10.3 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1; + +labels=['A' 'B' 'C' 'D']; + + +//Error +//tsp : All values in the adjacency matrix ( input argument #1) are expected to be integral +//at line 155 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + +[mincost,path,status]=tsp(adj,start_node,labels); + + + diff --git a/tests/general_tests/tsp/tsp_adj_type.sce b/tests/general_tests/tsp/tsp_adj_type.sce new file mode 100644 index 0000000..5c5bcb4 --- /dev/null +++ b/tests/general_tests/tsp/tsp_adj_type.sce @@ -0,0 +1,20 @@ +// Check if the type of the adj_matrix is correct ("constant" ie. scilab numeric matrix) + +adj = ['0' '10' '15' '20'; + '10' '0' '35' '25'; + '15' '35' '0' '30'; + '20' '25' '30' '0']; + +start_node=1; + +labels=['A' 'B' 'C' 'D']; + + +//Error +//tsp: Expected type ["constant"] for input argument adj_matrix at input #1, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 112 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_input1.sce b/tests/general_tests/tsp/tsp_input1.sce new file mode 100644 index 0000000..d3637a2 --- /dev/null +++ b/tests/general_tests/tsp/tsp_input1.sce @@ -0,0 +1,17 @@ +//Check for the admissible number of input arguments(2-3) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + + +//Error +//tsp : Number of input arguments is expected to be 2 or 3. Found 1. Refer to help/FOT documentation for more details. +//at line 89 of function tsp called by : +//[mincost,path,status]=tsp(adj); + + + +[mincost,path,status]=tsp(adj); + diff --git a/tests/general_tests/tsp/tsp_input2.sce b/tests/general_tests/tsp/tsp_input2.sce new file mode 100644 index 0000000..03bb258 --- /dev/null +++ b/tests/general_tests/tsp/tsp_input2.sce @@ -0,0 +1,19 @@ +//Check for the admissible number of input arguments(2-3) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1; + +labels=['A' 'B' 'C' 'D']; + +//Error +//tsp : Number of input arguments is expected to be 2 or 3. Found 4. Refer to help/FOT documentation for more details. +//at line 89 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels,1); + + + +[mincost,path,status]=tsp(adj,start_node,labels,1); diff --git a/tests/general_tests/tsp/tsp_labels_dims1.sce b/tests/general_tests/tsp/tsp_labels_dims1.sce new file mode 100644 index 0000000..b1b84d7 --- /dev/null +++ b/tests/general_tests/tsp/tsp_labels_dims1.sce @@ -0,0 +1,22 @@ +//Check if the dimensions of the 'labels' vector are correct ( [1xn] expected ; n->no. of nodes in the given graph) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1; + +labels=['A' 'B' 'C' 'D' 'E']; + + +//Error +//tsp : The number of elements 'labels' vector (input argument #3) must be equal to the number of nodes in the graph.(found 5) +//at line 187 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + + + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_labels_dims2.sce b/tests/general_tests/tsp/tsp_labels_dims2.sce new file mode 100644 index 0000000..6b0ab8c --- /dev/null +++ b/tests/general_tests/tsp/tsp_labels_dims2.sce @@ -0,0 +1,21 @@ +//Check if the dimensions of the 'labels' vector are correct ( [1xn] expected ; n->no. of nodes in the given graph) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1; + +labels=['A' 'B' 'C' 'D'; + 'E' 'F' 'G' 'H' ]; + + + +//Error +//tsp : The 'labels' matrix (input argument #3) must have only one row, ie., it must be vector +//at line 187 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_labels_dims3.sce b/tests/general_tests/tsp/tsp_labels_dims3.sce new file mode 100644 index 0000000..7a7833b --- /dev/null +++ b/tests/general_tests/tsp/tsp_labels_dims3.sce @@ -0,0 +1,21 @@ +//Check if the dimensions of the 'labels' vector are correct ( [1xn] expected ; n->no. of nodes in the given graph) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=5; + +labels=['A' 'B' 'C' 'D' 'X'; + 'E' 'F' 'G' 'H' 'Y']; + + +//Error +//tsp : Invalid 'start node' index (5). It is expected to be between '1' and '4'(no. of nodes in the given graph). +//at line 169 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_labels_type.sce b/tests/general_tests/tsp/tsp_labels_type.sce new file mode 100644 index 0000000..497a96f --- /dev/null +++ b/tests/general_tests/tsp/tsp_labels_type.sce @@ -0,0 +1,20 @@ +//Check if the type of the 'labels' vector is correct ( "string" i.e. scilab string matrix) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1; + +labels=[1 2 3 4]; + + +//Error +//tsp: Expected type ["string"] for input argument labels at input #3, but got "constant" instead. +//at line 56 of function Checktype called by : +//at line 116 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_labels_unique.sce b/tests/general_tests/tsp/tsp_labels_unique.sce new file mode 100644 index 0000000..9783c70 --- /dev/null +++ b/tests/general_tests/tsp/tsp_labels_unique.sce @@ -0,0 +1,19 @@ +//Check if all the values in the 'labels' vector are unique ( 2 nodes of the graph cannot have the same label) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1; + +labels=['A' 'B' 'C' 'B']; + +//Error +//tsp : The entries in the 'label' matrix should be unique ( no 2 nodes can have the same label) +//at line 195 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_output1.sce b/tests/general_tests/tsp/tsp_output1.sce new file mode 100644 index 0000000..5849aef --- /dev/null +++ b/tests/general_tests/tsp/tsp_output1.sce @@ -0,0 +1,19 @@ +//Check for the admissible number of output parameters( 2 or 3) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1; + +labels=['A' 'B' 'C' 'D']; + + +//Error +//tsp : Number of output arguments is expected to be to 2 or 3. Found 1. Refer to the help/FOT documentation for more details. +//at line 96 of function tsp called by : +//[mincost]=tsp(adj,start_node,labels); + + +[mincost]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_output2.sce b/tests/general_tests/tsp/tsp_output2.sce new file mode 100644 index 0000000..f37a58a --- /dev/null +++ b/tests/general_tests/tsp/tsp_output2.sce @@ -0,0 +1,18 @@ +//Check for the admissible number of output parameters( 2 or 3) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1; + +labels=['A' 'B' 'C' 'D']; + +//Error +//Wrong number of output arguments. + + + + +[mincost,path,status,xx]=tsp(adj,start_node,labels,1); diff --git a/tests/general_tests/tsp/tsp_startnode_integral.sce b/tests/general_tests/tsp/tsp_startnode_integral.sce new file mode 100644 index 0000000..e009b19 --- /dev/null +++ b/tests/general_tests/tsp/tsp_startnode_integral.sce @@ -0,0 +1,21 @@ +//Check if the value of the start node index isintegral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=1.9; + +labels=['A' 'B' 'C' 'D']; + + +//Error +//tsp : The start_node index ( input argument #2) is expected to be integral +//at line 160 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + +[mincost,path,status]=tsp(adj,start_node,labels); + + diff --git a/tests/general_tests/tsp/tsp_startnode_type.sce b/tests/general_tests/tsp/tsp_startnode_type.sce new file mode 100644 index 0000000..7e0b647 --- /dev/null +++ b/tests/general_tests/tsp/tsp_startnode_type.sce @@ -0,0 +1,21 @@ +//Check if the type of the 'start_node' is correct("constant" ie. scilab numeric matrix) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node='1'; + +labels=['A' 'B' 'C' 'D']; + +//Error +//tsp: Expected type ["constant"] for input argument start_node at input #2, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 113 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_startnode_valid.sce b/tests/general_tests/tsp/tsp_startnode_valid.sce new file mode 100644 index 0000000..218c4a1 --- /dev/null +++ b/tests/general_tests/tsp/tsp_startnode_valid.sce @@ -0,0 +1,20 @@ +//Check if the value of the start node index is valid ( can only be from 1 to 'n' ; n-> no. of nodes in the graph) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=5; + +labels=['A' 'B' 'C' 'D']; + + +//Error +//tsp : Invalid 'start node' index (5). It is expected to be between '1' and '4'(no. of nodes in the given graph). +//at line 169 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/tsp/tsp_startnodes_dims.sce b/tests/general_tests/tsp/tsp_startnodes_dims.sce new file mode 100644 index 0000000..d2c0791 --- /dev/null +++ b/tests/general_tests/tsp/tsp_startnodes_dims.sce @@ -0,0 +1,19 @@ +//Check if the dimensions of the 'start_node' argument are correct(singular numeric value expected) + +adj = [0 10 15 20; + 10 0 35 25; + 15 35 0 30; + 20 25 30 0]; + +start_node=[1 2]; + +labels=['A' 'B' 'C' 'D']; + +//Error +//tsp : Invalid start_node index value. Singlular value indicating the index of the node from where the journey is to begin expected +//at line 145 of function tsp called by : +//[mincost,path,status]=tsp(adj,start_node,labels); + + + +[mincost,path,status]=tsp(adj,start_node,labels); diff --git a/tests/general_tests/vrp/vrp_adj_dim.sce b/tests/general_tests/vrp/vrp_adj_dim.sce new file mode 100644 index 0000000..b0bfbda --- /dev/null +++ b/tests/general_tests/vrp/vrp_adj_dim.sce @@ -0,0 +1,59 @@ +//Check if the dimensions of the adjacency matrix are correct + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; + + + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); +// !--error 10000 +//vrp : The dimensions of the given adjacency matrix 'adj_matrix' (argument #1) are erroneous [33 32]. Number of rows and columns are to be equal (square matrix) (=no. of nodes of the graph). +//at line 320 of function vrp called by : +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + diff --git a/tests/general_tests/vrp/vrp_adj_int.sce b/tests/general_tests/vrp/vrp_adj_int.sce new file mode 100644 index 0000000..ce48185 --- /dev/null +++ b/tests/general_tests/vrp/vrp_adj_int.sce @@ -0,0 +1,60 @@ +//Check if all the values of the adjacency matrix - 'adj_matrix' are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +adj_matrix = [0, 2451.2, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +//!--error 10000 +//vrp : All values in argument #1 ('adj_matrix') are expected to be integral. +//at line 559 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_adj_type.sce b/tests/general_tests/vrp/vrp_adj_type.sce new file mode 100644 index 0000000..4a0587a --- /dev/null +++ b/tests/general_tests/vrp/vrp_adj_type.sce @@ -0,0 +1,60 @@ +//Check if the Adjacency Matrix 'adj_matrix' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error + +//vrp: Expected type ["constant"] for input argument adj_matrix at input #1, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 287 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_adjdiagonal_zero.sce b/tests/general_tests/vrp/vrp_adjdiagonal_zero.sce new file mode 100644 index 0000000..95dea33 --- /dev/null +++ b/tests/general_tests/vrp/vrp_adjdiagonal_zero.sce @@ -0,0 +1,60 @@ +//Check if all the elements in the leading diagonal of the given adjacency matrix 'adj_matrix are zeroes. + +adj_matrix = [1111111111, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//tsp : All leading diagonal elements of the adjacency matrix need to be 0 +//at line 656 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_demand_lt_vehiclecapacity.sce b/tests/general_tests/vrp/vrp_demand_lt_vehiclecapacity.sce new file mode 100644 index 0000000..21d7f08 --- /dev/null +++ b/tests/general_tests/vrp/vrp_demand_lt_vehiclecapacity.sce @@ -0,0 +1,74 @@ +//Check if the demand value of no node is greater than the total capacity of a single vehicle in the fleet( The problem would be inherently ifeasible otherwise) + + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 67956345346 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + + +//Error +//vrp : The demand values for one or more nodes exceed the maximum capacity for the vehicles in question, rendering them unserviceable. +//at line 742 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_demands_dim.sce b/tests/general_tests/vrp/vrp_demands_dim.sce new file mode 100644 index 0000000..a9c051d --- /dev/null +++ b/tests/general_tests/vrp/vrp_demands_dim.sce @@ -0,0 +1,56 @@ +//Check if the dimensions of the 'demands' matrix are correct (Expected- Empty matrix or [1xn]; n->No. of nodes) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14]; + +labels = []; + +max_vehicle_capacity = 100; + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); +// !--error 10000 +//vrp : Wrong dimensions for the input argument #5 ('demands'). Expected to be either an empty matrix or one with dimensions [1x32]. +//at line 366 of function vrp called by : +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + diff --git a/tests/general_tests/vrp/vrp_demands_int.sce b/tests/general_tests/vrp/vrp_demands_int.sce new file mode 100644 index 0000000..16a7a58 --- /dev/null +++ b/tests/general_tests/vrp/vrp_demands_int.sce @@ -0,0 +1,61 @@ +//Check if the value in the argument 'demands' are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21.50, 6, 19, 7, 12, 16, 6, 16, 8, 14.90, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : All values in argument #5 ('demands') are expected to be integral. +//at line 578 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_demands_nonnegative.sce b/tests/general_tests/vrp/vrp_demands_nonnegative.sce new file mode 100644 index 0000000..3f8c7ba --- /dev/null +++ b/tests/general_tests/vrp/vrp_demands_nonnegative.sce @@ -0,0 +1,72 @@ +//Check if all the demand value in the 'demands' vector(in case of a capacitated VRP), are non-negative. + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 -10 18 19 1 24 8 -10 4 8 -24 24 2 20 -15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : One or more values in the 'demands' vector are negative. +//at line 735 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_demands_type.sce b/tests/general_tests/vrp/vrp_demands_type.sce new file mode 100644 index 0000000..3ded33c --- /dev/null +++ b/tests/general_tests/vrp/vrp_demands_type.sce @@ -0,0 +1,61 @@ +//Check if the argument 'demands' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = ['0', '19', '21', '6', '19', '7', '12', '16', '6', '16', '8', '14', '21' ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument demands at input #5, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 298 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_depotdemand_zero.sce b/tests/general_tests/vrp/vrp_depotdemand_zero.sce new file mode 100644 index 0000000..62ef623 --- /dev/null +++ b/tests/general_tests/vrp/vrp_depotdemand_zero.sce @@ -0,0 +1,72 @@ +//Check if the demand(s) of the depot node(s) is(are) zero(Depot nodes cannot logically have any demands). + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [50 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The demand for the depot node has to be zero. +//at line 747 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_fuelcapacity_dim.sce b/tests/general_tests/vrp/vrp_fuelcapacity_dim.sce new file mode 100644 index 0000000..cdfcbf5 --- /dev/null +++ b/tests/general_tests/vrp/vrp_fuelcapacity_dim.sce @@ -0,0 +1,61 @@ +//Check if the dimensions of 'fuel_capacity' are correct (Expected - Single integral value expected; cannot be empty matrix is refuel_flag =1) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +speeds = []; +refuel_flag = 1; +fuel_capacity = [100; 200]; + + +//Error +// !--error 10000 +//vrp : Wrong dimensions for the input argument #12 ('fuel_capacity'). Expected a singular integral value. +//at line 467 of function vrp called by : +//, time_windows, speeds, [], refuel_flag, fuel_capacity,[]) + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds, [], refuel_flag, fuel_capacity,[]); + + diff --git a/tests/general_tests/vrp/vrp_fuelcapacity_int.sce b/tests/general_tests/vrp/vrp_fuelcapacity_int.sce new file mode 100644 index 0000000..a20d229 --- /dev/null +++ b/tests/general_tests/vrp/vrp_fuelcapacity_int.sce @@ -0,0 +1,59 @@ +//Check if the value of the argument 'fuel_capacity' in integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 1; + +fuel_capacity = 100.4; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The fuel capacity value for the vehicles (argument #12) is expected to be integral. +//at line 616 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_fuelcapacity_positive.sce b/tests/general_tests/vrp/vrp_fuelcapacity_positive.sce new file mode 100644 index 0000000..c9c9dce --- /dev/null +++ b/tests/general_tests/vrp/vrp_fuelcapacity_positive.sce @@ -0,0 +1,75 @@ +//Check if the 'fuel_capacity' value is positive, if fuel constraints are to be considered. + + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 1; +fuel_capacity = -343; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : Fuel Capacity value is expected to be positive. +//at line 911 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_fuelcapacity_specified.sce b/tests/general_tests/vrp/vrp_fuelcapacity_specified.sce new file mode 100644 index 0000000..b19da70 --- /dev/null +++ b/tests/general_tests/vrp/vrp_fuelcapacity_specified.sce @@ -0,0 +1,72 @@ +//Check if the fuel capacity value for the vehicle('fuel_capacity') is positive, if refuelling constraints are included(ie. refuel_flag = 1) + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 1; +fuel_capacity = 0; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : Fuel Capacity value is expected to be positive. +//at line 906 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_fuelcapacity_type.sce b/tests/general_tests/vrp/vrp_fuelcapacity_type.sce new file mode 100644 index 0000000..ec03877 --- /dev/null +++ b/tests/general_tests/vrp/vrp_fuelcapacity_type.sce @@ -0,0 +1,60 @@ +//Check if the argument 'fuel_capacity' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = "500"; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument fuel_capacity at input #12, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 305 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_grouppenalty_dim.sci b/tests/general_tests/vrp/vrp_grouppenalty_dim.sci new file mode 100644 index 0000000..835e31e --- /dev/null +++ b/tests/general_tests/vrp/vrp_grouppenalty_dim.sci @@ -0,0 +1,64 @@ +//Check if the dimensions of the 'group_penalty' are correct (Expected - Single integral value or empty matrix) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +speeds = []; +penalty =[]; +refuel_flag = 0; + +groups = [1 2 3 4]; + +group_penalty = [10 20]; + +//Error +//!--error 10000 +//vrp : Wrong dimensions for the input argument #16 ('group_penalty'). Expected a singular integral value or an empty matrix. +//at line 528 of function vrp called by : +// speeds,[],refuel_flag,[],[],penalty,groups,group_penalty) + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,[],refuel_flag,[],[],penalty,groups,group_penalty); + + diff --git a/tests/general_tests/vrp/vrp_grouppenalty_int.sce b/tests/general_tests/vrp/vrp_grouppenalty_int.sce new file mode 100644 index 0000000..89a7853 --- /dev/null +++ b/tests/general_tests/vrp/vrp_grouppenalty_int.sce @@ -0,0 +1,61 @@ +//Check if the value of the argument 'group_penalty' in integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = 50.555; + +time_limit = []; + + +//Error +//vrp : The group-penalty value (argument #16) is exected to be integral. +//at line 636 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_grouppenalty_nonnegative_or_minus1.sce b/tests/general_tests/vrp/vrp_grouppenalty_nonnegative_or_minus1.sce new file mode 100644 index 0000000..a93dc37 --- /dev/null +++ b/tests/general_tests/vrp/vrp_grouppenalty_nonnegative_or_minus1.sce @@ -0,0 +1,73 @@ +//Check if the group penalty value, if provided, non-negative or -1 + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = [1 2 3 4]; + +group_penalty = -465; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : Forbidden value for 'group_penalty' (argument #16). Expected- -1, 0, or any positive value. +//at line 1019 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_grouppenalty_type.sce b/tests/general_tests/vrp/vrp_grouppenalty_type.sce new file mode 100644 index 0000000..c2df485 --- /dev/null +++ b/tests/general_tests/vrp/vrp_grouppenalty_type.sce @@ -0,0 +1,60 @@ +//Check if the argument 'group_penalty' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = '20'; + +time_limit = []; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument group_penalty at input #16, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 309 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_groups_int.sce b/tests/general_tests/vrp/vrp_groups_int.sce new file mode 100644 index 0000000..8b8e008 --- /dev/null +++ b/tests/general_tests/vrp/vrp_groups_int.sce @@ -0,0 +1,60 @@ +//Check if the value in the argument 'groups' are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = [1.2 3 4 5]; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : All values in argument #15 ('groups') are expected to be integral. +//at line 631 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_groups_norepeat.sce b/tests/general_tests/vrp/vrp_groups_norepeat.sce new file mode 100644 index 0000000..fc28f28 --- /dev/null +++ b/tests/general_tests/vrp/vrp_groups_norepeat.sce @@ -0,0 +1,60 @@ +//Check if no node in the 'groups' matrix is repeated. + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = [ 1 2 1]; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : One or more node index values in the 'groups' matrix (argument #15) are repeated. No index can occur twice in a group. Also, no node can be a part of 2 groups. +//at line 1025 of function vrp called by : +//refuel_nodes, penalty, groups, group_penalty, time_limit) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_groups_type.sce b/tests/general_tests/vrp/vrp_groups_type.sce new file mode 100644 index 0000000..e9ee21a --- /dev/null +++ b/tests/general_tests/vrp/vrp_groups_type.sce @@ -0,0 +1,60 @@ +//Check if the argument 'groups' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = ['3', '5' ,'6'; '1','2','0']; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument groups at input #15, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 308 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_groupsindices_valid.sce b/tests/general_tests/vrp/vrp_groupsindices_valid.sce new file mode 100644 index 0000000..7497b47 --- /dev/null +++ b/tests/general_tests/vrp/vrp_groupsindices_valid.sce @@ -0,0 +1,76 @@ +//Check if all the node indices in the 'groups' matrix, if provided, are valid. + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = [1 2 3 54 6]; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : One or more node index values in argument #15 ( 'groups') is invalid. Valid indices for this model - '1' to '32'. +//at line 969 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// +// + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_labels_dim.sce b/tests/general_tests/vrp/vrp_labels_dim.sce new file mode 100644 index 0000000..22193b4 --- /dev/null +++ b/tests/general_tests/vrp/vrp_labels_dim.sce @@ -0,0 +1,58 @@ +//Checking is the dimensions of the 'labels' matrix, IF PROVIDED, are indeed correct ( Expected - [1xn], if provided, otherwise empty matrix; n-> No. of nodes in the graph) + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = ['A']; + +max_vehicle_capacity = 100; + + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); +// !--error 10000 +//vrp : Wrong dimensions for the input argument #4 ( 'labels'). Expected to be an empty matrix or one with dimensions [1x32]. +//at line 379 of function vrp called by : +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + diff --git a/tests/general_tests/vrp/vrp_labels_type.sce b/tests/general_tests/vrp/vrp_labels_type.sce new file mode 100644 index 0000000..68a408d --- /dev/null +++ b/tests/general_tests/vrp/vrp_labels_type.sce @@ -0,0 +1,62 @@ +//Check if the argument 'labels' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = [1 2 3 4 5 67 8 9 10 11 12 13]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp: Expected type ["string"] for input argument labels at input #4, but got "constant" instead. +//at line 56 of function Checktype called by : +//at line 297 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_maxvehiclecapacity_dim.sce b/tests/general_tests/vrp/vrp_maxvehiclecapacity_dim.sce new file mode 100644 index 0000000..d57f079 --- /dev/null +++ b/tests/general_tests/vrp/vrp_maxvehiclecapacity_dim.sce @@ -0,0 +1,56 @@ +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = [ 100 10]; + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); +// !--error 10000 +//vrp : Wrong dimensions for the input argument #6 ( 'max_vehicle_capacity'). Expected to be either an empty matrix or a singular integral value[1x1]. +//at line 394 of function vrp called by : +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + diff --git a/tests/general_tests/vrp/vrp_maxvehiclecapacity_int.sce b/tests/general_tests/vrp/vrp_maxvehiclecapacity_int.sce new file mode 100644 index 0000000..0fdcb02 --- /dev/null +++ b/tests/general_tests/vrp/vrp_maxvehiclecapacity_int.sce @@ -0,0 +1,60 @@ +//Check if the value of the argument 'max_vehicle_capacity' is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60.5; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : Max Vehicle Capacity value (argument #6) is expected to be integral. +//at line 584 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_maxvehiclecapacity_positive.sce b/tests/general_tests/vrp/vrp_maxvehiclecapacity_positive.sce new file mode 100644 index 0000000..653ac63 --- /dev/null +++ b/tests/general_tests/vrp/vrp_maxvehiclecapacity_positive.sce @@ -0,0 +1,73 @@ +//Check if the value of 'max_vehicle_capacity'(in case of capacitated VRP), is (>0) + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = -1; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The maximum-vehicle-capacity value needs to be positive. +//at line 715 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_maxvehiclecapacity_type.sce b/tests/general_tests/vrp/vrp_maxvehiclecapacity_type.sce new file mode 100644 index 0000000..f9142c2 --- /dev/null +++ b/tests/general_tests/vrp/vrp_maxvehiclecapacity_type.sce @@ -0,0 +1,61 @@ +//Check if the argument 'max_vehicle_capacity' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = "A"; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument max_vehicle_capacity at input #6, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 299 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_penalty_dim.sce b/tests/general_tests/vrp/vrp_penalty_dim.sce new file mode 100644 index 0000000..20c2811 --- /dev/null +++ b/tests/general_tests/vrp/vrp_penalty_dim.sce @@ -0,0 +1,60 @@ +//Check if the dimensions of the 'penalty' matrix are correct(Expected - Empty or a 2-column matrix) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +speeds = []; +refuel_flag = 0; +penalty = [1 2 3; 4 5 6]; + +//Error +// !--error 10000 +//vrp : Wrong dimensions for the input argument #14 ('penalty'). Expected an [Ax2] matrix (A->number of skippable nodes) or an empty matrix. +//at line 506 of function vrp called by : +//emand, time_windows, speeds,[], refuel_flag,[],[],penalty) + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,[], refuel_flag,[],[],penalty); + + diff --git a/tests/general_tests/vrp/vrp_penalty_int.sce b/tests/general_tests/vrp/vrp_penalty_int.sce new file mode 100644 index 0000000..3a90196 --- /dev/null +++ b/tests/general_tests/vrp/vrp_penalty_int.sce @@ -0,0 +1,62 @@ +//Check if the values of the argument 'penalty' are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = [1 5.5; + 2 10.5; + 3 4.0]; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : All values in argument #14 ('penalty') are expected to be integral. +//at line 626 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_penalty_nodepot.sce b/tests/general_tests/vrp/vrp_penalty_nodepot.sce new file mode 100644 index 0000000..b1e25cb --- /dev/null +++ b/tests/general_tests/vrp/vrp_penalty_nodepot.sce @@ -0,0 +1,59 @@ +//Check if no 'depot' nodes or 'start/end' nodes are listed as optional(penalty) nodes. + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = [1 100]; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The depot cannot be provided as an optional node. +//at line 980 of function vrp called by : +//refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_penalty_nonnegative.sce b/tests/general_tests/vrp/vrp_penalty_nonnegative.sce new file mode 100644 index 0000000..1929472 --- /dev/null +++ b/tests/general_tests/vrp/vrp_penalty_nonnegative.sce @@ -0,0 +1,60 @@ +//Check if all the penalty values ( 2nd column in the 'penalty' matrix) are non-negative + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = [10 5; 9 -1]; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : Cost penalty values in the 'penalty' matrix (argument #14) cannot be negative. +//at line 972 of function vrp called by : +//refuel_nodes, penalty, groups, group_penalty, time_limit) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_penalty_type.sce b/tests/general_tests/vrp/vrp_penalty_type.sce new file mode 100644 index 0000000..fdcb123 --- /dev/null +++ b/tests/general_tests/vrp/vrp_penalty_type.sce @@ -0,0 +1,59 @@ +//Check if the argument 'penalty' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = [list(4,100)]; +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument penalty at input #14, but got "list" instead. +//at line 56 of function Checktype called by : +//at line 307 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_penaltyindices_valid.sce b/tests/general_tests/vrp/vrp_penaltyindices_valid.sce new file mode 100644 index 0000000..45b6cd5 --- /dev/null +++ b/tests/general_tests/vrp/vrp_penaltyindices_valid.sce @@ -0,0 +1,74 @@ +//Check if the node indices in the 'penalty' matrix(first column), if provided, are valid node indices. + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = [2 100; 33 500]; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : One or more node indices provided in the 'penalty' matrix ( argument #14) are invalid. Valid indices for the current model- '1' to '32'. +//at line 934 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_refuelflag_dim.sce b/tests/general_tests/vrp/vrp_refuelflag_dim.sce new file mode 100644 index 0000000..de323ef --- /dev/null +++ b/tests/general_tests/vrp/vrp_refuelflag_dim.sce @@ -0,0 +1,61 @@ +//Check if the dimensions of 'refuel_flag' are correct(Expected - Single 0/1 value or empty matrix expectex) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +speeds = []; +refuel_flag = [1 2]; + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,[],refuel_flag,[],[]); +// !--error 10000 +//vrp : Wrong dimensions for the input argument #11 ('refuel_flag'). Expected either a singular 0/1 value or an empty matrix. +//at line 456 of function vrp called by : +//ime_per_demand, time_windows, speeds,[],refuel_flag,[],[]) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,[],refuel_flag,[],[]); + + diff --git a/tests/general_tests/vrp/vrp_refuelflag_int.sce b/tests/general_tests/vrp/vrp_refuelflag_int.sce new file mode 100644 index 0000000..cfb6a04 --- /dev/null +++ b/tests/general_tests/vrp/vrp_refuelflag_int.sce @@ -0,0 +1,59 @@ +//Check if the value of the argument 'refuel_flag' is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 1.1; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The Refuel Flag value (argument #11) is expected to be integral. +//at line 611 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_refuelflag_type.sce b/tests/general_tests/vrp/vrp_refuelflag_type.sce new file mode 100644 index 0000000..cf453fe --- /dev/null +++ b/tests/general_tests/vrp/vrp_refuelflag_type.sce @@ -0,0 +1,61 @@ +//Check if the argument 'refuel_flag' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = %F; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +//!--error 10000 +//vrp: Expected type ["constant"] for input argument refuel_flag at input #11, but got "boolean" instead. +//at line 56 of function Checktype called by : +//at line 304 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_refuelflag_valid.sce b/tests/general_tests/vrp/vrp_refuelflag_valid.sce new file mode 100644 index 0000000..d73d215 --- /dev/null +++ b/tests/general_tests/vrp/vrp_refuelflag_valid.sce @@ -0,0 +1,60 @@ +//Checking if the value of the refuel_flag, if specified), is valid ( only '0' or '1' allowed) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 500; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : The refuel flag can only take the value '0' or '1'. Check the FOT documentation for details. +//at line 890 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_refuelnodes_dim.sce b/tests/general_tests/vrp/vrp_refuelnodes_dim.sce new file mode 100644 index 0000000..976c427 --- /dev/null +++ b/tests/general_tests/vrp/vrp_refuelnodes_dim.sce @@ -0,0 +1,63 @@ +//Check if the dimensions of the vector - 'refuel_nodes' are correct (Expected - An empty matrix/vector or a row-vector) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +speeds = []; +refuel_flag = 1; +fuel_capacity = 100; + +refuel_nodes = [1 ;2; 4]; + + +//Error +// !--error 10000 +//vrp : Wrong dimensions for the input argument #13 ('refuel_nodes'). Expected a vector or an empty matrix. +//at line 480 of function vrp called by : +//dows, speeds, [], refuel_flag, fuel_capacity,refuel_nodes) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds, [], refuel_flag, fuel_capacity,refuel_nodes); diff --git a/tests/general_tests/vrp/vrp_refuelnodes_int.sce b/tests/general_tests/vrp/vrp_refuelnodes_int.sce new file mode 100644 index 0000000..88dc07d --- /dev/null +++ b/tests/general_tests/vrp/vrp_refuelnodes_int.sce @@ -0,0 +1,58 @@ +//Check if the value(s) in the argument 'refuel_nodes' is(are) integral( x.0 is considered INTEGRAL; any other fractional part throws an error) +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 1; + +fuel_capacity = 100; + +refuel_nodes = [1.1, 2, 3 ,4]; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : All values in argument #13 ('refuel_nodes') are expected to be integral. +//at line 621 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_refuelnodes_type.sce b/tests/general_tests/vrp/vrp_refuelnodes_type.sce new file mode 100644 index 0000000..ab427e6 --- /dev/null +++ b/tests/general_tests/vrp/vrp_refuelnodes_type.sce @@ -0,0 +1,60 @@ +//Check if the argument 'refuel_nodes' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = list(1 , 2); + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument refuel_nodes at input #13, but got "list" instead. +//at line 56 of function Checktype called by : +//at line 306 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_refuelnodes_valid.sce b/tests/general_tests/vrp/vrp_refuelnodes_valid.sce new file mode 100644 index 0000000..914335c --- /dev/null +++ b/tests/general_tests/vrp/vrp_refuelnodes_valid.sce @@ -0,0 +1,60 @@ +//Check if the values are refuel_nodes ( if fuel constraints are considered), are valid node indices. + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 1; + +fuel_capacity = 200; + +refuel_nodes = [1 14]; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +//vrp : One or more fuel node index values are invalid. Valid indices for the current model - '1' to '13'. +//at line 921 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_servicetime_dim.sce b/tests/general_tests/vrp/vrp_servicetime_dim.sce new file mode 100644 index 0000000..f1c133b --- /dev/null +++ b/tests/general_tests/vrp/vrp_servicetime_dim.sce @@ -0,0 +1,58 @@ +//Checking if the dimensions of 'service_time_per_demand' are correct (Expected - Empty matrix or integral value) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; + +service_time_per_demand= [1 2]; + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand); +// !--error 10000 +//vrp : Wrong dimensions for the input argument #7 ('service_time_per_demand'). Expected to be either an empty matrix or a singular integral value[1x1]. +//at line 408 of function vrp called by : +//s, demands, max_vehicle_capacity, service_time_per_demand) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand); + + diff --git a/tests/general_tests/vrp/vrp_servicetime_gtzero.sce b/tests/general_tests/vrp/vrp_servicetime_gtzero.sce new file mode 100644 index 0000000..7f78865 --- /dev/null +++ b/tests/general_tests/vrp/vrp_servicetime_gtzero.sce @@ -0,0 +1,74 @@ +//Check if the value of the argument 'service_time_per_demand', if provided, is greater than zero. + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = -123; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The value for argument #7 ('service_time_per_demand') cannot be negative. +//at line 789 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_servicetime_int.sce b/tests/general_tests/vrp/vrp_servicetime_int.sce new file mode 100644 index 0000000..a5eefd2 --- /dev/null +++ b/tests/general_tests/vrp/vrp_servicetime_int.sce @@ -0,0 +1,62 @@ +//Check if the value of the argument 'service_time_per_demand' is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=1.45654; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : The value for servive-time-per-demand (argument #7) is expected to be integral. +//at line 589 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_servicetime_type.sce b/tests/general_tests/vrp/vrp_servicetime_type.sce new file mode 100644 index 0000000..2904fdc --- /dev/null +++ b/tests/general_tests/vrp/vrp_servicetime_type.sce @@ -0,0 +1,61 @@ +//Check if the argument 'service_time_per_demand' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand= poly(0,"s"); + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument service_time_per_demand at input #7, but got "polynomial" instead. +//at line 56 of function Checktype called by : +//at line 300 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_speeds_dim.sce b/tests/general_tests/vrp/vrp_speeds_dim.sce new file mode 100644 index 0000000..5724fb4 --- /dev/null +++ b/tests/general_tests/vrp/vrp_speeds_dim.sce @@ -0,0 +1,97 @@ +//Checking if the dimensions of the 'speed' matrix are correct (Expected - Empty matrix, a single integral value or an [nxn] matrix) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; + +service_time_per_demand = []; +time_windows =[]; + +speeds =[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ; +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ]; // 33x32 matrix + + + + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds); +// !--error 10000 +//vrp : Wrong dimensions for the input argument #9 ( 'speeds'). Expected to be either [1x1], [32x32] or an empty matrix. +//at line 433 of function vrp called by : +//e_capacity, service_time_per_demand, time_windows, speeds) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds); + + diff --git a/tests/general_tests/vrp/vrp_speeds_int.sce b/tests/general_tests/vrp/vrp_speeds_int.sce new file mode 100644 index 0000000..10c1086 --- /dev/null +++ b/tests/general_tests/vrp/vrp_speeds_int.sce @@ -0,0 +1,61 @@ +//Check if the values in the argument 'speeds' are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = 100.666667; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The value(s) for argument #9 ('speeds') is (are) expected to be integral. +//at line 600 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_speeds_positive.sce b/tests/general_tests/vrp/vrp_speeds_positive.sce new file mode 100644 index 0000000..007bf0f --- /dev/null +++ b/tests/general_tests/vrp/vrp_speeds_positive.sce @@ -0,0 +1,73 @@ +//Checking if the value(s) in the 'speeds' matrix is (are) positive. + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = 0; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The avg.speeds value thus provided must be POSITIVE. +//at line 842 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_speeds_type.sce b/tests/general_tests/vrp/vrp_speeds_type.sce new file mode 100644 index 0000000..f374951 --- /dev/null +++ b/tests/general_tests/vrp/vrp_speeds_type.sce @@ -0,0 +1,62 @@ +//Check if the argument 'speeds' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = list(10,"VIE"); + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument speeds at input #9, but got "list" instead. +//at line 56 of function Checktype called by : +//at line 302 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_start_dim.sce b/tests/general_tests/vrp/vrp_start_dim.sce new file mode 100644 index 0000000..4823af8 --- /dev/null +++ b/tests/general_tests/vrp/vrp_start_dim.sce @@ -0,0 +1,58 @@ +//Check if the dimensions of 'start' matrix are valid ( Expected - Empty Matrix, [1x1] or [vxv]; where v= no. of variables/routes + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = [1 2 4]; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; + + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); +// !--error 10000 +//vrp : Wrong dimensions for input argument #3 ('start'). Expected to be either [1x1], (empty matrix) or [vx2] ( v->number of vehicles). Refer to help/FOT Documentation for more details. +//at line 353 of function vrp called by : +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + diff --git a/tests/general_tests/vrp/vrp_start_int.sce b/tests/general_tests/vrp/vrp_start_int.sce new file mode 100644 index 0000000..161b103 --- /dev/null +++ b/tests/general_tests/vrp/vrp_start_int.sce @@ -0,0 +1,59 @@ +//Check if the value(s) of the argument 'start' (if note an empty matrix), is(are) integral ( x.0 is considered INTEGRAL; any other fractional part throws an error) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1.3; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +//vrp : The value(s) for argument #3 ( 'start') is (are) expected to be integral. +//at line 572 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_start_type.sce b/tests/general_tests/vrp/vrp_start_type.sce new file mode 100644 index 0000000..0730be0 --- /dev/null +++ b/tests/general_tests/vrp/vrp_start_type.sce @@ -0,0 +1,62 @@ +//Check if the argument 'start' is of the correct types + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = "1"; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +//-->[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); +// !--error 10000 +//vrp: Expected type ["constant"] for input argument start at input #3, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 293 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_startnode_valid.sce b/tests/general_tests/vrp/vrp_startnode_valid.sce new file mode 100644 index 0000000..b7f9e9e --- /dev/null +++ b/tests/general_tests/vrp/vrp_startnode_valid.sce @@ -0,0 +1,73 @@ +//Check if the value of the start-node is a valid node index for the problem. + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 33; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The given 'start' value is not a valid node index. Indices can only go from '1' to '32' for the given problem +//at line 677 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_timelimit_dim.sce b/tests/general_tests/vrp/vrp_timelimit_dim.sce new file mode 100644 index 0000000..3afebe9 --- /dev/null +++ b/tests/general_tests/vrp/vrp_timelimit_dim.sce @@ -0,0 +1,71 @@ +//Check if the dimensions of 'time_limit' are correct( Expected- Single integral value or empty matrix) + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = [1000 2000]; + +//Error +// !--error 10000 +//vrp : Wrong dimensions for the input argument #17 ('time_limit'). Expected a singular, integral, positive value. +//at line 539 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag,fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_timelimit_int.sce b/tests/general_tests/vrp/vrp_timelimit_int.sce new file mode 100644 index 0000000..3ab22bc --- /dev/null +++ b/tests/general_tests/vrp/vrp_timelimit_int.sce @@ -0,0 +1,61 @@ +//Check if the value of the argument 'time_limit' is integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = 1200.70; + +//Error +// !--error 10000 +//vrp : The time limit values (argument #17) is expected to be integral. +//at line 641 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_timelimit_positive.sce b/tests/general_tests/vrp/vrp_timelimit_positive.sce new file mode 100644 index 0000000..9ddb78f --- /dev/null +++ b/tests/general_tests/vrp/vrp_timelimit_positive.sce @@ -0,0 +1,74 @@ +// Check if the value of the 'time_limit', if given, is positive + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = 0; + +//Error +// !--error 10000 +//vrp : Positive value expected for the 'time_limit' (argument #17). +//at line 1031 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_timelimit_type.sce b/tests/general_tests/vrp/vrp_timelimit_type.sce new file mode 100644 index 0000000..3dfc776 --- /dev/null +++ b/tests/general_tests/vrp/vrp_timelimit_type.sce @@ -0,0 +1,60 @@ +//Check if the argument 'time_limit' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = %T; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument time_limit at input #17, but got "boolean" instead. +//at line 56 of function Checktype called by : +//at line 310 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_timewindows_dim.sce b/tests/general_tests/vrp/vrp_timewindows_dim.sce new file mode 100644 index 0000000..3b19bd2 --- /dev/null +++ b/tests/general_tests/vrp/vrp_timewindows_dim.sce @@ -0,0 +1,65 @@ +//Checking if the dimensions of the 'time_windows' matrix are correct (Expected - Empty matrix or [nx2]; n->no. of nodes) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; + + +service_time_per_demand = []; + +time_windows = [ 1 2 3; + 5 2 5]; + + + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows); +// !--error 10000 +//vrp : Wrong dimensions for the input argument #8 ('time_windows'). Expected to be either an empty matrix or one with dimensions [32x2]. +//at line 420 of function vrp called by : +//x_vehicle_capacity, service_time_per_demand, time_windows) + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows); + + diff --git a/tests/general_tests/vrp/vrp_timewindows_ends_gt_starts.sce b/tests/general_tests/vrp/vrp_timewindows_ends_gt_starts.sce new file mode 100644 index 0000000..e9aee17 --- /dev/null +++ b/tests/general_tests/vrp/vrp_timewindows_ends_gt_starts.sce @@ -0,0 +1,69 @@ +//Check if all the end-time(unless '-1' indicating "no upper bound") are greater than or equal to the corresponding start times. + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = [0 100; +0 100; +0 100; +0 100; +0 100; +100 99; +0 100; +0 100; +0 100; +0 100; +0 100; +0 100; +0 100]; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : Invalid time-window values : The end-time for service window for one or more nodes in less than the corresponding start-time. +//at line 819 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + diff --git a/tests/general_tests/vrp/vrp_timewindows_int.sce b/tests/general_tests/vrp/vrp_timewindows_int.sce new file mode 100644 index 0000000..685aeb9 --- /dev/null +++ b/tests/general_tests/vrp/vrp_timewindows_int.sce @@ -0,0 +1,72 @@ +//Check if the values of the argument 'time_windows' are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = [0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5 + 0.5 2.5]; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : All values in argument #8 ('time_windows') are expected to be integral. +//at line 594 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_timewindows_nonnegative_or_minus1.sce b/tests/general_tests/vrp/vrp_timewindows_nonnegative_or_minus1.sce new file mode 100644 index 0000000..1ea8070 --- /dev/null +++ b/tests/general_tests/vrp/vrp_timewindows_nonnegative_or_minus1.sce @@ -0,0 +1,73 @@ +//Check if all the values in 'time_windows' matrix are non-negative( except '1' for end-times indicating no upper bounds) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = [0 100; +0 100; +0 100; +0 100; +0 100; +-1 100; +0 100; +0 100; +0 100; +0 100; +0 100; +0 100; +0 100]; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : Values in 'time_windows' matrix cannot be negative (except '-1' for end times indicating no upper bound for the corresponding node). +//at line 811 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + + diff --git a/tests/general_tests/vrp/vrp_timewindows_type.sce b/tests/general_tests/vrp/vrp_timewindows_type.sce new file mode 100644 index 0000000..7ecde73 --- /dev/null +++ b/tests/general_tests/vrp/vrp_timewindows_type.sce @@ -0,0 +1,72 @@ +//Check if the argument 'time_windows' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = ['0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0' +'0' '0']; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument time_windows at input #8, but got "string" instead. +//at line 56 of function Checktype called by : +//at line 301 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_totaldemands_lt_totalcapacity.sce b/tests/general_tests/vrp/vrp_totaldemands_lt_totalcapacity.sce new file mode 100644 index 0000000..0bde93f --- /dev/null +++ b/tests/general_tests/vrp/vrp_totaldemands_lt_totalcapacity.sce @@ -0,0 +1,75 @@ +//Checking if the total demands accross all the nodes is less than the total capacity the vehicle fleet( the problem would be inherently infeasible otherwise, allowing us to circumvent invoking the solver, at all) + + + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 99 8 99 99 16 3 22 99 99 99 94 98 92 94 98 94 94 92 90 95 92 94 99]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +//vrp : The total demand exceeds the total capacity of the vehicles in the fleet. The scenario is inherently unserviceable. +//at line 749 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) +// + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_uniquelabels.sce b/tests/general_tests/vrp/vrp_uniquelabels.sce new file mode 100644 index 0000000..6b71b7e --- /dev/null +++ b/tests/general_tests/vrp/vrp_uniquelabels.sce @@ -0,0 +1,59 @@ +//Check if the the strings in 'labels' are unique (2 nodes cannot have the same label) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "New York", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : The entries in the 'label' matrix need to be unique (no 2 nodes can have the same labels). +//at line 685 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_vehiclecapacity_if_capacitated.sce b/tests/general_tests/vrp/vrp_vehiclecapacity_if_capacitated.sce new file mode 100644 index 0000000..e7dd74b --- /dev/null +++ b/tests/general_tests/vrp/vrp_vehiclecapacity_if_capacitated.sce @@ -0,0 +1,75 @@ +//Checking if the maximum_vehicle_capacity is specified if it's a Capacitated Vehicle Routing Problem(demands are given) + + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = []; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : For a capacitate VRP, the max_vehicle_capacity cannot be exclude(cannot be an empty matrix). +//at line 703 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_vehicles_dim.sce b/tests/general_tests/vrp/vrp_vehicles_dim.sce new file mode 100644 index 0000000..4e7e43c --- /dev/null +++ b/tests/general_tests/vrp/vrp_vehicles_dim.sce @@ -0,0 +1,58 @@ +//Check if the dimensions of the 'vehicles' argument are correct ( single integral value [1x1] expected) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = [5 2]; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; + + + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); +// !--error 10000 +//vrp : Wrong dimensions [1x2] for input argument #2 ( 'vehicles'). Single integral value expected (ie. [1x1]). +//at line 336 of function vrp called by : +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity); + + diff --git a/tests/general_tests/vrp/vrp_vehicles_int.sce b/tests/general_tests/vrp/vrp_vehicles_int.sce new file mode 100644 index 0000000..cfab932 --- /dev/null +++ b/tests/general_tests/vrp/vrp_vehicles_int.sce @@ -0,0 +1,60 @@ +//Check if value of the argument 'vehicles' is integral ( x.0 is considered INTEGRAL; any other fractional part throws an error) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3.5; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error +// !--error 10000 +//vrp : Number of vehicles ( argument #2) is expected to be an integral value. +//at line 566 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_vehicles_positive.sce b/tests/general_tests/vrp/vrp_vehicles_positive.sce new file mode 100644 index 0000000..1e1230b --- /dev/null +++ b/tests/general_tests/vrp/vrp_vehicles_positive.sce @@ -0,0 +1,74 @@ +//Check if the value of the argument 'vehicles' is positive + + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 0; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +waiting_times =[]; +speeds = []; +refuel_flag = 0; +fuel_capacity = []; +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + + +//Error + +// !--error 10000 +//vrp : The number of vehicles in the fleet must be a positive value. +//at line 667 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + diff --git a/tests/general_tests/vrp/vrp_vehicles_type.sce b/tests/general_tests/vrp/vrp_vehicles_type.sce new file mode 100644 index 0000000..be9d2a9 --- /dev/null +++ b/tests/general_tests/vrp/vrp_vehicles_type.sce @@ -0,0 +1,61 @@ +//Check if 'vehicles' is of the correct type + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = %T; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = []; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp: Expected type ["constant"] for input argument vehicles at input #2, but got "boolean" instead. +//at line 56 of function Checktype called by : +//at line 292 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_waitingtimes_dim.sce b/tests/general_tests/vrp/vrp_waitingtimes_dim.sce new file mode 100644 index 0000000..63676ad --- /dev/null +++ b/tests/general_tests/vrp/vrp_waitingtimes_dim.sce @@ -0,0 +1,64 @@ +//Check if the dimensions of 'waiting_times' matrix are correct (Expected -> empty matrix or [1xn]; n->No. of nodes) + +adj_matrix = [0 46 103 101 138 66 70 39 120 107 85 143 40 53 38 92 31 83 107 84 49 78 111 107 35 94 23 32 120 68 19 87 ; + 46 0 85 83 120 112 52 17 102 89 131 125 10 31 50 116 15 47 89 44 95 32 93 89 53 140 27 64 102 102 27 41 ; + 103 85 0 4 39 105 33 68 55 72 124 50 95 54 65 109 84 44 58 45 88 57 82 12 68 133 80 71 37 95 90 48 ; + 101 83 4 0 37 101 31 66 51 68 120 46 93 52 63 105 82 48 54 49 86 55 78 8 66 129 78 69 33 91 88 52 ; + 138 120 39 37 0 98 68 103 18 33 85 11 130 89 100 70 119 83 31 84 123 92 43 31 103 94 115 106 18 70 125 87 ; + 66 112 105 101 98 0 88 105 80 67 33 103 106 119 62 52 97 149 67 150 25 144 71 93 59 28 85 48 80 28 85 153 ; + 70 52 33 31 68 88 0 35 50 55 107 73 62 31 32 92 51 61 41 62 71 56 65 37 35 116 47 40 50 78 57 65 ; + 39 17 68 66 103 105 35 0 85 72 124 108 27 14 43 109 16 44 72 45 88 39 82 72 46 133 20 57 85 95 22 48 ; + 120 102 55 51 18 80 50 85 0 17 69 23 112 71 82 54 101 99 13 100 105 94 27 43 85 78 97 88 18 52 107 103 ; + 107 89 72 68 33 67 55 72 17 0 52 36 99 86 69 37 88 116 14 117 92 111 10 60 72 61 84 75 35 39 94 120 ; + 85 131 124 120 85 33 107 124 69 52 0 74 125 138 81 19 116 168 66 169 58 163 42 112 78 21 104 67 87 29 104 172 ; + 143 125 50 46 11 103 73 108 23 36 74 0 135 94 105 59 124 94 36 95 128 97 32 38 108 91 120 111 23 75 130 98 ; + 40 10 95 93 130 106 62 27 112 99 125 135 0 41 44 110 11 57 99 54 89 38 103 99 47 134 21 58 112 96 21 47 ; + 53 31 54 52 89 119 31 14 71 86 138 94 41 0 57 123 30 30 72 31 102 25 96 58 60 147 34 71 71 109 36 34 ; + 38 50 65 63 100 62 32 43 82 69 81 105 44 57 0 66 35 87 69 88 45 82 73 69 3 90 23 14 82 52 25 91 ; + 92 116 109 105 70 52 92 109 54 37 19 59 110 123 66 0 101 153 51 154 77 148 27 97 63 40 89 60 72 24 89 157 ; + 31 15 84 82 119 97 51 16 101 88 116 124 11 30 35 101 0 52 88 53 80 47 92 88 38 125 12 49 101 87 12 56 ; + 83 47 44 48 83 149 61 44 99 116 168 94 57 30 87 153 52 0 102 3 132 19 126 56 90 177 64 101 81 139 64 10 ; + 107 89 58 54 31 67 41 72 13 14 66 36 99 72 69 51 88 102 0 103 92 97 24 46 72 75 84 75 21 39 94 106 ; + 84 44 45 49 84 150 62 45 100 117 169 95 54 31 88 154 53 3 103 0 133 16 127 57 91 178 65 102 82 140 65 7 ; + 49 95 88 86 123 25 71 88 105 92 58 128 89 102 45 77 80 132 92 133 0 127 96 92 42 45 68 31 105 53 68 136 ; + 78 32 57 55 92 144 56 39 94 111 163 97 38 25 82 148 47 19 97 16 127 0 121 61 85 172 59 96 76 134 59 9 ; + 111 93 82 78 43 71 65 82 27 10 42 32 103 96 73 27 92 126 24 127 96 121 0 70 76 59 88 79 45 43 98 130 ; + 107 89 12 8 31 93 37 72 43 60 112 38 99 58 69 97 88 56 46 57 92 61 70 0 72 121 84 75 25 83 94 60 ; + 35 53 68 66 103 59 35 46 85 72 78 108 47 60 3 63 38 90 72 91 42 85 76 72 0 87 26 11 85 49 26 94 ; + 94 140 133 129 94 28 116 133 78 61 21 91 134 147 90 40 125 177 75 178 45 172 59 121 87 0 113 76 96 38 113 181 ; + 23 27 80 78 115 85 47 20 97 84 104 120 21 34 23 89 12 64 84 65 68 59 88 84 26 113 0 37 97 75 10 68 ; + 32 64 71 69 106 48 40 57 88 75 67 111 58 71 14 60 49 101 75 102 31 96 79 75 11 76 37 0 88 38 37 105 ; + 120 102 37 33 18 80 50 85 18 35 87 23 112 71 82 72 101 81 21 82 105 76 45 25 85 96 97 88 0 58 107 85 ; + 68 102 95 91 70 28 78 95 52 39 29 75 96 109 52 24 87 139 39 140 53 134 43 83 49 38 75 38 58 0 75 143 ; + 19 27 90 88 125 85 57 22 107 94 104 130 21 36 25 89 12 64 94 65 68 59 98 94 26 113 10 37 107 75 0 68 ; + 87 41 48 52 87 153 65 48 103 120 172 98 47 34 91 157 56 10 106 7 136 9 130 60 94 181 68 105 85 143 68 0 ]; + +vehicles = 5; +start = 1; + + +demands = [0 19 21 6 19 7 12 16 6 16 8 14 21 16 3 22 18 19 1 24 8 12 4 8 24 24 2 20 15 2 14 9]; + +labels = []; + +max_vehicle_capacity = 100; +service_time_per_demand = []; +time_windows =[]; + +speeds = []; + +waiting_times = [1 2 3 4 6 7 6 7]; + + + +//Error +//[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows,speeds, ); +// !--error 10000 +//vrp : Wrong dimensions for the input argument #10 ('waiting_times'). Expected to be either an empty matrix or one with dimensions [1x32]. +//at line 444 of function vrp called by : +//_capacity, service_time_per_demand, time_windows,speeds, ) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows,speeds,waiting_times ); + + diff --git a/tests/general_tests/vrp/vrp_waitingtimes_int.sce b/tests/general_tests/vrp/vrp_waitingtimes_int.sce new file mode 100644 index 0000000..470aa73 --- /dev/null +++ b/tests/general_tests/vrp/vrp_waitingtimes_int.sce @@ -0,0 +1,60 @@ +//Check if the values in the argument 'waiting_times' are integral( x.0 is considered INTEGRAL; any other fractional part throws an error) + + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = [0,20,20,60.0,20.7,20.5,20.1,20,20,20,20,20,20]; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : Wrong dimensions for the input argument #10 ('waiting_times'). Expected to be either an empty matrix or one with dimensions [1x13]. +//at line 449 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_waitingtimes_nonnegative.sce b/tests/general_tests/vrp/vrp_waitingtimes_nonnegative.sce new file mode 100644 index 0000000..0621b6a --- /dev/null +++ b/tests/general_tests/vrp/vrp_waitingtimes_nonnegative.sce @@ -0,0 +1,59 @@ +//Check if all the values in the argument 'waiting_times' non-negative. + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = [5,5,5,5,5,5,5,5,5,5,5,5,-8]; + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +// !--error 10000 +//vrp : Waiting time values cannot be negative. +//at line 880 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/general_tests/vrp/vrp_waitingtimes_type.sce b/tests/general_tests/vrp/vrp_waitingtimes_type.sce new file mode 100644 index 0000000..5bb578f --- /dev/null +++ b/tests/general_tests/vrp/vrp_waitingtimes_type.sce @@ -0,0 +1,59 @@ +//Check if the argument 'waiting_times' is of the correct type + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972; + 2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579; + 713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260; + 1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987; + 1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371; + 1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999; + 2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701; + 213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099; + 2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600; + 875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162; + 1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200; + 2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504; + 1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas", "Seattle", "Boston", "San Francisco", "St. Louis", "Houston", "Phoenix", "Salt Lake City"]; + +start = 1; + +vehicles = 3; + +demands = [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21 ]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + +time_windows = []; + +speeds = []; + +waiting_times = list( 10,10,10,10,10,10,10,10,10,10,10,10,10); + +refuel_flag = 0; + +fuel_capacity = []; + +refuel_nodes = []; + +penalty = []; + +groups = []; + +group_penalty = []; + +time_limit = []; + +//Error +//vrp: Expected type ["constant"] for input argument waiting_times at input #10, but got "list" instead. +//at line 56 of function Checktype called by : +//at line 303 of function vrp called by : +// refuel_nodes, penalty, groups, group_penalty, time_limit) + + +[total_distance, routes ] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand, time_windows, speeds,waiting_times,refuel_flag, fuel_capacity, refuel_nodes, penalty, groups, group_penalty, time_limit); + + + diff --git a/tests/unit_tests/fmaxflow.dia.ref b/tests/unit_tests/fmaxflow.dia.ref new file mode 100644 index 0000000..ccbb80a --- /dev/null +++ b/tests/unit_tests/fmaxflow.dia.ref @@ -0,0 +1,78 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end +//endfunction +//A simple max-flow problem(has optimal solution). Ref : https://developers.google.com/optimization/flow/maxflow +//Defining the graph(3 vectors) +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]; +//Specifying the source and target nodes for the max-flow solution +st=[0, 4]; +//calling the scilab routine +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); +Max flow = 60 +Arc Flow Capacity +0->1 20 20 +0->2 30 30 +0->3 10 10 +1->2 0 40 +1->4 20 30 +2->3 10 10 +2->4 20 20 +3->2 0 5 +3->4 20 20 + +An optimal solution was found +assert_checkequal(maxflow,int32(60)); +assert_checkequal(arcflows,int32([20 30 10 0 20 10 20 0 20])); +assert_checkequal(status,int32(0)); +printf("\nTest Successful!\n"); + +Test Successful! diff --git a/tests/unit_tests/fmaxflow.tst b/tests/unit_tests/fmaxflow.tst new file mode 100644 index 0000000..ffcd00c --- /dev/null +++ b/tests/unit_tests/fmaxflow.tst @@ -0,0 +1,73 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt + +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> + + +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end +//endfunction + +//A simple max-flow problem(has optimal solution). Ref : https://developers.google.com/optimization/flow/maxflow + +//Defining the graph(3 vectors) +start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]; +end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]; +capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]; + +//Specifying the source and target nodes for the max-flow solution +st=[0, 4]; + + +//calling the scilab routine +[maxflow,arcflows,status]=fmaxflow(start_nodes,end_nodes,capacities,st); + +assert_checkequal(maxflow,int32(60)); +assert_checkequal(arcflows,int32([20 30 10 0 20 10 20 0 20])); +assert_checkequal(status,int32(0)); +printf("\nTest Successful!\n"); + diff --git a/tests/unit_tests/fshortestpath.dia.ref b/tests/unit_tests/fshortestpath.dia.ref new file mode 100644 index 0000000..853ccf5 --- /dev/null +++ b/tests/unit_tests/fshortestpath.dia.ref @@ -0,0 +1,69 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end +//endfunction +//A simple shortest-path example. Refer to the documentation for more details on the same example. +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; +st=[0,3]; +//Calling the routine +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st); + +Shortest path from start-node:0 to end-node:3 is : +0 -> 1 -> 2 -> 3 +Minumum cost (using the said path) :- 22.000000 + + Shortest/Lowest Cost Path found. +assert_checkequal(mincost,[22]); +assert_checkequal(shortestpath,int32([0 1 2 3])); +assert_checkequal(flag,int32(1)); +printf("\nTest Successful!\n"); + +Test Successful! diff --git a/tests/unit_tests/fshortestpath.tst b/tests/unit_tests/fshortestpath.tst new file mode 100644 index 0000000..520ce05 --- /dev/null +++ b/tests/unit_tests/fshortestpath.tst @@ -0,0 +1,68 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt + +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> + + +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end +//endfunction + +//A simple shortest-path example. Refer to the documentation for more details on the same example. + +start_nodes=[ 0 0 1 1 2 4 5 4]; +end_nodes= [ 1 5 2 5 3 3 4 2]; +weights=[10 8 5 2 7 10 10 8]; +st=[0,3]; + +//Calling the routine +[mincost,shortestpath,flag]=fshortestpath(start_nodes,end_nodes,weights,st); + +assert_checkequal(mincost,[22]); +assert_checkequal(shortestpath,int32([0 1 2 3])); +assert_checkequal(flag,int32(1)); +printf("\nTest Successful!\n"); diff --git a/tests/unit_tests/jssp.dia.ref b/tests/unit_tests/jssp.dia.ref new file mode 100644 index 0000000..a7fb2dc --- /dev/null +++ b/tests/unit_tests/jssp.dia.ref @@ -0,0 +1,78 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end +//endfunction +//A simple Job-Shop Scheduling problem(has optimal solution) +machines = 3; +jobs = 3; +jssp_mode = 0; +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); +Optimal Solution Found! +Optimal Makespan : 11 +Optimal Schedule(machine-wise) :- +machine_0: Job- 1, Task- 1[0, 3] Job- 2, Task- 1[3, 5] +machine_1: Job- 3, Task- 1[0, 4] Job- 1, Task- 2[4, 6] Job- 2, Task- 3[6, 10] +machine_2: Job- 2, Task- 2[5, 6] Job- 1, Task- 3[6, 8] Job- 3, Task- 2[8, 11] + +assert_checkequal(makespan,int32(11)); +assert_checkequal(schedule,int32([1 1 3 0 3;1 2 2 4 6;1 3 2 6 8;2 1 2 3 5;2 3 1 5 6;2 2 4 6 10;3 2 4 0 4;3 3 3 8 11])); +assert_checkequal(status,int32(0)); +printf("\nTest Successful!\n"); + +Test Successful! diff --git a/tests/unit_tests/jssp.tst b/tests/unit_tests/jssp.tst new file mode 100644 index 0000000..8781cab --- /dev/null +++ b/tests/unit_tests/jssp.tst @@ -0,0 +1,81 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt + +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> + + +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end +//endfunction + +//A simple Job-Shop Scheduling problem(has optimal solution) + +machines = 3; +jobs = 3; + +jssp_mode = 0; + +tasks=[ 1 1 3; + 1 2 2; + 1 3 2; + 2 1 2; + 2 3 1; + 2 2 4; + 3 2 4; + 3 3 3; + ]; + + +[makespan, schedule, status] = jssp(machines, jobs, jssp_mode, tasks, []); + + + +assert_checkequal(makespan,int32(11)); +assert_checkequal(schedule,int32([1 1 3 0 3;1 2 2 4 6;1 3 2 6 8;2 1 2 3 5;2 3 1 5 6;2 2 4 6 10;3 2 4 0 4;3 3 3 8 11])); +assert_checkequal(status,int32(0)); +printf("\nTest Successful!\n"); + diff --git a/tests/unit_tests/linsum.dia.ref b/tests/unit_tests/linsum.dia.ref new file mode 100644 index 0000000..9f29f1b --- /dev/null +++ b/tests/unit_tests/linsum.dia.ref @@ -0,0 +1,65 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Souvik Das +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end +//endfunction +//A simple linear sum test problem +// Ref : http://www.hungarianalgorithm.com/examplehungarianalgorithm.php +kNumLeftNodes = 4; +kNumRightNodes = 4; +kCost = [82, 83, 69, 92; 77, 37, 49, 92; 11, 69, 5, 86; 8, 9, 98, 23]; +//Calling the routine +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); + +Optimal Solution Found. +assert_checkequal(cost,[140]); +assert_checkequal(assignment,[%F %F %T %F;%F %T %F %F;%T %F %F %F;%F %F %F %T]); +assert_checkequal(status,[1]); +printf("\nTest Successful!\n"); + +Test Successful! diff --git a/tests/unit_tests/linsum.tst b/tests/unit_tests/linsum.tst new file mode 100644 index 0000000..a33e0ad --- /dev/null +++ b/tests/unit_tests/linsum.tst @@ -0,0 +1,69 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Souvik Das +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt + +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> + + +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end +//endfunction + + +//A simple linear sum test problem +// Ref : http://www.hungarianalgorithm.com/examplehungarianalgorithm.php + +kNumLeftNodes = 4; +kNumRightNodes = 4; +kCost = [82, 83, 69, 92; 77, 37, 49, 92; 11, 69, 5, 86; 8, 9, 98, 23]; + +//Calling the routine +[cost, assignment, status] = linsum(kNumLeftNodes, kNumRightNodes, kCost); + +assert_checkequal(cost,[140]); +assert_checkequal(assignment,[%F %F %T %F;%F %T %F %F;%T %F %F %F;%F %F %F %T]); +assert_checkequal(status,[1]); +printf("\nTest Successful!\n"); \ No newline at end of file diff --git a/tests/unit_tests/min_cost_flow.dia.ref b/tests/unit_tests/min_cost_flow.dia.ref new file mode 100644 index 0000000..a0844cb --- /dev/null +++ b/tests/unit_tests/min_cost_flow.dia.ref @@ -0,0 +1,78 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Souvik Das +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end +//endfunction +//A simple min-cost-flow example +// Before balancing (Infeasible): +// kNumSources = 4; +// kNumTargets = 4; +// kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; +// kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; +// kSupply = [50, 70, 30, 50]; +// kDemand = [25, 35, 105, 20]; +// [cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); +// After balancing (Optimal): +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); + +Optimal Solution Found. +assert_checkequal(cost,[1465]); //We can check for equality rather than 'close' as cost is supposed to be integral(as specified by the typedef in Google OR tools) +assert_checkequal(flow,[25 0 25 0 0; + 0 0 70 0 0; + 0 30 0 0 0; + 0 5 10 20 15]); +assert_checkequal(status,[1]); +printf("\nTest Successful!\n"); + +Test Successful! diff --git a/tests/unit_tests/min_cost_flow.tst b/tests/unit_tests/min_cost_flow.tst new file mode 100644 index 0000000..6556f81 --- /dev/null +++ b/tests/unit_tests/min_cost_flow.tst @@ -0,0 +1,85 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Souvik Das +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt + +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> + + +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end +//endfunction + + +//A simple min-cost-flow example + +// Before balancing (Infeasible): +// kNumSources = 4; +// kNumTargets = 4; +// kCost = [4, 6, 8, 13; 13, 11, 10, 8; 14, 4, 10, 13; 9, 11, 13, 8]; +// kCapacity = [200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200; 200, 200, 200, 200]; +// kSupply = [50, 70, 30, 50]; +// kDemand = [25, 35, 105, 20]; +// [cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); + +// After balancing (Optimal): + + +kNumSources = 4; +kNumTargets = 5; +kCost = [4, 6, 8, 13, 0; 13, 11, 10, 8, 0; 14, 4, 10, 13, 0; 9, 11, 13, 8, 0]; +kCapacity = [200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200; 200, 200, 200, 200, 200]; +kSupply = [50, 70, 30, 50]; +kDemand = [25, 35, 105, 20, 15]; +[cost, flow, status] = min_cost_flow(kNumSources, kNumTargets, kCost, kCapacity, kSupply, kDemand); + + +assert_checkequal(cost,[1465]); //We can check for equality rather than 'close' as cost is supposed to be integral(as specified by the typedef in Google OR tools) +assert_checkequal(flow,[25 0 25 0 0; + 0 0 70 0 0; + 0 30 0 0 0; + 0 5 10 20 15]); +assert_checkequal(status,[1]); +printf("\nTest Successful!\n"); diff --git a/tests/unit_tests/tsp.dia.ref b/tests/unit_tests/tsp.dia.ref new file mode 100644 index 0000000..b44751c --- /dev/null +++ b/tests/unit_tests/tsp.dia.ref @@ -0,0 +1,70 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end +//endfunction +//A simple Travelling Saleman Problem Example(optimal solution exists). Refer to the documentation of the function for more details on the same example +//defining the adjacency matrix +adj=[0 10 15 20; +10 0 35 25; +15 35 0 30; +20 25 30 0]; +//specifying the start node +start_node=1; +labels=['A' 'B' 'C' 'D']; +//calling the routine +[mincost,path,status]=tsp(adj,start_node,labels); + + 'ROUTING_SUCCESS' ; An optimal solution was found +Minimum cost -> 80 + +Optimal Path :- + A (1) -> B (2) -> D (4) -> C (3) ->A (1)assert_checkequal(mincost,int32[80]); + + +exec('SCI/etc/scilab.quit',-1);quit; diff --git a/tests/unit_tests/tsp.tst b/tests/unit_tests/tsp.tst new file mode 100644 index 0000000..cc924be --- /dev/null +++ b/tests/unit_tests/tsp.tst @@ -0,0 +1,78 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt + +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> + + +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end +//endfunction + + +//A simple Travelling Saleman Problem Example(optimal solution exists). Refer to the documentation of the function for more details on the same example + +//defining the adjacency matrix +adj=[0 10 15 20; +10 0 35 25; +15 35 0 30; +20 25 30 0]; + +//specifying the start node +start_node=1; + +labels=['A' 'B' 'C' 'D']; + +//calling the routine +[mincost,path,status]=tsp(adj,start_node,labels); + + +assert_checkequal(mincost,int32[80]); +assert_checkequal(path,int32[1 2 4 3 1]); +assert_checkequal(status,int32[1]); +printf("\n Test Successful!\n"); + + diff --git a/tests/unit_tests/vrp.dia.ref b/tests/unit_tests/vrp.dia.ref new file mode 100644 index 0000000..a7e2758 --- /dev/null +++ b/tests/unit_tests/vrp.dia.ref @@ -0,0 +1,78 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then bugmes();quit;end +//endfunction + +//A simple Vehicle-Routing Problem(with optimal solution) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, + 2451, 0, 1745, 1524, 831, 1240; + 713, 1745, 0, 355, 920, 803; + 1018, 1524, 355, 0, 700, 862; + 1631, 831, 920, 700, 0, 663; + 1374, 1240, 803, 862, 663, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas"]; + +start = 1; + +vehicles = 2; + +demands = [0, 19, 21, 6, 19, 7]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + + + +[total_distance, routes,distances, total_time, times, status] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand); + + +exec('SCI/etc/scilab.quit',-1);quit; diff --git a/tests/unit_tests/vrp.tst b/tests/unit_tests/vrp.tst new file mode 100644 index 0000000..1d065aa --- /dev/null +++ b/tests/unit_tests/vrp.tst @@ -0,0 +1,90 @@ +// Copyright (C) 2017 - IIT Bombay - FOSSEE +// +// Author: Samuel Wilson +// Organization: FOSSEE, IIT Bombay +// Email: harpreet.mertia@gmail.com +// +// This file must be used under the terms of the CeCILL. +// This source file is licensed as described in the file COPYING, which +// you should have received as part of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt + +// <-- JVM NOT MANDATORY --> +// <-- ENGLISH IMPOSED --> +// <-- NO CHECK REF --> +// <-- NO CHECK ERROR OUTPUT --> + +// +// assert_close -- +// Returns 1 if the two real matrices computed and expected are close, +// i.e. if the relative distance between computed and expected is lesser than epsilon. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +function flag = assert_close ( computed, expected, epsilon ) + if expected==0.0 then + shift = norm(computed-expected); + else + shift = norm(computed-expected)/norm(expected); + end +// if shift < epsilon then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end + flag = assert_checktrue ( shift < epsilon ); +endfunction +// +// assert_equal -- +// Returns 1 if the two real matrices computed and expected are equal. +// Arguments +// computed, expected : the two matrices to compare +// epsilon : a small number +// +//function flag = assert_equal ( computed , expected ) +// if computed==expected then +// flag = 1; +// else +// flag = 0; +// end +// if flag <> 1 then pause,end +//endfunction + + +//A simple Vehicle-Routing Problem(with optimal solution) + +adj_matrix = [0, 2451, 713, 1018, 1631, 1374, + 2451, 0, 1745, 1524, 831, 1240; + 713, 1745, 0, 355, 920, 803; + 1018, 1524, 355, 0, 700, 862; + 1631, 831, 920, 700, 0, 663; + 1374, 1240, 803, 862, 663, 0]; + +labels = ["New York", "Los Angeles", "Chicago", "Minneapolis", "Denver", "Dallas"]; + +start = 1; + +vehicles = 2; + +demands = [0, 19, 21, 6, 19, 7]; + +service_time_per_demand=3; + +max_vehicle_capacity = 60; + + + +[total_distance, routes,distances, total_time, times, status] = vrp( adj_matrix, vehicles, start, labels, demands, max_vehicle_capacity, service_time_per_demand); + + +assert_checkequal(total_distance, int32(6589)); +assert_checkequal(routes,int32([1 3 1 0 0 0; 1 6 2 5 4 1)); +assert_checkequal(distances, int32([1426 5163])); +assert_checkequal(total_time, int32([216])); +assert_checkequal(times, int32([63 153])); +assert_checkequal(status, int32([1])); +printf("\nTest Successful!\n"); + diff --git a/thirdparty/.gitignore b/thirdparty/.gitignore new file mode 100644 index 0000000..f9be8df --- /dev/null +++ b/thirdparty/.gitignore @@ -0,0 +1 @@ +!* diff --git a/thirdparty/linux/include/boost/assert.hpp b/thirdparty/linux/include/boost/assert.hpp new file mode 100644 index 0000000..9650d7a --- /dev/null +++ b/thirdparty/linux/include/boost/assert.hpp @@ -0,0 +1,85 @@ +// +// boost/assert.hpp - BOOST_ASSERT(expr) +// BOOST_ASSERT_MSG(expr, msg) +// BOOST_VERIFY(expr) +// BOOST_VERIFY_MSG(expr, msg) +// BOOST_ASSERT_IS_VOID +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2007, 2014 Peter Dimov +// Copyright (c) Beman Dawes 2011 +// Copyright (c) 2015 Ion Gaztanaga +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// Note: There are no include guards. This is intentional. +// +// See http://www.boost.org/libs/assert/assert.html for documentation. +// + +// +// Stop inspect complaining about use of 'assert': +// +// boostinspect:naassert_macro +// + +// +// BOOST_ASSERT, BOOST_ASSERT_MSG, BOOST_ASSERT_IS_VOID +// + +#undef BOOST_ASSERT +#undef BOOST_ASSERT_MSG +#undef BOOST_ASSERT_IS_VOID + +#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ) + +# define BOOST_ASSERT(expr) ((void)0) +# define BOOST_ASSERT_MSG(expr, msg) ((void)0) +# define BOOST_ASSERT_IS_VOID + +#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) ) + +#include // for BOOST_LIKELY +#include + +namespace boost +{ + void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined + void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined +} // namespace boost + +#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) +#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) + +#else + +# include // .h to support old libraries w/o - effect is the same + +# define BOOST_ASSERT(expr) assert(expr) +# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg)) +#if defined(NDEBUG) +# define BOOST_ASSERT_IS_VOID +#endif + +#endif + +// +// BOOST_VERIFY, BOOST_VERIFY_MSG +// + +#undef BOOST_VERIFY +#undef BOOST_VERIFY_MSG + +#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) + +# define BOOST_VERIFY(expr) ((void)(expr)) +# define BOOST_VERIFY_MSG(expr, msg) ((void)(expr)) + +#else + +# define BOOST_VERIFY(expr) BOOST_ASSERT(expr) +# define BOOST_VERIFY_MSG(expr, msg) BOOST_ASSERT_MSG(expr,msg) + +#endif diff --git a/thirdparty/linux/include/boost/checked_delete.hpp b/thirdparty/linux/include/boost/checked_delete.hpp new file mode 100644 index 0000000..fb71c78 --- /dev/null +++ b/thirdparty/linux/include/boost/checked_delete.hpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2014 Glen Fernandes + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_CHECKED_DELETE_HPP +#define BOOST_CHECKED_DELETE_HPP + +// The header file at this path is deprecated; +// use boost/core/checked_delete.hpp instead. + +#include + +#endif diff --git a/thirdparty/linux/include/boost/config.hpp b/thirdparty/linux/include/boost/config.hpp new file mode 100644 index 0000000..d49bb27 --- /dev/null +++ b/thirdparty/linux/include/boost/config.hpp @@ -0,0 +1,67 @@ +// Boost config.hpp configuration header file ------------------------------// + +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config +// +// CAUTION: This file is intended to be completely stable - +// DO NOT MODIFY THIS FILE! +// + +#ifndef BOOST_CONFIG_HPP +#define BOOST_CONFIG_HPP + +// if we don't have a user config, then use the default location: +#if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG) +# define BOOST_USER_CONFIG +#if 0 +// For dependency trackers: +# include +#endif +#endif +// include it first: +#ifdef BOOST_USER_CONFIG +# include BOOST_USER_CONFIG +#endif + +// if we don't have a compiler config set, try and find one: +#if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a compiler config, include it now: +#ifdef BOOST_COMPILER_CONFIG +# include BOOST_COMPILER_CONFIG +#endif + +// if we don't have a std library config set, try and find one: +#if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG) && defined(__cplusplus) +# include +#endif +// if we have a std library config, include it now: +#ifdef BOOST_STDLIB_CONFIG +# include BOOST_STDLIB_CONFIG +#endif + +// if we don't have a platform config set, try and find one: +#if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a platform config, include it now: +#ifdef BOOST_PLATFORM_CONFIG +# include BOOST_PLATFORM_CONFIG +#endif + +// get config suffix code: +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_CONFIG_HPP diff --git a/thirdparty/linux/include/boost/config/abi/borland_prefix.hpp b/thirdparty/linux/include/boost/config/abi/borland_prefix.hpp new file mode 100644 index 0000000..3a0e5ae --- /dev/null +++ b/thirdparty/linux/include/boost/config/abi/borland_prefix.hpp @@ -0,0 +1,27 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// for C++ Builder the following options effect the ABI: +// +// -b (on or off - effect emum sizes) +// -Vx (on or off - empty members) +// -Ve (on or off - empty base classes) +// -aX (alignment - 5 options). +// -pX (Calling convention - 4 options) +// -VmX (member pointer size and layout - 5 options) +// -VC (on or off, changes name mangling) +// -Vl (on or off, changes struct layout). + +// In addition the following warnings are sufficiently annoying (and +// unfixable) to have them turned off by default: +// +// 8027 - functions containing [for|while] loops are not expanded inline +// 8026 - functions taking class by value arguments are not expanded inline + +#pragma nopushoptwarn +# pragma option push -a8 -Vx- -Ve- -b- -pc -Vmv -VC- -Vl- -w-8027 -w-8026 + + + diff --git a/thirdparty/linux/include/boost/config/abi/borland_suffix.hpp b/thirdparty/linux/include/boost/config/abi/borland_suffix.hpp new file mode 100644 index 0000000..940535f --- /dev/null +++ b/thirdparty/linux/include/boost/config/abi/borland_suffix.hpp @@ -0,0 +1,12 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# pragma option pop +#pragma nopushoptwarn + + + + + diff --git a/thirdparty/linux/include/boost/config/abi/msvc_prefix.hpp b/thirdparty/linux/include/boost/config/abi/msvc_prefix.hpp new file mode 100644 index 0000000..97f06cd --- /dev/null +++ b/thirdparty/linux/include/boost/config/abi/msvc_prefix.hpp @@ -0,0 +1,22 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// +// Boost binaries are built with the compiler's default ABI settings, +// if the user changes their default alignment in the VS IDE then their +// code will no longer be binary compatible with the bjam built binaries +// unless this header is included to force Boost code into a consistent ABI. +// +// Note that inclusion of this header is only necessary for libraries with +// separate source, header only libraries DO NOT need this as long as all +// translation units are built with the same options. +// +#if defined(_M_X64) +# pragma pack(push,16) +#else +# pragma pack(push,8) +#endif + + diff --git a/thirdparty/linux/include/boost/config/abi/msvc_suffix.hpp b/thirdparty/linux/include/boost/config/abi/msvc_suffix.hpp new file mode 100644 index 0000000..a64d783 --- /dev/null +++ b/thirdparty/linux/include/boost/config/abi/msvc_suffix.hpp @@ -0,0 +1,8 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma pack(pop) + + diff --git a/thirdparty/linux/include/boost/config/abi_prefix.hpp b/thirdparty/linux/include/boost/config/abi_prefix.hpp new file mode 100644 index 0000000..3b13474 --- /dev/null +++ b/thirdparty/linux/include/boost/config/abi_prefix.hpp @@ -0,0 +1,25 @@ +// abi_prefix header -------------------------------------------------------// + +// (c) Copyright John Maddock 2003 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# define BOOST_CONFIG_ABI_PREFIX_HPP +#else +# error double inclusion of header boost/config/abi_prefix.hpp is an error +#endif + +#include + +// this must occur after all other includes and before any code appears: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/thirdparty/linux/include/boost/config/abi_suffix.hpp b/thirdparty/linux/include/boost/config/abi_suffix.hpp new file mode 100644 index 0000000..9391616 --- /dev/null +++ b/thirdparty/linux/include/boost/config/abi_suffix.hpp @@ -0,0 +1,27 @@ +// abi_sufffix header -------------------------------------------------------// + +// (c) Copyright John Maddock 2003 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +// This header should be #included AFTER code that was preceded by a #include +// . + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# error Header boost/config/abi_suffix.hpp must only be used after boost/config/abi_prefix.hpp +#else +# undef BOOST_CONFIG_ABI_PREFIX_HPP +#endif + +// the suffix header occurs after all of our code: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + + diff --git a/thirdparty/linux/include/boost/config/auto_link.hpp b/thirdparty/linux/include/boost/config/auto_link.hpp new file mode 100644 index 0000000..56a16b0 --- /dev/null +++ b/thirdparty/linux/include/boost/config/auto_link.hpp @@ -0,0 +1,439 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE auto_link.hpp + * VERSION see + * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. + */ + +/************************************************************************* + +USAGE: +~~~~~~ + +Before including this header you must define one or more of define the following macros: + +BOOST_LIB_NAME: Required: A string containing the basename of the library, + for example boost_regex. +BOOST_LIB_TOOLSET: Optional: the base name of the toolset. +BOOST_DYN_LINK: Optional: when set link to dll rather than static library. +BOOST_LIB_DIAGNOSTIC: Optional: when set the header will print out the name + of the library selected (useful for debugging). +BOOST_AUTO_LINK_NOMANGLE: Specifies that we should link to BOOST_LIB_NAME.lib, + rather than a mangled-name version. +BOOST_AUTO_LINK_TAGGED: Specifies that we link to libraries built with the --layout=tagged option. + This is essentially the same as the default name-mangled version, but without + the compiler name and version, or the Boost version. Just the build options. + +These macros will be undef'ed at the end of the header, further this header +has no include guards - so be sure to include it only once from your library! + +Algorithm: +~~~~~~~~~~ + +Libraries for Borland and Microsoft compilers are automatically +selected here, the name of the lib is selected according to the following +formula: + +BOOST_LIB_PREFIX + + BOOST_LIB_NAME + + "_" + + BOOST_LIB_TOOLSET + + BOOST_LIB_THREAD_OPT + + BOOST_LIB_RT_OPT + "-" + + BOOST_LIB_VERSION + +These are defined as: + +BOOST_LIB_PREFIX: "lib" for static libraries otherwise "". + +BOOST_LIB_NAME: The base name of the lib ( for example boost_regex). + +BOOST_LIB_TOOLSET: The compiler toolset name (vc6, vc7, bcb5 etc). + +BOOST_LIB_THREAD_OPT: "-mt" for multithread builds, otherwise nothing. + +BOOST_LIB_RT_OPT: A suffix that indicates the runtime library used, + contains one or more of the following letters after + a hyphen: + + s static runtime (dynamic if not present). + g debug/diagnostic runtime (release if not present). + y Python debug/diagnostic runtime (release if not present). + d debug build (release if not present). + p STLport build. + n STLport build without its IOStreams. + +BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. + + +***************************************************************************/ + +#ifdef __cplusplus +# ifndef BOOST_CONFIG_HPP +# include +# endif +#elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__) +// +// C language compatability (no, honestly) +// +# define BOOST_MSVC _MSC_VER +# define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +# define BOOST_DO_STRINGIZE(X) #X +#endif +// +// Only include what follows for known and supported compilers: +// +#if defined(BOOST_MSVC) \ + || defined(__BORLANDC__) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) + +#ifndef BOOST_VERSION_HPP +# include +#endif + +#ifndef BOOST_LIB_NAME +# error "Macro BOOST_LIB_NAME not set (internal error)" +#endif + +// +// error check: +// +#if defined(__MSVC_RUNTIME_CHECKS) && !defined(_DEBUG) +# pragma message("Using the /RTC option without specifying a debug runtime will lead to linker errors") +# pragma message("Hint: go to the code generation options and switch to one of the debugging runtimes") +# error "Incompatible build options" +#endif +// +// select toolset if not defined already: +// +#ifndef BOOST_LIB_TOOLSET +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1200) + // Note: no compilers before 1200 are supported +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +# ifdef UNDER_CE + // eVC4: +# define BOOST_LIB_TOOLSET "evc4" +# else + // vc6: +# define BOOST_LIB_TOOLSET "vc6" +# endif + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1310) + + // vc7: +# define BOOST_LIB_TOOLSET "vc7" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1400) + + // vc71: +# define BOOST_LIB_TOOLSET "vc71" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1500) + + // vc80: +# define BOOST_LIB_TOOLSET "vc80" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1600) + + // vc90: +# define BOOST_LIB_TOOLSET "vc90" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1700) + + // vc10: +# define BOOST_LIB_TOOLSET "vc100" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) + + // vc11: +# define BOOST_LIB_TOOLSET "vc110" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1900) + + // vc12: +# define BOOST_LIB_TOOLSET "vc120" + +# elif defined(BOOST_MSVC) + + // vc14: +# define BOOST_LIB_TOOLSET "vc140" + +# elif defined(__BORLANDC__) + + // CBuilder 6: +# define BOOST_LIB_TOOLSET "bcb" + +# elif defined(__ICL) + + // Intel C++, no version number: +# define BOOST_LIB_TOOLSET "iw" + +# elif defined(__MWERKS__) && (__MWERKS__ <= 0x31FF ) + + // Metrowerks CodeWarrior 8.x +# define BOOST_LIB_TOOLSET "cw8" + +# elif defined(__MWERKS__) && (__MWERKS__ <= 0x32FF ) + + // Metrowerks CodeWarrior 9.x +# define BOOST_LIB_TOOLSET "cw9" + +# endif +#endif // BOOST_LIB_TOOLSET + +// +// select thread opt: +// +#if defined(_MT) || defined(__MT__) +# define BOOST_LIB_THREAD_OPT "-mt" +#else +# define BOOST_LIB_THREAD_OPT +#endif + +#if defined(_MSC_VER) || defined(__MWERKS__) + +# ifdef _DLL + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-p" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-pn" +# endif + +# else + +# if defined(_DEBUG) && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gyd" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gd" +# else +# define BOOST_LIB_RT_OPT +# endif + +# endif + +# else + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-sp" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-spn" +# endif + +# else + +# if defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgyd" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +# endif + +#elif defined(__BORLANDC__) + +// +// figure out whether we want the debug builds or not: +// +#if __BORLANDC__ > 0x561 +#pragma defineonoption BOOST_BORLAND_DEBUG -v +#endif +// +// sanity check: +// +#if defined(__STL_DEBUG) || defined(_STLP_DEBUG) +#error "Pre-built versions of the Boost libraries are not provided in STLport-debug form" +#endif + +# ifdef _RTLDLL + +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-yd" +# elif defined(BOOST_BORLAND_DEBUG) +# define BOOST_LIB_RT_OPT "-d" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT -y +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-syd" +# elif defined(BOOST_BORLAND_DEBUG) +# define BOOST_LIB_RT_OPT "-sd" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sy" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#endif + +// +// select linkage opt: +// +#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK) +# define BOOST_LIB_PREFIX +#elif defined(BOOST_DYN_LINK) +# error "Mixing a dll boost library with a static runtime is a really bad idea..." +#else +# define BOOST_LIB_PREFIX "lib" +#endif + +// +// now include the lib: +// +#if defined(BOOST_LIB_NAME) \ + && defined(BOOST_LIB_PREFIX) \ + && defined(BOOST_LIB_TOOLSET) \ + && defined(BOOST_LIB_THREAD_OPT) \ + && defined(BOOST_LIB_RT_OPT) \ + && defined(BOOST_LIB_VERSION) + +#ifdef BOOST_AUTO_LINK_TAGGED +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT ".lib") +# endif +#elif defined(BOOST_AUTO_LINK_NOMANGLE) +# pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") +# endif +#elif defined(BOOST_LIB_BUILDID) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) ".lib") +# endif +#else +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +# endif +#endif + +#else +# error "some required macros where not defined (internal logic error)." +#endif + + +#endif // _MSC_VER || __BORLANDC__ + +// +// finally undef any macros we may have set: +// +#ifdef BOOST_LIB_PREFIX +# undef BOOST_LIB_PREFIX +#endif +#if defined(BOOST_LIB_NAME) +# undef BOOST_LIB_NAME +#endif +// Don't undef this one: it can be set by the user and should be the +// same for all libraries: +//#if defined(BOOST_LIB_TOOLSET) +//# undef BOOST_LIB_TOOLSET +//#endif +#if defined(BOOST_LIB_THREAD_OPT) +# undef BOOST_LIB_THREAD_OPT +#endif +#if defined(BOOST_LIB_RT_OPT) +# undef BOOST_LIB_RT_OPT +#endif +#if defined(BOOST_LIB_LINK_OPT) +# undef BOOST_LIB_LINK_OPT +#endif +#if defined(BOOST_LIB_DEBUG_OPT) +# undef BOOST_LIB_DEBUG_OPT +#endif +#if defined(BOOST_DYN_LINK) +# undef BOOST_DYN_LINK +#endif + + diff --git a/thirdparty/linux/include/boost/config/compiler/borland.hpp b/thirdparty/linux/include/boost/config/compiler/borland.hpp new file mode 100644 index 0000000..ccd930e --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/borland.hpp @@ -0,0 +1,319 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Borland C++ compiler setup: + +// +// versions check: +// we don't support Borland prior to version 5.4: +#if __BORLANDC__ < 0x540 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// last known compiler version: +#if (__BORLANDC__ > 0x613) +//# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +//# else +//# pragma message( "Unknown compiler version - please run the configure tests and report the results") +//# endif +#elif (__BORLANDC__ == 0x600) +# error "CBuilderX preview compiler is no longer supported" +#endif + +// +// Support macros to help with standard library detection +#if (__BORLANDC__ < 0x560) || defined(_USE_OLD_RW_STL) +# define BOOST_BCB_WITH_ROGUE_WAVE +#elif __BORLANDC__ < 0x570 +# define BOOST_BCB_WITH_STLPORT +#else +# define BOOST_BCB_WITH_DINKUMWARE +#endif + +// +// Version 5.0 and below: +# if __BORLANDC__ <= 0x0550 +// Borland C++Builder 4 and 5: +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# if __BORLANDC__ == 0x0550 +// Borland C++Builder 5, command-line compiler 5.5: +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# endif +// Variadic macros do not exist for C++ Builder versions 5 and below +#define BOOST_NO_CXX11_VARIADIC_MACROS +# endif + +// Version 5.51 and below: +#if (__BORLANDC__ <= 0x551) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# define BOOST_NO_DEDUCED_TYPENAME +// workaround for missing WCHAR_MAX/WCHAR_MIN: +#ifdef __cplusplus +#include +#include +#else +#include +#include +#endif // __cplusplus +#ifndef WCHAR_MAX +# define WCHAR_MAX 0xffff +#endif +#ifndef WCHAR_MIN +# define WCHAR_MIN 0 +#endif +#endif + +// Borland C++ Builder 6 and below: +#if (__BORLANDC__ <= 0x564) + +# if defined(NDEBUG) && defined(__cplusplus) + // fix broken so that Boost.test works: +# include +# undef strcmp +# endif + // fix broken errno declaration: +# include +# ifndef errno +# define errno errno +# endif + +#endif + +// +// new bug in 5.61: +#if (__BORLANDC__ >= 0x561) && (__BORLANDC__ <= 0x580) + // this seems to be needed by the command line compiler, but not the IDE: +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +// Borland C++ Builder 2006 Update 2 and below: +#if (__BORLANDC__ <= 0x582) +# define BOOST_NO_SFINAE +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# define BOOST_NO_TEMPLATE_TEMPLATES + +# define BOOST_NO_PRIVATE_IN_AGGREGATE + +# ifdef _WIN32 +# define BOOST_NO_SWPRINTF +# elif defined(linux) || defined(__linux__) || defined(__linux) + // we should really be able to do without this + // but the wcs* functions aren't imported into std:: +# define BOOST_NO_STDC_NAMESPACE + // _CPPUNWIND doesn't get automatically set for some reason: +# pragma defineonoption BOOST_CPPUNWIND -x +# endif +#endif + +#if (__BORLANDC__ <= 0x613) // Beman has asked Alisdair for more info + // we shouldn't really need this - but too many things choke + // without it, this needs more investigation: +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +# define BOOST_NO_USING_TEMPLATE +# define BOOST_SP_NO_SP_CONVERTIBLE + +// Temporary workaround +#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif + +// Borland C++ Builder 2008 and below: +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# define BOOST_NO_NESTED_FRIENDSHIP +# define BOOST_NO_TYPENAME_WITH_CTOR +#if (__BORLANDC__ < 0x600) +# define BOOST_ILLEGAL_CV_REFERENCES +#endif + +// +// Positive Feature detection +// +// Borland C++ Builder 2008 and below: +#if (__BORLANDC__ >= 0x599) +# pragma defineonoption BOOST_CODEGEAR_0X_SUPPORT -Ax +#endif +// +// C++0x Macros: +// +#if !defined( BOOST_CODEGEAR_0X_SUPPORT ) || (__BORLANDC__ < 0x610) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_STATIC_ASSERT +#else +# define BOOST_HAS_ALIGNOF +# define BOOST_HAS_CHAR16_T +# define BOOST_HAS_CHAR32_T +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_EXPLICIT_CONVERSION_OPS +# define BOOST_HAS_REF_QUALIFIER +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +#endif + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS // UTF-8 still not supported +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#if __BORLANDC__ >= 0x590 +# define BOOST_HAS_TR1_HASH + +# define BOOST_HAS_MACRO_USE_FACET +#endif + +// +// Post 0x561 we have long long and stdint.h: +#if __BORLANDC__ >= 0x561 +# ifndef __NO_LONG_LONG +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif + // On non-Win32 platforms let the platform config figure this out: +# ifdef _WIN32 +# define BOOST_HAS_STDINT_H +# endif +#endif + +// Borland C++Builder 6 defaults to using STLPort. If _USE_OLD_RW_STL is +// defined, then we have 0x560 or greater with the Rogue Wave implementation +// which presumably has the std::DBL_MAX bug. +#if defined( BOOST_BCB_WITH_ROGUE_WAVE ) +// is partly broken, some macros define symbols that are really in +// namespace std, so you end up having to use illegal constructs like +// std::DBL_MAX, as a fix we'll just include float.h and have done with: +#include +#endif +// +// __int64: +// +#if (__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif +// +// all versions have a : +// +#ifndef __STRICT_ANSI__ +# define BOOST_HAS_DIRENT_H +#endif +// +// all versions support __declspec: +// +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif +// +// ABI fixing headers: +// +#if __BORLANDC__ != 0x600 // not implemented for version 6 compiler yet +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" +#endif +#endif +// +// Disable Win32 support in ANSI mode: +// +#if __BORLANDC__ < 0x600 +# pragma defineonoption BOOST_DISABLE_WIN32 -A +#elif defined(__STRICT_ANSI__) +# define BOOST_DISABLE_WIN32 +#endif +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif + +// Borland did not implement value-initialization completely, as I reported +// in 2007, Borland Report 51854, "Value-initialization: POD struct should be +// zero-initialized", http://qc.embarcadero.com/wc/qcmain.aspx?d=51854 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, April 2010) +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION + +#define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) diff --git a/thirdparty/linux/include/boost/config/compiler/clang.hpp b/thirdparty/linux/include/boost/config/compiler/clang.hpp new file mode 100644 index 0000000..150e3c0 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/clang.hpp @@ -0,0 +1,304 @@ +// (C) Copyright Douglas Gregor 2010 +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Clang compiler setup. + +#define BOOST_HAS_PRAGMA_ONCE + +// Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used. +#if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) +# define BOOST_HAS_PRAGMA_DETECT_MISMATCH +#endif + +// When compiling with clang before __has_extension was defined, +// even if one writes 'defined(__has_extension) && __has_extension(xxx)', +// clang reports a compiler error. So the only workaround found is: + +#ifndef __has_extension +#define __has_extension __has_feature +#endif + +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif + +#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID) +# define BOOST_NO_TYPEID +#endif + +#if !__has_feature(cxx_thread_local) +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#ifdef __is_identifier +#if !__is_identifier(__int64) && !defined(__GNUC__) +# define BOOST_HAS_MS_INT64 +#endif +#endif + +#if __has_include() +# define BOOST_HAS_STDINT_H +#endif + + +#define BOOST_HAS_NRVO + +// Branch prediction hints +#if defined(__has_builtin) +#if __has_builtin(__builtin_expect) +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif +#endif + +// Clang supports "long long" in all compilation modes. +#define BOOST_HAS_LONG_LONG + +// +// We disable this if the compiler is really nvcc with C++03 as it +// doesn't actually support __int128 as of CUDA_VERSION=7500 +// even though it defines __SIZEOF_INT128__. +// See https://svn.boost.org/trac/boost/ticket/10418 +// https://svn.boost.org/trac/boost/ticket/11852 +// Only re-enable this for nvcc if you're absolutely sure +// of the circumstances under which it's supported. +// Similarly __SIZEOF_INT128__ is defined when targetting msvc +// compatibility even though the required support functions are absent. +// +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__SIZEOF_INT128__) && !defined(BOOST_NVCC_CXX03) && !defined(_MSC_VER) +# define BOOST_HAS_INT128 +#endif + + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#endif + +// +// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +// between switch labels. +// +#if __cplusplus >= 201103L && defined(__has_warning) +# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +# define BOOST_FALLTHROUGH [[clang::fallthrough]] +# endif +#endif + +#if !__has_feature(cxx_auto_type) +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif + +// +// Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t +// +#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(__GNUC__) +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +#if !__has_feature(cxx_constexpr) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#if !__has_feature(cxx_decltype) +# define BOOST_NO_CXX11_DECLTYPE +#endif + +#if !__has_feature(cxx_decltype_incomplete_return_types) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +#if !__has_feature(cxx_defaulted_functions) +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#endif + +#if !__has_feature(cxx_deleted_functions) +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +#endif + +#if !__has_feature(cxx_explicit_conversions) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +#if !__has_feature(cxx_default_function_template_args) +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if !__has_feature(cxx_lambdas) +# define BOOST_NO_CXX11_LAMBDAS +#endif + +#if !__has_feature(cxx_local_type_template_args) +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +#if !__has_feature(cxx_noexcept) +# define BOOST_NO_CXX11_NOEXCEPT +#endif + +#if !__has_feature(cxx_nullptr) +# define BOOST_NO_CXX11_NULLPTR +#endif + +#if !__has_feature(cxx_range_for) +# define BOOST_NO_CXX11_RANGE_BASED_FOR +#endif + +#if !__has_feature(cxx_raw_string_literals) +# define BOOST_NO_CXX11_RAW_LITERALS +#endif + +#if !__has_feature(cxx_reference_qualified_functions) +# define BOOST_NO_CXX11_REF_QUALIFIERS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +#if !__has_feature(cxx_rvalue_references) +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +#if !__has_feature(cxx_strong_enums) +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#if !__has_feature(cxx_static_assert) +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +#if !__has_feature(cxx_alias_templates) +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +#endif + +#if !__has_feature(cxx_unicode_literals) +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +#if !__has_feature(cxx_variadic_templates) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if !__has_feature(cxx_user_literals) +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif + +#if !__has_feature(cxx_alignas) +# define BOOST_NO_CXX11_ALIGNAS +#endif + +#if !__has_feature(cxx_trailing_return) +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +#if !__has_feature(cxx_inline_namespaces) +# define BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +#if !__has_feature(cxx_override_control) +# define BOOST_NO_CXX11_FINAL +#endif + +#if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__)) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +#if !__has_feature(__cxx_decltype_auto__) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif + +#if !__has_feature(__cxx_aggregate_nsdmi__) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif + +#if !__has_feature(__cxx_init_captures__) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif + +#if !__has_feature(__cxx_generic_lambdas__) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif + +// clang < 3.5 has a defect with dependent type, like following. +// +// template +// constexpr typename enable_if >::type foo(T &) +// { } // error: no return statement in constexpr function +// +// This issue also affects C++11 mode, but C++11 constexpr requires return stmt. +// Therefore we don't care such case. +// +// Note that we can't check Clang version directly as the numbering system changes depending who's +// creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873) +// so instead verify that we have a feature that was introduced at the same time as working C++14 +// constexpr (generic lambda's in this case): +// +#if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__) +# define BOOST_NO_CXX14_CONSTEXPR +#endif + +#if !__has_feature(__cxx_return_type_deduction__) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif + +#if !__has_feature(__cxx_variable_templates__) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#if __cplusplus < 201400 +// All versions with __cplusplus above this value seem to support this: +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +// +// __builtin_unreachable: +#if defined(__has_builtin) && __has_builtin(__builtin_unreachable) +#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); +#endif + +// Clang has supported the 'unused' attribute since the first release. +#define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "Clang version " __clang_version__ +#endif + +// Macro used to identify the Clang compiler. +#define BOOST_CLANG 1 + diff --git a/thirdparty/linux/include/boost/config/compiler/codegear.hpp b/thirdparty/linux/include/boost/config/compiler/codegear.hpp new file mode 100644 index 0000000..e2f6061 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/codegear.hpp @@ -0,0 +1,221 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// CodeGear C++ compiler setup: + +#if !defined( BOOST_WITH_CODEGEAR_WARNINGS ) +// these warnings occur frequently in optimized template code +# pragma warn -8004 // var assigned value, but never used +# pragma warn -8008 // condition always true/false +# pragma warn -8066 // dead code can never execute +# pragma warn -8104 // static members with ctors not threadsafe +# pragma warn -8105 // reference member in class without ctors +#endif +// +// versions check: +// last known and checked version is 0x621 +#if (__CODEGEARC__ > 0x621) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +# pragma message( "Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + +// CodeGear C++ Builder 2009 +#if (__CODEGEARC__ <= 0x613) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_PRIVATE_IN_AGGREGATE +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE + // we shouldn't really need this - but too many things choke + // without it, this needs more investigation: +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +// CodeGear C++ Builder 2010 +#if (__CODEGEARC__ <= 0x621) +# define BOOST_NO_TYPENAME_WITH_CTOR // Cannot use typename keyword when making temporaries of a dependant type +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_NESTED_FRIENDSHIP // TC1 gives nested classes access rights as any other member +# define BOOST_NO_USING_TEMPLATE +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +// Temporary hack, until specific MPL preprocessed headers are generated +# define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +// CodeGear has not yet completely implemented value-initialization, for +// example for array types, as I reported in 2010: Embarcadero Report 83751, +// "Value-initialization: arrays should have each element value-initialized", +// http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 +// Last checked version: Embarcadero C++ 6.21 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, April 2010) +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION + +# if defined(NDEBUG) && defined(__cplusplus) + // fix broken so that Boost.test works: +# include +# undef strcmp +# endif + // fix broken errno declaration: +# include +# ifndef errno +# define errno errno +# endif + +#endif + +// Reportedly, #pragma once is supported since C++ Builder 2010 +#if (__CODEGEARC__ >= 0x620) +# define BOOST_HAS_PRAGMA_ONCE +#endif + +// +// C++0x macros: +// +#if (__CODEGEARC__ <= 0x620) +#define BOOST_NO_CXX11_STATIC_ASSERT +#else +#define BOOST_HAS_STATIC_ASSERT +#endif +#define BOOST_HAS_CHAR16_T +#define BOOST_HAS_CHAR32_T +#define BOOST_HAS_LONG_LONG +// #define BOOST_HAS_ALIGNOF +#define BOOST_HAS_DECLTYPE +#define BOOST_HAS_EXPLICIT_CONVERSION_OPS +// #define BOOST_HAS_RVALUE_REFS +#define BOOST_HAS_SCOPED_ENUM +// #define BOOST_HAS_STATIC_ASSERT +#define BOOST_HAS_STD_TYPE_TRAITS + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// +// TR1 macros: +// +#define BOOST_HAS_TR1_HASH +#define BOOST_HAS_TR1_TYPE_TRAITS +#define BOOST_HAS_TR1_UNORDERED_MAP +#define BOOST_HAS_TR1_UNORDERED_SET + +#define BOOST_HAS_MACRO_USE_FACET + +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST + +// On non-Win32 platforms let the platform config figure this out: +#ifdef _WIN32 +# define BOOST_HAS_STDINT_H +#endif + +// +// __int64: +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif +// +// all versions have a : +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_DIRENT_H +#endif +// +// all versions support __declspec: +// +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif +// +// ABI fixing headers: +// +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" +#endif +// +// Disable Win32 support in ANSI mode: +// +# pragma defineonoption BOOST_DISABLE_WIN32 -A +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif + +#define BOOST_COMPILER "CodeGear C++ version " BOOST_STRINGIZE(__CODEGEARC__) + diff --git a/thirdparty/linux/include/boost/config/compiler/comeau.hpp b/thirdparty/linux/include/boost/config/compiler/comeau.hpp new file mode 100644 index 0000000..0984160 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/comeau.hpp @@ -0,0 +1,59 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Douglas Gregor 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Comeau C++ compiler setup: + +#include + +#if (__COMO_VERSION__ <= 4245) + +# if defined(_MSC_VER) && _MSC_VER <= 1300 +# if _MSC_VER > 100 + // only set this in non-strict mode: +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# endif +# endif + +// Void returns don't work when emulating VC 6 (Peter Dimov) +// TODO: look up if this doesn't apply to the whole 12xx range +# if defined(_MSC_VER) && (_MSC_VER < 1300) +# define BOOST_NO_VOID_RETURNS +# endif + +#endif // version 4245 + +// +// enable __int64 support in VC emulation mode +// +# if defined(_MSC_VER) && (_MSC_VER >= 1200) +# define BOOST_HAS_MS_INT64 +# endif + +#define BOOST_COMPILER "Comeau compiler version " BOOST_STRINGIZE(__COMO_VERSION__) + +// +// versions check: +// we don't know Comeau prior to version 4245: +#if __COMO_VERSION__ < 4245 +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 4245: +#if (__COMO_VERSION__ > 4245) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + diff --git a/thirdparty/linux/include/boost/config/compiler/common_edg.hpp b/thirdparty/linux/include/boost/config/compiler/common_edg.hpp new file mode 100644 index 0000000..c09faeb --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/common_edg.hpp @@ -0,0 +1,144 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright Markus Schoepflin 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// +// Options common to all edg based compilers. +// +// This is included from within the individual compiler mini-configs. + +#ifndef __EDG_VERSION__ +# error This file requires that __EDG_VERSION__ be defined. +#endif + +#if (__EDG_VERSION__ <= 238) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_SFINAE +#endif + +#if (__EDG_VERSION__ <= 240) +# define BOOST_NO_VOID_RETURNS +#endif + +#if (__EDG_VERSION__ <= 241) && !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +#endif + +#if (__EDG_VERSION__ <= 244) && !defined(BOOST_NO_TEMPLATE_TEMPLATES) +# define BOOST_NO_TEMPLATE_TEMPLATES +#endif + +#if (__EDG_VERSION__ < 300) && !defined(BOOST_NO_IS_ABSTRACT) +# define BOOST_NO_IS_ABSTRACT +#endif + +#if (__EDG_VERSION__ <= 303) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// See also kai.hpp which checks a Kai-specific symbol for EH +# if !defined(__KCC) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +# if !defined(__NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif + +// Not sure what version was the first to support #pragma once, but +// different EDG-based compilers (e.g. Intel) supported it for ages. +// Add a proper version check if it causes problems. +#define BOOST_HAS_PRAGMA_ONCE + +// +// C++0x features +// +// See above for BOOST_NO_LONG_LONG +// +#if (__EDG_VERSION__ < 310) +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if (__EDG_VERSION__ <= 310) +// No support for initializer lists +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif +#if (__EDG_VERSION__ < 400) +# define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#ifdef c_plusplus +// EDG has "long long" in non-strict mode +// However, some libraries have insufficient "long long" support +// #define BOOST_HAS_LONG_LONG +#endif diff --git a/thirdparty/linux/include/boost/config/compiler/compaq_cxx.hpp b/thirdparty/linux/include/boost/config/compiler/compaq_cxx.hpp new file mode 100644 index 0000000..4d6b8ab --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/compaq_cxx.hpp @@ -0,0 +1,19 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Tru64 C++ compiler setup (now HP): + +#define BOOST_COMPILER "HP Tru64 C++ " BOOST_STRINGIZE(__DECCXX_VER) + +#include + +// +// versions check: +// Nothing to do here? + + + diff --git a/thirdparty/linux/include/boost/config/compiler/cray.hpp b/thirdparty/linux/include/boost/config/compiler/cray.hpp new file mode 100644 index 0000000..837f815 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/cray.hpp @@ -0,0 +1,93 @@ +// (C) Copyright John Maddock 2011. +// (C) Copyright Cray, Inc. 2013 +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Greenhills C compiler setup: + +#define BOOST_COMPILER "Cray C version " BOOST_STRINGIZE(_RELEASE) + +#if _RELEASE < 8 +# error "Boost is not configured for Cray compilers prior to version 8, please try the configure script." +#endif + +// +// Check this is a recent EDG based compiler, otherwise we don't support it here: +// +#ifndef __EDG_VERSION__ +# error "Unsupported Cray compiler, please try running the configure script." +#endif + +#include + + +// +// +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_HAS_NRVO +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_HAS_NRVO +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + + +//#define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +#define BOOST_MATH_DISABLE_STD_FPCLASSIFY +//#define BOOST_HAS_FPCLASSIFY + +#define BOOST_SP_USE_PTHREADS +#define BOOST_AC_USE_PTHREADS + +/* everything that follows is working around what are thought to be + * compiler shortcomings. Revist all of these regularly. + */ + +//#define BOOST_USE_ENUM_STATIC_ASSERT +//#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS //(this may be implied by the previous #define + +// These constants should be provided by the +// compiler, at least when -hgnu is asserted on the command line. + +#ifndef __ATOMIC_RELAXED +#define __ATOMIC_RELAXED 0 +#define __ATOMIC_CONSUME 1 +#define __ATOMIC_ACQUIRE 2 +#define __ATOMIC_RELEASE 3 +#define __ATOMIC_ACQ_REL 4 +#define __ATOMIC_SEQ_CST 5 +#endif + + + diff --git a/thirdparty/linux/include/boost/config/compiler/digitalmars.hpp b/thirdparty/linux/include/boost/config/compiler/digitalmars.hpp new file mode 100644 index 0000000..c344aae --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/digitalmars.hpp @@ -0,0 +1,125 @@ +// Copyright (C) Christof Meerwald 2003 +// Copyright (C) Dan Watkins 2003 +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Digital Mars C++ compiler setup: +#define BOOST_COMPILER __DMC_VERSION_STRING__ + +#define BOOST_HAS_LONG_LONG +#define BOOST_HAS_PRAGMA_ONCE + +#if !defined(BOOST_STRICT_CONFIG) +#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#define BOOST_NO_OPERATORS_IN_NAMESPACE +#define BOOST_NO_UNREACHABLE_RETURN_DETECTION +#define BOOST_NO_SFINAE +#define BOOST_NO_USING_TEMPLATE +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// has macros: +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_WINTHREADS + +#if (__DMC__ >= 0x847) +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +// +// Is this really the best way to detect whether the std lib is in namespace std? +// +#ifdef __cplusplus +#include +#endif +#if !defined(__STL_IMPORT_VENDOR_CSTD) && !defined(_STLP_IMPORT_VENDOR_CSTD) +# define BOOST_NO_STDC_NAMESPACE +#endif + + +// check for exception handling support: +#if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +// +// C++0x features +// +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#if (__DMC__ <= 0x840) +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is ...: +#if (__DMC__ > 0x848) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/thirdparty/linux/include/boost/config/compiler/gcc.hpp b/thirdparty/linux/include/boost/config/compiler/gcc.hpp new file mode 100644 index 0000000..e319d04 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/gcc.hpp @@ -0,0 +1,328 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Jens Maurer 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Douglas Gregor 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Synge Todo 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// GNU C++ compiler setup. + +// +// Define BOOST_GCC so we know this is "real" GCC and not some pretender: +// +#define BOOST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#if !defined(__CUDACC__) +#define BOOST_GCC BOOST_GCC_VERSION +#endif + +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) +# define BOOST_GCC_CXX11 +#endif + +#if __GNUC__ == 3 +# if defined (__PATHSCALE__) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_IS_ABSTRACT +# endif + +# if __GNUC_MINOR__ < 4 +# define BOOST_NO_IS_ABSTRACT +# endif +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if __GNUC__ < 4 +// +// All problems to gcc-3.x and earlier here: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# ifdef __OPEN64__ +# define BOOST_NO_IS_ABSTRACT +# endif +#endif + +// GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links +#if BOOST_GCC_VERSION >= 30400 +#define BOOST_HAS_PRAGMA_ONCE +#endif + +#if BOOST_GCC_VERSION < 40400 +// Previous versions of GCC did not completely implement value-initialization: +// GCC Bug 30111, "Value-initialization of POD base class doesn't initialize +// members", reported by Jonathan Wakely in 2006, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 (fixed for GCC 4.4) +// GCC Bug 33916, "Default constructor fails to initialize array members", +// reported by Michael Elizabeth Chastain in 2007, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4) +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + +#if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// Except on Darwin with standard compliance enabled (-pedantic) +// Apple gcc helpfully defines this macro we can query +// +#if !defined(__DARWIN_NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +#endif + +// +// gcc implements the named return value optimization since version 3.1 +// +#define BOOST_HAS_NRVO + +// Branch prediction hints +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __GNUC__ >= 4 +# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(__CYGWIN__) + // All Win32 development environments, including 64-bit Windows and MinGW, define + // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, + // so does not define _WIN32 or its variants. +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) +# define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__)) +# else +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +# endif +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#else +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif + +// +// RTTI and typeinfo detection is possible post gcc-4.3: +// +#if BOOST_GCC_VERSION > 40300 +# ifndef __GXX_RTTI +# ifndef BOOST_NO_TYPEID +# define BOOST_NO_TYPEID +# endif +# ifndef BOOST_NO_RTTI +# define BOOST_NO_RTTI +# endif +# endif +#endif + +// +// Recent GCC versions have __int128 when in 64-bit mode. +// +// We disable this if the compiler is really nvcc with C++03 as it +// doesn't actually support __int128 as of CUDA_VERSION=7500 +// even though it defines __SIZEOF_INT128__. +// See https://svn.boost.org/trac/boost/ticket/8048 +// https://svn.boost.org/trac/boost/ticket/11852 +// Only re-enable this for nvcc if you're absolutely sure +// of the circumstances under which it's supported: +// +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__SIZEOF_INT128__) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_INT128 +#endif +// +// Recent GCC versions have a __float128 native type, we need to +// include a std lib header to detect this - not ideal, but we'll +// be including later anyway when we select the std lib. +// +// Nevertheless, as of CUDA 7.5, using __float128 with the host +// compiler in pre-C++11 mode is still not supported. +// See https://svn.boost.org/trac/boost/ticket/11852 +// +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_FLOAT128 +#endif + +// C++0x features in 4.3.n and later +// +#if (BOOST_GCC_VERSION >= 40300) && defined(BOOST_GCC_CXX11) +// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are +// passed on the command line, which in turn defines +// __GXX_EXPERIMENTAL_CXX0X__. +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +# define BOOST_HAS_VARIADIC_TMPL +#else +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +// C++0x features in 4.4.n and later +// +#if (BOOST_GCC_VERSION < 40400) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if BOOST_GCC_VERSION < 40500 +# define BOOST_NO_SFINAE_EXPR +#endif + +// GCC 4.5 forbids declaration of defaulted functions in private or protected sections +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 5) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// C++0x features in 4.5.0 and later +// +#if (BOOST_GCC_VERSION < 40500) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +// C++0x features in 4.5.1 and later +// +#if (BOOST_GCC_VERSION < 40501) || !defined(BOOST_GCC_CXX11) +// scoped enums have a serious bug in 4.4.0, so define BOOST_NO_CXX11_SCOPED_ENUMS before 4.5.1 +// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064 +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +// C++0x features in 4.6.n and later +// +#if (BOOST_GCC_VERSION < 40600) || !defined(BOOST_GCC_CXX11) +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +// C++0x features in 4.7.n and later +// +#if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#endif + +// C++0x features in 4.8.n and later +// +#if (BOOST_GCC_VERSION < 40800) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +// C++0x features in 4.8.1 and later +// +#if (BOOST_GCC_VERSION < 40801) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +// C++14 features in 4.9.0 and later +// +#if (BOOST_GCC_VERSION < 40900) || (__cplusplus < 201300) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX14_DECLTYPE_AUTO +# if !((BOOST_GCC_VERSION >= 40801) && (BOOST_GCC_VERSION < 40900) && defined(BOOST_GCC_CXX11)) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# endif +#endif + + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// +// Unused attribute: +#if __GNUC__ >= 4 +# define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) +#endif +// +// __builtin_unreachable: +#if BOOST_GCC_VERSION >= 40800 +#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "GNU C++ version " __VERSION__ +#endif + +// ConceptGCC compiler: +// http://www.generic-programming.org/software/ConceptGCC/ +#ifdef __GXX_CONCEPTS__ +# define BOOST_HAS_CONCEPTS +# define BOOST_COMPILER "ConceptGCC version " __VERSION__ +#endif + +// versions check: +// we don't know gcc prior to version 3.30: +#if (BOOST_GCC_VERSION< 30300) +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 4.9: +#if (BOOST_GCC_VERSION > 40900) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +// we don't emit warnings here anymore since there are no defect macros defined for +// gcc post 3.4, so any failures are gcc regressions... +//# warning "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + diff --git a/thirdparty/linux/include/boost/config/compiler/gcc_xml.hpp b/thirdparty/linux/include/boost/config/compiler/gcc_xml.hpp new file mode 100644 index 0000000..b56c786 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/gcc_xml.hpp @@ -0,0 +1,96 @@ +// (C) Copyright John Maddock 2006. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// GCC-XML C++ compiler setup: + +# if !defined(__GCCXML_GNUC__) || ((__GCCXML_GNUC__ <= 3) && (__GCCXML_GNUC_MINOR__ <= 3)) +# define BOOST_NO_IS_ABSTRACT +# endif + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// +#define BOOST_HAS_LONG_LONG + +// C++0x features: +// +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ + + diff --git a/thirdparty/linux/include/boost/config/compiler/greenhills.hpp b/thirdparty/linux/include/boost/config/compiler/greenhills.hpp new file mode 100644 index 0000000..a76a07c --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/greenhills.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Greenhills C++ compiler setup: + +#define BOOST_COMPILER "Greenhills C++ version " BOOST_STRINGIZE(__ghs) + +#include + +// +// versions check: +// we don't support Greenhills prior to version 0: +#if __ghs < 0 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0: +#if (__ghs > 0) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/thirdparty/linux/include/boost/config/compiler/hp_acc.hpp b/thirdparty/linux/include/boost/config/compiler/hp_acc.hpp new file mode 100644 index 0000000..a773b8c --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/hp_acc.hpp @@ -0,0 +1,146 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// HP aCC C++ compiler setup: + +#if defined(__EDG__) +#include +#endif + +#if (__HP_aCC <= 33100) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# if !defined(_NAMESPACE_STD) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +# endif +#endif + +#if (__HP_aCC <= 33300) +// member templates are sufficiently broken that we disable them for now +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +#endif + +#if (__HP_aCC <= 38000) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#if (__HP_aCC > 50000) && (__HP_aCC < 60000) +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_NO_TEMPLATE_TEMPLATES +# define BOOST_NO_SWPRINTF +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +// optional features rather than defects: +#if (__HP_aCC >= 33900) +# define BOOST_HAS_LONG_LONG +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +#if (__HP_aCC >= 50000 ) && (__HP_aCC <= 53800 ) || (__HP_aCC < 31300 ) +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +// This macro should not be defined when compiling in strict ansi +// mode, but, currently, we don't have the ability to determine +// what standard mode we are compiling with. Some future version +// of aCC6 compiler will provide predefined macros reflecting the +// compilation options, including the standard mode. +#if (__HP_aCC >= 60000) || ((__HP_aCC > 38000) && defined(__hpxstd98)) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#define BOOST_COMPILER "HP aCC version " BOOST_STRINGIZE(__HP_aCC) + +// +// versions check: +// we don't support HP aCC prior to version 33000: +#if __HP_aCC < 33000 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// +// Extended checks for supporting aCC on PA-RISC +#if __HP_aCC > 30000 && __HP_aCC < 50000 +# if __HP_aCC < 38000 + // versions prior to version A.03.80 not supported +# error "Compiler version not supported - version A.03.80 or higher is required" +# elif !defined(__hpxstd98) + // must compile using the option +hpxstd98 with version A.03.80 and above +# error "Compiler option '+hpxstd98' is required for proper support" +# endif //PA-RISC +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if !defined(__EDG__) + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_THREAD_LOCAL + +/* + See https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443331 and + https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443436 +*/ + +#if (__HP_aCC < 62500) || !defined(HP_CXX0x_SOURCE) + #define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#endif + +// +// last known and checked version for HP-UX/ia64 is 61300 +// last known and checked version for PA-RISC is 38000 +#if ((__HP_aCC > 61300) || ((__HP_aCC > 38000) && defined(__hpxstd98))) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/thirdparty/linux/include/boost/config/compiler/intel.hpp b/thirdparty/linux/include/boost/config/compiler/intel.hpp new file mode 100644 index 0000000..1885ea2 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/intel.hpp @@ -0,0 +1,552 @@ +// (C) Copyright John Maddock 2001-8. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright Guillaume Melquiond 2002 - 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Martin Wille 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Intel compiler setup: + +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__)) + +#ifdef _MSC_VER + +#include + +#undef BOOST_MSVC +#undef BOOST_MSVC_FULL_VER + +#if (__INTEL_COMPILER >= 1500) && (_MSC_VER >= 1900) +// +// These appear to be supported, even though VC++ may not support them: +// +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#undef BOOST_NO_CXX14_BINARY_LITERALS +// This one may be a little risky to enable?? +#undef BOOST_NO_SFINAE_EXPR + +#endif + +#if (__INTEL_COMPILER <= 1600) && !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#else + +#include + +#undef BOOST_GCC_VERSION +#undef BOOST_GCC_CXX11 + +#endif + +#undef BOOST_COMPILER + +#if defined(__INTEL_COMPILER) +#if __INTEL_COMPILER == 9999 +# define BOOST_INTEL_CXX_VERSION 1200 // Intel bug in 12.1. +#else +# define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER +#endif +#elif defined(__ICL) +# define BOOST_INTEL_CXX_VERSION __ICL +#elif defined(__ICC) +# define BOOST_INTEL_CXX_VERSION __ICC +#elif defined(__ECC) +# define BOOST_INTEL_CXX_VERSION __ECC +#endif + +// Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' +#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_INTEL_STDCXX0X +#endif +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_INTEL_STDCXX0X +#endif + +#ifdef __GNUC__ +# define BOOST_INTEL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#if !defined(BOOST_COMPILER) +# if defined(BOOST_INTEL_STDCXX0X) +# define BOOST_COMPILER "Intel C++ C++0x mode version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# else +# define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# endif +#endif + +#define BOOST_INTEL BOOST_INTEL_CXX_VERSION + +#if defined(_WIN32) || defined(_WIN64) +# define BOOST_INTEL_WIN BOOST_INTEL +#else +# define BOOST_INTEL_LINUX BOOST_INTEL +#endif + +#else + +#include + +#if defined(__INTEL_COMPILER) +#if __INTEL_COMPILER == 9999 +# define BOOST_INTEL_CXX_VERSION 1200 // Intel bug in 12.1. +#else +# define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER +#endif +#elif defined(__ICL) +# define BOOST_INTEL_CXX_VERSION __ICL +#elif defined(__ICC) +# define BOOST_INTEL_CXX_VERSION __ICC +#elif defined(__ECC) +# define BOOST_INTEL_CXX_VERSION __ECC +#endif + +// Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' +#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_INTEL_STDCXX0X +#endif +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_INTEL_STDCXX0X +#endif + +#ifdef __GNUC__ +# define BOOST_INTEL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#if !defined(BOOST_COMPILER) +# if defined(BOOST_INTEL_STDCXX0X) +# define BOOST_COMPILER "Intel C++ C++0x mode version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# else +# define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# endif +#endif + +#define BOOST_INTEL BOOST_INTEL_CXX_VERSION + +#if defined(_WIN32) || defined(_WIN64) +# define BOOST_INTEL_WIN BOOST_INTEL +#else +# define BOOST_INTEL_LINUX BOOST_INTEL +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 600) + +# if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov) + +// Boost libraries assume strong standard conformance unless otherwise +// indicated by a config macro. As configured by Intel, the EDG front-end +// requires certain compiler options be set to achieve that strong conformance. +// Particularly /Qoption,c,--arg_dep_lookup (reported by Kirk Klobe & Thomas Witt) +// and /Zc:wchar_t,forScope. See boost-root/tools/build/intel-win32-tools.jam for +// details as they apply to particular versions of the compiler. When the +// compiler does not predefine a macro indicating if an option has been set, +// this config file simply assumes the option has been set. +// Thus BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP will not be defined, even if +// the compiler option is not enabled. + +# define BOOST_NO_SWPRINTF +# endif + +// Void returns, 64 bit integrals don't work when emulating VC 6 (Peter Dimov) + +# if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_VOID_RETURNS +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 710) && defined(_WIN32) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +// See http://aspn.activestate.com/ASPN/Mail/Message/boost/1614864 +#if BOOST_INTEL_CXX_VERSION < 600 +# define BOOST_NO_INTRINSIC_WCHAR_T +#else +// We should test the macro _WCHAR_T_DEFINED to check if the compiler +// supports wchar_t natively. *BUT* there is a problem here: the standard +// headers define this macro if they typedef wchar_t. Anyway, we're lucky +// because they define it without a value, while Intel C++ defines it +// to 1. So we can check its value to see if the macro was defined natively +// or not. +// Under UNIX, the situation is exactly the same, but the macro _WCHAR_T +// is used instead. +# if ((_WCHAR_T_DEFINED + 0) == 0) && ((_WCHAR_T + 0) == 0) +# define BOOST_NO_INTRINSIC_WCHAR_T +# endif +#endif + +#if defined(__GNUC__) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +// +// Figure out when Intel is emulating this gcc bug +// (All Intel versions prior to 9.0.26, and versions +// later than that if they are set up to emulate gcc 3.2 +// or earlier): +// +# if ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 2)) || (BOOST_INTEL < 900) || (__INTEL_COMPILER_BUILD_DATE < 20050912) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# endif +#endif +#if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_WIN32) && (BOOST_INTEL_CXX_VERSION <= 1200)) || (BOOST_INTEL_CXX_VERSION <= 1200) +// GCC or VC emulation: +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif +// +// Verify that we have actually got BOOST_NO_INTRINSIC_WCHAR_T +// set correctly, if we don't do this now, we will get errors later +// in type_traits code among other things, getting this correct +// for the Intel compiler is actually remarkably fragile and tricky: +// +#ifdef __cplusplus +#if defined(BOOST_NO_INTRINSIC_WCHAR_T) +#include +template< typename T > struct assert_no_intrinsic_wchar_t; +template<> struct assert_no_intrinsic_wchar_t { typedef void type; }; +// if you see an error here then you need to unset BOOST_NO_INTRINSIC_WCHAR_T +// where it is defined above: +typedef assert_no_intrinsic_wchar_t::type assert_no_intrinsic_wchar_t_; +#else +template< typename T > struct assert_intrinsic_wchar_t; +template<> struct assert_intrinsic_wchar_t {}; +// if you see an error here then define BOOST_NO_INTRINSIC_WCHAR_T on the command line: +template<> struct assert_intrinsic_wchar_t {}; +#endif +#endif + +#if defined(_MSC_VER) && (_MSC_VER+0 >= 1000) +# if _MSC_VER >= 1200 +# define BOOST_HAS_MS_INT64 +# endif +# define BOOST_NO_SWPRINTF +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#elif defined(_WIN32) +# define BOOST_DISABLE_WIN32 +#endif + +// I checked version 6.0 build 020312Z, it implements the NRVO. +// Correct this as you find out which version of the compiler +// implemented the NRVO first. (Daniel Frey) +#if (BOOST_INTEL_CXX_VERSION >= 600) +# define BOOST_HAS_NRVO +#endif + +// Branch prediction hints +// I'm not sure 8.0 was the first version to support these builtins, +// update the condition if the version is not accurate. (Andrey Semashev) +#if defined(__GNUC__) && BOOST_INTEL_CXX_VERSION >= 800 +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif + +// RTTI +// __RTTI is the EDG macro +// __INTEL_RTTI__ is the Intel macro +// __GXX_RTTI is the g++ macro +// _CPPRTTI is the MSVC++ macro +#if !defined(__RTTI) && !defined(__INTEL_RTTI__) && !defined(__GXX_RTTI) && !defined(_CPPRTTI) + +#if !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// in MS mode, static typeid works even when RTTI is off +#if !defined(_MSC_VER) && !defined(BOOST_NO_TYPEID) +# define BOOST_NO_TYPEID +#endif + +#endif + +// +// versions check: +// we don't support Intel prior to version 6.0: +#if BOOST_INTEL_CXX_VERSION < 600 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// Intel on MacOS requires +#if defined(__APPLE__) && defined(__INTEL_COMPILER) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +// Intel on Altix Itanium +#if defined(__itanium__) && defined(__INTEL_COMPILER) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +// +// An attempt to value-initialize a pointer-to-member may trigger an +// internal error on Intel <= 11.1 (last checked version), as was +// reported by John Maddock, Intel support issue 589832, May 2010. +// Moreover, according to test results from Huang-Vista-x86_32_intel, +// intel-vc9-win-11.1 may leave a non-POD array uninitialized, in some +// cases when it should be value-initialized. +// (Niels Dekker, LKEB, May 2010) +// Apparently Intel 12.1 (compiler version number 9999 !!) has the same issue (compiler regression). +#if defined(__INTEL_COMPILER) +# if (__INTEL_COMPILER <= 1110) || (__INTEL_COMPILER == 9999) || (defined(_WIN32) && (__INTEL_COMPILER < 1600)) +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# endif +#endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) +#endif +// +// C++0x features +// For each feature we need to check both the Intel compiler version, +// and the version of MSVC or GCC that we are emulating. +// See http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler/ +// for a list of which features were implemented in which Intel releases. +// +#if defined(BOOST_INTEL_STDCXX0X) +// BOOST_NO_CXX11_CONSTEXPR: +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && !defined(_MSC_VER) +// Available in earlier Intel versions, but fail our tests: +# undef BOOST_NO_CXX11_CONSTEXPR +#endif +// BOOST_NO_CXX11_NULLPTR: +#if (BOOST_INTEL_CXX_VERSION >= 1210) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_NULLPTR +#endif +// BOOST_NO_CXX11_TEMPLATE_ALIASES +#if (BOOST_INTEL_CXX_VERSION >= 1210) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_TEMPLATE_ALIASES +#endif + +// BOOST_NO_CXX11_DECLTYPE +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_DECLTYPE +#endif + +// BOOST_NO_CXX11_DECLTYPE_N3276 +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +// BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +// BOOST_NO_CXX11_RVALUE_REFERENCES +#if (BOOST_INTEL_CXX_VERSION >= 1300) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +// This is available from earlier Intel versions, but breaks Filesystem and other libraries: +# undef BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +// BOOST_NO_CXX11_STATIC_ASSERT +#if (BOOST_INTEL_CXX_VERSION >= 1110) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_STATIC_ASSERT +#endif + +// BOOST_NO_CXX11_VARIADIC_TEMPLATES +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +// BOOST_NO_CXX11_VARIADIC_MACROS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40200)) && (!defined(_MSC_VER) || (_MSC_VER >= 1400)) +# undef BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +// BOOST_NO_CXX11_AUTO_DECLARATIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_AUTO_DECLARATIONS +#endif + +// BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif + +// BOOST_NO_CXX11_CHAR16_T +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_CHAR16_T +#endif + +// BOOST_NO_CXX11_CHAR32_T +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_CHAR32_T +#endif + +// BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#endif + +// BOOST_NO_CXX11_DELETED_FUNCTIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DELETED_FUNCTIONS +#endif + +// BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +// BOOST_NO_CXX11_SCOPED_ENUMS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40501)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +// This is available but broken in earlier Intel releases. +# undef BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +// BOOST_NO_SFINAE_EXPR +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_SFINAE_EXPR +#endif + +// BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +// This is available in earlier Intel releases, but breaks Multiprecision: +# undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +// BOOST_NO_CXX11_LAMBDAS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_LAMBDAS +#endif + +// BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) +# undef BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +// BOOST_NO_CXX11_RANGE_BASED_FOR +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_RANGE_BASED_FOR +#endif + +// BOOST_NO_CXX11_RAW_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_RAW_LITERALS +#endif + +// BOOST_NO_CXX11_UNICODE_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +// BOOST_NO_CXX11_NOEXCEPT +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +// Available in earlier Intel release, but generates errors when used with +// conditional exception specifications, for example in multiprecision: +# undef BOOST_NO_CXX11_NOEXCEPT +#endif + +// BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +// BOOST_NO_CXX11_USER_DEFINED_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif + +// BOOST_NO_CXX11_ALIGNAS +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_ALIGNAS +#endif + +// BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +// BOOST_NO_CXX11_INLINE_NAMESPACES +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +// BOOST_NO_CXX11_REF_QUALIFIERS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_REF_QUALIFIERS +#endif + +// BOOST_NO_CXX11_FINAL +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_FINAL +#endif + +#endif + +// +// Broken in all versions up to 15: +#define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS + +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION <= 1310) +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION == 1400) +// A regression in Intel's compiler means that seems to be broken in this release as well as : +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +// Broken in all versions up to 17: +#if !defined(BOOST_NO_CXX14_CONSTEXPR) +#define BOOST_NO_CXX14_CONSTEXPR +#endif + +#if (BOOST_INTEL_CXX_VERSION < 1200) +// +// fenv.h appears not to work with Intel prior to 12.0: +// +# define BOOST_NO_FENV_H +#endif + +// Intel 13.10 fails to access defaulted functions of a base class declared in private or protected sections, +// producing the following errors: +// error #453: protected function "..." (declared at ...") is not accessible through a "..." pointer or object +#if (BOOST_INTEL_CXX_VERSION <= 1310) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_HAS_STDINT_H +#endif + +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__LP64__) && defined(__GNUC__) && (BOOST_INTEL_CXX_VERSION >= 1310) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_INT128 +#endif + +#endif +// +// last known and checked version: +#if (BOOST_INTEL_CXX_VERSION > 1500) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# elif defined(_MSC_VER) +// +// We don't emit this warning any more, since we have so few +// defect macros set anyway (just the one). +// +//# pragma message("Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + diff --git a/thirdparty/linux/include/boost/config/compiler/kai.hpp b/thirdparty/linux/include/boost/config/compiler/kai.hpp new file mode 100644 index 0000000..960d501 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/kai.hpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Kai C++ compiler setup: + +#include + +# if (__KCC_VERSION <= 4001) || !defined(BOOST_STRICT_CONFIG) + // at least on Sun, the contents of is not in namespace std +# define BOOST_NO_STDC_NAMESPACE +# endif + +// see also common_edg.hpp which needs a special check for __KCC +# if !defined(_EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +// +// last known and checked version is 4001: +#if (__KCC_VERSION > 4001) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + diff --git a/thirdparty/linux/include/boost/config/compiler/metrowerks.hpp b/thirdparty/linux/include/boost/config/compiler/metrowerks.hpp new file mode 100644 index 0000000..3c5e228 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/metrowerks.hpp @@ -0,0 +1,180 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Stefan Slapeta 2004. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Metrowerks C++ compiler setup: + +// locale support is disabled when linking with the dynamic runtime +# ifdef _MSL_NO_LOCALE +# define BOOST_NO_STD_LOCALE +# endif + +# if __MWERKS__ <= 0x2301 // 5.3 +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# define BOOST_NO_POINTER_TO_MEMBER_CONST +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# endif + +# if __MWERKS__ <= 0x2401 // 6.2 +//# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if(__MWERKS__ <= 0x2407) // 7.x +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# endif + +# if(__MWERKS__ <= 0x3003) // 8.x +# define BOOST_NO_SFINAE +# endif + +// the "|| !defined(BOOST_STRICT_CONFIG)" part should apply to the last +// tested version *only*: +# if(__MWERKS__ <= 0x3207) || !defined(BOOST_STRICT_CONFIG) // 9.6 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_IS_ABSTRACT +# endif + +#if !__option(wchar_type) +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +#if !__option(exceptions) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if (__INTEL__ && _WIN32) || (__POWERPC__ && macintosh) +# if __MWERKS__ == 0x3000 +# define BOOST_COMPILER_VERSION 8.0 +# elif __MWERKS__ == 0x3001 +# define BOOST_COMPILER_VERSION 8.1 +# elif __MWERKS__ == 0x3002 +# define BOOST_COMPILER_VERSION 8.2 +# elif __MWERKS__ == 0x3003 +# define BOOST_COMPILER_VERSION 8.3 +# elif __MWERKS__ == 0x3200 +# define BOOST_COMPILER_VERSION 9.0 +# elif __MWERKS__ == 0x3201 +# define BOOST_COMPILER_VERSION 9.1 +# elif __MWERKS__ == 0x3202 +# define BOOST_COMPILER_VERSION 9.2 +# elif __MWERKS__ == 0x3204 +# define BOOST_COMPILER_VERSION 9.3 +# elif __MWERKS__ == 0x3205 +# define BOOST_COMPILER_VERSION 9.4 +# elif __MWERKS__ == 0x3206 +# define BOOST_COMPILER_VERSION 9.5 +# elif __MWERKS__ == 0x3207 +# define BOOST_COMPILER_VERSION 9.6 +# else +# define BOOST_COMPILER_VERSION __MWERKS__ +# endif +#else +# define BOOST_COMPILER_VERSION __MWERKS__ +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if __MWERKS__ > 0x3206 && __option(rvalue_refs) +# define BOOST_HAS_RVALUE_REFS +#else +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// +// versions check: +// we don't support Metrowerks prior to version 5.3: +#if __MWERKS__ < 0x2301 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version: +#if (__MWERKS__ > 0x3205) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + + + + diff --git a/thirdparty/linux/include/boost/config/compiler/mpw.hpp b/thirdparty/linux/include/boost/config/compiler/mpw.hpp new file mode 100644 index 0000000..084f9e1 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/mpw.hpp @@ -0,0 +1,122 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// MPW C++ compilers setup: + +# if defined(__SC__) +# define BOOST_COMPILER "MPW SCpp version " BOOST_STRINGIZE(__SC__) +# elif defined(__MRC__) +# define BOOST_COMPILER "MPW MrCpp version " BOOST_STRINGIZE(__MRC__) +# else +# error "Using MPW compiler configuration by mistake. Please update." +# endif + +// +// MPW 8.90: +// +#if (MPW_CPLUS <= 0x890) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define BOOST_NO_USING_TEMPLATE + +# define BOOST_NO_CWCHAR +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + +# define BOOST_NO_STD_ALLOCATOR /* actually a bug with const reference overloading */ + +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// +// versions check: +// we don't support MPW prior to version 8.9: +#if MPW_CPLUS < 0x890 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0x890: +#if (MPW_CPLUS > 0x890) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/thirdparty/linux/include/boost/config/compiler/nvcc.hpp b/thirdparty/linux/include/boost/config/compiler/nvcc.hpp new file mode 100644 index 0000000..b31d4f4 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/nvcc.hpp @@ -0,0 +1,32 @@ +// (C) Copyright Eric Jourdanneau, Joel Falcou 2010 +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// NVIDIA CUDA C++ compiler setup + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "NVIDIA CUDA C++ Compiler" +#endif + +// NVIDIA Specific support +// BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device +#define BOOST_GPU_ENABLED __host__ __device__ + +// A bug in version 7.0 of CUDA prevents use of variadic templates in some occasions +// https://svn.boost.org/trac/boost/ticket/11897 +// This is fixed in 7.5. As the following version macro was introduced in 7.5 an existance +// check is enough to detect versions < 7.5 +#if !defined(__CUDACC_VER__) || (__CUDACC_VER__ < 70500) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +// The same bug is back again in 8.0: +#if (__CUDACC_VER__ > 80000) && (__CUDACC_VER__ < 80100) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +// Most recent CUDA (8.0) has no constexpr support in msvc mode: +#if defined(_MSC_VER) +# define BOOST_NO_CXX11_CONSTEXPR +#endif diff --git a/thirdparty/linux/include/boost/config/compiler/pathscale.hpp b/thirdparty/linux/include/boost/config/compiler/pathscale.hpp new file mode 100644 index 0000000..a5e65af --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/pathscale.hpp @@ -0,0 +1,115 @@ +// (C) Copyright Bryce Lelbach 2011 + +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// PathScale EKOPath C++ Compiler + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "PathScale EKOPath C++ Compiler version " __PATHSCALE__ +#endif + +#if __PATHCC__ >= 4 +# define BOOST_MSVC6_MEMBER_TEMPLATES +# define BOOST_HAS_UNISTD_H +# define BOOST_HAS_STDINT_H +# define BOOST_HAS_SIGACTION +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_THREADS +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_PTHREAD_YIELD +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +# define BOOST_HAS_NRVO +# define BOOST_HAS_NL_TYPES_H +# define BOOST_HAS_NANOSLEEP +# define BOOST_HAS_LONG_LONG +# define BOOST_HAS_LOG1P +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_EXPM1 +# define BOOST_HAS_DIRENT_H +# define BOOST_HAS_CLOCK_GETTIME +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif +#endif diff --git a/thirdparty/linux/include/boost/config/compiler/pgi.hpp b/thirdparty/linux/include/boost/config/compiler/pgi.hpp new file mode 100644 index 0000000..fa2d5e4 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/pgi.hpp @@ -0,0 +1,156 @@ +// (C) Copyright Noel Belcourt 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// PGI C++ compiler setup: + +#define BOOST_COMPILER_VERSION __PGIC__##__PGIC_MINOR__ +#define BOOST_COMPILER "PGI compiler version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// +// Threading support: +// Turn this on unconditionally here, it will get turned off again later +// if no threading API is detected. +// + +#if __PGIC__ >= 11 + +// options requested by configure --enable-test +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_THREADS +#define BOOST_HAS_PTHREAD_YIELD +#define BOOST_HAS_NRVO +#define BOOST_HAS_LONG_LONG + +// options --enable-test wants undefined +#undef BOOST_NO_STDC_NAMESPACE +#undef BOOST_NO_EXCEPTION_STD_NAMESPACE +#undef BOOST_DEDUCED_TYPENAME + +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_AUTO_DECLARATIONS + +#elif __PGIC__ >= 10 + +// options requested by configure --enable-test +#define BOOST_HAS_THREADS +#define BOOST_HAS_NRVO +#define BOOST_HAS_LONG_LONG +#if defined(linux) || defined(__linux) || defined(__linux__) +# define BOOST_HAS_STDINT_H +#endif + +// options --enable-test wants undefined +#undef BOOST_NO_STDC_NAMESPACE +#undef BOOST_NO_EXCEPTION_STD_NAMESPACE +#undef BOOST_DEDUCED_TYPENAME + +#elif __PGIC__ >= 7 + +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_NO_SWPRINTF +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_AUTO_DECLARATIONS + +#else + +# error "Pgi compiler not configured - please reconfigure" + +#endif +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_NUMERIC_LIMITS +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_SWPRINTF +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX + +#define BOOST_NO_CXX11_HDR_UNORDERED_SET +#define BOOST_NO_CXX11_HDR_UNORDERED_MAP +#define BOOST_NO_CXX11_HDR_TYPEINDEX +#define BOOST_NO_CXX11_HDR_TYPE_TRAITS +#define BOOST_NO_CXX11_HDR_TUPLE +#define BOOST_NO_CXX11_HDR_THREAD +#define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +#define BOOST_NO_CXX11_HDR_REGEX +#define BOOST_NO_CXX11_HDR_RATIO +#define BOOST_NO_CXX11_HDR_RANDOM +#define BOOST_NO_CXX11_HDR_MUTEX +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_HDR_FUTURE +#define BOOST_NO_CXX11_HDR_FORWARD_LIST +#define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +#define BOOST_NO_CXX11_HDR_CODECVT +#define BOOST_NO_CXX11_HDR_CHRONO +#define BOOST_NO_CXX11_HDR_ARRAY +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif +// +// version check: +// probably nothing to do here? + diff --git a/thirdparty/linux/include/boost/config/compiler/sgi_mipspro.hpp b/thirdparty/linux/include/boost/config/compiler/sgi_mipspro.hpp new file mode 100644 index 0000000..54433c9 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/sgi_mipspro.hpp @@ -0,0 +1,29 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// SGI C++ compiler setup: + +#define BOOST_COMPILER "SGI Irix compiler version " BOOST_STRINGIZE(_COMPILER_VERSION) + +#include + +// +// Threading support: +// Turn this on unconditionally here, it will get turned off again later +// if no threading API is detected. +// +#define BOOST_HAS_THREADS +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +#undef BOOST_NO_SWPRINTF +#undef BOOST_DEDUCED_TYPENAME + +// +// version check: +// probably nothing to do here? + + diff --git a/thirdparty/linux/include/boost/config/compiler/sunpro_cc.hpp b/thirdparty/linux/include/boost/config/compiler/sunpro_cc.hpp new file mode 100644 index 0000000..ac259fc --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/sunpro_cc.hpp @@ -0,0 +1,198 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Peter Dimov 2002. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright David Abrahams 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Sun C++ compiler setup: + +# if __SUNPRO_CC <= 0x500 +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if (__SUNPRO_CC <= 0x520) + // + // Sunpro 5.2 and earler: + // + // although sunpro 5.2 supports the syntax for + // inline initialization it often gets the value + // wrong, especially where the value is computed + // from other constants (J Maddock 6th May 2001) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // Although sunpro 5.2 supports the syntax for + // partial specialization, it often seems to + // bind to the wrong specialization. Better + // to disable it until suppport becomes more stable + // (J Maddock 6th May 2001). +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# endif + +# if (__SUNPRO_CC <= 0x530) + // Requesting debug info (-g) with Boost.Python results + // in an internal compiler error for "static const" + // initialized in-class. + // >> Assertion: (../links/dbg_cstabs.cc, line 611) + // while processing ../test.cpp at line 0. + // (Jens Maurer according to Gottfried Ganssauge 04 Mar 2002) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // SunPro 5.3 has better support for partial specialization, + // but breaks when compiling std::less > + // (Jens Maurer 4 Nov 2001). + + // std::less specialization fixed as reported by George + // Heintzelman; partial specialization re-enabled + // (Peter Dimov 17 Jan 2002) + +//# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // integral constant expressions with 64 bit numbers fail +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +# if (__SUNPRO_CC < 0x570) +# define BOOST_NO_TEMPLATE_TEMPLATES + // see http://lists.boost.org/MailArchives/boost/msg47184.php + // and http://lists.boost.org/MailArchives/boost/msg47220.php +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_SFINAE +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif +# if (__SUNPRO_CC <= 0x580) +# define BOOST_NO_IS_ABSTRACT +# endif + +# if (__SUNPRO_CC <= 0x5100) + // Sun 5.10 may not correctly value-initialize objects of + // some user defined types, as was reported in April 2010 + // (CR 6947016), and confirmed by Steve Clamage. + // (Niels Dekker, LKEB, May 2010). +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __SUNPRO_CC > 0x500 +# define BOOST_SYMBOL_EXPORT __global +# define BOOST_SYMBOL_IMPORT __global +# define BOOST_SYMBOL_VISIBLE __global +#endif + +#if (__SUNPRO_CC < 0x5130) +// C++03 features in 12.4: +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_ADL_BARRIER +#define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#if (__SUNPRO_CC < 0x5130) || (__cplusplus < 201100) +// C++11 only featuires in 12.4: +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_FINAL +#endif + +#if (__SUNPRO_CC < 0x5140) || (__cplusplus < 201103) +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// +// C++0x features +// +# define BOOST_HAS_LONG_LONG + + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) || (__cplusplus < 201402L) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// Turn on threading support for Solaris 12. +// Ticket #11972 +#if (__SUNPRO_CC >= 0x5140) && defined(__SunOS_5_12) && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Version +// + +#define BOOST_COMPILER "Sun compiler version " BOOST_STRINGIZE(__SUNPRO_CC) + +// +// versions check: +// we don't support sunpro prior to version 4: +#if __SUNPRO_CC < 0x400 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0x590: +#if (__SUNPRO_CC > 0x590) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/thirdparty/linux/include/boost/config/compiler/vacpp.hpp b/thirdparty/linux/include/boost/config/compiler/vacpp.hpp new file mode 100644 index 0000000..3fbed9f --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/vacpp.hpp @@ -0,0 +1,163 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Toon Knapen 2001 - 2003. +// (C) Copyright Lie-Quan Lee 2001. +// (C) Copyright Markus Schoepflin 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Visual Age (IBM) C++ compiler setup: + +#if __IBMCPP__ <= 501 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +#if (__IBMCPP__ <= 502) +// Actually the compiler supports inclass member initialization but it +// requires a definition for the class member and it doesn't recognize +// it as an integral constant expression when used as a template argument. +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +#if (__IBMCPP__ <= 600) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +#if (__IBMCPP__ <= 1110) +// XL C++ V11.1 and earlier versions may not always value-initialize +// a temporary object T(), when T is a non-POD aggregate class type. +// Michael Wong (IBM Canada Ltd) has confirmed this issue and gave it +// high priority. -- Niels Dekker (LKEB), May 2010. +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + +// +// On AIX thread support seems to be indicated by _THREAD_SAFE: +// +#ifdef _THREAD_SAFE +# define BOOST_HAS_THREADS +#endif + +#define BOOST_COMPILER "IBM Visual Age version " BOOST_STRINGIZE(__IBMCPP__) + +// +// versions check: +// we don't support Visual age prior to version 5: +#if __IBMCPP__ < 500 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 1210: +#if (__IBMCPP__ > 1210) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + +// Some versions of the compiler have issues with default arguments on partial specializations +#if __IBMCPP__ <= 1010 +#define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if ! __IBMCPP_AUTO_TYPEDEDUCTION +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif +#if ! __IBMCPP_UTF_LITERAL__ +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif +#if ! __IBMCPP_CONSTEXPR +# define BOOST_NO_CXX11_CONSTEXPR +#endif +#if ! __IBMCPP_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE +#else +# define BOOST_HAS_DECLTYPE +#endif +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#if ! __IBMCPP_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif +#if ! __IBMCPP_EXTERN_TEMPLATE +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if ! __IBMCPP_VARIADIC_TEMPLATES +// not enabled separately at this time +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#if ! __IBMCPP_RVALUE_REFERENCES +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif +#if ! __IBMCPP_SCOPED_ENUM +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if ! __IBMCPP_STATIC_ASSERT +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#if ! __IBMCPP_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +#if ! __C99_MACRO_WITH_VA_ARGS +# define BOOST_NO_CXX11_VARIADIC_MACROS +#endif +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif diff --git a/thirdparty/linux/include/boost/config/compiler/visualc.hpp b/thirdparty/linux/include/boost/config/compiler/visualc.hpp new file mode 100644 index 0000000..cdbc9b6 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/visualc.hpp @@ -0,0 +1,303 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. +// +// Microsoft Visual C++ compiler setup: +// +// We need to be careful with the checks in this file, as contrary +// to popular belief there are versions with _MSC_VER with the final +// digit non-zero (mainly the MIPS cross compiler). +// +// So we either test _MSC_VER >= XXXX or else _MSC_VER < XXXX. +// No other comparisons (==, >, or <=) are safe. +// + +#define BOOST_MSVC _MSC_VER + +// +// Helper macro BOOST_MSVC_FULL_VER for use in Boost code: +// +#if _MSC_FULL_VER > 100000000 +# define BOOST_MSVC_FULL_VER _MSC_FULL_VER +#else +# define BOOST_MSVC_FULL_VER (_MSC_FULL_VER * 10) +#endif + +// Attempt to suppress VC6 warnings about the length of decorated names (obsolete): +#pragma warning( disable : 4503 ) // warning: decorated name length exceeded + +#define BOOST_HAS_PRAGMA_ONCE + +// +// versions check: +// we don't support Visual C++ prior to version 7.1: +#if _MSC_VER < 1310 +# error "Compiler not supported or configured - please reconfigure" +#endif + +#if _MSC_FULL_VER < 180020827 +# define BOOST_NO_FENV_H +#endif + +#if _MSC_VER < 1400 +// although a conforming signature for swprint exists in VC7.1 +// it appears not to actually work: +# define BOOST_NO_SWPRINTF +// Our extern template tests also fail for this compiler: +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +// Variadic macros do not exist for VC7.1 and lower +# define BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +#if _MSC_VER < 1500 // 140X == VC++ 8.0 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +#if _MSC_VER < 1600 // 150X == VC++ 9.0 + // A bug in VC9: +# define BOOST_NO_ADL_BARRIER +#endif + + +#ifndef _NATIVE_WCHAR_T_DEFINED +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +// +// check for exception handling support: +#if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +// +// __int64 support: +// +#define BOOST_HAS_MS_INT64 +#if defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400) +# define BOOST_HAS_LONG_LONG +#else +# define BOOST_NO_LONG_LONG +#endif +#if (_MSC_VER >= 1400) && !defined(_DEBUG) +# define BOOST_HAS_NRVO +#endif +#if _MSC_VER >= 1600 // 160X == VC++ 10.0 +# define BOOST_HAS_PRAGMA_DETECT_MISMATCH +#endif +// +// disable Win32 API's if compiler extensions are +// turned off: +// +#if !defined(_MSC_EXTENSIONS) && !defined(BOOST_DISABLE_WIN32) +# define BOOST_DISABLE_WIN32 +#endif +#if !defined(_CPPRTTI) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// +// TR1 features: +// +#if _MSC_VER >= 1700 +// # define BOOST_HAS_TR1_HASH // don't know if this is true yet. +// # define BOOST_HAS_TR1_TYPE_TRAITS // don't know if this is true yet. +# define BOOST_HAS_TR1_UNORDERED_MAP +# define BOOST_HAS_TR1_UNORDERED_SET +#endif + +// +// C++0x features +// +// See above for BOOST_NO_LONG_LONG + +// C++ features supported by VC++ 10 (aka 2010) +// +#if _MSC_VER < 1600 +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_DECLTYPE +#endif // _MSC_VER < 1600 + +#if _MSC_VER >= 1600 +# define BOOST_HAS_STDINT_H +#endif + +// C++11 features supported by VC++ 11 (aka 2012) +// +#if _MSC_VER < 1700 +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif // _MSC_VER < 1700 + +// C++11 features supported by VC++ 12 (aka 2013). +// +#if _MSC_FULL_VER < 180020827 +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +#if _MSC_FULL_VER >= 180020827 +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +// C++11 features supported by VC++ 14 (aka 2015) +// +#if (_MSC_FULL_VER < 190023026) +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX14_DECLTYPE_AUTO +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# define BOOST_NO_CXX14_BINARY_LITERALS +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif +// C++11 features supported by VC++ 14 update 3 (aka 2015) +// +#if (_MSC_FULL_VER < 190024210) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +// C++14 features supported by VC++ 15 Preview 5 +// +#if (_MSC_VER < 1910) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +# define BOOST_NO_CXX14_CONSTEXPR +#endif + +// MSVC including version 14 has not yet completely +// implemented value-initialization, as is reported: +// "VC++ does not value-initialize members of derived classes without +// user-declared constructor", reported in 2009 by Sylvester Hesp: +// https://connect.microsoft.com/VisualStudio/feedback/details/484295 +// "Presence of copy constructor breaks member class initialization", +// reported in 2009 by Alex Vakulenko: +// https://connect.microsoft.com/VisualStudio/feedback/details/499606 +// "Value-initialization in new-expression", reported in 2005 by +// Pavel Kuznetsov (MetaCommunications Engineering): +// https://connect.microsoft.com/VisualStudio/feedback/details/100744 +// Reported again by John Maddock in 2015 for VC14: +// https://connect.microsoft.com/VisualStudio/feedback/details/1582233/c-subobjects-still-not-value-initialized-correctly +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, May 2010) +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// +// C++ 11: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +// +// prefix and suffix headers: +// +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/msvc_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/msvc_suffix.hpp" +#endif + +#ifndef BOOST_COMPILER +// TODO: +// these things are mostly bogus. 1200 means version 12.0 of the compiler. The +// artificial versions assigned to them only refer to the versions of some IDE +// these compilers have been shipped with, and even that is not all of it. Some +// were shipped with freely downloadable SDKs, others as crosscompilers in eVC. +// IOW, you can't use these 'versions' in any sensible way. Sorry. +# if defined(UNDER_CE) +# if _MSC_VER < 1400 + // Note: I'm not aware of any CE compiler with version 13xx +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# elif _MSC_VER < 1500 +# define BOOST_COMPILER_VERSION evc8 +# elif _MSC_VER < 1600 +# define BOOST_COMPILER_VERSION evc9 +# elif _MSC_VER < 1700 +# define BOOST_COMPILER_VERSION evc10 +# elif _MSC_VER < 1800 +# define BOOST_COMPILER_VERSION evc11 +# elif _MSC_VER < 1900 +# define BOOST_COMPILER_VERSION evc12 +# elif _MSC_VER < 2000 +# define BOOST_COMPILER_VERSION evc14 +# else +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# endif +# else +# if _MSC_VER < 1310 + // Note: Versions up to 7.0 aren't supported. +# define BOOST_COMPILER_VERSION 5.0 +# elif _MSC_VER < 1300 +# define BOOST_COMPILER_VERSION 6.0 +# elif _MSC_VER < 1310 +# define BOOST_COMPILER_VERSION 7.0 +# elif _MSC_VER < 1400 +# define BOOST_COMPILER_VERSION 7.1 +# elif _MSC_VER < 1500 +# define BOOST_COMPILER_VERSION 8.0 +# elif _MSC_VER < 1600 +# define BOOST_COMPILER_VERSION 9.0 +# elif _MSC_VER < 1700 +# define BOOST_COMPILER_VERSION 10.0 +# elif _MSC_VER < 1800 +# define BOOST_COMPILER_VERSION 11.0 +# elif _MSC_VER < 1900 +# define BOOST_COMPILER_VERSION 12.0 +# elif _MSC_VER < 2000 +# define BOOST_COMPILER_VERSION 14.0 +# else +# define BOOST_COMPILER_VERSION _MSC_VER +# endif +# endif + +# define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) +#endif + +// +// last known and checked version is 19.10.24629 (VC++ 2017 RC): +#if (_MSC_VER > 1910) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +# pragma message("Unknown compiler version - please run the configure tests and report the results") +# endif +#endif diff --git a/thirdparty/linux/include/boost/config/compiler/xlcpp.hpp b/thirdparty/linux/include/boost/config/compiler/xlcpp.hpp new file mode 100644 index 0000000..2aaafc3 --- /dev/null +++ b/thirdparty/linux/include/boost/config/compiler/xlcpp.hpp @@ -0,0 +1,262 @@ +// (C) Copyright Douglas Gregor 2010 +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// compiler setup for IBM XL C/C++ for Linux (Little Endian) based on clang. + +#define BOOST_HAS_PRAGMA_ONCE + +// Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used. +#if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) +# define BOOST_HAS_PRAGMA_DETECT_MISMATCH +#endif + +// When compiling with clang before __has_extension was defined, +// even if one writes 'defined(__has_extension) && __has_extension(xxx)', +// clang reports a compiler error. So the only workaround found is: + +#ifndef __has_extension +#define __has_extension __has_feature +#endif + +#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID) +# define BOOST_NO_TYPEID +#endif + +#if defined(__int64) && !defined(__GNUC__) +# define BOOST_HAS_MS_INT64 +#endif + +#define BOOST_HAS_NRVO + +// Branch prediction hints +#if defined(__has_builtin) +#if __has_builtin(__builtin_expect) +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif +#endif + +// Clang supports "long long" in all compilation modes. +#define BOOST_HAS_LONG_LONG + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#endif + +// +// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +// between switch labels. +// +#if __cplusplus >= 201103L && defined(__has_warning) +# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +# define BOOST_FALLTHROUGH [[clang::fallthrough]] +# endif +#endif + +#if !__has_feature(cxx_auto_type) +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif + +// +// Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t +// +#if defined(_MSC_VER) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif + +#if !__has_feature(cxx_constexpr) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#if !__has_feature(cxx_decltype) +# define BOOST_NO_CXX11_DECLTYPE +#endif + +#if !__has_feature(cxx_decltype_incomplete_return_types) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +#if !__has_feature(cxx_defaulted_functions) +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#endif + +#if !__has_feature(cxx_deleted_functions) +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +#endif + +#if !__has_feature(cxx_explicit_conversions) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +#if !__has_feature(cxx_default_function_template_args) +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if !__has_feature(cxx_lambdas) +# define BOOST_NO_CXX11_LAMBDAS +#endif + +#if !__has_feature(cxx_local_type_template_args) +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +#if !__has_feature(cxx_noexcept) +# define BOOST_NO_CXX11_NOEXCEPT +#endif + +#if !__has_feature(cxx_nullptr) +# define BOOST_NO_CXX11_NULLPTR +#endif + +#if !__has_feature(cxx_range_for) +# define BOOST_NO_CXX11_RANGE_BASED_FOR +#endif + +#if !__has_feature(cxx_raw_string_literals) +# define BOOST_NO_CXX11_RAW_LITERALS +#endif + +#if !__has_feature(cxx_reference_qualified_functions) +# define BOOST_NO_CXX11_REF_QUALIFIERS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +#if !__has_feature(cxx_rvalue_references) +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +#if !__has_feature(cxx_strong_enums) +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#if !__has_feature(cxx_static_assert) +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +#if !__has_feature(cxx_alias_templates) +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +#endif + +#if !__has_feature(cxx_unicode_literals) +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +#if !__has_feature(cxx_variadic_templates) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if !__has_feature(cxx_user_literals) +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif + +#if !__has_feature(cxx_alignas) +# define BOOST_NO_CXX11_ALIGNAS +#endif + +#if !__has_feature(cxx_trailing_return) +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +#if !__has_feature(cxx_inline_namespaces) +# define BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +#if !__has_feature(cxx_override_control) +# define BOOST_NO_CXX11_FINAL +#endif + +#if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__)) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +#if !__has_feature(__cxx_decltype_auto__) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif + +#if !__has_feature(__cxx_aggregate_nsdmi__) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif + +#if !__has_feature(__cxx_init_captures__) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif + +#if !__has_feature(__cxx_generic_lambdas__) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif + +// clang < 3.5 has a defect with dependent type, like following. +// +// template +// constexpr typename enable_if >::type foo(T &) +// { } // error: no return statement in constexpr function +// +// This issue also affects C++11 mode, but C++11 constexpr requires return stmt. +// Therefore we don't care such case. +// +// Note that we can't check Clang version directly as the numbering system changes depending who's +// creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873) +// so instead verify that we have a feature that was introduced at the same time as working C++14 +// constexpr (generic lambda's in this case): +// +#if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__) +# define BOOST_NO_CXX14_CONSTEXPR +#endif + +#if !__has_feature(__cxx_return_type_deduction__) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif + +#if !__has_feature(__cxx_variable_templates__) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#if !__has_feature(cxx_thread_local) +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#if __cplusplus < 201400 +// All versions with __cplusplus above this value seem to support this: +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif + + +// Unused attribute: +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define BOOST_ATTRIBUTE_UNUSED __attribute__((unused)) +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "Clang version " __clang_version__ +#endif + +// Macro used to identify the Clang compiler. +#define BOOST_CLANG 1 + diff --git a/thirdparty/linux/include/boost/config/no_tr1/cmath.hpp b/thirdparty/linux/include/boost/config/no_tr1/cmath.hpp new file mode 100644 index 0000000..d8268d8 --- /dev/null +++ b/thirdparty/linux/include/boost/config/no_tr1/cmath.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/cmath is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_CMATH +# define BOOST_CONFIG_CMATH + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_CMATH_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +#endif diff --git a/thirdparty/linux/include/boost/config/no_tr1/complex.hpp b/thirdparty/linux/include/boost/config/no_tr1/complex.hpp new file mode 100644 index 0000000..ca20092 --- /dev/null +++ b/thirdparty/linux/include/boost/config/no_tr1/complex.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/complex is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_COMPLEX +# define BOOST_CONFIG_COMPLEX + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_COMPLEX_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +#endif diff --git a/thirdparty/linux/include/boost/config/no_tr1/functional.hpp b/thirdparty/linux/include/boost/config/no_tr1/functional.hpp new file mode 100644 index 0000000..e395efc --- /dev/null +++ b/thirdparty/linux/include/boost/config/no_tr1/functional.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/functional is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_FUNCTIONAL +# define BOOST_CONFIG_FUNCTIONAL + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +#endif diff --git a/thirdparty/linux/include/boost/config/no_tr1/memory.hpp b/thirdparty/linux/include/boost/config/no_tr1/memory.hpp new file mode 100644 index 0000000..2b5d208 --- /dev/null +++ b/thirdparty/linux/include/boost/config/no_tr1/memory.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/memory is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_MEMORY +# define BOOST_CONFIG_MEMORY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_MEMORY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +#endif diff --git a/thirdparty/linux/include/boost/config/no_tr1/utility.hpp b/thirdparty/linux/include/boost/config/no_tr1/utility.hpp new file mode 100644 index 0000000..dea8f11 --- /dev/null +++ b/thirdparty/linux/include/boost/config/no_tr1/utility.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/utility is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_UTILITY +# define BOOST_CONFIG_UTILITY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_UTILITY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +#endif diff --git a/thirdparty/linux/include/boost/config/platform/aix.hpp b/thirdparty/linux/include/boost/config/platform/aix.hpp new file mode 100644 index 0000000..894ef42 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/aix.hpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// IBM/Aix specific config options: + +#define BOOST_PLATFORM "IBM Aix" + +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME + +// This needs support in "boost/cstdint.hpp" exactly like FreeBSD. +// This platform has header named which includes all +// the things needed. +#define BOOST_HAS_STDINT_H + +// Threading API's: +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_DELAY_NP +#define BOOST_HAS_SCHED_YIELD +//#define BOOST_HAS_PTHREAD_YIELD + +// boilerplate code: +#include + + + + diff --git a/thirdparty/linux/include/boost/config/platform/amigaos.hpp b/thirdparty/linux/include/boost/config/platform/amigaos.hpp new file mode 100644 index 0000000..34bcf41 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/amigaos.hpp @@ -0,0 +1,15 @@ +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +#define BOOST_PLATFORM "AmigaOS" + +#define BOOST_DISABLE_THREADS +#define BOOST_NO_CWCHAR +#define BOOST_NO_STD_WSTRING +#define BOOST_NO_INTRINSIC_WCHAR_T + + diff --git a/thirdparty/linux/include/boost/config/platform/beos.hpp b/thirdparty/linux/include/boost/config/platform/beos.hpp new file mode 100644 index 0000000..48c3d8d --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/beos.hpp @@ -0,0 +1,26 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// BeOS specific config options: + +#define BOOST_PLATFORM "BeOS" + +#define BOOST_NO_CWCHAR +#define BOOST_NO_CWCTYPE +#define BOOST_HAS_UNISTD_H + +#define BOOST_HAS_BETHREADS + +#ifndef BOOST_DISABLE_THREADS +# define BOOST_HAS_THREADS +#endif + +// boilerplate code: +#include + + + diff --git a/thirdparty/linux/include/boost/config/platform/bsd.hpp b/thirdparty/linux/include/boost/config/platform/bsd.hpp new file mode 100644 index 0000000..a014297 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/bsd.hpp @@ -0,0 +1,86 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Douglas Gregor 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// generic BSD config options: + +#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) +#error "This platform is not BSD" +#endif + +#ifdef __FreeBSD__ +#define BOOST_PLATFORM "FreeBSD " BOOST_STRINGIZE(__FreeBSD__) +#elif defined(__NetBSD__) +#define BOOST_PLATFORM "NetBSD " BOOST_STRINGIZE(__NetBSD__) +#elif defined(__OpenBSD__) +#define BOOST_PLATFORM "OpenBSD " BOOST_STRINGIZE(__OpenBSD__) +#elif defined(__DragonFly__) +#define BOOST_PLATFORM "DragonFly " BOOST_STRINGIZE(__DragonFly__) +#endif + +// +// is this the correct version check? +// FreeBSD has but does not +// advertise the fact in : +// +#if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) || defined(__DragonFly__) +# define BOOST_HAS_NL_TYPES_H +#endif + +// +// FreeBSD 3.x has pthreads support, but defines _POSIX_THREADS in +// and not in +// +#if (defined(__FreeBSD__) && (__FreeBSD__ <= 3))\ + || defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_HAS_PTHREADS +#endif + +// +// No wide character support in the BSD header files: +// +#if defined(__NetBSD__) +#define __NetBSD_GCC__ (__GNUC__ * 1000000 \ + + __GNUC_MINOR__ * 1000 \ + + __GNUC_PATCHLEVEL__) +// XXX - the following is required until c++config.h +// defines _GLIBCXX_HAVE_SWPRINTF and friends +// or the preprocessor conditionals are removed +// from the cwchar header. +#define _GLIBCXX_HAVE_SWPRINTF 1 +#endif + +#if !((defined(__FreeBSD__) && (__FreeBSD__ >= 5)) \ + || (defined(__NetBSD_GCC__) && (__NetBSD_GCC__ >= 2095003)) || defined(__DragonFly__)) +# define BOOST_NO_CWCHAR +#endif +// +// The BSD has macros only, no functions: +// +#if !defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// thread API's not auto detected: +// +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_SIGACTION + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + + + + diff --git a/thirdparty/linux/include/boost/config/platform/cloudabi.hpp b/thirdparty/linux/include/boost/config/platform/cloudabi.hpp new file mode 100644 index 0000000..bed7b63 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/cloudabi.hpp @@ -0,0 +1,18 @@ +// Copyright Nuxi, https://nuxi.nl/ 2015. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#define BOOST_PLATFORM "CloudABI" + +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_UNISTD_H + +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_LOG1P +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_SCHED_YIELD diff --git a/thirdparty/linux/include/boost/config/platform/cray.hpp b/thirdparty/linux/include/boost/config/platform/cray.hpp new file mode 100644 index 0000000..5c476e4 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/cray.hpp @@ -0,0 +1,18 @@ +// (C) Copyright John Maddock 2011. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// SGI Irix specific config options: + +#define BOOST_PLATFORM "Cray" + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + diff --git a/thirdparty/linux/include/boost/config/platform/cygwin.hpp b/thirdparty/linux/include/boost/config/platform/cygwin.hpp new file mode 100644 index 0000000..b7ef572 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/cygwin.hpp @@ -0,0 +1,58 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// cygwin specific config options: + +#define BOOST_PLATFORM "Cygwin" +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 + +// +// Threading API: +// See if we have POSIX threads, if we do use them, otherwise +// revert to native Win threads. +#define BOOST_HAS_UNISTD_H +#include +#if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_SIGACTION +#else +# if !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_WINTHREADS +# endif +# define BOOST_HAS_FTIME +#endif + +// +// find out if we have a stdint.h, there should be a better way to do this: +// +#include +#ifdef _STDINT_H +#define BOOST_HAS_STDINT_H +#endif + +/// Cygwin has no fenv.h +#define BOOST_NO_FENV_H + +// boilerplate code: +#include + +// +// Cygwin lies about XSI conformance, there is no nl_types.h: +// +#ifdef BOOST_HAS_NL_TYPES_H +# undef BOOST_HAS_NL_TYPES_H +#endif + + + + + diff --git a/thirdparty/linux/include/boost/config/platform/haiku.hpp b/thirdparty/linux/include/boost/config/platform/haiku.hpp new file mode 100644 index 0000000..750866c --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/haiku.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Jessica Hamilton 2014. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Haiku specific config options: + +#define BOOST_PLATFORM "Haiku" + +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_STDINT_H + +#ifndef BOOST_DISABLE_THREADS +# define BOOST_HAS_THREADS +#endif + +#define BOOST_NO_CXX11_HDR_TYPE_TRAITS +#define BOOST_NO_CXX11_ATOMIC_SMART_PTR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_VARIADIC_MACROS + +// +// thread API's not auto detected: +// +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_GETTIMEOFDAY + +// boilerplate code: +#include diff --git a/thirdparty/linux/include/boost/config/platform/hpux.hpp b/thirdparty/linux/include/boost/config/platform/hpux.hpp new file mode 100644 index 0000000..19ce68e --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/hpux.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// hpux specific config options: + +#define BOOST_PLATFORM "HP-UX" + +// In principle, HP-UX has a nice under the name +// However, it has the following problem: +// Use of UINT32_C(0) results in "0u l" for the preprocessed source +// (verifyable with gcc 2.95.3) +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__HP_aCC) +# define BOOST_HAS_STDINT_H +#endif + +#if !(defined(__HP_aCC) || !defined(_INCLUDE__STDC_A1_SOURCE)) +# define BOOST_NO_SWPRINTF +#endif +#if defined(__HP_aCC) && !defined(_INCLUDE__STDC_A1_SOURCE) +# define BOOST_NO_CWCTYPE +#endif + +#if defined(__GNUC__) +# if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3)) + // GNU C on HP-UX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +# elif !defined(BOOST_DISABLE_THREADS) + // threads supported from gcc-3.3 onwards: +# define BOOST_HAS_THREADS +# define BOOST_HAS_PTHREADS +# endif +#elif defined(__HP_aCC) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_HAS_PTHREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// the following are always available: +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_SCHED_YIELD +#endif +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#endif +#ifndef BOOST_HAS_NL_TYPES_H +# define BOOST_HAS_NL_TYPES_H +#endif +#ifndef BOOST_HAS_NANOSLEEP +# define BOOST_HAS_NANOSLEEP +#endif +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_DIRENT_H +# define BOOST_HAS_DIRENT_H +#endif +#ifndef BOOST_HAS_CLOCK_GETTIME +# define BOOST_HAS_CLOCK_GETTIME +#endif +#ifndef BOOST_HAS_SIGACTION +# define BOOST_HAS_SIGACTION +#endif +#ifndef BOOST_HAS_NRVO +# ifndef __parisc +# define BOOST_HAS_NRVO +# endif +#endif +#ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +#endif +#ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +#endif + diff --git a/thirdparty/linux/include/boost/config/platform/irix.hpp b/thirdparty/linux/include/boost/config/platform/irix.hpp new file mode 100644 index 0000000..aeae49c --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/irix.hpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// SGI Irix specific config options: + +#define BOOST_PLATFORM "SGI Irix" + +#define BOOST_NO_SWPRINTF +// +// these are not auto detected by POSIX feature tests: +// +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#ifdef __GNUC__ + // GNU C on IRIX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + diff --git a/thirdparty/linux/include/boost/config/platform/linux.hpp b/thirdparty/linux/include/boost/config/platform/linux.hpp new file mode 100644 index 0000000..8c43c7b --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/linux.hpp @@ -0,0 +1,105 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// linux specific config options: + +#define BOOST_PLATFORM "linux" + +// make sure we have __GLIBC_PREREQ if available at all +#ifdef __cplusplus +#include +#else +#include +#endif + +// +// added to glibc 2.1.1 +// We can only test for 2.1 though: +// +#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) + // defines int64_t unconditionally, but defines + // int64_t only if __GNUC__. Thus, assume a fully usable + // only when using GCC. +# if defined __GNUC__ +# define BOOST_HAS_STDINT_H +# endif +#endif + +#if defined(__LIBCOMO__) + // + // como on linux doesn't have std:: c functions: + // NOTE: versions of libcomo prior to beta28 have octal version numbering, + // e.g. version 25 is 21 (dec) + // +# if __LIBCOMO_VERSION__ <= 20 +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if __LIBCOMO_VERSION__ <= 21 +# define BOOST_NO_SWPRINTF +# endif + +#endif + +// +// If glibc is past version 2 then we definitely have +// gettimeofday, earlier versions may or may not have it: +// +#if defined(__GLIBC__) && (__GLIBC__ >= 2) +# define BOOST_HAS_GETTIMEOFDAY +#endif + +#ifdef __USE_POSIX199309 +# define BOOST_HAS_NANOSLEEP +#endif + +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +// __GLIBC_PREREQ is available since 2.1.2 + + // swprintf is available since glibc 2.2.0 +# if !__GLIBC_PREREQ(2,2) || (!defined(__USE_ISOC99) && !defined(__USE_UNIX98)) +# define BOOST_NO_SWPRINTF +# endif +#else +# define BOOST_NO_SWPRINTF +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include +#if defined(__USE_GNU) && !defined(__ANDROID__) && !defined(ANDROID) +#define BOOST_HAS_PTHREAD_YIELD +#endif + +#ifndef __GNUC__ +// +// if the compiler is not gcc we still need to be able to parse +// the GNU system headers, some of which (mainly ) +// use GNU specific extensions: +// +# ifndef __extension__ +# define __extension__ +# endif +# ifndef __const__ +# define __const__ const +# endif +# ifndef __volatile__ +# define __volatile__ volatile +# endif +# ifndef __signed__ +# define __signed__ signed +# endif +# ifndef __typeof__ +# define __typeof__ typeof +# endif +# ifndef __inline__ +# define __inline__ inline +# endif +#endif + + diff --git a/thirdparty/linux/include/boost/config/platform/macos.hpp b/thirdparty/linux/include/boost/config/platform/macos.hpp new file mode 100644 index 0000000..5be4e3b --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/macos.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Bill Kempf 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Mac OS specific config options: + +#define BOOST_PLATFORM "Mac OS" + +#if __MACH__ && !defined(_MSL_USING_MSL_C) + +// Using the Mac OS X system BSD-style C library. + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif +// +// Begin by including our boilerplate code for POSIX +// feature detection, this is safe even when using +// the MSL as Metrowerks supply their own +// to replace the platform-native BSD one. G++ users +// should also always be able to do this on MaxOS X. +// +# include +# ifndef BOOST_HAS_STDINT_H +# define BOOST_HAS_STDINT_H +# endif + +// +// BSD runtime has pthreads, sigaction, sched_yield and gettimeofday, +// of these only pthreads are advertised in , so set the +// other options explicitly: +// +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_SIGACTION + +# if (__GNUC__ < 3) && !defined( __APPLE_CC__) + +// GCC strange "ignore std" mode works better if you pretend everything +// is in the std namespace, for the most part. + +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if (__GNUC__ >= 4) + +// Both gcc and intel require these. +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_NANOSLEEP + +# endif + +#else + +// Using the MSL C library. + +// We will eventually support threads in non-Carbon builds, but we do +// not support this yet. +# if ( defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON ) || ( defined(TARGET_CARBON) && TARGET_CARBON ) + +# if !defined(BOOST_HAS_PTHREADS) +// MPTasks support is deprecated/removed from Boost: +//# define BOOST_HAS_MPTASKS +# elif ( __dest_os == __mac_os_x ) +// We are doing a Carbon/Mach-O/MSL build which has pthreads, but only the +// gettimeofday and no posix. +# define BOOST_HAS_GETTIMEOFDAY +# endif + +#ifdef BOOST_HAS_PTHREADS +# define BOOST_HAS_THREADS +#endif + +// The remote call manager depends on this. +# define BOOST_BIND_ENABLE_PASCAL + +# endif + +#endif + + + diff --git a/thirdparty/linux/include/boost/config/platform/qnxnto.hpp b/thirdparty/linux/include/boost/config/platform/qnxnto.hpp new file mode 100644 index 0000000..b1377c8 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/qnxnto.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Jim Douglas 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// QNX specific config options: + +#define BOOST_PLATFORM "QNX" + +#define BOOST_HAS_UNISTD_H +#include + +// QNX claims XOpen version 5 compatibility, but doesn't have an nl_types.h +// or log1p and expm1: +#undef BOOST_HAS_NL_TYPES_H +#undef BOOST_HAS_LOG1P +#undef BOOST_HAS_EXPM1 + +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_NANOSLEEP + + + + + diff --git a/thirdparty/linux/include/boost/config/platform/solaris.hpp b/thirdparty/linux/include/boost/config/platform/solaris.hpp new file mode 100644 index 0000000..6e4efc9 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/solaris.hpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// sun specific config options: + +#define BOOST_PLATFORM "Sun Solaris" + +#define BOOST_HAS_GETTIMEOFDAY + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// +// pthreads don't actually work with gcc unless _PTHREADS is defined: +// +#if defined(__GNUC__) && defined(_POSIX_THREADS) && !defined(_PTHREADS) +# undef BOOST_HAS_PTHREADS +#endif + +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 + + diff --git a/thirdparty/linux/include/boost/config/platform/symbian.hpp b/thirdparty/linux/include/boost/config/platform/symbian.hpp new file mode 100644 index 0000000..e02a778 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/symbian.hpp @@ -0,0 +1,97 @@ +// (C) Copyright Yuriy Krasnoschek 2009. +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// symbian specific config options: + + +#define BOOST_PLATFORM "Symbian" +#define BOOST_SYMBIAN 1 + + +#if defined(__S60_3X__) +// Open C / C++ plugin was introdused in this SDK, earlier versions don't have CRT / STL +# define BOOST_S60_3rd_EDITION_FP2_OR_LATER_SDK +// make sure we have __GLIBC_PREREQ if available at all +#ifdef __cplusplus +#include +#else +#include +#endif// boilerplate code: +# define BOOST_HAS_UNISTD_H +# include +// S60 SDK defines _POSIX_VERSION as POSIX.1 +# ifndef BOOST_HAS_STDINT_H +# define BOOST_HAS_STDINT_H +# endif +# ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +# endif +# ifndef BOOST_HAS_DIRENT_H +# define BOOST_HAS_DIRENT_H +# endif +# ifndef BOOST_HAS_SIGACTION +# define BOOST_HAS_SIGACTION +# endif +# ifndef BOOST_HAS_PTHREADS +# define BOOST_HAS_PTHREADS +# endif +# ifndef BOOST_HAS_NANOSLEEP +# define BOOST_HAS_NANOSLEEP +# endif +# ifndef BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_SCHED_YIELD +# endif +# ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# ifndef BOOST_POSIX_API +# define BOOST_POSIX_API +# endif +// endianess support +# include +// Symbian SDK provides _BYTE_ORDER instead of __BYTE_ORDER +# ifndef __LITTLE_ENDIAN +# ifdef _LITTLE_ENDIAN +# define __LITTLE_ENDIAN _LITTLE_ENDIAN +# else +# define __LITTLE_ENDIAN 1234 +# endif +# endif +# ifndef __BIG_ENDIAN +# ifdef _BIG_ENDIAN +# define __BIG_ENDIAN _BIG_ENDIAN +# else +# define __BIG_ENDIAN 4321 +# endif +# endif +# ifndef __BYTE_ORDER +# define __BYTE_ORDER __LITTLE_ENDIAN // Symbian is LE +# endif +// Known limitations +# define BOOST_ASIO_DISABLE_SERIAL_PORT +# define BOOST_DATE_TIME_NO_LOCALE +# define BOOST_NO_STD_WSTRING +# define BOOST_EXCEPTION_DISABLE +# define BOOST_NO_EXCEPTIONS + +#else // TODO: More platform support e.g. UIQ +# error "Unsuppoted Symbian SDK" +#endif + +#if defined(__WINSCW__) && !defined(BOOST_DISABLE_WIN32) +# define BOOST_DISABLE_WIN32 // winscw defines WIN32 macro +#endif + + diff --git a/thirdparty/linux/include/boost/config/platform/vms.hpp b/thirdparty/linux/include/boost/config/platform/vms.hpp new file mode 100644 index 0000000..f70efcf --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/vms.hpp @@ -0,0 +1,25 @@ +// (C) Copyright Artyom Beilis 2010. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_CONFIG_PLATFORM_VMS_HPP +#define BOOST_CONFIG_PLATFORM_VMS_HPP + +#define BOOST_PLATFORM "OpenVMS" + +#undef BOOST_HAS_STDINT_H +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_THREADS +#undef BOOST_HAS_SCHED_YIELD + +#endif diff --git a/thirdparty/linux/include/boost/config/platform/vxworks.hpp b/thirdparty/linux/include/boost/config/platform/vxworks.hpp new file mode 100644 index 0000000..cdda015 --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/vxworks.hpp @@ -0,0 +1,369 @@ +// (C) Copyright Dustin Spicuzza 2009. +// Adapted to vxWorks 6.9 by Peter Brockamp 2012. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Since WRS does not yet properly support boost under vxWorks +// and this file was badly outdated, but I was keen on using it, +// I patched boost myself to make things work. This has been tested +// and adapted by me for vxWorks 6.9 *only*, as I'm lacking access +// to earlier 6.X versions! The only thing I know for sure is that +// very old versions of vxWorks (namely everything below 6.x) are +// absolutely unable to use boost. This is mainly due to the completely +// outdated libraries and ancient compiler (GCC 2.96 or worse). Do +// not even think of getting this to work, a miserable failure will +// be guaranteed! +// Equally, this file has been tested for RTPs (Real Time Processes) +// only, not for DKMs (Downloadable Kernel Modules). These two types +// of executables differ largely in the available functionality of +// the C-library, STL, and so on. A DKM uses a library similar to those +// of vxWorks 5.X - with all its limitations and incompatibilities +// with respect to ANSI C++ and STL. So probably there might be problems +// with the usage of boost from DKMs. WRS or any voluteers are free to +// prove the opposite! + +// ==================================================================== +// +// Some important information regarding the usage of POSIX semaphores: +// ------------------------------------------------------------------- +// +// VxWorks as a real time operating system handles threads somewhat +// different from what "normal" OSes do, regarding their scheduling! +// This could lead to a scenario called "priority inversion" when using +// semaphores, see http://en.wikipedia.org/wiki/Priority_inversion. +// +// Now, VxWorks POSIX-semaphores for DKM's default to the usage of +// priority inverting semaphores, which is fine. On the other hand, +// for RTP's it defaults to using non priority inverting semaphores, +// which could easily pose a serious problem for a real time process, +// i.e. deadlocks! To overcome this two possibilities do exist: +// +// a) Patch every piece of boost that uses semaphores to instanciate +// the proper type of semaphores. This is non-intrusive with respect +// to the OS and could relatively easy been done by giving all +// semaphores attributes deviating from the default (for in-depth +// information see the POSIX functions pthread_mutexattr_init() +// and pthread_mutexattr_setprotocol()). However this breaks all +// too easily, as with every new version some boost library could +// all in a sudden start using semaphores, resurrecting the very +// same, hard to locate problem over and over again! +// +// b) We could change the default properties for POSIX-semaphores +// that VxWorks uses for RTP's and this is being suggested here, +// as it will more or less seamlessly integrate with boost. I got +// the following information from WRS how to do this, compare +// Wind River TSR# 1209768: +// +// Instructions for changing the default properties of POSIX- +// semaphores for RTP's in VxWorks 6.9: +// - Edit the file /vxworks-6.9/target/usr/src/posix/pthreadLib.c +// in the root of your Workbench-installation. +// - Around line 917 there should be the definition of the default +// mutex attributes: +// +// LOCAL pthread_mutexattr_t defaultMutexAttr = +// { +// PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0, +// PTHREAD_MUTEX_DEFAULT +// }; +// +// Here, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT. +// - Around line 1236 there should be a definition for the function +// pthread_mutexattr_init(). A couple of lines below you should +// find a block of code like this: +// +// pAttr->mutexAttrStatus = PTHREAD_INITIALIZED_OBJ; +// pAttr->mutexAttrProtocol = PTHREAD_PRIO_NONE; +// pAttr->mutexAttrPrioceiling = 0; +// pAttr->mutexAttrType = PTHREAD_MUTEX_DEFAULT; +// +// Here again, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT. +// - Finally, rebuild your VSB. This will create a new VxWorks kernel +// with the changed properties. That's it! Now, using boost should +// no longer cause any problems with task deadlocks! +// +// And here's another useful piece of information concerning VxWorks' +// POSIX-functionality in general: +// VxWorks is not a genuine POSIX-OS in itself, rather it is using a +// kind of compatibility layer (sort of a wrapper) to emulate the +// POSIX-functionality by using its own resources and functions. +// At the time a task (thread) calls it's first POSIX-function during +// runtime it is being transformed by the OS into a POSIX-thread. +// This transformation does include a call to malloc() to allocate the +// memory required for the housekeeping of POSIX-threads. In a high +// priority RTP this malloc() call may be highly undesirable, as its +// timing is more or less unpredictable (depending on what your actual +// heap looks like). You can circumvent this problem by calling the +// function thread_self() at a well defined point in the code of the +// task, e.g. shortly after the task spawns up. Thereby you are able +// to define the time when the task-transformation will take place and +// you could shift it to an uncritical point where a malloc() call is +// tolerable. So, if this could pose a problem for your code, remember +// to call thread_self() from the affected task at an early stage. +// +// ==================================================================== + +// Block out all versions before vxWorks 6.x, as these don't work: +// Include header with the vxWorks version information and query them +#include +#if !defined(_WRS_VXWORKS_MAJOR) || (_WRS_VXWORKS_MAJOR < 6) +# error "The vxWorks version you're using is so badly outdated,\ + it doesn't work at all with boost, sorry, no chance!" +#endif + +// Handle versions above 5.X but below 6.9 +#if (_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR < 9) +// TODO: Starting from what version does vxWorks work with boost? +// We can't reasonably insert a #warning "" as a user hint here, +// as this will show up with every file including some boost header, +// badly bugging the user... So for the time being we just leave it. +#endif + +// vxWorks specific config options: +// -------------------------------- +#define BOOST_PLATFORM "vxWorks" + +// Special behaviour for DKMs: +#ifdef _WRS_KERNEL + // DKMs do not have the -header, + // but apparently they do have an intrinsic wchar_t meanwhile! +# define BOOST_NO_CWCHAR + + // Lots of wide-functions and -headers are unavailable for DKMs as well: +# define BOOST_NO_CWCTYPE +# define BOOST_NO_SWPRINTF +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + +// Generally available headers: +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_SLIST + +// vxWorks does not have installed an iconv-library by default, +// so unfortunately no Unicode support from scratch is available! +// Thus, instead it is suggested to switch to ICU, as this seems +// to be the most complete and portable option... +#define BOOST_LOCALE_WITH_ICU + +// Generally available functionality: +#define BOOST_HAS_THREADS +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_MACRO_USE_FACET + +// Generally unavailable functionality, delivered by boost's test function: +//#define BOOST_NO_DEDUCED_TYPENAME // Commented this out, boost's test gives an errorneous result! +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_VARIADIC_MACROS + +// Generally available threading API's: +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_SIGACTION + +// Functionality available for RTPs only: +#ifdef __RTP__ +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_LOG1P +# define BOOST_HAS_EXPM1 +#endif + +// Functionality available for DKMs only: +#ifdef _WRS_KERNEL + // Luckily, at the moment there seems to be none! +#endif + +// These #defines allow posix_features to work, since vxWorks doesn't +// #define them itself for DKMs (for RTPs on the contrary it does): +#ifdef _WRS_KERNEL +# ifndef _POSIX_TIMERS +# define _POSIX_TIMERS 1 +# endif +# ifndef _POSIX_THREADS +# define _POSIX_THREADS 1 +# endif +#endif + +// vxWorks doesn't work with asio serial ports: +#define BOOST_ASIO_DISABLE_SERIAL_PORT +// TODO: The problem here seems to bee that vxWorks uses its own, very specific +// ways to handle serial ports, incompatible with POSIX or anything... +// Maybe a specific implementation would be possible, but until the +// straight need arises... This implementation would presumably consist +// of some vxWorks specific ioctl-calls, etc. Any voluteers? + +// vxWorks-around: #defines CLOCKS_PER_SEC as sysClkRateGet() but +// miserably fails to #include the required to make +// sysClkRateGet() available! So we manually include it here. +#ifdef __RTP__ +# include +# include +#endif + +// vxWorks-around: In the macros INT32_C(), UINT32_C(), INT64_C() and +// UINT64_C() are defined errorneously, yielding not a signed/ +// unsigned long/long long type, but a signed/unsigned int/long +// type. Eventually this leads to compile errors in ratio_fwd.hpp, +// when trying to define several constants which do not fit into a +// long type! We correct them here by redefining. +#include + +// Some macro-magic to do the job +#define VX_JOIN(X, Y) VX_DO_JOIN(X, Y) +#define VX_DO_JOIN(X, Y) VX_DO_JOIN2(X, Y) +#define VX_DO_JOIN2(X, Y) X##Y + +// Correctly setup the macros +#undef INT32_C +#undef UINT32_C +#undef INT64_C +#undef UINT64_C +#define INT32_C(x) VX_JOIN(x, L) +#define UINT32_C(x) VX_JOIN(x, UL) +#define INT64_C(x) VX_JOIN(x, LL) +#define UINT64_C(x) VX_JOIN(x, ULL) + +// #include Libraries required for the following function adaption +#include +#include +#include + +// Use C-linkage for the following helper functions +extern "C" { + +// vxWorks-around: The required functions getrlimit() and getrlimit() are missing. +// But we have the similar functions getprlimit() and setprlimit(), +// which may serve the purpose. +// Problem: The vxWorks-documentation regarding these functions +// doesn't deserve its name! It isn't documented what the first two +// parameters idtype and id mean, so we must fall back to an educated +// guess - null, argh... :-/ + +// TODO: getprlimit() and setprlimit() do exist for RTPs only, for whatever reason. +// Thus for DKMs there would have to be another implementation. +#ifdef __RTP__ + inline int getrlimit(int resource, struct rlimit *rlp){ + return getprlimit(0, 0, resource, rlp); + } + + inline int setrlimit(int resource, const struct rlimit *rlp){ + return setprlimit(0, 0, resource, const_cast(rlp)); + } +#endif + +// vxWorks has ftruncate() only, so we do simulate truncate(): +inline int truncate(const char *p, off_t l){ + int fd = open(p, O_WRONLY); + if (fd == -1){ + errno = EACCES; + return -1; + } + if (ftruncate(fd, l) == -1){ + close(fd); + errno = EACCES; + return -1; + } + return close(fd); +} + +// Fake symlink handling by dummy functions: +inline int symlink(const char*, const char*){ + // vxWorks has no symlinks -> always return an error! + errno = EACCES; + return -1; +} + +inline ssize_t readlink(const char*, char*, size_t){ + // vxWorks has no symlinks -> always return an error! + errno = EACCES; + return -1; +} + +// vxWorks claims to implement gettimeofday in sys/time.h +// but nevertheless does not provide it! See +// https://support.windriver.com/olsPortal/faces/maintenance/techtipDetail_noHeader.jspx?docId=16442&contentId=WR_TECHTIP_006256 +// We implement a surrogate version here via clock_gettime: +inline int gettimeofday(struct timeval *tv, void * /*tzv*/) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + return 0; +} + +// vxWorks does provide neither struct tms nor function times()! +// We implement an empty dummy-function, simply setting the user +// and system time to the half of thew actual system ticks-value +// and the child user and system time to 0. +// Rather ugly but at least it suppresses compiler errors... +// Unfortunately, this of course *does* have an severe impact on +// dependant libraries, actually this is chrono only! Here it will +// not be possible to correctly use user and system times! But +// as vxWorks is lacking the ability to calculate user and system +// process times there seems to be no other possible solution. +struct tms{ + clock_t tms_utime; // User CPU time + clock_t tms_stime; // System CPU time + clock_t tms_cutime; // User CPU time of terminated child processes + clock_t tms_cstime; // System CPU time of terminated child processes +}; + +inline clock_t times(struct tms *t){ + struct timespec ts; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); + clock_t ticks(static_cast(static_cast(ts.tv_sec) * CLOCKS_PER_SEC + + static_cast(ts.tv_nsec) * CLOCKS_PER_SEC / 1000000.0)); + t->tms_utime = ticks/2U; + t->tms_stime = ticks/2U; + t->tms_cutime = 0; // vxWorks is lacking the concept of a child process! + t->tms_cstime = 0; // -> Set the wait times for childs to 0 + return ticks; +} + +} // extern "C" + +// Put the selfmade functions into the std-namespace, just in case +namespace std { +# ifdef __RTP__ + using ::getrlimit; + using ::setrlimit; +# endif + using ::truncate; + using ::symlink; + using ::readlink; + using ::times; + using ::gettimeofday; +} + +// Some more macro-magic: +// vxWorks-around: Some functions are not present or broken in vxWorks +// but may be patched to life via helper macros... + +// Include signal.h which might contain a typo to be corrected here +#include + +#define getpagesize() sysconf(_SC_PAGESIZE) // getpagesize is deprecated anyway! +#ifndef S_ISSOCK +# define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) // Is file a socket? +#endif +#define lstat(p, b) stat(p, b) // lstat() == stat(), as vxWorks has no symlinks! +#ifndef FPE_FLTINV +# define FPE_FLTINV (FPE_FLTSUB+1) // vxWorks has no FPE_FLTINV, so define one as a dummy +#endif +#if !defined(BUS_ADRALN) && defined(BUS_ADRALNR) +# define BUS_ADRALN BUS_ADRALNR // Correct a supposed typo in vxWorks' +#endif +//typedef int locale_t; // locale_t is a POSIX-extension, currently unpresent in vxWorks! + +// #include boilerplate code: +#include + +// vxWorks lies about XSI conformance, there is no nl_types.h: +#undef BOOST_HAS_NL_TYPES_H diff --git a/thirdparty/linux/include/boost/config/platform/win32.hpp b/thirdparty/linux/include/boost/config/platform/win32.hpp new file mode 100644 index 0000000..450158f --- /dev/null +++ b/thirdparty/linux/include/boost/config/platform/win32.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Bill Kempf 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Rene Rivera 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Win32 specific config options: + +#define BOOST_PLATFORM "Win32" + +// Get the information about the MinGW runtime, i.e. __MINGW32_*VERSION. +#if defined(__MINGW32__) +# include <_mingw.h> +#endif + +#if defined(__GNUC__) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +#endif + +// Default defines for BOOST_SYMBOL_EXPORT and BOOST_SYMBOL_IMPORT +// If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport), +// its boost/config/compiler/ file must define BOOST_SYMBOL_EXPORT and +// BOOST_SYMBOL_IMPORT +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __declspec(dllexport) +# define BOOST_SYMBOL_IMPORT __declspec(dllimport) +#endif + +#if defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 2) || ((__MINGW32_MAJOR_VERSION == 2) && (__MINGW32_MINOR_VERSION >= 0))) +# define BOOST_HAS_STDINT_H +# ifndef __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS +# endif +# define BOOST_HAS_DIRENT_H +# define BOOST_HAS_UNISTD_H +#endif + +#if defined(__MINGW32__) && (__GNUC__ >= 4) +// Mingw has these functions but there are persistent problems +// with calls to these crashing, so disable for now: +//# define BOOST_HAS_EXPM1 +//# define BOOST_HAS_LOG1P +# define BOOST_HAS_GETTIMEOFDAY +#endif +// +// Win32 will normally be using native Win32 threads, +// but there is a pthread library avaliable as an option, +// we used to disable this when BOOST_DISABLE_WIN32 was +// defined but no longer - this should allow some +// files to be compiled in strict mode - while maintaining +// a consistent setting of BOOST_HAS_THREADS across +// all translation units (needed for shared_ptr etc). +// + +#ifndef BOOST_HAS_PTHREADS +# define BOOST_HAS_WINTHREADS +#endif + +// +// WinCE configuration: +// +#if defined(_WIN32_WCE) || defined(UNDER_CE) +# define BOOST_NO_ANSI_APIS +// Windows CE does not have a conforming signature for swprintf +# define BOOST_NO_SWPRINTF +#else +# define BOOST_HAS_GETSYSTEMTIMEASFILETIME +# define BOOST_HAS_THREADEX +# define BOOST_HAS_GETSYSTEMTIMEASFILETIME +#endif + +// +// Windows Runtime +// +#if defined(WINAPI_FAMILY) && \ + (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +# define BOOST_NO_ANSI_APIS +#endif + +#ifndef BOOST_DISABLE_WIN32 +// WEK: Added +#define BOOST_HAS_FTIME +#define BOOST_WINDOWS 1 + +#endif diff --git a/thirdparty/linux/include/boost/config/posix_features.hpp b/thirdparty/linux/include/boost/config/posix_features.hpp new file mode 100644 index 0000000..d129547 --- /dev/null +++ b/thirdparty/linux/include/boost/config/posix_features.hpp @@ -0,0 +1,95 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// All POSIX feature tests go in this file, +// Note that we test _POSIX_C_SOURCE and _XOPEN_SOURCE as well +// _POSIX_VERSION and _XOPEN_VERSION: on some systems POSIX API's +// may be present but none-functional unless _POSIX_C_SOURCE and +// _XOPEN_SOURCE have been defined to the right value (it's up +// to the user to do this *before* including any header, although +// in most cases the compiler will do this for you). + +# if defined(BOOST_HAS_UNISTD_H) +# include + + // XOpen has , but is this the correct version check? +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 3) +# define BOOST_HAS_NL_TYPES_H +# endif + + // POSIX version 6 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200100) +# define BOOST_HAS_STDINT_H +# endif + + // POSIX version 2 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199009L) +# define BOOST_HAS_DIRENT_H +# endif + + // POSIX version 3 requires to have sigaction: +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L) +# define BOOST_HAS_SIGACTION +# endif + // POSIX defines _POSIX_THREADS > 0 for pthread support, + // however some platforms define _POSIX_THREADS without + // a value, hence the (_POSIX_THREADS+0 >= 0) check. + // Strictly speaking this may catch platforms with a + // non-functioning stub , but such occurrences should + // occur very rarely if at all. +# if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_MPTASKS) +# define BOOST_HAS_PTHREADS +# endif + + // BOOST_HAS_NANOSLEEP: + // This is predicated on _POSIX_TIMERS or _XOPEN_REALTIME: +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) \ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_NANOSLEEP +# endif + + // BOOST_HAS_CLOCK_GETTIME: + // This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME + // but at least one platform - linux - defines that flag without + // defining clock_gettime): +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) +# define BOOST_HAS_CLOCK_GETTIME +# endif + + // BOOST_HAS_SCHED_YIELD: + // This is predicated on _POSIX_PRIORITY_SCHEDULING or + // on _POSIX_THREAD_PRIORITY_SCHEDULING or on _XOPEN_REALTIME. +# if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING+0 > 0)\ + || (defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING+0 > 0))\ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_SCHED_YIELD +# endif + + // BOOST_HAS_GETTIMEOFDAY: + // BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE: + // These are predicated on _XOPEN_VERSION, and appears to be first released + // in issue 4, version 2 (_XOPEN_VERSION > 500). + // Likewise for the functions log1p and expm1. +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION+0 >= 500) +# define BOOST_HAS_GETTIMEOFDAY +# if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE+0 >= 500) +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +# endif + + + + diff --git a/thirdparty/linux/include/boost/config/requires_threads.hpp b/thirdparty/linux/include/boost/config/requires_threads.hpp new file mode 100644 index 0000000..cfaff23 --- /dev/null +++ b/thirdparty/linux/include/boost/config/requires_threads.hpp @@ -0,0 +1,92 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef BOOST_CONFIG_REQUIRES_THREADS_HPP +#define BOOST_CONFIG_REQUIRES_THREADS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_DISABLE_THREADS) + +// +// special case to handle versions of gcc which don't currently support threads: +// +#if defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC_MINOR__ <= 3) || !defined(BOOST_STRICT_CONFIG)) +// +// this is checked up to gcc 3.3: +// +#if defined(__sgi) || defined(__hpux) +# error "Multi-threaded programs are not supported by gcc on HPUX or Irix (last checked with gcc 3.3)" +#endif + +#endif + +# error "Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS" + +#elif !defined(BOOST_HAS_THREADS) + +# if defined __COMO__ +// Comeau C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_MT (Windows) or -D_REENTRANT (Unix)" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +#ifdef _WIN32 +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" +#else +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -openmp" +#endif + +# elif defined __GNUC__ +// GNU C++: +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" + +#elif defined __sgi +// SGI MIPSpro C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_SGI_MP_SOURCE" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread" + +#elif defined __BORLANDC__ +// Borland +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -tWM" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either -runtime sm, -runtime smd, -runtime dm, or -runtime dmd" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined __HP_aCC +// HP aCC +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined(__IBMCPP__) +// IBM Visual Age +# error "Compiler threading support is not turned on. Please compile the code with the xlC_r compiler" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" + +#else + +# error "Compiler threading support is not turned on. Please consult your compiler's documentation for the appropriate options to use" + +#endif // compilers + +#endif // BOOST_HAS_THREADS + +#endif // BOOST_CONFIG_REQUIRES_THREADS_HPP diff --git a/thirdparty/linux/include/boost/config/select_compiler_config.hpp b/thirdparty/linux/include/boost/config/select_compiler_config.hpp new file mode 100644 index 0000000..7a75708 --- /dev/null +++ b/thirdparty/linux/include/boost/config/select_compiler_config.hpp @@ -0,0 +1,148 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Martin Wille 2003. +// (C) Copyright Guillaume Melquiond 2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for most recent version. + +// locate which compiler we are using and define +// BOOST_COMPILER_CONFIG as needed: + +#if defined __CUDACC__ +// NVIDIA CUDA C++ compiler for GPU +# include "boost/config/compiler/nvcc.hpp" + +#endif + +#if defined(__GCCXML__) +// GCC-XML emulates other compilers, it has to appear first here! +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" + +#elif defined(_CRAYC) +// EDG based Cray compiler: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp" + +#elif defined __COMO__ +// Comeau C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" + +#elif defined(__PATHSCALE__) && (__PATHCC__ >= 4) +// PathScale EKOPath compiler (has to come before clang and gcc) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pathscale.hpp" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +# define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp" + +#elif defined __clang__ && !defined(__CUDACC__) && !defined(__ibmxl__) +// when using clang and cuda at same time, you want to appear as gcc +// Clang C++ emulates GCC, so it has to appear early. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/clang.hpp" + +#elif defined __DMC__ +// Digital Mars C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp" + +# elif defined(__GNUC__) && !defined(__ibmxl__) +// GNU C++: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp" + +#elif defined __KCC +// Kai C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp" + +#elif defined __sgi +// SGI MIPSpro C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp" + +#elif defined __ghs +// Greenhills C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp" + +#elif defined __CODEGEARC__ +// CodeGear - must be checked for before Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/codegear.hpp" + +#elif defined __BORLANDC__ +// Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp" + +#elif defined __HP_aCC +// HP aCC +# define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp" + +#elif defined(__MRC__) || defined(__SC__) +// MPW MrCpp or SCpp +# define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp" + +#elif defined(__ibmxl__) +// IBM XL C/C++ for Linux (Little Endian) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp.hpp" + +#elif defined(__IBMCPP__) +// IBM Visual Age or IBM XL C/C++ for Linux (Big Endian) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp" + +#elif defined(__PGI) +// Portland Group Inc. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pgi.hpp" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the compiler: +# error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)" + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the headers we *might* include: +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/thirdparty/linux/include/boost/config/select_platform_config.hpp b/thirdparty/linux/include/boost/config/select_platform_config.hpp new file mode 100644 index 0000000..62fd818 --- /dev/null +++ b/thirdparty/linux/include/boost/config/select_platform_config.hpp @@ -0,0 +1,137 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed. +// Note that we define the headers to include using "header_name" not +// in order to prevent macro expansion within the header +// name (for example "linux" is a macro on linux systems). + +#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) +// linux, also other platforms (Hurd etc) that use GLIBC, should these really have their own config headers though? +# define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp" + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +// BSD: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp" + +#elif defined(sun) || defined(__sun) +// solaris: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp" + +#elif defined(__sgi) +// SGI Irix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp" + +#elif defined(__hpux) +// hp unix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp" + +#elif defined(__CYGWIN__) +// cygwin is not win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +// win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp" + +#elif defined(__HAIKU__) +// Haiku +# define BOOST_PLATFORM_CONFIG "boost/config/platform/haiku.hpp" + +#elif defined(__BEOS__) +// BeOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp" + +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +// MacOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp" + +#elif defined(__IBMCPP__) || defined(_AIX) +// IBM +# define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp" + +#elif defined(__amigaos__) +// AmigaOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp" + +#elif defined(__QNXNTO__) +// QNX: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/qnxnto.hpp" + +#elif defined(__VXWORKS__) +// vxWorks: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vxworks.hpp" + +#elif defined(__SYMBIAN32__) +// Symbian: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/symbian.hpp" + +#elif defined(_CRAYC) +// Cray: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cray.hpp" + +#elif defined(__VMS) +// VMS: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vms.hpp" + +#elif defined(__CloudABI__) +// Nuxi CloudABI: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cloudabi.hpp" +#else + +# if defined(unix) \ + || defined(__unix) \ + || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) + + // generic unix platform: + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif + +# include + +# endif + +# if defined (BOOST_ASSERT_CONFIG) + // this must come last - generate an error if we don't + // recognise the platform: +# error "Unknown platform - please configure and report the results to boost.org" +# endif + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the files we *might* include: +// +# include "boost/config/platform/linux.hpp" +# include "boost/config/platform/bsd.hpp" +# include "boost/config/platform/solaris.hpp" +# include "boost/config/platform/irix.hpp" +# include "boost/config/platform/hpux.hpp" +# include "boost/config/platform/cygwin.hpp" +# include "boost/config/platform/win32.hpp" +# include "boost/config/platform/beos.hpp" +# include "boost/config/platform/macos.hpp" +# include "boost/config/platform/aix.hpp" +# include "boost/config/platform/amigaos.hpp" +# include "boost/config/platform/qnxnto.hpp" +# include "boost/config/platform/vxworks.hpp" +# include "boost/config/platform/symbian.hpp" +# include "boost/config/platform/cray.hpp" +# include "boost/config/platform/vms.hpp" +# include + + + +#endif + diff --git a/thirdparty/linux/include/boost/config/select_stdlib_config.hpp b/thirdparty/linux/include/boost/config/select_stdlib_config.hpp new file mode 100644 index 0000000..e270a88 --- /dev/null +++ b/thirdparty/linux/include/boost/config/select_stdlib_config.hpp @@ -0,0 +1,105 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed: + +// First include to determine if some version of STLport is in use as the std lib +// (do not rely on this header being included since users can short-circuit this header +// if they know whose std lib they are using.) +#ifdef __cplusplus +# include +#else +# include +#endif + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +// STLPort library; this _must_ come first, otherwise since +// STLport typically sits on top of some other library, we +// can end up detecting that first rather than STLport: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp" + +#else + +// If our std lib was not some version of STLport, and has not otherwise +// been detected, then include as it is about +// the smallest of the std lib headers that includes real C++ stuff. +// Some std libs do not include their C++-related macros in +// so this additional include makes sure we get those definitions. +// Note: do not rely on this header being included since users can short-circuit this +// #include if they know whose std lib they are using. +#if !defined(__LIBCOMO__) && !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER)\ + && !defined(_LIBCPP_VERSION) && !defined(__GLIBCPP__) && !defined(__GLIBCXX__)\ + && !defined(__STL_CONFIG_H) && !defined(__MSL_CPP__) && !defined(__IBMCPP__)\ + && !defined(MSIPL_COMPILE_H) && !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#endif + +#if defined(__LIBCOMO__) +// Comeau STL: +#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp" + +#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// Rogue Wave library: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp" + +#elif defined(_LIBCPP_VERSION) +// libc++ +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcpp.hpp" + +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +// GNU libstdc++ 3 +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp" + +#elif defined(__STL_CONFIG_H) +// generic SGI STL +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp" + +#elif defined(__MSL_CPP__) +// MSL standard lib: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp" + +#elif defined(__IBMCPP__) +// take the default VACPP std lib +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp" + +#elif defined(MSIPL_COMPILE_H) +// Modena C++ standard library +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp" + +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +// Dinkumware Library (this has to appear after any possible replacement libraries): +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the library: +# error "Unknown standard library - please configure and report the results to boost.org" + +#endif + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the files we *might* include: +// +# include "boost/config/stdlib/stlport.hpp" +# include "boost/config/stdlib/libcomo.hpp" +# include "boost/config/stdlib/roguewave.hpp" +# include "boost/config/stdlib/libcpp.hpp" +# include "boost/config/stdlib/libstdcpp3.hpp" +# include "boost/config/stdlib/sgi.hpp" +# include "boost/config/stdlib/msl.hpp" +# include "boost/config/stdlib/vacpp.hpp" +# include "boost/config/stdlib/modena.hpp" +# include "boost/config/stdlib/dinkumware.hpp" +#endif + diff --git a/thirdparty/linux/include/boost/config/stdlib/dinkumware.hpp b/thirdparty/linux/include/boost/config/stdlib/dinkumware.hpp new file mode 100644 index 0000000..8cf5d4d --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/dinkumware.hpp @@ -0,0 +1,209 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Guillaume Melquiond 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Dinkumware standard library config: + +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#error This is not the Dinkumware lib! +#endif +#endif + + +#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 306) + // full dinkumware 3.06 and above + // fully conforming provided the compiler supports it: +# if !(defined(_GLOBAL_USING) && (_GLOBAL_USING+0 > 0)) && !defined(__BORLANDC__) && !defined(_STD) && !(defined(__ICC) && (__ICC >= 700)) // can be defined in yvals.h +# define BOOST_NO_STDC_NAMESPACE +# endif +# if !(defined(_HAS_MEMBER_TEMPLATES_REBIND) && (_HAS_MEMBER_TEMPLATES_REBIND+0 > 0)) && !(defined(_MSC_VER) && (_MSC_VER > 1300)) && defined(BOOST_MSVC) +# define BOOST_NO_STD_ALLOCATOR +# endif +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + // if this lib version is set up for vc6 then there is no std::use_facet: +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET + // C lib functions aren't in namespace std either: +# define BOOST_NO_STDC_NAMESPACE + // and nor is +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +// There's no numeric_limits support unless _LONGLONG is defined: +# if !defined(_LONGLONG) && (_CPPLIB_VER <= 310) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +// 3.06 appears to have (non-sgi versions of) & , +// and no at all +#else +# define BOOST_MSVC_STD_ITERATOR 1 +# define BOOST_NO_STD_ITERATOR +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_STD_USE_FACET +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +# define BOOST_HAS_MACRO_USE_FACET +# ifndef _CPPLIB_VER + // Updated Dinkum library defines this, and provides + // its own min and max definitions, as does MTA version. +# ifndef __MTA__ +# define BOOST_NO_STD_MIN_MAX +# endif +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +#endif + +// +// std extension namespace is stdext for vc7.1 and later, +// the same applies to other compilers that sit on top +// of vc7.1 (Intel and Comeau): +// +#if defined(_MSC_VER) && (_MSC_VER >= 1310) && !defined(__BORLANDC__) +# define BOOST_STD_EXTENSION_NAMESPACE stdext +#endif + + +#if (defined(_MSC_VER) && (_MSC_VER <= 1300) && !defined(__BORLANDC__)) || !defined(_CPPLIB_VER) || (_CPPLIB_VER < 306) + // if we're using a dinkum lib that's + // been configured for VC6/7 then there is + // no iterator traits (true even for icl) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +#if defined(__ICL) && (__ICL < 800) && defined(_CPPLIB_VER) && (_CPPLIB_VER <= 310) +// Intel C++ chokes over any non-trivial use of +// this may be an overly restrictive define, but regex fails without it: +# define BOOST_NO_STD_LOCALE +#endif + +// Fix for VC++ 8.0 on up ( I do not have a previous version to test ) +// or clang-cl. If exceptions are off you must manually include the +// header before including the header. Admittedly +// trying to use Boost libraries or the standard C++ libraries without +// exception support is not suggested but currently clang-cl ( v 3.4 ) +// does not support exceptions and must be compiled with exceptions off. +#if !_HAS_EXCEPTIONS && ((defined(BOOST_MSVC) && BOOST_MSVC >= 1400) || (defined(__clang__) && defined(_MSC_VER))) +#include +#endif +#include +#if ( (!_HAS_EXCEPTIONS && !defined(__ghs__)) || (!_HAS_NAMESPACE && defined(__ghs__)) ) && !defined(__TI_COMPILER_VERSION__) && !defined(__VISUALDSPVERSION__) +# define BOOST_NO_STD_TYPEINFO +#endif + +// C++0x headers implemented in 520 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 520 +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_SMART_PTR +#endif + +#if ((!defined(_HAS_TR1_IMPORTS) || (_HAS_TR1_IMPORTS+0 == 0)) && !defined(BOOST_NO_CXX11_HDR_TUPLE)) \ + && (!defined(_CPPLIB_VER) || _CPPLIB_VER < 610) +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +// C++0x headers implemented in 540 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 540 +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +#endif + +// C++0x headers implemented in 610 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 610 +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ALLOCATOR +// 540 has std::align but it is not a conforming implementation +# define BOOST_NO_CXX11_STD_ALIGN +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif (__cplusplus < 201402) && !defined(_MSC_VER) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#elif !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) +# define BOOST_NO_CXX17_STD_INVOKE +#endif + +#if defined(BOOST_INTEL) && (BOOST_INTEL <= 1400) +// Intel's compiler can't handle this header yet: +# define BOOST_NO_CXX11_HDR_ATOMIC +#endif + + +// 520..610 have std::addressof, but it doesn't support functions +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 650 +# define BOOST_NO_CXX11_ADDRESSOF +#endif + +// Bug specific to VC14, +// See https://connect.microsoft.com/VisualStudio/feedback/details/1348277/link-error-when-using-std-codecvt-utf8-utf16-char16-t +// and discussion here: http://blogs.msdn.com/b/vcblog/archive/2014/11/12/visual-studio-2015-preview-now-available.aspx?PageIndex=2 +#if defined(_CPPLIB_VER) && (_CPPLIB_VER == 650) +# define BOOST_NO_CXX11_HDR_CODECVT +#endif + +#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 650) +// If _HAS_AUTO_PTR_ETC is defined to 0, std::auto_ptr is not available. +// See https://www.visualstudio.com/en-us/news/vs2015-vs.aspx#C++ +// and http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx +# if defined(_HAS_AUTO_PTR_ETC) && (_HAS_AUTO_PTR_ETC == 0) +# define BOOST_NO_AUTO_PTR +# endif +#endif + +#ifdef _CPPLIB_VER +# define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER +#else +# define BOOST_DINKUMWARE_STDLIB 1 +#endif + +#ifdef _CPPLIB_VER +# define BOOST_STDLIB "Dinkumware standard library version " BOOST_STRINGIZE(_CPPLIB_VER) +#else +# define BOOST_STDLIB "Dinkumware standard library version 1.x" +#endif diff --git a/thirdparty/linux/include/boost/config/stdlib/libcomo.hpp b/thirdparty/linux/include/boost/config/stdlib/libcomo.hpp new file mode 100644 index 0000000..e3fc627 --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/libcomo.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2002 - 2003. +// (C) Copyright Jens Maurer 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Comeau STL: + +#if !defined(__LIBCOMO__) +# include +# if !defined(__LIBCOMO__) +# error "This is not the Comeau STL!" +# endif +#endif + +// +// std::streambuf is non-standard +// NOTE: versions of libcomo prior to beta28 have octal version numbering, +// e.g. version 25 is 21 (dec) +#if __LIBCOMO_VERSION__ <= 22 +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if (__LIBCOMO_VERSION__ <= 31) && defined(_WIN32) +#define BOOST_NO_SWPRINTF +#endif + +#if __LIBCOMO_VERSION__ >= 31 +# define BOOST_HAS_HASH +# define BOOST_HAS_SLIST +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +#define BOOST_STDLIB "Comeau standard library " BOOST_STRINGIZE(__LIBCOMO_VERSION__) diff --git a/thirdparty/linux/include/boost/config/stdlib/libcpp.hpp b/thirdparty/linux/include/boost/config/stdlib/libcpp.hpp new file mode 100644 index 0000000..2eea999 --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/libcpp.hpp @@ -0,0 +1,113 @@ +// (C) Copyright Christopher Jefferson 2011. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// config for libc++ +// Might need more in here later. + +#if !defined(_LIBCPP_VERSION) +# include +# if !defined(_LIBCPP_VERSION) +# error "This is not libc++!" +# endif +#endif + +#define BOOST_STDLIB "libc++ version " BOOST_STRINGIZE(_LIBCPP_VERSION) + +#define BOOST_HAS_THREADS + +#ifdef _LIBCPP_HAS_NO_VARIADICS +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +// BOOST_NO_CXX11_ALLOCATOR should imply no support for the C++11 +// allocator model. The C++11 allocator model requires a conforming +// std::allocator_traits which is only possible with C++11 template +// aliases since members rebind_alloc and rebind_traits require it. +#if defined(_LIBCPP_HAS_NO_TEMPLATE_ALIASES) +# define BOOST_NO_CXX11_ALLOCATOR +#endif + +#if __cplusplus < 201103 +// +// These two appear to be somewhat useable in C++03 mode, there may be others... +// +//# define BOOST_NO_CXX11_HDR_ARRAY +//# define BOOST_NO_CXX11_HDR_FORWARD_LIST + +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_FUTURE +#elif _LIBCPP_VERSION < 3700 +// +// These appear to be unusable/incomplete so far: +// +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_FUTURE +#endif + + +#if _LIBCPP_VERSION < 3700 +// libc++ uses a non-standard messages_base +#define BOOST_NO_STD_MESSAGES +#endif + +// C++14 features +#if (_LIBCPP_VERSION < 3700) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +// C++17 features +#if (_LIBCPP_VERSION < 3700) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_INVOKE +#endif +#if (_LIBCPP_VERSION < 4000) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_APPLY +#endif + +#if (_LIBCPP_VERSION <= 1101) && !defined(BOOST_NO_CXX11_THREAD_LOCAL) +// This is a bit of a sledgehammer, because really it's just libc++abi that has no +// support for thread_local, leading to linker errors such as +// "undefined reference to `__cxa_thread_atexit'". It is fixed in the +// most recent releases of libc++abi though... +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus <= 201103 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// --- end --- diff --git a/thirdparty/linux/include/boost/config/stdlib/libstdcpp3.hpp b/thirdparty/linux/include/boost/config/stdlib/libstdcpp3.hpp new file mode 100644 index 0000000..557767b --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/libstdcpp3.hpp @@ -0,0 +1,314 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// config for libstdc++ v3 +// not much to go in here: + +#define BOOST_GNU_STDLIB 1 + +#ifdef __GLIBCXX__ +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__) +#else +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCPP__) +#endif + +#if !defined(_GLIBCPP_USE_WCHAR_T) && !defined(_GLIBCXX_USE_WCHAR_T) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if defined(__osf__) && !defined(_REENTRANT) \ + && ( defined(_GLIBCXX_HAVE_GTHR_DEFAULT) || defined(_GLIBCPP_HAVE_GTHR_DEFAULT) ) +// GCC 3 on Tru64 forces the definition of _REENTRANT when any std lib header +// file is included, therefore for consistency we define it here as well. +# define _REENTRANT +#endif + +#ifdef __GLIBCXX__ // gcc 3.4 and greater: +# if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \ + || defined(_GLIBCXX__PTHREADS) \ + || defined(_GLIBCXX_HAS_GTHREADS) \ + || defined(_WIN32) \ + || defined(_AIX) \ + || defined(__HAIKU__) + // + // If the std lib has thread support turned on, then turn it on in Boost + // as well. We do this because some gcc-3.4 std lib headers define _REENTANT + // while others do not... + // +# define BOOST_HAS_THREADS +# else +# define BOOST_DISABLE_THREADS +# endif +#elif defined(__GLIBCPP__) \ + && !defined(_GLIBCPP_HAVE_GTHR_DEFAULT) \ + && !defined(_GLIBCPP__PTHREADS) + // disable thread support if the std lib was built single threaded: +# define BOOST_DISABLE_THREADS +#endif + +#if (defined(linux) || defined(__linux) || defined(__linux__)) && defined(__arm__) && defined(_GLIBCPP_HAVE_GTHR_DEFAULT) +// linux on arm apparently doesn't define _REENTRANT +// so just turn on threading support whenever the std lib is thread safe: +# define BOOST_HAS_THREADS +#endif + +#if !defined(_GLIBCPP_USE_LONG_LONG) \ + && !defined(_GLIBCXX_USE_LONG_LONG)\ + && defined(BOOST_HAS_LONG_LONG) +// May have been set by compiler/*.hpp, but "long long" without library +// support is useless. +# undef BOOST_HAS_LONG_LONG +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +#if defined(__GLIBCXX__) || (defined(__GLIBCPP__) && __GLIBCPP__>=20020514) // GCC >= 3.1.0 +# define BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx +# define BOOST_HAS_SLIST +# define BOOST_HAS_HASH +# define BOOST_SLIST_HEADER +# if !defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# else +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# endif +#endif + +// +// Decide whether we have C++11 support turned on: +// +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103) +# define BOOST_LIBSTDCXX11 +#endif + +// +// Decide which version of libstdc++ we have, normally +// stdlibc++ C++0x support is detected via __GNUC__, __GNUC_MINOR__, and possibly +// __GNUC_PATCHLEVEL__ at the suggestion of Jonathan Wakely, one of the stdlibc++ +// developers. He also commented: +// +// "I'm not sure how useful __GLIBCXX__ is for your purposes, for instance in +// GCC 4.2.4 it is set to 20080519 but in GCC 4.3.0 it is set to 20080305. +// Although 4.3.0 was released earlier than 4.2.4, it has better C++0x support +// than any release in the 4.2 series." +// +// Another resource for understanding stdlibc++ features is: +// http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#manual.intro.status.standard.200x +// +// However, using the GCC version number fails when the compiler is clang since this +// only ever claims to emulate GCC-4.2, see https://svn.boost.org/trac/boost/ticket/7473 +// for a long discussion on this issue. What we can do though is use clang's __has_include +// to detect the presence of a C++11 header that was introduced with a specific GCC release. +// We still have to be careful though as many such headers were buggy and/or incomplete when +// first introduced, so we only check for headers that were fully featured from day 1, and then +// use that to infer the underlying GCC version: +// +#ifdef __clang__ + +#if __has_include() +# define BOOST_LIBSTDCXX_VERSION 60100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 50100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40900 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40800 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40700 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40600 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40500 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40400 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40300 +#endif + +// +// GCC 4.8 and 9 add working versions of and respectively. +// However, we have no test for these as the headers were present but broken +// in early GCC versions. +// +#endif + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) && (__cplusplus >= 201103L) +// +// Oracle Solaris compiler uses it's own verison of libstdc++ but doesn't +// set __GNUC__ +// +#if __SUNPRO_CC >= 0x5140 +#define BOOST_LIBSTDCXX_VERSION 50100 +#else +#define BOOST_LIBSTDCXX_VERSION 40800 +#endif +#endif + +#if !defined(BOOST_LIBSTDCXX_VERSION) +# define BOOST_LIBSTDCXX_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +// std::auto_ptr isn't provided with _GLIBCXX_DEPRECATED=0 (GCC 4.5 and earlier) +// or _GLIBCXX_USE_DEPRECATED=0 (GCC 4.6 and later). +#if defined(BOOST_LIBSTDCXX11) +# if BOOST_LIBSTDCXX_VERSION < 40600 +# if !_GLIBCXX_DEPRECATED +# define BOOST_NO_AUTO_PTR +# endif +# elif !_GLIBCXX_USE_DEPRECATED +# define BOOST_NO_AUTO_PTR +# endif +#endif + +// C++0x headers in GCC 4.3.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40300) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +#endif + +// C++0x headers in GCC 4.4.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40400) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_SMART_PTR +#else +# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG +# define BOOST_HAS_TR1_COMPLEX_OVERLOADS +#endif + +// C++0x features in GCC 4.5.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40500) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_RANDOM +#endif + +// C++0x features in GCC 4.6.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40600) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_ADDRESSOF +#endif + +// C++0x features in GCC 4.7.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40700) || !defined(BOOST_LIBSTDCXX11) +// Note that although existed prior to 4.7, "steady_clock" is spelled "monotonic_clock" +// so 4.7.0 is the first truely conforming one. +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_ALLOCATOR +#endif +// C++0x features in GCC 4.8.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40800) || !defined(BOOST_LIBSTDCXX11) +// Note that although existed prior to gcc 4.8 it was largely unimplemented for many types: +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_THREAD +#endif +// C++0x features in GCC 4.9.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) +// Although is present and compilable against, the actual implementation is not functional +// even for the simplest patterns such as "\d" or "[0-9]". This is the case at least in gcc up to 4.8, inclusively. +# define BOOST_NO_CXX11_HDR_REGEX +#endif +#if (BOOST_LIBSTDCXX_VERSION < 40900) || (__cplusplus <= 201103) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +#if defined(__clang_major__) && ((__clang_major__ < 3) || ((__clang_major__ == 3) && (__clang_minor__ < 7))) +// As of clang-3.6, libstdc++ header throws up errors with clang: +# define BOOST_NO_CXX11_HDR_ATOMIC +#endif +// +// C++0x features in GCC 5.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 50100) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_STD_ALIGN +#endif + +// +// C++17 features in GCC 6.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 60100) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_INVOKE +#endif +#if (BOOST_LIBSTDCXX_VERSION < 70100) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_APPLY +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus <= 201103 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#elif __cplusplus < 201402 || (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// +// Headers not present on Solaris with the Oracle compiler: +#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140) +#define BOOST_NO_CXX11_HDR_FUTURE +#define BOOST_NO_CXX11_HDR_FORWARD_LIST +#define BOOST_NO_CXX11_HDR_ATOMIC +// shared_ptr is present, but is not convertible to bool +// which causes all kinds of problems especially in Boost.Thread +// but probably elsewhere as well. +#define BOOST_NO_CXX11_SMART_PTR +#endif + +#if (!defined(_GLIBCXX_HAS_GTHREADS) || !defined(_GLIBCXX_USE_C99_STDINT_TR1)) + // Headers not always available: +# ifndef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# endif +# ifndef BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_MUTEX +# endif +# ifndef BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_THREAD +# endif +# ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +# endif +#endif + +#if (!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK) || (_GTHREAD_USE_MUTEX_TIMEDLOCK == 0)) && !defined(BOOST_NO_CXX11_HDR_MUTEX) +// Timed mutexes are not always available: +# define BOOST_NO_CXX11_HDR_MUTEX +#endif + +// --- end --- diff --git a/thirdparty/linux/include/boost/config/stdlib/modena.hpp b/thirdparty/linux/include/boost/config/stdlib/modena.hpp new file mode 100644 index 0000000..fa4a818 --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/modena.hpp @@ -0,0 +1,76 @@ +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Modena C++ standard library (comes with KAI C++) + +#if !defined(MSIPL_COMPILE_H) +# include +# if !defined(__MSIPL_COMPILE_H) +# error "This is not the Modena C++ library!" +# endif +#endif + +#ifndef MSIPL_NL_TYPES +#define BOOST_NO_STD_MESSAGES +#endif + +#ifndef MSIPL_WCHART +#define BOOST_NO_STD_WSTRING +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE + +#define BOOST_STDLIB "Modena C++ standard library" + + + + + diff --git a/thirdparty/linux/include/boost/config/stdlib/msl.hpp b/thirdparty/linux/include/boost/config/stdlib/msl.hpp new file mode 100644 index 0000000..8f21a13 --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/msl.hpp @@ -0,0 +1,95 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Metrowerks standard library: + +#ifndef __MSL_CPP__ +# include +# ifndef __MSL_CPP__ +# error This is not the MSL standard library! +# endif +#endif + +#if __MSL_CPP__ >= 0x6000 // Pro 6 +# define BOOST_HAS_HASH +# define BOOST_STD_EXTENSION_NAMESPACE Metrowerks +#endif +#define BOOST_HAS_SLIST + +#if __MSL_CPP__ < 0x6209 +# define BOOST_NO_STD_MESSAGES +#endif + +// check C lib version for +#include + +#if defined(__MSL__) && (__MSL__ >= 0x5000) +# define BOOST_HAS_STDINT_H +# if !defined(__PALMOS_TRAPS__) +# define BOOST_HAS_UNISTD_H +# endif + // boilerplate code: +# include +#endif + +#if defined(_MWMT) || _MSL_THREADSAFE +# define BOOST_HAS_THREADS +#endif + +#ifdef _MSL_NO_EXPLICIT_FUNC_TEMPLATE_ARG +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE + +#define BOOST_STDLIB "Metrowerks Standard Library version " BOOST_STRINGIZE(__MSL_CPP__) diff --git a/thirdparty/linux/include/boost/config/stdlib/roguewave.hpp b/thirdparty/linux/include/boost/config/stdlib/roguewave.hpp new file mode 100644 index 0000000..437d38d --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/roguewave.hpp @@ -0,0 +1,205 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2003. +// (C) Copyright Boris Gubenko 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Rogue Wave std lib: + +#define BOOST_RW_STDLIB 1 + +#if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# include +# if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# error This is not the Rogue Wave standard library +# endif +#endif +// +// figure out a consistent version number: +// +#ifndef _RWSTD_VER +# define BOOST_RWSTD_VER 0x010000 +#elif _RWSTD_VER < 0x010000 +# define BOOST_RWSTD_VER (_RWSTD_VER << 8) +#else +# define BOOST_RWSTD_VER _RWSTD_VER +#endif + +#ifndef _RWSTD_VER +# define BOOST_STDLIB "Rogue Wave standard library version (Unknown version)" +#elif _RWSTD_VER < 0x04010200 + # define BOOST_STDLIB "Rogue Wave standard library version " BOOST_STRINGIZE(_RWSTD_VER) +#else +# ifdef _RWSTD_VER_STR +# define BOOST_STDLIB "Apache STDCXX standard library version " _RWSTD_VER_STR +# else +# define BOOST_STDLIB "Apache STDCXX standard library version " BOOST_STRINGIZE(_RWSTD_VER) +# endif +#endif + +// +// Prior to version 2.2.0 the primary template for std::numeric_limits +// does not have compile time constants, even though specializations of that +// template do: +// +#if BOOST_RWSTD_VER < 0x020200 +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// Sun CC 5.5 patch 113817-07 adds long long specialization, but does not change the +// library version number (http://sunsolve6.sun.com/search/document.do?assetkey=1-21-113817): +#if BOOST_RWSTD_VER <= 0x020101 && (!defined(__SUNPRO_CC) || (__SUNPRO_CC < 0x550)) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// Borland version of numeric_limits lacks __int64 specialisation: +// +#ifdef __BORLANDC__ +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// No std::iterator if it can't figure out default template args: +// +#if defined(_RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || defined(RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// No iterator traits without partial specialization: +// +#if defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) || defined(RWSTD_NO_CLASS_PARTIAL_SPEC) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// Prior to version 2.0, std::auto_ptr was buggy, and there were no +// new-style iostreams, and no conformant std::allocator: +// +#if (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_AUTO_PTR +# define BOOST_NO_STRINGSTREAM +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STD_LOCALE +#endif + +// +// No template iterator constructors without member template support: +// +#if defined(RWSTD_NO_MEMBER_TEMPLATES) || defined(_RWSTD_NO_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +#endif + +// +// RW defines _RWSTD_ALLOCATOR if the allocator is conformant and in use +// (the or _HPACC_ part is a hack - the library seems to define _RWSTD_ALLOCATOR +// on HP aCC systems even though the allocator is in fact broken): +// +#if !defined(_RWSTD_ALLOCATOR) || (defined(__HP_aCC) && __HP_aCC <= 33100) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If we have a std::locale, we still may not have std::use_facet: +// +#if defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) && !defined(BOOST_NO_STD_LOCALE) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// +// There's no std::distance prior to version 2, or without +// partial specialization support: +// +#if (BOOST_RWSTD_VER < 0x020000) || defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + #define BOOST_NO_STD_DISTANCE +#endif + +// +// Some versions of the rogue wave library don't have assignable +// OutputIterators: +// +#if BOOST_RWSTD_VER < 0x020100 +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +#endif + +// +// Disable BOOST_HAS_LONG_LONG when the library has no support for it. +// +#if !defined(_RWSTD_LONG_LONG) && defined(BOOST_HAS_LONG_LONG) +# undef BOOST_HAS_LONG_LONG +#endif + +// +// check that on HP-UX, the proper RW library is used +// +#if defined(__HP_aCC) && !defined(_HP_NAMESPACE_STD) +# error "Boost requires Standard RW library. Please compile and link with -AA" +#endif + +// +// Define macros specific to RW V2.2 on HP-UX +// +#if defined(__HP_aCC) && (BOOST_RWSTD_VER == 0x02020100) +# ifndef __HP_TC1_MAKE_PAIR +# define __HP_TC1_MAKE_PAIR +# endif +# ifndef _HP_INSTANTIATE_STD2_VL +# define _HP_INSTANTIATE_STD2_VL +# endif +#endif + +#if _RWSTD_VER < 0x05000000 +# define BOOST_NO_CXX11_HDR_ARRAY +#endif +// type_traits header is incomplete: +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +// +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE diff --git a/thirdparty/linux/include/boost/config/stdlib/sgi.hpp b/thirdparty/linux/include/boost/config/stdlib/sgi.hpp new file mode 100644 index 0000000..8d2f849 --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/sgi.hpp @@ -0,0 +1,165 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// generic SGI STL: + +#if !defined(__STL_CONFIG_H) +# include +# if !defined(__STL_CONFIG_H) +# error "This is not the SGI STL!" +# endif +#endif + +// +// No std::iterator traits without partial specialisation: +// +#if !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No std::stringstream with gcc < 3 +// +#if defined(__GNUC__) && (__GNUC__ < 3) && \ + ((__GNUC_MINOR__ < 95) || (__GNUC_MINOR__ == 96)) && \ + !defined(__STL_USE_NEW_IOSTREAMS) || \ + defined(__APPLE_CC__) + // Note that we only set this for GNU C++ prior to 2.95 since the + // latest patches for that release do contain a minimal + // If you are running a 2.95 release prior to 2.95.3 then this will need + // setting, but there is no way to detect that automatically (other + // than by running the configure script). + // Also, the unofficial GNU C++ 2.96 included in RedHat 7.1 doesn't + // have . +# define BOOST_NO_STRINGSTREAM +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + + +// +// Assume no std::locale without own iostreams (this may be an +// incorrect assumption in some cases): +// +#if !defined(__SGI_STL_OWN_IOSTREAMS) && !defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// Original native SGI streams have non-standard std::messages facet: +// +#if defined(__sgi) && (_COMPILER_VERSION <= 650) && !defined(__SGI_STL_OWN_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// SGI's new iostreams have missing "const" in messages<>::open +// +#if defined(__sgi) && (_COMPILER_VERSION <= 740) && defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_MESSAGES +#endif + +// +// No template iterator constructors, or std::allocator +// without member templates: +// +#if !defined(__STL_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST + +// +// If this is GNU libstdc++2, then no and no std::wstring: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) +# include +# if defined(__BASTRING__) +# define BOOST_NO_LIMITS +// Note: will provide compile-time constants +# undef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_STD_WSTRING +# endif +#endif + +// +// There is no standard iterator unless we have namespace support: +// +#if !defined(__STL_USE_NAMESPACES) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE + +#define BOOST_STDLIB "SGI standard library" diff --git a/thirdparty/linux/include/boost/config/stdlib/stlport.hpp b/thirdparty/linux/include/boost/config/stdlib/stlport.hpp new file mode 100644 index 0000000..518f9ef --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/stlport.hpp @@ -0,0 +1,255 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// STLPort standard library config: + +#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# include +# if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# error "This is not STLPort!" +# endif +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +// +// __STL_STATIC_CONST_INIT_BUG implies BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +// for versions prior to 4.1(beta) +// +#if (defined(__STL_STATIC_CONST_INIT_BUG) || defined(_STLP_STATIC_CONST_INIT_BUG)) && (__SGI_STL_PORT <= 0x400) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// +// If STLport thinks that there is no partial specialisation, then there is no +// std::iterator traits: +// +#if !(defined(_STLP_CLASS_PARTIAL_SPECIALIZATION) || defined(__STL_CLASS_PARTIAL_SPECIALIZATION)) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No new style iostreams on GCC without STLport's iostreams enabled: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) && !(defined(__SGI_STL_OWN_IOSTREAMS) || defined(_STLP_OWN_IOSTREAMS)) +# define BOOST_NO_STRINGSTREAM +#endif + +// +// No new iostreams implies no std::locale, and no std::stringstream: +// +#if defined(__STL_NO_IOSTREAMS) || defined(__STL_NO_NEW_IOSTREAMS) || defined(_STLP_NO_IOSTREAMS) || defined(_STLP_NO_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +#endif + +// +// If the streams are not native, and we have a "using ::x" compiler bug +// then the io stream facets are not available in namespace std:: +// +#ifdef _STLPORT_VERSION +# if !(_STLPORT_VERSION >= 0x500) && !defined(_STLP_OWN_IOSTREAMS) && defined(_STLP_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__BORLANDC__) +# define BOOST_NO_STD_LOCALE +# endif +#else +# if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__BORLANDC__) +# define BOOST_NO_STD_LOCALE +# endif +#endif + +#if defined(_STLPORT_VERSION) && (_STLPORT_VERSION >= 0x520) +# define BOOST_HAS_TR1_UNORDERED_SET +# define BOOST_HAS_TR1_UNORDERED_MAP +#endif +// +// Without member template support enabled, their are no template +// iterate constructors, and no std::allocator: +// +#if !(defined(__STL_MEMBER_TEMPLATES) || defined(_STLP_MEMBER_TEMPLATES)) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif +// +// however we always have at least a partial allocator: +// +#define BOOST_HAS_PARTIAL_STD_ALLOCATOR + +#if !defined(_STLP_MEMBER_TEMPLATE_CLASSES) || defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) +# define BOOST_NO_STD_ALLOCATOR +#endif + +#if defined(_STLP_NO_MEMBER_TEMPLATE_KEYWORD) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If STLport thinks there is no wchar_t at all, then we have to disable +// the support for the relevant specilazations of std:: templates. +// +#if !defined(_STLP_HAS_WCHAR_T) && !defined(_STLP_WCHAR_T_IS_USHORT) +# ifndef BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTRING +# endif +# ifndef BOOST_NO_STD_WSTREAMBUF +# define BOOST_NO_STD_WSTREAMBUF +# endif +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#ifndef _STLP_NO_EXTENSIONS +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST +#endif + +// +// STLport does a good job of importing names into namespace std::, +// but doesn't always get them all, define BOOST_NO_STDC_NAMESPACE, since our +// workaround does not conflict with STLports: +// +// +// Harold Howe says: +// Borland switched to STLport in BCB6. Defining BOOST_NO_STDC_NAMESPACE with +// BCB6 does cause problems. If we detect C++ Builder, then don't define +// BOOST_NO_STDC_NAMESPACE +// +#if !defined(__BORLANDC__) && !defined(__DMC__) +// +// If STLport is using it's own namespace, and the real names are in +// the global namespace, then we duplicate STLport's using declarations +// (by defining BOOST_NO_STDC_NAMESPACE), we do this because STLport doesn't +// necessarily import all the names we need into namespace std:: +// +# if (defined(__STL_IMPORT_VENDOR_CSTD) \ + || defined(__STL_USE_OWN_NAMESPACE) \ + || defined(_STLP_IMPORT_VENDOR_CSTD) \ + || defined(_STLP_USE_OWN_NAMESPACE)) \ + && (defined(__STL_VENDOR_GLOBAL_CSTD) || defined (_STLP_VENDOR_GLOBAL_CSTD)) +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +#elif defined(__BORLANDC__) && __BORLANDC__ < 0x560 +// STLport doesn't import std::abs correctly: +#include +namespace std { using ::abs; } +// and strcmp/strcpy don't get imported either ('cos they are macros) +#include +#ifdef strcpy +# undef strcpy +#endif +#ifdef strcmp +# undef strcmp +#endif +#ifdef _STLP_VENDOR_CSTD +namespace std{ using _STLP_VENDOR_CSTD::strcmp; using _STLP_VENDOR_CSTD::strcpy; } +#endif +#endif + +// +// std::use_facet may be non-standard, uses a class instead: +// +#if defined(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) || defined(_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_STLP_USE_FACET +#endif + +// +// If STLport thinks there are no wide functions, etc. is not working; but +// only if BOOST_NO_STDC_NAMESPACE is not defined (if it is then we do the import +// into std:: ourselves). +// +#if defined(_STLP_NO_NATIVE_WIDE_FUNCTIONS) && !defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +#endif + +// +// If STLport for some reason was configured so that it thinks that wchar_t +// is not an intrinsic type, then we have to disable the support for it as +// well (we would be missing required specializations otherwise). +// +#if !defined( _STLP_HAS_WCHAR_T) || defined(_STLP_WCHAR_T_IS_USHORT) +# undef BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +// +// Borland ships a version of STLport with C++ Builder 6 that lacks +// hashtables and the like: +// +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x560) +# undef BOOST_HAS_HASH +#endif + +// +// gcc-2.95.3/STLPort does not like the using declarations we use to get ADL with std::min/max +// +#if defined(__GNUC__) && (__GNUC__ < 3) +# include // for std::min and std::max +# define BOOST_USING_STD_MIN() ((void)0) +# define BOOST_USING_STD_MAX() ((void)0) +namespace boost { using std::min; using std::max; } +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE + +#define BOOST_STDLIB "STLPort standard library version " BOOST_STRINGIZE(__SGI_STL_PORT) diff --git a/thirdparty/linux/include/boost/config/stdlib/vacpp.hpp b/thirdparty/linux/include/boost/config/stdlib/vacpp.hpp new file mode 100644 index 0000000..f9afef6 --- /dev/null +++ b/thirdparty/linux/include/boost/config/stdlib/vacpp.hpp @@ -0,0 +1,71 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +#if __IBMCPP__ <= 501 +# define BOOST_NO_STD_ALLOCATOR +#endif + +#define BOOST_HAS_MACRO_USE_FACET +#define BOOST_NO_STD_MESSAGES + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE + +#define BOOST_STDLIB "Visual Age default standard library" diff --git a/thirdparty/linux/include/boost/config/suffix.hpp b/thirdparty/linux/include/boost/config/suffix.hpp new file mode 100644 index 0000000..eeaec2b --- /dev/null +++ b/thirdparty/linux/include/boost/config/suffix.hpp @@ -0,0 +1,1017 @@ +// Boost config.hpp configuration header file ------------------------------// +// boostinspect:ndprecated_macros -- tell the inspect tool to ignore this file + +// Copyright (c) 2001-2003 John Maddock +// Copyright (c) 2001 Darin Adler +// Copyright (c) 2001 Peter Dimov +// Copyright (c) 2002 Bill Kempf +// Copyright (c) 2002 Jens Maurer +// Copyright (c) 2002-2003 David Abrahams +// Copyright (c) 2003 Gennaro Prota +// Copyright (c) 2003 Eric Friedman +// Copyright (c) 2010 Eric Jourdanneau, Joel Falcou +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config/ +// +// This file is intended to be stable, and relatively unchanging. +// It should contain boilerplate code only - no compiler specific +// code unless it is unavoidable - no changes unless unavoidable. + +#ifndef BOOST_CONFIG_SUFFIX_HPP +#define BOOST_CONFIG_SUFFIX_HPP + +#if defined(__GNUC__) && (__GNUC__ >= 4) +// +// Some GCC-4.x versions issue warnings even when __extension__ is used, +// so use this as a workaround: +// +#pragma GCC system_header +#endif + +// +// ensure that visibility macros are always defined, thus symplifying use +// +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_SYMBOL_EXPORT +#endif +#ifndef BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_IMPORT +#endif +#ifndef BOOST_SYMBOL_VISIBLE +# define BOOST_SYMBOL_VISIBLE +#endif + +// +// look for long long by looking for the appropriate macros in . +// Note that we use limits.h rather than climits for maximal portability, +// remember that since these just declare a bunch of macros, there should be +// no namespace issues from this. +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG) \ + && !defined(BOOST_MSVC) && !defined(__BORLANDC__) +# include +# if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif +#endif + +// GCC 3.x will clean up all of those nasty macro definitions that +// BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine +// it under GCC 3.x. +#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS) +# undef BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// Assume any extensions are in namespace std:: unless stated otherwise: +// +# ifndef BOOST_STD_EXTENSION_NAMESPACE +# define BOOST_STD_EXTENSION_NAMESPACE std +# endif + +// +// If cv-qualified specializations are not allowed, then neither are cv-void ones: +// +# if defined(BOOST_NO_CV_SPECIALIZATIONS) \ + && !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# endif + +// +// If there is no numeric_limits template, then it can't have any compile time +// constants either! +// +# if defined(BOOST_NO_LIMITS) \ + && !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// if there is no long long then there is no specialisation +// for numeric_limits either: +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +#endif + +// +// if there is no __int64 then there is no specialisation +// for numeric_limits<__int64> either: +// +#if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// if member templates are supported then so is the +// VC6 subset of member templates: +// +# if !defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +# define BOOST_MSVC6_MEMBER_TEMPLATES +# endif + +// +// Without partial specialization, can't test for partial specialisation bugs: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# endif + +// +// Without partial specialization, we can't have array-type partial specialisations: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif + +// +// Without partial specialization, std::iterator_traits can't work: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_STD_ITERATOR_TRAITS) +# define BOOST_NO_STD_ITERATOR_TRAITS +# endif + +// +// Without partial specialization, partial +// specialization with default args won't work either: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS) +# define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +# endif + +// +// Without member template support, we can't have template constructors +// in the standard library either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# endif + +// +// Without member template support, we can't have a conforming +// std::allocator template either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_NO_STD_ALLOCATOR +# endif + +// +// without ADL support then using declarations will break ADL as well: +// +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// Without typeid support we have no dynamic RTTI either: +// +#if defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// +// If we have a standard allocator, then we have a partial one as well: +// +#if !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +// +// We can't have a working std::use_facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET) +# define BOOST_NO_STD_USE_FACET +# endif + +// +// We can't have a std::messages facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES) +# define BOOST_NO_STD_MESSAGES +# endif + +// +// We can't have a working std::wstreambuf if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF) +# define BOOST_NO_STD_WSTREAMBUF +# endif + +// +// We can't have a if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE) +# define BOOST_NO_CWCTYPE +# endif + +// +// We can't have a swprintf if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +# endif + +// +// If Win32 support is turned off, then we must turn off +// threading support also, unless there is some other +// thread API enabled: +// +#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \ + && !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS) +# define BOOST_DISABLE_THREADS +#endif + +// +// Turn on threading support if the compiler thinks that it's in +// multithreaded mode. We put this here because there are only a +// limited number of macros that identify this (if there's any missing +// from here then add to the appropriate compiler section): +// +#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \ + || defined(_PTHREADS) || defined(__APPLE__) || defined(__DragonFly__)) \ + && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if BOOST_DISABLE_THREADS is defined: +// +#if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if we don't recognise the threading API: +// +#if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\ + && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\ + && !defined(BOOST_HAS_MPTASKS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading detail macros off if we don't (want to) use threading +// +#ifndef BOOST_HAS_THREADS +# undef BOOST_HAS_PTHREADS +# undef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# undef BOOST_HAS_PTHREAD_YIELD +# undef BOOST_HAS_PTHREAD_DELAY_NP +# undef BOOST_HAS_WINTHREADS +# undef BOOST_HAS_BETHREADS +# undef BOOST_HAS_MPTASKS +#endif + +// +// If the compiler claims to be C99 conformant, then it had better +// have a : +// +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +# define BOOST_HAS_STDINT_H +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +// +// Define BOOST_NO_SLIST and BOOST_NO_HASH if required. +// Note that this is for backwards compatibility only. +// +# if !defined(BOOST_HAS_SLIST) && !defined(BOOST_NO_SLIST) +# define BOOST_NO_SLIST +# endif + +# if !defined(BOOST_HAS_HASH) && !defined(BOOST_NO_HASH) +# define BOOST_NO_HASH +# endif + +// +// Set BOOST_SLIST_HEADER if not set already: +// +#if defined(BOOST_HAS_SLIST) && !defined(BOOST_SLIST_HEADER) +# define BOOST_SLIST_HEADER +#endif + +// +// Set BOOST_HASH_SET_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER) +# define BOOST_HASH_SET_HEADER +#endif + +// +// Set BOOST_HASH_MAP_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_MAP_HEADER) +# define BOOST_HASH_MAP_HEADER +#endif + +// BOOST_HAS_ABI_HEADERS +// This macro gets set if we have headers that fix the ABI, +// and prevent ODR violations when linking to external libraries: +#if defined(BOOST_ABI_PREFIX) && defined(BOOST_ABI_SUFFIX) && !defined(BOOST_HAS_ABI_HEADERS) +# define BOOST_HAS_ABI_HEADERS +#endif + +#if defined(BOOST_HAS_ABI_HEADERS) && defined(BOOST_DISABLE_ABI_HEADERS) +# undef BOOST_HAS_ABI_HEADERS +#endif + +// BOOST_NO_STDC_NAMESPACE workaround --------------------------------------// +// Because std::size_t usage is so common, even in boost headers which do not +// otherwise use the C library, the workaround is included here so +// that ugly workaround code need not appear in many other boost headers. +// NOTE WELL: This is a workaround for non-conforming compilers; +// must still be #included in the usual places so that inclusion +// works as expected with standard conforming compilers. The resulting +// double inclusion of is harmless. + +# if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus) +# include + namespace std { using ::ptrdiff_t; using ::size_t; } +# endif + +// Workaround for the unfortunate min/max macros defined by some platform headers + +#define BOOST_PREVENT_MACRO_SUBSTITUTION + +#ifndef BOOST_USING_STD_MIN +# define BOOST_USING_STD_MIN() using std::min +#endif + +#ifndef BOOST_USING_STD_MAX +# define BOOST_USING_STD_MAX() using std::max +#endif + +// BOOST_NO_STD_MIN_MAX workaround -----------------------------------------// + +# if defined(BOOST_NO_STD_MIN_MAX) && defined(__cplusplus) + +namespace std { + template + inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; + } + template + inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; + } +} + +# endif + +// BOOST_STATIC_CONSTANT workaround --------------------------------------- // +// On compilers which don't allow in-class initialization of static integral +// constant members, we must use enums as a workaround if we want the constants +// to be available at compile-time. This macro gives us a convenient way to +// declare such constants. + +# ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } +# else +# define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment +# endif + +// BOOST_USE_FACET / HAS_FACET workaround ----------------------------------// +// When the standard library does not have a conforming std::use_facet there +// are various workarounds available, but they differ from library to library. +// The same problem occurs with has_facet. +// These macros provide a consistent way to access a locale's facets. +// Usage: +// replace +// std::use_facet(loc); +// with +// BOOST_USE_FACET(Type, loc); +// Note do not add a std:: prefix to the front of BOOST_USE_FACET! +// Use for BOOST_HAS_FACET is analogous. + +#if defined(BOOST_NO_STD_USE_FACET) +# ifdef BOOST_HAS_TWO_ARG_USE_FACET +# define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast(0)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet(loc, static_cast(0)) +# elif defined(BOOST_HAS_MACRO_USE_FACET) +# define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type) +# define BOOST_HAS_FACET(Type, loc) std::_HAS(loc, Type) +# elif defined(BOOST_HAS_STLP_USE_FACET) +# define BOOST_USE_FACET(Type, loc) (*std::_Use_facet(loc)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +# endif +#else +# define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +#endif + +// BOOST_NESTED_TEMPLATE workaround ------------------------------------------// +// Member templates are supported by some compilers even though they can't use +// the A::template member syntax, as a workaround replace: +// +// typedef typename A::template rebind binder; +// +// with: +// +// typedef typename A::BOOST_NESTED_TEMPLATE rebind binder; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# define BOOST_NESTED_TEMPLATE template +#else +# define BOOST_NESTED_TEMPLATE +#endif + +// BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------// +// Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION +// is defined, in which case it evaluates to return x; Use when you have a return +// statement that can never be reached. + +#ifndef BOOST_UNREACHABLE_RETURN +# ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_UNREACHABLE_RETURN(x) return x; +# else +# define BOOST_UNREACHABLE_RETURN(x) +# endif +#endif + +// BOOST_DEDUCED_TYPENAME workaround ------------------------------------------// +// +// Some compilers don't support the use of `typename' for dependent +// types in deduced contexts, e.g. +// +// template void f(T, typename T::type); +// ^^^^^^^^ +// Replace these declarations with: +// +// template void f(T, BOOST_DEDUCED_TYPENAME T::type); + +#ifndef BOOST_NO_DEDUCED_TYPENAME +# define BOOST_DEDUCED_TYPENAME typename +#else +# define BOOST_DEDUCED_TYPENAME +#endif + +#ifndef BOOST_NO_TYPENAME_WITH_CTOR +# define BOOST_CTOR_TYPENAME typename +#else +# define BOOST_CTOR_TYPENAME +#endif + +// long long workaround ------------------------------------------// +// On gcc (and maybe other compilers?) long long is alway supported +// but it's use may generate either warnings (with -ansi), or errors +// (with -pedantic -ansi) unless it's use is prefixed by __extension__ +// +#if defined(BOOST_HAS_LONG_LONG) && defined(__cplusplus) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef long long long_long_type; + __extension__ typedef unsigned long long ulong_long_type; +# else + typedef long long long_long_type; + typedef unsigned long long ulong_long_type; +# endif +} +#endif +// same again for __int128: +#if defined(BOOST_HAS_INT128) && defined(__cplusplus) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef __int128 int128_type; + __extension__ typedef unsigned __int128 uint128_type; +# else + typedef __int128 int128_type; + typedef unsigned __int128 uint128_type; +# endif +} +#endif +// same again for __float128: +#if defined(BOOST_HAS_FLOAT128) && defined(__cplusplus) +namespace boost { +# ifdef __GNUC__ + __extension__ typedef __float128 float128_type; +# else + typedef __float128 float128_type; +# endif +} +#endif + +// BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// + +// These macros are obsolete. Port away and remove. + +# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +// When BOOST_NO_STD_TYPEINFO is defined, we can just import +// the global definition into std namespace: +#if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus) +#include +namespace std{ using ::type_info; } +#endif + +// ---------------------------------------------------------------------------// + +// +// Helper macro BOOST_STRINGIZE: +// Converts the parameter X to a string after macro replacement +// on X has been performed. +// +#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +#define BOOST_DO_STRINGIZE(X) #X + +// +// Helper macro BOOST_JOIN: +// The following piece of macro magic joins the two +// arguments together, even when one of the arguments is +// itself a macro (see 16.3.1 in C++ standard). The key +// is that macro expansion of macro arguments does not +// occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN. +// +#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) +#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y) +#define BOOST_DO_JOIN2( X, Y ) X##Y + +// +// Set some default values for compiler/library/platform names. +// These are for debugging config setup only: +// +# ifndef BOOST_COMPILER +# define BOOST_COMPILER "Unknown ISO C++ Compiler" +# endif +# ifndef BOOST_STDLIB +# define BOOST_STDLIB "Unknown ISO standard library" +# endif +# ifndef BOOST_PLATFORM +# if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) +# define BOOST_PLATFORM "Generic Unix" +# else +# define BOOST_PLATFORM "Unknown" +# endif +# endif + +// +// Set some default values GPU support +// +# ifndef BOOST_GPU_ENABLED +# define BOOST_GPU_ENABLED +# endif + +// BOOST_FORCEINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to force a function to be inline +#if !defined(BOOST_FORCEINLINE) +# if defined(_MSC_VER) +# define BOOST_FORCEINLINE __forceinline +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__)) +# else +# define BOOST_FORCEINLINE inline +# endif +#endif + +// BOOST_NOINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to prevent a function to be inlined +#if !defined(BOOST_NOINLINE) +# if defined(_MSC_VER) +# define BOOST_NOINLINE __declspec(noinline) +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# if defined(__CUDACC__) + // nvcc doesn't always parse __noinline__, + // see: https://svn.boost.org/trac/boost/ticket/9392 +# define BOOST_NOINLINE __attribute__ ((noinline)) +# else +# define BOOST_NOINLINE __attribute__ ((__noinline__)) +# endif +# else +# define BOOST_NOINLINE +# endif +#endif + +// BOOST_NORETURN ---------------------------------------------// +// Macro to use before a function declaration/definition to designate +// the function as not returning normally (i.e. with a return statement +// or by leaving the function scope, if the function return type is void). +#if !defined(BOOST_NORETURN) +# if defined(_MSC_VER) +# define BOOST_NORETURN __declspec(noreturn) +# elif defined(__GNUC__) +# define BOOST_NORETURN __attribute__ ((__noreturn__)) +# elif defined(__has_attribute) && defined(__SUNPRO_CC) +# if __has_attribute(noreturn) +# define BOOST_NORETURN [[noreturn]] +# endif +# elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(noreturn) +# define BOOST_NORETURN [[noreturn]] +# endif +# endif +#endif + +#if !defined(BOOST_NORETURN) +# define BOOST_NO_NORETURN +# define BOOST_NORETURN +#endif + +// Branch prediction hints +// These macros are intended to wrap conditional expressions that yield true or false +// +// if (BOOST_LIKELY(var == 10)) +// { +// // the most probable code here +// } +// +#if !defined(BOOST_LIKELY) +# define BOOST_LIKELY(x) x +#endif +#if !defined(BOOST_UNLIKELY) +# define BOOST_UNLIKELY(x) x +#endif + +// Type and data alignment specification +// +#if !defined(BOOST_NO_CXX11_ALIGNAS) +# define BOOST_ALIGNMENT(x) alignas(x) +#elif defined(_MSC_VER) +# define BOOST_ALIGNMENT(x) __declspec(align(x)) +#elif defined(__GNUC__) +# define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x))) +#else +# define BOOST_NO_ALIGNMENT +# define BOOST_ALIGNMENT(x) +#endif + +// Lack of non-public defaulted functions is implied by the lack of any defaulted functions +#if !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) && defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// Defaulted and deleted function declaration helpers +// These macros are intended to be inside a class definition. +// BOOST_DEFAULTED_FUNCTION accepts the function declaration and its +// body, which will be used if the compiler doesn't support defaulted functions. +// BOOST_DELETED_FUNCTION only accepts the function declaration. It +// will expand to a private function declaration, if the compiler doesn't support +// deleted functions. Because of this it is recommended to use BOOST_DELETED_FUNCTION +// in the end of the class definition. +// +// class my_class +// { +// public: +// // Default-constructible +// BOOST_DEFAULTED_FUNCTION(my_class(), {}) +// // Copying prohibited +// BOOST_DELETED_FUNCTION(my_class(my_class const&)) +// BOOST_DELETED_FUNCTION(my_class& operator= (my_class const&)) +// }; +// +#if !(defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)) +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun = default; +#else +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun body +#endif + +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +# define BOOST_DELETED_FUNCTION(fun) fun = delete; +#else +# define BOOST_DELETED_FUNCTION(fun) private: fun; +#endif + +// +// Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined +// +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +#define BOOST_NO_CXX11_DECLTYPE_N3276 BOOST_NO_CXX11_DECLTYPE +#endif + +// -------------------- Deprecated macros for 1.50 --------------------------- +// These will go away in a future release + +// Use BOOST_NO_CXX11_HDR_UNORDERED_SET or BOOST_NO_CXX11_HDR_UNORDERED_MAP +// instead of BOOST_NO_STD_UNORDERED +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) || defined (BOOST_NO_CXX11_HDR_UNORDERED_SET) +# ifndef BOOST_NO_CXX11_STD_UNORDERED +# define BOOST_NO_CXX11_STD_UNORDERED +# endif +#endif + +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST instead of BOOST_NO_INITIALIZER_LISTS +#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_INITIALIZER_LISTS) +# define BOOST_NO_INITIALIZER_LISTS +#endif + +// Use BOOST_NO_CXX11_HDR_ARRAY instead of BOOST_NO_0X_HDR_ARRAY +#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_NO_0X_HDR_ARRAY) +# define BOOST_NO_0X_HDR_ARRAY +#endif +// Use BOOST_NO_CXX11_HDR_CHRONO instead of BOOST_NO_0X_HDR_CHRONO +#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_NO_0X_HDR_CHRONO) +# define BOOST_NO_0X_HDR_CHRONO +#endif +// Use BOOST_NO_CXX11_HDR_CODECVT instead of BOOST_NO_0X_HDR_CODECVT +#if defined(BOOST_NO_CXX11_HDR_CODECVT) && !defined(BOOST_NO_0X_HDR_CODECVT) +# define BOOST_NO_0X_HDR_CODECVT +#endif +// Use BOOST_NO_CXX11_HDR_CONDITION_VARIABLE instead of BOOST_NO_0X_HDR_CONDITION_VARIABLE +#if defined(BOOST_NO_CXX11_HDR_CONDITION_VARIABLE) && !defined(BOOST_NO_0X_HDR_CONDITION_VARIABLE) +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +#endif +// Use BOOST_NO_CXX11_HDR_FORWARD_LIST instead of BOOST_NO_0X_HDR_FORWARD_LIST +#if defined(BOOST_NO_CXX11_HDR_FORWARD_LIST) && !defined(BOOST_NO_0X_HDR_FORWARD_LIST) +# define BOOST_NO_0X_HDR_FORWARD_LIST +#endif +// Use BOOST_NO_CXX11_HDR_FUTURE instead of BOOST_NO_0X_HDR_FUTURE +#if defined(BOOST_NO_CXX11_HDR_FUTURE) && !defined(BOOST_NO_0X_HDR_FUTURE) +# define BOOST_NO_0X_HDR_FUTURE +#endif + +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST +// instead of BOOST_NO_0X_HDR_INITIALIZER_LIST or BOOST_NO_INITIALIZER_LISTS +#ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# ifndef BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# endif +# ifndef BOOST_NO_INITIALIZER_LISTS +# define BOOST_NO_INITIALIZER_LISTS +# endif +#endif + +// Use BOOST_NO_CXX11_HDR_MUTEX instead of BOOST_NO_0X_HDR_MUTEX +#if defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX) +# define BOOST_NO_0X_HDR_MUTEX +#endif +// Use BOOST_NO_CXX11_HDR_RANDOM instead of BOOST_NO_0X_HDR_RANDOM +#if defined(BOOST_NO_CXX11_HDR_RANDOM) && !defined(BOOST_NO_0X_HDR_RANDOM) +# define BOOST_NO_0X_HDR_RANDOM +#endif +// Use BOOST_NO_CXX11_HDR_RATIO instead of BOOST_NO_0X_HDR_RATIO +#if defined(BOOST_NO_CXX11_HDR_RATIO) && !defined(BOOST_NO_0X_HDR_RATIO) +# define BOOST_NO_0X_HDR_RATIO +#endif +// Use BOOST_NO_CXX11_HDR_REGEX instead of BOOST_NO_0X_HDR_REGEX +#if defined(BOOST_NO_CXX11_HDR_REGEX) && !defined(BOOST_NO_0X_HDR_REGEX) +# define BOOST_NO_0X_HDR_REGEX +#endif +// Use BOOST_NO_CXX11_HDR_SYSTEM_ERROR instead of BOOST_NO_0X_HDR_SYSTEM_ERROR +#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_0X_HDR_SYSTEM_ERROR) +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +#endif +// Use BOOST_NO_CXX11_HDR_THREAD instead of BOOST_NO_0X_HDR_THREAD +#if defined(BOOST_NO_CXX11_HDR_THREAD) && !defined(BOOST_NO_0X_HDR_THREAD) +# define BOOST_NO_0X_HDR_THREAD +#endif +// Use BOOST_NO_CXX11_HDR_TUPLE instead of BOOST_NO_0X_HDR_TUPLE +#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_0X_HDR_TUPLE) +# define BOOST_NO_0X_HDR_TUPLE +#endif +// Use BOOST_NO_CXX11_HDR_TYPE_TRAITS instead of BOOST_NO_0X_HDR_TYPE_TRAITS +#if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_0X_HDR_TYPE_TRAITS) +# define BOOST_NO_0X_HDR_TYPE_TRAITS +#endif +// Use BOOST_NO_CXX11_HDR_TYPEINDEX instead of BOOST_NO_0X_HDR_TYPEINDEX +#if defined(BOOST_NO_CXX11_HDR_TYPEINDEX) && !defined(BOOST_NO_0X_HDR_TYPEINDEX) +# define BOOST_NO_0X_HDR_TYPEINDEX +#endif +// Use BOOST_NO_CXX11_HDR_UNORDERED_MAP instead of BOOST_NO_0X_HDR_UNORDERED_MAP +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) && !defined(BOOST_NO_0X_HDR_UNORDERED_MAP) +# define BOOST_NO_0X_HDR_UNORDERED_MAP +#endif +// Use BOOST_NO_CXX11_HDR_UNORDERED_SET instead of BOOST_NO_0X_HDR_UNORDERED_SET +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_NO_0X_HDR_UNORDERED_SET) +# define BOOST_NO_0X_HDR_UNORDERED_SET +#endif + +// ------------------ End of deprecated macros for 1.50 --------------------------- + +// -------------------- Deprecated macros for 1.51 --------------------------- +// These will go away in a future release + +// Use BOOST_NO_CXX11_AUTO_DECLARATIONS instead of BOOST_NO_AUTO_DECLARATIONS +#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_AUTO_DECLARATIONS) +# define BOOST_NO_AUTO_DECLARATIONS +#endif +// Use BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS instead of BOOST_NO_AUTO_MULTIDECLARATIONS +#if defined(BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS) && !defined(BOOST_NO_AUTO_MULTIDECLARATIONS) +# define BOOST_NO_AUTO_MULTIDECLARATIONS +#endif +// Use BOOST_NO_CXX11_CHAR16_T instead of BOOST_NO_CHAR16_T +#if defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CHAR16_T) +# define BOOST_NO_CHAR16_T +#endif +// Use BOOST_NO_CXX11_CHAR32_T instead of BOOST_NO_CHAR32_T +#if defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CHAR32_T) +# define BOOST_NO_CHAR32_T +#endif +// Use BOOST_NO_CXX11_TEMPLATE_ALIASES instead of BOOST_NO_TEMPLATE_ALIASES +#if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_TEMPLATE_ALIASES) +# define BOOST_NO_TEMPLATE_ALIASES +#endif +// Use BOOST_NO_CXX11_CONSTEXPR instead of BOOST_NO_CONSTEXPR +#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CONSTEXPR) +# define BOOST_NO_CONSTEXPR +#endif +// Use BOOST_NO_CXX11_DECLTYPE_N3276 instead of BOOST_NO_DECLTYPE_N3276 +#if defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_DECLTYPE_N3276) +# define BOOST_NO_DECLTYPE_N3276 +#endif +// Use BOOST_NO_CXX11_DECLTYPE instead of BOOST_NO_DECLTYPE +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE) +# define BOOST_NO_DECLTYPE +#endif +// Use BOOST_NO_CXX11_DEFAULTED_FUNCTIONS instead of BOOST_NO_DEFAULTED_FUNCTIONS +#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_DEFAULTED_FUNCTIONS) +# define BOOST_NO_DEFAULTED_FUNCTIONS +#endif +// Use BOOST_NO_CXX11_DELETED_FUNCTIONS instead of BOOST_NO_DELETED_FUNCTIONS +#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_DELETED_FUNCTIONS) +# define BOOST_NO_DELETED_FUNCTIONS +#endif +// Use BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS instead of BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS) +# define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#endif +// Use BOOST_NO_CXX11_EXTERN_TEMPLATE instead of BOOST_NO_EXTERN_TEMPLATE +#if defined(BOOST_NO_CXX11_EXTERN_TEMPLATE) && !defined(BOOST_NO_EXTERN_TEMPLATE) +# define BOOST_NO_EXTERN_TEMPLATE +#endif +// Use BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS instead of BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !defined(BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) +# define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif +// Use BOOST_NO_CXX11_LAMBDAS instead of BOOST_NO_LAMBDAS +#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS) +# define BOOST_NO_LAMBDAS +#endif +// Use BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS instead of BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +#if defined(BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS) && !defined(BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) +# define BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif +// Use BOOST_NO_CXX11_NOEXCEPT instead of BOOST_NO_NOEXCEPT +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_NOEXCEPT) +# define BOOST_NO_NOEXCEPT +#endif +// Use BOOST_NO_CXX11_NULLPTR instead of BOOST_NO_NULLPTR +#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR) +# define BOOST_NO_NULLPTR +#endif +// Use BOOST_NO_CXX11_RAW_LITERALS instead of BOOST_NO_RAW_LITERALS +#if defined(BOOST_NO_CXX11_RAW_LITERALS) && !defined(BOOST_NO_RAW_LITERALS) +# define BOOST_NO_RAW_LITERALS +#endif +// Use BOOST_NO_CXX11_RVALUE_REFERENCES instead of BOOST_NO_RVALUE_REFERENCES +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_RVALUE_REFERENCES) +# define BOOST_NO_RVALUE_REFERENCES +#endif +// Use BOOST_NO_CXX11_SCOPED_ENUMS instead of BOOST_NO_SCOPED_ENUMS +#if defined(BOOST_NO_CXX11_SCOPED_ENUMS) && !defined(BOOST_NO_SCOPED_ENUMS) +# define BOOST_NO_SCOPED_ENUMS +#endif +// Use BOOST_NO_CXX11_STATIC_ASSERT instead of BOOST_NO_STATIC_ASSERT +#if defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_NO_STATIC_ASSERT) +# define BOOST_NO_STATIC_ASSERT +#endif +// Use BOOST_NO_CXX11_STD_UNORDERED instead of BOOST_NO_STD_UNORDERED +#if defined(BOOST_NO_CXX11_STD_UNORDERED) && !defined(BOOST_NO_STD_UNORDERED) +# define BOOST_NO_STD_UNORDERED +#endif +// Use BOOST_NO_CXX11_UNICODE_LITERALS instead of BOOST_NO_UNICODE_LITERALS +#if defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(BOOST_NO_UNICODE_LITERALS) +# define BOOST_NO_UNICODE_LITERALS +#endif +// Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead of BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX +#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX) +# define BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX +#endif +// Use BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of BOOST_NO_VARIADIC_TEMPLATES +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_VARIADIC_TEMPLATES) +# define BOOST_NO_VARIADIC_TEMPLATES +#endif +// Use BOOST_NO_CXX11_VARIADIC_MACROS instead of BOOST_NO_VARIADIC_MACROS +#if defined(BOOST_NO_CXX11_VARIADIC_MACROS) && !defined(BOOST_NO_VARIADIC_MACROS) +# define BOOST_NO_VARIADIC_MACROS +#endif +// Use BOOST_NO_CXX11_NUMERIC_LIMITS instead of BOOST_NO_NUMERIC_LIMITS_LOWEST +#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_NO_NUMERIC_LIMITS_LOWEST) +# define BOOST_NO_NUMERIC_LIMITS_LOWEST +#endif +// ------------------ End of deprecated macros for 1.51 --------------------------- + + + +// +// Helper macros BOOST_NOEXCEPT, BOOST_NOEXCEPT_IF, BOOST_NOEXCEPT_EXPR +// These aid the transition to C++11 while still supporting C++03 compilers +// +#ifdef BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NOEXCEPT +# define BOOST_NOEXCEPT_OR_NOTHROW throw() +# define BOOST_NOEXCEPT_IF(Predicate) +# define BOOST_NOEXCEPT_EXPR(Expression) false +#else +# define BOOST_NOEXCEPT noexcept +# define BOOST_NOEXCEPT_OR_NOTHROW noexcept +# define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate)) +# define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression)) +#endif +// +// Helper macro BOOST_FALLTHROUGH +// Fallback definition of BOOST_FALLTHROUGH macro used to mark intended +// fall-through between case labels in a switch statement. We use a definition +// that requires a semicolon after it to avoid at least one type of misuse even +// on unsupported compilers. +// +#ifndef BOOST_FALLTHROUGH +# define BOOST_FALLTHROUGH ((void)0) +#endif + +// +// constexpr workarounds +// +#if defined(BOOST_NO_CXX11_CONSTEXPR) +#define BOOST_CONSTEXPR +#define BOOST_CONSTEXPR_OR_CONST const +#else +#define BOOST_CONSTEXPR constexpr +#define BOOST_CONSTEXPR_OR_CONST constexpr +#endif +#if defined(BOOST_NO_CXX14_CONSTEXPR) +#define BOOST_CXX14_CONSTEXPR +#else +#define BOOST_CXX14_CONSTEXPR constexpr +#endif + +// +// Unused variable/typedef workarounds: +// +#ifndef BOOST_ATTRIBUTE_UNUSED +# define BOOST_ATTRIBUTE_UNUSED +#endif + +#define BOOST_STATIC_CONSTEXPR static BOOST_CONSTEXPR_OR_CONST + +// +// Set BOOST_HAS_STATIC_ASSERT when BOOST_NO_CXX11_STATIC_ASSERT is not defined +// +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_HAS_STATIC_ASSERT) +# define BOOST_HAS_STATIC_ASSERT +#endif + +// +// Set BOOST_HAS_RVALUE_REFS when BOOST_NO_CXX11_RVALUE_REFERENCES is not defined +// +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_HAS_RVALUE_REFS) +#define BOOST_HAS_RVALUE_REFS +#endif + +// +// Set BOOST_HAS_VARIADIC_TMPL when BOOST_NO_CXX11_VARIADIC_TEMPLATES is not defined +// +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_HAS_VARIADIC_TMPL) +#define BOOST_HAS_VARIADIC_TMPL +#endif +// +// Set BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS when +// BOOST_NO_CXX11_VARIADIC_TEMPLATES is set: +// +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS) +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#endif + +// +// Finish off with checks for macros that are depricated / no longer supported, +// if any of these are set then it's very likely that much of Boost will no +// longer work. So stop with a #error for now, but give the user a chance +// to continue at their own risk if they really want to: +// +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_CONFIG_ALLOW_DEPRECATED) +# error "You are using a compiler which lacks features which are now a minimum requirement in order to use Boost, define BOOST_CONFIG_ALLOW_DEPRECATED if you want to continue at your own risk!!!" +#endif + +#endif diff --git a/thirdparty/linux/include/boost/config/user.hpp b/thirdparty/linux/include/boost/config/user.hpp new file mode 100644 index 0000000..28e7476 --- /dev/null +++ b/thirdparty/linux/include/boost/config/user.hpp @@ -0,0 +1,133 @@ +// boost/config/user.hpp ---------------------------------------------------// + +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Do not check in modified versions of this file, +// This file may be customized by the end user, but not by boost. + +// +// Use this file to define a site and compiler specific +// configuration policy: +// + +// define this to locate a compiler config file: +// #define BOOST_COMPILER_CONFIG + +// define this to locate a stdlib config file: +// #define BOOST_STDLIB_CONFIG + +// define this to locate a platform config file: +// #define BOOST_PLATFORM_CONFIG + +// define this to disable compiler config, +// use if your compiler config has nothing to set: +// #define BOOST_NO_COMPILER_CONFIG + +// define this to disable stdlib config, +// use if your stdlib config has nothing to set: +// #define BOOST_NO_STDLIB_CONFIG + +// define this to disable platform config, +// use if your platform config has nothing to set: +// #define BOOST_NO_PLATFORM_CONFIG + +// define this to disable all config options, +// excluding the user config. Use if your +// setup is fully ISO compliant, and has no +// useful extensions, or for autoconf generated +// setups: +// #define BOOST_NO_CONFIG + +// define this to make the config "optimistic" +// about unknown compiler versions. Normally +// unknown compiler versions are assumed to have +// all the defects of the last known version, however +// setting this flag, causes the config to assume +// that unknown compiler versions are fully conformant +// with the standard: +// #define BOOST_STRICT_CONFIG + +// define this to cause the config to halt compilation +// with an #error if it encounters anything unknown -- +// either an unknown compiler version or an unknown +// compiler/platform/library: +// #define BOOST_ASSERT_CONFIG + + +// define if you want to disable threading support, even +// when available: +// #define BOOST_DISABLE_THREADS + +// define when you want to disable Win32 specific features +// even when available: +// #define BOOST_DISABLE_WIN32 + +// BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any +// prefix/suffix headers that normally control things like struct +// packing and alignment. +// #define BOOST_DISABLE_ABI_HEADERS + +// BOOST_ABI_PREFIX: A prefix header to include in place of whatever +// boost.config would normally select, any replacement should set up +// struct packing and alignment options as required. +// #define BOOST_ABI_PREFIX my-header-name + +// BOOST_ABI_SUFFIX: A suffix header to include in place of whatever +// boost.config would normally select, any replacement should undo +// the effects of the prefix header. +// #define BOOST_ABI_SUFFIX my-header-name + +// BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, +// to be linked as dll's rather than static libraries on Microsoft Windows +// (this macro is used to turn on __declspec(dllimport) modifiers, so that +// the compiler knows which symbols to look for in a dll rather than in a +// static library). Note that there may be some libraries that can only +// be linked in one way (statically or dynamically), in these cases this +// macro has no effect. +// #define BOOST_ALL_DYN_LINK + +// BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll +// rather than a static library on Microsoft Windows: replace the WHATEVER +// part of the macro name with the name of the library that you want to +// dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or +// BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport) +// modifiers, so that the compiler knows which symbols to look for in a dll +// rather than in a static library). +// Note that there may be some libraries that can only +// be linked in one way (statically or dynamically), +// in these cases this macro is unsupported. +// #define BOOST_WHATEVER_DYN_LINK + +// BOOST_ALL_NO_LIB: Tells the config system not to automatically select +// which libraries to link against. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, +// simply by the act of including one of that library's headers. +// This macro turns that feature off. +// #define BOOST_ALL_NO_LIB + +// BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically +// select which library to link against for library "whatever", +// replace WHATEVER in the macro name with the name of the library; +// for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, simply +// by the act of including one of that library's headers. This macro turns +// that feature off. +// #define BOOST_WHATEVER_NO_LIB + +// BOOST_LIB_BUILDID: Set to the same value as the value passed to Boost.Build's +// --buildid command line option. For example if you built using: +// +// bjam address-model=64 --buildid=amd64 +// +// then compile your code with: +// +// -DBOOST_LIB_BUILDID = amd64 +// +// to ensure the correct libraries are selected at link time. +// #define BOOST_LIB_BUILDID amd64 + diff --git a/thirdparty/linux/include/boost/config/warning_disable.hpp b/thirdparty/linux/include/boost/config/warning_disable.hpp new file mode 100644 index 0000000..fea8e82 --- /dev/null +++ b/thirdparty/linux/include/boost/config/warning_disable.hpp @@ -0,0 +1,47 @@ +// Copyright John Maddock 2008 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// This file exists to turn off some overly-pedantic warning emitted +// by certain compilers. You should include this header only in: +// +// * A test case, before any other headers, or, +// * A library source file before any other headers. +// +// IT SHOULD NOT BE INCLUDED BY ANY BOOST HEADER. +// +// YOU SHOULD NOT INCLUDE IT IF YOU CAN REASONABLY FIX THE WARNING. +// +// The only warnings disabled here are those that are: +// +// * Quite unreasonably pedantic. +// * Generally only emitted by a single compiler. +// * Can't easily be fixed: for example if the vendors own std lib +// code emits these warnings! +// +// Note that THIS HEADER MUST NOT INCLUDE ANY OTHER HEADERS: +// not even std library ones! Doing so may turn the warning +// off too late to be of any use. For example the VC++ C4996 +// warning can be emitted from if that header is included +// before or by this one :-( +// + +#ifndef BOOST_CONFIG_WARNING_DISABLE_HPP +#define BOOST_CONFIG_WARNING_DISABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + // Error 'function': was declared deprecated + // http://msdn2.microsoft.com/en-us/library/ttcz0bys(VS.80).aspx + // This error is emitted when you use some perfectly conforming + // std lib functions in a perfectly correct way, and also by + // some of Microsoft's own std lib code ! +# pragma warning(disable:4996) +#endif +#if defined(__INTEL_COMPILER) || defined(__ICL) + // As above: gives warning when a "deprecated" + // std library function is encountered. +# pragma warning(disable:1786) +#endif + +#endif // BOOST_CONFIG_WARNING_DISABLE_HPP diff --git a/thirdparty/linux/include/boost/core/addressof.hpp b/thirdparty/linux/include/boost/core/addressof.hpp new file mode 100644 index 0000000..889b582 --- /dev/null +++ b/thirdparty/linux/include/boost/core/addressof.hpp @@ -0,0 +1,162 @@ +// Copyright (C) 2002 Brad King (brad.king@kitware.com) +// Douglas Gregor (gregod@cs.rpi.edu) +// +// Copyright (C) 2002, 2008, 2013 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#ifndef BOOST_CORE_ADDRESSOF_HPP +#define BOOST_CORE_ADDRESSOF_HPP + +# include +# include +# include + +namespace boost +{ + +namespace detail +{ + +template struct addr_impl_ref +{ + T & v_; + + BOOST_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {} + BOOST_FORCEINLINE operator T& () const { return v_; } + +private: + addr_impl_ref & operator=(const addr_impl_ref &); +}; + +template struct addressof_impl +{ + static BOOST_FORCEINLINE T * f( T & v, long ) + { + return reinterpret_cast( + &const_cast(reinterpret_cast(v))); + } + + static BOOST_FORCEINLINE T * f( T * v, int ) + { + return v; + } +}; + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) ) + + typedef decltype(nullptr) addr_nullptr_t; + +#else + + typedef std::nullptr_t addr_nullptr_t; + +#endif + +template<> struct addressof_impl< addr_nullptr_t > +{ + typedef addr_nullptr_t T; + + static BOOST_FORCEINLINE T * f( T & v, int ) + { + return &v; + } +}; + +template<> struct addressof_impl< addr_nullptr_t const > +{ + typedef addr_nullptr_t const T; + + static BOOST_FORCEINLINE T * f( T & v, int ) + { + return &v; + } +}; + +template<> struct addressof_impl< addr_nullptr_t volatile > +{ + typedef addr_nullptr_t volatile T; + + static BOOST_FORCEINLINE T * f( T & v, int ) + { + return &v; + } +}; + +template<> struct addressof_impl< addr_nullptr_t const volatile > +{ + typedef addr_nullptr_t const volatile T; + + static BOOST_FORCEINLINE T * f( T & v, int ) + { + return &v; + } +}; + +#endif + +} // namespace detail + +template +BOOST_FORCEINLINE +T * addressof( T & v ) +{ +#if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)) + + return boost::detail::addressof_impl::f( v, 0 ); + +#else + + return boost::detail::addressof_impl::f( boost::detail::addr_impl_ref( v ), 0 ); + +#endif +} + +#if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) ) + +namespace detail +{ + +template struct addressof_addp +{ + typedef T * type; +}; + +} // namespace detail + +template< class T, std::size_t N > +BOOST_FORCEINLINE +typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] ) +{ + return &t; +} + +#endif + +// Borland doesn't like casting an array reference to a char reference +// but these overloads work around the problem. +#if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template +BOOST_FORCEINLINE +T (*addressof(T (&t)[N]))[N] +{ + return reinterpret_cast(&t); +} + +template +BOOST_FORCEINLINE +const T (*addressof(const T (&t)[N]))[N] +{ + return reinterpret_cast(&t); +} +#endif + +} // namespace boost + +#endif // BOOST_CORE_ADDRESSOF_HPP diff --git a/thirdparty/linux/include/boost/core/checked_delete.hpp b/thirdparty/linux/include/boost/core/checked_delete.hpp new file mode 100644 index 0000000..b086e03 --- /dev/null +++ b/thirdparty/linux/include/boost/core/checked_delete.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_CORE_CHECKED_DELETE_HPP +#define BOOST_CORE_CHECKED_DELETE_HPP + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/checked_delete.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov +// Copyright (c) 2003 Daniel Frey +// Copyright (c) 2003 Howard Hinnant +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/core/doc/html/core/checked_delete.html for documentation. +// + +namespace boost +{ + +// verify that types are complete for increased safety + +template inline void checked_delete(T * x) +{ + // intentionally complex - simplification causes regressions + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete x; +} + +template inline void checked_array_delete(T * x) +{ + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete [] x; +} + +template struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + // boost:: disables ADL + boost::checked_delete(x); + } +}; + +template struct checked_array_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + boost::checked_array_delete(x); + } +}; + +} // namespace boost + +#endif // #ifndef BOOST_CORE_CHECKED_DELETE_HPP diff --git a/thirdparty/linux/include/boost/core/demangle.hpp b/thirdparty/linux/include/boost/core/demangle.hpp new file mode 100644 index 0000000..f13c26a --- /dev/null +++ b/thirdparty/linux/include/boost/core/demangle.hpp @@ -0,0 +1,131 @@ +#ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED +#define BOOST_CORE_DEMANGLE_HPP_INCLUDED + +// core::demangle +// +// Copyright 2014 Peter Dimov +// Copyright 2014 Andrey Semashev +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +// __has_include is currently supported by GCC and Clang. However GCC 4.9 may have issues and +// returns 1 for 'defined( __has_include )', while '__has_include' is actually not supported: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63662 +#if defined( __has_include ) && (!defined( BOOST_GCC ) || (__GNUC__ + 0) >= 5) +# if __has_include() +# define BOOST_CORE_HAS_CXXABI_H +# endif +#elif defined( __GLIBCXX__ ) || defined( __GLIBCPP__ ) +# define BOOST_CORE_HAS_CXXABI_H +#endif + +#if defined( BOOST_CORE_HAS_CXXABI_H ) +# include +// For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library +// (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement +// abi::__cxa_demangle(). We detect this implementation by checking the include guard here. +# if defined( __GABIXX_CXXABI_H__ ) +# undef BOOST_CORE_HAS_CXXABI_H +# else +# include +# include +# endif +#endif + +namespace boost +{ + +namespace core +{ + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT; +inline void demangle_free( char const * name ) BOOST_NOEXCEPT; + +class scoped_demangled_name +{ +private: + char const * m_p; + +public: + explicit scoped_demangled_name( char const * name ) BOOST_NOEXCEPT : + m_p( demangle_alloc( name ) ) + { + } + + ~scoped_demangled_name() BOOST_NOEXCEPT + { + demangle_free( m_p ); + } + + char const * get() const BOOST_NOEXCEPT + { + return m_p; + } + + BOOST_DELETED_FUNCTION(scoped_demangled_name( scoped_demangled_name const& )) + BOOST_DELETED_FUNCTION(scoped_demangled_name& operator= ( scoped_demangled_name const& )) +}; + + +#if defined( BOOST_CORE_HAS_CXXABI_H ) + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT +{ + int status = 0; + std::size_t size = 0; + return abi::__cxa_demangle( name, NULL, &size, &status ); +} + +inline void demangle_free( char const * name ) BOOST_NOEXCEPT +{ + std::free( const_cast< char* >( name ) ); +} + +inline std::string demangle( char const * name ) +{ + scoped_demangled_name demangled_name( name ); + char const * const p = demangled_name.get(); + if( p ) + { + return p; + } + else + { + return name; + } +} + +#else + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT +{ + return name; +} + +inline void demangle_free( char const * ) BOOST_NOEXCEPT +{ +} + +inline std::string demangle( char const * name ) +{ + return name; +} + +#endif + +} // namespace core + +} // namespace boost + +#undef BOOST_CORE_HAS_CXXABI_H + +#endif // #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/core/typeinfo.hpp b/thirdparty/linux/include/boost/core/typeinfo.hpp new file mode 100644 index 0000000..e67b4a3 --- /dev/null +++ b/thirdparty/linux/include/boost/core/typeinfo.hpp @@ -0,0 +1,151 @@ +#ifndef BOOST_CORE_TYPEINFO_HPP_INCLUDED +#define BOOST_CORE_TYPEINFO_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// core::typeinfo, BOOST_CORE_TYPEID +// +// Copyright 2007, 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if defined( BOOST_NO_TYPEID ) + +#include +#include + +namespace boost +{ + +namespace core +{ + +class typeinfo +{ +private: + + typeinfo( typeinfo const& ); + typeinfo& operator=( typeinfo const& ); + + char const * name_; + +public: + + explicit typeinfo( char const * name ): name_( name ) + { + } + + bool operator==( typeinfo const& rhs ) const + { + return this == &rhs; + } + + bool operator!=( typeinfo const& rhs ) const + { + return this != &rhs; + } + + bool before( typeinfo const& rhs ) const + { + return std::less< typeinfo const* >()( this, &rhs ); + } + + char const* name() const + { + return name_; + } +}; + +inline char const * demangled_name( core::typeinfo const & ti ) +{ + return ti.name(); +} + +} // namespace core + +namespace detail +{ + +template struct core_typeid_ +{ + static boost::core::typeinfo ti_; + + static char const * name() + { + return BOOST_CURRENT_FUNCTION; + } +}; + +#if defined(__SUNPRO_CC) +// see #4199, the Sun Studio compiler gets confused about static initialization +// constructor arguments. But an assignment works just fine. +template boost::core::typeinfo core_typeid_< T >::ti_ = core_typeid_< T >::name(); +#else +template boost::core::typeinfo core_typeid_< T >::ti_(core_typeid_< T >::name()); +#endif + +template struct core_typeid_< T & >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T const >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T volatile >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T const volatile >: core_typeid_< T > +{ +}; + +} // namespace detail + +} // namespace boost + +#define BOOST_CORE_TYPEID(T) (boost::detail::core_typeid_::ti_) + +#else + +#include +#include + +namespace boost +{ + +namespace core +{ + +#if defined( BOOST_NO_STD_TYPEINFO ) + +typedef ::type_info typeinfo; + +#else + +typedef std::type_info typeinfo; + +#endif + +inline std::string demangled_name( core::typeinfo const & ti ) +{ + return core::demangle( ti.name() ); +} + +} // namespace core + +} // namespace boost + +#define BOOST_CORE_TYPEID(T) typeid(T) + +#endif + +#endif // #ifndef BOOST_CORE_TYPEINFO_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/cstdint.hpp b/thirdparty/linux/include/boost/cstdint.hpp new file mode 100644 index 0000000..bf7097e --- /dev/null +++ b/thirdparty/linux/include/boost/cstdint.hpp @@ -0,0 +1,546 @@ +// boost cstdint.hpp header file ------------------------------------------// + +// (C) Copyright Beman Dawes 1999. +// (C) Copyright Jens Mauer 2001 +// (C) Copyright John Maddock 2001 +// Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/integer for documentation. + +// Revision History +// 31 Oct 01 use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.) +// 16 Apr 01 check LONGLONG_MAX when looking for "long long" (Jens Maurer) +// 23 Jan 01 prefer "long" over "int" for int32_t and intmax_t (Jens Maurer) +// 12 Nov 00 Merged (Jens Maurer) +// 23 Sep 00 Added INTXX_C macro support (John Maddock). +// 22 Sep 00 Better 64-bit support (John Maddock) +// 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost +// 8 Aug 99 Initial version (Beman Dawes) + + +#ifndef BOOST_CSTDINT_HPP +#define BOOST_CSTDINT_HPP + +// +// Since we always define the INT#_C macros as per C++0x, +// define __STDC_CONSTANT_MACROS so that does the right +// thing if possible, and so that the user knows that the macros +// are actually defined as per C99. +// +#ifndef __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS +#endif + +#include + +// +// Note that GLIBC is a bit inconsistent about whether int64_t is defined or not +// depending upon what headers happen to have been included first... +// so we disable use of stdint.h when GLIBC does not define __GLIBC_HAVE_LONG_LONG. +// See https://svn.boost.org/trac/boost/ticket/3548 and http://sources.redhat.com/bugzilla/show_bug.cgi?id=10990 +// +#if defined(BOOST_HAS_STDINT_H) \ + && (!defined(__GLIBC__) \ + || defined(__GLIBC_HAVE_LONG_LONG) \ + || (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 17))))) + +// The following #include is an implementation artifact; not part of interface. +# ifdef __hpux +// HP-UX has a vaguely nice in a non-standard location +# include +# ifdef __STDC_32_MODE__ + // this is triggered with GCC, because it defines __cplusplus < 199707L +# define BOOST_NO_INT64_T +# endif +# elif defined(__FreeBSD__) || defined(__IBMCPP__) || defined(_AIX) +# include +# else +# include + +// There is a bug in Cygwin two _C macros +# if defined(__STDC_CONSTANT_MACROS) && defined(__CYGWIN__) +# undef INTMAX_C +# undef UINTMAX_C +# define INTMAX_C(c) c##LL +# define UINTMAX_C(c) c##ULL +# endif + +# endif + +#if defined(__QNX__) && defined(__EXT_QNX) + +// QNX (Dinkumware stdlib) defines these as non-standard names. +// Reflect to the standard names. + +typedef ::intleast8_t int_least8_t; +typedef ::intfast8_t int_fast8_t; +typedef ::uintleast8_t uint_least8_t; +typedef ::uintfast8_t uint_fast8_t; + +typedef ::intleast16_t int_least16_t; +typedef ::intfast16_t int_fast16_t; +typedef ::uintleast16_t uint_least16_t; +typedef ::uintfast16_t uint_fast16_t; + +typedef ::intleast32_t int_least32_t; +typedef ::intfast32_t int_fast32_t; +typedef ::uintleast32_t uint_least32_t; +typedef ::uintfast32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + +typedef ::intleast64_t int_least64_t; +typedef ::intfast64_t int_fast64_t; +typedef ::uintleast64_t uint_least64_t; +typedef ::uintfast64_t uint_fast64_t; + +# endif + +#endif + +namespace boost +{ + + using ::int8_t; + using ::int_least8_t; + using ::int_fast8_t; + using ::uint8_t; + using ::uint_least8_t; + using ::uint_fast8_t; + + using ::int16_t; + using ::int_least16_t; + using ::int_fast16_t; + using ::uint16_t; + using ::uint_least16_t; + using ::uint_fast16_t; + + using ::int32_t; + using ::int_least32_t; + using ::int_fast32_t; + using ::uint32_t; + using ::uint_least32_t; + using ::uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + using ::int_least64_t; + using ::int_fast64_t; + using ::uint64_t; + using ::uint_least64_t; + using ::uint_fast64_t; + +# endif + + using ::intmax_t; + using ::uintmax_t; + +} // namespace boost + +#elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) || defined(__VMS) || defined(__SOLARIS9__) || defined(__NetBSD__) +// FreeBSD and Tru64 have an that contains much of what we need. +# include + +namespace boost { + + using ::int8_t; + typedef int8_t int_least8_t; + typedef int8_t int_fast8_t; + using ::uint8_t; + typedef uint8_t uint_least8_t; + typedef uint8_t uint_fast8_t; + + using ::int16_t; + typedef int16_t int_least16_t; + typedef int16_t int_fast16_t; + using ::uint16_t; + typedef uint16_t uint_least16_t; + typedef uint16_t uint_fast16_t; + + using ::int32_t; + typedef int32_t int_least32_t; + typedef int32_t int_fast32_t; + using ::uint32_t; + typedef uint32_t uint_least32_t; + typedef uint32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + typedef int64_t int_least64_t; + typedef int64_t int_fast64_t; + using ::uint64_t; + typedef uint64_t uint_least64_t; + typedef uint64_t uint_fast64_t; + + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; + +# else + + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; + +# endif + +} // namespace boost + +#else // BOOST_HAS_STDINT_H + +# include // implementation artifact; not part of interface +# include // needed for limits macros + + +namespace boost +{ + +// These are fairly safe guesses for some 16-bit, and most 32-bit and 64-bit +// platforms. For other systems, they will have to be hand tailored. +// +// Because the fast types are assumed to be the same as the undecorated types, +// it may be possible to hand tailor a more efficient implementation. Such +// an optimization may be illusionary; on the Intel x86-family 386 on, for +// example, byte arithmetic and load/stores are as fast as "int" sized ones. + +// 8-bit types ------------------------------------------------------------// + +# if UCHAR_MAX == 0xff + typedef signed char int8_t; + typedef signed char int_least8_t; + typedef signed char int_fast8_t; + typedef unsigned char uint8_t; + typedef unsigned char uint_least8_t; + typedef unsigned char uint_fast8_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 16-bit types -----------------------------------------------------------// + +# if USHRT_MAX == 0xffff +# if defined(__crayx1) + // The Cray X1 has a 16-bit short, however it is not recommend + // for use in performance critical code. + typedef short int16_t; + typedef short int_least16_t; + typedef int int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned int uint_fast16_t; +# else + typedef short int16_t; + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# endif +# elif (USHRT_MAX == 0xffffffff) && defined(__MTA__) + // On MTA / XMT short is 32 bits unless the -short16 compiler flag is specified + // MTA / XMT does support the following non-standard integer types + typedef __short16 int16_t; + typedef __short16 int_least16_t; + typedef __short16 int_fast16_t; + typedef unsigned __short16 uint16_t; + typedef unsigned __short16 uint_least16_t; + typedef unsigned __short16 uint_fast16_t; +# elif (USHRT_MAX == 0xffffffff) && defined(CRAY) + // no 16-bit types on Cray: + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 32-bit types -----------------------------------------------------------// + +# if UINT_MAX == 0xffffffff + typedef int int32_t; + typedef int int_least32_t; + typedef int int_fast32_t; + typedef unsigned int uint32_t; + typedef unsigned int uint_least32_t; + typedef unsigned int uint_fast32_t; +# elif (USHRT_MAX == 0xffffffff) + typedef short int32_t; + typedef short int_least32_t; + typedef short int_fast32_t; + typedef unsigned short uint32_t; + typedef unsigned short uint_least32_t; + typedef unsigned short uint_fast32_t; +# elif ULONG_MAX == 0xffffffff + typedef long int32_t; + typedef long int_least32_t; + typedef long int_fast32_t; + typedef unsigned long uint32_t; + typedef unsigned long uint_least32_t; + typedef unsigned long uint_fast32_t; +# elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__) + // Integers are 64 bits on the MTA / XMT + typedef __int32 int32_t; + typedef __int32 int_least32_t; + typedef __int32 int_fast32_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int32 uint_fast32_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// + +# if defined(BOOST_HAS_LONG_LONG) && \ + !defined(BOOST_MSVC) && !defined(__BORLANDC__) && \ + (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) + // 2**64 - 1 +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + + typedef ::boost::long_long_type intmax_t; + typedef ::boost::ulong_long_type uintmax_t; + typedef ::boost::long_long_type int64_t; + typedef ::boost::long_long_type int_least64_t; + typedef ::boost::long_long_type int_fast64_t; + typedef ::boost::ulong_long_type uint64_t; + typedef ::boost::ulong_long_type uint_least64_t; + typedef ::boost::ulong_long_type uint_fast64_t; + +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615 // 2**64 - 1 + typedef long intmax_t; + typedef unsigned long uintmax_t; + typedef long int64_t; + typedef long int_least64_t; + typedef long int_fast64_t; + typedef unsigned long uint64_t; + typedef unsigned long uint_least64_t; + typedef unsigned long uint_fast64_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(__GNUC__) && defined(BOOST_HAS_LONG_LONG) + __extension__ typedef long long intmax_t; + __extension__ typedef unsigned long long uintmax_t; + __extension__ typedef long long int64_t; + __extension__ typedef long long int_least64_t; + __extension__ typedef long long int_fast64_t; + __extension__ typedef unsigned long long uint64_t; + __extension__ typedef unsigned long long uint_least64_t; + __extension__ typedef unsigned long long uint_fast64_t; +# elif defined(BOOST_HAS_MS_INT64) + // + // we have Borland/Intel/Microsoft __int64: + // + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; + typedef __int64 int64_t; + typedef __int64 int_least64_t; + typedef __int64 int_fast64_t; + typedef unsigned __int64 uint64_t; + typedef unsigned __int64 uint_least64_t; + typedef unsigned __int64 uint_fast64_t; +# else // assume no 64-bit integers +# define BOOST_NO_INT64_T + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# endif + +} // namespace boost + + +#endif // BOOST_HAS_STDINT_H + +// intptr_t/uintptr_t are defined separately because they are optional and not universally available +#if defined(BOOST_WINDOWS) && !defined(_WIN32_WCE) && !defined(BOOST_HAS_STDINT_H) +// Older MSVC don't have stdint.h and have intptr_t/uintptr_t defined in stddef.h +#include +#endif + +// PGI seems to not support intptr_t/uintptr_t properly. BOOST_HAS_STDINT_H is not defined for this compiler by Boost.Config. +#if !defined(__PGIC__) + +#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \ + || (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \ + || defined(__CYGWIN__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ + || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(sun) + +namespace boost { + using ::intptr_t; + using ::uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +// Clang pretends to be GCC, so it'll match this condition +#elif defined(__GNUC__) && defined(__INTPTR_TYPE__) && defined(__UINTPTR_TYPE__) + +namespace boost { + typedef __INTPTR_TYPE__ intptr_t; + typedef __UINTPTR_TYPE__ uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +#endif + +#endif // !defined(__PGIC__) + +#endif // BOOST_CSTDINT_HPP + + +/**************************************************** + +Macro definition section: + +Added 23rd September 2000 (John Maddock). +Modified 11th September 2001 to be excluded when +BOOST_HAS_STDINT_H is defined (John Maddock). +Modified 11th Dec 2009 to always define the +INT#_C macros if they're not already defined (John Maddock). + +******************************************************/ + +#if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && \ + (!defined(INT8_C) || !defined(INT16_C) || !defined(INT32_C) || !defined(INT64_C)) +// +// For the following code we get several warnings along the lines of: +// +// boost/cstdint.hpp:428:35: error: use of C99 long long integer constant +// +// So we declare this a system header to suppress these warnings. +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +#include +# define BOOST__STDC_CONSTANT_MACROS_DEFINED +# if defined(BOOST_HAS_MS_INT64) +// +// Borland/Intel/Microsoft compilers have width specific suffixes: +// +#ifndef INT8_C +# define INT8_C(value) value##i8 +#endif +#ifndef INT16_C +# define INT16_C(value) value##i16 +#endif +#ifndef INT32_C +# define INT32_C(value) value##i32 +#endif +#ifndef INT64_C +# define INT64_C(value) value##i64 +#endif +# ifdef __BORLANDC__ + // Borland bug: appending ui8 makes the type a signed char +# define UINT8_C(value) static_cast(value##u) +# else +# define UINT8_C(value) value##ui8 +# endif +#ifndef UINT16_C +# define UINT16_C(value) value##ui16 +#endif +#ifndef UINT32_C +# define UINT32_C(value) value##ui32 +#endif +#ifndef UINT64_C +# define UINT64_C(value) value##ui64 +#endif +#ifndef INTMAX_C +# define INTMAX_C(value) value##i64 +# define UINTMAX_C(value) value##ui64 +#endif + +# else +// do it the old fashioned way: + +// 8-bit types ------------------------------------------------------------// + +# if (UCHAR_MAX == 0xff) && !defined(INT8_C) +# define INT8_C(value) static_cast(value) +# define UINT8_C(value) static_cast(value##u) +# endif + +// 16-bit types -----------------------------------------------------------// + +# if (USHRT_MAX == 0xffff) && !defined(INT16_C) +# define INT16_C(value) static_cast(value) +# define UINT16_C(value) static_cast(value##u) +# endif + +// 32-bit types -----------------------------------------------------------// +#ifndef INT32_C +# if (UINT_MAX == 0xffffffff) +# define INT32_C(value) value +# define UINT32_C(value) value##u +# elif ULONG_MAX == 0xffffffff +# define INT32_C(value) value##L +# define UINT32_C(value) value##uL +# endif +#endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// +#ifndef INT64_C +# if defined(BOOST_HAS_LONG_LONG) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX) || defined(_ULLONG_MAX) || defined(_LLONG_MAX)) + +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || \ + (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || \ + (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) || \ + (defined(_ULLONG_MAX) && _ULLONG_MAX == 18446744073709551615ULL) || \ + (defined(_LLONG_MAX) && _LLONG_MAX == 9223372036854775807LL) + +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615U // 2**64 - 1 +# define INT64_C(value) value##L +# define UINT64_C(value) value##uL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(BOOST_HAS_LONG_LONG) + // Usual macros not defined, work things out for ourselves: +# if(~0uLL == 18446744073709551615ULL) +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +# ifdef BOOST_NO_INT64_T +# define INTMAX_C(value) INT32_C(value) +# define UINTMAX_C(value) UINT32_C(value) +# else +# define INTMAX_C(value) INT64_C(value) +# define UINTMAX_C(value) UINT64_C(value) +# endif +#endif +# endif // Borland/Microsoft specific width suffixes + +#endif // INT#_C macros. + + + + diff --git a/thirdparty/linux/include/boost/current_function.hpp b/thirdparty/linux/include/boost/current_function.hpp new file mode 100644 index 0000000..86955cb --- /dev/null +++ b/thirdparty/linux/include/boost/current_function.hpp @@ -0,0 +1,75 @@ +#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED +#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/current_function.hpp - BOOST_CURRENT_FUNCTION +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// http://www.boost.org/libs/assert/current_function.html +// + +namespace boost +{ + +namespace detail +{ + +inline void current_function_helper() +{ + +#if defined( BOOST_DISABLE_CURRENT_FUNCTION ) + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__DMC__) && (__DMC__ >= 0x810) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__FUNCSIG__) + +# define BOOST_CURRENT_FUNCTION __FUNCSIG__ + +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) + +# define BOOST_CURRENT_FUNCTION __FUNCTION__ + +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) + +# define BOOST_CURRENT_FUNCTION __FUNC__ + +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) + +# define BOOST_CURRENT_FUNCTION __func__ + +#elif defined(__cplusplus) && (__cplusplus >= 201103) + +# define BOOST_CURRENT_FUNCTION __func__ + +#else + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#endif + +} + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/detail/lightweight_mutex.hpp b/thirdparty/linux/include/boost/detail/lightweight_mutex.hpp new file mode 100644 index 0000000..b7a7f6d --- /dev/null +++ b/thirdparty/linux/include/boost/detail/lightweight_mutex.hpp @@ -0,0 +1,22 @@ +#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED +#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lightweight_mutex.hpp - lightweight mutex +// +// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/detail/sp_typeinfo.hpp b/thirdparty/linux/include/boost/detail/sp_typeinfo.hpp new file mode 100644 index 0000000..4e4de55 --- /dev/null +++ b/thirdparty/linux/include/boost/detail/sp_typeinfo.hpp @@ -0,0 +1,36 @@ +#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED +#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_typeinfo.hpp +// +// Deprecated, please use boost/core/typeinfo.hpp +// +// Copyright 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +namespace boost +{ + +namespace detail +{ + +typedef boost::core::typeinfo sp_typeinfo; + +} // namespace detail + +} // namespace boost + +#define BOOST_SP_TYPEID(T) BOOST_CORE_TYPEID(T) + +#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/detail/workaround.hpp b/thirdparty/linux/include/boost/detail/workaround.hpp new file mode 100644 index 0000000..40b3423 --- /dev/null +++ b/thirdparty/linux/include/boost/detail/workaround.hpp @@ -0,0 +1,267 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef WORKAROUND_DWA2002126_HPP +# define WORKAROUND_DWA2002126_HPP + +// Compiler/library version workaround macro +// +// Usage: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// // workaround for eVC4 and VC6 +// ... // workaround code here +// #endif +// +// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the +// first argument must be undefined or expand to a numeric +// value. The above expands to: +// +// (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300 +// +// When used for workarounds that apply to the latest known version +// and all earlier versions of a compiler, the following convention +// should be observed: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301)) +// +// The version number in this case corresponds to the last version in +// which the workaround was known to have been required. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro +// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates +// the workaround for any version of the compiler. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or +// error will be issued if the compiler version exceeds the argument +// to BOOST_TESTED_AT(). This can be used to locate workarounds which +// may be obsoleted by newer versions. + +# ifndef BOOST_STRICT_CONFIG + +#include + +#ifndef __BORLANDC__ +#define __BORLANDC___WORKAROUND_GUARD 1 +#else +#define __BORLANDC___WORKAROUND_GUARD 0 +#endif +#ifndef __CODEGEARC__ +#define __CODEGEARC___WORKAROUND_GUARD 1 +#else +#define __CODEGEARC___WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_VER +#define _MSC_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_VER_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_FULL_VER +#define _MSC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC +#define BOOST_MSVC_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC_FULL_VER +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC__ +#define __GNUC___WORKAROUND_GUARD 1 +#else +#define __GNUC___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_MINOR__ +#define __GNUC_MINOR___WORKAROUND_GUARD 1 +#else +#define __GNUC_MINOR___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_PATCHLEVEL__ +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 1 +#else +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 0 +#endif +#ifndef __IBMCPP__ +#define __IBMCPP___WORKAROUND_GUARD 1 +#else +#define __IBMCPP___WORKAROUND_GUARD 0 +#endif +#ifndef __SUNPRO_CC +#define __SUNPRO_CC_WORKAROUND_GUARD 1 +#else +#define __SUNPRO_CC_WORKAROUND_GUARD 0 +#endif +#ifndef __DECCXX_VER +#define __DECCXX_VER_WORKAROUND_GUARD 1 +#else +#define __DECCXX_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __MWERKS__ +#define __MWERKS___WORKAROUND_GUARD 1 +#else +#define __MWERKS___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG__ +#define __EDG___WORKAROUND_GUARD 1 +#else +#define __EDG___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG_VERSION__ +#define __EDG_VERSION___WORKAROUND_GUARD 1 +#else +#define __EDG_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __HP_aCC +#define __HP_aCC_WORKAROUND_GUARD 1 +#else +#define __HP_aCC_WORKAROUND_GUARD 0 +#endif +#ifndef __hpxstd98 +#define __hpxstd98_WORKAROUND_GUARD 1 +#else +#define __hpxstd98_WORKAROUND_GUARD 0 +#endif +#ifndef _CRAYC +#define _CRAYC_WORKAROUND_GUARD 1 +#else +#define _CRAYC_WORKAROUND_GUARD 0 +#endif +#ifndef __DMC__ +#define __DMC___WORKAROUND_GUARD 1 +#else +#define __DMC___WORKAROUND_GUARD 0 +#endif +#ifndef MPW_CPLUS +#define MPW_CPLUS_WORKAROUND_GUARD 1 +#else +#define MPW_CPLUS_WORKAROUND_GUARD 0 +#endif +#ifndef __COMO__ +#define __COMO___WORKAROUND_GUARD 1 +#else +#define __COMO___WORKAROUND_GUARD 0 +#endif +#ifndef __COMO_VERSION__ +#define __COMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __COMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __INTEL_COMPILER +#define __INTEL_COMPILER_WORKAROUND_GUARD 1 +#else +#define __INTEL_COMPILER_WORKAROUND_GUARD 0 +#endif +#ifndef __ICL +#define __ICL_WORKAROUND_GUARD 1 +#else +#define __ICL_WORKAROUND_GUARD 0 +#endif +#ifndef _COMPILER_VERSION +#define _COMPILER_VERSION_WORKAROUND_GUARD 1 +#else +#define _COMPILER_VERSION_WORKAROUND_GUARD 0 +#endif + +#ifndef _RWSTD_VER +#define _RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define _RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_RWSTD_VER +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GLIBCPP__ +#define __GLIBCPP___WORKAROUND_GUARD 1 +#else +#define __GLIBCPP___WORKAROUND_GUARD 0 +#endif +#ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1 +#else +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 0 +#endif +#ifndef __SGI_STL_PORT +#define __SGI_STL_PORT_WORKAROUND_GUARD 1 +#else +#define __SGI_STL_PORT_WORKAROUND_GUARD 0 +#endif +#ifndef _STLPORT_VERSION +#define _STLPORT_VERSION_WORKAROUND_GUARD 1 +#else +#define _STLPORT_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef __LIBCOMO_VERSION__ +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef _CPPLIB_VER +#define _CPPLIB_VER_WORKAROUND_GUARD 1 +#else +#define _CPPLIB_VER_WORKAROUND_GUARD 0 +#endif + +#ifndef BOOST_INTEL_CXX_VERSION +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL_WIN +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_DINKUMWARE_STDLIB +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 1 +#else +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL +#define BOOST_INTEL_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WORKAROUND_GUARD 0 +#endif +// Always define to zero, if it's used it'll be defined my MPL: +#define BOOST_MPL_CFG_GCC_WORKAROUND_GUARD 0 + +# define BOOST_WORKAROUND(symbol, test) \ + ((symbol ## _WORKAROUND_GUARD + 0 == 0) && \ + (symbol != 0) && (1 % (( (symbol test) ) + 1))) +// ^ ^ ^ ^ +// The extra level of parenthesis nesting above, along with the +// BOOST_OPEN_PAREN indirection below, is required to satisfy the +// broken preprocessor in MWCW 8.3 and earlier. +// +// The basic mechanism works as follows: +// (symbol test) + 1 => if (symbol test) then 2 else 1 +// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0 +// +// The complication with % is for cooperation with BOOST_TESTED_AT(). +// When "test" is BOOST_TESTED_AT(x) and +// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined, +// +// symbol test => if (symbol <= x) then 1 else -1 +// (symbol test) + 1 => if (symbol <= x) then 2 else 0 +// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero +// + +# ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS +# define BOOST_OPEN_PAREN ( +# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1 +# else +# define BOOST_TESTED_AT(value) != ((value)-(value)) +# endif + +# else + +# define BOOST_WORKAROUND(symbol, test) 0 + +# endif + +#endif // WORKAROUND_DWA2002126_HPP diff --git a/thirdparty/linux/include/boost/exception/exception.hpp b/thirdparty/linux/include/boost/exception/exception.hpp new file mode 100644 index 0000000..c0fdaf9 --- /dev/null +++ b/thirdparty/linux/include/boost/exception/exception.hpp @@ -0,0 +1,521 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_274DA366004E11DCB1DDFE2E56D89593 +#define UUID_274DA366004E11DCB1DDFE2E56D89593 +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#ifdef BOOST_EXCEPTION_MINI_BOOST +#include +namespace boost { namespace exception_detail { using std::shared_ptr; } } +#else +namespace boost { template class shared_ptr; }; +namespace boost { namespace exception_detail { using boost::shared_ptr; } } +#endif + +namespace +boost + { + namespace + exception_detail + { + template + class + refcount_ptr + { + public: + + refcount_ptr(): + px_(0) + { + } + + ~refcount_ptr() + { + release(); + } + + refcount_ptr( refcount_ptr const & x ): + px_(x.px_) + { + add_ref(); + } + + refcount_ptr & + operator=( refcount_ptr const & x ) + { + adopt(x.px_); + return *this; + } + + void + adopt( T * px ) + { + release(); + px_=px; + add_ref(); + } + + T * + get() const + { + return px_; + } + + private: + + T * px_; + + void + add_ref() + { + if( px_ ) + px_->add_ref(); + } + + void + release() + { + if( px_ && px_->release() ) + px_=0; + } + }; + } + + //////////////////////////////////////////////////////////////////////// + + template + class error_info; + + typedef error_info throw_function; + typedef error_info throw_file; + typedef error_info throw_line; + + template <> + class + error_info + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef int value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class exception; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + namespace + exception_detail + { + class error_info_base; + struct type_info_; + + struct + error_info_container + { + virtual char const * diagnostic_information( char const * ) const = 0; + virtual shared_ptr get( type_info_ const & ) const = 0; + virtual void set( shared_ptr const &, type_info_ const & ) = 0; + virtual void add_ref() const = 0; + virtual bool release() const = 0; + virtual refcount_ptr clone() const = 0; + + protected: + + ~error_info_container() throw() + { + } + }; + + template + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + template + struct set_info_rv; + + template <> + struct set_info_rv; + + template <> + struct set_info_rv; + + template <> + struct set_info_rv; + + char const * get_diagnostic_information( exception const &, char const * ); + + void copy_boost_exception( exception *, exception const * ); + + template + E const & set_info( E const &, error_info const & ); + + template + E const & set_info( E const &, throw_function const & ); + + template + E const & set_info( E const &, throw_file const & ); + + template + E const & set_info( E const &, throw_line const & ); + } + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class + exception + { + // + public: + template void set( typename Tag::type const & ); + template typename Tag::type const * get() const; + // + + protected: + + exception(): + throw_function_(0), + throw_file_(0), + throw_line_(-1) + { + } + +#ifdef __HP_aCC + //On HP aCC, this protected copy constructor prevents throwing boost::exception. + //On all other platforms, the same effect is achieved by the pure virtual destructor. + exception( exception const & x ) throw(): + data_(x.data_), + throw_function_(x.throw_function_), + throw_file_(x.throw_file_), + throw_line_(x.throw_line_) + { + } +#endif + + virtual ~exception() throw() +#ifndef __HP_aCC + = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors. +#endif + ; + +#if (defined(__MWERKS__) && __MWERKS__<=0x3207) || (defined(_MSC_VER) && _MSC_VER<=1310) + public: +#else + private: + + template + friend E const & exception_detail::set_info( E const &, throw_function const & ); + + template + friend E const & exception_detail::set_info( E const &, throw_file const & ); + + template + friend E const & exception_detail::set_info( E const &, throw_line const & ); + + template + friend E const & exception_detail::set_info( E const &, error_info const & ); + + friend char const * exception_detail::get_diagnostic_information( exception const &, char const * ); + + template + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + template + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend void exception_detail::copy_boost_exception( exception *, exception const * ); +#endif + mutable exception_detail::refcount_ptr data_; + mutable char const * throw_function_; + mutable char const * throw_file_; + mutable int throw_line_; + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + inline + exception:: + ~exception() throw() + { + } + + namespace + exception_detail + { + template + E const & + set_info( E const & x, throw_function const & y ) + { + x.throw_function_=y.v_; + return x; + } + + template + E const & + set_info( E const & x, throw_file const & y ) + { + x.throw_file_=y.v_; + return x; + } + + template + E const & + set_info( E const & x, throw_line const & y ) + { + x.throw_line_=y.v_; + return x; + } + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + template + struct + error_info_injector: + public T, + public exception + { + explicit + error_info_injector( T const & x ): + T(x) + { + } + + ~error_info_injector() throw() + { + } + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + struct large_size { char c[256]; }; + large_size dispatch_boost_exception( exception const * ); + + struct small_size { }; + small_size dispatch_boost_exception( void const * ); + + template + struct enable_error_info_helper; + + template + struct + enable_error_info_helper + { + typedef T type; + }; + + template + struct + enable_error_info_helper + { + typedef error_info_injector type; + }; + + template + struct + enable_error_info_return_type + { + typedef typename enable_error_info_helper(0)))>::type type; + }; + } + + template + inline + typename + exception_detail::enable_error_info_return_type::type + enable_error_info( T const & x ) + { + typedef typename exception_detail::enable_error_info_return_type::type rt; + return rt(x); + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class + clone_base + { + public: + + virtual clone_base const * clone() const = 0; + virtual void rethrow() const = 0; + + virtual + ~clone_base() throw() + { + } + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + inline + void + copy_boost_exception( exception * a, exception const * b ) + { + refcount_ptr data; + if( error_info_container * d=b->data_.get() ) + data = d->clone(); + a->throw_file_ = b->throw_file_; + a->throw_line_ = b->throw_line_; + a->throw_function_ = b->throw_function_; + a->data_ = data; + } + + inline + void + copy_boost_exception( void *, void const * ) + { + } + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + template + class + clone_impl: + public T, + public virtual clone_base + { + struct clone_tag { }; + clone_impl( clone_impl const & x, clone_tag ): + T(x) + { + copy_boost_exception(this,&x); + } + + public: + + explicit + clone_impl( T const & x ): + T(x) + { + copy_boost_exception(this,&x); + } + + ~clone_impl() throw() + { + } + + private: + + clone_base const * + clone() const + { + return new clone_impl(*this,clone_tag()); + } + + void + rethrow() const + { + throw*this; + } + }; + } +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + template + inline + exception_detail::clone_impl + enable_current_exception( T const & x ) + { + return exception_detail::clone_impl(x); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/thirdparty/linux/include/boost/limits.hpp b/thirdparty/linux/include/boost/limits.hpp new file mode 100644 index 0000000..47d8155 --- /dev/null +++ b/thirdparty/linux/include/boost/limits.hpp @@ -0,0 +1,146 @@ + +// (C) Copyright John maddock 1999. +// (C) David Abrahams 2002. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// use this header as a workaround for missing + +// See http://www.boost.org/libs/compatibility/index.html for documentation. + +#ifndef BOOST_LIMITS +#define BOOST_LIMITS + +#include + +#ifdef BOOST_NO_LIMITS +# error "There is no std::numeric_limits suppport available." +#else +# include +#endif + +#if (defined(BOOST_HAS_LONG_LONG) && defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)) \ + || (defined(BOOST_HAS_MS_INT64) && defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS)) +// Add missing specializations for numeric_limits: +#ifdef BOOST_HAS_MS_INT64 +# define BOOST_LLT __int64 +# define BOOST_ULLT unsigned __int64 +#else +# define BOOST_LLT ::boost::long_long_type +# define BOOST_ULLT ::boost::ulong_long_type +#endif + +#include // for CHAR_BIT + +namespace std +{ + template<> + class numeric_limits + { + public: + + BOOST_STATIC_CONSTANT(bool, is_specialized = true); +#ifdef BOOST_HAS_MS_INT64 + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x8000000000000000i64; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x7FFFFFFFFFFFFFFFi64; } +#elif defined(LLONG_MAX) + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MIN; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MAX; } +#elif defined(LONGLONG_MAX) + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MIN; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MAX; } +#else + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~(min)(); } +#endif + BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT -1); + BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT) - 1) * 301L / 1000); + BOOST_STATIC_CONSTANT(bool, is_signed = true); + BOOST_STATIC_CONSTANT(bool, is_integer = true); + BOOST_STATIC_CONSTANT(bool, is_exact = true); + BOOST_STATIC_CONSTANT(int, radix = 2); + static BOOST_LLT epsilon() throw() { return 0; }; + static BOOST_LLT round_error() throw() { return 0; }; + + BOOST_STATIC_CONSTANT(int, min_exponent = 0); + BOOST_STATIC_CONSTANT(int, min_exponent10 = 0); + BOOST_STATIC_CONSTANT(int, max_exponent = 0); + BOOST_STATIC_CONSTANT(int, max_exponent10 = 0); + + BOOST_STATIC_CONSTANT(bool, has_infinity = false); + BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false); + BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false); + BOOST_STATIC_CONSTANT(bool, has_denorm = false); + BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false); + static BOOST_LLT infinity() throw() { return 0; }; + static BOOST_LLT quiet_NaN() throw() { return 0; }; + static BOOST_LLT signaling_NaN() throw() { return 0; }; + static BOOST_LLT denorm_min() throw() { return 0; }; + + BOOST_STATIC_CONSTANT(bool, is_iec559 = false); + BOOST_STATIC_CONSTANT(bool, is_bounded = true); + BOOST_STATIC_CONSTANT(bool, is_modulo = true); + + BOOST_STATIC_CONSTANT(bool, traps = false); + BOOST_STATIC_CONSTANT(bool, tinyness_before = false); + BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero); + + }; + + template<> + class numeric_limits + { + public: + + BOOST_STATIC_CONSTANT(bool, is_specialized = true); +#ifdef BOOST_HAS_MS_INT64 + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0ui64; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0xFFFFFFFFFFFFFFFFui64; } +#elif defined(ULLONG_MAX) && defined(ULLONG_MIN) + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MIN; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MAX; } +#elif defined(ULONGLONG_MAX) && defined(ULONGLONG_MIN) + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MIN; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MAX; } +#else + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0uLL; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~0uLL; } +#endif + BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT); + BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT)) * 301L / 1000); + BOOST_STATIC_CONSTANT(bool, is_signed = false); + BOOST_STATIC_CONSTANT(bool, is_integer = true); + BOOST_STATIC_CONSTANT(bool, is_exact = true); + BOOST_STATIC_CONSTANT(int, radix = 2); + static BOOST_ULLT epsilon() throw() { return 0; }; + static BOOST_ULLT round_error() throw() { return 0; }; + + BOOST_STATIC_CONSTANT(int, min_exponent = 0); + BOOST_STATIC_CONSTANT(int, min_exponent10 = 0); + BOOST_STATIC_CONSTANT(int, max_exponent = 0); + BOOST_STATIC_CONSTANT(int, max_exponent10 = 0); + + BOOST_STATIC_CONSTANT(bool, has_infinity = false); + BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false); + BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false); + BOOST_STATIC_CONSTANT(bool, has_denorm = false); + BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false); + static BOOST_ULLT infinity() throw() { return 0; }; + static BOOST_ULLT quiet_NaN() throw() { return 0; }; + static BOOST_ULLT signaling_NaN() throw() { return 0; }; + static BOOST_ULLT denorm_min() throw() { return 0; }; + + BOOST_STATIC_CONSTANT(bool, is_iec559 = false); + BOOST_STATIC_CONSTANT(bool, is_bounded = true); + BOOST_STATIC_CONSTANT(bool, is_modulo = true); + + BOOST_STATIC_CONSTANT(bool, traps = false); + BOOST_STATIC_CONSTANT(bool, tinyness_before = false); + BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero); + + }; +} +#endif + +#endif + diff --git a/thirdparty/linux/include/boost/predef.h b/thirdparty/linux/include/boost/predef.h new file mode 100644 index 0000000..4965337 --- /dev/null +++ b/thirdparty/linux/include/boost/predef.h @@ -0,0 +1,24 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_H +#define BOOST_PREDEF_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/architecture.h b/thirdparty/linux/include/boost/predef/architecture.h new file mode 100644 index 0000000..c433d43 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture.h @@ -0,0 +1,32 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_ARCHITECTURE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_ARCHITECTURE_H +#define BOOST_PREDEF_ARCHITECTURE_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/*#include */ + +#endif diff --git a/thirdparty/linux/include/boost/predef/architecture/alpha.h b/thirdparty/linux/include/boost/predef/architecture/alpha.h new file mode 100644 index 0000000..5bcade1 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/alpha.h @@ -0,0 +1,59 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_ALPHA_H +#define BOOST_PREDEF_ARCHITECTURE_ALPHA_H + +#include +#include + +/*` +[heading `BOOST_ARCH_ALPHA`] + +[@http://en.wikipedia.org/wiki/DEC_Alpha DEC Alpha] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + [[`__alpha__`] [__predef_detection__]] + [[`__alpha`] [__predef_detection__]] + [[`_M_ALPHA`] [__predef_detection__]] + + [[`__alpha_ev4__`] [4.0.0]] + [[`__alpha_ev5__`] [5.0.0]] + [[`__alpha_ev6__`] [6.0.0]] + ] + */ + +#define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__alpha__) || defined(__alpha) || \ + defined(_M_ALPHA) +# undef BOOST_ARCH_ALPHA +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev4__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev5__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev6__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_ALPHA +# define BOOST_ARCH_ALPHA_AVAILABLE +#endif + +#define BOOST_ARCH_ALPHA_NAME "DEC Alpha" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ALPHA,BOOST_ARCH_ALPHA_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/arm.h b/thirdparty/linux/include/boost/predef/architecture/arm.h new file mode 100644 index 0000000..b200c62 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/arm.h @@ -0,0 +1,70 @@ +/* +Copyright Rene Rivera 2008-2015 +Copyright Franz Detro 2014 +Copyright (c) Microsoft Corporation 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_ARM_H +#define BOOST_PREDEF_ARCHITECTURE_ARM_H + +#include +#include + +/*` +[heading `BOOST_ARCH_ARM`] + +[@http://en.wikipedia.org/wiki/ARM_architecture ARM] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__arm__`] [__predef_detection__]] + [[`__arm64`] [__predef_detection__]] + [[`__thumb__`] [__predef_detection__]] + [[`__TARGET_ARCH_ARM`] [__predef_detection__]] + [[`__TARGET_ARCH_THUMB`] [__predef_detection__]] + [[`_M_ARM`] [__predef_detection__]] + + [[`__arm64`] [8.0.0]] + [[`__TARGET_ARCH_ARM`] [V.0.0]] + [[`__TARGET_ARCH_THUMB`] [V.0.0]] + [[`_M_ARM`] [V.0.0]] + ] + */ + +#define BOOST_ARCH_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__arm__) || defined(__arm64) || defined(__thumb__) || \ + defined(__TARGET_ARCH_ARM) || defined(__TARGET_ARCH_THUMB) || \ + defined(_M_ARM) +# undef BOOST_ARCH_ARM +# if !defined(BOOST_ARCH_ARM) && defined(__arm64) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(8,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && defined(__TARGET_ARCH_ARM) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__TARGET_ARCH_ARM,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && defined(__TARGET_ARCH_THUMB) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__TARGET_ARCH_THUMB,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && defined(_M_ARM) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(_M_ARM,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_ARM +# define BOOST_ARCH_ARM_AVAILABLE +#endif + +#define BOOST_ARCH_ARM_NAME "ARM" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ARM,BOOST_ARCH_ARM_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/blackfin.h b/thirdparty/linux/include/boost/predef/architecture/blackfin.h new file mode 100644 index 0000000..84c58a2 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/blackfin.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2013-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_BLACKFIN_H +#define BOOST_PREDEF_ARCHITECTURE_BLACKFIN_H + +#include +#include + +/*` +[heading `BOOST_ARCH_BLACKFIN`] + +Blackfin Processors from Analog Devices. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__bfin__`] [__predef_detection__]] + [[`__BFIN__`] [__predef_detection__]] + [[`bfin`] [__predef_detection__]] + [[`BFIN`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_BLACKFIN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__bfin__) || defined(__BFIN__) || \ + defined(bfin) || defined(BFIN) +# undef BOOST_ARCH_BLACKFIN +# define BOOST_ARCH_BLACKFIN BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_BLACKFIN +# define BOOST_ARCH_BLACKFIN_AVAILABLE +#endif + +#define BOOST_ARCH_BLACKFIN_NAME "Blackfin" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_BLACKFIN,BOOST_ARCH_BLACKFIN_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/convex.h b/thirdparty/linux/include/boost/predef/architecture/convex.h new file mode 100644 index 0000000..ac783a9 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/convex.h @@ -0,0 +1,65 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_CONVEX_H +#define BOOST_PREDEF_ARCHITECTURE_CONVEX_H + +#include +#include + +/*` +[heading `BOOST_ARCH_CONVEX`] + +[@http://en.wikipedia.org/wiki/Convex_Computer Convex Computer] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__convex__`] [__predef_detection__]] + + [[`__convex_c1__`] [1.0.0]] + [[`__convex_c2__`] [2.0.0]] + [[`__convex_c32__`] [3.2.0]] + [[`__convex_c34__`] [3.4.0]] + [[`__convex_c38__`] [3.8.0]] + ] + */ + +#define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__convex__) +# undef BOOST_ARCH_CONVEX +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c1__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c2__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c32__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c34__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,4,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c38__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,8,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_CONVEX +# define BOOST_ARCH_CONVEX_AVAILABLE +#endif + +#define BOOST_ARCH_CONVEX_NAME "Convex Computer" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_CONVEX,BOOST_ARCH_CONVEX_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/ia64.h b/thirdparty/linux/include/boost/predef/architecture/ia64.h new file mode 100644 index 0000000..9b1972b --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/ia64.h @@ -0,0 +1,49 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_IA64_H +#define BOOST_PREDEF_ARCHITECTURE_IA64_H + +#include +#include + +/*` +[heading `BOOST_ARCH_IA64`] + +[@http://en.wikipedia.org/wiki/Ia64 Intel Itanium 64] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__ia64__`] [__predef_detection__]] + [[`_IA64`] [__predef_detection__]] + [[`__IA64__`] [__predef_detection__]] + [[`__ia64`] [__predef_detection__]] + [[`_M_IA64`] [__predef_detection__]] + [[`__itanium__`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_IA64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__ia64__) || defined(_IA64) || \ + defined(__IA64__) || defined(__ia64) || \ + defined(_M_IA64) || defined(__itanium__) +# undef BOOST_ARCH_IA64 +# define BOOST_ARCH_IA64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_IA64 +# define BOOST_ARCH_IA64_AVAILABLE +#endif + +#define BOOST_ARCH_IA64_NAME "Intel Itanium 64" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_IA64,BOOST_ARCH_IA64_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/m68k.h b/thirdparty/linux/include/boost/predef/architecture/m68k.h new file mode 100644 index 0000000..63ed5f8 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/m68k.h @@ -0,0 +1,82 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_M68K_H +#define BOOST_PREDEF_ARCHITECTURE_M68K_H + +#include +#include + +/*` +[heading `BOOST_ARCH_M68K`] + +[@http://en.wikipedia.org/wiki/M68k Motorola 68k] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__m68k__`] [__predef_detection__]] + [[`M68000`] [__predef_detection__]] + + [[`__mc68060__`] [6.0.0]] + [[`mc68060`] [6.0.0]] + [[`__mc68060`] [6.0.0]] + [[`__mc68040__`] [4.0.0]] + [[`mc68040`] [4.0.0]] + [[`__mc68040`] [4.0.0]] + [[`__mc68030__`] [3.0.0]] + [[`mc68030`] [3.0.0]] + [[`__mc68030`] [3.0.0]] + [[`__mc68020__`] [2.0.0]] + [[`mc68020`] [2.0.0]] + [[`__mc68020`] [2.0.0]] + [[`__mc68010__`] [1.0.0]] + [[`mc68010`] [1.0.0]] + [[`__mc68010`] [1.0.0]] + [[`__mc68000__`] [0.0.1]] + [[`mc68000`] [0.0.1]] + [[`__mc68000`] [0.0.1]] + ] + */ + +#define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__m68k__) || defined(M68000) +# undef BOOST_ARCH_M68K +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68060__) || defined(mc68060) || defined(__mc68060)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68040__) || defined(mc68040) || defined(__mc68040)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68030__) || defined(mc68030) || defined(__mc68030)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68020__) || defined(mc68020) || defined(__mc68020)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68010__) || defined(mc68010) || defined(__mc68010)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68000__) || defined(mc68000) || defined(__mc68000)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if !defined(BOOST_ARCH_M68K) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_M68K +# define BOOST_ARCH_M68K_AVAILABLE +#endif + +#define BOOST_ARCH_M68K_NAME "Motorola 68k" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_M68K,BOOST_ARCH_M68K_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/mips.h b/thirdparty/linux/include/boost/predef/architecture/mips.h new file mode 100644 index 0000000..0189d7d --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/mips.h @@ -0,0 +1,73 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_MIPS_H +#define BOOST_PREDEF_ARCHITECTURE_MIPS_H + +#include +#include + +/*` +[heading `BOOST_ARCH_MIPS`] + +[@http://en.wikipedia.org/wiki/MIPS_architecture MIPS] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__mips__`] [__predef_detection__]] + [[`__mips`] [__predef_detection__]] + [[`__MIPS__`] [__predef_detection__]] + + [[`__mips`] [V.0.0]] + [[`_MIPS_ISA_MIPS1`] [1.0.0]] + [[`_R3000`] [1.0.0]] + [[`_MIPS_ISA_MIPS2`] [2.0.0]] + [[`__MIPS_ISA2__`] [2.0.0]] + [[`_R4000`] [2.0.0]] + [[`_MIPS_ISA_MIPS3`] [3.0.0]] + [[`__MIPS_ISA3__`] [3.0.0]] + [[`_MIPS_ISA_MIPS4`] [4.0.0]] + [[`__MIPS_ISA4__`] [4.0.0]] + ] + */ + +#define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__mips__) || defined(__mips) || \ + defined(__MIPS__) +# undef BOOST_ARCH_MIPS +# if !defined(BOOST_ARCH_MIPS) && (defined(__mips)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(__mips,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS1) || defined(_R3000)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS2) || defined(__MIPS_ISA2__) || defined(_R4000)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS3) || defined(__MIPS_ISA3__)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS4) || defined(__MIPS_ISA4__)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_MIPS +# define BOOST_ARCH_MIPS_AVAILABLE +#endif + +#define BOOST_ARCH_MIPS_NAME "MIPS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_MIPS,BOOST_ARCH_MIPS_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/parisc.h b/thirdparty/linux/include/boost/predef/architecture/parisc.h new file mode 100644 index 0000000..7c7625f --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/parisc.h @@ -0,0 +1,64 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PARISC_H +#define BOOST_PREDEF_ARCHITECTURE_PARISC_H + +#include +#include + +/*` +[heading `BOOST_ARCH_PARISK`] + +[@http://en.wikipedia.org/wiki/PA-RISC_family HP/PA RISC] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__hppa__`] [__predef_detection__]] + [[`__hppa`] [__predef_detection__]] + [[`__HPPA__`] [__predef_detection__]] + + [[`_PA_RISC1_0`] [1.0.0]] + [[`_PA_RISC1_1`] [1.1.0]] + [[`__HPPA11__`] [1.1.0]] + [[`__PA7100__`] [1.1.0]] + [[`_PA_RISC2_0`] [2.0.0]] + [[`__RISC2_0__`] [2.0.0]] + [[`__HPPA20__`] [2.0.0]] + [[`__PA8000__`] [2.0.0]] + ] + */ + +#define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__hppa__) || defined(__hppa) || defined(__HPPA__) +# undef BOOST_ARCH_PARISC +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC1_0)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC1_1) || defined(__HPPA11__) || defined(__PA7100__)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(1,1,0) +# endif +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC2_0) || defined(__RISC2_0__) || defined(__HPPA20__) || defined(__PA8000__)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_PARISC) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_PARISC +# define BOOST_ARCH_PARISC_AVAILABLE +#endif + +#define BOOST_ARCH_PARISC_NAME "HP/PA RISC" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PARISC,BOOST_ARCH_PARISC_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/ppc.h b/thirdparty/linux/include/boost/predef/architecture/ppc.h new file mode 100644 index 0000000..e8c57c9 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/ppc.h @@ -0,0 +1,72 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PPC_H +#define BOOST_PREDEF_ARCHITECTURE_PPC_H + +#include +#include + +/*` +[heading `BOOST_ARCH_PPC`] + +[@http://en.wikipedia.org/wiki/PowerPC PowerPC] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__powerpc`] [__predef_detection__]] + [[`__powerpc__`] [__predef_detection__]] + [[`__POWERPC__`] [__predef_detection__]] + [[`__ppc__`] [__predef_detection__]] + [[`_M_PPC`] [__predef_detection__]] + [[`_ARCH_PPC`] [__predef_detection__]] + [[`__PPCGECKO__`] [__predef_detection__]] + [[`__PPCBROADWAY__`] [__predef_detection__]] + [[`_XENON`] [__predef_detection__]] + + [[`__ppc601__`] [6.1.0]] + [[`_ARCH_601`] [6.1.0]] + [[`__ppc603__`] [6.3.0]] + [[`_ARCH_603`] [6.3.0]] + [[`__ppc604__`] [6.4.0]] + [[`__ppc604__`] [6.4.0]] + ] + */ + +#define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__powerpc) || defined(__powerpc__) || \ + defined(__POWERPC__) || defined(__ppc__) || \ + defined(_M_PPC) || defined(_ARCH_PPC) || \ + defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \ + defined(_XENON) +# undef BOOST_ARCH_PPC +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc601__) || defined(_ARCH_601)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,1,0) +# endif +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc603__) || defined(_ARCH_603)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,3,0) +# endif +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc604__) || defined(__ppc604__)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,4,0) +# endif +# if !defined (BOOST_ARCH_PPC) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_PPC +# define BOOST_ARCH_PPC_AVAILABLE +#endif + +#define BOOST_ARCH_PPC_NAME "PowerPC" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PPC,BOOST_ARCH_PPC_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/pyramid.h b/thirdparty/linux/include/boost/predef/architecture/pyramid.h new file mode 100644 index 0000000..4f13253 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/pyramid.h @@ -0,0 +1,42 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PYRAMID_H +#define BOOST_PREDEF_ARCHITECTURE_PYRAMID_H + +#include +#include + +/*` +[heading `BOOST_ARCH_PYRAMID`] + +Pyramid 9810 architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`pyr`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_PYRAMID BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(pyr) +# undef BOOST_ARCH_PYRAMID +# define BOOST_ARCH_PYRAMID BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_PYRAMID +# define BOOST_ARCH_PYRAMID_AVAILABLE +#endif + +#define BOOST_ARCH_PYRAMID_NAME "Pyramid 9810" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PYRAMID,BOOST_ARCH_PYRAMID_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/rs6k.h b/thirdparty/linux/include/boost/predef/architecture/rs6k.h new file mode 100644 index 0000000..8a6e9b6 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/rs6k.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_RS6K_H +#define BOOST_PREDEF_ARCHITECTURE_RS6K_H + +#include +#include + +/*` +[heading `BOOST_ARCH_RS6000`] + +[@http://en.wikipedia.org/wiki/RS/6000 RS/6000] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__THW_RS6000`] [__predef_detection__]] + [[`_IBMR2`] [__predef_detection__]] + [[`_POWER`] [__predef_detection__]] + [[`_ARCH_PWR`] [__predef_detection__]] + [[`_ARCH_PWR2`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_RS6000 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__THW_RS6000) || defined(_IBMR2) || \ + defined(_POWER) || defined(_ARCH_PWR) || \ + defined(_ARCH_PWR2) +# undef BOOST_ARCH_RS6000 +# define BOOST_ARCH_RS6000 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_RS6000 +# define BOOST_ARCH_RS6000_AVAILABLE +#endif + +#define BOOST_ARCH_RS6000_NAME "RS/6000" + +#define BOOST_ARCH_PWR BOOST_ARCH_RS6000 + +#if BOOST_ARCH_PWR +# define BOOST_ARCH_PWR_AVAILABLE +#endif + +#define BOOST_ARCH_PWR_NAME BOOST_ARCH_RS6000_NAME + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_RS6000,BOOST_ARCH_RS6000_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/sparc.h b/thirdparty/linux/include/boost/predef/architecture/sparc.h new file mode 100644 index 0000000..a89a510 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/sparc.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SPARC_H +#define BOOST_PREDEF_ARCHITECTURE_SPARC_H + +#include +#include + +/*` +[heading `BOOST_ARCH_SPARC`] + +[@http://en.wikipedia.org/wiki/SPARC SPARC] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__sparc__`] [__predef_detection__]] + [[`__sparc`] [__predef_detection__]] + + [[`__sparcv9`] [9.0.0]] + [[`__sparcv8`] [8.0.0]] + ] + */ + +#define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sparc__) || defined(__sparc) +# undef BOOST_ARCH_SPARC +# if !defined(BOOST_ARCH_SPARC) && defined(__sparcv9) +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(9,0,0) +# endif +# if !defined(BOOST_ARCH_SPARC) && defined(__sparcv8) +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(8,0,0) +# endif +# if !defined(BOOST_ARCH_SPARC) +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_SPARC +# define BOOST_ARCH_SPARC_AVAILABLE +#endif + +#define BOOST_ARCH_SPARC_NAME "SPARC" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SPARC,BOOST_ARCH_SPARC_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/superh.h b/thirdparty/linux/include/boost/predef/architecture/superh.h new file mode 100644 index 0000000..da0529e --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/superh.h @@ -0,0 +1,67 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SUPERH_H +#define BOOST_PREDEF_ARCHITECTURE_SUPERH_H + +#include +#include + +/*` +[heading `BOOST_ARCH_SH`] + +[@http://en.wikipedia.org/wiki/SuperH SuperH] architecture: +If available versions \[1-5\] are specifically detected. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__sh__`] [__predef_detection__]] + + [[`__SH5__`] [5.0.0]] + [[`__SH4__`] [4.0.0]] + [[`__sh3__`] [3.0.0]] + [[`__SH3__`] [3.0.0]] + [[`__sh2__`] [2.0.0]] + [[`__sh1__`] [1.0.0]] + ] + */ + +#define BOOST_ARCH_SH BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sh__) +# undef BOOST_ARCH_SH +# if !defined(BOOST_ARCH_SH) && (defined(__SH5__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__SH4__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh3__) || defined(__SH3__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh2__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh1__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_SH) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_SH +# define BOOST_ARCH_SH_AVAILABLE +#endif + +#define BOOST_ARCH_SH_NAME "SuperH" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SH,BOOST_ARCH_SH_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/sys370.h b/thirdparty/linux/include/boost/predef/architecture/sys370.h new file mode 100644 index 0000000..cfd85dc --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/sys370.h @@ -0,0 +1,43 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SYS370_H +#define BOOST_PREDEF_ARCHITECTURE_SYS370_H + +#include +#include + +/*` +[heading `BOOST_ARCH_SYS370`] + +[@http://en.wikipedia.org/wiki/System/370 System/370] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__370__`] [__predef_detection__]] + [[`__THW_370__`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_SYS370 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__370__) || defined(__THW_370__) +# undef BOOST_ARCH_SYS370 +# define BOOST_ARCH_SYS370 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_SYS370 +# define BOOST_ARCH_SYS370_AVAILABLE +#endif + +#define BOOST_ARCH_SYS370_NAME "System/370" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS370,BOOST_ARCH_SYS370_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/sys390.h b/thirdparty/linux/include/boost/predef/architecture/sys390.h new file mode 100644 index 0000000..47aff6a --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/sys390.h @@ -0,0 +1,43 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SYS390_H +#define BOOST_PREDEF_ARCHITECTURE_SYS390_H + +#include +#include + +/*` +[heading `BOOST_ARCH_SYS390`] + +[@http://en.wikipedia.org/wiki/System/390 System/390] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__s390__`] [__predef_detection__]] + [[`__s390x__`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_SYS390 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__s390__) || defined(__s390x__) +# undef BOOST_ARCH_SYS390 +# define BOOST_ARCH_SYS390 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_SYS390 +# define BOOST_ARCH_SYS390_AVAILABLE +#endif + +#define BOOST_ARCH_SYS390_NAME "System/390" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS390,BOOST_ARCH_SYS390_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/x86.h b/thirdparty/linux/include/boost/predef/architecture/x86.h new file mode 100644 index 0000000..0ef3ef4 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/x86.h @@ -0,0 +1,38 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#include +#include + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_H +#define BOOST_PREDEF_ARCHITECTURE_X86_H + +/*` +[heading `BOOST_ARCH_X86`] + +[@http://en.wikipedia.org/wiki/X86 Intel x86] architecture. This is +a category to indicate that either `BOOST_ARCH_X86_32` or +`BOOST_ARCH_X86_64` is detected. + */ + +#define BOOST_ARCH_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_ARCH_X86_32 || BOOST_ARCH_X86_64 +# undef BOOST_ARCH_X86 +# define BOOST_ARCH_X86 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_X86 +# define BOOST_ARCH_X86_AVAILABLE +#endif + +#define BOOST_ARCH_X86_NAME "Intel x86" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86,BOOST_ARCH_X86_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/x86/32.h b/thirdparty/linux/include/boost/predef/architecture/x86/32.h new file mode 100644 index 0000000..17fbff5 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/x86/32.h @@ -0,0 +1,87 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_32_H +#define BOOST_PREDEF_ARCHITECTURE_X86_32_H + +#include +#include + +/*` +[heading `BOOST_ARCH_X86_32`] + +[@http://en.wikipedia.org/wiki/X86 Intel x86] architecture: +If available versions \[3-6\] are specifically detected. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`i386`] [__predef_detection__]] + [[`__i386__`] [__predef_detection__]] + [[`__i486__`] [__predef_detection__]] + [[`__i586__`] [__predef_detection__]] + [[`__i686__`] [__predef_detection__]] + [[`__i386`] [__predef_detection__]] + [[`_M_IX86`] [__predef_detection__]] + [[`_X86_`] [__predef_detection__]] + [[`__THW_INTEL__`] [__predef_detection__]] + [[`__I86__`] [__predef_detection__]] + [[`__INTEL__`] [__predef_detection__]] + + [[`__I86__`] [V.0.0]] + [[`_M_IX86`] [V.0.0]] + [[`__i686__`] [6.0.0]] + [[`__i586__`] [5.0.0]] + [[`__i486__`] [4.0.0]] + [[`__i386__`] [3.0.0]] + ] + */ + +#define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(i386) || defined(__i386__) || \ + defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(__i386) || \ + defined(_M_IX86) || defined(_X86_) || \ + defined(__THW_INTEL__) || defined(__I86__) || \ + defined(__INTEL__) +# undef BOOST_ARCH_X86_32 +# if !defined(BOOST_ARCH_X86_32) && defined(__I86__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(__I86__,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(_M_IX86) +# define BOOST_ARCH_X86_32 BOOST_PREDEF_MAKE_10_VV00(_M_IX86) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i686__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i586__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i486__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i386__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_X86_32 +# define BOOST_ARCH_X86_32_AVAILABLE +#endif + +#define BOOST_ARCH_X86_32_NAME "Intel x86-32" + +#include + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_32,BOOST_ARCH_X86_32_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/x86/64.h b/thirdparty/linux/include/boost/predef/architecture/x86/64.h new file mode 100644 index 0000000..f761c92 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/x86/64.h @@ -0,0 +1,50 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_64_H +#define BOOST_PREDEF_ARCHITECTURE_X86_64_H + +#include +#include + +/*` +[heading `BOOST_ARCH_X86_64`] + +[@http://en.wikipedia.org/wiki/Ia64 Intel IA-64] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__x86_64`] [__predef_detection__]] + [[`__x86_64__`] [__predef_detection__]] + [[`__amd64__`] [__predef_detection__]] + [[`__amd64`] [__predef_detection__]] + [[`_M_X64`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_X86_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__x86_64) || defined(__x86_64__) || \ + defined(__amd64__) || defined(__amd64) || \ + defined(_M_X64) +# undef BOOST_ARCH_X86_64 +# define BOOST_ARCH_X86_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_X86_64 +# define BOOST_ARCH_X86_64_AVAILABLE +#endif + +#define BOOST_ARCH_X86_64_NAME "Intel x86-64" + +#include + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_64,BOOST_ARCH_X86_64_NAME) diff --git a/thirdparty/linux/include/boost/predef/architecture/z.h b/thirdparty/linux/include/boost/predef/architecture/z.h new file mode 100644 index 0000000..3d218aa --- /dev/null +++ b/thirdparty/linux/include/boost/predef/architecture/z.h @@ -0,0 +1,42 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_Z_H +#define BOOST_PREDEF_ARCHITECTURE_Z_H + +#include +#include + +/*` +[heading `BOOST_ARCH_Z`] + +[@http://en.wikipedia.org/wiki/Z/Architecture z/Architecture] architecture. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__SYSC_ZARCH__`] [__predef_detection__]] + ] + */ + +#define BOOST_ARCH_Z BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SYSC_ZARCH__) +# undef BOOST_ARCH_Z +# define BOOST_ARCH_Z BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_Z +# define BOOST_ARCH_Z_AVAILABLE +#endif + +#define BOOST_ARCH_Z_NAME "z/Architecture" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_Z,BOOST_ARCH_Z_NAME) diff --git a/thirdparty/linux/include/boost/predef/compiler.h b/thirdparty/linux/include/boost/predef/compiler.h new file mode 100644 index 0000000..61a4c52 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler.h @@ -0,0 +1,43 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_COMPILER_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_COMPILER_H +#define BOOST_PREDEF_COMPILER_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/borland.h b/thirdparty/linux/include/boost/predef/compiler/borland.h new file mode 100644 index 0000000..3677cca --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/borland.h @@ -0,0 +1,63 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_BORLAND_H +#define BOOST_PREDEF_COMPILER_BORLAND_H + +#include +#include + +/*` +[heading `BOOST_COMP_BORLAND`] + +[@http://en.wikipedia.org/wiki/C_plus_plus_builder Borland C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__BORLANDC__`] [__predef_detection__]] + [[`__CODEGEARC__`] [__predef_detection__]] + + [[`__BORLANDC__`] [V.R.P]] + [[`__CODEGEARC__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_BORLAND BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__BORLANDC__) || defined(__CODEGEARC__) +# if !defined(BOOST_COMP_BORLAND_DETECTION) && (defined(__CODEGEARC__)) +# define BOOST_COMP_BORLAND_DETECTION BOOST_PREDEF_MAKE_0X_VVRP(__CODEGEARC__) +# endif +# if !defined(BOOST_COMP_BORLAND_DETECTION) +# define BOOST_COMP_BORLAND_DETECTION BOOST_PREDEF_MAKE_0X_VVRP(__BORLANDC__) +# endif +#endif + +#ifdef BOOST_COMP_BORLAND_DETECTION +# define BOOST_COMP_BORLAND_AVAILABLE +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_BORLAND_EMULATED BOOST_COMP_BORLAND_DETECTION +# else +# undef BOOST_COMP_BORLAND +# define BOOST_COMP_BORLAND BOOST_COMP_BORLAND_DETECTION +# endif +# include +#endif + +#define BOOST_COMP_BORLAND_NAME "Borland C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND,BOOST_COMP_BORLAND_NAME) + +#ifdef BOOST_COMP_BORLAND_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND_EMULATED,BOOST_COMP_BORLAND_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/clang.h b/thirdparty/linux/include/boost/predef/compiler/clang.h new file mode 100644 index 0000000..56678fe --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/clang.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_CLANG_H +#define BOOST_PREDEF_COMPILER_CLANG_H + +#include +#include + +/*` +[heading `BOOST_COMP_CLANG`] + +[@http://en.wikipedia.org/wiki/Clang Clang] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__clang__`] [__predef_detection__]] + + [[`__clang_major__`, `__clang_minor__`, `__clang_patchlevel__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_CLANG BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__clang__) +# define BOOST_COMP_CLANG_DETECTION BOOST_VERSION_NUMBER(__clang_major__,__clang_minor__,__clang_patchlevel__) +#endif + +#ifdef BOOST_COMP_CLANG_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_CLANG_EMULATED BOOST_COMP_CLANG_DETECTION +# else +# undef BOOST_COMP_CLANG +# define BOOST_COMP_CLANG BOOST_COMP_CLANG_DETECTION +# endif +# define BOOST_COMP_CLANG_AVAILABLE +# include +#endif + +#define BOOST_COMP_CLANG_NAME "Clang" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG,BOOST_COMP_CLANG_NAME) + +#ifdef BOOST_COMP_CLANG_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG_EMULATED,BOOST_COMP_CLANG_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/comeau.h b/thirdparty/linux/include/boost/predef/compiler/comeau.h new file mode 100644 index 0000000..15a4564 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/comeau.h @@ -0,0 +1,61 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_COMEAU_H +#define BOOST_PREDEF_COMPILER_COMEAU_H + +#include +#include + +#define BOOST_COMP_COMO BOOST_VERSION_NUMBER_NOT_AVAILABLE + +/*` +[heading `BOOST_COMP_COMO`] + +[@http://en.wikipedia.org/wiki/Comeau_C/C%2B%2B Comeau C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__COMO__`] [__predef_detection__]] + + [[`__COMO_VERSION__`] [V.R.P]] + ] + */ + +#if defined(__COMO__) +# if !defined(BOOST_COMP_COMO_DETECTION) && defined(__COMO_VERSION__) +# define BOOST_COMP_COMO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__COMO_VERSION__) +# endif +# if !defined(BOOST_COMP_COMO_DETECTION) +# define BOOST_COMP_COMO_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_COMO_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_COMO_EMULATED BOOST_COMP_COMO_DETECTION +# else +# undef BOOST_COMP_COMO +# define BOOST_COMP_COMO BOOST_COMP_COMO_DETECTION +# endif +# define BOOST_COMP_COMO_AVAILABLE +# include +#endif + +#define BOOST_COMP_COMO_NAME "Comeau C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO,BOOST_COMP_COMO_NAME) + +#ifdef BOOST_COMP_COMO_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO_EMULATED,BOOST_COMP_COMO_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/compaq.h b/thirdparty/linux/include/boost/predef/compiler/compaq.h new file mode 100644 index 0000000..96a79e6 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/compaq.h @@ -0,0 +1,66 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_COMPAQ_H +#define BOOST_PREDEF_COMPILER_COMPAQ_H + +#include +#include + +/*` +[heading `BOOST_COMP_DEC`] + +[@http://www.openvms.compaq.com/openvms/brochures/deccplus/ Compaq C/C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__DECCXX`] [__predef_detection__]] + [[`__DECC`] [__predef_detection__]] + + [[`__DECCXX_VER`] [V.R.P]] + [[`__DECC_VER`] [V.R.P]] + ] + */ + +#define BOOST_COMP_DEC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__DECC) || defined(__DECCXX) +# if !defined(BOOST_COMP_DEC_DETECTION) && defined(__DECCXX_VER) +# define BOOST_COMP_DEC_DETECTION BOOST_PREDEF_MAKE_10_VVRR0PP00(__DECCXX_VER) +# endif +# if !defined(BOOST_COMP_DEC_DETECTION) && defined(__DECC_VER) +# define BOOST_COMP_DEC_DETECTION BOOST_PREDEF_MAKE_10_VVRR0PP00(__DECC_VER) +# endif +# if !defined(BOOST_COMP_DEC_DETECTION) +# define BOOST_COM_DEC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_DEC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_DEC_EMULATED BOOST_COMP_DEC_DETECTION +# else +# undef BOOST_COMP_DEC +# define BOOST_COMP_DEC BOOST_COMP_DEC_DETECTION +# endif +# define BOOST_COMP_DEC_AVAILABLE +# include +#endif + +#define BOOST_COMP_DEC_NAME "Compaq C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC,BOOST_COMP_DEC_NAME) + +#ifdef BOOST_COMP_DEC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC_EMULATED,BOOST_COMP_DEC_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/diab.h b/thirdparty/linux/include/boost/predef/compiler/diab.h new file mode 100644 index 0000000..f5a37de --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/diab.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_DIAB_H +#define BOOST_PREDEF_COMPILER_DIAB_H + +#include +#include + +/*` +[heading `BOOST_COMP_DIAB`] + +[@http://www.windriver.com/products/development_suite/wind_river_compiler/ Diab C/C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__DCC__`] [__predef_detection__]] + + [[`__VERSION_NUMBER__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_DIAB BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__DCC__) +# define BOOST_COMP_DIAB_DETECTION BOOST_PREDEF_MAKE_10_VRPP(__VERSION_NUMBER__) +#endif + +#ifdef BOOST_COMP_DIAB_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_DIAB_EMULATED BOOST_COMP_DIAB_DETECTION +# else +# undef BOOST_COMP_DIAB +# define BOOST_COMP_DIAB BOOST_COMP_DIAB_DETECTION +# endif +# define BOOST_COMP_DIAB_AVAILABLE +# include +#endif + +#define BOOST_COMP_DIAB_NAME "Diab C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB,BOOST_COMP_DIAB_NAME) + +#ifdef BOOST_COMP_DIAB_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB_EMULATED,BOOST_COMP_DIAB_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/digitalmars.h b/thirdparty/linux/include/boost/predef/compiler/digitalmars.h new file mode 100644 index 0000000..9bd5850 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/digitalmars.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_DIGITALMARS_H +#define BOOST_PREDEF_COMPILER_DIGITALMARS_H + +#include +#include + +/*` +[heading `BOOST_COMP_DMC`] + +[@http://en.wikipedia.org/wiki/Digital_Mars Digital Mars] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__DMC__`] [__predef_detection__]] + + [[`__DMC__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_DMC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__DMC__) +# define BOOST_COMP_DMC_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__DMC__) +#endif + +#ifdef BOOST_COMP_DMC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_DMC_EMULATED BOOST_COMP_DMC_DETECTION +# else +# undef BOOST_COMP_DMC +# define BOOST_COMP_DMC BOOST_COMP_DMC_DETECTION +# endif +# define BOOST_COMP_DMC_AVAILABLE +# include +#endif + +#define BOOST_COMP_DMC_NAME "Digital Mars" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC,BOOST_COMP_DMC_NAME) + +#ifdef BOOST_COMP_DMC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC_EMULATED,BOOST_COMP_DMC_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/dignus.h b/thirdparty/linux/include/boost/predef/compiler/dignus.h new file mode 100644 index 0000000..c65d3dc --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/dignus.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_DIGNUS_H +#define BOOST_PREDEF_COMPILER_DIGNUS_H + +#include +#include + +/*` +[heading `BOOST_COMP_SYSC`] + +[@http://www.dignus.com/dcxx/ Dignus Systems/C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__SYSC__`] [__predef_detection__]] + + [[`__SYSC_VER__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_SYSC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SYSC__) +# define BOOST_COMP_SYSC_DETECTION BOOST_PREDEF_MAKE_10_VRRPP(__SYSC_VER__) +#endif + +#ifdef BOOST_COMP_SYSC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_SYSC_EMULATED BOOST_COMP_SYSC_DETECTION +# else +# undef BOOST_COMP_SYSC +# define BOOST_COMP_SYSC BOOST_COMP_SYSC_DETECTION +# endif +# define BOOST_COMP_SYSC_AVAILABLE +# include +#endif + +#define BOOST_COMP_SYSC_NAME "Dignus Systems/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC,BOOST_COMP_SYSC_NAME) + +#ifdef BOOST_COMP_SYSC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC_EMULATED,BOOST_COMP_SYSC_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/edg.h b/thirdparty/linux/include/boost/predef/compiler/edg.h new file mode 100644 index 0000000..2ffb9b0 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/edg.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_EDG_H +#define BOOST_PREDEF_COMPILER_EDG_H + +#include +#include + +/*` +[heading `BOOST_COMP_EDG`] + +[@http://en.wikipedia.org/wiki/Edison_Design_Group EDG C++ Frontend] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__EDG__`] [__predef_detection__]] + + [[`__EDG_VERSION__`] [V.R.0]] + ] + */ + +#define BOOST_COMP_EDG BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__EDG__) +# define BOOST_COMP_EDG_DETECTION BOOST_PREDEF_MAKE_10_VRR(__EDG_VERSION__) +#endif + +#ifdef BOOST_COMP_EDG_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_EDG_EMULATED BOOST_COMP_EDG_DETECTION +# else +# undef BOOST_COMP_EDG +# define BOOST_COMP_EDG BOOST_COMP_EDG_DETECTION +# endif +# define BOOST_COMP_EDG_AVAILABLE +# include +#endif + +#define BOOST_COMP_EDG_NAME "EDG C++ Frontend" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG,BOOST_COMP_EDG_NAME) + +#ifdef BOOST_COMP_EDG_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG_EMULATED,BOOST_COMP_EDG_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/ekopath.h b/thirdparty/linux/include/boost/predef/compiler/ekopath.h new file mode 100644 index 0000000..e5cde36 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/ekopath.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_EKOPATH_H +#define BOOST_PREDEF_COMPILER_EKOPATH_H + +#include +#include + +/*` +[heading `BOOST_COMP_PATH`] + +[@http://en.wikipedia.org/wiki/PathScale EKOpath] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__PATHCC__`] [__predef_detection__]] + + [[`__PATHCC__`, `__PATHCC_MINOR__`, `__PATHCC_PATCHLEVEL__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_PATH BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__PATHCC__) +# define BOOST_COMP_PATH_DETECTION \ + BOOST_VERSION_NUMBER(__PATHCC__,__PATHCC_MINOR__,__PATHCC_PATCHLEVEL__) +#endif + +#ifdef BOOST_COMP_PATH_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_PATH_EMULATED BOOST_COMP_PATH_DETECTION +# else +# undef BOOST_COMP_PATH +# define BOOST_COMP_PATH BOOST_COMP_PATH_DETECTION +# endif +# define BOOST_COMP_PATH_AVAILABLE +# include +#endif + +#define BOOST_COMP_PATH_NAME "EKOpath" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH,BOOST_COMP_PATH_NAME) + +#ifdef BOOST_COMP_PATH_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH_EMULATED,BOOST_COMP_PATH_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/gcc.h b/thirdparty/linux/include/boost/predef/compiler/gcc.h new file mode 100644 index 0000000..c2d7fff --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/gcc.h @@ -0,0 +1,68 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_GCC_H +#define BOOST_PREDEF_COMPILER_GCC_H + +/* Other compilers that emulate this one need to be detected first. */ + +#include + +#include +#include + +/*` +[heading `BOOST_COMP_GNUC`] + +[@http://en.wikipedia.org/wiki/GNU_Compiler_Collection Gnu GCC C/C++] compiler. +Version number available as major, minor, and patch (if available). + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__GNUC__`] [__predef_detection__]] + + [[`__GNUC__`, `__GNUC_MINOR__`, `__GNUC_PATCHLEVEL__`] [V.R.P]] + [[`__GNUC__`, `__GNUC_MINOR__`] [V.R.0]] + ] + */ + +#define BOOST_COMP_GNUC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GNUC__) +# if !defined(BOOST_COMP_GNUC_DETECTION) && defined(__GNUC_PATCHLEVEL__) +# define BOOST_COMP_GNUC_DETECTION \ + BOOST_VERSION_NUMBER(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +# endif +# if !defined(BOOST_COMP_GNUC_DETECTION) +# define BOOST_COMP_GNUC_DETECTION \ + BOOST_VERSION_NUMBER(__GNUC__,__GNUC_MINOR__,0) +# endif +#endif + +#ifdef BOOST_COMP_GNUC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_GNUC_EMULATED BOOST_COMP_GNUC_DETECTION +# else +# undef BOOST_COMP_GNUC +# define BOOST_COMP_GNUC BOOST_COMP_GNUC_DETECTION +# endif +# define BOOST_COMP_GNUC_AVAILABLE +# include +#endif + +#define BOOST_COMP_GNUC_NAME "Gnu GCC C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC,BOOST_COMP_GNUC_NAME) + +#ifdef BOOST_COMP_GNUC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC_EMULATED,BOOST_COMP_GNUC_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/gcc_xml.h b/thirdparty/linux/include/boost/predef/compiler/gcc_xml.h new file mode 100644 index 0000000..acae600 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/gcc_xml.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_GCC_XML_H +#define BOOST_PREDEF_COMPILER_GCC_XML_H + +#include +#include + +/*` +[heading `BOOST_COMP_GCCXML`] + +[@http://www.gccxml.org/ GCC XML] compiler. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__GCCXML__`] [__predef_detection__]] + ] + */ + +#define BOOST_COMP_GCCXML BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GCCXML__) +# define BOOST_COMP_GCCXML_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_GCCXML_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_GCCXML_EMULATED BOOST_COMP_GCCXML_DETECTION +# else +# undef BOOST_COMP_GCCXML +# define BOOST_COMP_GCCXML BOOST_COMP_GCCXML_DETECTION +# endif +# define BOOST_COMP_GCCXML_AVAILABLE +# include +#endif + +#define BOOST_COMP_GCCXML_NAME "GCC XML" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML,BOOST_COMP_GCCXML_NAME) + +#ifdef BOOST_COMP_GCCXML_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML_EMULATED,BOOST_COMP_GCCXML_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/greenhills.h b/thirdparty/linux/include/boost/predef/compiler/greenhills.h new file mode 100644 index 0000000..23b8f01 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/greenhills.h @@ -0,0 +1,66 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_GREENHILLS_H +#define BOOST_PREDEF_COMPILER_GREENHILLS_H + +#include +#include + +/*` +[heading `BOOST_COMP_GHS`] + +[@http://en.wikipedia.org/wiki/Green_Hills_Software Green Hills C/C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__ghs`] [__predef_detection__]] + [[`__ghs__`] [__predef_detection__]] + + [[`__GHS_VERSION_NUMBER__`] [V.R.P]] + [[`__ghs`] [V.R.P]] + ] + */ + +#define BOOST_COMP_GHS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__ghs) || defined(__ghs__) +# if !defined(BOOST_COMP_GHS_DETECTION) && defined(__GHS_VERSION_NUMBER__) +# define BOOST_COMP_GHS_DETECTION BOOST_PREDEF_MAKE_10_VRP(__GHS_VERSION_NUMBER__) +# endif +# if !defined(BOOST_COMP_GHS_DETECTION) && defined(__ghs) +# define BOOST_COMP_GHS_DETECTION BOOST_PREDEF_MAKE_10_VRP(__ghs) +# endif +# if !defined(BOOST_COMP_GHS_DETECTION) +# define BOOST_COMP_GHS_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_GHS_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_GHS_EMULATED BOOST_COMP_GHS_DETECTION +# else +# undef BOOST_COMP_GHS +# define BOOST_COMP_GHS BOOST_COMP_GHS_DETECTION +# endif +# define BOOST_COMP_GHS_AVAILABLE +# include +#endif + +#define BOOST_COMP_GHS_NAME "Green Hills C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS,BOOST_COMP_GHS_NAME) + +#ifdef BOOST_COMP_GHS_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS_EMULATED,BOOST_COMP_GHS_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/hp_acc.h b/thirdparty/linux/include/boost/predef/compiler/hp_acc.h new file mode 100644 index 0000000..7b3ffe9 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/hp_acc.h @@ -0,0 +1,61 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_HP_ACC_H +#define BOOST_PREDEF_COMPILER_HP_ACC_H + +#include +#include + +/*` +[heading `BOOST_COMP_HPACC`] + +HP aC++ compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__HP_aCC`] [__predef_detection__]] + + [[`__HP_aCC`] [V.R.P]] + ] + */ + +#define BOOST_COMP_HPACC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__HP_aCC) +# if !defined(BOOST_COMP_HPACC_DETECTION) && (__HP_aCC > 1) +# define BOOST_COMP_HPACC_DETECTION BOOST_PREDEF_MAKE_10_VVRRPP(__HP_aCC) +# endif +# if !defined(BOOST_COMP_HPACC_DETECTION) +# define BOOST_COMP_HPACC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_HPACC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_HPACC_EMULATED BOOST_COMP_HPACC_DETECTION +# else +# undef BOOST_COMP_HPACC +# define BOOST_COMP_HPACC BOOST_COMP_HPACC_DETECTION +# endif +# define BOOST_COMP_HPACC_AVAILABLE +# include +#endif + +#define BOOST_COMP_HPACC_NAME "HP aC++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC,BOOST_COMP_HPACC_NAME) + +#ifdef BOOST_COMP_HPACC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC_EMULATED,BOOST_COMP_HPACC_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/iar.h b/thirdparty/linux/include/boost/predef/compiler/iar.h new file mode 100644 index 0000000..237f492 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/iar.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_IAR_H +#define BOOST_PREDEF_COMPILER_IAR_H + +#include +#include + +/*` +[heading `BOOST_COMP_IAR`] + +IAR C/C++ compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__IAR_SYSTEMS_ICC__`] [__predef_detection__]] + + [[`__VER__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_IAR BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__IAR_SYSTEMS_ICC__) +# define BOOST_COMP_IAR_DETECTION BOOST_PREDEF_MAKE_10_VVRR(__VER__) +#endif + +#ifdef BOOST_COMP_IAR_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_IAR_EMULATED BOOST_COMP_IAR_DETECTION +# else +# undef BOOST_COMP_IAR +# define BOOST_COMP_IAR BOOST_COMP_IAR_DETECTION +# endif +# define BOOST_COMP_IAR_AVAILABLE +# include +#endif + +#define BOOST_COMP_IAR_NAME "IAR C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR,BOOST_COMP_IAR_NAME) + +#ifdef BOOST_COMP_IAR_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR_EMULATED,BOOST_COMP_IAR_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/ibm.h b/thirdparty/linux/include/boost/predef/compiler/ibm.h new file mode 100644 index 0000000..6931ebd --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/ibm.h @@ -0,0 +1,72 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_IBM_H +#define BOOST_PREDEF_COMPILER_IBM_H + +#include +#include + +/*` +[heading `BOOST_COMP_IBM`] + +[@http://en.wikipedia.org/wiki/VisualAge IBM XL C/C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__IBMCPP__`] [__predef_detection__]] + [[`__xlC__`] [__predef_detection__]] + [[`__xlc__`] [__predef_detection__]] + + [[`__COMPILER_VER__`] [V.R.P]] + [[`__xlC__`] [V.R.P]] + [[`__xlc__`] [V.R.P]] + [[`__IBMCPP__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_IBM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__IBMCPP__) || defined(__xlC__) || defined(__xlc__) +# if !defined(BOOST_COMP_IBM_DETECTION) && defined(__COMPILER_VER__) +# define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VRRPPPP(__COMPILER_VER__) +# endif +# if !defined(BOOST_COMP_IBM_DETECTION) && defined(__xlC__) +# define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__xlC__) +# endif +# if !defined(BOOST_COMP_IBM_DETECTION) && defined(__xlc__) +# define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__xlc__) +# endif +# if !defined(BOOST_COMP_IBM_DETECTION) +# define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_10_VRP(__IBMCPP__) +# endif +#endif + +#ifdef BOOST_COMP_IBM_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_IBM_EMULATED BOOST_COMP_IBM_DETECTION +# else +# undef BOOST_COMP_IBM +# define BOOST_COMP_IBM BOOST_COMP_IBM_DETECTION +# endif +# define BOOST_COMP_IBM_AVAILABLE +# include +#endif + +#define BOOST_COMP_IBM_NAME "IBM XL C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM,BOOST_COMP_IBM_NAME) + +#ifdef BOOST_COMP_IBM_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM_EMULATED,BOOST_COMP_IBM_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/intel.h b/thirdparty/linux/include/boost/predef/compiler/intel.h new file mode 100644 index 0000000..65bde67 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/intel.h @@ -0,0 +1,65 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_INTEL_H +#define BOOST_PREDEF_COMPILER_INTEL_H + +#include +#include + +/*` +[heading `BOOST_COMP_INTEL`] + +[@http://en.wikipedia.org/wiki/Intel_C%2B%2B Intel C/C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__INTEL_COMPILER`] [__predef_detection__]] + [[`__ICL`] [__predef_detection__]] + [[`__ICC`] [__predef_detection__]] + [[`__ECC`] [__predef_detection__]] + + [[`__INTEL_COMPILER`] [V.R.P]] + ] + */ + +#define BOOST_COMP_INTEL BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || \ + defined(__ECC) +# if !defined(BOOST_COMP_INTEL_DETECTION) && defined(__INTEL_COMPILER) +# define BOOST_COMP_INTEL_DETECTION BOOST_PREDEF_MAKE_10_VRP(__INTEL_COMPILER) +# endif +# if !defined(BOOST_COMP_INTEL_DETECTION) +# define BOOST_COMP_INTEL_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_INTEL_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_INTEL_EMULATED BOOST_COMP_INTEL_DETECTION +# else +# undef BOOST_COMP_INTEL +# define BOOST_COMP_INTEL BOOST_COMP_INTEL_DETECTION +# endif +# define BOOST_COMP_INTEL_AVAILABLE +# include +#endif + +#define BOOST_COMP_INTEL_NAME "Intel C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL,BOOST_COMP_INTEL_NAME) + +#ifdef BOOST_COMP_INTEL_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL_EMULATED,BOOST_COMP_INTEL_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/kai.h b/thirdparty/linux/include/boost/predef/compiler/kai.h new file mode 100644 index 0000000..68ce84e --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/kai.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_KAI_H +#define BOOST_PREDEF_COMPILER_KAI_H + +#include +#include + +/*` +[heading `BOOST_COMP_KCC`] + +Kai C++ compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__KCC`] [__predef_detection__]] + + [[`__KCC_VERSION`] [V.R.P]] + ] + */ + +#define BOOST_COMP_KCC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__KCC) +# define BOOST_COMP_KCC_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__KCC_VERSION) +#endif + +#ifdef BOOST_COMP_KCC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_KCC_EMULATED BOOST_COMP_KCC_DETECTION +# else +# undef BOOST_COMP_KCC +# define BOOST_COMP_KCC BOOST_COMP_KCC_DETECTION +# endif +# define BOOST_COMP_KCC_AVAILABLE +# include +#endif + +#define BOOST_COMP_KCC_NAME "Kai C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC,BOOST_COMP_KCC_NAME) + +#ifdef BOOST_COMP_KCC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC_EMULATED,BOOST_COMP_KCC_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/llvm.h b/thirdparty/linux/include/boost/predef/compiler/llvm.h new file mode 100644 index 0000000..de654eb --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/llvm.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_LLVM_H +#define BOOST_PREDEF_COMPILER_LLVM_H + +/* Other compilers that emulate this one need to be detected first. */ + +#include + +#include +#include + +/*` +[heading `BOOST_COMP_LLVM`] + +[@http://en.wikipedia.org/wiki/LLVM LLVM] compiler. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__llvm__`] [__predef_detection__]] + ] + */ + +#define BOOST_COMP_LLVM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__llvm__) +# define BOOST_COMP_LLVM_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_LLVM_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_LLVM_EMULATED BOOST_COMP_LLVM_DETECTION +# else +# undef BOOST_COMP_LLVM +# define BOOST_COMP_LLVM BOOST_COMP_LLVM_DETECTION +# endif +# define BOOST_COMP_LLVM_AVAILABLE +# include +#endif + +#define BOOST_COMP_LLVM_NAME "LLVM" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM,BOOST_COMP_LLVM_NAME) + +#ifdef BOOST_COMP_LLVM_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM_EMULATED,BOOST_COMP_LLVM_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/metaware.h b/thirdparty/linux/include/boost/predef/compiler/metaware.h new file mode 100644 index 0000000..1a32039 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/metaware.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_METAWARE_H +#define BOOST_PREDEF_COMPILER_METAWARE_H + +#include +#include + +/*` +[heading `BOOST_COMP_HIGHC`] + +MetaWare High C/C++ compiler. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__HIGHC__`] [__predef_detection__]] + ] + */ + +#define BOOST_COMP_HIGHC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__HIGHC__) +# define BOOST_COMP_HIGHC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_HIGHC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_HIGHC_EMULATED BOOST_COMP_HIGHC_DETECTION +# else +# undef BOOST_COMP_HIGHC +# define BOOST_COMP_HIGHC BOOST_COMP_HIGHC_DETECTION +# endif +# define BOOST_COMP_HIGHC_AVAILABLE +# include +#endif + +#define BOOST_COMP_HIGHC_NAME "MetaWare High C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC,BOOST_COMP_HIGHC_NAME) + +#ifdef BOOST_COMP_HIGHC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC_EMULATED,BOOST_COMP_HIGHC_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/metrowerks.h b/thirdparty/linux/include/boost/predef/compiler/metrowerks.h new file mode 100644 index 0000000..f2d739b --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/metrowerks.h @@ -0,0 +1,77 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_METROWERKS_H +#define BOOST_PREDEF_COMPILER_METROWERKS_H + +#include +#include + +/*` +[heading `BOOST_COMP_MWERKS`] + +[@http://en.wikipedia.org/wiki/CodeWarrior Metrowerks CodeWarrior] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__MWERKS__`] [__predef_detection__]] + [[`__CWCC__`] [__predef_detection__]] + + [[`__CWCC__`] [V.R.P]] + [[`__MWERKS__`] [V.R.P >= 4.2.0]] + [[`__MWERKS__`] [9.R.0]] + [[`__MWERKS__`] [8.R.0]] + ] + */ + +#define BOOST_COMP_MWERKS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MWERKS__) || defined(__CWCC__) +# if !defined(BOOST_COMP_MWERKS_DETECTION) && defined(__CWCC__) +# define BOOST_COMP_MWERKS_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__CWCC__) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x4200) +# define BOOST_COMP_MWERKS_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__MWERKS__) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3204) // note the "skip": 04->9.3 +# define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(9,(__MWERKS__)%100-1,0) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3200) +# define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(9,(__MWERKS__)%100,0) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3000) +# define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(8,(__MWERKS__)%100,0) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) +# define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_MWERKS_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_MWERKS_EMULATED BOOST_COMP_MWERKS_DETECTION +# else +# undef BOOST_COMP_MWERKS +# define BOOST_COMP_MWERKS BOOST_COMP_MWERKS_DETECTION +# endif +# define BOOST_COMP_MWERKS_AVAILABLE +# include +#endif + +#define BOOST_COMP_MWERKS_NAME "Metrowerks CodeWarrior" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS,BOOST_COMP_MWERKS_NAME) + +#ifdef BOOST_COMP_MWERKS_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS_EMULATED,BOOST_COMP_MWERKS_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/microtec.h b/thirdparty/linux/include/boost/predef/compiler/microtec.h new file mode 100644 index 0000000..066a6d2 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/microtec.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_MICROTEC_H +#define BOOST_PREDEF_COMPILER_MICROTEC_H + +#include +#include + +/*` +[heading `BOOST_COMP_MRI`] + +[@http://www.mentor.com/microtec/ Microtec C/C++] compiler. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_MRI`] [__predef_detection__]] + ] + */ + +#define BOOST_COMP_MRI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_MRI) +# define BOOST_COMP_MRI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_MRI_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_MRI_EMULATED BOOST_COMP_MRI_DETECTION +# else +# undef BOOST_COMP_MRI +# define BOOST_COMP_MRI BOOST_COMP_MRI_DETECTION +# endif +# define BOOST_COMP_MRI_AVAILABLE +# include +#endif + +#define BOOST_COMP_MRI_NAME "Microtec C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI,BOOST_COMP_MRI_NAME) + +#ifdef BOOST_COMP_MRI_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI_EMULATED,BOOST_COMP_MRI_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/mpw.h b/thirdparty/linux/include/boost/predef/compiler/mpw.h new file mode 100644 index 0000000..1183306 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/mpw.h @@ -0,0 +1,63 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_MPW_H +#define BOOST_PREDEF_COMPILER_MPW_H + +#include +#include + +/*` +[heading `BOOST_COMP_MPW`] + +[@http://en.wikipedia.org/wiki/Macintosh_Programmer%27s_Workshop MPW C++] compiler. +Version number available as major, and minor. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__MRC__`] [__predef_detection__]] + [[`MPW_C`] [__predef_detection__]] + [[`MPW_CPLUS`] [__predef_detection__]] + + [[`__MRC__`] [V.R.0]] + ] + */ + +#define BOOST_COMP_MPW BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MRC__) || defined(MPW_C) || defined(MPW_CPLUS) +# if !defined(BOOST_COMP_MPW_DETECTION) && defined(__MRC__) +# define BOOST_COMP_MPW_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__MRC__) +# endif +# if !defined(BOOST_COMP_MPW_DETECTION) +# define BOOST_COMP_MPW_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_MPW_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_MPW_EMULATED BOOST_COMP_MPW_DETECTION +# else +# undef BOOST_COMP_MPW +# define BOOST_COMP_MPW BOOST_COMP_MPW_DETECTION +# endif +# define BOOST_COMP_MPW_AVAILABLE +# include +#endif + +#define BOOST_COMP_MPW_NAME "MPW C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW,BOOST_COMP_MPW_NAME) + +#ifdef BOOST_COMP_MPW_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW_EMULATED,BOOST_COMP_MPW_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/palm.h b/thirdparty/linux/include/boost/predef/compiler/palm.h new file mode 100644 index 0000000..707925a --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/palm.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_PALM_H +#define BOOST_PREDEF_COMPILER_PALM_H + +#include +#include + +/*` +[heading `BOOST_COMP_PALM`] + +Palm C/C++ compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_PACC_VER`] [__predef_detection__]] + + [[`_PACC_VER`] [V.R.P]] + ] + */ + +#define BOOST_COMP_PALM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_PACC_VER) +# define BOOST_COMP_PALM_DETECTION BOOST_PREDEF_MAKE_0X_VRRPP000(_PACC_VER) +#endif + +#ifdef BOOST_COMP_PALM_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_PALM_EMULATED BOOST_COMP_PALM_DETECTION +# else +# undef BOOST_COMP_PALM +# define BOOST_COMP_PALM BOOST_COMP_PALM_DETECTION +# endif +# define BOOST_COMP_PALM_AVAILABLE +# include +#endif + +#define BOOST_COMP_PALM_NAME "Palm C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM,BOOST_COMP_PALM_NAME) + +#ifdef BOOST_COMP_PALM_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM_EMULATED,BOOST_COMP_PALM_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/pgi.h b/thirdparty/linux/include/boost/predef/compiler/pgi.h new file mode 100644 index 0000000..e016aeb --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/pgi.h @@ -0,0 +1,60 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_PGI_H +#define BOOST_PREDEF_COMPILER_PGI_H + +#include +#include + +/*` +[heading `BOOST_COMP_PGI`] + +[@http://en.wikipedia.org/wiki/The_Portland_Group Portland Group C/C++] compiler. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__PGI`] [__predef_detection__]] + + [[`__PGIC__`, `__PGIC_MINOR__`, `__PGIC_PATCHLEVEL__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_PGI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__PGI) +# if !defined(BOOST_COMP_PGI_DETECTION) && (defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)) +# define BOOST_COMP_PGI_DETECTION BOOST_VERSION_NUMBER(__PGIC__,__PGIC_MINOR__,__PGIC_PATCHLEVEL__) +# endif +# if !defined(BOOST_COMP_PGI_DETECTION) +# define BOOST_COMP_PGI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_PGI_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_PGI_EMULATED BOOST_COMP_PGI_DETECTION +# else +# undef BOOST_COMP_PGI +# define BOOST_COMP_PGI BOOST_COMP_PGI_DETECTION +# endif +# define BOOST_COMP_PGI_AVAILABLE +# include +#endif + +#define BOOST_COMP_PGI_NAME "Portland Group C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI,BOOST_COMP_PGI_NAME) + +#ifdef BOOST_COMP_PGI_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI_EMULATED,BOOST_COMP_PGI_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/sgi_mipspro.h b/thirdparty/linux/include/boost/predef/compiler/sgi_mipspro.h new file mode 100644 index 0000000..00739f0 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/sgi_mipspro.h @@ -0,0 +1,66 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_SGI_MIPSPRO_H +#define BOOST_PREDEF_COMPILER_SGI_MIPSPRO_H + +#include +#include + +/*` +[heading `BOOST_COMP_SGI`] + +[@http://en.wikipedia.org/wiki/MIPSpro SGI MIPSpro] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__sgi`] [__predef_detection__]] + [[`sgi`] [__predef_detection__]] + + [[`_SGI_COMPILER_VERSION`] [V.R.P]] + [[`_COMPILER_VERSION`] [V.R.P]] + ] + */ + +#define BOOST_COMP_SGI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sgi) || defined(sgi) +# if !defined(BOOST_COMP_SGI_DETECTION) && defined(_SGI_COMPILER_VERSION) +# define BOOST_COMP_SGI_DETECTION BOOST_PREDEF_MAKE_10_VRP(_SGI_COMPILER_VERSION) +# endif +# if !defined(BOOST_COMP_SGI_DETECTION) && defined(_COMPILER_VERSION) +# define BOOST_COMP_SGI_DETECTION BOOST_PREDEF_MAKE_10_VRP(_COMPILER_VERSION) +# endif +# if !defined(BOOST_COMP_SGI_DETECTION) +# define BOOST_COMP_SGI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_SGI_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_SGI_EMULATED BOOST_COMP_SGI_DETECTION +# else +# undef BOOST_COMP_SGI +# define BOOST_COMP_SGI BOOST_COMP_SGI_DETECTION +# endif +# define BOOST_COMP_SGI_AVAILABLE +# include +#endif + +#define BOOST_COMP_SGI_NAME "SGI MIPSpro" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI,BOOST_COMP_SGI_NAME) + +#ifdef BOOST_COMP_SGI_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI_EMULATED,BOOST_COMP_SGI_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/sunpro.h b/thirdparty/linux/include/boost/predef/compiler/sunpro.h new file mode 100644 index 0000000..92c3926 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/sunpro.h @@ -0,0 +1,76 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_SUNPRO_H +#define BOOST_PREDEF_COMPILER_SUNPRO_H + +#include +#include + +/*` +[heading `BOOST_COMP_SUNPRO`] + +[@http://en.wikipedia.org/wiki/Oracle_Solaris_Studio Oracle Solaris Studio] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__SUNPRO_CC`] [__predef_detection__]] + [[`__SUNPRO_C`] [__predef_detection__]] + + [[`__SUNPRO_CC`] [V.R.P]] + [[`__SUNPRO_C`] [V.R.P]] + [[`__SUNPRO_CC`] [VV.RR.P]] + [[`__SUNPRO_C`] [VV.RR.P]] + ] + */ + +#define BOOST_COMP_SUNPRO BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SUNPRO_CC) || defined(__SUNPRO_C) +# if !defined(BOOST_COMP_SUNPRO_DETECTION) && defined(__SUNPRO_CC) +# if (__SUNPRO_CC < 0x5100) +# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_CC) +# else +# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VVRRP(__SUNPRO_CC) +# endif +# endif +# if !defined(BOOST_COMP_SUNPRO_DETECTION) && defined(__SUNPRO_C) +# if (__SUNPRO_C < 0x5100) +# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_C) +# else +# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VVRRP(__SUNPRO_C) +# endif +# endif +# if !defined(BOOST_COMP_SUNPRO_DETECTION) +# define BOOST_COMP_SUNPRO_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_SUNPRO_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_SUNPRO_EMULATED BOOST_COMP_SUNPRO_DETECTION +# else +# undef BOOST_COMP_SUNPRO +# define BOOST_COMP_SUNPRO BOOST_COMP_SUNPRO_DETECTION +# endif +# define BOOST_COMP_SUNPRO_AVAILABLE +# include +#endif + +#define BOOST_COMP_SUNPRO_NAME "Oracle Solaris Studio" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO,BOOST_COMP_SUNPRO_NAME) + +#ifdef BOOST_COMP_SUNPRO_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO_EMULATED,BOOST_COMP_SUNPRO_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/tendra.h b/thirdparty/linux/include/boost/predef/compiler/tendra.h new file mode 100644 index 0000000..c2bc5e4 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/tendra.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_TENDRA_H +#define BOOST_PREDEF_COMPILER_TENDRA_H + +#include +#include + +/*` +[heading `BOOST_COMP_TENDRA`] + +[@http://en.wikipedia.org/wiki/TenDRA_Compiler TenDRA C/C++] compiler. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__TenDRA__`] [__predef_detection__]] + ] + */ + +#define BOOST_COMP_TENDRA BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__TenDRA__) +# define BOOST_COMP_TENDRA_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_TENDRA_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_TENDRA_EMULATED BOOST_COMP_TENDRA_DETECTION +# else +# undef BOOST_COMP_TENDRA +# define BOOST_COMP_TENDRA BOOST_COMP_TENDRA_DETECTION +# endif +# define BOOST_COMP_TENDRA_AVAILABLE +# include +#endif + +#define BOOST_COMP_TENDRA_NAME "TenDRA C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA,BOOST_COMP_TENDRA_NAME) + +#ifdef BOOST_COMP_TENDRA_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA_EMULATED,BOOST_COMP_TENDRA_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/visualc.h b/thirdparty/linux/include/boost/predef/compiler/visualc.h new file mode 100644 index 0000000..9481d9d --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/visualc.h @@ -0,0 +1,91 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_VISUALC_H +#define BOOST_PREDEF_COMPILER_VISUALC_H + +/* Other compilers that emulate this one need to be detected first. */ + +#include + +#include +#include + +/*` +[heading `BOOST_COMP_MSVC`] + +[@http://en.wikipedia.org/wiki/Visual_studio Microsoft Visual C/C++] compiler. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_MSC_VER`] [__predef_detection__]] + + [[`_MSC_FULL_VER`] [V.R.P]] + [[`_MSC_VER`] [V.R.0]] + ] + */ + +#define BOOST_COMP_MSVC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_MSC_VER) +# if !defined (_MSC_FULL_VER) +# define BOOST_COMP_MSVC_BUILD 0 +# else + /* how many digits does the build number have? */ +# if _MSC_FULL_VER / 10000 == _MSC_VER + /* four digits */ +# define BOOST_COMP_MSVC_BUILD (_MSC_FULL_VER % 10000) +# elif _MSC_FULL_VER / 100000 == _MSC_VER + /* five digits */ +# define BOOST_COMP_MSVC_BUILD (_MSC_FULL_VER % 100000) +# else +# error "Cannot determine build number from _MSC_FULL_VER" +# endif +# endif + /* + VS2014 was skipped in the release sequence for MS. Which + means that the compiler and VS product versions are no longer + in sync. Hence we need to use different formulas for + mapping from MSC version to VS product version. + */ +# if (_MSC_VER >= 1900) +# define BOOST_COMP_MSVC_DETECTION BOOST_VERSION_NUMBER(\ + _MSC_VER/100-5,\ + _MSC_VER%100,\ + BOOST_COMP_MSVC_BUILD) +# else +# define BOOST_COMP_MSVC_DETECTION BOOST_VERSION_NUMBER(\ + _MSC_VER/100-6,\ + _MSC_VER%100,\ + BOOST_COMP_MSVC_BUILD) +# endif +#endif + +#ifdef BOOST_COMP_MSVC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_MSVC_EMULATED BOOST_COMP_MSVC_DETECTION +# else +# undef BOOST_COMP_MSVC +# define BOOST_COMP_MSVC BOOST_COMP_MSVC_DETECTION +# endif +# define BOOST_COMP_MSVC_AVAILABLE +# include +#endif + +#define BOOST_COMP_MSVC_NAME "Microsoft Visual C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC,BOOST_COMP_MSVC_NAME) + +#ifdef BOOST_COMP_MSVC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC_EMULATED,BOOST_COMP_MSVC_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/compiler/watcom.h b/thirdparty/linux/include/boost/predef/compiler/watcom.h new file mode 100644 index 0000000..b0e7776 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/compiler/watcom.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_WATCOM_H +#define BOOST_PREDEF_COMPILER_WATCOM_H + +#include +#include + +/*` +[heading `BOOST_COMP_WATCOM`] + +[@http://en.wikipedia.org/wiki/Watcom Watcom C++] compiler. +Version number available as major, and minor. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__WATCOMC__`] [__predef_detection__]] + + [[`__WATCOMC__`] [V.R.P]] + ] + */ + +#define BOOST_COMP_WATCOM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__WATCOMC__) +# define BOOST_COMP_WATCOM_DETECTION BOOST_PREDEF_MAKE_10_VVRR(__WATCOMC__) +#endif + +#ifdef BOOST_COMP_WATCOM_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_WATCOM_EMULATED BOOST_COMP_WATCOM_DETECTION +# else +# undef BOOST_COMP_WATCOM +# define BOOST_COMP_WATCOM BOOST_COMP_WATCOM_DETECTION +# endif +# define BOOST_COMP_WATCOM_AVAILABLE +# include +#endif + +#define BOOST_COMP_WATCOM_NAME "Watcom C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM,BOOST_COMP_WATCOM_NAME) + +#ifdef BOOST_COMP_WATCOM_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM_EMULATED,BOOST_COMP_WATCOM_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/detail/_cassert.h b/thirdparty/linux/include/boost/predef/detail/_cassert.h new file mode 100644 index 0000000..940e944 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/detail/_cassert.h @@ -0,0 +1,17 @@ +/* +Copyright Rene Rivera 2011-2012 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_DETAIL__CASSERT_H +#define BOOST_PREDEF_DETAIL__CASSERT_H + +#if defined(__cplusplus) +#include +#else +#include +#endif + +#endif diff --git a/thirdparty/linux/include/boost/predef/detail/_exception.h b/thirdparty/linux/include/boost/predef/detail/_exception.h new file mode 100644 index 0000000..f5a6687 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/detail/_exception.h @@ -0,0 +1,15 @@ +/* +Copyright Rene Rivera 2011-2012 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_DETAIL__EXCEPTION_H +#define BOOST_PREDEF_DETAIL__EXCEPTION_H + +#if defined(__cplusplus) +#include +#endif + +#endif diff --git a/thirdparty/linux/include/boost/predef/detail/comp_detected.h b/thirdparty/linux/include/boost/predef/detail/comp_detected.h new file mode 100644 index 0000000..fda1801 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/detail/comp_detected.h @@ -0,0 +1,10 @@ +/* +Copyright Rene Rivera 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_DETAIL_COMP_DETECTED +#define BOOST_PREDEF_DETAIL_COMP_DETECTED 1 +#endif diff --git a/thirdparty/linux/include/boost/predef/detail/os_detected.h b/thirdparty/linux/include/boost/predef/detail/os_detected.h new file mode 100644 index 0000000..08e10f9 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/detail/os_detected.h @@ -0,0 +1,10 @@ +/* +Copyright Rene Rivera 2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_DETAIL_OS_DETECTED +#define BOOST_PREDEF_DETAIL_OS_DETECTED 1 +#endif diff --git a/thirdparty/linux/include/boost/predef/detail/platform_detected.h b/thirdparty/linux/include/boost/predef/detail/platform_detected.h new file mode 100644 index 0000000..4faf693 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/detail/platform_detected.h @@ -0,0 +1,10 @@ +/* +Copyright Rene Rivera 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_DETAIL_PLAT_DETECTED +#define BOOST_PREDEF_DETAIL_PLAT_DETECTED 1 +#endif diff --git a/thirdparty/linux/include/boost/predef/detail/test.h b/thirdparty/linux/include/boost/predef/detail/test.h new file mode 100644 index 0000000..546a9e4 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/detail/test.h @@ -0,0 +1,17 @@ +/* +Copyright Rene Rivera 2011-2012 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_DETAIL_TEST_H +#define BOOST_PREDEF_DETAIL_TEST_H + +#if !defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) + +#define BOOST_PREDEF_DECLARE_TEST(x,s) + +#endif + +#endif diff --git a/thirdparty/linux/include/boost/predef/hardware.h b/thirdparty/linux/include/boost/predef/hardware.h new file mode 100644 index 0000000..972b73a --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware.h @@ -0,0 +1,16 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_HARDWARE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_HARDWARE_H +#define BOOST_PREDEF_HARDWARE_H +#endif + +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/hardware/simd.h b/thirdparty/linux/include/boost/predef/hardware/simd.h new file mode 100644 index 0000000..ac5c9da --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd.h @@ -0,0 +1,119 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#include +#include +#include +#include + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_H +#define BOOST_PREDEF_HARDWARE_SIMD_H + +#include + +/*` + [section Using the `BOOST_HW_SIMD_*` predefs] + [include ../doc/hardware_simd.qbk] + [endsect] + + [/ --------------------------- ] + + [section `BOOST_HW_SIMD_*`] + + [heading `BOOST_HW_SIMD`] + + The SIMD extension detected for a specific architectures. + Version number depends on the detected extension. + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`BOOST_HW_SIMD_X86_AVAILABLE`] [__predef_detection__]] + [[`BOOST_HW_SIMD_X86_AMD_AVAILABLE`] [__predef_detection__]] + [[`BOOST_HW_SIMD_ARM_AVAILABLE`] [__predef_detection__]] + [[`BOOST_HW_SIMD_PPC_AVAILABLE`] [__predef_detection__]] + ] + + [include ../include/boost/predef/hardware/simd/x86.h] + [include ../include/boost/predef/hardware/simd/x86_amd.h] + [include ../include/boost/predef/hardware/simd/arm.h] + [include ../include/boost/predef/hardware/simd/ppc.h] + + [endsect] + + [/ --------------------------- ] + + [section `BOOST_HW_SIMD_X86_*_VERSION`] + [include ../include/boost/predef/hardware/simd/x86/versions.h] + [endsect] + + [section `BOOST_HW_SIMD_X86_AMD_*_VERSION`] + [include ../include/boost/predef/hardware/simd/x86_amd/versions.h] + [endsect] + + [section `BOOST_HW_SIMD_ARM_*_VERSION`] + [include ../include/boost/predef/hardware/simd/arm/versions.h] + [endsect] + + [section `BOOST_HW_SIMD_PPC_*_VERSION`] + [include ../include/boost/predef/hardware/simd/ppc/versions.h] + [endsect] + + */ + +// We check if SIMD extension of multiples architectures have been detected, +// if yes, then this is an error! +// +// NOTE: _X86_AMD implies _X86, so there is no need to check for it here! +// +#if defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_PPC_AVAILABLE) ||\ + defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE) ||\ + defined(BOOST_HW_SIMD_PPC_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE) +# error "Multiple SIMD architectures detected, this cannot happen!" +#endif + +#if defined(BOOST_HW_SIMD_X86_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE) + // If both standard _X86 and _X86_AMD are available, + // then take the biggest version of the two! +# if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_AMD +# define BOOST_HW_SIMD BOOST_HW_SIMD_X86 +# else +# define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD +# endif +#endif + +#if !defined(BOOST_HW_SIMD) + // At this point, only one of these two is defined +# if defined(BOOST_HW_SIMD_X86_AVAILABLE) +# define BOOST_HW_SIMD BOOST_HW_SIMD_X86 +# endif +# if defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE) +# define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD +# endif +#endif + +#if defined(BOOST_HW_SIMD_ARM_AVAILABLE) +# define BOOST_HW_SIMD BOOST_HW_SIMD_ARM +#endif + +#if defined(BOOST_HW_SIMD_PPC_AVAILABLE) +# define BOOST_HW_SIMD BOOST_HW_SIMD_PPC +#endif + +#if defined(BOOST_HW_SIMD) +# define BOOST_HW_SIMD_AVAILABLE +#else +# define BOOST_HW_SIMD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#endif + +#define BOOST_HW_SIMD_NAME "Hardware SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD, BOOST_HW_SIMD_NAME) diff --git a/thirdparty/linux/include/boost/predef/hardware/simd/arm.h b/thirdparty/linux/include/boost/predef/hardware/simd/arm.h new file mode 100644 index 0000000..d067c93 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd/arm.h @@ -0,0 +1,57 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_ARM_H +#define BOOST_PREDEF_HARDWARE_SIMD_ARM_H + +#include +#include + +/*` + [heading `BOOST_HW_SIMD_ARM`] + + The SIMD extension for ARM (*if detected*). + Version number depends on the most recent detected extension. + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`__ARM_NEON__`] [__predef_detection__]] + [[`__aarch64__`] [__predef_detection__]] + [[`_M_ARM`] [__predef_detection__]] + ] + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`__ARM_NEON__`] [BOOST_HW_SIMD_ARM_NEON_VERSION]] + [[`__aarch64__`] [BOOST_HW_SIMD_ARM_NEON_VERSION]] + [[`_M_ARM`] [BOOST_HW_SIMD_ARM_NEON_VERSION]] + ] + + */ + +#define BOOST_HW_SIMD_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#undef BOOST_HW_SIMD_ARM +#if !defined(BOOST_HW_SIMD_ARM) && (defined(__ARM_NEON__) || defined(__aarch64__) || defined (_M_ARM)) +# define BOOST_HW_SIMD_ARM BOOST_HW_SIMD_ARM_NEON_VERSION +#endif + +#if !defined(BOOST_HW_SIMD_ARM) +# define BOOST_HW_SIMD_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE +#else +# define BOOST_HW_SIMD_ARM_AVAILABLE +#endif + +#define BOOST_HW_SIMD_ARM_NAME "ARM SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_ARM, BOOST_HW_SIMD_ARM_NAME) diff --git a/thirdparty/linux/include/boost/predef/hardware/simd/arm/versions.h b/thirdparty/linux/include/boost/predef/hardware/simd/arm/versions.h new file mode 100644 index 0000000..8425b31 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd/arm/versions.h @@ -0,0 +1,32 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_ARM_VERSIONS_H +#define BOOST_PREDEF_HARDWARE_SIMD_ARM_VERSIONS_H + +#include + +/*` + Those defines represent ARM SIMD extensions versions. + + [note You *MUST* compare them with the predef `BOOST_HW_SIMD_ARM`.] + */ + +// --------------------------------- + +/*` + [heading `BOOST_HW_SIMD_ARM_NEON_VERSION`] + + The [@https://en.wikipedia.org/wiki/ARM_architecture#Advanced_SIMD_.28NEON.29 NEON] + ARM extension version number. + + Version number is: *1.0.0*. + */ +#define BOOST_HW_SIMD_ARM_NEON_VERSION BOOST_VERSION_NUMBER(1, 0, 0) + +#endif diff --git a/thirdparty/linux/include/boost/predef/hardware/simd/ppc.h b/thirdparty/linux/include/boost/predef/hardware/simd/ppc.h new file mode 100644 index 0000000..eef25c2 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd/ppc.h @@ -0,0 +1,69 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_PPC_H +#define BOOST_PREDEF_HARDWARE_SIMD_PPC_H + +#include +#include + +/*` + [heading `BOOST_HW_SIMD_PPC`] + + The SIMD extension for PowerPC (*if detected*). + Version number depends on the most recent detected extension. + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`__VECTOR4DOUBLE__`] [__predef_detection__]] + + [[`__ALTIVEC__`] [__predef_detection__]] + [[`__VEC__`] [__predef_detection__]] + + [[`__VSX__`] [__predef_detection__]] + ] + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`__VECTOR4DOUBLE__`] [BOOST_HW_SIMD_PPC_QPX_VERSION]] + + [[`__ALTIVEC__`] [BOOST_HW_SIMD_PPC_VMX_VERSION]] + [[`__VEC__`] [BOOST_HW_SIMD_PPC_VMX_VERSION]] + + [[`__VSX__`] [BOOST_HW_SIMD_PPC_VSX_VERSION]] + ] + + */ + +#define BOOST_HW_SIMD_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#undef BOOST_HW_SIMD_PPC +#if !defined(BOOST_HW_SIMD_PPC) && defined(__VECTOR4DOUBLE__) +# define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_QPX_VERSION +#endif +#if !defined(BOOST_HW_SIMD_PPC) && defined(__VSX__) +# define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_VSX_VERSION +#endif +#if !defined(BOOST_HW_SIMD_PPC) && (defined(__ALTIVEC__) || defined(__VEC__)) +# define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_VMX_VERSION +#endif + +#if !defined(BOOST_HW_SIMD_PPC) +# define BOOST_HW_SIMD_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE +#else +# define BOOST_HW_SIMD_PPC_AVAILABLE +#endif + +#define BOOST_HW_SIMD_PPC_NAME "PPC SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_PPC, BOOST_HW_SIMD_PPC_NAME) diff --git a/thirdparty/linux/include/boost/predef/hardware/simd/ppc/versions.h b/thirdparty/linux/include/boost/predef/hardware/simd/ppc/versions.h new file mode 100644 index 0000000..ffe3f0b --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd/ppc/versions.h @@ -0,0 +1,51 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_PPC_VERSIONS_H +#define BOOST_PREDEF_HARDWARE_SIMD_PPC_VERSIONS_H + +#include + +/*` + Those defines represent Power PC SIMD extensions versions. + + [note You *MUST* compare them with the predef `BOOST_HW_SIMD_PPC`.] + */ + +// --------------------------------- + +/*` + [heading `BOOST_HW_SIMD_PPC_VMX_VERSION`] + + The [@https://en.wikipedia.org/wiki/AltiVec#VMX128 VMX] powerpc extension + version number. + + Version number is: *1.0.0*. + */ +#define BOOST_HW_SIMD_PPC_VMX_VERSION BOOST_VERSION_NUMBER(1, 0, 0) + +/*` + [heading `BOOST_HW_SIMD_PPC_VSX_VERSION`] + + The [@https://en.wikipedia.org/wiki/AltiVec#VSX VSX] powerpc extension version + number. + + Version number is: *1.1.0*. + */ +#define BOOST_HW_SIMD_PPC_VSX_VERSION BOOST_VERSION_NUMBER(1, 1, 0) + +/*` + [heading `BOOST_HW_SIMD_PPC_QPX_VERSION`] + + The QPX powerpc extension version number. + + Version number is: *2.0.0*. + */ +#define BOOST_HW_SIMD_PPC_QPX_VERSION BOOST_VERSION_NUMBER(2, 0, 0) + +#endif diff --git a/thirdparty/linux/include/boost/predef/hardware/simd/x86.h b/thirdparty/linux/include/boost/predef/hardware/simd/x86.h new file mode 100644 index 0000000..88bd81e --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd/x86.h @@ -0,0 +1,123 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_H +#define BOOST_PREDEF_HARDWARE_SIMD_X86_H + +#include +#include + +/*` + [heading `BOOST_HW_SIMD_X86`] + + The SIMD extension for x86 (*if detected*). + Version number depends on the most recent detected extension. + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`__SSE__`] [__predef_detection__]] + [[`_M_X64`] [__predef_detection__]] + [[`_M_IX86_FP >= 1`] [__predef_detection__]] + + [[`__SSE2__`] [__predef_detection__]] + [[`_M_X64`] [__predef_detection__]] + [[`_M_IX86_FP >= 2`] [__predef_detection__]] + + [[`__SSE3__`] [__predef_detection__]] + + [[`__SSSE3__`] [__predef_detection__]] + + [[`__SSE4_1__`] [__predef_detection__]] + + [[`__SSE4_2__`] [__predef_detection__]] + + [[`__AVX__`] [__predef_detection__]] + + [[`__FMA__`] [__predef_detection__]] + + [[`__AVX2__`] [__predef_detection__]] + ] + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`__SSE__`] [BOOST_HW_SIMD_X86_SSE_VERSION]] + [[`_M_X64`] [BOOST_HW_SIMD_X86_SSE_VERSION]] + [[`_M_IX86_FP >= 1`] [BOOST_HW_SIMD_X86_SSE_VERSION]] + + [[`__SSE2__`] [BOOST_HW_SIMD_X86_SSE2_VERSION]] + [[`_M_X64`] [BOOST_HW_SIMD_X86_SSE2_VERSION]] + [[`_M_IX86_FP >= 2`] [BOOST_HW_SIMD_X86_SSE2_VERSION]] + + [[`__SSE3__`] [BOOST_HW_SIMD_X86_SSE3_VERSION]] + + [[`__SSSE3__`] [BOOST_HW_SIMD_X86_SSSE3_VERSION]] + + [[`__SSE4_1__`] [BOOST_HW_SIMD_X86_SSE4_1_VERSION]] + + [[`__SSE4_2__`] [BOOST_HW_SIMD_X86_SSE4_2_VERSION]] + + [[`__AVX__`] [BOOST_HW_SIMD_X86_AVX_VERSION]] + + [[`__FMA__`] [BOOST_HW_SIMD_X86_FMA3_VERSION]] + + [[`__AVX2__`] [BOOST_HW_SIMD_X86_AVX2_VERSION]] + ] + + */ + +#define BOOST_HW_SIMD_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#undef BOOST_HW_SIMD_X86 +#if !defined(BOOST_HW_SIMD_X86) && defined(__MIC__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_MIC_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__AVX2__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_AVX2_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__AVX__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_AVX_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__FMA__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_FMA_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE4_2__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE4_2_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE4_1__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE4_1_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__SSSE3__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSSE3_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE3__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE3_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE2_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && (defined(__SSE__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__MMX__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_MMX_VERSION +#endif + +#if !defined(BOOST_HW_SIMD_X86) +# define BOOST_HW_SIMD_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE +#else +# define BOOST_HW_SIMD_X86_AVAILABLE +#endif + +#define BOOST_HW_SIMD_X86_NAME "x86 SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_X86, BOOST_HW_SIMD_X86_NAME) diff --git a/thirdparty/linux/include/boost/predef/hardware/simd/x86/versions.h b/thirdparty/linux/include/boost/predef/hardware/simd/x86/versions.h new file mode 100644 index 0000000..0c7a4d3 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd/x86/versions.h @@ -0,0 +1,129 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_VERSIONS_H +#define BOOST_PREDEF_HARDWARE_SIMD_X86_VERSIONS_H + +#include + +/*` + Those defines represent x86 SIMD extensions versions. + + [note You *MUST* compare them with the predef `BOOST_HW_SIMD_X86`.] + */ + +// --------------------------------- + +/*` + [heading `BOOST_HW_SIMD_X86_MMX_VERSION`] + + The [@https://en.wikipedia.org/wiki/MMX_(instruction_set) MMX] x86 extension + version number. + + Version number is: *0.99.0*. + */ +#define BOOST_HW_SIMD_X86_MMX_VERSION BOOST_VERSION_NUMBER(0, 99, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_SSE_VERSION`] + + The [@https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions SSE] x86 extension + version number. + + Version number is: *1.0.0*. + */ +#define BOOST_HW_SIMD_X86_SSE_VERSION BOOST_VERSION_NUMBER(1, 0, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_SSE2_VERSION`] + + The [@https://en.wikipedia.org/wiki/SSE2 SSE2] x86 extension version number. + + Version number is: *2.0.0*. + */ +#define BOOST_HW_SIMD_X86_SSE2_VERSION BOOST_VERSION_NUMBER(2, 0, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_SSE3_VERSION`] + + The [@https://en.wikipedia.org/wiki/SSE3 SSE3] x86 extension version number. + + Version number is: *3.0.0*. + */ +#define BOOST_HW_SIMD_X86_SSE3_VERSION BOOST_VERSION_NUMBER(3, 0, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_SSSE3_VERSION`] + + The [@https://en.wikipedia.org/wiki/SSSE3 SSSE3] x86 extension version number. + + Version number is: *3.1.0*. + */ +#define BOOST_HW_SIMD_X86_SSSE3_VERSION BOOST_VERSION_NUMBER(3, 1, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_SSE4_1_VERSION`] + + The [@https://en.wikipedia.org/wiki/SSE4#SSE4.1 SSE4_1] x86 extension version + number. + + Version number is: *4.1.0*. + */ +#define BOOST_HW_SIMD_X86_SSE4_1_VERSION BOOST_VERSION_NUMBER(4, 1, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_SSE4_2_VERSION`] + + The [@https://en.wikipedia.org/wiki/SSE4##SSE4.2 SSE4_2] x86 extension version + number. + + Version number is: *4.2.0*. + */ +#define BOOST_HW_SIMD_X86_SSE4_2_VERSION BOOST_VERSION_NUMBER(4, 2, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_AVX_VERSION`] + + The [@https://en.wikipedia.org/wiki/Advanced_Vector_Extensions AVX] x86 + extension version number. + + Version number is: *5.0.0*. + */ +#define BOOST_HW_SIMD_X86_AVX_VERSION BOOST_VERSION_NUMBER(5, 0, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_FMA3_VERSION`] + + The [@https://en.wikipedia.org/wiki/FMA_instruction_set FMA3] x86 extension + version number. + + Version number is: *5.2.0*. + */ +#define BOOST_HW_SIMD_X86_FMA3_VERSION BOOST_VERSION_NUMBER(5, 2, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_AVX2_VERSION`] + + The [@https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2 AVX2] + x86 extension version number. + + Version number is: *5.3.0*. + */ +#define BOOST_HW_SIMD_X86_AVX2_VERSION BOOST_VERSION_NUMBER(5, 3, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_MIC_VERSION`] + + The [@https://en.wikipedia.org/wiki/Xeon_Phi MIC] (Xeon Phi) x86 extension + version number. + + Version number is: *9.0.0*. + */ +#define BOOST_HW_SIMD_X86_MIC_VERSION BOOST_VERSION_NUMBER(9, 0, 0) + +#endif diff --git a/thirdparty/linux/include/boost/predef/hardware/simd/x86_amd.h b/thirdparty/linux/include/boost/predef/hardware/simd/x86_amd.h new file mode 100644 index 0000000..c80d1ce --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd/x86_amd.h @@ -0,0 +1,87 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_H +#define BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_H + +#include +#include + +/*` + [heading `BOOST_HW_SIMD_X86_AMD`] + + The SIMD extension for x86 (AMD) (*if detected*). + Version number depends on the most recent detected extension. + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`__SSE4A__`] [__predef_detection__]] + + [[`__FMA4__`] [__predef_detection__]] + + [[`__XOP__`] [__predef_detection__]] + + [[`BOOST_HW_SIMD_X86`] [__predef_detection__]] + ] + + [table + [[__predef_symbol__] [__predef_version__]] + + [[`__SSE4A__`] [BOOST_HW_SIMD_X86_SSE4A_VERSION]] + + [[`__FMA4__`] [BOOST_HW_SIMD_X86_FMA4_VERSION]] + + [[`__XOP__`] [BOOST_HW_SIMD_X86_XOP_VERSION]] + + [[`BOOST_HW_SIMD_X86`] [BOOST_HW_SIMD_X86]] + ] + + [note This predef includes every other x86 SIMD extensions and also has other + more specific extensions (FMA4, XOP, SSE4a). You should use this predef + instead of `BOOST_HW_SIMD_X86` to test if those specific extensions have + been detected.] + + */ + +#define BOOST_HW_SIMD_X86_AMD BOOST_VERSION_NUMBER_NOT_AVAILABLE + +// AMD CPUs also use x86 architecture. We first try to detect if any AMD +// specific extension are detected, if yes, then try to detect more recent x86 +// common extensions. + +#undef BOOST_HW_SIMD_X86_AMD +#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__XOP__) +# define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_XOP_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__FMA4__) +# define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_FMA4_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__SSE4A__) +# define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_SSE4A_VERSION +#endif + +#if !defined(BOOST_HW_SIMD_X86_AMD) +# define BOOST_HW_SIMD_X86_AMD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#else + // At this point, we know that we have an AMD CPU, we do need to check for + // other x86 extensions to determine the final version number. +# include +# if BOOST_HW_SIMD_X86 > BOOST_HW_SIMD_X86_AMD +# undef BOOST_HW_SIMD_X86_AMD +# define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86 +# endif +# define BOOST_HW_SIMD_X86_AMD_AVAILABLE +#endif + +#define BOOST_HW_SIMD_X86_AMD_NAME "x86 (AMD) SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_X86_AMD, BOOST_HW_SIMD_X86_AMD_NAME) diff --git a/thirdparty/linux/include/boost/predef/hardware/simd/x86_amd/versions.h b/thirdparty/linux/include/boost/predef/hardware/simd/x86_amd/versions.h new file mode 100644 index 0000000..1f9e96c --- /dev/null +++ b/thirdparty/linux/include/boost/predef/hardware/simd/x86_amd/versions.h @@ -0,0 +1,51 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_VERSIONS_H +#define BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_VERSIONS_H + +#include + +/*` + Those defines represent x86 (AMD specific) SIMD extensions versions. + + [note You *MUST* compare them with the predef `BOOST_HW_SIMD_X86_AMD`.] + */ + + +// --------------------------------- + +/*` + [heading `BOOST_HW_SIMD_X86_AMD_SSE4A_VERSION`] + + [@https://en.wikipedia.org/wiki/SSE4##SSE4A SSE4A] x86 extension (AMD specific). + + Version number is: *4.0.0*. + */ +#define BOOST_HW_SIMD_X86_AMD_SSE4A_VERSION BOOST_VERSION_NUMBER(4, 0, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_AMD_FMA4_VERSION`] + + [@https://en.wikipedia.org/wiki/FMA_instruction_set#FMA4_instruction_set FMA4] x86 extension (AMD specific). + + Version number is: *5.1.0*. + */ +#define BOOST_HW_SIMD_X86_AMD_FMA4_VERSION BOOST_VERSION_NUMBER(5, 1, 0) + +/*` + [heading `BOOST_HW_SIMD_X86_AMD_XOP_VERSION`] + + [@https://en.wikipedia.org/wiki/XOP_instruction_set XOP] x86 extension (AMD specific). + + Version number is: *5.1.1*. + */ +#define BOOST_HW_SIMD_X86_AMD_XOP_VERSION BOOST_VERSION_NUMBER(5, 1, 1) + + +#endif diff --git a/thirdparty/linux/include/boost/predef/language.h b/thirdparty/linux/include/boost/predef/language.h new file mode 100644 index 0000000..0a317d5 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/language.h @@ -0,0 +1,17 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_LANGUAGE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_LANGUAGE_H +#define BOOST_PREDEF_LANGUAGE_H +#endif + +#include +#include +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/language/objc.h b/thirdparty/linux/include/boost/predef/language/objc.h new file mode 100644 index 0000000..24e3ad3 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/language/objc.h @@ -0,0 +1,42 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LANGUAGE_OBJC_H +#define BOOST_PREDEF_LANGUAGE_OBJC_H + +#include +#include + +/*` +[heading `BOOST_LANG_OBJC`] + +[@http://en.wikipedia.org/wiki/Objective-C Objective-C] language. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__OBJC__`] [__predef_detection__]] + ] + */ + +#define BOOST_LANG_OBJC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__OBJC__) +# undef BOOST_LANG_OBJC +# define BOOST_LANG_OBJC BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_LANG_OBJC +# define BOOST_LANG_OBJC_AVAILABLE +#endif + +#define BOOST_LANG_OBJC_NAME "Objective-C" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_OBJC,BOOST_LANG_OBJC_NAME) diff --git a/thirdparty/linux/include/boost/predef/language/stdc.h b/thirdparty/linux/include/boost/predef/language/stdc.h new file mode 100644 index 0000000..db25c12 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/language/stdc.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LANGUAGE_STDC_H +#define BOOST_PREDEF_LANGUAGE_STDC_H + +#include +#include + +/*` +[heading `BOOST_LANG_STDC`] + +[@http://en.wikipedia.org/wiki/C_(programming_language) Standard C] language. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__STDC__`] [__predef_detection__]] + + [[`__STDC_VERSION__`] [V.R.P]] + ] + */ + +#define BOOST_LANG_STDC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__STDC__) +# undef BOOST_LANG_STDC +# if defined(__STDC_VERSION__) +# if (__STDC_VERSION__ > 100) +# define BOOST_LANG_STDC BOOST_PREDEF_MAKE_YYYYMM(__STDC_VERSION__) +# else +# define BOOST_LANG_STDC BOOST_VERSION_NUMBER_AVAILABLE +# endif +# else +# define BOOST_LANG_STDC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LANG_STDC +# define BOOST_LANG_STDC_AVAILABLE +#endif + +#define BOOST_LANG_STDC_NAME "Standard C" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDC,BOOST_LANG_STDC_NAME) diff --git a/thirdparty/linux/include/boost/predef/language/stdcpp.h b/thirdparty/linux/include/boost/predef/language/stdcpp.h new file mode 100644 index 0000000..34dc8c7 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/language/stdcpp.h @@ -0,0 +1,121 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LANGUAGE_STDCPP_H +#define BOOST_PREDEF_LANGUAGE_STDCPP_H + +#include +#include + +/*` +[heading `BOOST_LANG_STDCPP`] + +[@http://en.wikipedia.org/wiki/C%2B%2B Standard C++] language. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date. +Because of the way the C++ standardization process works the +defined version year will not be the commonly known year of the standard. +Specifically the defined versions are: + +[table Detected Version Number vs. C++ Standard Year + [[Detected Version Number] [Standard Year] [C++ Standard]] + [[27.11.1] [1998] [ISO/IEC 14882:1998]] + [[41.12.1] [2011] [ISO/IEC 14882:2011]] +] + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__cplusplus`] [__predef_detection__]] + + [[`__cplusplus`] [YYYY.MM.1]] + ] + */ + +#define BOOST_LANG_STDCPP BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__cplusplus) +# undef BOOST_LANG_STDCPP +# if (__cplusplus > 100) +# define BOOST_LANG_STDCPP BOOST_PREDEF_MAKE_YYYYMM(__cplusplus) +# else +# define BOOST_LANG_STDCPP BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LANG_STDCPP +# define BOOST_LANG_STDCPP_AVAILABLE +#endif + +#define BOOST_LANG_STDCPP_NAME "Standard C++" + +/*` +[heading `BOOST_LANG_STDCPPCLI`] + +[@http://en.wikipedia.org/wiki/C%2B%2B/CLI Standard C++/CLI] language. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__cplusplus_cli`] [__predef_detection__]] + + [[`__cplusplus_cli`] [YYYY.MM.1]] + ] + */ + +#define BOOST_LANG_STDCPPCLI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__cplusplus_cli) +# undef BOOST_LANG_STDCPPCLI +# if (__cplusplus_cli > 100) +# define BOOST_LANG_STDCPPCLI BOOST_PREDEF_MAKE_YYYYMM(__cplusplus_cli) +# else +# define BOOST_LANG_STDCPPCLI BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LANG_STDCPPCLI +# define BOOST_LANG_STDCPPCLI_AVAILABLE +#endif + +#define BOOST_LANG_STDCPPCLI_NAME "Standard C++/CLI" + +/*` +[heading `BOOST_LANG_STDECPP`] + +[@http://en.wikipedia.org/wiki/Embedded_C%2B%2B Standard Embedded C++] language. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__embedded_cplusplus`] [__predef_detection__]] + ] + */ + +#define BOOST_LANG_STDECPP BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__embedded_cplusplus) +# undef BOOST_LANG_STDECPP +# define BOOST_LANG_STDECPP BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_LANG_STDECPP +# define BOOST_LANG_STDECPP_AVAILABLE +#endif + +#define BOOST_LANG_STDECPP_NAME "Standard Embedded C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPP,BOOST_LANG_STDCPP_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPPCLI,BOOST_LANG_STDCPPCLI_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDECPP,BOOST_LANG_STDECPP_NAME) diff --git a/thirdparty/linux/include/boost/predef/library.h b/thirdparty/linux/include/boost/predef/library.h new file mode 100644 index 0000000..40518a9 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library.h @@ -0,0 +1,16 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_LIBRARY_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_LIBRARY_H +#define BOOST_PREDEF_LIBRARY_H +#endif + +#include +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/library/c.h b/thirdparty/linux/include/boost/predef/library/c.h new file mode 100644 index 0000000..fa8841e --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/c.h @@ -0,0 +1,20 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_LIBRARY_C_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_LIBRARY_C_H +#define BOOST_PREDEF_LIBRARY_C_H +#endif + +#include + +#include +#include +#include +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/library/c/_prefix.h b/thirdparty/linux/include/boost/predef/library/c/_prefix.h new file mode 100644 index 0000000..12bcb0f --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/c/_prefix.h @@ -0,0 +1,13 @@ +/* +Copyright Rene Rivera 2008-2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C__PREFIX_H +#define BOOST_PREDEF_LIBRARY_C__PREFIX_H + +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/library/c/gnu.h b/thirdparty/linux/include/boost/predef/library/c/gnu.h new file mode 100644 index 0000000..9e4ca89 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/c/gnu.h @@ -0,0 +1,61 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_GNU_H +#define BOOST_PREDEF_LIBRARY_C_GNU_H + +#include +#include + +#include + +#if defined(__STDC__) +#include +#elif defined(__cplusplus) +#include +#endif + +/*` +[heading `BOOST_LIB_C_GNU`] + +[@http://en.wikipedia.org/wiki/Glibc GNU glibc] Standard C library. +Version number available as major, and minor. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__GLIBC__`] [__predef_detection__]] + [[`__GNU_LIBRARY__`] [__predef_detection__]] + + [[`__GLIBC__`, `__GLIBC_MINOR__`] [V.R.0]] + [[`__GNU_LIBRARY__`, `__GNU_LIBRARY_MINOR__`] [V.R.0]] + ] + */ + +#define BOOST_LIB_C_GNU BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GLIBC__) || defined(__GNU_LIBRARY__) +# undef BOOST_LIB_C_GNU +# if defined(__GLIBC__) +# define BOOST_LIB_C_GNU \ + BOOST_VERSION_NUMBER(__GLIBC__,__GLIBC_MINOR__,0) +# else +# define BOOST_LIB_C_GNU \ + BOOST_VERSION_NUMBER(__GNU_LIBRARY__,__GNU_LIBRARY_MINOR__,0) +# endif +#endif + +#if BOOST_LIB_C_GNU +# define BOOST_LIB_C_GNU_AVAILABLE +#endif + +#define BOOST_LIB_C_GNU_NAME "GNU" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_GNU,BOOST_LIB_C_GNU_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/c/uc.h b/thirdparty/linux/include/boost/predef/library/c/uc.h new file mode 100644 index 0000000..03081e9 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/c/uc.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_UC_H +#define BOOST_PREDEF_LIBRARY_C_UC_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_C_UC`] + +[@http://en.wikipedia.org/wiki/Uclibc uClibc] Standard C library. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__UCLIBC__`] [__predef_detection__]] + + [[`__UCLIBC_MAJOR__`, `__UCLIBC_MINOR__`, `__UCLIBC_SUBLEVEL__`] [V.R.P]] + ] + */ + +#define BOOST_LIB_C_UC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__UCLIBC__) +# undef BOOST_LIB_C_UC +# define BOOST_LIB_C_UC BOOST_VERSION_NUMBER(\ + __UCLIBC_MAJOR__,__UCLIBC_MINOR__,__UCLIBC_SUBLEVEL__) +#endif + +#if BOOST_LIB_C_UC +# define BOOST_LIB_C_UC_AVAILABLE +#endif + +#define BOOST_LIB_C_UC_NAME "uClibc" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_UC,BOOST_LIB_C_UC_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/c/vms.h b/thirdparty/linux/include/boost/predef/library/c/vms.h new file mode 100644 index 0000000..685f1a7 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/c/vms.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_VMS_H +#define BOOST_PREDEF_LIBRARY_C_VMS_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_C_VMS`] + +VMS libc Standard C library. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__CRTL_VER`] [__predef_detection__]] + + [[`__CRTL_VER`] [V.R.P]] + ] + */ + +#define BOOST_LIB_C_VMS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__CRTL_VER) +# undef BOOST_LIB_C_VMS +# define BOOST_LIB_C_VMS BOOST_PREDEF_MAKE_10_VVRR0PP00(__CRTL_VER) +#endif + +#if BOOST_LIB_C_VMS +# define BOOST_LIB_C_VMS_AVAILABLE +#endif + +#define BOOST_LIB_C_VMS_NAME "VMS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_VMS,BOOST_LIB_C_VMS_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/c/zos.h b/thirdparty/linux/include/boost/predef/library/c/zos.h new file mode 100644 index 0000000..222d355 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/c/zos.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_ZOS_H +#define BOOST_PREDEF_LIBRARY_C_ZOS_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_C_ZOS`] + +z/OS libc Standard C library. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__LIBREL__`] [__predef_detection__]] + + [[`__LIBREL__`] [V.R.P]] + [[`__TARGET_LIB__`] [V.R.P]] + ] + */ + +#define BOOST_LIB_C_ZOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__LIBREL__) +# undef BOOST_LIB_C_ZOS +# if !defined(BOOST_LIB_C_ZOS) && defined(__LIBREL__) +# define BOOST_LIB_C_ZOS BOOST_PREDEF_MAKE_0X_VRRPPPP(__LIBREL__) +# endif +# if !defined(BOOST_LIB_C_ZOS) && defined(__TARGET_LIB__) +# define BOOST_LIB_C_ZOS BOOST_PREDEF_MAKE_0X_VRRPPPP(__TARGET_LIB__) +# endif +# if !defined(BOOST_LIB_C_ZOS) +# define BOOST_LIB_C_ZOS BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LIB_C_ZOS +# define BOOST_LIB_C_ZOS_AVAILABLE +#endif + +#define BOOST_LIB_C_ZOS_NAME "z/OS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_ZOS,BOOST_LIB_C_ZOS_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std.h b/thirdparty/linux/include/boost/predef/library/std.h new file mode 100644 index 0000000..403b6ff --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std.h @@ -0,0 +1,25 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#if !defined(BOOST_PREDEF_LIBRARY_STD_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_LIBRARY_STD_H +#define BOOST_PREDEF_LIBRARY_STD_H +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/library/std/_prefix.h b/thirdparty/linux/include/boost/predef/library/std/_prefix.h new file mode 100644 index 0000000..932b855 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/_prefix.h @@ -0,0 +1,23 @@ +/* +Copyright Rene Rivera 2008-2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_PREDEF_LIBRARY_STD__PREFIX_H +#define BOOST_PREDEF_LIBRARY_STD__PREFIX_H + +/* +We need to include an STD header to gives us the context +of which library we are using. The "smallest" code-wise header +seems to be . Boost uses but as far +as I can tell (RR) it's not a stand-alone header in most +implementations. Using also has the benefit of +being available in EC++, so we get a chance to make this work +for embedded users. And since it's not a header impacted by TR1 +there's no magic needed for inclusion in the face of the +Boost.TR1 library. +*/ +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/library/std/cxx.h b/thirdparty/linux/include/boost/predef/library/std/cxx.h new file mode 100644 index 0000000..07b52cd --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/cxx.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_CXX_H +#define BOOST_PREDEF_LIBRARY_STD_CXX_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_CXX`] + +[@http://libcxx.llvm.org/ libc++] C++ Standard Library. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_LIBCPP_VERSION`] [__predef_detection__]] + + [[`_LIBCPP_VERSION`] [V.0.P]] + ] + */ + +#define BOOST_LIB_STD_CXX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_LIBCPP_VERSION) +# undef BOOST_LIB_STD_CXX +# define BOOST_LIB_STD_CXX BOOST_PREDEF_MAKE_10_VPPP(_LIBCPP_VERSION) +#endif + +#if BOOST_LIB_STD_CXX +# define BOOST_LIB_STD_CXX_AVAILABLE +#endif + +#define BOOST_LIB_STD_CXX_NAME "libc++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_CXX,BOOST_LIB_STD_CXX_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/dinkumware.h b/thirdparty/linux/include/boost/predef/library/std/dinkumware.h new file mode 100644 index 0000000..0fc0776 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/dinkumware.h @@ -0,0 +1,52 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_DINKUMWARE_H +#define BOOST_PREDEF_LIBRARY_STD_DINKUMWARE_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_DINKUMWARE`] + +[@http://en.wikipedia.org/wiki/Dinkumware Dinkumware] Standard C++ Library. +If available version number as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_YVALS`, `__IBMCPP__`] [__predef_detection__]] + [[`_CPPLIB_VER`] [__predef_detection__]] + + [[`_CPPLIB_VER`] [V.R.0]] + ] + */ + +#define BOOST_LIB_STD_DINKUMWARE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +# undef BOOST_LIB_STD_DINKUMWARE +# if defined(_CPPLIB_VER) +# define BOOST_LIB_STD_DINKUMWARE BOOST_PREDEF_MAKE_10_VVRR(_CPPLIB_VER) +# else +# define BOOST_LIB_STD_DINKUMWARE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LIB_STD_DINKUMWARE +# define BOOST_LIB_STD_DINKUMWARE_AVAILABLE +#endif + +#define BOOST_LIB_STD_DINKUMWARE_NAME "Dinkumware" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_DINKUMWARE,BOOST_LIB_STD_DINKUMWARE_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/libcomo.h b/thirdparty/linux/include/boost/predef/library/std/libcomo.h new file mode 100644 index 0000000..97d4a53 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/libcomo.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_LIBCOMO_H +#define BOOST_PREDEF_LIBRARY_STD_LIBCOMO_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_COMO`] + +[@http://www.comeaucomputing.com/libcomo/ Comeau Computing] Standard C++ Library. +Version number available as major. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__LIBCOMO__`] [__predef_detection__]] + + [[`__LIBCOMO_VERSION__`] [V.0.0]] + ] + */ + +#define BOOST_LIB_STD_COMO BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__LIBCOMO__) +# undef BOOST_LIB_STD_COMO +# define BOOST_LIB_STD_COMO BOOST_VERSION_NUMBER(__LIBCOMO_VERSION__,0,0) +#endif + +#if BOOST_LIB_STD_COMO +# define BOOST_LIB_STD_COMO_AVAILABLE +#endif + +#define BOOST_LIB_STD_COMO_NAME "Comeau Computing" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_COMO,BOOST_LIB_STD_COMO_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/modena.h b/thirdparty/linux/include/boost/predef/library/std/modena.h new file mode 100644 index 0000000..b67ac62 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/modena.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_MODENA_H +#define BOOST_PREDEF_LIBRARY_STD_MODENA_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_MSIPL`] + +[@http://modena.us/ Modena Software Lib++] Standard C++ Library. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`MSIPL_COMPILE_H`] [__predef_detection__]] + [[`__MSIPL_COMPILE_H`] [__predef_detection__]] + ] + */ + +#define BOOST_LIB_STD_MSIPL BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(MSIPL_COMPILE_H) || defined(__MSIPL_COMPILE_H) +# undef BOOST_LIB_STD_MSIPL +# define BOOST_LIB_STD_MSIPL BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_LIB_STD_MSIPL +# define BOOST_LIB_STD_MSIPL_AVAILABLE +#endif + +#define BOOST_LIB_STD_MSIPL_NAME "Modena Software Lib++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSIPL,BOOST_LIB_STD_MSIPL_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/msl.h b/thirdparty/linux/include/boost/predef/library/std/msl.h new file mode 100644 index 0000000..d73c74c --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/msl.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_MSL_H +#define BOOST_PREDEF_LIBRARY_STD_MSL_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_MSL`] + +[@http://www.freescale.com/ Metrowerks] Standard C++ Library. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__MSL_CPP__`] [__predef_detection__]] + [[`__MSL__`] [__predef_detection__]] + + [[`__MSL_CPP__`] [V.R.P]] + [[`__MSL__`] [V.R.P]] + ] + */ + +#define BOOST_LIB_STD_MSL BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MSL_CPP__) || defined(__MSL__) +# undef BOOST_LIB_STD_MSL +# if defined(__MSL_CPP__) +# define BOOST_LIB_STD_MSL BOOST_PREDEF_MAKE_0X_VRPP(__MSL_CPP__) +# else +# define BOOST_LIB_STD_MSL BOOST_PREDEF_MAKE_0X_VRPP(__MSL__) +# endif +#endif + +#if BOOST_LIB_STD_MSL +# define BOOST_LIB_STD_MSL_AVAILABLE +#endif + +#define BOOST_LIB_STD_MSL_NAME "Metrowerks" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSL,BOOST_LIB_STD_MSL_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/roguewave.h b/thirdparty/linux/include/boost/predef/library/std/roguewave.h new file mode 100644 index 0000000..9c3f288 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/roguewave.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_ROGUEWAVE_H +#define BOOST_PREDEF_LIBRARY_STD_ROGUEWAVE_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_RW`] + +[@http://stdcxx.apache.org/ Roguewave] Standard C++ library. +If available version number as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__STD_RWCOMPILER_H__`] [__predef_detection__]] + [[`_RWSTD_VER`] [__predef_detection__]] + + [[`_RWSTD_VER`] [V.R.P]] + ] + */ + +#define BOOST_LIB_STD_RW BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +# undef BOOST_LIB_STD_RW +# if defined(_RWSTD_VER) +# if _RWSTD_VER < 0x010000 +# define BOOST_LIB_STD_RW BOOST_PREDEF_MAKE_0X_VVRRP(_RWSTD_VER) +# else +# define BOOST_LIB_STD_RW BOOST_PREDEF_MAKE_0X_VVRRPP(_RWSTD_VER) +# endif +# else +# define BOOST_LIB_STD_RW BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LIB_STD_RW +# define BOOST_LIB_STD_RW_AVAILABLE +#endif + +#define BOOST_LIB_STD_RW_NAME "Roguewave" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_RW,BOOST_LIB_STD_RW_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/sgi.h b/thirdparty/linux/include/boost/predef/library/std/sgi.h new file mode 100644 index 0000000..5d19bba --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/sgi.h @@ -0,0 +1,51 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_SGI_H +#define BOOST_PREDEF_LIBRARY_STD_SGI_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_SGI`] + +[@http://www.sgi.com/tech/stl/ SGI] Standard C++ library. +If available version number as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__STL_CONFIG_H`] [__predef_detection__]] + + [[`__SGI_STL`] [V.R.P]] + ] + */ + +#define BOOST_LIB_STD_SGI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__STL_CONFIG_H) +# undef BOOST_LIB_STD_SGI +# if defined(__SGI_STL) +# define BOOST_LIB_STD_SGI BOOST_PREDEF_MAKE_0X_VRP(__SGI_STL) +# else +# define BOOST_LIB_STD_SGI BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LIB_STD_SGI +# define BOOST_LIB_STD_SGI_AVAILABLE +#endif + +#define BOOST_LIB_STD_SGI_NAME "SGI" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_SGI,BOOST_LIB_STD_SGI_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/stdcpp3.h b/thirdparty/linux/include/boost/predef/library/std/stdcpp3.h new file mode 100644 index 0000000..c980292 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/stdcpp3.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_STDCPP3_H +#define BOOST_PREDEF_LIBRARY_STD_STDCPP3_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_GNU`] + +[@http://gcc.gnu.org/libstdc++/ GNU libstdc++] Standard C++ library. +Version number available as year (from 1970), month, and day. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__GLIBCXX__`] [__predef_detection__]] + [[`__GLIBCPP__`] [__predef_detection__]] + + [[`__GLIBCXX__`] [V.R.P]] + [[`__GLIBCPP__`] [V.R.P]] + ] + */ + +#define BOOST_LIB_STD_GNU BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GLIBCPP__) || defined(__GLIBCXX__) +# undef BOOST_LIB_STD_GNU +# if defined(__GLIBCXX__) +# define BOOST_LIB_STD_GNU BOOST_PREDEF_MAKE_YYYYMMDD(__GLIBCXX__) +# else +# define BOOST_LIB_STD_GNU BOOST_PREDEF_MAKE_YYYYMMDD(__GLIBCPP__) +# endif +#endif + +#if BOOST_LIB_STD_GNU +# define BOOST_LIB_STD_GNU_AVAILABLE +#endif + +#define BOOST_LIB_STD_GNU_NAME "GNU" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_GNU,BOOST_LIB_STD_GNU_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/stlport.h b/thirdparty/linux/include/boost/predef/library/std/stlport.h new file mode 100644 index 0000000..c09483b --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/stlport.h @@ -0,0 +1,59 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_STLPORT_H +#define BOOST_PREDEF_LIBRARY_STD_STLPORT_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_STLPORT`] + +[@http://sourceforge.net/projects/stlport/ STLport Standard C++] library. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__SGI_STL_PORT`] [__predef_detection__]] + [[`_STLPORT_VERSION`] [__predef_detection__]] + + [[`_STLPORT_MAJOR`, `_STLPORT_MINOR`, `_STLPORT_PATCHLEVEL`] [V.R.P]] + [[`_STLPORT_VERSION`] [V.R.P]] + [[`__SGI_STL_PORT`] [V.R.P]] + ] + */ + +#define BOOST_LIB_STD_STLPORT BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +# undef BOOST_LIB_STD_STLPORT +# if !defined(BOOST_LIB_STD_STLPORT) && defined(_STLPORT_MAJOR) +# define BOOST_LIB_STD_STLPORT \ + BOOST_VERSION_NUMBER(_STLPORT_MAJOR,_STLPORT_MINOR,_STLPORT_PATCHLEVEL) +# endif +# if !defined(BOOST_LIB_STD_STLPORT) && defined(_STLPORT_VERSION) +# define BOOST_LIB_STD_STLPORT BOOST_PREDEF_MAKE_0X_VRP(_STLPORT_VERSION) +# endif +# if !defined(BOOST_LIB_STD_STLPORT) +# define BOOST_LIB_STD_STLPORT BOOST_PREDEF_MAKE_0X_VRP(__SGI_STL_PORT) +# endif +#endif + +#if BOOST_LIB_STD_STLPORT +# define BOOST_LIB_STD_STLPORT_AVAILABLE +#endif + +#define BOOST_LIB_STD_STLPORT_NAME "STLport" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_STLPORT,BOOST_LIB_STD_STLPORT_NAME) diff --git a/thirdparty/linux/include/boost/predef/library/std/vacpp.h b/thirdparty/linux/include/boost/predef/library/std/vacpp.h new file mode 100644 index 0000000..632f846 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/library/std/vacpp.h @@ -0,0 +1,44 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_VACPP_H +#define BOOST_PREDEF_LIBRARY_STD_VACPP_H + +#include + +#include +#include + +/*` +[heading `BOOST_LIB_STD_IBM`] + +[@http://www.ibm.com/software/awdtools/xlcpp/ IBM VACPP Standard C++] library. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__IBMCPP__`] [__predef_detection__]] + ] + */ + +#define BOOST_LIB_STD_IBM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__IBMCPP__) +# undef BOOST_LIB_STD_IBM +# define BOOST_LIB_STD_IBM BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_LIB_STD_IBM +# define BOOST_LIB_STD_IBM_AVAILABLE +#endif + +#define BOOST_LIB_STD_IBM_NAME "IBM VACPP" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_IBM,BOOST_LIB_STD_IBM_NAME) diff --git a/thirdparty/linux/include/boost/predef/make.h b/thirdparty/linux/include/boost/predef/make.h new file mode 100644 index 0000000..4f2f9ee --- /dev/null +++ b/thirdparty/linux/include/boost/predef/make.h @@ -0,0 +1,89 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include + +#ifndef BOOST_PREDEF_MAKE_H +#define BOOST_PREDEF_MAKE_H + +/* +Shorthands for the common version number formats used by vendors... +*/ + +/*` +[heading `BOOST_PREDEF_MAKE_..` macros] + +These set of macros decompose common vendor version number +macros which are composed version, revision, and patch digits. +The naming convention indicates: + +* The base of the specified version number. "`BOOST_PREDEF_MAKE_0X`" for + hexadecimal digits, and "`BOOST_PREDEF_MAKE_10`" for decimal digits. +* The format of the vendor version number. Where "`V`" indicates the version digits, + "`R`" indicates the revision digits, "`P`" indicates the patch digits, and "`0`" + indicates an ignored digit. + +Macros are: +*/ +/*` `BOOST_PREDEF_MAKE_0X_VRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRP(V) BOOST_VERSION_NUMBER((V&0xF00)>>8,(V&0xF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRP(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VRPP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRPP(V) BOOST_VERSION_NUMBER((V&0xF000)>>12,(V&0xF00)>>8,(V&0xFF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRR(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRR(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xFF),0) +/*` `BOOST_PREDEF_MAKE_0X_VRRPPPP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRRPPPP(V) BOOST_VERSION_NUMBER((V&0xF000000)>>24,(V&0xFF0000)>>16,(V&0xFFFF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRRP(V) BOOST_VERSION_NUMBER((V&0xFF000)>>12,(V&0xFF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VRRPP000(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRRPP000(V) BOOST_VERSION_NUMBER((V&0xF0000000)>>28,(V&0xFF00000)>>20,(V&0xFF000)>>12) +/*` `BOOST_PREDEF_MAKE_0X_VVRRPP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRRPP(V) BOOST_VERSION_NUMBER((V&0xFF0000)>>16,(V&0xFF00)>>8,(V&0xFF)) +/*` `BOOST_PREDEF_MAKE_10_VPPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VPPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,0,(V)%1000) +/*` `BOOST_PREDEF_MAKE_10_VRP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRP(V) BOOST_VERSION_NUMBER(((V)/100)%10,((V)/10)%10,(V)%10) +/*` `BOOST_PREDEF_MAKE_10_VRP000(V)` */ +#define BOOST_PREDEF_MAKE_10_VRP000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/10000)%10,((V)/1000)%10) +/*` `BOOST_PREDEF_MAKE_10_VRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,((V)/100)%10,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VRR(V)` */ +#define BOOST_PREDEF_MAKE_10_VRR(V) BOOST_VERSION_NUMBER(((V)/100)%10,(V)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VRRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%10,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VRR000(V)` */ +#define BOOST_PREDEF_MAKE_10_VRR000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/1000)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VV00(V)` */ +#define BOOST_PREDEF_MAKE_10_VV00(V) BOOST_VERSION_NUMBER(((V)/100)%100,0,0) +/*` `BOOST_PREDEF_MAKE_10_VVRR(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR(V) BOOST_VERSION_NUMBER(((V)/100)%100,(V)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VVRRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%100,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VVRR0PP00(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR0PP00(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,((V)/100)%100) +/*` `BOOST_PREDEF_MAKE_10_VVRR0PPPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR0PPPP(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,(V)%10000) +/*` `BOOST_PREDEF_MAKE_10_VVRR00PP00(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR00PP00(V) BOOST_VERSION_NUMBER(((V)/100000000)%100,((V)/1000000)%100,((V)/100)%100) +/*` +[heading `BOOST_PREDEF_MAKE_*..` date macros] + +Date decomposition macros return a date in the relative to the 1970 +Epoch date. If the month is not available, January 1st is used as the month and day. +If the day is not available, but the month is, the 1st of the month is used as the day. +*/ +/*` `BOOST_PREDEF_MAKE_DATE(Y,M,D)` */ +#define BOOST_PREDEF_MAKE_DATE(Y,M,D) BOOST_VERSION_NUMBER((Y)%10000-1970,(M)%100,(D)%100) +/*` `BOOST_PREDEF_MAKE_YYYYMMDD(V)` */ +#define BOOST_PREDEF_MAKE_YYYYMMDD(V) BOOST_PREDEF_MAKE_DATE(((V)/10000)%10000,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_YYYY(V)` */ +#define BOOST_PREDEF_MAKE_YYYY(V) BOOST_PREDEF_MAKE_DATE(V,1,1) +/*` `BOOST_PREDEF_MAKE_YYYYMM(V)` */ +#define BOOST_PREDEF_MAKE_YYYYMM(V) BOOST_PREDEF_MAKE_DATE((V)/100,(V)%100,1) + +#endif diff --git a/thirdparty/linux/include/boost/predef/os.h b/thirdparty/linux/include/boost/predef/os.h new file mode 100644 index 0000000..bedf99e --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os.h @@ -0,0 +1,33 @@ +/* +Copyright Rene Rivera 2008-2015 +Copyright Franz Detro 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_OS_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_OS_H +#define BOOST_PREDEF_OS_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/thirdparty/linux/include/boost/predef/os/aix.h b/thirdparty/linux/include/boost/predef/os/aix.h new file mode 100644 index 0000000..3e5a953 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/aix.h @@ -0,0 +1,66 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_AIX_H +#define BOOST_PREDEF_OS_AIX_H + +#include +#include + +/*` +[heading `BOOST_OS_AIX`] + +[@http://en.wikipedia.org/wiki/AIX_operating_system IBM AIX] operating system. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_AIX`] [__predef_detection__]] + [[`__TOS_AIX__`] [__predef_detection__]] + + [[`_AIX43`] [4.3.0]] + [[`_AIX41`] [4.1.0]] + [[`_AIX32`] [3.2.0]] + [[`_AIX3`] [3.0.0]] + ] + */ + +#define BOOST_OS_AIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(_AIX) || defined(__TOS_AIX__) \ + ) +# undef BOOST_OS_AIX +# if !defined(BOOST_OS_AIX) && defined(_AIX43) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX41) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(4,1,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX32) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX3) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_OS_AIX) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_AIX +# define BOOST_OS_AIX_AVAILABLE +# include +#endif + +#define BOOST_OS_AIX_NAME "IBM AIX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AIX,BOOST_OS_AIX_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/amigaos.h b/thirdparty/linux/include/boost/predef/os/amigaos.h new file mode 100644 index 0000000..7b32ddf --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/amigaos.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_AMIGAOS_H +#define BOOST_PREDEF_OS_AMIGAOS_H + +#include +#include + +/*` +[heading `BOOST_OS_AMIGAOS`] + +[@http://en.wikipedia.org/wiki/AmigaOS AmigaOS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`AMIGA`] [__predef_detection__]] + [[`__amigaos__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_AMIGAOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(AMIGA) || defined(__amigaos__) \ + ) +# undef BOOST_OS_AMIGAOS +# define BOOST_OS_AMIGAOS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_AMIGAOS +# define BOOST_OS_AMIGAOS_AVAILABLE +# include +#endif + +#define BOOST_OS_AMIGAOS_NAME "AmigaOS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AMIGAOS,BOOST_OS_AMIGAOS_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/android.h b/thirdparty/linux/include/boost/predef/os/android.h new file mode 100644 index 0000000..00836e7 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/android.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_ADROID_H +#define BOOST_PREDEF_OS_ADROID_H + +#include +#include + +/*` +[heading `BOOST_OS_ANDROID`] + +[@http://en.wikipedia.org/wiki/Android_%28operating_system%29 Android] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__ANDROID__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_ANDROID BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__ANDROID__) \ + ) +# undef BOOST_OS_ANDROID +# define BOOST_OS_ANDROID BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_ANDROID +# define BOOST_OS_ANDROID_AVAILABLE +# include +#endif + +#define BOOST_OS_ANDROID_NAME "Android" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_ANDROID,BOOST_OS_ANDROID_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/beos.h b/thirdparty/linux/include/boost/predef/os/beos.h new file mode 100644 index 0000000..19f4cb7 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/beos.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BEOS_H +#define BOOST_PREDEF_OS_BEOS_H + +#include +#include + +/*` +[heading `BOOST_OS_BEOS`] + +[@http://en.wikipedia.org/wiki/BeOS BeOS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__BEOS__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_BEOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__BEOS__) \ + ) +# undef BOOST_OS_BEOS +# define BOOST_OS_BEOS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_BEOS +# define BOOST_OS_BEOS_AVAILABLE +# include +#endif + +#define BOOST_OS_BEOS_NAME "BeOS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BEOS,BOOST_OS_BEOS_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/bsd.h b/thirdparty/linux/include/boost/predef/os/bsd.h new file mode 100644 index 0000000..fad9aed --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/bsd.h @@ -0,0 +1,103 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_H +#define BOOST_PREDEF_OS_BSD_H + +/* Special case: OSX will define BSD predefs if the sys/param.h + * header is included. We can guard against that, but only if we + * detect OSX first. Hence we will force include OSX detection + * before doing any BSD detection. + */ +#include + +#include +#include + +/*` +[heading `BOOST_OS_BSD`] + +[@http://en.wikipedia.org/wiki/Berkeley_Software_Distribution BSD] operating system. + +BSD has various branch operating systems possible and each detected +individually. This detects the following variations and sets a specific +version number macro to match: + +* `BOOST_OS_BSD_DRAGONFLY` [@http://en.wikipedia.org/wiki/DragonFly_BSD DragonFly BSD] +* `BOOST_OS_BSD_FREE` [@http://en.wikipedia.org/wiki/Freebsd FreeBSD] +* `BOOST_OS_BSD_BSDI` [@http://en.wikipedia.org/wiki/BSD/OS BSDi BSD/OS] +* `BOOST_OS_BSD_NET` [@http://en.wikipedia.org/wiki/Netbsd NetBSD] +* `BOOST_OS_BSD_OPEN` [@http://en.wikipedia.org/wiki/Openbsd OpenBSD] + +[note The general `BOOST_OS_BSD` is set in all cases to indicate some form +of BSD. If the above variants is detected the corresponding macro is also set.] + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`BSD`] [__predef_detection__]] + [[`_SYSTYPE_BSD`] [__predef_detection__]] + + [[`BSD4_2`] [4.2.0]] + [[`BSD4_3`] [4.3.0]] + [[`BSD4_4`] [4.4.0]] + [[`BSD`] [V.R.0]] + ] + */ + +#include +#include +#include +#include +#include + +#ifndef BOOST_OS_BSD +#define BOOST_OS_BSD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#endif + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(BSD) || \ + defined(_SYSTYPE_BSD) \ + ) +# undef BOOST_OS_BSD +# include +# if !defined(BOOST_OS_BSD) && defined(BSD4_4) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,4,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD4_3) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD4_2) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,2,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD) +# define BOOST_OS_BSD BOOST_PREDEF_MAKE_10_VVRR(BSD) +# endif +# if !defined(BOOST_OS_BSD) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD +# define BOOST_OS_BSD_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_NAME "BSD" + +#else + +#include +#include +#include +#include +#include + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD,BOOST_OS_BSD_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/bsd/bsdi.h b/thirdparty/linux/include/boost/predef/os/bsd/bsdi.h new file mode 100644 index 0000000..afdcd3e --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/bsd/bsdi.h @@ -0,0 +1,48 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_BSDI_H +#define BOOST_PREDEF_OS_BSD_BSDI_H + +#include + +/*` +[heading `BOOST_OS_BSD_BSDI`] + +[@http://en.wikipedia.org/wiki/BSD/OS BSDi BSD/OS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__bsdi__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__bsdi__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_BSDI +# define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_BSD_BSDI +# define BOOST_OS_BSD_BSDI_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_BSDI_NAME "BSDi BSD/OS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_BSDI,BOOST_OS_BSD_BSDI_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/bsd/dragonfly.h b/thirdparty/linux/include/boost/predef/os/bsd/dragonfly.h new file mode 100644 index 0000000..1d07579 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/bsd/dragonfly.h @@ -0,0 +1,50 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_DRAGONFLY_H +#define BOOST_PREDEF_OS_BSD_DRAGONFLY_H + +#include + +/*` +[heading `BOOST_OS_BSD_DRAGONFLY`] + +[@http://en.wikipedia.org/wiki/DragonFly_BSD DragonFly BSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__DragonFly__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_BSD_DRAGONFLY BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__DragonFly__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_DRAGONFLY +# if defined(__DragonFly__) +# define BOOST_OS_DRAGONFLY_BSD BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_DRAGONFLY +# define BOOST_OS_BSD_DRAGONFLY_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_DRAGONFLY_NAME "DragonFly BSD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_DRAGONFLY,BOOST_OS_BSD_DRAGONFLY_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/bsd/free.h b/thirdparty/linux/include/boost/predef/os/bsd/free.h new file mode 100644 index 0000000..248011a --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/bsd/free.h @@ -0,0 +1,60 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_FREE_H +#define BOOST_PREDEF_OS_BSD_FREE_H + +#include + +/*` +[heading `BOOST_OS_BSD_FREE`] + +[@http://en.wikipedia.org/wiki/Freebsd FreeBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__FreeBSD__`] [__predef_detection__]] + + [[`__FreeBSD_version`] [V.R.P]] + ] + */ + +#define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__FreeBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_FREE +# if defined(__FreeBSD_version) +# if __FreeBSD_version < 500000 +# define BOOST_OS_BSD_FREE \ + BOOST_PREDEF_MAKE_10_VRP000(__FreeBSD_version) +# else +# define BOOST_OS_BSD_FREE \ + BOOST_PREDEF_MAKE_10_VRR000(__FreeBSD_version) +# endif +# else +# define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_FREE +# define BOOST_OS_BSD_FREE_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_FREE_NAME "Free BSD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_FREE,BOOST_OS_BSD_FREE_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/bsd/net.h b/thirdparty/linux/include/boost/predef/os/bsd/net.h new file mode 100644 index 0000000..387cbde --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/bsd/net.h @@ -0,0 +1,84 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_NET_H +#define BOOST_PREDEF_OS_BSD_NET_H + +#include + +/*` +[heading `BOOST_OS_BSD_NET`] + +[@http://en.wikipedia.org/wiki/Netbsd NetBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__NETBSD__`] [__predef_detection__]] + [[`__NetBSD__`] [__predef_detection__]] + + [[`__NETBSD_version`] [V.R.P]] + [[`NetBSD0_8`] [0.8.0]] + [[`NetBSD0_9`] [0.9.0]] + [[`NetBSD1_0`] [1.0.0]] + [[`__NetBSD_Version`] [V.R.P]] + ] + */ + +#define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__NETBSD__) || defined(__NetBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_NET +# if defined(__NETBSD__) +# if defined(__NETBSD_version) +# if __NETBSD_version < 500000 +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VRP000(__NETBSD_version) +# else +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VRR000(__NETBSD_version) +# endif +# else +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE +# endif +# elif defined(__NetBSD__) +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_8) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,8,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_9) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,9,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD1_0) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(__NetBSD_Version) +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VVRR00PP00(__NetBSD_Version) +# endif +# if !defined(BOOST_OS_BSD_NET) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +#if BOOST_OS_BSD_NET +# define BOOST_OS_BSD_NET_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_NET_NAME "DragonFly BSD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_NET,BOOST_OS_BSD_NET_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/bsd/open.h b/thirdparty/linux/include/boost/predef/os/bsd/open.h new file mode 100644 index 0000000..423103a --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/bsd/open.h @@ -0,0 +1,171 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_OPEN_H +#define BOOST_PREDEF_OS_BSD_OPEN_H + +#include + +/*` +[heading `BOOST_OS_BSD_OPEN`] + +[@http://en.wikipedia.org/wiki/Openbsd OpenBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__OpenBSD__`] [__predef_detection__]] + + [[`OpenBSD2_0`] [2.0.0]] + [[`OpenBSD2_1`] [2.1.0]] + [[`OpenBSD2_2`] [2.2.0]] + [[`OpenBSD2_3`] [2.3.0]] + [[`OpenBSD2_4`] [2.4.0]] + [[`OpenBSD2_5`] [2.5.0]] + [[`OpenBSD2_6`] [2.6.0]] + [[`OpenBSD2_7`] [2.7.0]] + [[`OpenBSD2_8`] [2.8.0]] + [[`OpenBSD2_9`] [2.9.0]] + [[`OpenBSD3_0`] [3.0.0]] + [[`OpenBSD3_1`] [3.1.0]] + [[`OpenBSD3_2`] [3.2.0]] + [[`OpenBSD3_3`] [3.3.0]] + [[`OpenBSD3_4`] [3.4.0]] + [[`OpenBSD3_5`] [3.5.0]] + [[`OpenBSD3_6`] [3.6.0]] + [[`OpenBSD3_7`] [3.7.0]] + [[`OpenBSD3_8`] [3.8.0]] + [[`OpenBSD3_9`] [3.9.0]] + [[`OpenBSD4_0`] [4.0.0]] + [[`OpenBSD4_1`] [4.1.0]] + [[`OpenBSD4_2`] [4.2.0]] + [[`OpenBSD4_3`] [4.3.0]] + [[`OpenBSD4_4`] [4.4.0]] + [[`OpenBSD4_5`] [4.5.0]] + [[`OpenBSD4_6`] [4.6.0]] + [[`OpenBSD4_7`] [4.7.0]] + [[`OpenBSD4_8`] [4.8.0]] + [[`OpenBSD4_9`] [4.9.0]] + ] + */ + +#define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__OpenBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_OPEN +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_OPEN +# define BOOST_OS_BSD_OPEN_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_OPEN_NAME "OpenBSD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_OPEN,BOOST_OS_BSD_OPEN_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/cygwin.h b/thirdparty/linux/include/boost/predef/os/cygwin.h new file mode 100644 index 0000000..9d36f0f --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/cygwin.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_CYGWIN_H +#define BOOST_PREDEF_OS_CYGWIN_H + +#include +#include + +/*` +[heading `BOOST_OS_CYGWIN`] + +[@http://en.wikipedia.org/wiki/Cygwin Cygwin] evironment. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__CYGWIN__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_CYGWIN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__CYGWIN__) \ + ) +# undef BOOST_OS_CYGWIN +# define BOOST_OS_CYGWIN BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_CYGWIN +# define BOOST_OS_CYGWIN_AVAILABLE +# include +#endif + +#define BOOST_OS_CYGWIN_NAME "Cygwin" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_CYGWIN,BOOST_OS_CYGWIN_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/haiku.h b/thirdparty/linux/include/boost/predef/os/haiku.h new file mode 100644 index 0000000..d79dbea --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/haiku.h @@ -0,0 +1,46 @@ +/* +Copyright Jessica Hamilton 2014 +Copyright Rene Rivera 2014-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_HAIKU_H +#define BOOST_PREDEF_OS_HAIKU_H + +#include +#include + +/*` +[heading `BOOST_OS_HAIKU`] + +[@http://en.wikipedia.org/wiki/Haiku_(operating_system) Haiku] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__HAIKU__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_HAIKU BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__HAIKU__) \ + ) +# undef BOOST_OS_HAIKU +# define BOOST_OS_HAIKU BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_HAIKU +# define BOOST_OS_HAIKU_AVAILABLE +# include +#endif + +#define BOOST_OS_HAIKU_NAME "Haiku" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HAIKU,BOOST_OS_HAIKU_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/hpux.h b/thirdparty/linux/include/boost/predef/os/hpux.h new file mode 100644 index 0000000..29243f4 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/hpux.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_HPUX_H +#define BOOST_PREDEF_OS_HPUX_H + +#include +#include + +/*` +[heading `BOOST_OS_HPUX`] + +[@http://en.wikipedia.org/wiki/HP-UX HP-UX] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`hpux`] [__predef_detection__]] + [[`_hpux`] [__predef_detection__]] + [[`__hpux`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_HPUX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(hpux) || defined(_hpux) || defined(__hpux) \ + ) +# undef BOOST_OS_HPUX +# define BOOST_OS_HPUX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_HPUX +# define BOOST_OS_HPUX_AVAILABLE +# include +#endif + +#define BOOST_OS_HPUX_NAME "HP-UX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HPUX,BOOST_OS_HPUX_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/ios.h b/thirdparty/linux/include/boost/predef/os/ios.h new file mode 100644 index 0000000..f853815 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/ios.h @@ -0,0 +1,51 @@ +/* +Copyright Franz Detro 2014 +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_IOS_H +#define BOOST_PREDEF_OS_IOS_H + +#include +#include + +/*` +[heading `BOOST_OS_IOS`] + +[@http://en.wikipedia.org/wiki/iOS iOS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__APPLE__`] [__predef_detection__]] + [[`__MACH__`] [__predef_detection__]] + [[`__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__`] [__predef_detection__]] + + [[`__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__`] [__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__*1000]] + ] + */ + +#define BOOST_OS_IOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__APPLE__) && defined(__MACH__) && \ + defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) \ + ) +# undef BOOST_OS_IOS +# define BOOST_OS_IOS (__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__*1000) +#endif + +#if BOOST_OS_IOS +# define BOOST_OS_IOS_AVAILABLE +# include +#endif + +#define BOOST_OS_IOS_NAME "iOS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IOS,BOOST_OS_IOS_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/irix.h b/thirdparty/linux/include/boost/predef/os/irix.h new file mode 100644 index 0000000..fa6ac41 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/irix.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_IRIX_H +#define BOOST_PREDEF_OS_IRIX_H + +#include +#include + +/*` +[heading `BOOST_OS_IRIX`] + +[@http://en.wikipedia.org/wiki/Irix IRIX] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`sgi`] [__predef_detection__]] + [[`__sgi`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_IRIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(sgi) || defined(__sgi) \ + ) +# undef BOOST_OS_IRIX +# define BOOST_OS_IRIX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_IRIX +# define BOOST_OS_IRIX_AVAILABLE +# include +#endif + +#define BOOST_OS_IRIX_NAME "IRIX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IRIX,BOOST_OS_IRIX_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/linux.h b/thirdparty/linux/include/boost/predef/os/linux.h new file mode 100644 index 0000000..a297d08 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/linux.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_LINUX_H +#define BOOST_PREDEF_OS_LINUX_H + +#include +#include + +/*` +[heading `BOOST_OS_LINUX`] + +[@http://en.wikipedia.org/wiki/Linux Linux] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`linux`] [__predef_detection__]] + [[`__linux`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_LINUX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(linux) || defined(__linux) \ + ) +# undef BOOST_OS_LINUX +# define BOOST_OS_LINUX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_LINUX +# define BOOST_OS_LINUX_AVAILABLE +# include +#endif + +#define BOOST_OS_LINUX_NAME "Linux" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_LINUX,BOOST_OS_LINUX_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/macos.h b/thirdparty/linux/include/boost/predef/os/macos.h new file mode 100644 index 0000000..4afb30d --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/macos.h @@ -0,0 +1,65 @@ +/* +Copyright Rene Rivera 2008-2015 +Copyright Franz Detro 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_MACOS_H +#define BOOST_PREDEF_OS_MACOS_H + +/* Special case: iOS will define the same predefs as MacOS, and additionally + '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__'. We can guard against that, + but only if we detect iOS first. Hence we will force include iOS detection + * before doing any MacOS detection. + */ +#include + +#include +#include + +/*` +[heading `BOOST_OS_MACOS`] + +[@http://en.wikipedia.org/wiki/Mac_OS Mac OS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`macintosh`] [__predef_detection__]] + [[`Macintosh`] [__predef_detection__]] + [[`__APPLE__`] [__predef_detection__]] + [[`__MACH__`] [__predef_detection__]] + + [[`__APPLE__`, `__MACH__`] [10.0.0]] + [[ /otherwise/ ] [9.0.0]] + ] + */ + +#define BOOST_OS_MACOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(macintosh) || defined(Macintosh) || \ + (defined(__APPLE__) && defined(__MACH__)) \ + ) +# undef BOOST_OS_MACOS +# if !defined(BOOST_OS_MACOS) && defined(__APPLE__) && defined(__MACH__) +# define BOOST_OS_MACOS BOOST_VERSION_NUMBER(10,0,0) +# endif +# if !defined(BOOST_OS_MACOS) +# define BOOST_OS_MACOS BOOST_VERSION_NUMBER(9,0,0) +# endif +#endif + +#if BOOST_OS_MACOS +# define BOOST_OS_MACOS_AVAILABLE +# include +#endif + +#define BOOST_OS_MACOS_NAME "Mac OS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_MACOS,BOOST_OS_MACOS_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/os400.h b/thirdparty/linux/include/boost/predef/os/os400.h new file mode 100644 index 0000000..b3446c2 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/os400.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_OS400_H +#define BOOST_PREDEF_OS_OS400_H + +#include +#include + +/*` +[heading `BOOST_OS_OS400`] + +[@http://en.wikipedia.org/wiki/IBM_i IBM OS/400] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__OS400__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_OS400 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__OS400__) \ + ) +# undef BOOST_OS_OS400 +# define BOOST_OS_OS400 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_OS400 +# define BOOST_OS_OS400_AVAILABLE +# include +#endif + +#define BOOST_OS_OS400_NAME "IBM OS/400" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_OS400,BOOST_OS_OS400_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/qnxnto.h b/thirdparty/linux/include/boost/predef/os/qnxnto.h new file mode 100644 index 0000000..e76fbf2 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/qnxnto.h @@ -0,0 +1,59 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_QNXNTO_H +#define BOOST_PREDEF_OS_QNXNTO_H + +#include +#include + +/*` +[heading `BOOST_OS_QNX`] + +[@http://en.wikipedia.org/wiki/QNX QNX] operating system. +Version number available as major, and minor if possible. And +version 4 is specifically detected. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__QNX__`] [__predef_detection__]] + [[`__QNXNTO__`] [__predef_detection__]] + + [[`_NTO_VERSION`] [V.R.0]] + [[`__QNX__`] [4.0.0]] + ] + */ + +#define BOOST_OS_QNX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__QNX__) || defined(__QNXNTO__) \ + ) +# undef BOOST_OS_QNX +# if !defined(BOOST_OS_QNX) && defined(_NTO_VERSION) +# define BOOST_OS_QNX BOOST_PREDEF_MAKE_10_VVRR(_NTO_VERSION) +# endif +# if !defined(BOOST_OS_QNX) && defined(__QNX__) +# define BOOST_OS_QNX BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_OS_QNX) +# define BOOST_OS_QNX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_QNX +# define BOOST_OS_QNX_AVAILABLE +# include +#endif + +#define BOOST_OS_QNX_NAME "QNX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_QNX,BOOST_OS_QNX_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/solaris.h b/thirdparty/linux/include/boost/predef/os/solaris.h new file mode 100644 index 0000000..75ddc91 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/solaris.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_SOLARIS_H +#define BOOST_PREDEF_OS_SOLARIS_H + +#include +#include + +/*` +[heading `BOOST_OS_SOLARIS`] + +[@http://en.wikipedia.org/wiki/Solaris_Operating_Environment Solaris] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`sun`] [__predef_detection__]] + [[`__sun`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_SOLARIS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(sun) || defined(__sun) \ + ) +# undef BOOST_OS_SOLARIS +# define BOOST_OS_SOLARIS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_SOLARIS +# define BOOST_OS_SOLARIS_AVAILABLE +# include +#endif + +#define BOOST_OS_SOLARIS_NAME "Solaris" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SOLARIS,BOOST_OS_SOLARIS_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/unix.h b/thirdparty/linux/include/boost/predef/os/unix.h new file mode 100644 index 0000000..a607104 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/unix.h @@ -0,0 +1,76 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_UNIX_H +#define BOOST_PREDEF_OS_UNIX_H + +#include +#include + +/*` +[heading `BOOST_OS_UNIX`] + +[@http://en.wikipedia.org/wiki/Unix Unix Environment] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`unix`] [__predef_detection__]] + [[`__unix`] [__predef_detection__]] + [[`_XOPEN_SOURCE`] [__predef_detection__]] + [[`_POSIX_SOURCE`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_UNIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(unix) || defined(__unix) || \ + defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) +# undef BOOST_OS_UNIX +# define BOOST_OS_UNIX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_UNIX +# define BOOST_OS_UNIX_AVAILABLE +#endif + +#define BOOST_OS_UNIX_NAME "Unix Environment" + +/*` +[heading `BOOST_OS_SVR4`] + +[@http://en.wikipedia.org/wiki/UNIX_System_V SVR4 Environment] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__sysv__`] [__predef_detection__]] + [[`__SVR4`] [__predef_detection__]] + [[`__svr4__`] [__predef_detection__]] + [[`_SYSTYPE_SVR4`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_SVR4 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sysv__) || defined(__SVR4) || \ + defined(__svr4__) || defined(_SYSTYPE_SVR4) +# undef BOOST_OS_SVR4 +# define BOOST_OS_SVR4 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_SVR4 +# define BOOST_OS_SVR4_AVAILABLE +#endif + +#define BOOST_OS_SVR4_NAME "SVR4 Environment" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_UNIX,BOOST_OS_UNIX_NAME) +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SVR4,BOOST_OS_SVR4_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/vms.h b/thirdparty/linux/include/boost/predef/os/vms.h new file mode 100644 index 0000000..2f8f786 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/vms.h @@ -0,0 +1,52 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_VMS_H +#define BOOST_PREDEF_OS_VMS_H + +#include +#include + +/*` +[heading `BOOST_OS_VMS`] + +[@http://en.wikipedia.org/wiki/Vms VMS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`VMS`] [__predef_detection__]] + [[`__VMS`] [__predef_detection__]] + + [[`__VMS_VER`] [V.R.P]] + ] + */ + +#define BOOST_OS_VMS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(VMS) || defined(__VMS) \ + ) +# undef BOOST_OS_VMS +# if defined(__VMS_VER) +# define BOOST_OS_VMS BOOST_PREDEF_MAKE_10_VVRR00PP00(__VMS_VER) +# else +# define BOOST_OS_VMS BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_VMS +# define BOOST_OS_VMS_AVAILABLE +# include +#endif + +#define BOOST_OS_VMS_NAME "VMS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_VMS,BOOST_OS_VMS_NAME) diff --git a/thirdparty/linux/include/boost/predef/os/windows.h b/thirdparty/linux/include/boost/predef/os/windows.h new file mode 100644 index 0000000..9db4390 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/os/windows.h @@ -0,0 +1,51 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_WINDOWS_H +#define BOOST_PREDEF_OS_WINDOWS_H + +#include +#include + +/*` +[heading `BOOST_OS_WINDOWS`] + +[@http://en.wikipedia.org/wiki/Category:Microsoft_Windows Microsoft Windows] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_WIN32`] [__predef_detection__]] + [[`_WIN64`] [__predef_detection__]] + [[`__WIN32__`] [__predef_detection__]] + [[`__TOS_WIN__`] [__predef_detection__]] + [[`__WINDOWS__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(_WIN32) || defined(_WIN64) || \ + defined(__WIN32__) || defined(__TOS_WIN__) || \ + defined(__WINDOWS__) \ + ) +# undef BOOST_OS_WINDOWS +# define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_WINDOWS +# define BOOST_OS_WINDOWS_AVAILABLE +# include +#endif + +#define BOOST_OS_WINDOWS_NAME "Microsoft Windows" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_WINDOWS,BOOST_OS_WINDOWS_NAME) diff --git a/thirdparty/linux/include/boost/predef/other.h b/thirdparty/linux/include/boost/predef/other.h new file mode 100644 index 0000000..c09ad49 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/other.h @@ -0,0 +1,16 @@ +/* +Copyright Rene Rivera 2013-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_OTHER_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_OTHER_H +#define BOOST_PREDEF_OTHER_H +#endif + +#include +/*#include */ + +#endif diff --git a/thirdparty/linux/include/boost/predef/other/endian.h b/thirdparty/linux/include/boost/predef/other/endian.h new file mode 100644 index 0000000..6d1f43f --- /dev/null +++ b/thirdparty/linux/include/boost/predef/other/endian.h @@ -0,0 +1,204 @@ +/* +Copyright Rene Rivera 2013-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_ENDIAN_H +#define BOOST_PREDEF_ENDIAN_H + +#include +#include +#include +#include +#include +#include + +/*` +[heading `BOOST_ENDIAN_*`] + +Detection of endian memory ordering. There are four defined macros +in this header that define the various generally possible endian +memory orderings: + +* `BOOST_ENDIAN_BIG_BYTE`, byte-swapped big-endian. +* `BOOST_ENDIAN_BIG_WORD`, word-swapped big-endian. +* `BOOST_ENDIAN_LITTLE_BYTE`, byte-swapped little-endian. +* `BOOST_ENDIAN_LITTLE_WORD`, word-swapped little-endian. + +The detection is conservative in that it only identifies endianness +that it knows for certain. In particular bi-endianness is not +indicated as is it not practically possible to determine the +endianness from anything but an operating system provided +header. And the currently known headers do not define that +programatic bi-endianness is available. + +This implementation is a compilation of various publicly available +information and acquired knowledge: + +# The indispensable documentation of "Pre-defined Compiler Macros" + [@http://sourceforge.net/p/predef/wiki/Endianness Endianness]. +# The various endian specifications available in the + [@http://wikipedia.org/ Wikipedia] computer architecture pages. +# Generally available searches for headers that define endianness. + */ + +#define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_BIG_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE + +/* GNU libc provides a header defining __BYTE_ORDER, or _BYTE_ORDER. + * And some OSs provide some for of endian header also. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if BOOST_LIB_C_GNU || BOOST_OS_ANDROID +# include +# else +# if BOOST_OS_MACOS +# include +# else +# if BOOST_OS_BSD +# if BOOST_OS_BSD_OPEN +# include +# else +# include +# endif +# endif +# endif +# endif +# if defined(__BYTE_ORDER) +# if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if defined(__PDP_ENDIAN) && (__BYTE_ORDER == __PDP_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +# if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER) +# if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if defined(_PDP_ENDIAN) && (_BYTE_ORDER == _PDP_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +/* Built-in byte-swpped big-endian macros. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \ + (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \ + defined(__ARMEB__) || \ + defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || \ + defined(_MIPSEB) || \ + defined(__MIPSEB) || \ + defined(__MIPSEB__) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +/* Built-in byte-swpped little-endian macros. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ + (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \ + defined(__ARMEL__) || \ + defined(__THUMBEL__) || \ + defined(__AARCH64EL__) || \ + defined(_MIPSEL) || \ + defined(__MIPSEL) || \ + defined(__MIPSEL__) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +/* Some architectures are strictly one endianess (as opposed + * the current common bi-endianess). + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# include +# if BOOST_ARCH_M68K || \ + BOOST_ARCH_PARISC || \ + BOOST_ARCH_SPARC || \ + BOOST_ARCH_SYS370 || \ + BOOST_ARCH_SYS390 || \ + BOOST_ARCH_Z +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if BOOST_ARCH_AMD64 || \ + BOOST_ARCH_IA64 || \ + BOOST_ARCH_X86 || \ + BOOST_ARCH_BLACKFIN +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +/* Windows on ARM, if not otherwise detected/specified, is always + * byte-swaped little-endian. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if BOOST_ARCH_ARM +# include +# if BOOST_OS_WINDOWS +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +#if BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_BIG_WORD +# define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE +#endif + +#define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian" +#define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian" +#define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian" +#define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME) diff --git a/thirdparty/linux/include/boost/predef/platform.h b/thirdparty/linux/include/boost/predef/platform.h new file mode 100644 index 0000000..c0c8706 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/platform.h @@ -0,0 +1,21 @@ +/* +Copyright Rene Rivera 2013-2015 +Copyright (c) Microsoft Corporation 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_PLATFORM_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_PLATFORM_H +#define BOOST_PREDEF_PLATFORM_H +#endif + +#include +#include +#include +#include +#include +/*#include */ + +#endif diff --git a/thirdparty/linux/include/boost/predef/platform/mingw.h b/thirdparty/linux/include/boost/predef/platform/mingw.h new file mode 100644 index 0000000..64c5837 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/platform/mingw.h @@ -0,0 +1,69 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_COMPILER_MINGW_H +#define BOOST_PREDEF_COMPILER_MINGW_H + +#include +#include + +/*` +[heading `BOOST_PLAT_MINGW`] + +[@http://en.wikipedia.org/wiki/MinGW MinGW] platform. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__MINGW32__`] [__predef_detection__]] + [[`__MINGW64__`] [__predef_detection__]] + + [[`__MINGW64_VERSION_MAJOR`, `__MINGW64_VERSION_MINOR`] [V.R.0]] + [[`__MINGW32_VERSION_MAJOR`, `__MINGW32_VERSION_MINOR`] [V.R.0]] + ] + */ + +#define BOOST_PLAT_MINGW BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MINGW32__) || defined(__MINGW64__) +# include <_mingw.h> +# if !defined(BOOST_PLAT_MINGW_DETECTION) && (defined(__MINGW64_VERSION_MAJOR) && defined(__MINGW64_VERSION_MINOR)) +# define BOOST_PLAT_MINGW_DETECTION \ + BOOST_VERSION_NUMBER(__MINGW64_VERSION_MAJOR,__MINGW64_VERSION_MINOR,0) +# endif +# if !defined(BOOST_PLAT_MINGW_DETECTION) && (defined(__MINGW32_VERSION_MAJOR) && defined(__MINGW32_VERSION_MINOR)) +# define BOOST_PLAT_MINGW_DETECTION \ + BOOST_VERSION_NUMBER(__MINGW32_MAJOR_VERSION,__MINGW32_MINOR_VERSION,0) +# endif +# if !defined(BOOST_PLAT_MINGW_DETECTION) +# define BOOST_PLAT_MINGW_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_PLAT_MINGW_DETECTION +# define BOOST_PLAT_MINGW_AVAILABLE +# if defined(BOOST_PREDEF_DETAIL_PLAT_DETECTED) +# define BOOST_PLAT_MINGW_EMULATED BOOST_PLAT_MINGW_DETECTION +# else +# undef BOOST_PLAT_MINGW +# define BOOST_PLAT_MINGW BOOST_PLAT_MINGW_DETECTION +# endif +# include +#endif + +#define BOOST_PLAT_MINGW_NAME "MinGW" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW,BOOST_PLAT_MINGW_NAME) + +#ifdef BOOST_PLAT_MINGW_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW_EMULATED,BOOST_PLAT_MINGW_NAME) +#endif diff --git a/thirdparty/linux/include/boost/predef/platform/windows_desktop.h b/thirdparty/linux/include/boost/predef/platform/windows_desktop.h new file mode 100644 index 0000000..62719b4 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/platform/windows_desktop.h @@ -0,0 +1,45 @@ +/* +Copyright (c) Microsoft Corporation 2014 +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_DESKTOP_H +#define BOOST_PREDEF_PLAT_WINDOWS_DESKTOP_H + +#include +#include +#include + +/*` +[heading `BOOST_PLAT_WINDOWS_DESKTOP`] + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`!WINAPI_FAMILY`] [__predef_detection__]] + [[`WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP`] [__predef_detection__]] + ] + */ + +#define BOOST_PLAT_WINDOWS_DESKTOP BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && \ + ( !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) ) +# undef BOOST_PLAT_WINDOWS_DESKTOP +# define BOOST_PLAT_WINDOWS_DESKTOP BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_DESKTOP +# define BOOST_PLAT_WINDOWS_DESKTOP_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_DESKTOP_NAME "Windows Desktop" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_DESKTOP,BOOST_PLAT_WINDOWS_DESKTOP_NAME) diff --git a/thirdparty/linux/include/boost/predef/platform/windows_phone.h b/thirdparty/linux/include/boost/predef/platform/windows_phone.h new file mode 100644 index 0000000..df583ad --- /dev/null +++ b/thirdparty/linux/include/boost/predef/platform/windows_phone.h @@ -0,0 +1,43 @@ +/* +Copyright (c) Microsoft Corporation 2014 +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_PHONE_H +#define BOOST_PREDEF_PLAT_WINDOWS_PHONE_H + +#include +#include +#include + +/*` +[heading `BOOST_PLAT_WINDOWS_PHONE`] + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP`] [__predef_detection__]] + ] + */ + +#define BOOST_PLAT_WINDOWS_PHONE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +# undef BOOST_PLAT_WINDOWS_PHONE +# define BOOST_PLAT_WINDOWS_PHONE BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_PHONE +# define BOOST_PLAT_WINDOWS_PHONE_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_PHONE_NAME "Windows Phone" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_PHONE,BOOST_PLAT_WINDOWS_PHONE_NAME) diff --git a/thirdparty/linux/include/boost/predef/platform/windows_runtime.h b/thirdparty/linux/include/boost/predef/platform/windows_runtime.h new file mode 100644 index 0000000..03be514 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/platform/windows_runtime.h @@ -0,0 +1,45 @@ +/* +Copyright (c) Microsoft Corporation 2014 +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_RUNTIME_H +#define BOOST_PREDEF_PLAT_WINDOWS_RUNTIME_H + +#include +#include +#include + +/*` +[heading `BOOST_PLAT_WINDOWS_RUNTIME`] + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`WINAPI_FAMILY == WINAPI_FAMILY_APP`] [__predef_detection__]] + [[`WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP`] [__predef_detection__]] + ] + */ + +#define BOOST_PLAT_WINDOWS_RUNTIME BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && defined(WINAPI_FAMILY) && \ + ( WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP ) +# undef BOOST_PLAT_WINDOWS_RUNTIME +# define BOOST_PLAT_WINDOWS_RUNTIME BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_RUNTIME +# define BOOST_PLAT_WINDOWS_RUNTIME_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_RUNTIME_NAME "Windows Runtime" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_RUNTIME,BOOST_PLAT_WINDOWS_RUNTIME_NAME) diff --git a/thirdparty/linux/include/boost/predef/platform/windows_store.h b/thirdparty/linux/include/boost/predef/platform/windows_store.h new file mode 100644 index 0000000..a34968b --- /dev/null +++ b/thirdparty/linux/include/boost/predef/platform/windows_store.h @@ -0,0 +1,43 @@ +/* +Copyright (c) Microsoft Corporation 2014 +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_STORE_H +#define BOOST_PREDEF_PLAT_WINDOWS_STORE_H + +#include +#include +#include + +/*` +[heading `BOOST_PLAT_WINDOWS_STORE`] + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`WINAPI_FAMILY == WINAPI_FAMILY_APP`] [__predef_detection__]] + ] + */ + +#define BOOST_PLAT_WINDOWS_STORE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP +# undef BOOST_PLAT_WINDOWS_STORE +# define BOOST_PLAT_WINDOWS_STORE BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_STORE +# define BOOST_PLAT_WINDOWS_STORE_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_STORE_NAME "Windows Store" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_STORE,BOOST_PLAT_WINDOWS_STORE_NAME) diff --git a/thirdparty/linux/include/boost/predef/version.h b/thirdparty/linux/include/boost/predef/version.h new file mode 100644 index 0000000..8745c94 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/version.h @@ -0,0 +1,15 @@ +/* +Copyright Rene Rivera 2015-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_VERSION_H +#define BOOST_PREDEF_VERSION_H + +#include + +#define BOOST_PREDEF_VERSION BOOST_VERSION_NUMBER(1,4,1) + +#endif diff --git a/thirdparty/linux/include/boost/predef/version_number.h b/thirdparty/linux/include/boost/predef/version_number.h new file mode 100644 index 0000000..3903a36 --- /dev/null +++ b/thirdparty/linux/include/boost/predef/version_number.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2005, 2008-2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_VERSION_NUMBER_H +#define BOOST_PREDEF_VERSION_NUMBER_H + +/*` +[heading `BOOST_VERSION_NUMBER`] + +`` +BOOST_VERSION_NUMBER(major,minor,patch) +`` + +Defines standard version numbers, with these properties: + +* Decimal base whole numbers in the range \[0,1000000000). + The number range is designed to allow for a (2,2,5) triplet. + Which fits within a 32 bit value. +* The `major` number can be in the \[0,99\] range. +* The `minor` number can be in the \[0,99\] range. +* The `patch` number can be in the \[0,99999\] range. +* Values can be specified in any base. As the defined value + is an constant expression. +* Value can be directly used in both preprocessor and compiler + expressions for comparison to other similarly defined values. +* The implementation enforces the individual ranges for the + major, minor, and patch numbers. And values over the ranges + are truncated (modulo). + +*/ +#define BOOST_VERSION_NUMBER(major,minor,patch) \ + ( (((major)%100)*10000000) + (((minor)%100)*100000) + ((patch)%100000) ) + +#define BOOST_VERSION_NUMBER_MAX \ + BOOST_VERSION_NUMBER(99,99,99999) + +#define BOOST_VERSION_NUMBER_ZERO \ + BOOST_VERSION_NUMBER(0,0,0) + +#define BOOST_VERSION_NUMBER_MIN \ + BOOST_VERSION_NUMBER(0,0,1) + +#define BOOST_VERSION_NUMBER_AVAILABLE \ + BOOST_VERSION_NUMBER_MIN + +#define BOOST_VERSION_NUMBER_NOT_AVAILABLE \ + BOOST_VERSION_NUMBER_ZERO + +#endif diff --git a/thirdparty/linux/include/boost/shared_ptr.hpp b/thirdparty/linux/include/boost/shared_ptr.hpp new file mode 100644 index 0000000..d31978c --- /dev/null +++ b/thirdparty/linux/include/boost/shared_ptr.hpp @@ -0,0 +1,19 @@ +#ifndef BOOST_SHARED_PTR_HPP_INCLUDED +#define BOOST_SHARED_PTR_HPP_INCLUDED + +// +// shared_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001-2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include + +#endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/bad_weak_ptr.hpp b/thirdparty/linux/include/boost/smart_ptr/bad_weak_ptr.hpp new file mode 100644 index 0000000..582fad8 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/bad_weak_ptr.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED +#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/smart_ptr/bad_weak_ptr.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#ifdef __BORLANDC__ +# pragma warn -8026 // Functions with excep. spec. are not expanded inline +#endif + +namespace boost +{ + +// The standard library that comes with Borland C++ 5.5.1, 5.6.4 +// defines std::exception and its members as having C calling +// convention (-pc). When the definition of bad_weak_ptr +// is compiled with -ps, the compiler issues an error. +// Hence, the temporary #pragma option -pc below. + +#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564 +# pragma option push -pc +#endif + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +class bad_weak_ptr: public std::exception +{ +public: + + virtual char const * what() const throw() + { + return "tr1::bad_weak_ptr"; + } +}; + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564 +# pragma option pop +#endif + +} // namespace boost + +#ifdef __BORLANDC__ +# pragma warn .8026 // Functions with excep. spec. are not expanded inline +#endif + +#endif // #ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/lightweight_mutex.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/lightweight_mutex.hpp new file mode 100644 index 0000000..d46b193 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/lightweight_mutex.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lightweight_mutex.hpp - lightweight mutex +// +// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// typedef boost::detail::lightweight_mutex; +// +// boost::detail::lightweight_mutex is a header-only implementation of +// a subset of the Mutex concept requirements: +// +// http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex +// +// It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX. +// + +#include + +#if !defined(BOOST_HAS_THREADS) +# include +#elif defined(BOOST_HAS_PTHREADS) +# include +#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# include +#else +// Use #define BOOST_DISABLE_THREADS to avoid the error +# error Unrecognized threading platform +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/lwm_nop.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/lwm_nop.hpp new file mode 100644 index 0000000..521a88e --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/lwm_nop.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_nop.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +namespace detail +{ + +class lightweight_mutex +{ +public: + + typedef lightweight_mutex scoped_lock; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/lwm_pthreads.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/lwm_pthreads.hpp new file mode 100644 index 0000000..8eda518 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/lwm_pthreads.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_pthreads.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +class lightweight_mutex +{ +private: + + pthread_mutex_t m_; + + lightweight_mutex(lightweight_mutex const &); + lightweight_mutex & operator=(lightweight_mutex const &); + +public: + + lightweight_mutex() + { + +// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init + +#if defined(__hpux) && defined(_DECTHREADS_) + BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 ); +#else + BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 ); +#endif + } + + ~lightweight_mutex() + { + BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 ); + } + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock + { + private: + + pthread_mutex_t & m_; + + scoped_lock(scoped_lock const &); + scoped_lock & operator=(scoped_lock const &); + + public: + + scoped_lock(lightweight_mutex & m): m_(m.m_) + { + BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); + } + + ~scoped_lock() + { + BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); + } + }; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/lwm_win32_cs.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/lwm_win32_cs.hpp new file mode 100644 index 0000000..a93cf09 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/lwm_win32_cs.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_win32_cs.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov +// Copyright (c) Microsoft Corporation 2014 +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#ifdef BOOST_USE_WINDOWS_H +# include +#endif + +namespace boost +{ + +namespace detail +{ + +#ifndef BOOST_USE_WINDOWS_H + +struct critical_section +{ + struct critical_section_debug * DebugInfo; + long LockCount; + long RecursionCount; + void * OwningThread; + void * LockSemaphore; +#if defined(_WIN64) + unsigned __int64 SpinCount; +#else + unsigned long SpinCount; +#endif +}; + +#if BOOST_PLAT_WINDOWS_RUNTIME +extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(critical_section *, unsigned long, unsigned long); +#else +extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *); +#endif +extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *); +extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *); +extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *); + +#else + +typedef ::CRITICAL_SECTION critical_section; + +#endif // #ifndef BOOST_USE_WINDOWS_H + +class lightweight_mutex +{ +private: + + critical_section cs_; + + lightweight_mutex(lightweight_mutex const &); + lightweight_mutex & operator=(lightweight_mutex const &); + +public: + + lightweight_mutex() + { +#if BOOST_PLAT_WINDOWS_RUNTIME + InitializeCriticalSectionEx(&cs_, 4000, 0); +#else + InitializeCriticalSection(&cs_); +#endif + } + + ~lightweight_mutex() + { + DeleteCriticalSection(&cs_); + } + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock + { + private: + + lightweight_mutex & m_; + + scoped_lock(scoped_lock const &); + scoped_lock & operator=(scoped_lock const &); + + public: + + explicit scoped_lock(lightweight_mutex & m): m_(m) + { + EnterCriticalSection(&m_.cs_); + } + + ~scoped_lock() + { + LeaveCriticalSection(&m_.cs_); + } + }; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/operator_bool.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/operator_bool.hpp new file mode 100644 index 0000000..c0289b8 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/operator_bool.hpp @@ -0,0 +1,64 @@ +// This header intentionally has no include guards. +// +// Copyright (c) 2001-2009, 2012 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )\ + && !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130)) + + explicit operator bool () const BOOST_NOEXCEPT + { + return px != 0; + } + +#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) + + operator bool () const BOOST_NOEXCEPT + { + return px != 0; + } + +#elif defined( _MANAGED ) + + static void unspecified_bool( this_type*** ) + { + } + + typedef void (*unspecified_bool_type)( this_type*** ); + + operator unspecified_bool_type() const BOOST_NOEXCEPT + { + return px == 0? 0: unspecified_bool; + } + +#elif \ + ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ + ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ + ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) + + typedef element_type * (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const BOOST_NOEXCEPT + { + return px == 0? 0: &this_type::get; + } + +#else + + typedef element_type * this_type::*unspecified_bool_type; + + operator unspecified_bool_type() const BOOST_NOEXCEPT + { + return px == 0? 0: &this_type::px; + } + +#endif + + // operator! is redundant, but some compilers need it + bool operator! () const BOOST_NOEXCEPT + { + return px == 0; + } diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/quick_allocator.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/quick_allocator.hpp new file mode 100644 index 0000000..159bd5e --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/quick_allocator.hpp @@ -0,0 +1,199 @@ +#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/quick_allocator.hpp +// +// Copyright (c) 2003 David Abrahams +// Copyright (c) 2003 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#include +#include +#include + +#include // ::operator new, ::operator delete +#include // std::size_t + +namespace boost +{ + +namespace detail +{ + +template union freeblock +{ + typedef typename boost::type_with_alignment::type aligner_type; + aligner_type aligner; + char bytes[size]; + freeblock * next; +}; + +template struct allocator_impl +{ + typedef freeblock block; + + // It may seem odd to use such small pages. + // + // However, on a typical Windows implementation that uses + // the OS allocator, "normal size" pages interact with the + // "ordinary" operator new, slowing it down dramatically. + // + // 512 byte pages are handled by the small object allocator, + // and don't interfere with ::new. + // + // The other alternative is to use much bigger pages (1M.) + // + // It is surprisingly easy to hit pathological behavior by + // varying the page size. g++ 2.96 on Red Hat Linux 7.2, + // for example, passionately dislikes 496. 512 seems OK. + +#if defined(BOOST_QA_PAGE_SIZE) + + enum { items_per_page = BOOST_QA_PAGE_SIZE / size }; + +#else + + enum { items_per_page = 512 / size }; // 1048560 / size + +#endif + +#ifdef BOOST_HAS_THREADS + + static lightweight_mutex & mutex() + { + static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm; + static lightweight_mutex * pm = new( &fbm ) lightweight_mutex; + return *pm; + } + + static lightweight_mutex * mutex_init; + +#endif + + static block * free; + static block * page; + static unsigned last; + + static inline void * alloc() + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + if(block * x = free) + { + free = x->next; + return x; + } + else + { + if(last == items_per_page) + { + // "Listen to me carefully: there is no memory leak" + // -- Scott Meyers, Eff C++ 2nd Ed Item 10 + page = ::new block[items_per_page]; + last = 0; + } + + return &page[last++]; + } + } + + static inline void * alloc(std::size_t n) + { + if(n != size) // class-specific new called for a derived object + { + return ::operator new(n); + } + else + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + if(block * x = free) + { + free = x->next; + return x; + } + else + { + if(last == items_per_page) + { + page = ::new block[items_per_page]; + last = 0; + } + + return &page[last++]; + } + } + } + + static inline void dealloc(void * pv) + { + if(pv != 0) // 18.4.1.1/13 + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + block * pb = static_cast(pv); + pb->next = free; + free = pb; + } + } + + static inline void dealloc(void * pv, std::size_t n) + { + if(n != size) // class-specific delete called for a derived object + { + ::operator delete(pv); + } + else if(pv != 0) // 18.4.1.1/13 + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + block * pb = static_cast(pv); + pb->next = free; + free = pb; + } + } +}; + +#ifdef BOOST_HAS_THREADS + +template + lightweight_mutex * allocator_impl::mutex_init = &allocator_impl::mutex(); + +#endif + +template + freeblock * allocator_impl::free = 0; + +template + freeblock * allocator_impl::page = 0; + +template + unsigned allocator_impl::last = allocator_impl::items_per_page; + +template +struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of::value > +{ +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/shared_count.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/shared_count.hpp new file mode 100644 index 0000000..7996aa4 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/shared_count.hpp @@ -0,0 +1,709 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/shared_count.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#ifdef __BORLANDC__ +# pragma warn -8027 // Functions containing try are not expanded inline +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// In order to avoid circular dependencies with Boost.TR1 +// we make sure that our include of doesn't try to +// pull in the TR1 headers: that's why we use this header +// rather than including directly: +#include // std::auto_ptr +#include // std::less + +#ifdef BOOST_NO_EXCEPTIONS +# include // std::bad_alloc +#endif + +#include + +#if defined( BOOST_SP_DISABLE_DEPRECATED ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +namespace boost +{ + +namespace movelib +{ + + template< class T, class D > class unique_ptr; + +} // namespace movelib + +namespace detail +{ + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +int const shared_count_id = 0x2C35F101; +int const weak_count_id = 0x298C38A4; + +#endif + +struct sp_nothrow_tag {}; + +template< class D > struct sp_inplace_tag +{ +}; + +template< class T > class sp_reference_wrapper +{ +public: + + explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) ) + { + } + + template< class Y > void operator()( Y * p ) const + { + (*t_)( p ); + } + +private: + + T * t_; +}; + +template< class D > struct sp_convert_reference +{ + typedef D type; +}; + +template< class D > struct sp_convert_reference< D& > +{ + typedef sp_reference_wrapper< D > type; +}; + +class weak_count; + +class shared_count +{ +private: + + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class weak_count; + +public: + + shared_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + } + + template explicit shared_count( Y * p ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_p( p ); + } + catch(...) + { + boost::checked_delete( p ); + throw; + } + +#else + + pi_ = new sp_counted_impl_p( p ); + + if( pi_ == 0 ) + { + boost::checked_delete( p ); + boost::throw_exception( std::bad_alloc() ); + } + +#endif + } + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) + template shared_count( Y * p, D d ): pi_(0) +#else + template shared_count( P p, D d ): pi_(0) +#endif +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) + typedef Y* P; +#endif +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_pd(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + +#else + + pi_ = new sp_counted_impl_pd(p, d); + + if(pi_ == 0) + { + d(p); // delete p + boost::throw_exception(std::bad_alloc()); + } + +#endif + } + +#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) + + template< class P, class D > shared_count( P p, sp_inplace_tag ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_pd< P, D >( p ); + } + catch( ... ) + { + D::operator_fn( p ); // delete p + throw; + } + +#else + + pi_ = new sp_counted_impl_pd< P, D >( p ); + + if( pi_ == 0 ) + { + D::operator_fn( p ); // delete p + boost::throw_exception( std::bad_alloc() ); + } + +#endif // #ifndef BOOST_NO_EXCEPTIONS + } + +#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) + + template shared_count( P p, D d, A a ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + typedef sp_counted_impl_pda impl_type; + +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + typedef typename std::allocator_traits::template rebind_alloc< impl_type > A2; + +#else + + typedef typename A::template rebind< impl_type >::other A2; + +#endif + + A2 a2( a ); + +#ifndef BOOST_NO_EXCEPTIONS + + try + { +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + impl_type * pi = std::allocator_traits::allocate( a2, 1 ); + pi_ = pi; + std::allocator_traits::construct( a2, pi, p, d, a ); + +#else + + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); + +#endif + } + catch(...) + { + d( p ); + + if( pi_ != 0 ) + { + a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); + } + + throw; + } + +#else + +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + impl_type * pi = std::allocator_traits::allocate( a2, 1 ); + pi_ = pi; + +#else + + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + +#endif + + if( pi_ != 0 ) + { +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + std::allocator_traits::construct( a2, pi, p, d, a ); + +#else + + ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); + +#endif + } + else + { + d( p ); + boost::throw_exception( std::bad_alloc() ); + } + +#endif + } + +#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) + + template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + typedef sp_counted_impl_pda< P, D, A > impl_type; + +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + typedef typename std::allocator_traits::template rebind_alloc< impl_type > A2; + +#else + + typedef typename A::template rebind< impl_type >::other A2; + +#endif + + A2 a2( a ); + +#ifndef BOOST_NO_EXCEPTIONS + + try + { +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + impl_type * pi = std::allocator_traits::allocate( a2, 1 ); + pi_ = pi; + std::allocator_traits::construct( a2, pi, p, a ); + +#else + + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + ::new( static_cast< void* >( pi_ ) ) impl_type( p, a ); + +#endif + } + catch(...) + { + D::operator_fn( p ); + + if( pi_ != 0 ) + { + a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); + } + + throw; + } + +#else + +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + impl_type * pi = std::allocator_traits::allocate( a2, 1 ); + pi_ = pi; + +#else + + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + +#endif + + if( pi_ != 0 ) + { +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + std::allocator_traits::construct( a2, pi, p, a ); + +#else + + ::new( static_cast< void* >( pi_ ) ) impl_type( p, a ); + +#endif + } + else + { + D::operator_fn( p ); + boost::throw_exception( std::bad_alloc() ); + } + +#endif // #ifndef BOOST_NO_EXCEPTIONS + } + +#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING ) + +#ifndef BOOST_NO_AUTO_PTR + + // auto_ptr is special cased to provide the strong guarantee + + template + explicit shared_count( std::auto_ptr & r ): pi_( new sp_counted_impl_p( r.get() ) ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifdef BOOST_NO_EXCEPTIONS + + if( pi_ == 0 ) + { + boost::throw_exception(std::bad_alloc()); + } + +#endif + + r.release(); + } + +#endif + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + + template + explicit shared_count( std::unique_ptr & r ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + typedef typename sp_convert_reference::type D2; + + D2 d2( r.get_deleter() ); + pi_ = new sp_counted_impl_pd< typename std::unique_ptr::pointer, D2 >( r.get(), d2 ); + +#ifdef BOOST_NO_EXCEPTIONS + + if( pi_ == 0 ) + { + boost::throw_exception( std::bad_alloc() ); + } + +#endif + + r.release(); + } + +#endif + + template + explicit shared_count( boost::movelib::unique_ptr & r ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + typedef typename sp_convert_reference::type D2; + + D2 d2( r.get_deleter() ); + pi_ = new sp_counted_impl_pd< typename boost::movelib::unique_ptr::pointer, D2 >( r.get(), d2 ); + +#ifdef BOOST_NO_EXCEPTIONS + + if( pi_ == 0 ) + { + boost::throw_exception( std::bad_alloc() ); + } + +#endif + + r.release(); + } + + ~shared_count() // nothrow + { + if( pi_ != 0 ) pi_->release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if( pi_ != 0 ) pi_->add_ref_copy(); + } + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + shared_count(shared_count && r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + r.pi_ = 0; + } + +#endif + + explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 + shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0 + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if( tmp != 0 ) tmp->add_ref_copy(); + if( pi_ != 0 ) pi_->release(); + pi_ = tmp; + } + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + bool empty() const // nothrow + { + return pi_ == 0; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less()( a.pi_, b.pi_ ); + } + + void * get_deleter( sp_typeinfo const & ti ) const + { + return pi_? pi_->get_deleter( ti ): 0; + } + + void * get_untyped_deleter() const + { + return pi_? pi_->get_untyped_deleter(): 0; + } +}; + + +class weak_count +{ +private: + + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class shared_count; + +public: + + weak_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + } + + weak_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + weak_count(weak_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + +// Move support + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + weak_count(weak_count && r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + r.pi_ = 0; + } + +#endif + + ~weak_count() // nothrow + { + if(pi_ != 0) pi_->weak_release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + weak_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + } + + return *this; + } + + weak_count & operator= (weak_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + } + + return *this; + } + + void swap(weak_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool empty() const // nothrow + { + return pi_ == 0; + } + + friend inline bool operator==(weak_count const & a, weak_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(weak_count const & a, weak_count const & b) + { + return std::less()(a.pi_, b.pi_); + } +}; + +inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif +{ + if( pi_ == 0 || !pi_->add_ref_lock() ) + { + boost::throw_exception( boost::bad_weak_ptr() ); + } +} + +inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif +{ + if( pi_ != 0 && !pi_->add_ref_lock() ) + { + pi_ = 0; + } +} + +} // namespace detail + +} // namespace boost + +#if defined( BOOST_SP_DISABLE_DEPRECATED ) +#pragma GCC diagnostic pop +#endif + +#ifdef __BORLANDC__ +# pragma warn .8027 // Functions containing try are not expanded inline +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_convertible.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_convertible.hpp new file mode 100644 index 0000000..4bba9ed --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_convertible.hpp @@ -0,0 +1,92 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_convertible.hpp +// +// Copyright 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE ) +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 ) +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 ) +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + +namespace boost +{ + +namespace detail +{ + +template< class Y, class T > struct sp_convertible +{ + typedef char (&yes) [1]; + typedef char (&no) [2]; + + static yes f( T* ); + static no f( ... ); + + enum _vt { value = sizeof( (f)( static_cast(0) ) ) == sizeof(yes) }; +}; + +template< class Y, class T > struct sp_convertible< Y, T[] > +{ + enum _vt { value = false }; +}; + +template< class Y, class T > struct sp_convertible< Y[], T[] > +{ + enum _vt { value = sp_convertible< Y[1], T[1] >::value }; +}; + +template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] > +{ + enum _vt { value = sp_convertible< Y[1], T[1] >::value }; +}; + +struct sp_empty +{ +}; + +template< bool > struct sp_enable_if_convertible_impl; + +template<> struct sp_enable_if_convertible_impl +{ + typedef sp_empty type; +}; + +template<> struct sp_enable_if_convertible_impl +{ +}; + +template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value > +{ +}; + +} // namespace detail + +} // namespace boost + +#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base.hpp new file mode 100644 index 0000000..83ede23 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -0,0 +1,96 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base.hpp +// +// Copyright 2005-2013 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +#if defined( __clang__ ) && defined( __has_extension ) +# if __has_extension( __c_atomic__ ) +# define BOOST_SP_HAS_CLANG_C11_ATOMICS +# endif +#endif + +#if defined( BOOST_SP_DISABLE_THREADS ) +# include + +#elif defined( BOOST_SP_USE_STD_ATOMIC ) +# include + +#elif defined( BOOST_SP_USE_SPINLOCK ) +# include + +#elif defined( BOOST_SP_USE_PTHREADS ) +# include + +#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 ) +# include + +#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS ) +# include + +#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) +# include + +#elif defined( __SNC__ ) +# include + +#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__) +# include + +#elif defined(__HP_aCC) && defined(__ia64) +# include + +#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__) +# include + +#elif defined( __IBMCPP__ ) && defined( __powerpc ) +# include + +#elif defined( __MWERKS__ ) && defined( __POWERPC__ ) +# include + +#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX ) +# include + +#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 ) +# include + +#elif defined( BOOST_SP_HAS_SYNC ) +# include + +#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) ) +# include + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__) +# include + +#elif defined( _AIX ) +# include + +#elif !defined( BOOST_HAS_THREADS ) +# include + +#else +# include + +#endif + +#undef BOOST_SP_HAS_CLANG_C11_ATOMICS + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp new file mode 100644 index 0000000..cebc243 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp @@ -0,0 +1,151 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED + +// +// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64 +// +// Copyright 2007 Baruch Zilber +// Copyright 2007 Boris Gubenko +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int r = static_cast(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE)); + if (1 == r) + { + _Asm_mf(); + } + + return r - 1; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int v = *pw; + + for (;;) + { + if (0 == v) + { + return 0; + } + + _Asm_mov_to_ar(_AREG_CCV, + v, + (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE)); + int r = static_cast(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE)); + if (r == v) + { + return r + 1; + } + + v = r; + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); // TODO use ld.acq here + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp new file mode 100644 index 0000000..fe6c727 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp @@ -0,0 +1,143 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED + +// +// detail/sp_counted_base_aix.hpp +// based on: detail/sp_counted_base_w32.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2006 Michael van der Westhuizen +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int32_t* pw ) +{ + // ++*pw; + + fetch_and_add( pw, 1 ); +} + +inline int32_t atomic_decrement( int32_t * pw ) +{ + // return --*pw; + + int32_t originalValue; + + __lwsync(); + originalValue = fetch_and_add( pw, -1 ); + __isync(); + + return (originalValue - 1); +} + +inline int32_t atomic_conditional_increment( int32_t * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int32_t tmp = fetch_and_add( pw, 0 ); + for( ;; ) + { + if( tmp == 0 ) return 0; + if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1); + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int32_t use_count_; // #shared + int32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return fetch_and_add( const_cast(&use_count_), 0 ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp new file mode 100644 index 0000000..7598495 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp @@ -0,0 +1,149 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_clang.hpp - __c11 clang intrinsics +// +// Copyright (c) 2007, 2013, 2015 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ + +namespace detail +{ + +typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t; + +inline void atomic_increment( atomic_int_least32_t * pw ) +{ + __c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED ); +} + +inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) +{ + return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL ); +} + +inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED ); + + for( ;; ) + { + if( r == 0 ) + { + return r; + } + + if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) ) + { + return r; + } + } +} + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + atomic_int_least32_t use_count_; // #shared + atomic_int_least32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base() + { + __c11_atomic_init( &use_count_, 1 ); + __c11_atomic_init( &weak_count_, 1 ); + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE ); + } +}; + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp new file mode 100644 index 0000000..6c268e8 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -0,0 +1,171 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( register long * pw ) +{ + register int a; + + asm + { +loop: + + lwarx a, 0, pw + addi a, a, 1 + stwcx. a, 0, pw + bne- loop + } +} + +inline long atomic_decrement( register long * pw ) +{ + register int a; + + asm + { + sync + +loop: + + lwarx a, 0, pw + addi a, a, -1 + stwcx. a, 0, pw + bne- loop + + isync + } + + return a; +} + +inline long atomic_conditional_increment( register long * pw ) +{ + register int a; + + asm + { +loop: + + lwarx a, 0, pw + cmpwi a, 0 + beq store + + addi a, a, 1 + +store: + + stwcx. a, 0, pw + bne- loop + } + + return a; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp new file mode 100644 index 0000000..f6e3904 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp @@ -0,0 +1,158 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED + +// +// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64 +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2006 Peter Dimov +// Copyright 2005 Ben Hutchings +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + // No barrier is required here but fetchadd always has an acquire or + // release barrier associated with it. We choose release as it should be + // cheaper. + __asm__ ("fetchadd4.rel %0=%1,1" : + "=r"(tmp), "=m"(*pw) : + "m"( *pw )); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv; + + __asm__ (" fetchadd4.rel %0=%1,-1 ;; \n" + " cmp.eq p7,p0=1,%0 ;; \n" + "(p7) ld4.acq %0=%1 " : + "=&r"(rv), "=m"(*pw) : + "m"( *pw ) : + "p7"); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv, tmp, tmp2; + + __asm__ ("0: ld4 %0=%3 ;; \n" + " cmp.eq p7,p0=0,%0 ;; \n" + "(p7) br.cond.spnt 1f \n" + " mov ar.ccv=%0 \n" + " add %1=1,%0 ;; \n" + " cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n" + " cmp.ne p7,p0=%0,%2 ;; \n" + "(p7) br.cond.spnt 0b \n" + " mov %0=%1 ;; \n" + "1:" : + "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) : + "m"( *pw ) : + "ar.ccv", "p7"); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); // TODO use ld.acq here + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp new file mode 100644 index 0000000..545c8ae --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS +// +// Copyright (c) 2009, Spirent Communications, Inc. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + ".set push\n\t" + ".set mips2\n\t" + "ll %0, %1\n\t" + "addiu %0, 1\n\t" + "sc %0, %1\n\t" + ".set pop\n\t" + "beqz %0, 0b": + "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ) + ); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv, tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + ".set push\n\t" + ".set mips2\n\t" + "ll %1, %2\n\t" + "addiu %0, %1, -1\n\t" + "sc %0, %2\n\t" + ".set pop\n\t" + "beqz %0, 0b\n\t" + "addiu %0, %1, -1": + "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ): + "memory" + ); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv, tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + ".set push\n\t" + ".set mips2\n\t" + "ll %0, %2\n\t" + "beqz %0, 1f\n\t" + "addiu %1, %0, 1\n\t" + "sc %1, %2\n\t" + ".set pop\n\t" + "beqz %1, 0b\n\t" + "addiu %0, %0, 1\n\t" + "1:": + "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ): + "memory" + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp new file mode 100644 index 0000000..2e5bc0e --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + __asm__ + ( + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "addi %1, %1, 1\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b": + + "=m"( *pw ), "=&b"( tmp ): + "r"( pw ), "m"( *pw ): + "cc" + ); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv; + + __asm__ __volatile__ + ( + "sync\n\t" + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "addi %1, %1, -1\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b\n\t" + "isync": + + "=m"( *pw ), "=&b"( rv ): + "r"( pw ), "m"( *pw ): + "memory", "cc" + ); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv; + + __asm__ + ( + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "cmpwi %1, 0\n\t" + "beq 1f\n\t" + "addi %1, %1, 1\n\t" + "1:\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b": + + "=m"( *pw ), "=&b"( rv ): + "r"( pw ), "m"( *pw ): + "cc" + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp new file mode 100644 index 0000000..c6d20ce --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+ +// +// Copyright (c) 2006 Piotr Wyderski +// Copyright (c) 2006 Tomas Puverle +// Copyright (c) 2006 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// Thanks to Michael van der Westhuizen + +#include +#include // int32_t + +namespace boost +{ + +namespace detail +{ + +inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ ) +{ + __asm__ __volatile__( "cas [%1], %2, %0" + : "+r" (swap_) + : "r" (dest_), "r" (compare_) + : "memory" ); + + return swap_; +} + +inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv ) +{ + // long r = *pw; + // *pw += dv; + // return r; + + for( ;; ) + { + int32_t r = *pw; + + if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) ) + { + return r; + } + } +} + +inline void atomic_increment( int32_t * pw ) +{ + atomic_fetch_and_add( pw, 1 ); +} + +inline int32_t atomic_decrement( int32_t * pw ) +{ + return atomic_fetch_and_add( pw, -1 ); +} + +inline int32_t atomic_conditional_increment( int32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + for( ;; ) + { + int32_t r = *pw; + + if( r == 0 ) + { + return r; + } + + if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) ) + { + return r; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int32_t use_count_; // #shared + int32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return const_cast< int32_t const volatile & >( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp new file mode 100644 index 0000000..173dce5 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -0,0 +1,174 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64 +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline int atomic_exchange_and_add( int * pw, int dv ) +{ + // int r = *pw; + // *pw += dv; + // return r; + + int r; + + __asm__ __volatile__ + ( + "lock\n\t" + "xadd %1, %0": + "=m"( *pw ), "=r"( r ): // outputs (%0, %1) + "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1) + "memory", "cc" // clobbers + ); + + return r; +} + +inline void atomic_increment( int * pw ) +{ + //atomic_exchange_and_add( pw, 1 ); + + __asm__ + ( + "lock\n\t" + "incl %0": + "=m"( *pw ): // output (%0) + "m"( *pw ): // input (%1) + "cc" // clobbers + ); +} + +inline int atomic_conditional_increment( int * pw ) +{ + // int rv = *pw; + // if( rv != 0 ) ++*pw; + // return rv; + + int rv, tmp; + + __asm__ + ( + "movl %0, %%eax\n\t" + "0:\n\t" + "test %%eax, %%eax\n\t" + "je 1f\n\t" + "movl %%eax, %2\n\t" + "incl %2\n\t" + "lock\n\t" + "cmpxchgl %2, %0\n\t" + "jne 0b\n\t" + "1:": + "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2) + "m"( *pw ): // input (%3) + "cc" // clobbers + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp new file mode 100644 index 0000000..5c901f9 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp @@ -0,0 +1,108 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_nt.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + ++use_count_; + } + + bool add_ref_lock() // true on success + { + if( use_count_ == 0 ) return false; + ++use_count_; + return true; + } + + void release() // nothrow + { + if( --use_count_ == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + ++weak_count_; + } + + void weak_release() // nothrow + { + if( --weak_count_ == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return use_count_; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp new file mode 100644 index 0000000..a16d2d8 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_pt.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + + mutable pthread_mutex_t m_; + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { +// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init + +#if defined(__hpux) && defined(_DECTHREADS_) + BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 ); +#else + BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 ); +#endif + } + + virtual ~sp_counted_base() // nothrow + { + BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 ); + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); + ++use_count_; + BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); + } + + bool add_ref_lock() // true on success + { + BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); + bool r = use_count_ == 0? false: ( ++use_count_, true ); + BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); + return r; + } + + void release() // nothrow + { + BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); + long new_use_count = --use_count_; + BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); + + if( new_use_count == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); + ++weak_count_; + BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); + } + + void weak_release() // nothrow + { + BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); + long new_weak_count = --weak_count_; + BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); + + if( new_weak_count == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); + long r = use_count_; + BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); + + return r; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp new file mode 100644 index 0000000..56ed79f --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -0,0 +1,162 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+ +// +// Copyright (c) 2006 Piotr Wyderski +// Copyright (c) 2006 Tomas Puverle +// Copyright (c) 2006 Peter Dimov +// Copyright (c) 2011 Emil Dotchevski +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// Thanks to Michael van der Westhuizen + +#include +#include // uint32_t + +namespace boost +{ + +namespace detail +{ + +inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ ) +{ + return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_); +} + +inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv ) +{ + // long r = *pw; + // *pw += dv; + // return r; + + for( ;; ) + { + uint32_t r = *pw; + + if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) ) + { + return r; + } + } +} + +inline void atomic_increment( uint32_t * pw ) +{ + (void) __builtin_cellAtomicIncr32( pw ); +} + +inline uint32_t atomic_decrement( uint32_t * pw ) +{ + return __builtin_cellAtomicDecr32( pw ); +} + +inline uint32_t atomic_conditional_increment( uint32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + for( ;; ) + { + uint32_t r = *pw; + + if( r == 0 ) + { + return r; + } + + if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) ) + { + return r; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + uint32_t use_count_; // #shared + uint32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return const_cast< uint32_t const volatile & >( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp new file mode 100644 index 0000000..77734e7 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp @@ -0,0 +1,132 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline int atomic_exchange_and_add( int * pw, int dv ) +{ + spinlock_pool<1>::scoped_lock lock( pw ); + + int r = *pw; + *pw += dv; + return r; +} + +inline void atomic_increment( int * pw ) +{ + spinlock_pool<1>::scoped_lock lock( pw ); + ++*pw; +} + +inline int atomic_conditional_increment( int * pw ) +{ + spinlock_pool<1>::scoped_lock lock( pw ); + + int rv = *pw; + if( rv != 0 ) ++*pw; + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + spinlock_pool<1>::scoped_lock lock( &use_count_ ); + return use_count_; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp new file mode 100644 index 0000000..cab8453 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_std_atomic.hpp - C++11 std::atomic +// +// Copyright (c) 2007, 2013 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( std::atomic_int_least32_t * pw ) +{ + pw->fetch_add( 1, std::memory_order_relaxed ); +} + +inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) +{ + return pw->fetch_sub( 1, std::memory_order_acq_rel ); +} + +inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + std::int_least32_t r = pw->load( std::memory_order_relaxed ); + + for( ;; ) + { + if( r == 0 ) + { + return r; + } + + if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) ) + { + return r; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + std::atomic_int_least32_t use_count_; // #shared + std::atomic_int_least32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return use_count_.load( std::memory_order_acquire ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp new file mode 100644 index 0000000..fafed0e --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp @@ -0,0 +1,156 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics +// +// Copyright (c) 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined( __ia64__ ) && defined( __INTEL_COMPILER ) +# include +#endif + +namespace boost +{ + +namespace detail +{ + +#if INT_MAX >= 2147483647 + +typedef int sp_int32_t; + +#else + +typedef long sp_int32_t; + +#endif + +inline void atomic_increment( sp_int32_t * pw ) +{ + __sync_fetch_and_add( pw, 1 ); +} + +inline sp_int32_t atomic_decrement( sp_int32_t * pw ) +{ + return __sync_fetch_and_add( pw, -1 ); +} + +inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + sp_int32_t r = *pw; + + for( ;; ) + { + if( r == 0 ) + { + return r; + } + + sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 ); + + if( r2 == r ) + { + return r; + } + else + { + r = r2; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + sp_int32_t use_count_; // #shared + sp_int32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return const_cast< sp_int32_t const volatile & >( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp new file mode 100644 index 0000000..162f309 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp @@ -0,0 +1,151 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED + +// +// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER +// based on: detail/sp_counted_base_w32.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2006 Michael van der Westhuizen +// Copyright 2012 IBM Corp. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include + +extern "builtin" void __lwsync(void); +extern "builtin" void __isync(void); +extern "builtin" int __fetch_and_add(volatile int* addr, int val); +extern "builtin" int __compare_and_swap(volatile int*, int*, int); + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int *pw ) +{ + // ++*pw; + __lwsync(); + __fetch_and_add(pw, 1); + __isync(); +} + +inline int atomic_decrement( int *pw ) +{ + // return --*pw; + __lwsync(); + int originalValue = __fetch_and_add(pw, -1); + __isync(); + + return (originalValue - 1); +} + +inline int atomic_conditional_increment( int *pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + __lwsync(); + int v = *const_cast(pw); + for (;;) + // loop until state is known + { + if (v == 0) return 0; + if (__compare_and_swap(pw, &v, v + 1)) + { + __isync(); return (v + 1); + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + char pad[64] __attribute__((__aligned__(64))); + // pad to prevent false sharing +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return *const_cast(&use_count_); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp new file mode 100644 index 0000000..4ba509c --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -0,0 +1,131 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_w32.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + for( ;; ) + { + long tmp = static_cast< long const volatile& >( use_count_ ); + if( tmp == 0 ) return false; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 ) + + // work around a code generation bug + + long tmp2 = tmp + 1; + if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true; + +#else + + if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; + +#endif + } + } + + void release() // nothrow + { + if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( BOOST_SP_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_impl.hpp new file mode 100644 index 0000000..1222f3c --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -0,0 +1,271 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_impl.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) +# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. +#endif + +#include +#include + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) +#include +#endif + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) +#include // std::allocator +#endif + +#include // std::size_t + +namespace boost +{ + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn ); +void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn ); + +#endif + +namespace detail +{ + +template class sp_counted_impl_p: public sp_counted_base +{ +private: + + X * px_; + + sp_counted_impl_p( sp_counted_impl_p const & ); + sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); + + typedef sp_counted_impl_p this_type; + +public: + + explicit sp_counted_impl_p( X * px ): px_( px ) + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_constructor_hook( px, sizeof(X), this ); +#endif + } + + virtual void dispose() // nothrow + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); +#endif + boost::checked_delete( px_ ); + } + + virtual void * get_deleter( sp_typeinfo const & ) + { + return 0; + } + + virtual void * get_untyped_deleter() + { + return 0; + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } + + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new( std::size_t ) + { + return quick_allocator::alloc(); + } + + void operator delete( void * p ) + { + quick_allocator::dealloc( p ); + } + +#endif +}; + +// +// Borland's Codeguard trips up over the -Vx- option here: +// +#ifdef __CODEGUARD__ +# pragma option push -Vx- +#endif + +template class sp_counted_impl_pd: public sp_counted_base +{ +private: + + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_impl_pd( sp_counted_impl_pd const & ); + sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); + + typedef sp_counted_impl_pd this_type; + +public: + + // pre: d(p) must not throw + + sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d ) + { + } + + sp_counted_impl_pd( P p ): ptr( p ), del() + { + } + + virtual void dispose() // nothrow + { + del( ptr ); + } + + virtual void * get_deleter( sp_typeinfo const & ti ) + { + return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast( del ): 0; + } + + virtual void * get_untyped_deleter() + { + return &reinterpret_cast( del ); + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } + + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new( std::size_t ) + { + return quick_allocator::alloc(); + } + + void operator delete( void * p ) + { + quick_allocator::dealloc( p ); + } + +#endif +}; + +template class sp_counted_impl_pda: public sp_counted_base +{ +private: + + P p_; // copy constructor must not throw + D d_; // copy constructor must not throw + A a_; // copy constructor must not throw + + sp_counted_impl_pda( sp_counted_impl_pda const & ); + sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & ); + + typedef sp_counted_impl_pda this_type; + +public: + + // pre: d( p ) must not throw + + sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a ) + { + } + + sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a ) + { + } + + virtual void dispose() // nothrow + { + d_( p_ ); + } + + virtual void destroy() // nothrow + { +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + typedef typename std::allocator_traits::template rebind_alloc< this_type > A2; + +#else + + typedef typename A::template rebind< this_type >::other A2; + +#endif + + A2 a2( a_ ); + +#if !defined( BOOST_NO_CXX11_ALLOCATOR ) + + std::allocator_traits::destroy( a2, this ); + +#else + + this->~this_type(); + +#endif + + a2.deallocate( this, 1 ); + } + + virtual void * get_deleter( sp_typeinfo const & ti ) + { + return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast( d_ ): 0; + } + + virtual void * get_untyped_deleter() + { + return &reinterpret_cast( d_ ); + } +}; + +#ifdef __CODEGUARD__ +# pragma option pop +#endif + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp new file mode 100644 index 0000000..f79bdf3 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/smart_ptr/detail/sp_disable_deprecated.hpp +// +// Copyright 2015 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined( __GNUC__ ) && ( defined( __GXX_EXPERIMENTAL_CXX0X__ ) || ( __cplusplus >= 201103L ) ) + +# if defined( BOOST_GCC ) + +# if BOOST_GCC >= 40600 +# define BOOST_SP_DISABLE_DEPRECATED +# endif + +# elif defined( __clang__ ) && defined( __has_warning ) + +# if __has_warning( "-Wdeprecated-declarations" ) +# define BOOST_SP_DISABLE_DEPRECATED +# endif + +# endif + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_has_sync.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_has_sync.hpp new file mode 100644 index 0000000..16de21d --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_has_sync.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/smart_ptr/detail/sp_has_sync.hpp +// +// Copyright (c) 2008, 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics +// are available. +// + +#ifndef BOOST_SP_NO_SYNC + +#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) + +# define BOOST_SP_HAS_SYNC + +#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) + +# define BOOST_SP_HAS_SYNC + +#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) + +#define BOOST_SP_HAS_SYNC + +#if defined( __arm__ ) || defined( __armel__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __hppa ) || defined( __hppa__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __m68k__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __sh__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __sparc__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9)) +#undef BOOST_SP_HAS_SYNC +#endif + +#endif + +#endif // #ifndef BOOST_SP_NO_SYNC + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_interlocked.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_interlocked.hpp new file mode 100644 index 0000000..79cae14 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_interlocked.hpp @@ -0,0 +1,163 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/sp_interlocked.hpp +// +// Copyright 2005, 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +// BOOST_SP_HAS_INTRIN_H + +// VC9 has intrin.h, but it collides with +#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600 + +# define BOOST_SP_HAS_INTRIN_H + +// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. +#elif defined( __MINGW64_VERSION_MAJOR ) + +// MinGW-w64 provides intrin.h for both 32 and 64-bit targets. +# define BOOST_SP_HAS_INTRIN_H + +// Intel C++ on Windows on VC10+ stdlib +#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520 + +# define BOOST_SP_HAS_INTRIN_H + +#endif + +#if defined( BOOST_USE_WINDOWS_H ) + +# include + +# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H ) + +#include + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#elif defined( _WIN32_WCE ) + +#if _WIN32_WCE >= 0x600 + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#else + +// under Windows CE we still have old-style Interlocked* functions + +extern "C" long __cdecl InterlockedIncrement( long* ); +extern "C" long __cdecl InterlockedDecrement( long* ); +extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); +extern "C" long __cdecl InterlockedExchange( long*, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); + +# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +#endif + +#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) + +#if defined( __CLRCALL_PURE_OR_CDECL ) + +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); + +#else + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +# if defined( BOOST_MSVC ) && BOOST_MSVC == 1310 +//From MSDN, Visual Studio .NET 2003 spedific: To declare one of the interlocked functions +//for use as an intrinsic, the function must be declared with the leading underscore and +//the new function must appear in a #pragma intrinsic statement. +# pragma intrinsic( _InterlockedIncrement ) +# pragma intrinsic( _InterlockedDecrement ) +# pragma intrinsic( _InterlockedCompareExchange ) +# pragma intrinsic( _InterlockedExchange ) +# pragma intrinsic( _InterlockedExchangeAdd ) +# endif + +#endif + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +namespace boost +{ + +namespace detail +{ + +extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); + +} // namespace detail + +} // namespace boost + +# define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd + +#else + +# error "Interlocked intrinsics not available" + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/sp_nullptr_t.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/sp_nullptr_t.hpp new file mode 100644 index 0000000..219ae80 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/sp_nullptr_t.hpp @@ -0,0 +1,45 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_nullptr_t.hpp +// +// Copyright 2013 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +namespace boost +{ + +namespace detail +{ + +#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) ) + + typedef decltype(nullptr) sp_nullptr_t; + +#else + + typedef std::nullptr_t sp_nullptr_t; + +#endif + +} // namespace detail + +} // namespace boost + +#endif // !defined( BOOST_NO_CXX11_NULLPTR ) + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/spinlock.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock.hpp new file mode 100644 index 0000000..0b618df --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/spinlock.hpp +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// struct spinlock +// { +// void lock(); +// bool try_lock(); +// void unlock(); +// +// class scoped_lock; +// }; +// +// #define BOOST_DETAIL_SPINLOCK_INIT +// + +#include +#include + +#if defined( BOOST_SP_USE_STD_ATOMIC ) +# if !defined( __clang__ ) +# include +# else +// Clang (at least up to 3.4) can't compile spinlock_pool when +// using std::atomic, so substitute the __sync implementation instead. +# include +# endif + +#elif defined( BOOST_SP_USE_PTHREADS ) +# include + +#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) +# include + +#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ ) +# include + +#elif defined( BOOST_SP_HAS_SYNC ) +# include + +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# include + +#elif defined(BOOST_HAS_PTHREADS) +# include + +#elif !defined(BOOST_HAS_THREADS) +# include + +#else +# error Unrecognized threading platform +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp new file mode 100644 index 0000000..24d08a8 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp @@ -0,0 +1,121 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED + +// +// Copyright (c) 2008, 2011 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__) + +# define BOOST_SP_ARM_BARRIER "dmb" +# define BOOST_SP_ARM_HAS_LDREX + +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) + +# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5" +# define BOOST_SP_ARM_HAS_LDREX + +#else + +# define BOOST_SP_ARM_BARRIER "" + +#endif + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + int v_; + +public: + + bool try_lock() + { + int r; + +#ifdef BOOST_SP_ARM_HAS_LDREX + + __asm__ __volatile__( + "ldrex %0, [%2]; \n" + "cmp %0, %1; \n" + "strexne %0, %1, [%2]; \n" + BOOST_SP_ARM_BARRIER : + "=&r"( r ): // outputs + "r"( 1 ), "r"( &v_ ): // inputs + "memory", "cc" ); + +#else + + __asm__ __volatile__( + "swp %0, %1, [%2];\n" + BOOST_SP_ARM_BARRIER : + "=&r"( r ): // outputs + "r"( 1 ), "r"( &v_ ): // inputs + "memory", "cc" ); + +#endif + + return r == 0; + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" ); + *const_cast< int volatile* >( &v_ ) = 0; + __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT {0} + +#undef BOOST_SP_ARM_BARRIER +#undef BOOST_SP_ARM_HAS_LDREX + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_nt.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_nt.hpp new file mode 100644 index 0000000..1f399d0 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_nt.hpp @@ -0,0 +1,89 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + bool locked_; + +public: + + inline bool try_lock() + { + if( locked_ ) + { + return false; + } + else + { + locked_ = true; + return true; + } + } + + inline void lock() + { + BOOST_ASSERT( !locked_ ); + locked_ = true; + } + + inline void unlock() + { + BOOST_ASSERT( locked_ ); + locked_ = false; + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT { false } + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_pool.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_pool.hpp new file mode 100644 index 0000000..39cf180 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_pool.hpp @@ -0,0 +1,91 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/spinlock_pool.hpp +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// spinlock_pool<0> is reserved for atomic<>, when/if it arrives +// spinlock_pool<1> is reserved for shared_ptr reference counts +// spinlock_pool<2> is reserved for shared_ptr atomic access +// + +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +template< int M > class spinlock_pool +{ +private: + + static spinlock pool_[ 41 ]; + +public: + + static spinlock & spinlock_for( void const * pv ) + { +#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64 + std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41; +#else + std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41; +#endif + return pool_[ i ]; + } + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) ) + { + sp_.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +template< int M > spinlock spinlock_pool< M >::pool_[ 41 ] = +{ + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT +}; + +} // namespace detail +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_pt.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_pt.hpp new file mode 100644 index 0000000..f9cabfc --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_pt.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + pthread_mutex_t v_; + +public: + + bool try_lock() + { + return pthread_mutex_trylock( &v_ ) == 0; + } + + void lock() + { + pthread_mutex_lock( &v_ ); + } + + void unlock() + { + pthread_mutex_unlock( &v_ ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER } + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp new file mode 100644 index 0000000..a61c1cd --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp @@ -0,0 +1,83 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + std::atomic_flag v_; + +public: + + bool try_lock() + { + return !v_.test_and_set( std::memory_order_acquire ); + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + v_ .clear( std::memory_order_release ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT } + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_sync.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_sync.hpp new file mode 100644 index 0000000..a7145c5 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_sync.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined( __ia64__ ) && defined( __INTEL_COMPILER ) +# include +#endif + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + int v_; + +public: + + bool try_lock() + { + int r = __sync_lock_test_and_set( &v_, 1 ); + return r == 0; + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + __sync_lock_release( &v_ ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT {0} + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_w32.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_w32.hpp new file mode 100644 index 0000000..d34e4fc --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -0,0 +1,113 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +// BOOST_COMPILER_FENCE + +#if defined(__INTEL_COMPILER) + +#define BOOST_COMPILER_FENCE __memory_barrier(); + +#elif defined( _MSC_VER ) && _MSC_VER >= 1310 + +extern "C" void _ReadWriteBarrier(); +#pragma intrinsic( _ReadWriteBarrier ) + +#define BOOST_COMPILER_FENCE _ReadWriteBarrier(); + +#elif defined(__GNUC__) + +#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" ); + +#else + +#define BOOST_COMPILER_FENCE + +#endif + +// + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + long v_; + +public: + + bool try_lock() + { + long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 ); + + BOOST_COMPILER_FENCE + + return r == 0; + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + BOOST_COMPILER_FENCE + *const_cast< long volatile* >( &v_ ) = 0; + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT {0} + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/detail/yield_k.hpp b/thirdparty/linux/include/boost/smart_ptr/detail/yield_k.hpp new file mode 100644 index 0000000..44d1836 --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/detail/yield_k.hpp @@ -0,0 +1,177 @@ +#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// yield_k.hpp +// +// Copyright (c) 2008 Peter Dimov +// Copyright (c) Microsoft Corporation 2014 +// +// void yield( unsigned k ); +// +// Typical use: +// +// for( unsigned k = 0; !try_lock(); ++k ) yield( k ); +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include +#include + +#if BOOST_PLAT_WINDOWS_RUNTIME +#include +#endif + +// BOOST_SMT_PAUSE + +#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) + +extern "C" void _mm_pause(); + +#define BOOST_SMT_PAUSE _mm_pause(); + +#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) + +#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" ); + +#endif + +// + +#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +#if defined( BOOST_USE_WINDOWS_H ) +# include +#endif + +namespace boost +{ + +namespace detail +{ + +#if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME +#if !BOOST_COMP_CLANG || !defined __MINGW32__ + extern "C" void __stdcall Sleep( unsigned long ms ); +#else +#include <_mingw.h> +#if !defined __MINGW64_VERSION_MAJOR + extern "C" void __stdcall Sleep( unsigned long ms ); +#else + extern "C" __declspec(dllimport) void __stdcall Sleep( unsigned long ms ); +#endif +#endif +#endif + +inline void yield( unsigned k ) +{ + if( k < 4 ) + { + } +#if defined( BOOST_SMT_PAUSE ) + else if( k < 16 ) + { + BOOST_SMT_PAUSE + } +#endif +#if !BOOST_PLAT_WINDOWS_RUNTIME + else if( k < 32 ) + { + Sleep( 0 ); + } + else + { + Sleep( 1 ); + } +#else + else + { + // Sleep isn't supported on the Windows Runtime. + std::this_thread::yield(); + } +#endif +} + +} // namespace detail + +} // namespace boost + +#elif defined( BOOST_HAS_PTHREADS ) + +#ifndef _AIX +#include +#else + // AIX's sched.h defines ::var which sometimes conflicts with Lambda's var + extern "C" int sched_yield(void); +#endif + +#include + +namespace boost +{ + +namespace detail +{ + +inline void yield( unsigned k ) +{ + if( k < 4 ) + { + } +#if defined( BOOST_SMT_PAUSE ) + else if( k < 16 ) + { + BOOST_SMT_PAUSE + } +#endif + else if( k < 32 || k & 1 ) + { + sched_yield(); + } + else + { + // g++ -Wextra warns on {} or {0} + struct timespec rqtp = { 0, 0 }; + + // POSIX says that timespec has tv_sec and tv_nsec + // But it doesn't guarantee order or placement + + rqtp.tv_sec = 0; + rqtp.tv_nsec = 1000; + + nanosleep( &rqtp, 0 ); + } +} + +} // namespace detail + +} // namespace boost + +#else + +namespace boost +{ + +namespace detail +{ + +inline void yield( unsigned ) +{ +} + +} // namespace detail + +} // namespace boost + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/smart_ptr/shared_ptr.hpp b/thirdparty/linux/include/boost/smart_ptr/shared_ptr.hpp new file mode 100644 index 0000000..77f68be --- /dev/null +++ b/thirdparty/linux/include/boost/smart_ptr/shared_ptr.hpp @@ -0,0 +1,1094 @@ +#ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED +#define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED + +// +// shared_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001-2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include // for broken compiler workarounds + +// In order to avoid circular dependencies with Boost.TR1 +// we make sure that our include of doesn't try to +// pull in the TR1 headers: that's why we use this header +// rather than including directly: +#include // std::auto_ptr + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_SP_NO_ATOMIC_ACCESS) +#include +#endif + +#include // for std::swap +#include // for std::less +#include // for std::bad_cast +#include // for std::size_t + +#if !defined(BOOST_NO_IOSTREAM) +#if !defined(BOOST_NO_IOSFWD) +#include // for std::basic_ostream +#else +#include +#endif +#endif + +#if defined( BOOST_SP_DISABLE_DEPRECATED ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +namespace boost +{ + +template class shared_ptr; +template class weak_ptr; +template class enable_shared_from_this; +class enable_shared_from_raw; + +namespace movelib +{ + + template< class T, class D > class unique_ptr; + +} // namespace movelib + +namespace detail +{ + +// sp_element, element_type + +template< class T > struct sp_element +{ + typedef T type; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_element< T[] > +{ + typedef T type; +}; + +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + +template< class T, std::size_t N > struct sp_element< T[N] > +{ + typedef T type; +}; + +#endif + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// sp_dereference, return type of operator* + +template< class T > struct sp_dereference +{ + typedef T & type; +}; + +template<> struct sp_dereference< void > +{ + typedef void type; +}; + +#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) + +template<> struct sp_dereference< void const > +{ + typedef void type; +}; + +template<> struct sp_dereference< void volatile > +{ + typedef void type; +}; + +template<> struct sp_dereference< void const volatile > +{ + typedef void type; +}; + +#endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_dereference< T[] > +{ + typedef void type; +}; + +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + +template< class T, std::size_t N > struct sp_dereference< T[N] > +{ + typedef void type; +}; + +#endif + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// sp_member_access, return type of operator-> + +template< class T > struct sp_member_access +{ + typedef T * type; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_member_access< T[] > +{ + typedef void type; +}; + +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + +template< class T, std::size_t N > struct sp_member_access< T[N] > +{ + typedef void type; +}; + +#endif + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// sp_array_access, return type of operator[] + +template< class T > struct sp_array_access +{ + typedef void type; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T > struct sp_array_access< T[] > +{ + typedef T & type; +}; + +#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 ) + +template< class T, std::size_t N > struct sp_array_access< T[N] > +{ + typedef T & type; +}; + +#endif + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// sp_extent, for operator[] index check + +template< class T > struct sp_extent +{ + enum _vt { value = 0 }; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T, std::size_t N > struct sp_extent< T[N] > +{ + enum _vt { value = N }; +}; + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// enable_shared_from_this support + +template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe ) +{ + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } +} + +template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); + +#ifdef _MANAGED + +// Avoid C4793, ... causes native code generation + +struct sp_any_pointer +{ + template sp_any_pointer( T* ) {} +}; + +inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer ) +{ +} + +#else // _MANAGED + +inline void sp_enable_shared_from_this( ... ) +{ +} + +#endif // _MANAGED + +#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR ) + +// rvalue auto_ptr support based on a technique by Dave Abrahams + +template< class T, class R > struct sp_enable_if_auto_ptr +{ +}; + +template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R > +{ + typedef R type; +}; + +#endif + +// sp_assert_convertible + +template< class Y, class T > inline void sp_assert_convertible() +{ +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + // static_assert( sp_convertible< Y, T >::value ); + typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ]; + (void)sizeof( tmp ); + +#else + + T* p = static_cast< Y* >( 0 ); + (void)p; + +#endif +} + +// pointer constructor helper + +template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn ) +{ + boost::detail::shared_count( p ).swap( pn ); + boost::detail::sp_enable_shared_from_this( ppx, p, p ); +} + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) +{ + sp_assert_convertible< Y[], T[] >(); + boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); +} + +template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) +{ + sp_assert_convertible< Y[N], T[N] >(); + boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); +} + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +// deleter constructor helper + +template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p ) +{ + boost::detail::sp_enable_shared_from_this( ppx, p, p ); +} + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ ) +{ + sp_assert_convertible< Y[], T[] >(); +} + +template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ ) +{ + sp_assert_convertible< Y[N], T[N] >(); +} + +#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +} // namespace detail + + +// +// shared_ptr +// +// An enhanced relative of scoped_ptr with reference counted copy semantics. +// The object pointed to is deleted when the last shared_ptr pointing to it +// is destroyed or reset. +// + +template class shared_ptr +{ +private: + + // Borland 5.5.1 specific workaround + typedef shared_ptr this_type; + +public: + + typedef typename boost::detail::sp_element< T >::type element_type; + + shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ + { + } + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws + { + } + +#endif + + template + explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete + { + boost::detail::sp_pointer_construct( this, p, pn ); + } + + // + // Requirements: D's copy constructor must not throw + // + // shared_ptr will release p by calling d(p) + // + + template shared_ptr( Y * p, D d ): px( p ), pn( p, d ) + { + boost::detail::sp_deleter_construct( this, p ); + } + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + template shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d ) + { + } + +#endif + + // As above, but with allocator. A's copy constructor shall not throw. + + template shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) + { + boost::detail::sp_deleter_construct( this, p ); + } + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + template shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a ) + { + } + +#endif + +// generated copy constructor, destructor are fine... + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +// ... except in C++0x, move disables the implicit copy + + shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + { + } + +#endif + + template + explicit shared_ptr( weak_ptr const & r ): pn( r.pn ) // may throw + { + boost::detail::sp_assert_convertible< Y, T >(); + + // it is now safe to copy r.px, as pn(r.pn) did not throw + px = r.px; + } + + template + shared_ptr( weak_ptr const & r, boost::detail::sp_nothrow_tag ) + BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) + { + if( !pn.empty() ) + { + px = r.px; + } + } + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + shared_ptr( shared_ptr const & r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + +#else + + shared_ptr( shared_ptr const & r ) + +#endif + BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + { + boost::detail::sp_assert_convertible< Y, T >(); + } + + // aliasing + template< class Y > + shared_ptr( shared_ptr const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn ) + { + } + +#ifndef BOOST_NO_AUTO_PTR + + template + explicit shared_ptr( std::auto_ptr & r ): px(r.get()), pn() + { + boost::detail::sp_assert_convertible< Y, T >(); + + Y * tmp = r.get(); + pn = boost::detail::shared_count( r ); + + boost::detail::sp_deleter_construct( this, tmp ); + } + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + template + shared_ptr( std::auto_ptr && r ): px(r.get()), pn() + { + boost::detail::sp_assert_convertible< Y, T >(); + + Y * tmp = r.get(); + pn = boost::detail::shared_count( r ); + + boost::detail::sp_deleter_construct( this, tmp ); + } + +#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + + template + explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr::type = 0 ): px( r.get() ), pn() + { + typedef typename Ap::element_type Y; + + boost::detail::sp_assert_convertible< Y, T >(); + + Y * tmp = r.get(); + pn = boost::detail::shared_count( r ); + + boost::detail::sp_deleter_construct( this, tmp ); + } + +#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#endif // BOOST_NO_AUTO_PTR + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + template< class Y, class D > + shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn() + { + boost::detail::sp_assert_convertible< Y, T >(); + + typename std::unique_ptr< Y, D >::pointer tmp = r.get(); + pn = boost::detail::shared_count( r ); + + boost::detail::sp_deleter_construct( this, tmp ); + } + +#endif + + template< class Y, class D > + shared_ptr( boost::movelib::unique_ptr< Y, D > r ): px( r.get() ), pn() + { + boost::detail::sp_assert_convertible< Y, T >(); + + typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get(); + pn = boost::detail::shared_count( r ); + + boost::detail::sp_deleter_construct( this, tmp ); + } + + // assignment + + shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT + { + this_type(r).swap(*this); + return *this; + } + +#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400) + + template + shared_ptr & operator=(shared_ptr const & r) BOOST_NOEXCEPT + { + this_type(r).swap(*this); + return *this; + } + +#endif + +#ifndef BOOST_NO_AUTO_PTR + + template + shared_ptr & operator=( std::auto_ptr & r ) + { + this_type( r ).swap( *this ); + return *this; + } + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + template + shared_ptr & operator=( std::auto_ptr && r ) + { + this_type( static_cast< std::auto_ptr && >( r ) ).swap( *this ); + return *this; + } + +#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + + template + typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r ) + { + this_type( r ).swap( *this ); + return *this; + } + +#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#endif // BOOST_NO_AUTO_PTR + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + template + shared_ptr & operator=( std::unique_ptr && r ) + { + this_type( static_cast< std::unique_ptr && >( r ) ).swap(*this); + return *this; + } + +#endif + + template + shared_ptr & operator=( boost::movelib::unique_ptr r ) + { + // this_type( static_cast< unique_ptr && >( r ) ).swap( *this ); + + boost::detail::sp_assert_convertible< Y, T >(); + + typename boost::movelib::unique_ptr< Y, D >::pointer p = r.get(); + + shared_ptr tmp; + + tmp.px = p; + tmp.pn = boost::detail::shared_count( r ); + + boost::detail::sp_deleter_construct( &tmp, p ); + + tmp.swap( *this ); + + return *this; + } + +// Move support + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn() + { + pn.swap( r.pn ); + r.px = 0; + } + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + shared_ptr( shared_ptr && r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + +#else + + shared_ptr( shared_ptr && r ) + +#endif + BOOST_NOEXCEPT : px( r.px ), pn() + { + boost::detail::sp_assert_convertible< Y, T >(); + + pn.swap( r.pn ); + r.px = 0; + } + + shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT + { + this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); + return *this; + } + + template + shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT + { + this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); + return *this; + } + + // aliasing move + template + shared_ptr( shared_ptr && r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn() + { + pn.swap( r.pn ); + r.px = 0; + } + +#endif + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws + { + this_type().swap(*this); + return *this; + } + +#endif + + void reset() BOOST_NOEXCEPT // never throws in 1.30+ + { + this_type().swap(*this); + } + + template void reset( Y * p ) // Y must be complete + { + BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors + this_type( p ).swap( *this ); + } + + template void reset( Y * p, D d ) + { + this_type( p, d ).swap( *this ); + } + + template void reset( Y * p, D d, A a ) + { + this_type( p, d, a ).swap( *this ); + } + + template void reset( shared_ptr const & r, element_type * p ) + { + this_type( r, p ).swap( *this ); + } + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + template void reset( shared_ptr && r, element_type * p ) + { + this_type( static_cast< shared_ptr && >( r ), p ).swap( *this ); + } + +#endif + + // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) + typename boost::detail::sp_dereference< T >::type operator* () const + { + BOOST_ASSERT( px != 0 ); + return *px; + } + + // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) + typename boost::detail::sp_member_access< T >::type operator-> () const + { + BOOST_ASSERT( px != 0 ); + return px; + } + + // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT) + typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const + { + BOOST_ASSERT( px != 0 ); + BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) ); + + return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] ); + } + + element_type * get() const BOOST_NOEXCEPT + { + return px; + } + +// implicit conversion to "bool" +#include + + bool unique() const BOOST_NOEXCEPT + { + return pn.unique(); + } + + long use_count() const BOOST_NOEXCEPT + { + return pn.use_count(); + } + + void swap( shared_ptr & other ) BOOST_NOEXCEPT + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + template bool owner_before( shared_ptr const & rhs ) const BOOST_NOEXCEPT + { + return pn < rhs.pn; + } + + template bool owner_before( weak_ptr const & rhs ) const BOOST_NOEXCEPT + { + return pn < rhs.pn; + } + + void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT + { + return pn.get_deleter( ti ); + } + + void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT + { + return pn.get_untyped_deleter(); + } + + bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT + { + return px == r.px && pn == r.pn; + } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + +private: + + template friend class shared_ptr; + template friend class weak_ptr; + + +#endif + + element_type * px; // contained pointer + boost::detail::shared_count pn; // reference counter + +}; // shared_ptr + +template inline bool operator==(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT +{ + return a.get() != b.get(); +} + +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT +{ + return a.get() != b.get(); +} + +#endif + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +template inline bool operator==( shared_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr const & p ) BOOST_NOEXCEPT +{ + return p.get() == 0; +} + +template inline bool operator!=( shared_ptr const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +template inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr const & p ) BOOST_NOEXCEPT +{ + return p.get() != 0; +} + +#endif + +template inline bool operator<(shared_ptr const & a, shared_ptr const & b) BOOST_NOEXCEPT +{ + return a.owner_before( b ); +} + +template inline void swap(shared_ptr & a, shared_ptr & b) BOOST_NOEXCEPT +{ + a.swap(b); +} + +template shared_ptr static_pointer_cast( shared_ptr const & r ) BOOST_NOEXCEPT +{ + (void) static_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = static_cast< E* >( r.get() ); + return shared_ptr( r, p ); +} + +template shared_ptr const_pointer_cast( shared_ptr const & r ) BOOST_NOEXCEPT +{ + (void) const_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = const_cast< E* >( r.get() ); + return shared_ptr( r, p ); +} + +template shared_ptr dynamic_pointer_cast( shared_ptr const & r ) BOOST_NOEXCEPT +{ + (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = dynamic_cast< E* >( r.get() ); + return p? shared_ptr( r, p ): shared_ptr(); +} + +template shared_ptr reinterpret_pointer_cast( shared_ptr const & r ) BOOST_NOEXCEPT +{ + (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = reinterpret_cast< E* >( r.get() ); + return shared_ptr( r, p ); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline typename shared_ptr::element_type * get_pointer(shared_ptr const & p) BOOST_NOEXCEPT +{ + return p.get(); +} + +// operator<< + +#if !defined(BOOST_NO_IOSTREAM) + +#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) ) + +template std::ostream & operator<< (std::ostream & os, shared_ptr const & p) +{ + os << p.get(); + return os; +} + +#else + +// in STLport's no-iostreams mode no iostream symbols can be used +#ifndef _STLP_NO_IOSTREAMS + +# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) +// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL +using std::basic_ostream; +template basic_ostream & operator<< (basic_ostream & os, shared_ptr const & p) +# else +template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) +# endif +{ + os << p.get(); + return os; +} + +#endif // _STLP_NO_IOSTREAMS + +#endif // __GNUC__ < 3 + +#endif // !defined(BOOST_NO_IOSTREAM) + +// get_deleter + +namespace detail +{ + +#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \ + ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ + ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) ) + +// g++ 2.9x doesn't allow static_cast(void *) +// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it + +template D * basic_get_deleter(shared_ptr const & p) +{ + void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D)); + return const_cast(static_cast(q)); +} + +#else + +template D * basic_get_deleter( shared_ptr const & p ) BOOST_NOEXCEPT +{ + return static_cast( p._internal_get_deleter(BOOST_SP_TYPEID(D)) ); +} + +#endif + +class esft2_deleter_wrapper +{ +private: + + shared_ptr deleter_; + +public: + + esft2_deleter_wrapper() + { + } + + template< class T > void set_deleter( shared_ptr const & deleter ) + { + deleter_ = deleter; + } + + template D* get_deleter() const BOOST_NOEXCEPT + { + return boost::detail::basic_get_deleter( deleter_ ); + } + + template< class T> void operator()( T* ) + { + BOOST_ASSERT( deleter_.use_count() <= 1 ); + deleter_.reset(); + } +}; + +} // namespace detail + +template D * get_deleter( shared_ptr const & p ) BOOST_NOEXCEPT +{ + D *del = boost::detail::basic_get_deleter(p); + + if(del == 0) + { + boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter(p); +// The following get_deleter method call is fully qualified because +// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter() + if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter(); + } + + return del; +} + +// atomic access + +#if !defined(BOOST_SP_NO_ATOMIC_ACCESS) + +template inline bool atomic_is_lock_free( shared_ptr const * /*p*/ ) BOOST_NOEXCEPT +{ + return false; +} + +template shared_ptr atomic_load( shared_ptr const * p ) +{ + boost::detail::spinlock_pool<2>::scoped_lock lock( p ); + return *p; +} + +template inline shared_ptr atomic_load_explicit( shared_ptr const * p, /*memory_order mo*/ int ) +{ + return atomic_load( p ); +} + +template void atomic_store( shared_ptr * p, shared_ptr r ) +{ + boost::detail::spinlock_pool<2>::scoped_lock lock( p ); + p->swap( r ); +} + +template inline void atomic_store_explicit( shared_ptr * p, shared_ptr r, /*memory_order mo*/ int ) +{ + atomic_store( p, r ); // std::move( r ) +} + +template shared_ptr atomic_exchange( shared_ptr * p, shared_ptr r ) +{ + boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p ); + + sp.lock(); + p->swap( r ); + sp.unlock(); + + return r; // return std::move( r ) +} + +template shared_ptr atomic_exchange_explicit( shared_ptr * p, shared_ptr r, /*memory_order mo*/ int ) +{ + return atomic_exchange( p, r ); // std::move( r ) +} + +template bool atomic_compare_exchange( shared_ptr * p, shared_ptr * v, shared_ptr w ) +{ + boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p ); + + sp.lock(); + + if( p->_internal_equiv( *v ) ) + { + p->swap( w ); + + sp.unlock(); + + return true; + } + else + { + shared_ptr tmp( *p ); + + sp.unlock(); + + tmp.swap( *v ); + return false; + } +} + +template inline bool atomic_compare_exchange_explicit( shared_ptr * p, shared_ptr * v, shared_ptr w, /*memory_order success*/ int, /*memory_order failure*/ int ) +{ + return atomic_compare_exchange( p, v, w ); // std::move( w ) +} + +#endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS) + +// hash_value + +template< class T > struct hash; + +template< class T > std::size_t hash_value( boost::shared_ptr const & p ) BOOST_NOEXCEPT +{ + return boost::hash< typename boost::shared_ptr::element_type* >()( p.get() ); +} + +} // namespace boost + +#if defined( BOOST_SP_DISABLE_DEPRECATED ) +#pragma GCC diagnostic pop +#endif + +#endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/static_assert.hpp b/thirdparty/linux/include/boost/static_assert.hpp new file mode 100644 index 0000000..07d461d --- /dev/null +++ b/thirdparty/linux/include/boost/static_assert.hpp @@ -0,0 +1,180 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/static_assert for documentation. + +/* + Revision history: + 02 August 2000 + Initial version. +*/ + +#ifndef BOOST_STATIC_ASSERT_HPP +#define BOOST_STATIC_ASSERT_HPP + +#include +#include + +#if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) +// +// This is horrible, but it seems to be the only we can shut up the +// "anonymous variadic macros were introduced in C99 [-Wvariadic-macros]" +// warning that get spewed out otherwise in non-C++11 mode. +// +#pragma GCC system_header +#endif + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_MSG( ... ) static_assert(__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT_MSG( B, Msg ) static_assert( B, Msg ) +# endif +#else +# define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B ) +#endif + +#ifdef __BORLANDC__ +// +// workaround for buggy integral-constant expression support: +#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS +#endif + +#if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4)) +// gcc 3.3 and 3.4 don't produce good error messages with the default version: +# define BOOST_SA_GCC_WORKAROUND +#endif + +// +// If the compiler issues warnings about old C style casts, +// then enable this: +// +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) ((__VA_ARGS__) == 0 ? false : true) +# else +# define BOOST_STATIC_ASSERT_BOOL_CAST( x ) ((x) == 0 ? false : true) +# endif +#else +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) (bool)(__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT_BOOL_CAST(x) (bool)(x) +# endif +#endif + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT( B ) static_assert(B, #B) +# endif +#else + +namespace boost{ + +// HP aCC cannot deal with missing names for template value parameters +template struct STATIC_ASSERTION_FAILURE; + +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; + +// HP aCC cannot deal with missing names for template value parameters +template struct static_assert_test{}; + +} + +// +// Implicit instantiation requires that all member declarations be +// instantiated, but that the definitions are *not* instantiated. +// +// It's not particularly clear how this applies to enum's or typedefs; +// both are described as declarations [7.1.3] and [7.2] in the standard, +// however some compilers use "delayed evaluation" of one or more of +// these when implicitly instantiating templates. We use typedef declarations +// by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum +// version gets better results from your compiler... +// +// Implementation: +// Both of these versions rely on sizeof(incomplete_type) generating an error +// message containing the name of the incomplete type. We use +// "STATIC_ASSERTION_FAILURE" as the type name here to generate +// an eye catching error message. The result of the sizeof expression is either +// used as an enum initialiser, or as a template argument depending which version +// is in use... +// Note that the argument to the assert is explicitly cast to bool using old- +// style casts: too many compilers currently have problems with static_cast +// when used inside integral constant expressions. +// +#if !defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS) + +#if defined(BOOST_MSVC) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) +#define BOOST_STATIC_ASSERT( B ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) +#elif defined(BOOST_MSVC) +#define BOOST_STATIC_ASSERT(...) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST (__VA_ARGS__) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) +#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) +// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error +// instead of warning in case of failure +# define BOOST_STATIC_ASSERT( B ) \ + typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ + [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >::value ] +#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && !defined(BOOST_NO_CXX11_VARIADIC_MACROS) +// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error +// instead of warning in case of failure +# define BOOST_STATIC_ASSERT(...) \ + typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ + [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >::value ] +#elif defined(__sgi) +// special version for SGI MIPSpro compiler +#define BOOST_STATIC_ASSERT( B ) \ + BOOST_STATIC_CONSTANT(bool, \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) = ( B )); \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) +#elif BOOST_WORKAROUND(__MWERKS__, <= 0x3003) +// special version for CodeWarrior <= 8.x +#define BOOST_STATIC_ASSERT( B ) \ + BOOST_STATIC_CONSTANT(int, \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) = \ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >) ) +#else +// generic version +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED +# else +# define BOOST_STATIC_ASSERT( B ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED +# endif +#endif + +#else +// alternative enum based implementation: +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) \ + enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ + = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( __VA_ARGS__ ) >) } +# else +# define BOOST_STATIC_ASSERT(B) \ + enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ + = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) } +# endif +#endif +#endif // defined(BOOST_NO_CXX11_STATIC_ASSERT) + +#endif // BOOST_STATIC_ASSERT_HPP + + diff --git a/thirdparty/linux/include/boost/throw_exception.hpp b/thirdparty/linux/include/boost/throw_exception.hpp new file mode 100644 index 0000000..aa977df --- /dev/null +++ b/thirdparty/linux/include/boost/throw_exception.hpp @@ -0,0 +1,102 @@ +#ifndef UUID_AA15E74A856F11E08B8D93F24824019B +#define UUID_AA15E74A856F11E08B8D93F24824019B +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/throw_exception.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// http://www.boost.org/libs/utility/throw_exception.html +// + +#include +#include +#include + +#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x593) ) +# define BOOST_EXCEPTION_DISABLE +#endif + +#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1310 ) +# define BOOST_EXCEPTION_DISABLE +#endif + +#if !defined( BOOST_EXCEPTION_DISABLE ) +# include +#if !defined(BOOST_THROW_EXCEPTION_CURRENT_FUNCTION) +# include +# define BOOST_THROW_EXCEPTION_CURRENT_FUNCTION BOOST_CURRENT_FUNCTION +#endif +# define BOOST_THROW_EXCEPTION(x) ::boost::exception_detail::throw_exception_(x,BOOST_THROW_EXCEPTION_CURRENT_FUNCTION,__FILE__,__LINE__) +#else +# define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x) +#endif + +namespace boost +{ +#ifdef BOOST_NO_EXCEPTIONS + +void throw_exception( std::exception const & e ); // user defined + +#else + +inline void throw_exception_assert_compatibility( std::exception const & ) { } + +template BOOST_NORETURN inline void throw_exception( E const & e ) +{ + //All boost exceptions are required to derive from std::exception, + //to ensure compatibility with BOOST_NO_EXCEPTIONS. + throw_exception_assert_compatibility(e); + +#ifndef BOOST_EXCEPTION_DISABLE + throw enable_current_exception(enable_error_info(e)); +#else + throw e; +#endif +} + +#endif + +#if !defined( BOOST_EXCEPTION_DISABLE ) + namespace + exception_detail + { + template + BOOST_NORETURN + void + throw_exception_( E const & x, char const * current_function, char const * file, int line ) + { + boost::throw_exception( + set_info( + set_info( + set_info( + enable_error_info(x), + throw_function(current_function)), + throw_file(file)), + throw_line(line))); + } + } +#endif +} // namespace boost + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/thirdparty/linux/include/boost/type_traits/add_lvalue_reference.hpp b/thirdparty/linux/include/boost/type_traits/add_lvalue_reference.hpp new file mode 100644 index 0000000..41851a1 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/add_lvalue_reference.hpp @@ -0,0 +1,27 @@ +// Copyright 2010 John Maddock + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP +#define BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP + +#include + +namespace boost{ + +template struct add_lvalue_reference +{ + typedef typename boost::add_reference::type type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template struct add_lvalue_reference +{ + typedef T& type; +}; +#endif + +} + +#endif // BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP diff --git a/thirdparty/linux/include/boost/type_traits/add_reference.hpp b/thirdparty/linux/include/boost/type_traits/add_reference.hpp new file mode 100644 index 0000000..3c91415 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/add_reference.hpp @@ -0,0 +1,59 @@ + +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_ADD_REFERENCE_HPP_INCLUDED +#define BOOST_TT_ADD_REFERENCE_HPP_INCLUDED + +#include +#include + +namespace boost { + +namespace detail { + +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// + +template +struct add_reference_impl +{ + typedef T& type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template +struct add_reference_impl +{ + typedef T&& type; +}; +#endif + +} // namespace detail + +template struct add_reference +{ + typedef typename boost::detail::add_reference_impl::type type; +}; +template struct add_reference +{ + typedef T& type; +}; + +// these full specialisations are always required: +template <> struct add_reference { typedef void type; }; +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +template <> struct add_reference { typedef const void type; }; +template <> struct add_reference { typedef const volatile void type; }; +template <> struct add_reference { typedef volatile void type; }; +#endif + +} // namespace boost + +#endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/add_rvalue_reference.hpp b/thirdparty/linux/include/boost/type_traits/add_rvalue_reference.hpp new file mode 100644 index 0000000..44ead34 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/add_rvalue_reference.hpp @@ -0,0 +1,64 @@ +// add_rvalue_reference.hpp ---------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP +#define BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP + +#include + +//----------------------------------------------------------------------------// + +#include +#include + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// 20.9.7.2 Reference modifications [meta.trans.ref] // +// Written by Vicente J. Botet Escriba // +// // +// If T names an object or function type then the member typedef type +// shall name T&&; otherwise, type shall name T. [ Note: This rule reflects +// the semantics of reference collapsing. For example, when a type T names +// a type T1&, the type add_rvalue_reference::type is not an rvalue +// reference. -end note ] +//----------------------------------------------------------------------------// + +namespace boost { + +namespace type_traits_detail { + + template + struct add_rvalue_reference_helper + { typedef T type; }; + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + template + struct add_rvalue_reference_helper + { + typedef T&& type; + }; +#endif + + template + struct add_rvalue_reference_imp + { + typedef typename boost::type_traits_detail::add_rvalue_reference_helper + ::value == false && is_reference::value == false) >::type type; + }; + +} + +template struct add_rvalue_reference +{ + typedef typename boost::type_traits_detail::add_rvalue_reference_imp::type type; +}; + +} // namespace boost + +#endif // BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP + diff --git a/thirdparty/linux/include/boost/type_traits/alignment_of.hpp b/thirdparty/linux/include/boost/type_traits/alignment_of.hpp new file mode 100644 index 0000000..7d960e3 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/alignment_of.hpp @@ -0,0 +1,119 @@ + +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED +#define BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED + +#include +#include + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4121 4512) // alignment is sensitive to packing +#endif +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600) +#pragma option push -Vx- -Ve- +#endif + +namespace boost { + +template struct alignment_of; + +// get the alignment of some arbitrary type: +namespace detail { + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4324) // structure was padded due to __declspec(align()) +#endif +template +struct alignment_of_hack +{ + char c; + T t; + alignment_of_hack(); +}; +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +template +struct alignment_logic +{ + BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S); +}; + + +template< typename T > +struct alignment_of_impl +{ +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) + // + // With MSVC both the native __alignof operator + // and our own logic gets things wrong from time to time :-( + // Using a combination of the two seems to make the most of a bad job: + // + BOOST_STATIC_CONSTANT(std::size_t, value = + (::boost::detail::alignment_logic< + sizeof(::boost::detail::alignment_of_hack) - sizeof(T), + __alignof(T) + >::value)); +#elif !defined(BOOST_ALIGNMENT_OF) + BOOST_STATIC_CONSTANT(std::size_t, value = + (::boost::detail::alignment_logic< + sizeof(::boost::detail::alignment_of_hack) - sizeof(T), + sizeof(T) + >::value)); +#else + // + // We put this here, rather than in the definition of + // alignment_of below, because MSVC's __alignof doesn't + // always work in that context for some unexplained reason. + // (See type_with_alignment tests for test cases). + // + BOOST_STATIC_CONSTANT(std::size_t, value = BOOST_ALIGNMENT_OF(T)); +#endif +}; + +} // namespace detail + +template struct alignment_of : public integral_constant::value>{}; + +// references have to be treated specially, assume +// that a reference is just a special pointer: +template struct alignment_of : public alignment_of{}; + +#ifdef __BORLANDC__ +// long double gives an incorrect value of 10 (!) +// unless we do this... +struct long_double_wrapper{ long double ld; }; +template<> struct alignment_of : public alignment_of{}; +#endif + +// void has to be treated specially: +template<> struct alignment_of : integral_constant{}; +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +template<> struct alignment_of : integral_constant{}; +template<> struct alignment_of : integral_constant{}; +template<> struct alignment_of : integral_constant{}; +#endif + +} // namespace boost + +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600) +#pragma option pop +#endif +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED + diff --git a/thirdparty/linux/include/boost/type_traits/conditional.hpp b/thirdparty/linux/include/boost/type_traits/conditional.hpp new file mode 100644 index 0000000..b7e82db --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/conditional.hpp @@ -0,0 +1,20 @@ +// (C) Copyright John Maddock 2010. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + + +#ifndef BOOST_TT_CONDITIONAL_HPP_INCLUDED +#define BOOST_TT_CONDITIONAL_HPP_INCLUDED + +namespace boost { + +template struct conditional { typedef T type; }; +template struct conditional { typedef U type; }; + +} // namespace boost + + +#endif // BOOST_TT_CONDITIONAL_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/declval.hpp b/thirdparty/linux/include/boost/type_traits/declval.hpp new file mode 100644 index 0000000..a050012 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/declval.hpp @@ -0,0 +1,44 @@ +// declval.hpp -------------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED + +#include + +//----------------------------------------------------------------------------// + +#include + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// 20.2.4 Function template declval [declval] // +// Written by Vicente J. Botet Escriba // +// // +// 1 The library provides the function template declval to simplify the +// definition of expressions which occur as unevaluated operands. +// 2 Remarks: If this function is used, the program is ill-formed. +// 3 Remarks: The template parameter T of declval may be an incomplete type. +// [ Example: +// +// template +// decltype(static_cast(declval())) convert(From&&); +// +// declares a function template convert which only participates in overloading +// if the type From can be explicitly converted to type To. For another example +// see class template common_type (20.9.7.6). -end example ] +//----------------------------------------------------------------------------// + +namespace boost { + + template + typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand + +} // namespace boost + +#endif // BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/detail/config.hpp b/thirdparty/linux/include/boost/type_traits/detail/config.hpp new file mode 100644 index 0000000..ebb1dd6 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/detail/config.hpp @@ -0,0 +1,72 @@ + +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_CONFIG_HPP_INCLUDED +#define BOOST_TT_CONFIG_HPP_INCLUDED + +#ifndef BOOST_CONFIG_HPP +#include +#endif +#include +#include + +// +// whenever we have a conversion function with ellipses +// it needs to be declared __cdecl to suppress compiler +// warnings from MS and Borland compilers (this *must* +// appear before we include is_same.hpp below): +#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32)) +# define BOOST_TT_DECL __cdecl +#else +# define BOOST_TT_DECL /**/ +#endif + +# if (BOOST_WORKAROUND(__MWERKS__, < 0x3000) \ + || BOOST_WORKAROUND(__IBMCPP__, < 600 ) \ + || BOOST_WORKAROUND(__BORLANDC__, < 0x5A0) \ + || defined(__ghs) \ + || BOOST_WORKAROUND(__HP_aCC, < 60700) \ + || BOOST_WORKAROUND(MPW_CPLUS, BOOST_TESTED_AT(0x890)) \ + || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))) \ + && defined(BOOST_NO_IS_ABSTRACT) + +# define BOOST_TT_NO_CONFORMING_IS_CLASS_IMPLEMENTATION 1 + +#endif + +#ifndef BOOST_TT_NO_CONFORMING_IS_CLASS_IMPLEMENTATION +# define BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION 1 +#endif + +// +// define BOOST_TT_TEST_MS_FUNC_SIGS +// when we want to test __stdcall etc function types with is_function etc +// (Note, does not work with Borland, even though it does support __stdcall etc): +// +#if defined(_MSC_EXTENSIONS) && !defined(__BORLANDC__) +# define BOOST_TT_TEST_MS_FUNC_SIGS +#endif + +// +// define BOOST_TT_NO_CV_FUNC_TEST +// if tests for cv-qualified member functions don't +// work in is_member_function_pointer +// +#if BOOST_WORKAROUND(__MWERKS__, < 0x3000) || BOOST_WORKAROUND(__IBMCPP__, <= 600) +# define BOOST_TT_NO_CV_FUNC_TEST +#endif + +// +// Macros that have been deprecated, defined here for backwards compatibility: +// +#define BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(x) +#define BOOST_TT_BROKEN_COMPILER_SPEC(x) + +#endif // BOOST_TT_CONFIG_HPP_INCLUDED + + diff --git a/thirdparty/linux/include/boost/type_traits/detail/is_function_ptr_helper.hpp b/thirdparty/linux/include/boost/type_traits/detail/is_function_ptr_helper.hpp new file mode 100644 index 0000000..3538e40 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/detail/is_function_ptr_helper.hpp @@ -0,0 +1,176 @@ + +// Copyright 2000 John Maddock (john@johnmaddock.co.uk) +// Copyright 2002 Aleksey Gurtovoy (agurtovoy@meta-comm.com) +// +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED +#define BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED + +#if defined(BOOST_TT_PREPROCESSING_MODE) +// +// Hide these #include from dependency analysers as +// these are required in maintenance mode only: +// +#define PP1 +#include PP1 +#undef PP1 +#define PP1 +#include PP1 +#undef PP1 +#define PP1 +#include PP1 +#undef PP1 +#endif + +namespace boost { +namespace type_traits { + +template +struct is_function_ptr_helper +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +#if !defined(BOOST_TT_PREPROCESSING_MODE) +// preprocessor-generated part, don't edit by hand! + +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +#else + +#undef BOOST_STATIC_CONSTANT +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, 25, "boost/type_traits/detail/is_function_ptr_helper.hpp")) +#include BOOST_PP_ITERATE() + +#endif // BOOST_TT_PREPROCESSING_MODE + +} // namespace type_traits +} // namespace boost + +#endif // BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED + +///// iteration + +#else +#define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1) + +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +@#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING +template +struct is_function_ptr_helper { BOOST_STATIC_CONSTANT(bool, value = true); }; +@#endif +#undef BOOST_PP_COUNTER +#endif // BOOST_PP_IS_ITERATING diff --git a/thirdparty/linux/include/boost/type_traits/detail/is_function_ptr_tester.hpp b/thirdparty/linux/include/boost/type_traits/detail/is_function_ptr_tester.hpp new file mode 100644 index 0000000..4fe88e8 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/detail/is_function_ptr_tester.hpp @@ -0,0 +1,449 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_TT_DETAIL_IS_FUNCTION_PTR_TESTER_HPP_INCLUDED +#define BOOST_TT_DETAIL_IS_FUNCTION_PTR_TESTER_HPP_INCLUDED + +#include + +#if defined(BOOST_TT_PREPROCESSING_MODE) +// +// Hide include dependencies from analysers since they're +// only require in maintenance mode: +// +#define PP1 +#define PP2 +#define PP3 +#include PP1 +#include PP2 +#include PP3 +#undef PP1 +#undef PP2 +#undef PP3 +#endif + +namespace boost { +namespace type_traits { + +// Note it is acceptable to use ellipsis here, since the argument will +// always be a pointer type of some sort (JM 2005/06/04): +no_type BOOST_TT_DECL is_function_ptr_tester(...); + +#if !defined(BOOST_TT_PREPROCESSING_MODE) +// pre-processed code, don't edit, try GNU cpp with +// cpp -I../../../ -DBOOST_TT_PREPROCESSING_MODE -x c++ -P filename + +template +yes_type is_function_ptr_tester(R (*)()); +template +yes_type is_function_ptr_tester(R (*)( ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)()); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)()); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)()); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0)); +template +yes_type is_function_ptr_tester(R (*)( T0 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); +#endif +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); +template +yes_type is_function_ptr_tester(R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...)); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); +#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); +#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); +#endif +#else + +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, 25, "boost/type_traits/detail/is_function_ptr_tester.hpp")) +#include BOOST_PP_ITERATE() + +#endif // BOOST_TT_PREPROCESSING_MODE + +} // namespace type_traits +} // namespace boost + +#endif // BOOST_TT_DETAIL_IS_FUNCTION_PTR_TESTER_HPP_INCLUDED + +///// iteration + +#else +#define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1) +#undef __stdcall +#undef __fastcall +#undef __cdecl + +template +yes_type is_function_ptr_tester(R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); +@#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING +template +yes_type is_function_ptr_tester(R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...)); +@#endif +@#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_function_ptr_tester(R (__stdcall*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); +@#ifndef _MANAGED +template +yes_type is_function_ptr_tester(R (__fastcall*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); +@#endif +template +yes_type is_function_ptr_tester(R (__cdecl*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); +@#endif + +#undef BOOST_PP_COUNTER +#endif // BOOST_PP_IS_ITERATING diff --git a/thirdparty/linux/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp b/thirdparty/linux/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp new file mode 100644 index 0000000..5698a74 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp @@ -0,0 +1,723 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED +#define BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED + +#include + +#if defined(BOOST_TT_PREPROCESSING_MODE) +// +// Maintenance mode, hide include dependencies +// from trackers: +// +#define PPI +#include PPI +#undef PPI +#define PPI +#include PPI +#undef PPI +#define PPI +#include PPI +#undef PPI +#endif + +namespace boost { +namespace type_traits { + +template +struct is_mem_fun_pointer_impl +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +#if !defined(BOOST_TT_PREPROCESSING_MODE) +// pre-processed code, don't edit, try GNU cpp with +// cpp -I../../../ -DBOOST_TT_PREPROCESSING_MODE -x c++ -P filename + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +#endif + +#else + +#undef BOOST_STATIC_CONSTANT +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, 25, "boost/type_traits/detail/is_mem_fun_pointer_impl.hpp")) +#include BOOST_PP_ITERATE() + +#endif // BOOST_TT_PREPROCESSING_MODE + +} // namespace type_traits +} // namespace boost + +#endif // BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED + +///// iteration + +#else +#define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1) + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +@#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +@#endif + +@#if !defined(BOOST_TT_NO_CV_FUNC_TEST) +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +@#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_mem_fun_pointer_impl { BOOST_STATIC_CONSTANT(bool, value = true); }; +@#endif +@#endif + +#undef BOOST_PP_COUNTER +#endif // BOOST_PP_IS_ITERATING + diff --git a/thirdparty/linux/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp b/thirdparty/linux/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp new file mode 100644 index 0000000..5e31693 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/detail/is_mem_fun_pointer_tester.hpp @@ -0,0 +1,1800 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_TESTER_HPP_INCLUDED +#define BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_TESTER_HPP_INCLUDED + +#include +#include + +#if defined(BOOST_TT_PREPROCESSING_MODE) +// +// Maintentance mode, hide include dependencies +// from dependency trackers: +// +#define PPI +#include PPI +#undef PPI +#define PPI +#include PPI +#undef PPI +#define +#include PPI +#undef +#endif + +namespace boost { +namespace type_traits { + +no_type BOOST_TT_DECL is_mem_fun_pointer_tester(...); + +#if !defined(BOOST_TT_PREPROCESSING_MODE) +// pre-processed code, don't edit, try GNU cpp with +// cpp -I../../../ -DBOOST_TT_PREPROCESSING_MODE -x c++ -P filename + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)()); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)() const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)() volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)() const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)()); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)() const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)() volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)() const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)()); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)() const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)() volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)() const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)()); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)() const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)() volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)() const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) const volatile); + +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile); + +#endif +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) const volatile); +#ifdef BOOST_TT_TEST_MS_FUNC_SIGS +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile); + +#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile); + +#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile); + +#endif + +#else + +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, 25, "boost/type_traits/detail/is_mem_fun_pointer_tester.hpp")) +#include BOOST_PP_ITERATE() + +#endif // BOOST_TT_PREPROCESSING_MODE + +} // namespace type_traits +} // namespace boost + +#endif // BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_TESTER_HPP_INCLUDED + +///// iteration + +#else +#define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1) +#undef __stdcall +#undef __fastcall +#undef __cdecl + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); + +@#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...)); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) const); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) const volatile); +@#endif +@#ifdef BOOST_TT_TEST_MS_FUNC_SIGS // Other calling conventions used by MS compatible compilers: +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__stdcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); + +@#ifndef _MANAGED +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__fastcall T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); + +@#endif + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile); + +template +yes_type is_mem_fun_pointer_tester(R (__cdecl T::*const volatile*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile); + +@#endif + +#undef BOOST_PP_COUNTER +#endif // BOOST_PP_IS_ITERATING diff --git a/thirdparty/linux/include/boost/type_traits/detail/yes_no_type.hpp b/thirdparty/linux/include/boost/type_traits/detail/yes_no_type.hpp new file mode 100644 index 0000000..f583730 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/detail/yes_no_type.hpp @@ -0,0 +1,26 @@ + +// (C) Copyright John Maddock and Steve Cleary 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. +// +// macros and helpers for working with integral-constant-expressions. + +#ifndef BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED +#define BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED + +namespace boost { +namespace type_traits { + +typedef char yes_type; +struct no_type +{ + char padding[8]; +}; + +} // namespace type_traits +} // namespace boost + +#endif // BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/integral_constant.hpp b/thirdparty/linux/include/boost/type_traits/integral_constant.hpp new file mode 100644 index 0000000..ae2448d --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/integral_constant.hpp @@ -0,0 +1,106 @@ +// (C) Copyright John Maddock 2015. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP +#define BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP + +#include +#include + +#if (BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \ + || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \ + || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \ + || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) ) + + +namespace boost{ + namespace mpl + { + template struct bool_; + template struct integral_c; + struct integral_c_tag; + } +} + +#else + +namespace mpl_{ + + template struct bool_; + template struct integral_c; + struct integral_c_tag; +} + +namespace boost +{ + namespace mpl + { + using ::mpl_::bool_; + using ::mpl_::integral_c; + using ::mpl_::integral_c_tag; + } +} + +#endif + +namespace boost{ + + template + struct integral_constant + { + typedef mpl::integral_c_tag tag; + typedef T value_type; + typedef integral_constant type; + static const T value = val; + // + // This helper function is just to disable type-punning + // warnings from GCC: + // + template + static U& dereference(U* p) { return *p; } + + operator const mpl::integral_c& ()const + { + static const char data[sizeof(long)] = { 0 }; + return dereference(reinterpret_cast*>(&data)); + } + BOOST_CONSTEXPR operator T()const { return val; } + }; + + template + T const integral_constant::value; + + template + struct integral_constant + { + typedef mpl::integral_c_tag tag; + typedef bool value_type; + typedef integral_constant type; + static const bool value = val; + // + // This helper function is just to disable type-punning + // warnings from GCC: + // + template + static T& dereference(T* p) { return *p; } + + operator const mpl::bool_& ()const + { + static const char data = 0; + return dereference(reinterpret_cast*>(&data)); + } + BOOST_CONSTEXPR operator bool()const { return val; } + }; + + template + bool const integral_constant::value; + + typedef integral_constant true_type; + typedef integral_constant false_type; + +} + +#endif diff --git a/thirdparty/linux/include/boost/type_traits/intrinsics.hpp b/thirdparty/linux/include/boost/type_traits/intrinsics.hpp new file mode 100644 index 0000000..e2246be --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/intrinsics.hpp @@ -0,0 +1,380 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_INTRINSICS_HPP_INCLUDED +#define BOOST_TT_INTRINSICS_HPP_INCLUDED + +#ifndef BOOST_TT_DISABLE_INTRINSICS + +#include + +#ifndef BOOST_TT_CONFIG_HPP_INCLUDED +#include +#endif + +// +// Helper macros for builtin compiler support. +// If your compiler has builtin support for any of the following +// traits concepts, then redefine the appropriate macros to pick +// up on the compiler support: +// +// (these should largely ignore cv-qualifiers) +// BOOST_IS_UNION(T) should evaluate to true if T is a union type +// BOOST_IS_POD(T) should evaluate to true if T is a POD type +// BOOST_IS_EMPTY(T) should evaluate to true if T is an empty class type (and not a union) +// BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect +// BOOST_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy +// BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) should evaluate to true if T(boost::move(t)) <==> memcpy +// BOOST_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy +// BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) should evaluate to true if t = boost::move(u) <==> memcpy +// BOOST_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect +// BOOST_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw +// BOOST_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw +// BOOST_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw +// BOOST_HAS_VIRTUAL_DESTRUCTOR(T) should evaluate to true T has a virtual destructor +// BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T) should evaluate to true if T has a non-throwing move constructor. +// BOOST_IS_NOTHROW_MOVE_ASSIGN(T) should evaluate to true if T has a non-throwing move assignment operator. +// +// The following can also be defined: when detected our implementation is greatly simplified. +// +// BOOST_IS_ABSTRACT(T) true if T is an abstract type +// BOOST_IS_BASE_OF(T,U) true if T is a base class of U +// BOOST_IS_CLASS(T) true if T is a class type (and not a union) +// BOOST_IS_CONVERTIBLE(T,U) true if T is convertible to U +// BOOST_IS_ENUM(T) true is T is an enum +// BOOST_IS_POLYMORPHIC(T) true if T is a polymorphic type +// BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T. +// +// define BOOST_TT_DISABLE_INTRINSICS to prevent any intrinsics being used (mostly used when testing) +// + +#ifdef BOOST_HAS_SGI_TYPE_TRAITS + // Hook into SGI's __type_traits class, this will pick up user supplied + // specializations as well as SGI - compiler supplied specializations. +# include +# ifdef __NetBSD__ + // There are two different versions of type_traits.h on NetBSD on Spark + // use an implicit include via algorithm instead, to make sure we get + // the same version as the std lib: +# include +# else +# include +# endif +# define BOOST_IS_POD(T) ::boost::is_same< typename ::__type_traits::is_POD_type, ::__true_type>::value +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) ::boost::is_same< typename ::__type_traits::has_trivial_default_constructor, ::__true_type>::value +# define BOOST_HAS_TRIVIAL_COPY(T) ::boost::is_same< typename ::__type_traits::has_trivial_copy_constructor, ::__true_type>::value +# define BOOST_HAS_TRIVIAL_ASSIGN(T) ::boost::is_same< typename ::__type_traits::has_trivial_assignment_operator, ::__true_type>::value +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) ::boost::is_same< typename ::__type_traits::has_trivial_destructor, ::__true_type>::value + +# ifdef __sgi +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +# endif +#endif + +#if defined(__MSL_CPP__) && (__MSL_CPP__ >= 0x8000) + // Metrowerks compiler is acquiring intrinsic type traits support + // post version 8. We hook into the published interface to pick up + // user defined specializations as well as compiler intrinsics as + // and when they become available: +# include +# define BOOST_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union::value +# define BOOST_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD::value +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor::value +# define BOOST_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor::value +# define BOOST_HAS_TRIVIAL_ASSIGN(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_assignment::value +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_dtor::value +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + +#if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\ + || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500)) +// +// Note that even though these intrinsics rely on other type traits classes +// we do not #include those here as it produces cyclic dependencies and +// can cause the intrinsics to not even be used at all! +// +# define BOOST_IS_UNION(T) __is_union(T) +# define BOOST_IS_POD(T) (__is_pod(T) && __has_trivial_constructor(T)) +# define BOOST_IS_EMPTY(T) __is_empty(T) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) +# define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) || ( ::boost::is_pod::value && ! ::boost::is_const::value && !::boost::is_volatile::value)) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) || ::boost::is_pod::value) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) || ::boost::has_trivial_constructor::value) +#if !defined(BOOST_INTEL) +# define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) || ::boost::has_trivial_copy::value) && !is_array::value) +# define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) || ::boost::is_pod::value) +#elif (_MSC_VER >= 1900) +# define BOOST_HAS_NOTHROW_COPY(T) ((__is_nothrow_constructible(T, typename add_lvalue_reference::type>::type)) && !is_array::value) +# define BOOST_HAS_TRIVIAL_COPY(T) (__is_trivially_constructible(T, typename add_lvalue_reference::type>::type)) +#endif +# define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) || ::boost::has_trivial_assign::value) +# define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) + +# define BOOST_IS_ABSTRACT(T) __is_abstract(T) +# define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) +# define BOOST_IS_CLASS(T) __is_class(T) +# define BOOST_IS_CONVERTIBLE(T,U) ((__is_convertible_to(T,U) || (is_same::value && !is_function::value)) && !__is_abstract(U)) +# define BOOST_IS_ENUM(T) __is_enum(T) +// This one fails if the default alignment has been changed with /Zp: +// # define BOOST_ALIGNMENT_OF(T) __alignof(T) + +# if defined(_MSC_VER) && (_MSC_VER >= 1700) +# define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) ((__has_trivial_move_constructor(T) || boost::is_pod::value) && ! ::boost::is_volatile::value && ! ::boost::is_reference::value) +# define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) ((__has_trivial_move_assign(T) || boost::is_pod::value) && ! ::boost::is_const::value && !::boost::is_volatile::value && ! ::boost::is_reference::value) +# endif +#ifndef BOOST_NO_CXX11_FINAL +// This one doesn't quite always do the right thing on older VC++ versions +// we really need it when the final keyword is supporyted though: +# define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) +#endif +#if _MSC_FULL_VER >= 180020827 +# define BOOST_IS_NOTHROW_MOVE_ASSIGN(T) (__is_nothrow_assignable(T&, T&&)) +# define BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T) (__is_nothrow_constructible(T, T&&)) +#endif +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + +#if defined(__DMC__) && (__DMC__ >= 0x848) +// For Digital Mars C++, www.digitalmars.com +# define BOOST_IS_UNION(T) (__typeinfo(T) & 0x400) +# define BOOST_IS_POD(T) (__typeinfo(T) & 0x800) +# define BOOST_IS_EMPTY(T) (__typeinfo(T) & 0x1000) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__typeinfo(T) & 0x10) +# define BOOST_HAS_TRIVIAL_COPY(T) (__typeinfo(T) & 0x20) +# define BOOST_HAS_TRIVIAL_ASSIGN(T) (__typeinfo(T) & 0x40) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__typeinfo(T) & 0x8) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__typeinfo(T) & 0x80) +# define BOOST_HAS_NOTHROW_COPY(T) (__typeinfo(T) & 0x100) +# define BOOST_HAS_NOTHROW_ASSIGN(T) (__typeinfo(T) & 0x200) +# define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) (__typeinfo(T) & 0x4) +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + +#if defined(BOOST_CLANG) && defined(__has_feature) && !defined(__CUDACC__) +// +// Note that these intrinsics are disabled for the CUDA meta-compiler as it appears +// to not support them, even though the underlying clang compiler does so. +// This is a rubbish fix as it basically stops type traits from working correctly, +// but maybe the best we can do for now. See https://svn.boost.org/trac/boost/ticket/10694 +// +// +// Note that even though these intrinsics rely on other type traits classes +// we do not #include those here as it produces cyclic dependencies and +// can cause the intrinsics to not even be used at all! +// +# include + +# if __has_feature(is_union) +# define BOOST_IS_UNION(T) __is_union(T) +# endif +# if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_pod) +# define BOOST_IS_POD(T) __is_pod(T) +# endif +# if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty) +# define BOOST_IS_EMPTY(T) __is_empty(T) +# endif +# if __has_feature(has_trivial_constructor) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) +# endif +# if __has_feature(has_trivial_copy) +# define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && !is_reference::value) +# endif +# if __has_feature(has_trivial_assign) +# define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile::value && is_assignable::value) +# endif +# if __has_feature(has_trivial_destructor) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) && is_destructible::value) +# endif +# if __has_feature(has_nothrow_constructor) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) && is_default_constructible::value) +# endif +# if __has_feature(has_nothrow_copy) +# define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T) && !is_volatile::value && !is_reference::value && is_copy_constructible::value) +# endif +# if __has_feature(has_nothrow_assign) +# define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile::value && is_assignable::value) +# endif +# if __has_feature(has_virtual_destructor) +# define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) +# endif +# if __has_feature(is_abstract) +# define BOOST_IS_ABSTRACT(T) __is_abstract(T) +# endif +# if __has_feature(is_base_of) +# define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) +# endif +# if __has_feature(is_class) +# define BOOST_IS_CLASS(T) __is_class(T) +# endif +# if __has_feature(is_convertible_to) +# define BOOST_IS_CONVERTIBLE(T,U) __is_convertible_to(T,U) +# endif +# if __has_feature(is_enum) +# define BOOST_IS_ENUM(T) __is_enum(T) +# endif +# if __has_feature(is_polymorphic) +# define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) +# endif +# if __has_feature(has_trivial_move_constructor) +# define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__has_trivial_move_constructor(T) && is_constructible::value && !::boost::is_volatile::value) +# endif +# if __has_feature(has_trivial_move_assign) +# define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__has_trivial_move_assign(T) && is_assignable::value && !::boost::is_volatile::value) +# endif +# if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) || !defined(__GNUC__) +// GCC sometimes lies about alignment requirements +// of type double on 32-bit unix platforms, use the +// old implementation instead in that case: +# define BOOST_ALIGNMENT_OF(T) __alignof(T) +# endif +# if __has_feature(is_final) +# define BOOST_IS_FINAL(T) __is_final(T) +# endif + +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + +#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG) +// +// Note that even though these intrinsics rely on other type traits classes +// we do not #include those here as it produces cyclic dependencies and +// can cause the intrinsics to not even be used at all! +// + +#ifdef BOOST_INTEL +# define BOOST_INTEL_TT_OPTS || is_pod::value +#else +# define BOOST_INTEL_TT_OPTS +#endif + +# define BOOST_IS_UNION(T) __is_union(T) +# define BOOST_IS_POD(T) __is_pod(T) +# define BOOST_IS_EMPTY(T) __is_empty(T) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile::value) +# define BOOST_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_INTEL_TT_OPTS) && !is_reference::value) +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 +# define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile::value && ! ::boost::is_const::value && is_assignable::value) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_INTEL_TT_OPTS && is_destructible::value) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) && is_default_constructible::value BOOST_INTEL_TT_OPTS) +# define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_INTEL_TT_OPTS) && !is_volatile::value && !is_reference::value && is_copy_constructible::value) +# define BOOST_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_INTEL_TT_OPTS) && !is_volatile::value && !is_const::value && is_assignable::value) +#else +# define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile::value && ! ::boost::is_const::value) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_INTEL_TT_OPTS) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_INTEL_TT_OPTS) +# define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_INTEL_TT_OPTS) && !is_volatile::value && !is_reference::value && !is_array::value) +# define BOOST_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_INTEL_TT_OPTS) && !is_volatile::value && !is_const::value && !is_array::value) +#endif +# define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) + +# define BOOST_IS_ABSTRACT(T) __is_abstract(T) +# define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) +# define BOOST_IS_CLASS(T) __is_class(T) +# define BOOST_IS_ENUM(T) __is_enum(T) +# define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) +# if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) + // GCC sometimes lies about alignment requirements + // of type double on 32-bit unix platforms, use the + // old implementation instead in that case: +# define BOOST_ALIGNMENT_OF(T) __alignof__(T) +# endif +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) +# define BOOST_IS_FINAL(T) __is_final(T) +# endif + +# if (__GNUC__ >= 5) && (__cplusplus >= 201103) +# define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__is_trivially_assignable(T&, T&&) && is_assignable::value && !::boost::is_volatile::value) +# define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_trivially_constructible(T, T&&) && is_constructible::value && !::boost::is_volatile::value) +# endif + +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) +# define BOOST_IS_UNION(T) __oracle_is_union(T) +# define BOOST_IS_POD(T) (__oracle_is_pod(T) && !is_function::value) +# define BOOST_IS_EMPTY(T) __oracle_is_empty(T) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__oracle_has_trivial_constructor(T) && ! ::boost::is_volatile::value) +# define BOOST_HAS_TRIVIAL_COPY(T) (__oracle_has_trivial_copy(T) && !is_reference::value) +# define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__oracle_has_trivial_assign(T) || __oracle_is_trivial(T)) && ! ::boost::is_volatile::value && ! ::boost::is_const::value && is_assignable::value) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__oracle_has_trivial_destructor(T) && is_destructible::value) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) ((__oracle_has_nothrow_constructor(T) || __oracle_has_trivial_constructor(T) || __oracle_is_trivial(T)) && is_default_constructible::value) +// __oracle_has_nothrow_copy appears to behave the same as __oracle_has_nothrow_assign, disabled for now: +//# define BOOST_HAS_NOTHROW_COPY(T) ((__oracle_has_nothrow_copy(T) || __oracle_has_trivial_copy(T) || __oracle_is_trivial(T)) && !is_volatile::value && !is_reference::value && is_copy_constructible::value) +# define BOOST_HAS_NOTHROW_ASSIGN(T) ((__oracle_has_nothrow_assign(T) || __oracle_has_trivial_assign(T) || __oracle_is_trivial(T)) && !is_volatile::value && !is_const::value && is_assignable::value) +# define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __oracle_has_virtual_destructor(T) + +# define BOOST_IS_ABSTRACT(T) __oracle_is_abstract(T) +//# define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) +# define BOOST_IS_CLASS(T) __oracle_is_class(T) +# define BOOST_IS_ENUM(T) __oracle_is_enum(T) +# define BOOST_IS_POLYMORPHIC(T) __oracle_is_polymorphic(T) +# define BOOST_ALIGNMENT_OF(T) __alignof__(T) +# define BOOST_IS_FINAL(T) __oracle_is_final(T) + +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + +#if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) +# include +# include +# include + +# define BOOST_IS_UNION(T) __is_union(T) +# define BOOST_IS_POD(T) __is_pod(T) +# define BOOST_IS_EMPTY(T) __is_empty(T) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) +# define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && !is_reference::value) +# define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile::value) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T) +# define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T) && !is_volatile::value && !is_reference::value) +# define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile::value) +# define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) + +# define BOOST_IS_ABSTRACT(T) __is_abstract(T) +# define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same::value) +# define BOOST_IS_CLASS(T) __is_class(T) +# define BOOST_IS_ENUM(T) __is_enum(T) +# define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) +# define BOOST_ALIGNMENT_OF(T) __alignof__(T) +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + +# if defined(__CODEGEARC__) +# include +# include +# include +# include + +# define BOOST_IS_UNION(T) __is_union(T) +# define BOOST_IS_POD(T) __is_pod(T) +# define BOOST_IS_EMPTY(T) __is_empty(T) +# define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T)) +# define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T) && !is_reference::value) +# define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile::value) +# define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T)) +# define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_default_constructor(T)) +# define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy_constructor(T) && !is_volatile::value && !is_reference::value) +# define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile::value) +# define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T) + +# define BOOST_IS_ABSTRACT(T) __is_abstract(T) +# define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_void::value && !is_void::value) +# define BOOST_IS_CLASS(T) __is_class(T) +# define BOOST_IS_CONVERTIBLE(T,U) (__is_convertible(T,U) || is_void::value) +# define BOOST_IS_ENUM(T) __is_enum(T) +# define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) +# define BOOST_ALIGNMENT_OF(T) alignof(T) + +# define BOOST_HAS_TYPE_TRAITS_INTRINSICS +#endif + +#endif // BOOST_TT_DISABLE_INTRINSICS + +#endif // BOOST_TT_INTRINSICS_HPP_INCLUDED + diff --git a/thirdparty/linux/include/boost/type_traits/is_abstract.hpp b/thirdparty/linux/include/boost/type_traits/is_abstract.hpp new file mode 100644 index 0000000..781d94a --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_abstract.hpp @@ -0,0 +1,150 @@ +#ifndef BOOST_TT_IS_ABSTRACT_CLASS_HPP +#define BOOST_TT_IS_ABSTRACT_CLASS_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// is_abstract_class.hpp: +// +// (C) Copyright 2002 Rani Sharoni (rani_sharoni@hotmail.com) and Robert Ramey +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org for updates, documentation, and revision history. +// + +// Compile type discovery whether given type is abstract class or not. +// +// Requires DR 337 to be supported by compiler +// (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#337). +// +// +// Believed (Jan 2004) to work on: +// - GCC 3.4 +// - VC++ 7.1 +// - compilers with new EDG frontend (Intel C++ 7, Comeau 4.3.2) +// +// Doesn't work on: +// - VC++6, VC++7.0 and less +// - GCC 3.3.X and less +// - Borland C++ 6 and less +// +// +// History: +// - Originally written by Rani Sharoni, see +// http://groups.google.com/groups?selm=df893da6.0207110613.75b2fe90%40posting.google.com +// At this time supported by EDG (Intel C++ 7, Comeau 4.3.2) and VC7.1. +// - Adapted and added into Boost.Serialization library by Robert Ramey +// (starting with submission #10). +// - Jan 2004: GCC 3.4 fixed to support DR337 (Giovanni Bajo). +// - Jan 2004: modified to be part of Boost.TypeTraits (Pavel Vozenilek). +// - Nov 2004: Christoph Ludwig found that the implementation did not work with +// template types and gcc-3.4 or VC7.1, fix due to Christoph Ludwig +// and John Maddock. +// - Dec 2004: Added new config macro BOOST_NO_IS_ABSTRACT which causes the template +// to degrade gracefully, rather than trash the compiler (John Maddock). +// + +#include // size_t +#include +#include +#ifndef BOOST_IS_ABSTRACT +#include +#include +#include +#ifdef BOOST_NO_IS_ABSTRACT +#include +#endif +#endif + +namespace boost { + +namespace detail{ + +#ifdef BOOST_IS_ABSTRACT +template +struct is_abstract_imp +{ + BOOST_STATIC_CONSTANT(bool, value = BOOST_IS_ABSTRACT(T)); +}; +#elif !defined(BOOST_NO_IS_ABSTRACT) +template +struct is_abstract_imp2 +{ + // Deduction fails if T is void, function type, + // reference type (14.8.2/2)or an abstract class type + // according to review status issue #337 + // + template + static type_traits::no_type check_sig(U (*)[1]); + template + static type_traits::yes_type check_sig(...); + // + // T must be a complete type, further if T is a template then + // it must be instantiated in order for us to get the right answer: + // + BOOST_STATIC_ASSERT(sizeof(T) != 0); + + // GCC2 won't even parse this template if we embed the computation + // of s1 in the computation of value. +#ifdef __GNUC__ + BOOST_STATIC_CONSTANT(std::size_t, s1 = sizeof(is_abstract_imp2::template check_sig(0))); +#else +#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) +#pragma warning(push) +#pragma warning(disable:6334) +#endif + BOOST_STATIC_CONSTANT(std::size_t, s1 = sizeof(check_sig(0))); +#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) +#pragma warning(pop) +#endif +#endif + + BOOST_STATIC_CONSTANT(bool, value = + (s1 == sizeof(type_traits::yes_type))); +}; + +template +struct is_abstract_select +{ + template + struct rebind + { + typedef is_abstract_imp2 type; + }; +}; +template <> +struct is_abstract_select +{ + template + struct rebind + { + typedef false_type type; + }; +}; + +template +struct is_abstract_imp +{ + typedef is_abstract_select< ::boost::is_class::value> selector; + typedef typename selector::template rebind binder; + typedef typename binder::type type; + + BOOST_STATIC_CONSTANT(bool, value = type::value); +}; + +#endif +} + +#ifndef BOOST_NO_IS_ABSTRACT +template struct is_abstract : public integral_constant::value> {}; +#else +template struct is_abstract : public integral_constant::value> {}; +#endif + +} // namespace boost + +#endif //BOOST_TT_IS_ABSTRACT_CLASS_HPP diff --git a/thirdparty/linux/include/boost/type_traits/is_arithmetic.hpp b/thirdparty/linux/include/boost/type_traits/is_arithmetic.hpp new file mode 100644 index 0000000..c23811e --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_arithmetic.hpp @@ -0,0 +1,22 @@ + +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED +#define BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED + +#include +#include + +namespace boost { + +template +struct is_arithmetic : public integral_constant::value || is_floating_point::value> {}; + +} // namespace boost + +#endif // BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_array.hpp b/thirdparty/linux/include/boost/type_traits/is_array.hpp new file mode 100644 index 0000000..53e1613 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_array.hpp @@ -0,0 +1,43 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard +// Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + + +// Some fixes for is_array are based on a newsgroup posting by Jonathan Lundquist. + + +#ifndef BOOST_TT_IS_ARRAY_HPP_INCLUDED +#define BOOST_TT_IS_ARRAY_HPP_INCLUDED + +#include +#include // size_t + +namespace boost { + +#if defined( __CODEGEARC__ ) + template struct is_array : public integral_constant {}; +#else + template struct is_array : public false_type {}; +#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) + template struct is_array : public true_type {}; + template struct is_array : public true_type{}; + template struct is_array : public true_type{}; + template struct is_array : public true_type{}; +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) + template struct is_array : public true_type{}; + template struct is_array : public true_type{}; + template struct is_array : public true_type{}; + template struct is_array : public true_type{}; +#endif +#endif + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_ARRAY_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_class.hpp b/thirdparty/linux/include/boost/type_traits/is_class.hpp new file mode 100644 index 0000000..e3a22d2 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_class.hpp @@ -0,0 +1,114 @@ +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard +// Hinnant & John Maddock 2000-2003. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + + +#ifndef BOOST_TT_IS_CLASS_HPP_INCLUDED +#define BOOST_TT_IS_CLASS_HPP_INCLUDED + +#include +#include +#include +#ifndef BOOST_IS_CLASS +# include + +#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION +# include +#else +# include +# include +# include +# include +# include +#endif + +#endif // BOOST_IS_CLASS + +namespace boost { + +namespace detail { + +#ifndef BOOST_IS_CLASS +#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION + +// This is actually the conforming implementation which works with +// abstract classes. However, enough compilers have trouble with +// it that most will use the one in +// boost/type_traits/object_traits.hpp. This implementation +// actually works with VC7.0, but other interactions seem to fail +// when we use it. + +// is_class<> metafunction due to Paul Mensonides +// (leavings@attbi.com). For more details: +// http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1 +#if defined(__GNUC__) && !defined(__EDG_VERSION__) + +template ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); +template ::boost::type_traits::no_type is_class_tester(...); + +template +struct is_class_impl +{ + + BOOST_STATIC_CONSTANT(bool, value = + sizeof(is_class_tester(0)) == sizeof(::boost::type_traits::yes_type) + && ! ::boost::is_union::value + ); +}; + +#else + +template +struct is_class_impl +{ + template static ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); + template static ::boost::type_traits::no_type is_class_tester(...); + + BOOST_STATIC_CONSTANT(bool, value = + sizeof(is_class_tester(0)) == sizeof(::boost::type_traits::yes_type) + && ! ::boost::is_union::value + ); +}; + +#endif + +#else + +template +struct is_class_impl +{ + BOOST_STATIC_CONSTANT(bool, value = + ! ::boost::is_union::value >::value + && ! ::boost::is_scalar::value + && ! ::boost::is_array::value + && ! ::boost::is_reference::value + && ! ::boost::is_void::value + && ! ::boost::is_function::value + ); +}; + +# endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION +# else // BOOST_IS_CLASS +template +struct is_class_impl +{ + BOOST_STATIC_CONSTANT(bool, value = BOOST_IS_CLASS(T)); +}; +# endif // BOOST_IS_CLASS + +} // namespace detail + +template struct is_class : public integral_constant::value> {}; +# ifdef __EDG_VERSION__ +template struct is_class : public is_class{}; +template struct is_class : public is_class{}; +template struct is_class : public is_class{}; +# endif + +} // namespace boost + +#endif // BOOST_TT_IS_CLASS_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_convertible.hpp b/thirdparty/linux/include/boost/type_traits/is_convertible.hpp new file mode 100644 index 0000000..417ece2 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_convertible.hpp @@ -0,0 +1,488 @@ + +// Copyright 2000 John Maddock (john@johnmaddock.co.uk) +// Copyright 2000 Jeremy Siek (jsiek@lsc.nd.edu) +// Copyright 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) +// +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED +#define BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED + +#include +#include +#ifndef BOOST_IS_CONVERTIBLE +#include +#include +#include +#include +#include +#if !defined(BOOST_NO_IS_ABSTRACT) +#include +#endif +#include +#include +#include + +#if defined(__MWERKS__) +#include +#endif +#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +# include +#endif +#elif defined(BOOST_MSVC) || defined(BOOST_INTEL) +#include +#include +#endif // BOOST_IS_CONVERTIBLE + +namespace boost { + +#ifndef BOOST_IS_CONVERTIBLE + +// is one type convertible to another? +// +// there are multiple versions of the is_convertible +// template, almost every compiler seems to require its +// own version. +// +// Thanks to Andrei Alexandrescu for the original version of the +// conversion detection technique! +// + +namespace detail { + +#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !(defined(BOOST_GCC) && (BOOST_GCC < 40700)) + + // This is a C++11 conforming version, place this first and use it wherever possible: + +# define BOOST_TT_CXX11_IS_CONVERTIBLE + + template + struct or_helper + { + static const bool value = (A::value || B::value || C::value); + }; + + template, boost::is_function, boost::is_array >::value> + struct is_convertible_basic_impl + { + // Nothing converts to function or array, but void converts to void: + static const bool value = is_void::value; + }; + + template + class is_convertible_basic_impl + { + typedef char one; + typedef int two; + + template + static void test_aux(To1); + + template + static decltype(test_aux(boost::declval()), one()) test(int); + + template + static two test(...); + + public: + static const bool value = sizeof(test(0)) == 1; + }; + +#elif defined(__BORLANDC__) && (__BORLANDC__ < 0x560) +// +// special version for Borland compilers +// this version breaks when used for some +// UDT conversions: +// +template +struct is_convertible_impl +{ +#pragma option push -w-8074 + // This workaround for Borland breaks the EDG C++ frontend, + // so we only use it for Borland. + template struct checker + { + static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...); + static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(T); + }; + + static typename add_lvalue_reference::type _m_from; + static bool const value = sizeof( checker::_m_check(_m_from) ) + == sizeof(::boost::type_traits::yes_type); +#pragma option pop +}; + +#elif defined(__GNUC__) || defined(__BORLANDC__) && (__BORLANDC__ < 0x600) +// special version for gcc compiler + recent Borland versions +// note that this does not pass UDT's through (...) + +struct any_conversion +{ + template any_conversion(const volatile T&); + template any_conversion(const T&); + template any_conversion(volatile T&); + template any_conversion(T&); +}; + +template struct checker +{ + static boost::type_traits::no_type _m_check(any_conversion ...); + static boost::type_traits::yes_type _m_check(T, int); +}; + +template +struct is_convertible_basic_impl +{ + typedef typename add_lvalue_reference::type lvalue_type; + typedef typename add_rvalue_reference::type rvalue_type; + static lvalue_type _m_from; +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6))) + static bool const value = + sizeof( boost::detail::checker::_m_check(static_cast(_m_from), 0) ) + == sizeof(::boost::type_traits::yes_type); +#else + static bool const value = + sizeof( boost::detail::checker::_m_check(_m_from, 0) ) + == sizeof(::boost::type_traits::yes_type); +#endif +}; + +#elif (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \ + || defined(__IBMCPP__) || defined(__HP_aCC) +// +// This is *almost* an ideal world implementation as it doesn't rely +// on undefined behaviour by passing UDT's through (...). +// Unfortunately it doesn't quite pass all the tests for most compilers (sigh...) +// Enable this for your compiler if is_convertible_test.cpp will compile it... +// +// Note we do not enable this for VC7.1, because even though it passes all the +// type_traits tests it is known to cause problems when instantiation occurs +// deep within the instantiation tree :-( +// +struct any_conversion +{ + template any_conversion(const volatile T&); + template any_conversion(const T&); + template any_conversion(volatile T&); + // we need this constructor to catch references to functions + // (which can not be cv-qualified): + template any_conversion(T&); +}; + +template +struct is_convertible_basic_impl +{ + static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...); + static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int); + typedef typename add_lvalue_reference::type lvalue_type; + typedef typename add_rvalue_reference::type rvalue_type; + static lvalue_type _m_from; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_CONSTANT(bool, value = + sizeof( _m_check(static_cast(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type) + ); +#else + BOOST_STATIC_CONSTANT(bool, value = + sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type) + ); +#endif +}; + +#elif defined(__DMC__) + +struct any_conversion +{ + template any_conversion(const volatile T&); + template any_conversion(const T&); + template any_conversion(volatile T&); + // we need this constructor to catch references to functions + // (which can not be cv-qualified): + template any_conversion(T&); +}; + +template +struct is_convertible_basic_impl +{ + // Using '...' doesn't always work on Digital Mars. This version seems to. + template + static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion, float, T); + static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int, int); + typedef typename add_lvalue_reference::type lvalue_type; + typedef typename add_rvalue_reference::type rvalue_type; + static lvalue_type _m_from; + + // Static constants sometime cause the conversion of _m_from to To to be + // called. This doesn't happen with an enum. +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + enum { value = + sizeof( _m_check(static_cast(_m_from), 0, 0) ) == sizeof(::boost::type_traits::yes_type) + }; +#else + enum { value = + sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type) + }; +#endif +}; + +#elif defined(__MWERKS__) +// +// CW works with the technique implemented above for EDG, except when From +// is a function type (or a reference to such a type), in which case +// any_conversion won't be accepted as a valid conversion. We detect this +// exceptional situation and channel it through an alternative algorithm. +// + +template +struct is_convertible_basic_impl_aux; + +struct any_conversion +{ + template any_conversion(const volatile T&); + template any_conversion(const T&); + template any_conversion(volatile T&); + template any_conversion(T&); +}; + +template +struct is_convertible_basic_impl_aux +{ + static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...); + static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int); + typedef typename add_lvalue_reference::type lvalue_type; + typedef typename add_rvalue_reference::type rvalue_type; + static lvalue_type _m_from; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_CONSTANT(bool, value = + sizeof( _m_check(static_cast(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type) + ); +#else + BOOST_STATIC_CONSTANT(bool, value = + sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type) + ); +#endif +}; + +template +struct is_convertible_basic_impl_aux +{ + static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...); + static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To); + typedef typename add_lvalue_reference::type lvalue_type; + typedef typename add_rvalue_reference::type rvalue_type; + static lvalue_type _m_from; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_CONSTANT(bool, value = + sizeof( _m_check(static_cast(_m_from)) ) == sizeof(::boost::type_traits::yes_type) + ); +#else + BOOST_STATIC_CONSTANT(bool, value = + sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type) + ); +#endif +}; + +template +struct is_convertible_basic_impl: + is_convertible_basic_impl_aux< + From,To, + ::boost::is_function::type>::value + > +{}; + +#else +// +// This version seems to work pretty well for a wide spectrum of compilers, +// however it does rely on undefined behaviour by passing UDT's through (...). +// + +//Workaround for old compilers like MSVC 7.1 to avoid +//forming a reference to an array of unknown bound +template +struct is_convertible_basic_impl_add_lvalue_reference + : add_lvalue_reference +{}; + +template +struct is_convertible_basic_impl_add_lvalue_reference +{ + typedef From type []; +}; + +template +struct is_convertible_basic_impl +{ + static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...); + static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To); + typedef typename is_convertible_basic_impl_add_lvalue_reference::type lvalue_type; + static lvalue_type _m_from; +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) +#pragma warning(disable:6334) +#endif +#endif +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + typedef typename add_rvalue_reference::type rvalue_type; + BOOST_STATIC_CONSTANT(bool, value = + sizeof( _m_check(static_cast(_m_from)) ) == sizeof(::boost::type_traits::yes_type) + ); +#else + BOOST_STATIC_CONSTANT(bool, value = + sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type) + ); +#endif +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +}; + +#endif // is_convertible_impl + +#if defined(__DMC__) +// As before, a static constant sometimes causes errors on Digital Mars. +template +struct is_convertible_impl +{ + enum { + value = ( ::boost::detail::is_convertible_basic_impl::value && ! ::boost::is_array::value && ! ::boost::is_function::value) + }; +}; +#elif !defined(__BORLANDC__) || __BORLANDC__ > 0x551 +template +struct is_convertible_impl +{ + BOOST_STATIC_CONSTANT(bool, value = ( ::boost::detail::is_convertible_basic_impl::value && !::boost::is_array::value && !::boost::is_function::value)); +}; +#endif + +template +struct is_convertible_impl_select +{ + template + struct rebind + { + typedef is_convertible_impl type; + }; +}; + +template <> +struct is_convertible_impl_select +{ + template + struct rebind + { + typedef true_type type; + }; +}; + +template <> +struct is_convertible_impl_select +{ + template + struct rebind + { + typedef false_type type; + }; +}; + +template <> +struct is_convertible_impl_select +{ + template + struct rebind + { + typedef false_type type; + }; +}; + +template +struct is_convertible_impl_dispatch_base +{ +#if !BOOST_WORKAROUND(__HP_aCC, < 60700) + typedef is_convertible_impl_select< + ::boost::is_arithmetic::value, + ::boost::is_arithmetic::value, +#if !defined(BOOST_NO_IS_ABSTRACT) && !defined(BOOST_TT_CXX11_IS_CONVERTIBLE) + // We need to filter out abstract types, only if we don't have a strictly conforming C++11 version: + ::boost::is_abstract::value +#else + false +#endif + > selector; +#else + typedef is_convertible_impl_select selector; +#endif + typedef typename selector::template rebind isc_binder; + typedef typename isc_binder::type type; +}; + +template +struct is_convertible_impl_dispatch + : public is_convertible_impl_dispatch_base::type +{}; + +// +// Now add the full and partial specialisations +// for void types, these are common to all the +// implementation above: +// +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS + +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; + +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; + +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; + +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; +template <> struct is_convertible_impl_dispatch : public true_type{}; + +#else +template <> struct is_convertible_impl_dispatch : public true_type{}; +#endif // BOOST_NO_CV_VOID_SPECIALIZATIONS + +template struct is_convertible_impl_dispatch : public false_type{}; +template struct is_convertible_impl_dispatch : public false_type{}; + +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +template struct is_convertible_impl_dispatch : public false_type{}; +template struct is_convertible_impl_dispatch : public false_type{}; +template struct is_convertible_impl_dispatch : public false_type{}; +template struct is_convertible_impl_dispatch : public false_type{}; +template struct is_convertible_impl_dispatch : public false_type{}; +template struct is_convertible_impl_dispatch : public false_type{}; +#endif + +} // namespace detail + +template +struct is_convertible : public integral_constant::value> {}; + +#else + +template +struct is_convertible : public integral_constant {}; + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_enum.hpp b/thirdparty/linux/include/boost/type_traits/is_enum.hpp new file mode 100644 index 0000000..eada480 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_enum.hpp @@ -0,0 +1,166 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard +// Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + + +#ifndef BOOST_TT_IS_ENUM_HPP_INCLUDED +#define BOOST_TT_IS_ENUM_HPP_INCLUDED + +#include +#include +#ifndef BOOST_IS_ENUM +#include +#include +#include +#include +#include +#ifdef __GNUC__ +#include +#endif +#include +#if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION) +# include +# include +#endif +#endif + +namespace boost { + +#ifndef BOOST_IS_ENUM +#if !(defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)) + +namespace detail { + +#if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION) + +template +struct is_class_or_union +{ + BOOST_STATIC_CONSTANT(bool, value = ::boost::is_class::value || ::boost::is_union::value); +}; + +#else + +template +struct is_class_or_union +{ +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))// we simply can't detect it this way. + BOOST_STATIC_CONSTANT(bool, value = false); +# else + template static ::boost::type_traits::yes_type is_class_or_union_tester(void(U::*)(void)); + +# if BOOST_WORKAROUND(__MWERKS__, <= 0x3000) // no SFINAE + static ::boost::type_traits::no_type is_class_or_union_tester(...); + BOOST_STATIC_CONSTANT( + bool, value = sizeof(is_class_or_union_tester(0)) == sizeof(::boost::type_traits::yes_type)); +# else + template + static ::boost::type_traits::no_type is_class_or_union_tester(...); + BOOST_STATIC_CONSTANT( + bool, value = sizeof(is_class_or_union_tester(0)) == sizeof(::boost::type_traits::yes_type)); +# endif +# endif +}; +#endif + +struct int_convertible +{ + int_convertible(int); +}; + +// Don't evaluate convertibility to int_convertible unless the type +// is non-arithmetic. This suppresses warnings with GCC. +template +struct is_enum_helper +{ + template struct type + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; +}; + +template <> +struct is_enum_helper +{ + template struct type + { + static const bool value = ::boost::is_convertible::type, ::boost::detail::int_convertible>::value; + }; +}; + +template struct is_enum_impl +{ + //typedef ::boost::add_reference ar_t; + //typedef typename ar_t::type r_type; + +#if defined(__GNUC__) + +#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION + + // We MUST check for is_class_or_union on conforming compilers in + // order to correctly deduce that noncopyable types are not enums + // (dwa 2002/04/15)... + BOOST_STATIC_CONSTANT(bool, selector = + ::boost::is_arithmetic::value + || ::boost::is_reference::value + || ::boost::is_function::value + || is_class_or_union::value + || is_array::value); +#else + // ...however, not checking is_class_or_union on non-conforming + // compilers prevents a dependency recursion. + BOOST_STATIC_CONSTANT(bool, selector = + ::boost::is_arithmetic::value + || ::boost::is_reference::value + || ::boost::is_function::value + || is_array::value); +#endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION + +#else // !defined(__GNUC__): + + BOOST_STATIC_CONSTANT(bool, selector = + ::boost::is_arithmetic::value + || ::boost::is_reference::value + || is_class_or_union::value + || is_array::value); + +#endif + +#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) + typedef ::boost::detail::is_enum_helper< + ::boost::detail::is_enum_impl::selector + > se_t; +#else + typedef ::boost::detail::is_enum_helper se_t; +#endif + + typedef typename se_t::template type helper; + BOOST_STATIC_CONSTANT(bool, value = helper::value); +}; + +} // namespace detail + +template struct is_enum : public integral_constant::value> {}; + +#else // __BORLANDC__ +// +// buggy is_convertible prevents working +// implementation of is_enum: +template struct is_enum : public integral_constant {}; + +#endif + +#else // BOOST_IS_ENUM + +template struct is_enum : public integral_constant {}; + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_ENUM_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_floating_point.hpp b/thirdparty/linux/include/boost/type_traits/is_floating_point.hpp new file mode 100644 index 0000000..196c900 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_floating_point.hpp @@ -0,0 +1,30 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000-2005. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TYPE_TRAITS_IS_FLOATING_HPP_INCLUDED +#define BOOST_TYPE_TRAITS_IS_FLOATING_HPP_INCLUDED + +#include + +namespace boost { + +//* is a type T a floating-point type described in the standard (3.9.1p8) + template struct is_floating_point : public false_type{}; + template struct is_floating_point : public is_floating_point{}; + template struct is_floating_point : public is_floating_point{}; + template struct is_floating_point : public is_floating_point{}; + template<> struct is_floating_point : public true_type{}; + template<> struct is_floating_point : public true_type{}; + template<> struct is_floating_point : public true_type{}; + +#if defined(BOOST_HAS_FLOAT128) + template<> struct is_floating_point<__float128> : public true_type{}; +#endif + +} // namespace boost + +#endif // BOOST_TYPE_TRAITS_IS_FLOAT_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_function.hpp b/thirdparty/linux/include/boost/type_traits/is_function.hpp new file mode 100644 index 0000000..f77c1f0 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_function.hpp @@ -0,0 +1,102 @@ + +// Copyright 2000 John Maddock (john@johnmaddock.co.uk) +// Copyright 2002 Aleksey Gurtovoy (agurtovoy@meta-comm.com) +// +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_FUNCTION_HPP_INCLUDED +#define BOOST_TT_IS_FUNCTION_HPP_INCLUDED + +#include +#include + +#if !defined(BOOST_TT_TEST_MS_FUNC_SIGS) +# include +#else +# include +# include +#endif + +// is a type a function? +// Please note that this implementation is unnecessarily complex: +// we could just use !is_convertible::value, +// except that some compilers erroneously allow conversions from +// function pointers to void*. + +namespace boost { + +#if !defined( __CODEGEARC__ ) + +namespace detail { + +#if !defined(BOOST_TT_TEST_MS_FUNC_SIGS) +template +struct is_function_chooser +{ + template< typename T > struct result_ + : public false_type {}; +}; + +template <> +struct is_function_chooser +{ + template< typename T > struct result_ + : public ::boost::type_traits::is_function_ptr_helper {}; +}; + +template +struct is_function_impl + : public is_function_chooser< ::boost::is_reference::value > + ::BOOST_NESTED_TEMPLATE result_ +{ +}; + +#else + +template +struct is_function_impl +{ +#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) +#pragma warning(push) +#pragma warning(disable:6334) +#endif + static T* t; + BOOST_STATIC_CONSTANT( + bool, value = sizeof(::boost::type_traits::is_function_ptr_tester(t)) + == sizeof(::boost::type_traits::yes_type) + ); +#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) +#pragma warning(pop) +#endif +}; + +template +struct is_function_impl : public false_type +{}; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template +struct is_function_impl : public false_type +{}; +#endif + +#endif + +} // namespace detail + +#endif // !defined( __CODEGEARC__ ) + +#if defined( __CODEGEARC__ ) +template struct is_function : integral_constant {}; +#else +template struct is_function : integral_constant::value> {}; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template struct is_function : public false_type {}; +#endif +#endif +} // namespace boost + +#endif // BOOST_TT_IS_FUNCTION_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_integral.hpp b/thirdparty/linux/include/boost/type_traits/is_integral.hpp new file mode 100644 index 0000000..7a7e54b --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_integral.hpp @@ -0,0 +1,89 @@ + +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_INTEGRAL_HPP_INCLUDED +#define BOOST_TT_IS_INTEGRAL_HPP_INCLUDED + +#include +#include + +namespace boost { + +#if defined( __CODEGEARC__ ) + template + struct is_integral : public integral_constant {}; +#else + +template struct is_integral : public false_type {}; +template struct is_integral : public is_integral {}; +template struct is_integral : public is_integral{}; +template struct is_integral : public is_integral{}; + +//* is a type T an [cv-qualified-] integral type described in the standard (3.9.1p3) +// as an extension we include long long, as this is likely to be added to the +// standard at a later date +template<> struct is_integral : public true_type {}; +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; + +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; + +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +// If the following line fails to compile and you're using the Intel +// compiler, see http://lists.boost.org/MailArchives/boost-users/msg06567.php, +// and define BOOST_NO_INTRINSIC_WCHAR_T on the command line. +template<> struct is_integral : public true_type{}; +#endif + +// Same set of integral types as in boost/type_traits/integral_promotion.hpp. +// Please, keep in sync. -- Alexander Nasonov +#if (defined(BOOST_INTEL_CXX_VERSION) && defined(_MSC_VER) && (BOOST_INTEL_CXX_VERSION <= 600)) \ + || (defined(__BORLANDC__) && (__BORLANDC__ == 0x600) && (_MSC_VER < 1300)) +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; +template<> struct is_integral<__int8> : public true_type{}; +template<> struct is_integral<__int16> : public true_type{}; +template<> struct is_integral<__int32> : public true_type{}; +#ifdef __BORLANDC__ +template<> struct is_integral : public true_type{}; +template<> struct is_integral<__int64> : public true_type{}; +#endif +#endif + +# if defined(BOOST_HAS_LONG_LONG) +template<> struct is_integral< ::boost::ulong_long_type> : public true_type{}; +template<> struct is_integral< ::boost::long_long_type> : public true_type{}; +#elif defined(BOOST_HAS_MS_INT64) +template<> struct is_integral : public true_type{}; +template<> struct is_integral<__int64> : public true_type{}; +#endif + +#ifdef BOOST_HAS_INT128 +template<> struct is_integral : public true_type{}; +template<> struct is_integral : public true_type{}; +#endif +#ifndef BOOST_NO_CXX11_CHAR16_T +template<> struct is_integral : public true_type{}; +#endif +#ifndef BOOST_NO_CXX11_CHAR32_T +template<> struct is_integral : public true_type{}; +#endif + +#endif // non-CodeGear implementation + +} // namespace boost + +#endif // BOOST_TT_IS_INTEGRAL_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_lvalue_reference.hpp b/thirdparty/linux/include/boost/type_traits/is_lvalue_reference.hpp new file mode 100644 index 0000000..e94d787 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_lvalue_reference.hpp @@ -0,0 +1,50 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Howard Hinnant and John Maddock 2000. +// (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +// Fixed is_pointer, is_lvalue_reference, is_const, is_volatile, is_same, +// is_member_pointer based on the Simulated Partial Specialization work +// of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or +// http://groups.yahoo.com/group/boost/message/5441 +// Some workarounds in here use ideas suggested from "Generic: +// Mappings between Types and Values" +// by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). + + +#ifndef BOOST_TT_IS_LVALUE_REFERENCE_HPP_INCLUDED +#define BOOST_TT_IS_LVALUE_REFERENCE_HPP_INCLUDED + +#include + +namespace boost { + +#if defined( __CODEGEARC__ ) + template struct is_lvalue_reference : public integral_constant{}; +#else + + template struct is_lvalue_reference : public false_type{}; + template struct is_lvalue_reference : public true_type{}; + +#if defined(BOOST_ILLEGAL_CV_REFERENCES) +// these are illegal specialisations; cv-qualifies applied to +// references have no effect according to [8.3.2p1], +// C++ Builder requires them though as it treats cv-qualified +// references as distinct types... + template struct is_lvalue_reference : public true_type{}; + template struct is_lvalue_reference : public true_type{}; + template struct is_lvalue_reference : public true_type{}; +#endif + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED + diff --git a/thirdparty/linux/include/boost/type_traits/is_member_function_pointer.hpp b/thirdparty/linux/include/boost/type_traits/is_member_function_pointer.hpp new file mode 100644 index 0000000..223197f --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_member_function_pointer.hpp @@ -0,0 +1,120 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard +// Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + + +#ifndef BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED +#define BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED + +#include +#include + +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(BOOST_TT_TEST_MS_FUNC_SIGS) + // + // Note: we use the "workaround" version for MSVC because it works for + // __stdcall etc function types, where as the partial specialisation + // version does not do so. + // +# include +# include +# include +#else +# include +# include +# include +# include +#endif + +namespace boost { + +#if defined( __CODEGEARC__ ) +template struct is_member_function_pointer : public integral_constant {}; +#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(BOOST_TT_TEST_MS_FUNC_SIGS) + +template struct is_member_function_pointer + : public ::boost::integral_constant::type>::value>{}; + +#else + +namespace detail { + +#ifndef __BORLANDC__ + +template +struct is_mem_fun_pointer_select +{ + template struct result_ : public false_type{}; +}; + +template <> +struct is_mem_fun_pointer_select +{ + template struct result_ + { +#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) +#pragma warning(push) +#pragma warning(disable:6334) +#endif + static T* make_t; + typedef result_ self_type; + + BOOST_STATIC_CONSTANT( + bool, value = ( + 1 == sizeof(::boost::type_traits::is_mem_fun_pointer_tester(self_type::make_t)) + )); +#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000) +#pragma warning(pop) +#endif + }; +}; + +template +struct is_member_function_pointer_impl + : public is_mem_fun_pointer_select< + ::boost::is_reference::value || ::boost::is_array::value>::template result_{}; + +template +struct is_member_function_pointer_impl : public false_type{}; + +#else // Borland C++ + +template +struct is_member_function_pointer_impl +{ + static T* m_t; + BOOST_STATIC_CONSTANT( + bool, value = + (1 == sizeof(type_traits::is_mem_fun_pointer_tester(m_t))) ); +}; + +template +struct is_member_function_pointer_impl +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +#endif + +template<> struct is_member_function_pointer_impl : public false_type{}; +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +template<> struct is_member_function_pointer_impl : public false_type{}; +template<> struct is_member_function_pointer_impl : public false_type{}; +template<> struct is_member_function_pointer_impl : public false_type{}; +#endif + +} // namespace detail + +template +struct is_member_function_pointer + : public integral_constant::value>{}; + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_member_pointer.hpp b/thirdparty/linux/include/boost/type_traits/is_member_pointer.hpp new file mode 100644 index 0000000..9757afc --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_member_pointer.hpp @@ -0,0 +1,45 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Howard Hinnant and John Maddock 2000. +// (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +// Fixed is_pointer, is_reference, is_const, is_volatile, is_same, +// is_member_pointer based on the Simulated Partial Specialization work +// of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or +// http://groups.yahoo.com/group/boost/message/5441 +// Some workarounds in here use ideas suggested from "Generic: +// Mappings between Types and Values" +// by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). + + +#ifndef BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED +#define BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED + +#include +#include + +namespace boost { + +#if defined( __CODEGEARC__ ) +template struct is_member_pointer : public integral_constant{}; +#else +template struct is_member_pointer : public integral_constant::value>{}; +template struct is_member_pointer : public true_type{}; + +#if !BOOST_WORKAROUND(__MWERKS__,<=0x3003) && !BOOST_WORKAROUND(__IBMCPP__, <=600) +template struct is_member_pointer : public true_type{}; +template struct is_member_pointer : public true_type{}; +template struct is_member_pointer : public true_type{}; +#endif + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_pod.hpp b/thirdparty/linux/include/boost/type_traits/is_pod.hpp new file mode 100644 index 0000000..9bd1962 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_pod.hpp @@ -0,0 +1,59 @@ + +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_POD_HPP_INCLUDED +#define BOOST_TT_IS_POD_HPP_INCLUDED + +#include // size_t +#include +#include +#include +#include + +#ifdef __SUNPRO_CC +#include +#endif + +#include + +#ifndef BOOST_IS_POD +#define BOOST_INTERNAL_IS_POD(T) false +#else +#define BOOST_INTERNAL_IS_POD(T) BOOST_IS_POD(T) +#endif + +namespace boost { + +// forward declaration, needed by 'is_pod_array_helper' template below +template< typename T > struct is_POD; + +template struct is_pod +: public integral_constant::value || ::boost::is_void::value || BOOST_INTERNAL_IS_POD(T)> +{}; + +#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +template struct is_pod : public is_pod{}; +#endif + + +// the following help compilers without partial specialization support: +template<> struct is_pod : public true_type{}; + +#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +template<> struct is_pod : public true_type{}; +template<> struct is_pod : public true_type{}; +template<> struct is_pod : public true_type{}; +#endif + +template struct is_POD : public is_pod{}; + +} // namespace boost + +#undef BOOST_INTERNAL_IS_POD + +#endif // BOOST_TT_IS_POD_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_pointer.hpp b/thirdparty/linux/include/boost/type_traits/is_pointer.hpp new file mode 100644 index 0000000..44b06c2 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_pointer.hpp @@ -0,0 +1,47 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Howard Hinnant and John Maddock 2000. +// (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +// Fixed is_pointer, is_reference, is_const, is_volatile, is_same, +// is_member_pointer based on the Simulated Partial Specialization work +// of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or +// http://groups.yahoo.com/group/boost/message/5441 +// Some workarounds in here use ideas suggested from "Generic: +// Mappings between Types and Values" +// by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). + + +#ifndef BOOST_TT_IS_POINTER_HPP_INCLUDED +#define BOOST_TT_IS_POINTER_HPP_INCLUDED + +#include + +namespace boost { + +#if defined( __CODEGEARC__ ) +template struct is_pointer : public integral_constant{}; +#else +template struct is_pointer : public false_type{}; +template struct is_pointer : public true_type{}; +template struct is_pointer : public true_type{}; +template struct is_pointer : public true_type{}; +template struct is_pointer : public true_type{}; + +#ifdef BOOST_MSVC +template struct is_pointer : public is_pointer{}; +template struct is_pointer : public is_pointer{}; +template struct is_pointer : public is_pointer{}; +#endif + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_POINTER_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_polymorphic.hpp b/thirdparty/linux/include/boost/type_traits/is_polymorphic.hpp new file mode 100644 index 0000000..722d8b4 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_polymorphic.hpp @@ -0,0 +1,122 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_POLYMORPHIC_HPP +#define BOOST_TT_IS_POLYMORPHIC_HPP + +#include +#include +#ifndef BOOST_IS_POLYMORPHIC +#include +#endif +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700) +#pragma warning(push) +#pragma warning(disable:4250) +#endif + +namespace boost{ + +#ifndef BOOST_IS_POLYMORPHIC + +namespace detail{ + +template +struct is_polymorphic_imp1 +{ +# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) // CWPro7 should return false always. + typedef char d1, (&d2)[2]; +# else + struct d1 : public T + { + d1(); +# if !defined(__GNUC__) // this raises warnings with some classes, and buys nothing with GCC + ~d1()throw(); +# endif + char padding[256]; + private: + // keep some picky compilers happy: + d1(const d1&); + d1& operator=(const d1&); + }; + struct d2 : public T + { + d2(); + virtual ~d2()throw(); +# if !defined(BOOST_MSVC) && !defined(__ICL) + // for some reason this messes up VC++ when T has virtual bases, + // probably likewise for compilers that use the same ABI: + struct unique{}; + virtual void unique_name_to_boost5487629(unique*); +# endif + char padding[256]; + private: + // keep some picky compilers happy: + d2(const d2&); + d2& operator=(const d2&); + }; +# endif + BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1))); +}; + +template struct is_polymorphic_imp1 : public is_polymorphic_imp1{}; +template struct is_polymorphic_imp1 : public is_polymorphic_imp1{}; +template struct is_polymorphic_imp1 : public is_polymorphic_imp1{}; + +template +struct is_polymorphic_imp2 +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_polymorphic_selector +{ + template + struct rebind + { + typedef is_polymorphic_imp2 type; + }; +}; + +template <> +struct is_polymorphic_selector +{ + template + struct rebind + { + typedef is_polymorphic_imp1 type; + }; +}; + +template +struct is_polymorphic_imp +{ + typedef is_polymorphic_selector< ::boost::is_class::value> selector; + typedef typename selector::template rebind binder; + typedef typename binder::type imp_type; + BOOST_STATIC_CONSTANT(bool, value = imp_type::value); +}; + +} // namespace detail + +template struct is_polymorphic : public integral_constant::value> {}; + +#else // BOOST_IS_POLYMORPHIC + +template struct is_polymorphic : public integral_constant {}; + +#endif + +} // namespace boost + +#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1700) +#pragma warning(pop) +#endif + +#endif diff --git a/thirdparty/linux/include/boost/type_traits/is_reference.hpp b/thirdparty/linux/include/boost/type_traits/is_reference.hpp new file mode 100644 index 0000000..85f0a63 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_reference.hpp @@ -0,0 +1,30 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Howard Hinnant and John Maddock 2000, 2010. +// (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_REFERENCE_HPP_INCLUDED +#define BOOST_TT_IS_REFERENCE_HPP_INCLUDED + +#include +#include + +namespace boost { + +template struct is_reference + : public + integral_constant< + bool, + ::boost::is_lvalue_reference::value || ::boost::is_rvalue_reference::value> +{}; + +} // namespace boost + +#endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED + diff --git a/thirdparty/linux/include/boost/type_traits/is_rvalue_reference.hpp b/thirdparty/linux/include/boost/type_traits/is_rvalue_reference.hpp new file mode 100644 index 0000000..50e88ed --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_rvalue_reference.hpp @@ -0,0 +1,25 @@ + +// (C) John Maddock 2010. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_RVALUE_REFERENCE_HPP_INCLUDED +#define BOOST_TT_IS_RVALUE_REFERENCE_HPP_INCLUDED + +#include +#include + +namespace boost { + +template struct is_rvalue_reference : public false_type {}; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template struct is_rvalue_reference : public true_type {}; +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED + diff --git a/thirdparty/linux/include/boost/type_traits/is_same.hpp b/thirdparty/linux/include/boost/type_traits/is_same.hpp new file mode 100644 index 0000000..d16f4b2 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_same.hpp @@ -0,0 +1,41 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Howard Hinnant and John Maddock 2000. +// (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +// Fixed is_pointer, is_reference, is_const, is_volatile, is_same, +// is_member_pointer based on the Simulated Partial Specialization work +// of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or +// http://groups.yahoo.com/group/boost/message/5441 +// Some workarounds in here use ideas suggested from "Generic: +// Mappings between Types and Values" +// by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). + + +#ifndef BOOST_TT_IS_SAME_HPP_INCLUDED +#define BOOST_TT_IS_SAME_HPP_INCLUDED + +#include + +namespace boost { + + + template struct is_same : public false_type {}; + template struct is_same : public true_type {}; +#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) +// without this, Borland's compiler gives the wrong answer for +// references to arrays: + template struct is_same : public true_type{}; +#endif + + +} // namespace boost + +#endif // BOOST_TT_IS_SAME_HPP_INCLUDED + diff --git a/thirdparty/linux/include/boost/type_traits/is_scalar.hpp b/thirdparty/linux/include/boost/type_traits/is_scalar.hpp new file mode 100644 index 0000000..3031440 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_scalar.hpp @@ -0,0 +1,27 @@ + +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_SCALAR_HPP_INCLUDED +#define BOOST_TT_IS_SCALAR_HPP_INCLUDED + +#include +#include +#include +#include +#include + +namespace boost { + +template +struct is_scalar + : public integral_constant::value || ::boost::is_enum::value || ::boost::is_pointer::value || ::boost::is_member_pointer::value> +{}; + +} // namespace boost + +#endif // BOOST_TT_IS_SCALAR_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_union.hpp b/thirdparty/linux/include/boost/type_traits/is_union.hpp new file mode 100644 index 0000000..c5e1a96 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_union.hpp @@ -0,0 +1,31 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard +// Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + + +#ifndef BOOST_TT_IS_UNION_HPP_INCLUDED +#define BOOST_TT_IS_UNION_HPP_INCLUDED + +#include +#include + +namespace boost { + +#ifdef BOOST_IS_UNION +template struct is_union : public integral_constant {}; +#else +template struct is_union : public integral_constant {}; +#endif + +template struct is_union : public is_union{}; +template struct is_union : public is_union{}; +template struct is_union : public is_union{}; + +} // namespace boost + +#endif // BOOST_TT_IS_UNION_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_void.hpp b/thirdparty/linux/include/boost/type_traits/is_void.hpp new file mode 100644 index 0000000..183f8ab --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_void.hpp @@ -0,0 +1,26 @@ + +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_VOID_HPP_INCLUDED +#define BOOST_TT_IS_VOID_HPP_INCLUDED + +#include + +namespace boost { + +template +struct is_void : public false_type {}; + +template<> struct is_void : public true_type {}; +template<> struct is_void : public true_type{}; +template<> struct is_void : public true_type{}; +template<> struct is_void : public true_type{}; + +} // namespace boost + +#endif // BOOST_TT_IS_VOID_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/is_volatile.hpp b/thirdparty/linux/include/boost/type_traits/is_volatile.hpp new file mode 100644 index 0000000..5b8e716 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/is_volatile.hpp @@ -0,0 +1,46 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Howard Hinnant and John Maddock 2000. +// (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +// Fixed is_pointer, is_reference, is_const, is_volatile, is_same, +// is_member_pointer based on the Simulated Partial Specialization work +// of Mat Marcus and Jesse Jones. See http://opensource.adobe.com or +// http://groups.yahoo.com/group/boost/message/5441 +// Some workarounds in here use ideas suggested from "Generic: +// Mappings between Types and Values" +// by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html). + + +#ifndef BOOST_TT_IS_VOLATILE_HPP_INCLUDED +#define BOOST_TT_IS_VOLATILE_HPP_INCLUDED + +#include // size_t +#include + +namespace boost { + +#if defined( __CODEGEARC__ ) + + template + struct is_volatile : public integral_constant {}; + +#else + + template + struct is_volatile : public false_type {}; + template struct is_volatile : public true_type{}; + template struct is_volatile : public true_type{}; + template struct is_volatile : public true_type{}; + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_VOLATILE_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/remove_cv.hpp b/thirdparty/linux/include/boost/type_traits/remove_cv.hpp new file mode 100644 index 0000000..08393cf --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/remove_cv.hpp @@ -0,0 +1,40 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard +// Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + + +#ifndef BOOST_TT_REMOVE_CV_HPP_INCLUDED +#define BOOST_TT_REMOVE_CV_HPP_INCLUDED + +#include +#include +#include // size_t + +namespace boost { + + // convert a type T to a non-cv-qualified type - remove_cv +template struct remove_cv{ typedef T type; }; +template struct remove_cv{ typedef T type; }; +template struct remove_cv{ typedef T type; }; +template struct remove_cv{ typedef T type; }; + +#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +template struct remove_cv{ typedef T type[N]; }; +template struct remove_cv{ typedef T type[N]; }; +template struct remove_cv{ typedef T type[N]; }; +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) +template struct remove_cv{ typedef T type[]; }; +template struct remove_cv{ typedef T type[]; }; +template struct remove_cv{ typedef T type[]; }; +#endif +#endif + + +} // namespace boost + +#endif // BOOST_TT_REMOVE_CV_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/remove_reference.hpp b/thirdparty/linux/include/boost/type_traits/remove_reference.hpp new file mode 100644 index 0000000..f75e677 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/remove_reference.hpp @@ -0,0 +1,54 @@ + +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED +#define BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED + +#include +#include + +namespace boost { + + +namespace detail{ +// +// We can't filter out rvalue_references at the same level as +// references or we get ambiguities from msvc: +// +template +struct remove_rvalue_ref +{ + typedef T type; +}; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template +struct remove_rvalue_ref +{ + typedef T type; +}; +#endif + +} // namespace detail + +template struct remove_reference{ typedef typename boost::detail::remove_rvalue_ref::type type; }; +template struct remove_reference{ typedef T type; }; + +#if defined(BOOST_ILLEGAL_CV_REFERENCES) +// these are illegal specialisations; cv-qualifies applied to +// references have no effect according to [8.3.2p1], +// C++ Builder requires them though as it treats cv-qualified +// references as distinct types... +template struct remove_reference{ typedef T type; }; +template struct remove_reference{ typedef T type; }; +template struct remove_reference{ typedef T type; }; +#endif + + +} // namespace boost + +#endif // BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED diff --git a/thirdparty/linux/include/boost/type_traits/type_with_alignment.hpp b/thirdparty/linux/include/boost/type_traits/type_with_alignment.hpp new file mode 100644 index 0000000..ddf1d98 --- /dev/null +++ b/thirdparty/linux/include/boost/type_traits/type_with_alignment.hpp @@ -0,0 +1,261 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED +#define BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED + +#include +#include +#include +#include +#include // size_t +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4121) // alignment is sensitive to packing +#endif + +#ifdef _MSC_VER +#include +#endif + +namespace boost { + namespace detail{ + +#ifndef __BORLANDC__ + + union max_align + { + char c; + short s; + int i; + long l; +#ifndef BOOST_NO_LONG_LONG + boost::long_long_type ll; +#endif +#ifdef BOOST_HAS_INT128 + boost::int128_type i128; +#endif + float f; + double d; + long double ld; +#ifdef BOOST_HAS_FLOAT128 + __float128 f128; +#endif + }; + +template struct long_double_alignment{ typedef long double type; }; +template struct long_double_alignment{ typedef boost::detail::max_align type; }; + +template struct double_alignment{ typedef double type; }; +template struct double_alignment{ typedef typename long_double_alignment::value >= Target>::type type; }; + +#ifndef BOOST_NO_LONG_LONG +template struct long_long_alignment{ typedef boost::long_long_type type; }; +template struct long_long_alignment{ typedef typename double_alignment::value >= Target>::type type; }; +#endif + +template struct long_alignment{ typedef long type; }; +#ifndef BOOST_NO_LONG_LONG +template struct long_alignment{ typedef typename long_long_alignment::value >= Target>::type type; }; +#else +template struct long_alignment{ typedef typename double_alignment::value >= Target>::type type; }; +#endif + +template struct int_alignment{ typedef int type; }; +template struct int_alignment{ typedef typename long_alignment::value >= Target>::type type; }; + +template struct short_alignment{ typedef short type; }; +template struct short_alignment{ typedef typename int_alignment::value >= Target>::type type; }; + +template struct char_alignment{ typedef char type; }; +template struct char_alignment{ typedef typename short_alignment::value >= Target>::type type; }; + +} + +template +struct type_with_alignment +{ + typedef typename boost::detail::char_alignment::value >= Align>::type type; +}; + +#if (defined(__GNUC__) || (defined (__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) || defined(__clang__)) && !defined(BOOST_TT_DISABLE_INTRINSICS) +namespace tt_align_ns { +struct __attribute__((__aligned__(2))) a2 {}; +struct __attribute__((__aligned__(4))) a4 {}; +struct __attribute__((__aligned__(8))) a8 {}; +struct __attribute__((__aligned__(16))) a16 {}; +struct __attribute__((__aligned__(32))) a32 {}; +struct __attribute__((__aligned__(64))) a64 {}; +struct __attribute__((__aligned__(128))) a128 {}; +} + +template<> struct type_with_alignment<1> { public: typedef char type; }; +template<> struct type_with_alignment<2> { public: typedef tt_align_ns::a2 type; }; +template<> struct type_with_alignment<4> { public: typedef tt_align_ns::a4 type; }; +template<> struct type_with_alignment<8> { public: typedef tt_align_ns::a8 type; }; +template<> struct type_with_alignment<16> { public: typedef tt_align_ns::a16 type; }; +template<> struct type_with_alignment<32> { public: typedef tt_align_ns::a32 type; }; +template<> struct type_with_alignment<64> { public: typedef tt_align_ns::a64 type; }; +template<> struct type_with_alignment<128> { public: typedef tt_align_ns::a128 type; }; + +template<> struct is_pod< ::boost::tt_align_ns::a2> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a4> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a32> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a64> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a128> : public true_type{}; + +#endif +#if (defined(BOOST_MSVC) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && !defined(BOOST_TT_DISABLE_INTRINSICS) +// +// MSVC supports types which have alignments greater than the normal +// maximum: these are used for example in the types __m64 and __m128 +// to provide types with alignment requirements which match the SSE +// registers. Therefore we extend type_with_alignment<> to support +// such types, however, we have to be careful to use a builtin type +// whenever possible otherwise we break previously working code: +// see http://article.gmane.org/gmane.comp.lib.boost.devel/173011 +// for an example and test case. Thus types like a8 below will +// be used *only* if the existing implementation can't provide a type +// with suitable alignment. This does mean however, that type_with_alignment<> +// may return a type which cannot be passed through a function call +// by value (and neither can any type containing such a type like +// Boost.Optional). However, this only happens when we have no choice +// in the matter because no other "ordinary" type is available. +// +namespace tt_align_ns { +struct __declspec(align(8)) a8 { + char m[8]; + typedef a8 type; +}; +struct __declspec(align(16)) a16 { + char m[16]; + typedef a16 type; +}; +struct __declspec(align(32)) a32 { + char m[32]; + typedef a32 type; +}; +struct __declspec(align(64)) a64 +{ + char m[64]; + typedef a64 type; +}; +struct __declspec(align(128)) a128 { + char m[128]; + typedef a128 type; +}; +} + +template<> struct type_with_alignment<8> +{ + typedef boost::conditional< + ::boost::alignment_of::value < 8, + tt_align_ns::a8, + boost::detail::char_alignment<8, false> >::type t1; +public: + typedef t1::type type; +}; +template<> struct type_with_alignment<16> +{ + typedef boost::conditional< + ::boost::alignment_of::value < 16, + tt_align_ns::a16, + boost::detail::char_alignment<16, false> >::type t1; +public: + typedef t1::type type; +}; +template<> struct type_with_alignment<32> +{ + typedef boost::conditional< + ::boost::alignment_of::value < 32, + tt_align_ns::a32, + boost::detail::char_alignment<32, false> >::type t1; +public: + typedef t1::type type; +}; +template<> struct type_with_alignment<64> { + typedef boost::conditional< + ::boost::alignment_of::value < 64, + tt_align_ns::a64, + boost::detail::char_alignment<64, false> >::type t1; +public: + typedef t1::type type; +}; +template<> struct type_with_alignment<128> { + typedef boost::conditional< + ::boost::alignment_of::value < 128, + tt_align_ns::a128, + boost::detail::char_alignment<128, false> >::type t1; +public: + typedef t1::type type; +}; + +template<> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a32> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a64> : public true_type{}; +template<> struct is_pod< ::boost::tt_align_ns::a128> : public true_type{}; + +#endif + +#else + +// +// Borland specific version, we have this for two reasons: +// 1) The version above doesn't always compile (with the new test cases for example) +// 2) Because of Borlands #pragma option we can create types with alignments that are +// greater that the largest aligned builtin type. + +namespace tt_align_ns{ +#pragma option push -a16 +struct a2{ short s; }; +struct a4{ int s; }; +struct a8{ double s; }; +struct a16{ long double s; }; +#pragma option pop +} + +namespace detail { + +typedef ::boost::tt_align_ns::a16 max_align; + +} +//#if ! BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) +template <> struct is_pod< ::boost::tt_align_ns::a2> : public true_type{}; +template <> struct is_pod< ::boost::tt_align_ns::a4> : public true_type{}; +template <> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{}; +template <> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{}; +//#endif + +template struct type_with_alignment +{ + // We should never get to here, but if we do use the maximally + // aligned type: + // BOOST_STATIC_ASSERT(0); + typedef tt_align_ns::a16 type; +}; +template <> struct type_with_alignment<1>{ typedef char type; }; +template <> struct type_with_alignment<2>{ typedef tt_align_ns::a2 type; }; +template <> struct type_with_alignment<4>{ typedef tt_align_ns::a4 type; }; +template <> struct type_with_alignment<8>{ typedef tt_align_ns::a8 type; }; +template <> struct type_with_alignment<16>{ typedef tt_align_ns::a16 type; }; + +#endif + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED + + diff --git a/thirdparty/linux/include/boost/version.hpp b/thirdparty/linux/include/boost/version.hpp new file mode 100644 index 0000000..94c16c3 --- /dev/null +++ b/thirdparty/linux/include/boost/version.hpp @@ -0,0 +1,32 @@ +// Boost version.hpp configuration header file ------------------------------// + +// (C) Copyright John maddock 1999. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for documentation + +#ifndef BOOST_VERSION_HPP +#define BOOST_VERSION_HPP + +// +// Caution: this is the only Boost header that is guaranteed +// to change with every Boost release. Including this header +// will cause a recompile every time a new Boost version is +// used. +// +// BOOST_VERSION % 100 is the patch level +// BOOST_VERSION / 100 % 1000 is the minor version +// BOOST_VERSION / 100000 is the major version + +#define BOOST_VERSION 106300 + +// +// BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION +// but as a *string* in the form "x_y[_z]" where x is the major version +// number, y is the minor version number, and z is the patch level if not 0. +// This is used by to select which library version to link to. + +#define BOOST_LIB_VERSION "1_63" + +#endif diff --git a/thirdparty/linux/include/coin/CbcOrClpParam.cpp b/thirdparty/linux/include/coin/CbcOrClpParam.cpp new file mode 100644 index 0000000..86365ca --- /dev/null +++ b/thirdparty/linux/include/coin/CbcOrClpParam.cpp @@ -0,0 +1,4134 @@ +/* $Id: CbcOrClpParam.cpp 2175 2015-10-06 08:56:43Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#include "CoinPragma.hpp" +#include "CoinTime.hpp" +#include "CbcOrClpParam.hpp" + +#include +#include +#include + +#ifdef COIN_HAS_CBC +#ifdef COIN_HAS_CLP +#include "OsiClpSolverInterface.hpp" +#include "ClpSimplex.hpp" +#endif +#include "CbcModel.hpp" +#endif +#include "CoinHelperFunctions.hpp" +#ifdef COIN_HAS_CLP +#include "ClpSimplex.hpp" +#include "ClpFactorization.hpp" +#endif +#ifdef COIN_HAS_READLINE +#include +#include +#endif +#ifdef COIN_HAS_CBC +// from CoinSolve +static char coin_prompt[] = "Coin:"; +#else +static char coin_prompt[] = "Clp:"; +#endif +#ifdef CLP_CILK +#ifndef CBC_THREAD +#define CBC_THREAD +#endif +#endif +#if defined(COIN_HAS_WSMP) && ! defined(USE_EKKWSSMP) +#ifndef CBC_THREAD +#define CBC_THREAD +#endif +#endif +#include "ClpConfig.h" +#ifdef CLP_HAS_ABC +#include "AbcCommon.hpp" +#endif +static bool doPrinting = true; +static std::string afterEquals = ""; +static char printArray[200]; +#if COIN_INT_MAX==0 +#undef COIN_INT_MAX +#define COIN_INT_MAX 2147483647 +#endif +#if FLUSH_PRINT_BUFFER > 2 +int coinFlushBufferFlag=0; +#endif +void setCbcOrClpPrinting(bool yesNo) +{ + doPrinting = yesNo; +} +//############################################################################# +// Constructors / Destructor / Assignment +//############################################################################# + +//------------------------------------------------------------------- +// Default Constructor +//------------------------------------------------------------------- +CbcOrClpParam::CbcOrClpParam () + : type_(CBC_PARAM_NOTUSED_INVALID), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + lengthName_(0), + lengthMatch_(0), + definedKeyWords_(), + name_(), + shortHelp_(), + longHelp_(), + action_(CBC_PARAM_NOTUSED_INVALID), + currentKeyWord_(-1), + display_(0), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ +} +// Other constructors +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + double lower, double upper, CbcOrClpParameterType type, + int display) + : type_(type), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ + lowerDoubleValue_ = lower; + upperDoubleValue_ = upper; + gutsOfConstructor(); +} +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + int lower, int upper, CbcOrClpParameterType type, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ + gutsOfConstructor(); + lowerIntValue_ = lower; + upperIntValue_ = upper; +} +// Other strings will be added by append +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + std::string firstValue, + CbcOrClpParameterType type, int whereUsed, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(0), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(whereUsed), + fakeKeyWord_(-1), + fakeValue_(0) +{ + gutsOfConstructor(); + definedKeyWords_.push_back(firstValue); +} +// Action +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + CbcOrClpParameterType type, int whereUsed, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + fakeKeyWord_(-1), + fakeValue_(0) +{ + whereUsed_ = whereUsed; + gutsOfConstructor(); +} + +//------------------------------------------------------------------- +// Copy constructor +//------------------------------------------------------------------- +CbcOrClpParam::CbcOrClpParam (const CbcOrClpParam & rhs) +{ + type_ = rhs.type_; + lowerDoubleValue_ = rhs.lowerDoubleValue_; + upperDoubleValue_ = rhs.upperDoubleValue_; + lowerIntValue_ = rhs.lowerIntValue_; + upperIntValue_ = rhs.upperIntValue_; + lengthName_ = rhs.lengthName_; + lengthMatch_ = rhs.lengthMatch_; + definedKeyWords_ = rhs.definedKeyWords_; + name_ = rhs.name_; + shortHelp_ = rhs.shortHelp_; + longHelp_ = rhs.longHelp_; + action_ = rhs.action_; + currentKeyWord_ = rhs.currentKeyWord_; + display_ = rhs.display_; + intValue_ = rhs.intValue_; + doubleValue_ = rhs.doubleValue_; + stringValue_ = rhs.stringValue_; + whereUsed_ = rhs.whereUsed_; + fakeKeyWord_ = rhs.fakeKeyWord_; + fakeValue_ = rhs.fakeValue_; +} + +//------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------- +CbcOrClpParam::~CbcOrClpParam () +{ +} + +//---------------------------------------------------------------- +// Assignment operator +//------------------------------------------------------------------- +CbcOrClpParam & +CbcOrClpParam::operator=(const CbcOrClpParam & rhs) +{ + if (this != &rhs) { + type_ = rhs.type_; + lowerDoubleValue_ = rhs.lowerDoubleValue_; + upperDoubleValue_ = rhs.upperDoubleValue_; + lowerIntValue_ = rhs.lowerIntValue_; + upperIntValue_ = rhs.upperIntValue_; + lengthName_ = rhs.lengthName_; + lengthMatch_ = rhs.lengthMatch_; + definedKeyWords_ = rhs.definedKeyWords_; + name_ = rhs.name_; + shortHelp_ = rhs.shortHelp_; + longHelp_ = rhs.longHelp_; + action_ = rhs.action_; + currentKeyWord_ = rhs.currentKeyWord_; + display_ = rhs.display_; + intValue_ = rhs.intValue_; + doubleValue_ = rhs.doubleValue_; + stringValue_ = rhs.stringValue_; + whereUsed_ = rhs.whereUsed_; + fakeKeyWord_ = rhs.fakeKeyWord_; + fakeValue_ = rhs.fakeValue_; + } + return *this; +} +void +CbcOrClpParam::gutsOfConstructor() +{ + std::string::size_type shriekPos = name_.find('!'); + lengthName_ = static_cast(name_.length()); + if ( shriekPos == std::string::npos ) { + //does not contain '!' + lengthMatch_ = lengthName_; + } else { + lengthMatch_ = static_cast(shriekPos); + name_ = name_.substr(0, shriekPos) + name_.substr(shriekPos + 1); + lengthName_--; + } +} +// Sets value of fake keyword to current size of keywords +void +CbcOrClpParam::setFakeKeyWord(int fakeValue) +{ + fakeKeyWord_ = static_cast(definedKeyWords_.size()); + assert (fakeKeyWord_>0); + fakeValue_ = fakeValue; + assert (fakeValue_>=0); +} +/* Returns current parameter option position + but if fake keyword returns fakeValue_ +*/ +int +CbcOrClpParam::currentOptionAsInteger ( ) const +{ + int fakeInteger; + return currentOptionAsInteger(fakeInteger); +} +/* Returns current parameter option position + but if fake keyword returns fakeValue_ and sets + fakeInteger to value +*/ +int +CbcOrClpParam::currentOptionAsInteger ( int & fakeInteger ) const +{ + fakeInteger=-COIN_INT_MAX; + if (fakeKeyWord_<0) { + return currentKeyWord_; + } else if (currentKeyWord_>=0&¤tKeyWord_ lengthName_) { + return 0; + } else { + unsigned int i; + for (i = 0; i < input.length(); i++) { + if (tolower(name_[i]) != tolower(input[i])) + break; + } + if (i < input.length()) { + return 0; + } else if (i >= lengthMatch_) { + return 1; + } else { + // matched but too short + return 2; + } + } +} +// Returns name which could match +std::string +CbcOrClpParam::matchName ( ) const +{ + if (lengthMatch_ == lengthName_) + return name_; + else + return name_.substr(0, lengthMatch_) + "(" + name_.substr(lengthMatch_) + ")"; +} + +// Returns parameter option which matches (-1 if none) +int +CbcOrClpParam::parameterOption ( std::string check ) const +{ + int numberItems = static_cast(definedKeyWords_.size()); + if (!numberItems) { + return -1; + } else { + int whichItem = 0; + unsigned int it; + for (it = 0; it < definedKeyWords_.size(); it++) { + std::string thisOne = definedKeyWords_[it]; + std::string::size_type shriekPos = thisOne.find('!'); + size_t length1 = thisOne.length(); + size_t length2 = length1; + if ( shriekPos != std::string::npos ) { + //contains '!' + length2 = shriekPos; + thisOne = thisOne.substr(0, shriekPos) + + thisOne.substr(shriekPos + 1); + length1 = thisOne.length(); + } + if (check.length() <= length1 && length2 <= check.length()) { + unsigned int i; + for (i = 0; i < check.length(); i++) { + if (tolower(thisOne[i]) != tolower(check[i])) + break; + } + if (i < check.length()) { + whichItem++; + } else if (i >= length2) { + break; + } + } else { + whichItem++; + } + } + if (whichItem < numberItems) { + return whichItem; + } else { + if (fakeKeyWord_<=0) + return -1; + // allow plus or minus + int n; + if (check.substr(0,4)=="plus"||check.substr(0,4)=="PLUS") { + n = 4; + } else if (check.substr(0,5)=="minus"||check.substr(0,5)=="MINUS") { + n = 5; + } else { + return -1; + } + int value = 0; + std::string field=check.substr(n); + if (field != "EOL") { + const char * start = field.c_str(); + char * endPointer = NULL; + // check valid + value = static_cast(strtol(start, &endPointer, 10)); + if (*endPointer != '\0') { + return -1; + } + if (n==4) + return value + 1000; + else + return -value - 1000; + } else { + return -1; + } + } + } +} +// Prints parameter options +void +CbcOrClpParam::printOptions ( ) const +{ + std::cout << "= 0 && currentKeyWord_ < static_cast(definedKeyWords_.size())); + std::string current = definedKeyWords_[currentKeyWord_]; + std::string::size_type shriekPos = current.find('!'); + if ( shriekPos != std::string::npos ) { + //contains '!' + current = current.substr(0, shriekPos) + + "(" + current.substr(shriekPos + 1) + ")"; + } + std::cout << ";\n\tcurrent " << current << ">" << std::endl; +} +// Print action and string +void +CbcOrClpParam::printString() const +{ + if (name_ == "directory") + std::cout << "Current working directory is " << stringValue_ << std::endl; + else if (name_.substr(0, 6) == "printM") + std::cout << "Current value of printMask is " << stringValue_ << std::endl; + else + std::cout << "Current default (if $ as parameter) for " << name_ + << " is " << stringValue_ << std::endl; +} +void CoinReadPrintit(const char * input) +{ + int length = static_cast(strlen(input)); + char temp[101]; + int i; + int n = 0; + for (i = 0; i < length; i++) { + if (input[i] == '\n') { + temp[n] = '\0'; + std::cout << temp << std::endl; + n = 0; + } else if (n >= 65 && input[i] == ' ') { + temp[n] = '\0'; + std::cout << temp << std::endl; + n = 0; + } else if (n || input[i] != ' ') { + temp[n++] = input[i]; + } + } + if (n) { + temp[n] = '\0'; + std::cout << temp << std::endl; + } +} +// Print Long help +void +CbcOrClpParam::printLongHelp() const +{ + if (type_ >= 1 && type_ < 400) { + CoinReadPrintit(longHelp_.c_str()); + if (type_ < CLP_PARAM_INT_SOLVERLOGLEVEL) { + printf("\n", lowerDoubleValue_, upperDoubleValue_, doubleValue_); + assert (upperDoubleValue_ > lowerDoubleValue_); + } else if (type_ < CLP_PARAM_STR_DIRECTION) { + printf("\n", lowerIntValue_, upperIntValue_, intValue_); + assert (upperIntValue_ > lowerIntValue_); + } else if (type_ < CLP_PARAM_ACTION_DIRECTORY) { + printOptions(); + } + } +} +#ifdef COIN_HAS_CBC +int +CbcOrClpParam::setDoubleParameter (OsiSolverInterface * model, double value) +{ + int returnCode; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets double parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( OsiSolverInterface * model, double value , int & returnCode) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + returnCode = 1; + } else { + double oldValue = doubleValue_; + doubleValue_ = value; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + model->getDblParam(OsiDualTolerance, oldValue); + model->setDblParam(OsiDualTolerance, value); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + model->getDblParam(OsiPrimalTolerance, oldValue); + model->setDblParam(OsiPrimalTolerance, value); + break; + default: + break; + } + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +#endif +#ifdef COIN_HAS_CLP +int +CbcOrClpParam::setDoubleParameter (ClpSimplex * model, double value) +{ + int returnCode; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( ClpSimplex * model, double value , int & returnCode) +{ + double oldValue = doubleValue_; + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + returnCode = 1; + } else { + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + doubleValue_ = value; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + model->setDualTolerance(value); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + model->setPrimalTolerance(value); + break; + case CLP_PARAM_DBL_ZEROTOLERANCE: + model->setSmallElementValue(value); + break; + case CLP_PARAM_DBL_DUALBOUND: + model->setDualBound(value); + break; + case CLP_PARAM_DBL_PRIMALWEIGHT: + model->setInfeasibilityCost(value); + break; +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_TIMELIMIT: + model->setMaximumSeconds(value); + break; +#endif + case CLP_PARAM_DBL_OBJSCALE: + model->setObjectiveScale(value); + break; + case CLP_PARAM_DBL_RHSSCALE: + model->setRhsScale(value); + break; + case CLP_PARAM_DBL_PRESOLVETOLERANCE: + model->setDblParam(ClpPresolveTolerance, value); + break; + default: + break; + } + } + return printArray; +} +double +CbcOrClpParam::doubleParameter (ClpSimplex * model) const +{ + double value; + switch (type_) { +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_DUALTOLERANCE: + value = model->dualTolerance(); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + value = model->primalTolerance(); + break; +#endif + case CLP_PARAM_DBL_ZEROTOLERANCE: + value = model->getSmallElementValue(); + break; + case CLP_PARAM_DBL_DUALBOUND: + value = model->dualBound(); + break; + case CLP_PARAM_DBL_PRIMALWEIGHT: + value = model->infeasibilityCost(); + break; +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_TIMELIMIT: + value = model->maximumSeconds(); + break; +#endif + case CLP_PARAM_DBL_OBJSCALE: + value = model->objectiveScale(); + break; + case CLP_PARAM_DBL_RHSSCALE: + value = model->rhsScale(); + break; + default: + value = doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (ClpSimplex * model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( ClpSimplex * model, int value , int & returnCode) +{ + int oldValue = intValue_; + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + intValue_ = value; + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + model->setLogLevel(value); + if (value > 2) + model->factorization()->messageLevel(8); + else + model->factorization()->messageLevel(0); + break; + case CLP_PARAM_INT_MAXFACTOR: + model->factorization()->maximumPivots(value); + break; + case CLP_PARAM_INT_PERTVALUE: + model->setPerturbation(value); + break; + case CLP_PARAM_INT_MAXITERATION: + model->setMaximumIterations(value); + break; + case CLP_PARAM_INT_SPECIALOPTIONS: + model->setSpecialOptions(value); + break; + case CLP_PARAM_INT_RANDOMSEED: + { + if (value==0) { + double time = fabs(CoinGetTimeOfDay()); + while (time>=COIN_INT_MAX) + time *= 0.5; + value = static_cast(time); + sprintf(printArray, "using time of day %s was changed from %d to %d", + name_.c_str(), oldValue, value); + } + model->setRandomSeed(value); + } + break; + case CLP_PARAM_INT_MORESPECIALOPTIONS: + model->setMoreSpecialOptions(value); + break; +#ifndef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + model->setNumberThreads(value); + break; +#endif +#endif + default: + break; + } + } + return printArray; +} +int +CbcOrClpParam::intParameter (ClpSimplex * model) const +{ + int value; + switch (type_) { +#ifndef COIN_HAS_CBC + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model->logLevel(); + break; +#endif + case CLP_PARAM_INT_MAXFACTOR: + value = model->factorization()->maximumPivots(); + break; + break; + case CLP_PARAM_INT_PERTVALUE: + value = model->perturbation(); + break; + case CLP_PARAM_INT_MAXITERATION: + value = model->maximumIterations(); + break; + case CLP_PARAM_INT_SPECIALOPTIONS: + value = model->specialOptions(); + break; + case CLP_PARAM_INT_RANDOMSEED: + value = model->randomNumberGenerator()->getSeed(); + break; + case CLP_PARAM_INT_MORESPECIALOPTIONS: + value = model->moreSpecialOptions(); + break; +#ifndef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + value = model->numberThreads(); + break; +#endif +#endif + default: + value = intValue_; + break; + } + return value; +} +#endif +int +CbcOrClpParam::checkDoubleParameter (double value) const +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + return 1; + } else { + return 0; + } +} +#ifdef COIN_HAS_CBC +double +CbcOrClpParam::doubleParameter (OsiSolverInterface * +#ifndef NDEBUG + model +#endif + ) const +{ + double value = 0.0; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + assert(model->getDblParam(OsiDualTolerance, value)); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + assert(model->getDblParam(OsiPrimalTolerance, value)); + break; + default: + return doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (OsiSolverInterface * model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( OsiSolverInterface * model, int value , int & returnCode) +{ + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + int oldValue = intValue_; + intValue_ = oldValue; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + model->messageHandler()->setLogLevel(value); + break; + default: + break; + } + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +int +CbcOrClpParam::intParameter (OsiSolverInterface * model) const +{ + int value = 0; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model->messageHandler()->logLevel(); + break; + default: + value = intValue_; + break; + } + return value; +} +int +CbcOrClpParam::setDoubleParameter (CbcModel &model, double value) +{ + int returnCode=0; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets double parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( CbcModel & model, double value , int & returnCode) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + returnCode = 1; + } else { + double oldValue = doubleValue_; + doubleValue_ = value; + switch (type_) { + case CBC_PARAM_DBL_INFEASIBILITYWEIGHT: + oldValue = model.getDblParam(CbcModel::CbcInfeasibilityWeight); + model.setDblParam(CbcModel::CbcInfeasibilityWeight, value); + break; + case CBC_PARAM_DBL_INTEGERTOLERANCE: + oldValue = model.getDblParam(CbcModel::CbcIntegerTolerance); + model.setDblParam(CbcModel::CbcIntegerTolerance, value); + break; + case CBC_PARAM_DBL_INCREMENT: + oldValue = model.getDblParam(CbcModel::CbcCutoffIncrement); + model.setDblParam(CbcModel::CbcCutoffIncrement, value); + case CBC_PARAM_DBL_ALLOWABLEGAP: + oldValue = model.getDblParam(CbcModel::CbcAllowableGap); + model.setDblParam(CbcModel::CbcAllowableGap, value); + break; + case CBC_PARAM_DBL_GAPRATIO: + oldValue = model.getDblParam(CbcModel::CbcAllowableFractionGap); + model.setDblParam(CbcModel::CbcAllowableFractionGap, value); + break; + case CBC_PARAM_DBL_CUTOFF: + oldValue = model.getCutoff(); + model.setCutoff(value); + break; + case CBC_PARAM_DBL_TIMELIMIT_BAB: + oldValue = model.getDblParam(CbcModel::CbcMaximumSeconds) ; + { + //OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver()); + //ClpSimplex * lpSolver = clpSolver->getModelPtr(); + //lpSolver->setMaximumSeconds(value); + model.setDblParam(CbcModel::CbcMaximumSeconds, value) ; + } + break ; + case CLP_PARAM_DBL_DUALTOLERANCE: + case CLP_PARAM_DBL_PRIMALTOLERANCE: + setDoubleParameter(model.solver(), value); + return 0; // to avoid message + default: + break; + } + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +double +CbcOrClpParam::doubleParameter (CbcModel &model) const +{ + double value; + switch (type_) { + case CBC_PARAM_DBL_INFEASIBILITYWEIGHT: + value = model.getDblParam(CbcModel::CbcInfeasibilityWeight); + break; + case CBC_PARAM_DBL_INTEGERTOLERANCE: + value = model.getDblParam(CbcModel::CbcIntegerTolerance); + break; + case CBC_PARAM_DBL_INCREMENT: + value = model.getDblParam(CbcModel::CbcCutoffIncrement); + break; + case CBC_PARAM_DBL_ALLOWABLEGAP: + value = model.getDblParam(CbcModel::CbcAllowableGap); + break; + case CBC_PARAM_DBL_GAPRATIO: + value = model.getDblParam(CbcModel::CbcAllowableFractionGap); + break; + case CBC_PARAM_DBL_CUTOFF: + value = model.getCutoff(); + break; + case CBC_PARAM_DBL_TIMELIMIT_BAB: + value = model.getDblParam(CbcModel::CbcMaximumSeconds) ; + break ; + case CLP_PARAM_DBL_DUALTOLERANCE: + case CLP_PARAM_DBL_PRIMALTOLERANCE: + value = doubleParameter(model.solver()); + break; + default: + value = doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (CbcModel &model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( CbcModel & model, int value , int & returnCode) +{ + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + printArray[0] = '\0'; + if (value==intValue_) + return printArray; + int oldValue = intValue_; + intValue_ = value; + switch (type_) { + case CLP_PARAM_INT_LOGLEVEL: + oldValue = model.messageHandler()->logLevel(); + model.messageHandler()->setLogLevel(CoinAbs(value)); + break; + case CLP_PARAM_INT_SOLVERLOGLEVEL: + oldValue = model.solver()->messageHandler()->logLevel(); + model.solver()->messageHandler()->setLogLevel(value); + break; + case CBC_PARAM_INT_MAXNODES: + oldValue = model.getIntParam(CbcModel::CbcMaxNumNode); + model.setIntParam(CbcModel::CbcMaxNumNode, value); + break; + case CBC_PARAM_INT_MAXSOLS: + oldValue = model.getIntParam(CbcModel::CbcMaxNumSol); + model.setIntParam(CbcModel::CbcMaxNumSol, value); + break; + case CBC_PARAM_INT_MAXSAVEDSOLS: + oldValue = model.maximumSavedSolutions(); + model.setMaximumSavedSolutions(value); + break; + case CBC_PARAM_INT_STRONGBRANCHING: + oldValue = model.numberStrong(); + model.setNumberStrong(value); + break; + case CBC_PARAM_INT_NUMBERBEFORE: + oldValue = model.numberBeforeTrust(); + model.setNumberBeforeTrust(value); + break; + case CBC_PARAM_INT_NUMBERANALYZE: + oldValue = model.numberAnalyzeIterations(); + model.setNumberAnalyzeIterations(value); + break; + case CBC_PARAM_INT_CUTPASSINTREE: + oldValue = model.getMaximumCutPasses(); + model.setMaximumCutPasses(value); + break; + case CBC_PARAM_INT_CUTPASS: + oldValue = model.getMaximumCutPassesAtRoot(); + model.setMaximumCutPassesAtRoot(value); + break; +#ifdef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + oldValue = model.getNumberThreads(); + model.setNumberThreads(value); + break; +#endif + case CBC_PARAM_INT_RANDOMSEED: + oldValue = model.getRandomSeed(); + model.setRandomSeed(value); + break; +#endif + default: + break; + } + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +int +CbcOrClpParam::intParameter (CbcModel &model) const +{ + int value; + switch (type_) { + case CLP_PARAM_INT_LOGLEVEL: + value = model.messageHandler()->logLevel(); + break; + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model.solver()->messageHandler()->logLevel(); + break; + case CBC_PARAM_INT_MAXNODES: + value = model.getIntParam(CbcModel::CbcMaxNumNode); + break; + case CBC_PARAM_INT_MAXSOLS: + value = model.getIntParam(CbcModel::CbcMaxNumSol); + break; + case CBC_PARAM_INT_MAXSAVEDSOLS: + value = model.maximumSavedSolutions(); + break; + case CBC_PARAM_INT_STRONGBRANCHING: + value = model.numberStrong(); + break; + case CBC_PARAM_INT_NUMBERBEFORE: + value = model.numberBeforeTrust(); + break; + case CBC_PARAM_INT_NUMBERANALYZE: + value = model.numberAnalyzeIterations(); + break; + case CBC_PARAM_INT_CUTPASSINTREE: + value = model.getMaximumCutPasses(); + break; + case CBC_PARAM_INT_CUTPASS: + value = model.getMaximumCutPassesAtRoot(); + break; +#ifdef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + value = model.getNumberThreads(); +#endif + case CBC_PARAM_INT_RANDOMSEED: + value = model.getRandomSeed(); + break; +#endif + default: + value = intValue_; + break; + } + return value; +} +#endif +// Sets current parameter option using string +void +CbcOrClpParam::setCurrentOption ( const std::string value ) +{ + int action = parameterOption(value); + if (action >= 0) + currentKeyWord_ = action; +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=action; +#endif +} +// Sets current parameter option +void +CbcOrClpParam::setCurrentOption ( int value , bool printIt) +{ + if (printIt && value != currentKeyWord_) + std::cout << "Option for " << name_ << " changed from " + << definedKeyWords_[currentKeyWord_] << " to " + << definedKeyWords_[value] << std::endl; + +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=value; +#endif + currentKeyWord_ = value; +} +// Sets current parameter option and returns printable string +const char * +CbcOrClpParam::setCurrentOptionWithMessage ( int value ) +{ + if (value != currentKeyWord_) { + char current[100]; + char newString[100]; + if (currentKeyWord_>=0&&(fakeKeyWord_<=0||currentKeyWord_=0&&(fakeKeyWord_<=0||value 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=value; +#endif + currentKeyWord_ = value; + } else { + printArray[0] = '\0'; + } + return printArray; +} +// Sets current parameter option using string with message +const char * +CbcOrClpParam::setCurrentOptionWithMessage ( const std::string value ) +{ + int action = parameterOption(value); + char current[100]; + printArray[0] = '\0'; + if (action >= 0) { +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=action; +#endif + if (action == currentKeyWord_) + return NULL; + if (currentKeyWord_>=0&&(fakeKeyWord_<=0||currentKeyWord_ upperIntValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerIntValue_ << " to " << + upperIntValue_ << std::endl; + } else { + intValue_ = value; + } +} +const char * +CbcOrClpParam::setIntValueWithMessage ( int value ) +{ + printArray[0] = '\0'; + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value,name_.c_str(),lowerIntValue_,upperIntValue_); + } else { + if (value==intValue_) + return NULL; + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), intValue_, value); + intValue_ = value; + } + return printArray; +} +void +CbcOrClpParam::setDoubleValue ( double value ) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + } else { + doubleValue_ = value; + } +} +const char * +CbcOrClpParam::setDoubleValueWithMessage ( double value ) +{ + printArray[0] = '\0'; + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value,name_.c_str(),lowerDoubleValue_,upperDoubleValue_); + } else { + if (value==doubleValue_) + return NULL; + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), doubleValue_, value); + doubleValue_ = value; + } + return printArray; +} +void +CbcOrClpParam::setStringValue ( std::string value ) +{ + stringValue_ = value; +} +static char line[1000]; +static char * where = NULL; +extern int CbcOrClpRead_mode; +int CbcOrClpEnvironmentIndex = -1; +static size_t fillEnv() +{ +#if defined(_MSC_VER) || defined(__MSVCRT__) + return 0; +#else + // Don't think it will work on Windows + char * environ = getenv("CBC_CLP_ENVIRONMENT"); + size_t length = 0; + if (environ) { + length = strlen(environ); + if (CbcOrClpEnvironmentIndex < static_cast(length)) { + // find next non blank + char * whereEnv = environ + CbcOrClpEnvironmentIndex; + // munch white space + while (*whereEnv == ' ' || *whereEnv == '\t' || *whereEnv < ' ') + whereEnv++; + // copy + char * put = line; + while ( *whereEnv != '\0' ) { + if ( *whereEnv == ' ' || *whereEnv == '\t' || *whereEnv < ' ' ) { + break; + } + *put = *whereEnv; + put++; + assert (put - line < 1000); + whereEnv++; + } + CbcOrClpEnvironmentIndex = static_cast(whereEnv - environ); + *put = '\0'; + length = strlen(line); + } else { + length = 0; + } + } + if (!length) + CbcOrClpEnvironmentIndex = -1; + return length; +#endif +} +extern FILE * CbcOrClpReadCommand; +// Simple read stuff +std::string +CoinReadNextField() +{ + std::string field; + if (!where) { + // need new line +#ifdef COIN_HAS_READLINE + if (CbcOrClpReadCommand == stdin) { + // Get a line from the user. + where = readline (coin_prompt); + + // If the line has any text in it, save it on the history. + if (where) { + if ( *where) + add_history (where); + strcpy(line, where); + free(where); + } + } else { + where = fgets(line, 1000, CbcOrClpReadCommand); + } +#else + if (CbcOrClpReadCommand == stdin) { + fputs(coin_prompt,stdout); + fflush(stdout); + } + where = fgets(line, 1000, CbcOrClpReadCommand); +#endif + if (!where) + return field; // EOF + where = line; + // clean image + char * lastNonBlank = line - 1; + while ( *where != '\0' ) { + if ( *where != '\t' && *where < ' ' ) { + break; + } else if ( *where != '\t' && *where != ' ') { + lastNonBlank = where; + } + where++; + } + where = line; + *(lastNonBlank + 1) = '\0'; + } + // munch white space + while (*where == ' ' || *where == '\t') + where++; + char * saveWhere = where; + while (*where != ' ' && *where != '\t' && *where != '\0') + where++; + if (where != saveWhere) { + char save = *where; + *where = '\0'; + //convert to string + field = saveWhere; + *where = save; + } else { + where = NULL; + field = "EOL"; + } + return field; +} + +std::string +CoinReadGetCommand(int argc, const char *argv[]) +{ + std::string field = "EOL"; + // say no = + afterEquals = ""; + while (field == "EOL") { + if (CbcOrClpRead_mode > 0) { + if ((CbcOrClpRead_mode < argc && argv[CbcOrClpRead_mode]) || + CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + field = argv[CbcOrClpRead_mode++]; + } else { + if (fillEnv()) { + field = line; + } else { + // not there + continue; + } + } + if (field == "-") { + std::cout << "Switching to line mode" << std::endl; + CbcOrClpRead_mode = -1; + field = CoinReadNextField(); + } else if (field[0] != '-') { + if (CbcOrClpRead_mode != 2) { + // now allow std::cout<<"skipping non-command "< 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + if (argv[CbcOrClpRead_mode][0] != '-') { + field = argv[CbcOrClpRead_mode++]; + } else if (!strcmp(argv[CbcOrClpRead_mode], "--")) { + field = argv[CbcOrClpRead_mode++]; + // -- means import from stdin + field = "-"; + } + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + //std::cout< 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + // may be negative value so do not check for - + field = argv[CbcOrClpRead_mode++]; + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + long int value = 0; + //std::cout<(value); +} +double +CoinReadGetDoubleField(int argc, const char *argv[], int * valid) +{ + std::string field = "EOL"; + if (afterEquals == "") { + if (CbcOrClpRead_mode > 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + // may be negative value so do not check for - + field = argv[CbcOrClpRead_mode++]; + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + double value = 0.0; + //std::cout<= this treated as artificials in feasibility pump", + 0.0, COIN_DBL_MAX, CBC_PARAM_DBL_ARTIFICIALCOST, 1); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise variables with costs >= this are treated as artificials and fixed to lower bound in feasibility pump" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("auto!Scale", "Whether to scale objective, rhs and bounds of problem if they look odd", + "off", CLP_PARAM_STR_AUTOSCALE, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "If you think you may get odd objective values or large equality rows etc then\ + it may be worth setting this true. It is still experimental and you may prefer\ + to use objective!Scale and rhs!Scale." + ); + parameters[numberParameters++] = + CbcOrClpParam("barr!ier", "Solve using primal dual predictor corrector algorithm", + CLP_PARAM_ACTION_BARRIER); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the current model using the primal dual predictor \ +corrector algorithm. You may want to link in an alternative \ +ordering and factorization. It will also solve models \ +with quadratic objectives." + + ); + parameters[numberParameters++] = + CbcOrClpParam("basisI!n", "Import basis from bas file", + CLP_PARAM_ACTION_BASISIN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read an MPS format basis file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. If you have libz then it can read compressed\ + files 'xxxxxxxx.gz' or xxxxxxxx.bz2." + ); + parameters[numberParameters++] = + CbcOrClpParam("basisO!ut", "Export basis as bas file", + CLP_PARAM_ACTION_BASISOUT); + parameters[numberParameters-1].setLonghelp + ( + "This will write an MPS format basis file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.bas'." + ); + parameters[numberParameters++] = + CbcOrClpParam("biasLU", "Whether factorization biased towards U", + "UU", CLP_PARAM_STR_BIASLU, 2, 0); + parameters[numberParameters-1].append("UX"); + parameters[numberParameters-1].append("LX"); + parameters[numberParameters-1].append("LL"); + parameters[numberParameters-1].setCurrentOption("LX"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("branch!AndCut", "Do Branch and Cut", + CBC_PARAM_ACTION_BAB); + parameters[numberParameters-1].setLonghelp + ( + "This does branch and cut. There are many parameters which can affect the performance. \ +First just try with default settings and look carefully at the log file. Did cuts help? Did they take too long? \ +Look at output to see which cuts were effective and then do some tuning. You will see that the \ +options for cuts are off, on, root and ifmove, forceon. Off is \ +obvious, on means that this cut generator will be tried in the branch and cut tree (you can fine tune using \ +'depth'). Root means just at the root node while 'ifmove' means that cuts will be used in the tree if they \ +look as if they are doing some good and moving the objective value. Forceon is same as on but forces code to use \ +cut generator at every node. For probing forceonbut just does fixing probing in tree - not strengthening etc. \ +If pre-processing reduced the size of the \ +problem or strengthened many coefficients then it is probably wise to leave it on. Switch off heuristics \ +which did not provide solutions. The other major area to look at is the search. Hopefully good solutions \ +were obtained fairly early in the search so the important point is to select the best variable to branch on. \ +See whether strong branching did a good job - or did it just take a lot of iterations. Adjust the strongBranching \ +and trustPseudoCosts parameters. If cuts did a good job, then you may wish to \ +have more rounds of cuts - see passC!uts and passT!ree." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("bscale", "Whether to scale in barrier (and ordering speed)", + "off", CLP_PARAM_STR_BARRIERSCALE, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("off1"); + parameters[numberParameters-1].append("on1"); + parameters[numberParameters-1].append("off2"); + parameters[numberParameters-1].append("on2"); +#if FLUSH_PRINT_BUFFER > 2 + parameters[numberParameters++] = + CbcOrClpParam("buff!eredMode", "Whether to flush print buffer", + "on", CLP_PARAM_STR_BUFFER_MODE); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "Default is on, off switches on unbuffered output" + ); + parameters[numberParameters-1].setIntValue(0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("chol!esky", "Which cholesky algorithm", + "native", CLP_PARAM_STR_CHOLESKY, 7); + parameters[numberParameters-1].append("dense"); + //#ifdef FOREIGN_BARRIER +#ifdef COIN_HAS_WSMP + parameters[numberParameters-1].append("fudge!Long"); + parameters[numberParameters-1].append("wssmp"); +#else + parameters[numberParameters-1].append("fudge!Long_dummy"); + parameters[numberParameters-1].append("wssmp_dummy"); +#endif +#if defined(COIN_HAS_AMD) || defined(COIN_HAS_CHOLMOD) || defined(COIN_HAS_GLPK) + parameters[numberParameters-1].append("Uni!versityOfFlorida"); +#else + parameters[numberParameters-1].append("Uni!versityOfFlorida_dummy"); +#endif +#ifdef TAUCS_BARRIER + parameters[numberParameters-1].append("Taucs"); +#else + parameters[numberParameters-1].append("Taucs_dummy"); +#endif +#ifdef COIN_HAS_MUMPS + parameters[numberParameters-1].append("Mumps"); +#else + parameters[numberParameters-1].append("Mumps_dummy"); +#endif + parameters[numberParameters-1].setLonghelp + ( + "For a barrier code to be effective it needs a good Cholesky ordering and factorization. \ +The native ordering and factorization is not state of the art, although acceptable. \ +You may want to link in one from another source. See Makefile.locations for some \ +possibilities." + ); + //#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("clique!Cuts", "Whether to use Clique cuts", + "off", CBC_PARAM_STR_CLIQUECUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on clique cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("combine!Solutions", "Whether to use combine solution heuristic", + "off", CBC_PARAM_STR_COMBINE); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("onquick"); + parameters[numberParameters-1].append("bothquick"); + parameters[numberParameters-1].append("beforequick"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which does branch and cut on the problem given by just \ +using variables which have appeared in one or more solutions. \ +It obviously only tries after two or more solutions. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("combine2!Solutions", "Whether to use crossover solution heuristic", + "off", CBC_PARAM_STR_CROSSOVER2); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which does branch and cut on the problem given by \ +fixing variables which have same value in two or more solutions. \ +It obviously only tries after two or more solutions. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("constraint!fromCutoff", "Whether to use cutoff as constraint", + "off", CBC_PARAM_STR_CUTOFF_CONSTRAINT); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("variable"); + parameters[numberParameters-1].append("forcevariable"); + parameters[numberParameters-1].append("conflict"); + parameters[numberParameters-1].setLonghelp + ( + "This adds the objective as a constraint with best solution as RHS" + ); + parameters[numberParameters++] = + CbcOrClpParam("cost!Strategy", "How to use costs as priorities", + "off", CBC_PARAM_STR_COSTSTRATEGY); + parameters[numberParameters-1].append("pri!orities"); + parameters[numberParameters-1].append("column!Order?"); + parameters[numberParameters-1].append("01f!irst?"); + parameters[numberParameters-1].append("01l!ast?"); + parameters[numberParameters-1].append("length!?"); + parameters[numberParameters-1].append("singletons"); + parameters[numberParameters-1].append("nonzero"); + parameters[numberParameters-1].append("general!Force?"); + parameters[numberParameters-1].setLonghelp + ( + "This orders the variables in order of their absolute costs - with largest cost ones being branched on \ +first. This primitive strategy can be surprsingly effective. The column order\ + option is obviously not on costs but easy to code here." + ); + parameters[numberParameters++] = + CbcOrClpParam("cplex!Use", "Whether to use Cplex!", + "off", CBC_PARAM_STR_CPX); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + " If the user has Cplex, but wants to use some of Cbc's heuristics \ +then you can! If this is on, then Cbc will get to the root node and then \ +hand over to Cplex. If heuristics find a solution this can be significantly \ +quicker. You will probably want to switch off Cbc's cuts as Cplex thinks \ +they are genuine constraints. It is also probable that you want to switch \ +off preprocessing, although for difficult problems it is worth trying \ +both." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("cpp!Generate", "Generates C++ code", + -1, 50000, CLP_PARAM_INT_CPP, 1); + parameters[numberParameters-1].setLonghelp + ( + "Once you like what the stand-alone solver does then this allows \ +you to generate user_driver.cpp which approximates the code. \ +0 gives simplest driver, 1 generates saves and restores, 2 \ +generates saves and restores even for variables at default value. \ +4 bit in cbc generates size dependent code rather than computed values. \ +This is now deprecated as you can call stand-alone solver - see \ +Cbc/examples/driver4.cpp." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("crash", "Whether to create basis for problem", + "off", CLP_PARAM_STR_CRASH); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("so!low_halim"); + parameters[numberParameters-1].append("lots"); +#ifdef CLP_INHERIT_MODE + parameters[numberParameters-1].append("dual"); + parameters[numberParameters-1].append("dw"); + parameters[numberParameters-1].append("idiot"); +#else + parameters[numberParameters-1].append("idiot1"); + parameters[numberParameters-1].append("idiot2"); + parameters[numberParameters-1].append("idiot3"); + parameters[numberParameters-1].append("idiot4"); + parameters[numberParameters-1].append("idiot5"); + parameters[numberParameters-1].append("idiot6"); + parameters[numberParameters-1].append("idiot7"); +#endif + parameters[numberParameters-1].setLonghelp + ( + "If crash is set on and there is an all slack basis then Clp will flip or put structural\ + variables into basis with the aim of getting dual feasible. On the whole dual seems to be\ + better without it and there are alternative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \ +I have also added a variant due to Solow and Halim which is as on but just flip."); + parameters[numberParameters++] = + CbcOrClpParam("cross!over", "Whether to get a basic solution after barrier", + "on", CLP_PARAM_STR_CROSSOVER); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].append("maybe"); + parameters[numberParameters-1].append("presolve"); + parameters[numberParameters-1].setLonghelp + ( + "Interior point algorithms do not obtain a basic solution (and \ +the feasibility criterion is a bit suspect (JJF)). This option will crossover \ +to a basic solution suitable for ranging or branch and cut. With the current state \ +of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \ +presolve as well) - the option maybe does this." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("csv!Statistics", "Create one line of statistics", + CLP_PARAM_ACTION_CSVSTATISTICS, 2, 1); + parameters[numberParameters-1].setLonghelp + ( + "This appends statistics to given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. Adds header if file empty or does not exist." + ); + parameters[numberParameters++] = + CbcOrClpParam("cutD!epth", "Depth in tree at which to do cuts", + -1, 999999, CBC_PARAM_INT_CUTDEPTH); + parameters[numberParameters-1].setLonghelp + ( + "Cut generators may be - off, on only at root, on if they look possible \ +and on. If they are done every node then that is that, but it may be worth doing them \ +every so often. The original method was every so many nodes but it is more logical \ +to do it whenever depth in tree is a multiple of K. This option does that and defaults \ +to -1 (off -> code decides)." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("cutL!ength", "Length of a cut", + -1, COIN_INT_MAX, CBC_PARAM_INT_CUTLENGTH); + parameters[numberParameters-1].setLonghelp + ( + "At present this only applies to Gomory cuts. -1 (default) leaves as is. \ +Any value >0 says that all cuts <= this length can be generated both at \ +root node and in tree. 0 says to use some dynamic lengths. If value >=10,000,000 \ +then the length in tree is value%10000000 - so 10000100 means unlimited length \ +at root and 100 in tree." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("cuto!ff", "All solutions must be better than this", + -1.0e60, 1.0e60, CBC_PARAM_DBL_CUTOFF); + parameters[numberParameters-1].setDoubleValue(1.0e50); + parameters[numberParameters-1].setLonghelp + ( + "All solutions must be better than this value (in a minimization sense). \ +This is also set by code whenever it obtains a solution and is set to value of \ +objective for solution minus cutoff increment." + ); + parameters[numberParameters++] = + CbcOrClpParam("cuts!OnOff", "Switches all cuts on or off", + "off", CBC_PARAM_STR_CUTSSTRATEGY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "This can be used to switch on or off all cuts (apart from Reduce and Split). Then you can do \ +individual ones off or on \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("debug!In", "read valid solution from file", + CLP_PARAM_ACTION_DEBUG, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This will read a solution file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set.\n\n\ +If set to create it will create a file called debug.file after search.\n\n\ +The idea is that if you suspect a bad cut generator \ +you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \ +re-run with debug set to 'debug.file' The create case has same effect as saveSolution." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("decomp!ose", "Whether to try decomposition", + -COIN_INT_MAX, COIN_INT_MAX, CLP_PARAM_INT_DECOMPOSE_BLOCKS, 1); + parameters[numberParameters-1].setLonghelp + ( + "0 - off, 1 choose blocks >1 use as blocks \ +Dantzig Wolfe if primal, Benders if dual \ +- uses sprint pass for number of passes" + ); + parameters[numberParameters-1].setIntValue(0); +#if CLP_MULTIPLE_FACTORIZATIONS >0 + parameters[numberParameters++] = + CbcOrClpParam("dense!Threshold", "Whether to use dense factorization", + -1, 10000, CBC_PARAM_INT_DENSE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If processed problem <= this use dense factorization" + ); + parameters[numberParameters-1].setIntValue(-1); +#endif +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("depth!MiniBab", "Depth at which to try mini BAB", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_DEPTHMINIBAB); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "Rather a complicated parameter but can be useful. -1 means off for large problems but on as if -12 for problems where rows+columns<500, -2 \ +means use Cplex if it is linked in. Otherwise if negative then go into depth first complete search fast branch and bound when depth>= -value-2 (so -3 will use this at depth>=1). This mode is only switched on after 500 nodes. If you really want to switch it off for small problems then set this to -999. If >=0 the value doesn't matter very much. The code will do approximately 100 nodes of fast branch and bound every now and then at depth>=5. The actual logic is too twisted to describe here." + ); + parameters[numberParameters++] = + CbcOrClpParam("dextra3", "Extra double parameter 3", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA3, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("dextra4", "Extra double parameter 4", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA4, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("dextra5", "Extra double parameter 5", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA5, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("Dins", "Whether to try Distance Induced Neighborhood Search", + "off", CBC_PARAM_STR_DINS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("often"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Distance induced neighborhood Search. \ +See Rounding for meaning of on,both,before" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("direction", "Minimize or Maximize", + "min!imize", CLP_PARAM_STR_DIRECTION); + parameters[numberParameters-1].append("max!imize"); + parameters[numberParameters-1].append("zero"); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'direction maximize' for maximization.\n\ +You can also use the parameters 'maximize' or 'minimize'." + ); + parameters[numberParameters++] = + CbcOrClpParam("directory", "Set Default directory for import etc.", + CLP_PARAM_ACTION_DIRECTORY); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory which import, export, saveModel, restoreModel etc will use.\ + It is initialized to './'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirSample", "Set directory where the COIN-OR sample problems are.", + CLP_PARAM_ACTION_DIRSAMPLE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the COIN-OR sample problems reside. It is\ + used only when -unitTest is passed to clp. clp will pick up the test problems\ + from this directory.\ + It is initialized to '../../Data/Sample'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirNetlib", "Set directory where the netlib problems are.", + CLP_PARAM_ACTION_DIRNETLIB, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the netlib problems reside. One can get\ + the netlib problems from COIN-OR or from the main netlib site. This\ + parameter is used only when -netlib is passed to clp. clp will pick up the\ + netlib problems from this directory. If clp is built without zlib support\ + then the problems must be uncompressed.\ + It is initialized to '../../Data/Netlib'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirMiplib", "Set directory where the miplib 2003 problems are.", + CBC_PARAM_ACTION_DIRMIPLIB, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the miplib 2003 problems reside. One can\ + get the miplib problems from COIN-OR or from the main miplib site. This\ + parameter is used only when -miplib is passed to cbc. cbc will pick up the\ + miplib problems from this directory. If cbc is built without zlib support\ + then the problems must be uncompressed.\ + It is initialized to '../../Data/miplib3'" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("diveO!pt", "Diving options", + -1, 200000, CBC_PARAM_INT_DIVEOPT, 1); + parameters[numberParameters-1].setLonghelp + ( + "If >2 && <20 then modify diving options - \ + \n\t3 only at root and if no solution, \ + \n\t4 only at root and if this heuristic has not got solution, \ + \n\t5 decay only if no solution, \ + \n\t6 if depth <3 or decay, \ + \n\t7 run up to 2 times if solution found 4 otherwise, \ + \n\t>10 All only at root (DivingC normal as value-10), \ + \n\t>20 All with value-20)." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("diveS!olves", "Diving solve option", + -1, 200000, CBC_PARAM_INT_DIVEOPTSOLVES, 1); + parameters[numberParameters-1].setLonghelp + ( + "If >0 then do up to this many solves. Last digit is ignored \ +and used for extra options - \ + \n\t1-3 allow fixing of satisfied integers (but not at bound) \ + \n\t1 switch off above for that dive if goes infeasible \ + \n\t2 switch off above permanently if goes infeasible" + ); + parameters[numberParameters-1].setIntValue(100); + parameters[numberParameters++] = + CbcOrClpParam("DivingS!ome", "Whether to try Diving heuristics", + "off", CBC_PARAM_STR_DIVINGS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a random diving heuristic at various times. \ +C - Coefficient, F - Fractional, G - Guided, L - LineSearch, P - PseudoCost, V - VectorLength. \ +You may prefer to use individual on/off \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("DivingC!oefficient", "Whether to try DiveCoefficient", + "off", CBC_PARAM_STR_DIVINGC); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingF!ractional", "Whether to try DiveFractional", + "off", CBC_PARAM_STR_DIVINGF); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingG!uided", "Whether to try DiveGuided", + "off", CBC_PARAM_STR_DIVINGG); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingL!ineSearch", "Whether to try DiveLineSearch", + "off", CBC_PARAM_STR_DIVINGL); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingP!seudoCost", "Whether to try DivePseudoCost", + "off", CBC_PARAM_STR_DIVINGP); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingV!ectorLength", "Whether to try DiveVectorLength", + "off", CBC_PARAM_STR_DIVINGV); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("doH!euristic", "Do heuristics before any preprocessing", + CBC_PARAM_ACTION_DOHEURISTIC, 3); + parameters[numberParameters-1].setLonghelp + ( + "Normally heuristics are done in branch and bound. It may be useful to do them outside. \ +Only those heuristics with 'both' or 'before' set will run. \ +Doing this may also set cutoff, which can help with preprocessing." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("dualB!ound", "Initially algorithm acts as if no \ +gap between bounds exceeds this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALBOUND); + parameters[numberParameters-1].setLonghelp + ( + "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\ + algorithm where you first get feasible then optimal. If a problem has both upper and\ + lower bounds then it is trivial to get dual feasible by setting non basic variables\ + to correct bound. If the gap between the upper and lower bounds of a variable is more\ + than the value of dualBound Clp introduces fake bounds so that it can make the problem\ + dual feasible. This has the same effect as a composite objective function in the\ + primal algorithm. Too high a value may mean more iterations, while too low a bound means\ + the code may go all the way and then have to increase the bounds. OSL had a heuristic to\ + adjust bounds, maybe we need that here." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualize", "Solves dual reformulation", + 0, 4, CLP_PARAM_INT_DUALIZE, 1); + parameters[numberParameters-1].setLonghelp + ( + "Don't even think about it." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualP!ivot", "Dual pivot choice algorithm", + "auto!matic", CLP_PARAM_STR_DUALPIVOT, 7, 1); + parameters[numberParameters-1].append("dant!zig"); + parameters[numberParameters-1].append("partial"); + parameters[numberParameters-1].append("steep!est"); + parameters[numberParameters-1].setLonghelp + ( + "Clp can use any pivot selection algorithm which the user codes as long as it\ + implements the features in the abstract pivot base class. The Dantzig method is implemented\ + to show a simple method but its use is deprecated. Steepest is the method of choice and there\ + are two variants which keep all weights updated but only scan a subset each iteration.\ + Partial switches this on while automatic decides at each iteration based on information\ + about the factorization." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualS!implex", "Do dual simplex algorithm", + CLP_PARAM_ACTION_DUALSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the dual steepest edge algorithm.\ +The time and iterations may be affected by settings such as presolve, scaling, crash\ + and also by dual pivot method, fake bound on variables and dual and primal tolerances." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("dualT!olerance", "For an optimal solution \ +no dual infeasibility may exceed this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Normally the default tolerance is fine, but you may want to increase it a\ + bit if a dual run seems to be having a hard time. One method which can be faster is \ +to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \ +correct tolerance (remembering to switch off presolve for this final short clean up phase)." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("dw!Heuristic", "Whether to try DW heuristic", + "off", CBC_PARAM_STR_DW); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "See Rounding for meaning of on,both,before" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("either!Simplex", "Do dual or primal simplex algorithm", + CLP_PARAM_ACTION_EITHERSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the dual or primal algorithm,\ + based on a dubious analysis of model." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("end", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops execution ; end, exit, quit and stop are synonyms" + ); + parameters[numberParameters++] = + CbcOrClpParam("environ!ment", "Read commands from environment", + CLP_PARAM_ACTION_ENVIRONMENT, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "This starts reading from environment variable CBC_CLP_ENVIRONMENT." + ); + parameters[numberParameters++] = + CbcOrClpParam("error!sAllowed", "Whether to allow import errors", + "off", CLP_PARAM_STR_ERRORSALLOWED, 3); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "The default is not to use any model which had errors when reading the mps file.\ + Setting this to 'on' will allow all errors from which the code can recover\ + simply by ignoring the error. There are some errors from which the code can not recover \ +e.g. no ENDATA. This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps." + ); + parameters[numberParameters++] = + CbcOrClpParam("exit", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("exper!iment", "Whether to use testing features", + -1, 200, CBC_PARAM_INT_EXPERIMENT, 0); + parameters[numberParameters-1].setLonghelp + ( + "Defines how adventurous you want to be in using new ideas. \ +0 then no new ideas, 1 fairly sensible, 2 a bit dubious, 3 you are on your own!" + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("expensive!Strong", "Whether to do even more strong branching", + 0, COIN_INT_MAX, CBC_PARAM_INT_STRONG_STRATEGY, 0); + parameters[numberParameters-1].setLonghelp + ( + "Strategy for extra strong branching \n\ +\n\t0 - normal\n\ +\n\twhen to do all fractional\n\ +\n\t1 - root node\n\ +\n\t2 - depth less than modifier\n\ +\n\t4 - if objective == best possible\n\ +\n\t6 - as 2+4\n\ +\n\twhen to do all including satisfied\n\ +\n\t10 - root node etc.\n\ +\n\tIf >=100 then do when depth <= strategy/100 (otherwise 5)" + ); + parameters[numberParameters-1].setIntValue(0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("export", "Export model as mps file", + CLP_PARAM_ACTION_EXPORT); + parameters[numberParameters-1].setLonghelp + ( + "This will write an MPS format file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.mps'. \ +It can be useful to get rid of the original names and go over to using Rnnnnnnn and Cnnnnnnn. This can be done by setting 'keepnames' off before importing mps file." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("extra1", "Extra integer parameter 1", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA1, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra2", "Extra integer parameter 2", + -100, COIN_INT_MAX, CBC_PARAM_INT_EXTRA2, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra3", "Extra integer parameter 3", + -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA3, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra4", "Extra integer parameter 4", + -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA4, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "This switches on yet more special options!! \ +The bottom digit is a strategy when to used shadow price stuff e.g. 3 \ +means use until a solution is found. The next two digits say what sort \ +of dual information to use. After that it goes back to powers of 2 so -\n\ +\n\t1000 - switches on experimental hotstart\n\ +\n\t2,4,6000 - switches on experimental methods of stopping cuts\n\ +\n\t8000 - increase minimum drop gradually\n\ +\n\t16000 - switches on alternate gomory criterion" + ); + parameters[numberParameters++] = + CbcOrClpParam("extraV!ariables", "Allow creation of extra integer variables", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA_VARIABLES, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "This switches on creation of extra integer variables \ +to gather all variables with same cost." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("fact!orization", "Which factorization to use", + "normal", CLP_PARAM_STR_FACTORIZATION); + parameters[numberParameters-1].append("dense"); + parameters[numberParameters-1].append("simple"); + parameters[numberParameters-1].append("osl"); + parameters[numberParameters-1].setLonghelp + ( +#ifndef ABC_INHERIT + "The default is to use the normal CoinFactorization, but \ +other choices are a dense one, osl's or one designed for small problems." +#else + "Normally the default is to use the normal CoinFactorization, but \ +other choices are a dense one, osl's or one designed for small problems. \ +However if at Aboca then the default is CoinAbcFactorization and other choices are \ +a dense one, one designed for small problems or if enabled a long factorization." +#endif + ); + parameters[numberParameters++] = + CbcOrClpParam("fakeB!ound", "All bounds <= this value - DEBUG", + 1.0, 1.0e15, CLP_PARAM_ACTION_FAKEBOUND, 0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("feas!ibilityPump", "Whether to try Feasibility Pump", + "off", CBC_PARAM_STR_FPUMP); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on feasibility pump heuristic at root. This is due to Fischetti, Lodi and Glover \ +and uses a sequence of Lps to try and get an integer feasible solution. \ +Some fine tuning is available by passFeasibilityPump and also pumpTune. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("fix!OnDj", "Try heuristic based on fixing variables with \ +reduced costs greater than this", + -1.0e20, 1.0e20, CBC_PARAM_DBL_DJFIX, 1); + parameters[numberParameters-1].setLonghelp + ( + "If this is set integer variables with reduced costs greater than this will be fixed \ +before branch and bound - use with extreme caution!" + ); + parameters[numberParameters++] = + CbcOrClpParam("flow!CoverCuts", "Whether to use Flow Cover cuts", + "off", CBC_PARAM_STR_FLOWCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setFakeKeyWord(3); + parameters[numberParameters-1].setLonghelp + ( + "This switches on flow cover cuts (either at root or in entire tree) \ +See branchAndCut for information on options. \ +Can also enter testing values by plusnn (==ifmove)" + ); + parameters[numberParameters++] = + CbcOrClpParam("force!Solution", "Whether to use given solution as crash for BAB", + -1, 20000000, CLP_PARAM_INT_USESOLUTION); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "-1 off. If 1 then tries to branch to solution given by AMPL or priorities file. \ +If 0 then just tries to set as best solution \ +If >1 then also does that many nodes on fixed problem." + ); + parameters[numberParameters++] = + CbcOrClpParam("fraction!forBAB", "Fraction in feasibility pump", + 1.0e-5, 1.1, CBC_PARAM_DBL_SMALLBAB, 1); + parameters[numberParameters-1].setDoubleValue(0.5); + parameters[numberParameters-1].setLonghelp + ( + "After a pass in feasibility pump, variables which have not moved \ +about are fixed and if the preprocessed model is small enough a few nodes \ +of branch and bound are done on reduced problem. Small problem has to be less than this fraction of original." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("gamma!(Delta)", "Whether to regularize barrier", + "off", CLP_PARAM_STR_GAMMA, 7, 1); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("gamma"); + parameters[numberParameters-1].append("delta"); + parameters[numberParameters-1].append("onstrong"); + parameters[numberParameters-1].append("gammastrong"); + parameters[numberParameters-1].append("deltastrong"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("GMI!Cuts", "Whether to use alternative Gomory cuts", + "off", CBC_PARAM_STR_GMICUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("long"); + parameters[numberParameters-1].append("longroot"); + parameters[numberParameters-1].append("longifmove"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].append("longendonly"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on an alternative Gomory cut generator (either at root or in entire tree) \ +This version is by Giacomo Nannicini and may be more robust \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("gomory!Cuts", "Whether to use Gomory cuts", + "off", CBC_PARAM_STR_GOMORYCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].append("long"); + parameters[numberParameters-1].setLonghelp + ( + "The original cuts - beware of imitations! Having gone out of favor, they are now more \ +fashionable as LP solvers are more robust and they interact well with other cuts. They will almost always \ +give cuts (although in this executable they are limited as to number of variables in cut). \ +However the cuts may be dense so it is worth experimenting (Long allows any length). \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("greedy!Heuristic", "Whether to use a greedy heuristic", + "off", CBC_PARAM_STR_GREEDY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + //parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].setLonghelp + ( + "Switches on a greedy heuristic which will try and obtain a solution. It may just fix a \ +percentage of variables and then try a small branch and cut run. \ +See Rounding for meaning of on,both,before" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("gsolu!tion", "Puts glpk solution to file", + CLP_PARAM_ACTION_GMPL_SOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "Will write a glpk solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout' (this defaults to ordinary solution if stdout). \ +If problem created from gmpl model - will do any reports." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("heur!isticsOnOff", "Switches most heuristics on or off", + "off", CBC_PARAM_STR_HEURISTICSTRATEGY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "This can be used to switch on or off all heuristics. Then you can do \ +individual ones off or on. CbcTreeLocal is not included as it dramatically \ +alters search." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("help", "Print out version, non-standard options and some help", + CLP_PARAM_ACTION_HELP, 3); + parameters[numberParameters-1].setLonghelp + ( + "This prints out some help to get user started. If you have printed this then \ +you should be past that stage:-)" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("hOp!tions", "Heuristic options", + -9999999, 9999999, CBC_PARAM_INT_HOPTIONS, 1); + parameters[numberParameters-1].setLonghelp + ( + "1 says stop heuristic immediately allowable gap reached. \ +Others are for feasibility pump - \ +2 says do exact number of passes given, \ +4 only applies if initial cutoff given and says relax after 50 passes, \ +while 8 will adapt cutoff rhs after first solution if it looks as if code is stalling." + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("hot!StartMaxIts", "Maximum iterations on hot start", + 0, COIN_INT_MAX, CBC_PARAM_INT_MAXHOTITS); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("idiot!Crash", "Whether to try idiot crash", + -1, 99999999, CLP_PARAM_INT_IDIOT); + parameters[numberParameters-1].setLonghelp + ( + "This is a type of 'crash' which works well on some homogeneous problems.\ + It works best on problems with unit elements and rhs but will do something to any model. It should only be\ + used before primal. It can be set to -1 when the code decides for itself whether to use it,\ + 0 to switch off or n > 0 to do n passes." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("import", "Import model from mps file", + CLP_PARAM_ACTION_IMPORT, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read an MPS format file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. If you have libgz then it can read compressed\ + files 'xxxxxxxx.gz' or 'xxxxxxxx.bz2'. \ +If 'keepnames' is off, then names are dropped -> Rnnnnnnn and Cnnnnnnn." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("inc!rement", "A valid solution must be at least this \ +much better than last integer solution", + -1.0e20, 1.0e20, CBC_PARAM_DBL_INCREMENT); + parameters[numberParameters-1].setLonghelp + ( + "Whenever a solution is found the bound on solutions is set to solution (in a minimization\ +sense) plus this. If it is not set then the code will try and work one out e.g. if \ +all objective coefficients are multiples of 0.01 and only integer variables have entries in \ +objective then this can be set to 0.01. Be careful if you set this negative!" + ); + parameters[numberParameters++] = + CbcOrClpParam("inf!easibilityWeight", "Each integer infeasibility is expected \ +to cost this much", + 0.0, 1.0e20, CBC_PARAM_DBL_INFEASIBILITYWEIGHT, 1); + parameters[numberParameters-1].setLonghelp + ( + "A primitive way of deciding which node to explore next. Satisfying each integer infeasibility is \ +expected to cost this much." + ); + parameters[numberParameters++] = + CbcOrClpParam("initialS!olve", "Solve to continuous", + CLP_PARAM_ACTION_SOLVECONTINUOUS); + parameters[numberParameters-1].setLonghelp + ( + "This just solves the problem to continuous - without adding any cuts" + ); + parameters[numberParameters++] = + CbcOrClpParam("integerT!olerance", "For an optimal solution \ +no integer variable may be this away from an integer value", + 1.0e-20, 0.5, CBC_PARAM_DBL_INTEGERTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Beware of setting this smaller than the primal tolerance." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("keepN!ames", "Whether to keep names from import", + "on", CLP_PARAM_STR_KEEPNAMES); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "It saves space to get rid of names so if you need to you can set this to off. \ +This needs to be set before the import of model - so -keepnames off -import xxxxx.mps." + ); + parameters[numberParameters++] = + CbcOrClpParam("KKT", "Whether to use KKT factorization", + "off", CLP_PARAM_STR_KKT, 7, 1); + parameters[numberParameters-1].append("on"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("knapsack!Cuts", "Whether to use Knapsack cuts", + "off", CBC_PARAM_STR_KNAPSACKCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on knapsack cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("lagomory!Cuts", "Whether to use Lagrangean Gomory cuts", + "off", CBC_PARAM_STR_LAGOMORYCUTS); + parameters[numberParameters-1].append("endonlyroot"); + parameters[numberParameters-1].append("endcleanroot"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("endclean"); + parameters[numberParameters-1].append("endboth"); + parameters[numberParameters-1].append("onlyaswell"); + parameters[numberParameters-1].append("cleanaswell"); + parameters[numberParameters-1].append("bothaswell"); + parameters[numberParameters-1].append("onlyinstead"); + parameters[numberParameters-1].append("cleaninstead"); + parameters[numberParameters-1].append("bothinstead"); + parameters[numberParameters-1].append("onlyaswellroot"); + parameters[numberParameters-1].append("cleanaswellroot"); + parameters[numberParameters-1].append("bothaswellroot"); + parameters[numberParameters-1].setLonghelp + ( + "This is a gross simplification of 'A Relax-and-Cut Framework for Gomory's Mixed-Integer Cuts' \ +by Matteo Fischetti & Domenico Salvagnin. This simplification \ +just uses original constraints while modifying objective using other cuts. \ +So you don't use messy constraints generated by Gomory etc. \ +A variant is to allow non messy cuts e.g. clique cuts. \ +So 'only' does this while clean also allows integral valued cuts. \ +'End' is recommended which waits until other cuts have finished and then \ +does a few passes. \ +The length options for gomory cuts are used." + ); + parameters[numberParameters++] = + CbcOrClpParam("latwomir!Cuts", "Whether to use Lagrangean TwoMir cuts", + "off", CBC_PARAM_STR_LATWOMIRCUTS); + parameters[numberParameters-1].append("endonlyroot"); + parameters[numberParameters-1].append("endcleanroot"); + parameters[numberParameters-1].append("endbothroot"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("endclean"); + parameters[numberParameters-1].append("endboth"); + parameters[numberParameters-1].append("onlyaswell"); + parameters[numberParameters-1].append("cleanaswell"); + parameters[numberParameters-1].append("bothaswell"); + parameters[numberParameters-1].append("onlyinstead"); + parameters[numberParameters-1].append("cleaninstead"); + parameters[numberParameters-1].append("bothinstead"); + parameters[numberParameters-1].setLonghelp + ( + "This is a lagrangean relaxation for TwoMir cuts. See \ +lagomoryCuts for description of options." + ); + parameters[numberParameters++] = + CbcOrClpParam("lift!AndProjectCuts", "Whether to use Lift and Project cuts", + "off", CBC_PARAM_STR_LANDPCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "Lift and project cuts. \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("local!TreeSearch", "Whether to use local treesearch", + "off", CBC_PARAM_STR_LOCALTREE); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a local search algorithm when a solution is found. This is from \ +Fischetti and Lodi and is not really a heuristic although it can be used as one. \ +When used from Coin solve it has limited functionality. It is not switched on when \ +heuristics are switched on." + ); +#endif +#ifndef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("log!Level", "Level of detail in Solver output", + -1, 999999, CLP_PARAM_INT_SOLVERLOGLEVEL); +#else + parameters[numberParameters++] = + CbcOrClpParam("log!Level", "Level of detail in Coin branch and Cut output", + -63, 63, CLP_PARAM_INT_LOGLEVEL); + parameters[numberParameters-1].setIntValue(1); +#endif + parameters[numberParameters-1].setLonghelp + ( + "If 0 then there should be no output in normal circumstances. 1 is probably the best\ + value for most uses, while 2 and 3 give more information." + ); + parameters[numberParameters++] = + CbcOrClpParam("max!imize", "Set optimization direction to maximize", + CLP_PARAM_ACTION_MAXIMIZE, 7); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'maximize' for maximization.\n\ +You can also use the parameters 'direction maximize'." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("maxF!actor", "Maximum number of iterations between \ +refactorizations", + 1, 999999, CLP_PARAM_INT_MAXFACTOR); + parameters[numberParameters-1].setLonghelp + ( + "If this is at its initial value of 200 then in this executable clp will guess at a\ + value to use. Otherwise the user can set a value. The code may decide to re-factorize\ + earlier for accuracy." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxIt!erations", "Maximum number of iterations before \ +stopping", + 0, 2147483647, CLP_PARAM_INT_MAXITERATION); + parameters[numberParameters-1].setLonghelp + ( + "This can be used for testing purposes. The corresponding library call\n\ + \tsetMaximumIterations(value)\n can be useful. If the code stops on\ + seconds or by an interrupt this will be treated as stopping on maximum iterations. This is ignored in branchAndCut - use maxN!odes." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("maxN!odes", "Maximum number of nodes to do", + -1, 2147483647, CBC_PARAM_INT_MAXNODES); + parameters[numberParameters-1].setLonghelp + ( + "This is a repeatable way to limit search. Normally using time is easier \ +but then the results may not be repeatable." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxSaved!Solutions", "Maximum number of solutions to save", + 0, 2147483647, CBC_PARAM_INT_MAXSAVEDSOLS); + parameters[numberParameters-1].setLonghelp + ( + "Number of solutions to save." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxSo!lutions", "Maximum number of solutions to get", + 1, 2147483647, CBC_PARAM_INT_MAXSOLS); + parameters[numberParameters-1].setLonghelp + ( + "You may want to stop after (say) two solutions or an hour. \ +This is checked every node in tree, so it is possible to get more solutions from heuristics." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("min!imize", "Set optimization direction to minimize", + CLP_PARAM_ACTION_MINIMIZE, 7); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'maximize' for maximization.\n\ +This should only be necessary if you have previously set maximization \ +You can also use the parameters 'direction minimize'." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("mipO!ptions", "Dubious options for mip", + 0, COIN_INT_MAX, CBC_PARAM_INT_MIPOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("more!MipOptions", "More dubious options for mip", + -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMIPOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("more2!MipOptions", "More more dubious options for mip", + -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMOREMIPOPTIONS, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("mixed!IntegerRoundingCuts", "Whether to use Mixed Integer Rounding cuts", + "off", CBC_PARAM_STR_MIXEDCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on mixed integer rounding cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("mess!ages", "Controls if Clpnnnn is printed", + "off", CLP_PARAM_STR_MESSAGES); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ("The default behavior is to put out messages such as:\n\ + Clp0005 2261 Objective 109.024 Primal infeas 944413 (758)\n\ +but this program turns this off to make it look more friendly. It can be useful\ + to turn them back on if you want to be able to 'grep' for particular messages or if\ + you intend to override the behavior of a particular message. This only affects Clp not Cbc." + ); + parameters[numberParameters++] = + CbcOrClpParam("miplib", "Do some of miplib test set", + CBC_PARAM_ACTION_MIPLIB, 3, 1); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("mips!tart", "reads an initial feasible solution from file", + CBC_PARAM_ACTION_MIPSTART); + parameters[numberParameters-1].setLonghelp + ("\ +The MIPStart allows one to enter an initial integer feasible solution \ +to CBC. Values of the main decision variables which are active (have \ +non-zero values) in this solution are specified in a text file. The \ +text file format used is the same of the solutions saved by CBC, but \ +not all fields are required to be filled. First line may contain the \ +solution status and will be ignored, remaining lines contain column \ +indexes, names and values as in this example:\n\ +\n\ +Stopped on iterations - objective value 57597.00000000\n\ + 0 x(1,1,2,2) 1 \n\ + 1 x(3,1,3,2) 1 \n\ + 5 v(5,1) 2 \n\ + 33 x(8,1,5,2) 1 \n\ + ...\n\ +\n\ +Column indexes are also ignored since pre-processing can change them. \ +There is no need to include values for continuous or integer auxiliary \ +variables, since they can be computed based on main decision variables. \ +Starting CBC with an integer feasible solution can dramatically improve \ +its performance: several MIP heuristics (e.g. RINS) rely on having at \ +least one feasible solution available and can start immediately if the \ +user provides one. Feasibility Pump (FP) is a heuristic which tries to \ +overcome the problem of taking too long to find feasible solution (or \ +not finding at all), but it not always succeeds. If you provide one \ +starting solution you will probably save some time by disabling FP. \ +\n\n\ +Knowledge specific to your problem can be considered to write an \ +external module to quickly produce an initial feasible solution - some \ +alternatives are the implementation of simple greedy heuristics or the \ +solution (by CBC for example) of a simpler model created just to find \ +a feasible solution. \ +\n\n\ +Question and suggestions regarding MIPStart can be directed to\n\ +haroldo.santos@gmail.com.\ +"); +#endif + parameters[numberParameters++] = + CbcOrClpParam("moreS!pecialOptions", "Yet more dubious options for Simplex - see ClpSimplex.hpp", + 0, COIN_INT_MAX, CLP_PARAM_INT_MORESPECIALOPTIONS, 0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("moreT!une", "Yet more dubious ideas for feasibility pump", + 0, 100000000, CBC_PARAM_INT_FPUMPTUNE2, 0); + parameters[numberParameters-1].setLonghelp + ( + "Yet more ideas for Feasibility Pump \n\ +\t/100000 == 1 use box constraints and original obj in cleanup\n\ +\t/1000 == 1 Pump will run twice if no solution found\n\ +\t/1000 == 2 Pump will only run after root cuts if no solution found\n\ +\t/1000 >10 as above but even if solution found\n\ +\t/100 == 1,3.. exact 1.0 for objective values\n\ +\t/100 == 2,3.. allow more iterations per pass\n\ +\t n fix if value of variable same for last n iterations." + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("multiple!RootPasses", "Do multiple root passes to collect cuts and solutions", + 0, 100000000, CBC_PARAM_INT_MULTIPLEROOTS, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "Do (in parallel if threads enabled) the root phase this number of times \ + and collect all solutions and cuts generated. The actual format is aabbcc \ +where aa is number of extra passes, if bb is non zero \ +then it is number of threads to use (otherwise uses threads setting) and \ +cc is number of times to do root phase. Yet another one from the Italian idea factory \ +(This time - Andrea Lodi , Matteo Fischetti , Michele Monaci , Domenico Salvagnin , \ +and Andrea Tramontani). \ +The solvers do not interact with each other. However if extra passes are specified \ +then cuts are collected and used in later passes - so there is interaction there." + ); + parameters[numberParameters++] = + CbcOrClpParam("naive!Heuristics", "Whether to try some stupid heuristic", + "off", CBC_PARAM_STR_NAIVE, 7, 1); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "Really silly stuff e.g. fix all integers with costs to zero!. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("netlib", "Solve entire netlib test set", + CLP_PARAM_ACTION_NETLIB_EITHER, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\ +The user can set options before e.g. clp -presolve off -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibB!arrier", "Solve entire netlib test set with barrier", + CLP_PARAM_ACTION_NETLIB_BARRIER, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using barrier.\ +The user can set options before e.g. clp -kkt on -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibD!ual", "Solve entire netlib test set (dual)", + CLP_PARAM_ACTION_NETLIB_DUAL, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using dual.\ +The user can set options before e.g. clp -presolve off -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibP!rimal", "Solve entire netlib test set (primal)", + CLP_PARAM_ACTION_NETLIB_PRIMAL, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using primal.\ +The user can set options before e.g. clp -presolve off -netlibp" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibT!une", "Solve entire netlib test set with 'best' algorithm", + CLP_PARAM_ACTION_NETLIB_TUNE, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using whatever \ +works best. I know this is cheating but it also stresses the code better by doing a \ +mixture of stuff. The best algorithm was chosen on a Linux ThinkPad using native cholesky \ +with University of Florida ordering." + ); + parameters[numberParameters++] = + CbcOrClpParam("network", "Tries to make network matrix", + CLP_PARAM_ACTION_NETWORK, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Clp will go faster if the matrix can be converted to a network. The matrix\ + operations may be a bit faster with more efficient storage, but the main advantage\ + comes from using a network factorization. It will probably not be as fast as a \ +specialized network code." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("nextB!estSolution", "Prints next best saved solution to file", + CLP_PARAM_ACTION_NEXTBESTSOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "To write best solution, just use solution. This prints next best (if exists) \ + and then deletes it. \ + This will write a primitive solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout'. The amount of output can be varied using printi!ngOptions or printMask." + ); + parameters[numberParameters++] = + CbcOrClpParam("node!Strategy", "What strategy to use to select nodes", + "hybrid", CBC_PARAM_STR_NODESTRATEGY); + parameters[numberParameters-1].append("fewest"); + parameters[numberParameters-1].append("depth"); + parameters[numberParameters-1].append("upfewest"); + parameters[numberParameters-1].append("downfewest"); + parameters[numberParameters-1].append("updepth"); + parameters[numberParameters-1].append("downdepth"); + parameters[numberParameters-1].setLonghelp + ( + "Normally before a solution the code will choose node with fewest infeasibilities. \ +You can choose depth as the criterion. You can also say if up or down branch must \ +be done first (the up down choice will carry on after solution). \ +Default has now been changed to hybrid which is breadth first on small depth nodes then fewest." + ); + parameters[numberParameters++] = + CbcOrClpParam("numberA!nalyze", "Number of analysis iterations", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_NUMBERANALYZE, 0); + parameters[numberParameters-1].setLonghelp + ( + "This says how many iterations to spend at root node analyzing problem. \ +This is a first try and will hopefully become more sophisticated." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("objective!Scale", "Scale factor to apply to objective", + -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If the objective function has some very large values, you may wish to scale them\ + internally by this amount. It can also be set by autoscale. It is applied after scaling. You are unlikely to need this." + ); + parameters[numberParameters-1].setDoubleValue(1.0); +#endif +#ifdef COIN_HAS_CBC +#ifdef COIN_HAS_NTY + parameters[numberParameters++] = + CbcOrClpParam("Orbit!alBranching", "Whether to try orbital branching", + "off", CBC_PARAM_STR_ORBITAL); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("strong"); + parameters[numberParameters-1].append("force"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Orbital branching. \ +On just adds orbital, strong tries extra fixing in strong branching"); +#endif + parameters[numberParameters++] = + CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model", + CLP_PARAM_ACTION_OUTDUPROWS, 7, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("output!Format", "Which output format to use", + 1, 6, CLP_PARAM_INT_OUTPUTFORMAT); + parameters[numberParameters-1].setLonghelp + ( + "Normally export will be done using normal representation for numbers and two values\ + per line. You may want to do just one per line (for grep or suchlike) and you may wish\ + to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\ + otherwise odd values gives one value per line, even two. Values 1,2 give normal format, 3,4\ + gives greater precision, while 5,6 give IEEE values. When used for exporting a basis 1 does not save \ +values, 2 saves values, 3 with greater accuracy and 4 in IEEE." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("para!metrics", "Import data from file and do parametrics", + CLP_PARAM_ACTION_PARAMETRICS, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read a file with parametric data from the given file name \ +and then do parametrics. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. This can not read from compressed files. \ +File is in modified csv format - a line ROWS will be followed by rows data \ +while a line COLUMNS will be followed by column data. The last line \ +should be ENDATA. The ROWS line must exist and is in the format \ +ROWS, inital theta, final theta, interval theta, n where n is 0 to get \ +CLPI0062 message at interval or at each change of theta \ +and 1 to get CLPI0063 message at each iteration. If interval theta is 0.0 \ +or >= final theta then no interval reporting. n may be missed out when it is \ +taken as 0. If there is Row data then \ +there is a headings line with allowed headings - name, number, \ +lower(rhs change), upper(rhs change), rhs(change). Either the lower and upper \ +fields should be given or the rhs field. \ +The optional COLUMNS line is followed by a headings line with allowed \ +headings - name, number, objective(change), lower(change), upper(change). \ + Exactly one of name and number must be given for either section and \ +missing ones have value 0.0." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("passC!uts", "Number of cut passes at root node", + -9999999, 9999999, CBC_PARAM_INT_CUTPASS); + parameters[numberParameters-1].setLonghelp + ( + "The default is 100 passes if less than 500 columns, 100 passes (but \ +stop if drop small if less than 5000 columns, 20 otherwise" + ); + parameters[numberParameters++] = + CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump", + 0, 10000, CBC_PARAM_INT_FPUMPITS); + parameters[numberParameters-1].setLonghelp + ( + "This fine tunes Feasibility Pump by doing more or fewer passes." + ); + parameters[numberParameters-1].setIntValue(20); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("passP!resolve", "How many passes in presolve", + -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1); + parameters[numberParameters-1].setLonghelp + ( + "Normally Presolve does 10 passes but you may want to do less to make it\ + more lightweight or do more if improvements are still being made. As Presolve will return\ + if nothing is being taken out, you should not normally need to use this fine tuning." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree", + -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE); + parameters[numberParameters-1].setLonghelp + ( + "The default is one pass" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("pertV!alue", "Method of perturbation", + -5000, 102, CLP_PARAM_INT_PERTVALUE, 1); + parameters[numberParameters++] = + CbcOrClpParam("perturb!ation", "Whether to perturb problem", + "on", CLP_PARAM_STR_PERTURBATION); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "Perturbation helps to stop cycling, but Clp uses other measures for this.\ + However large problems and especially ones with unit elements and unit rhs or costs\ + benefit from perturbation. Normally Clp tries to be intelligent, but you can switch this off.\ + The Clp library has this off by default. This program has it on by default." + ); + parameters[numberParameters++] = + CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex", + "off", CLP_PARAM_STR_PFI, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "By default clp uses Forrest-Tomlin L-U update. If you are masochistic you can switch it off." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic", + "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic", + "off", CBC_PARAM_STR_PIVOTANDFIX); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix", + CLP_PARAM_ACTION_PLUSMINUS, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Clp will go slightly faster if the matrix can be converted so that the elements are\ + not stored and are known to be unit. The main advantage is memory use. Clp may automatically\ + see if it can convert the problem so you should not need to use this." + ); + parameters[numberParameters++] = + CbcOrClpParam("pO!ptions", "Dubious print options", + 0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "If this is > 0 then presolve will give more information and branch and cut will give statistics" + ); + parameters[numberParameters++] = + CbcOrClpParam("preO!pt", "Presolve options", + 0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("presolve", "Whether to presolve problem", + "on", CLP_PARAM_STR_PRESOLVE); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].append("more"); + parameters[numberParameters-1].append("file"); + parameters[numberParameters-1].setLonghelp + ( + "Presolve analyzes the model to find such things as redundant equations, equations\ + which fix some variables, equations which can be transformed into bounds etc etc. For the\ + initial solve of any problem this is worth doing unless you know that it will have no effect. \ +on will normally do 5 passes while using 'more' will do 10. If the problem is very large you may need \ +to write the original to file using 'file'." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("preprocess", "Whether to use integer preprocessing", + "off", CBC_PARAM_STR_PREPROCESS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("save"); + parameters[numberParameters-1].append("equal"); + parameters[numberParameters-1].append("sos"); + parameters[numberParameters-1].append("trysos"); + parameters[numberParameters-1].append("equalall"); + parameters[numberParameters-1].append("strategy"); + parameters[numberParameters-1].append("aggregate"); + parameters[numberParameters-1].append("forcesos"); + parameters[numberParameters-1].setLonghelp + ( + "This tries to reduce size of model in a similar way to presolve and \ +it also tries to strengthen the model - this can be very useful and is worth trying. \ + Save option saves on file presolved.mps. equal will turn <= cliques into \ +==. sos will create sos sets if all 0-1 in sets (well one extra is allowed) \ +and no overlaps. trysos is same but allows any number extra. equalall will turn all \ +valid inequalities into equalities with integer slacks. strategy is as \ +on but uses CbcStrategy." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("preT!olerance", "Tolerance to use in presolve", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \ +infeasible and you have awkward numbers and you are sure the problem is really feasible." + ); + parameters[numberParameters++] = + CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm", + "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1); + parameters[numberParameters-1].append("exa!ct"); + parameters[numberParameters-1].append("dant!zig"); + parameters[numberParameters-1].append("part!ial"); + parameters[numberParameters-1].append("steep!est"); + parameters[numberParameters-1].append("change"); + parameters[numberParameters-1].append("sprint"); + parameters[numberParameters-1].setLonghelp + ( + "Clp can use any pivot selection algorithm which the user codes as long as it\ + implements the features in the abstract pivot base class. The Dantzig method is implemented\ + to show a simple method but its use is deprecated. Exact devex is the method of choice and there\ + are two variants which keep all weights updated but only scan a subset each iteration.\ + Partial switches this on while change initially does dantzig until the factorization\ + becomes denser. This is still a work in progress." + ); + parameters[numberParameters++] = + CbcOrClpParam("primalS!implex", "Do primal simplex algorithm", + CLP_PARAM_ACTION_PRIMALSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the primal algorithm.\ + The default is to use exact devex.\ + The time and iterations may be affected by settings such as presolve, scaling, crash\ + and also by column selection method, infeasibility weight and dual and primal tolerances." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("primalT!olerance", "For an optimal solution \ +no primal infeasibility may exceed this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Normally the default tolerance is fine, but you may want to increase it a\ + bit if a primal run seems to be having a hard time" + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \ +costs this much to be infeasible", + 1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT); + parameters[numberParameters-1].setLonghelp + ( + "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\ + algorithm where you first get feasible then optimal. So Clp is minimizing this weight times\ + the sum of primal infeasibilities plus the true objective function (in minimization sense).\ + Too high a value may mean more iterations, while too low a bound means\ + the code may go all the way and then have to increase the weight in order to get feasible.\ + OSL had a heuristic to\ + adjust bounds, maybe we need that here." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("printi!ngOptions", "Print options", + "normal", CLP_PARAM_STR_INTPRINT, 3); + parameters[numberParameters-1].append("integer"); + parameters[numberParameters-1].append("special"); + parameters[numberParameters-1].append("rows"); + parameters[numberParameters-1].append("all"); + parameters[numberParameters-1].append("csv"); + parameters[numberParameters-1].append("bound!ranging"); + parameters[numberParameters-1].append("rhs!ranging"); + parameters[numberParameters-1].append("objective!ranging"); + parameters[numberParameters-1].append("stats"); + parameters[numberParameters-1].append("boundsint"); + parameters[numberParameters-1].append("boundsall"); + parameters[numberParameters-1].setLonghelp + ( + "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\ +integer - nonzero integer column variables\n\ +special - in format suitable for OsiRowCutDebugger\n\ +rows - nonzero column variables and row activities\n\ +all - all column variables and row activities.\n\ +\nFor non-integer problems 'integer' and 'special' act like 'normal'. \ +Also see printMask for controlling output." + ); + parameters[numberParameters++] = + CbcOrClpParam("printM!ask", "Control printing of solution on a mask", + CLP_PARAM_ACTION_PRINTMASK, 3); + parameters[numberParameters-1].setLonghelp + ( + "If set then only those names which match mask are printed in a solution. \ +'?' matches any character and '*' matches any set of characters. \ + The default is '' i.e. unset so all variables are printed. \ +This is only active if model has names." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("prio!rityIn", "Import priorities etc from file", + CBC_PARAM_ACTION_PRIORITYIN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read a file with priorities from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. This can not read from compressed files. \ +File is in csv format with allowed headings - name, number, priority, direction, up, down, solution. Exactly one of\ + name and number must be given." + ); + parameters[numberParameters++] = + CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts", + "off", CBC_PARAM_STR_PROBINGCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceonglobal"); + parameters[numberParameters-1].append("forceOnBut"); + parameters[numberParameters-1].append("forceOnStrong"); + parameters[numberParameters-1].append("forceOnButStrong"); + parameters[numberParameters-1].append("strongRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on probing cuts (either at root or in entire tree) \ +See branchAndCut for information on options. \ +but strong options do more probing" + ); + parameters[numberParameters++] = + CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic", + "off", CBC_PARAM_STR_PROXIMITY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("10"); + parameters[numberParameters-1].append("100"); + parameters[numberParameters-1].append("300"); + // but allow numbers after this (returning 1) + parameters[numberParameters-1].setFakeKeyWord(1); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which looks for a solution close \ +to incumbent solution (Fischetti and Monaci). \ +See Rounding for meaning of on,both,before. \ +Can also set different maxNode settings by plusnnnn (and are 'on'(on==30))." + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKECUTOFF); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise add a constraint forcing objective below this value\ + in feasibility pump" + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKEINCREMENT, 1); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise use as absolute increment to cutoff \ +when solution found in feasibility pump" + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump", + 0, 100000000, CBC_PARAM_INT_FPUMPTUNE); + parameters[numberParameters-1].setLonghelp + ( + "This fine tunes Feasibility Pump \n\ +\t>=10000000 use as objective weight switch\n\ +\t>=1000000 use as accumulate switch\n\ +\t>=1000 use index+1 as number of large loops\n\ +\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\ +\t%100 == 10,20 affects how each solve is done\n\ +\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \ +If accumulate is on then after a major pass, variables which have not moved \ +are fixed and a small branch and bound is tried." + ); + parameters[numberParameters-1].setIntValue(0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("quit", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("randomC!bcSeed", "Random seed for Cbc", + -1, COIN_INT_MAX, CBC_PARAM_INT_RANDOMSEED); + parameters[numberParameters-1].setLonghelp + ( + "This sets a random seed for Cbc \ +- 0 says use time of day, -1 is as now." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("randomi!zedRounding", "Whether to try randomized rounding heuristic", + "off", CBC_PARAM_STR_RANDROUND); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("randomS!eed", "Random seed for Clp", + 0, COIN_INT_MAX, CLP_PARAM_INT_RANDOMSEED); + parameters[numberParameters-1].setLonghelp + ( + "This sets a random seed for Clp \ +- 0 says use time of day." + ); + parameters[numberParameters-1].setIntValue(1234567); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \ +best less than this fraction of larger of two", + 0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "If the gap between best solution and best possible solution is less than this fraction \ +of the objective value at the root node then the search will terminate. See 'allowableGap' for a \ +way of using absolute value rather than fraction." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("restoreS!olution", "reads solution from file", + CLP_PARAM_ACTION_RESTORESOL); + parameters[numberParameters-1].setLonghelp + ( + "This will read a binary solution file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'solution.file'. This reads in a file from saveSolution" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("readSt!ored", "Import stored cuts from file", + CLP_PARAM_ACTION_STOREDFILE, 3, 0); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place", + -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0); + parameters[numberParameters-1].setLonghelp + ( + "You can set this to -1.0 to test maximization or other to stress code" + ); + parameters[numberParameters-1].setDoubleValue(1.0); + parameters[numberParameters++] = + CbcOrClpParam("reallyS!cale", "Scales model in place", + CLP_PARAM_ACTION_REALLY_SCALE, 7, 0); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts", + "off", CBC_PARAM_STR_REDSPLITCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree). \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2", + "off", CBC_PARAM_STR_REDSPLIT2CUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("longOn"); + parameters[numberParameters-1].append("longRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree) \ +This version is by Giacomo Nannicini based on Francois Margot's version \ +Standard setting only uses rows in tableau <=256, long uses all \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2", + "off", CBC_PARAM_STR_REDSPLIT2CUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("longOn"); + parameters[numberParameters-1].append("longRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree) \ +This version is by Giacomo Nannicini based on Francois Margot's version \ +Standard setting only uses rows in tableau <=256, long uses all \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts", + "off", CBC_PARAM_STR_RESIDCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "Residual capacity cuts. \ +See branchAndCut for information on options." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("restore!Model", "Restore model from binary file", + CLP_PARAM_ACTION_RESTORE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This reads data save by saveModel from the given file. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.prob'." + ); + parameters[numberParameters++] = + CbcOrClpParam("reverse", "Reverses sign of objective", + CLP_PARAM_ACTION_REVERSE, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Useful for testing if maximization works correctly" + ); + parameters[numberParameters++] = + CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds", + -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0); + parameters[numberParameters-1].setLonghelp + ( + "If the rhs or bounds have some very large meaningful values, you may wish to scale them\ + internally by this amount. It can also be set by autoscale. This should not be needed." + ); + parameters[numberParameters-1].setDoubleValue(1.0); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search", + "off", CBC_PARAM_STR_RENS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("200"); + parameters[numberParameters-1].append("1000"); + parameters[numberParameters-1].append("10000"); + parameters[numberParameters-1].append("dj"); + parameters[numberParameters-1].append("djbefore"); + parameters[numberParameters-1].append("usesolution"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Relaxation enforced neighborhood Search. \ +on just does 50 nodes \ +200 or 1000 does that many nodes. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search", + "off", CBC_PARAM_STR_RINS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("often"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Relaxed induced neighborhood Search. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic", + "off", CBC_PARAM_STR_ROUNDING); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a simple (but effective) rounding heuristic at each node of tree. \ +On means do in solve i.e. after preprocessing, \ +Before means do if doHeuristics used, off otherwise, \ +and both means do if doHeuristics and in solve." + ); + +#endif + parameters[numberParameters++] = + CbcOrClpParam("saveM!odel", "Save model to binary file", + CLP_PARAM_ACTION_SAVE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This will save the problem to the given file name for future use\ + by restoreModel. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.prob'." + ); + parameters[numberParameters++] = + CbcOrClpParam("saveS!olution", "saves solution to file", + CLP_PARAM_ACTION_SAVESOL); + parameters[numberParameters-1].setLonghelp + ( + "This will write a binary solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'solution.file'. To read the file use fread(int) twice to pick up number of rows \ +and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \ +activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \ +If name contains '_fix_read_' then does not write but reads and will fix all variables" + ); + parameters[numberParameters++] = + CbcOrClpParam("scal!ing", "Whether to scale problem", + "off", CLP_PARAM_STR_SCALING); + parameters[numberParameters-1].append("equi!librium"); + parameters[numberParameters-1].append("geo!metric"); + parameters[numberParameters-1].append("auto!matic"); + parameters[numberParameters-1].append("dynamic"); + parameters[numberParameters-1].append("rows!only"); + parameters[numberParameters-1].setLonghelp + ( + "Scaling can help in solving problems which might otherwise fail because of lack of\ + accuracy. It can also reduce the number of iterations. It is not applied if the range\ + of elements is small. When unscaled it is possible that there may be small primal and/or\ + infeasibilities." + ); + parameters[numberParameters-1].setCurrentOption(3); // say auto +#ifndef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("sec!onds", "Maximum seconds", + -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT); + parameters[numberParameters-1].setLonghelp + ( + "After this many seconds clp will act as if maximum iterations had been reached \ +(if value >=0)." + ); +#else + parameters[numberParameters++] = + CbcOrClpParam("sec!onds", "maximum seconds", + -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB); + parameters[numberParameters-1].setLonghelp + ( + "After this many seconds coin solver will act as if maximum nodes had been reached." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("sleep", "for debug", + CLP_PARAM_ACTION_DUMMY, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("slow!cutpasses", "Maximum number of tries for slower cuts", + -1, COIN_INT_MAX, CBC_PARAM_INT_MAX_SLOW_CUTS); + parameters[numberParameters-1].setLonghelp + ( + "Some cut generators are fairly slow - this limits the number of times they are tried." + ); + parameters[numberParameters-1].setIntValue(10); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("slp!Value", "Number of slp passes before primal", + -50000, 50000, CLP_PARAM_INT_SLPVALUE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If you are solving a quadratic problem using primal then it may be helpful to do some \ +sequential Lps to get a good approximate solution." + ); +#if CLP_MULTIPLE_FACTORIZATIONS > 0 + parameters[numberParameters++] = + CbcOrClpParam("small!Factorization", "Whether to use small factorization", + -1, 10000, CBC_PARAM_INT_SMALLFACT, 1); + parameters[numberParameters-1].setLonghelp + ( + "If processed problem <= this use small factorization" + ); + parameters[numberParameters-1].setIntValue(-1); +#endif +#endif + parameters[numberParameters++] = + CbcOrClpParam("solu!tion", "Prints solution to file", + CLP_PARAM_ACTION_SOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "This will write a primitive solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout'. The amount of output can be varied using printi!ngOptions or printMask." + ); +#ifdef COIN_HAS_CLP +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("solv!e", "Solve problem", + CBC_PARAM_ACTION_BAB); + parameters[numberParameters-1].setLonghelp + ( + "If there are no integer variables then this just solves LP. If there are integer variables \ +this does branch and cut." + ); + parameters[numberParameters++] = + CbcOrClpParam("sos!Options", "Whether to use SOS from AMPL", + "off", CBC_PARAM_STR_SOS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setCurrentOption("on"); + parameters[numberParameters-1].setLonghelp + ( + "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\ + be turned off - this does so." + ); + parameters[numberParameters++] = + CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output", + -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL); + parameters[numberParameters-1].setLonghelp + ( + "If 0 then there should be no output in normal circumstances. 1 is probably the best\ + value for most uses, while 2 and 3 give more information. This parameter is only used inside MIP - for Clp use 'log'" + ); +#else + // allow solve as synonym for possible dual + parameters[numberParameters++] = + CbcOrClpParam("solv!e", "Solve problem using dual simplex (probably)", + CLP_PARAM_ACTION_EITHERSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "Just so can use solve for clp as well as in cbc" + ); +#endif +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse", + "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0); + parameters[numberParameters-1].append("off"); + parameters[numberParameters++] = + CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp", + 0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("sprint!Crash", "Whether to try sprint crash", + -1, 5000000, CLP_PARAM_INT_SPRINT); + parameters[numberParameters-1].setLonghelp + ( + "For long and thin problems this program may solve a series of small problems\ + created by taking a subset of the columns. I introduced the idea as 'Sprint' after\ + an LP code of that name of the 60's which tried the same tactic (not totally successfully).\ + Cplex calls it 'sifting'. -1 is automatic choice, 0 is off, n is number of passes" + ); + parameters[numberParameters++] = + CbcOrClpParam("stat!istics", "Print some statistics", + CLP_PARAM_ACTION_STATISTICS); + parameters[numberParameters-1].setLonghelp + ( + "This command prints some statistics for the current model.\ + If log level >1 then more is printed.\ + These are for presolved model if presolve on (and unscaled)." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("stop", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("strat!egy", "Switches on groups of features", + 0, 2, CBC_PARAM_INT_STRATEGY); + parameters[numberParameters-1].setLonghelp + ( + "This turns on newer features. \ +Use 0 for easy problems, 1 is default, 2 is aggressive. \ +1 uses Gomory cuts using tolerance of 0.01 at root, \ +does a possible restart after 100 nodes if can fix many \ +and activates a diving and RINS heuristic and makes feasibility pump \ +more aggressive. \ +This does not apply to unit tests (where 'experiment' may have similar effects)." + ); + parameters[numberParameters-1].setIntValue(1); +#ifdef CBC_KEEP_DEPRECATED + parameters[numberParameters++] = + CbcOrClpParam("strengthen", "Create strengthened problem", + CBC_PARAM_ACTION_STRENGTHEN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This creates a new problem by applying the root node cuts. All tight constraints \ +will be in resulting problem" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching", + 0, COIN_INT_MAX, CBC_PARAM_INT_STRONGBRANCHING); + parameters[numberParameters-1].setLonghelp + ( + "In order to decide which variable to branch on, the code will choose up to this number \ +of unsatisfied variables to do mini up and down branches on. Then the most effective one is chosen. \ +If a variable is branched on many times then the previous average up and down costs may be used - \ +see number before trust." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve", + 0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0); + parameters[numberParameters-1].setLonghelp + ( + "Normally Presolve gets rid of 'free' variables when there are no more than 3 \ + variables in column. If you increase this the number of rows may decrease but number of \ + elements may increase." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("testO!si", "Test OsiObject stuff", + -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0); +#endif +#ifdef CBC_THREAD + parameters[numberParameters++] = + CbcOrClpParam("thread!s", "Number of threads to try and use", + -100, 100000, CBC_PARAM_INT_THREADS, 1); + parameters[numberParameters-1].setLonghelp + ( + "To use multiple threads, set threads to number wanted. It may be better \ +to use one or two more than number of cpus available. If 100+n then n threads and \ +search is repeatable (maybe be somewhat slower), \ +if 200+n use threads for root cuts, 400+n threads used in sub-trees." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \ +activity at continuous solution", + 1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0); + parameters[numberParameters-1].setLonghelp + ( + "This sleazy trick can help on some problems." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("tightLP", "Poor person's preSolve for now", + CLP_PARAM_ACTION_TIGHTEN, 7, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time", + "cpu", CLP_PARAM_STR_TIME_MODE); + parameters[numberParameters-1].append("elapsed"); + parameters[numberParameters-1].setLonghelp + ( + "cpu uses CPU time for stopping, while elapsed uses elapsed time. \ +(On Windows, elapsed time is always used)." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts", + -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE); + parameters[numberParameters-1].setLonghelp + ( + "Using strong branching computes pseudo-costs. After this many times for a variable we just \ +trust the pseudo costs and do not do any more strong branching." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters", + 0, 2000000000, CLP_PARAM_INT_PROCESSTUNE, 1); + parameters[numberParameters-1].setLonghelp + ( + "Format aabbcccc - \n If aa then this is number of major passes (i.e. with presolve) \n \ +If bb and bb>0 then this is number of minor passes (if unset or 0 then 10) \n \ +cccc is bit set \n 0 - 1 Heavy probing \n 1 - 2 Make variables integer if possible (if obj value)\n \ +2 - 4 As above but even if zero objective value\n \ +7 - 128 Try and create cliques\n 8 - 256 If all +1 try hard for dominated rows\n \ +10 - 1024 Use a larger feasibility tolerance in presolve\n \ +11 - 2048 Try probing before creating cliques" + ); + parameters[numberParameters++] = + CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts", + "off", CBC_PARAM_STR_TWOMIRCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on two phase mixed integer rounding cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("unitTest", "Do unit test", + CLP_PARAM_ACTION_UNITTEST, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp" + ); + parameters[numberParameters++] = + CbcOrClpParam("userClp", "Hand coded Clp stuff", + CLP_PARAM_ACTION_USERCLP, 0, 0); + parameters[numberParameters-1].setLonghelp + ( + "There are times e.g. when using AMPL interface when you may wish to do something unusual. \ +Look for USERCLP in main driver and modify sample code." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("userCbc", "Hand coded Cbc stuff", + CBC_PARAM_ACTION_USERCBC, 0, 0); + parameters[numberParameters-1].setLonghelp + ( + "There are times e.g. when using AMPL interface when you may wish to do something unusual. \ +Look for USERCBC in main driver and modify sample code. \ +It is possible you can get same effect by using example driver4.cpp." + ); + parameters[numberParameters++] = + CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search", + "off", CBC_PARAM_STR_VND); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("intree"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on variable neighborhood Search. \ +Doh option does heuristic before preprocessing" ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex", + "off", CLP_PARAM_STR_VECTOR, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "If this is on ClpPackedMatrix uses extra column copy in odd format." + ); + parameters[numberParameters++] = + CbcOrClpParam("verbose", "Switches on longer help on single ?", + 0, 31, CLP_PARAM_INT_VERBOSE, 0); + parameters[numberParameters-1].setLonghelp + ( + "Set to 1 to get short help with ? list, 2 to get long help, 3 for both. (add 4 to just get ampl ones)." + ); + parameters[numberParameters-1].setIntValue(0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("vub!heuristic", "Type of vub heuristic", + -2, 20, CBC_PARAM_INT_VUBTRY, 0); + parameters[numberParameters-1].setLonghelp + ( + "If set will try and fix some integer variables" + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts", + "off", CBC_PARAM_STR_ZEROHALFCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on zero-half cuts (either at root or in entire tree) \ +See branchAndCut for information on options. This implementation was written by \ +Alberto Caprara." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("zeroT!olerance", "Kill all coefficients \ +whose absolute value is less than this value", + 1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "This applies to reading mps files (and also lp files \ +if KILL_ZERO_READLP defined)" + ); + parameters[numberParameters-1].setDoubleValue(1.0e-20); + assert(numberParameters < CBCMAXPARAMETERS); +} +// Given a parameter type - returns its number in list +int whichParam (CbcOrClpParameterType name, + int numberParameters, CbcOrClpParam *const parameters) +{ + int i; + for (i = 0; i < numberParameters; i++) { + if (parameters[i].type() == name) + break; + } + assert (i < numberParameters); + return i; +} +#ifdef COIN_HAS_CLP +/* Restore a solution from file. + mode 0 normal, 1 swap rows and columns and primal and dual + if 2 set then also change signs +*/ +void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode) +{ + FILE * fp = fopen(fileName.c_str(), "rb"); + if (fp) { + int numberRows = lpSolver->numberRows(); + int numberColumns = lpSolver->numberColumns(); + int numberRowsFile; + int numberColumnsFile; + double objectiveValue; + size_t nRead; + nRead = fread(&numberRowsFile, sizeof(int), 1, fp); + if (nRead != 1) + throw("Error in fread"); + nRead = fread(&numberColumnsFile, sizeof(int), 1, fp); + if (nRead != 1) + throw("Error in fread"); + nRead = fread(&objectiveValue, sizeof(double), 1, fp); + if (nRead != 1) + throw("Error in fread"); + double * dualRowSolution = lpSolver->dualRowSolution(); + double * primalRowSolution = lpSolver->primalRowSolution(); + double * dualColumnSolution = lpSolver->dualColumnSolution(); + double * primalColumnSolution = lpSolver->primalColumnSolution(); + if (mode) { + // swap + int k = numberRows; + numberRows = numberColumns; + numberColumns = k; + double * temp; + temp = dualRowSolution; + dualRowSolution = primalColumnSolution; + primalColumnSolution = temp; + temp = dualColumnSolution; + dualColumnSolution = primalRowSolution; + primalRowSolution = temp; + } + if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) { + std::cout << "Mismatch on rows and/or columns - giving up" << std::endl; + } else { + lpSolver->setObjectiveValue(objectiveValue); + if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) { + nRead = fread(primalRowSolution, sizeof(double), numberRows, fp); + if (nRead != static_cast(numberRows)) + throw("Error in fread"); + nRead = fread(dualRowSolution, sizeof(double), numberRows, fp); + if (nRead != static_cast(numberRows)) + throw("Error in fread"); + nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp); + if (nRead != static_cast(numberColumns)) + throw("Error in fread"); + nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp); + if (nRead != static_cast(numberColumns)) + throw("Error in fread"); + } else { + std::cout << "Mismatch on rows and/or columns - truncating" << std::endl; + double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)]; + nRead = fread(temp, sizeof(double), numberRowsFile, fp); + if (nRead != static_cast(numberRowsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberRows, primalRowSolution); + nRead = fread(temp, sizeof(double), numberRowsFile, fp); + if (nRead != static_cast(numberRowsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberRows, dualRowSolution); + nRead = fread(temp, sizeof(double), numberColumnsFile, fp); + if (nRead != static_cast(numberColumnsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberColumns, primalColumnSolution); + nRead = fread(temp, sizeof(double), numberColumnsFile, fp); + if (nRead != static_cast(numberColumnsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberColumns, dualColumnSolution); + delete [] temp; + } + if (mode == 3) { + int i; + for (i = 0; i < numberRows; i++) { + primalRowSolution[i] = -primalRowSolution[i]; + dualRowSolution[i] = -dualRowSolution[i]; + } + for (i = 0; i < numberColumns; i++) { + primalColumnSolution[i] = -primalColumnSolution[i]; + dualColumnSolution[i] = -dualColumnSolution[i]; + } + } + } + fclose(fp); + } else { + std::cout << "Unable to open file " << fileName << std::endl; + } +} +// Dump a solution to file +void saveSolution(const ClpSimplex * lpSolver, std::string fileName) +{ + if (strstr(fileName.c_str(), "_fix_read_")) { + FILE * fp = fopen(fileName.c_str(), "rb"); + if (fp) { + ClpSimplex * solver = const_cast(lpSolver); + restoreSolution(solver, fileName, 0); + // fix all + int logLevel = solver->logLevel(); + int iColumn; + int numberColumns = solver->numberColumns(); + double * primalColumnSolution = + solver->primalColumnSolution(); + double * columnLower = solver->columnLower(); + double * columnUpper = solver->columnUpper(); + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = primalColumnSolution[iColumn]; + if (value > columnUpper[iColumn]) { + if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1) + printf("%d value of %g - bounds %g %g\n", + iColumn, value, columnLower[iColumn], columnUpper[iColumn]); + value = columnUpper[iColumn]; + } else if (value < columnLower[iColumn]) { + if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1) + printf("%d value of %g - bounds %g %g\n", + iColumn, value, columnLower[iColumn], columnUpper[iColumn]); + value = columnLower[iColumn]; + } + columnLower[iColumn] = value; + columnUpper[iColumn] = value; + } + return; + } + } + FILE * fp = fopen(fileName.c_str(), "wb"); + if (fp) { + int numberRows = lpSolver->numberRows(); + int numberColumns = lpSolver->numberColumns(); + double objectiveValue = lpSolver->objectiveValue(); + size_t nWrite; + nWrite = fwrite(&numberRows, sizeof(int), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + nWrite = fwrite(&numberColumns, sizeof(int), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + double * dualRowSolution = lpSolver->dualRowSolution(); + double * primalRowSolution = lpSolver->primalRowSolution(); + nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp); + if (nWrite != static_cast(numberRows)) + throw("Error in fwrite"); + nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp); + if (nWrite != static_cast(numberRows)) + throw("Error in fwrite"); + double * dualColumnSolution = lpSolver->dualColumnSolution(); + double * primalColumnSolution = lpSolver->primalColumnSolution(); + nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp); + if (nWrite != static_cast(numberColumns)) + throw("Error in fwrite"); + nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp); + if (nWrite != static_cast(numberColumns)) + throw("Error in fwrite"); + fclose(fp); + } else { + std::cout << "Unable to open file " << fileName << std::endl; + } +} +#endif diff --git a/thirdparty/linux/include/coin/CbcOrClpParam.hpp b/thirdparty/linux/include/coin/CbcOrClpParam.hpp new file mode 100644 index 0000000..5e0794a --- /dev/null +++ b/thirdparty/linux/include/coin/CbcOrClpParam.hpp @@ -0,0 +1,532 @@ + +/* $Id: CbcOrClpParam.hpp 2175 2015-10-06 08:56:43Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifdef USE_CBCCONFIG +# include "CbcConfig.h" +#else +# include "ClpConfig.h" +#endif + +#ifndef CbcOrClpParam_H +#define CbcOrClpParam_H +/** + This has parameter handling stuff which can be shared between Cbc and Clp (and Dylp etc). + + This (and .cpp) should be copied so that it is the same in Cbc/Test and Clp/Test. + I know this is not elegant but it seems simplest. + + It uses COIN_HAS_CBC for parameters wanted by CBC + It uses COIN_HAS_CLP for parameters wanted by CLP (or CBC using CLP) + It could use COIN_HAS_DYLP for parameters wanted by DYLP + It could use COIN_HAS_DYLP_OR_CLP for parameters wanted by DYLP or CLP etc etc + + */ +class OsiSolverInterface; +class CbcModel; +class ClpSimplex; +/*! \brief Parameter codes + + Parameter type ranges are allocated as follows +
    +
  • 1 -- 100 double parameters +
  • 101 -- 200 integer parameters +
  • 201 -- 250 string parameters +
  • 251 -- 300 cuts etc(string but broken out for clarity) +
  • 301 -- 400 `actions' +
+ + `Actions' do not necessarily invoke an immediate action; it's just that they + don't fit neatly into the parameters array. + + This coding scheme is in flux. +*/ + +enum CbcOrClpParameterType + +{ + CBC_PARAM_GENERALQUERY = -100, + CBC_PARAM_FULLGENERALQUERY, + + CLP_PARAM_DBL_PRIMALTOLERANCE = 1, + CLP_PARAM_DBL_DUALTOLERANCE, + CLP_PARAM_DBL_TIMELIMIT, + CLP_PARAM_DBL_DUALBOUND, + CLP_PARAM_DBL_PRIMALWEIGHT, + CLP_PARAM_DBL_OBJSCALE, + CLP_PARAM_DBL_RHSSCALE, + CLP_PARAM_DBL_ZEROTOLERANCE, + + CBC_PARAM_DBL_INFEASIBILITYWEIGHT = 51, + CBC_PARAM_DBL_CUTOFF, + CBC_PARAM_DBL_INTEGERTOLERANCE, + CBC_PARAM_DBL_INCREMENT, + CBC_PARAM_DBL_ALLOWABLEGAP, + CBC_PARAM_DBL_TIMELIMIT_BAB, + CBC_PARAM_DBL_GAPRATIO, + + CBC_PARAM_DBL_DJFIX = 81, + CBC_PARAM_DBL_TIGHTENFACTOR, + CLP_PARAM_DBL_PRESOLVETOLERANCE, + CLP_PARAM_DBL_OBJSCALE2, + CBC_PARAM_DBL_FAKEINCREMENT, + CBC_PARAM_DBL_FAKECUTOFF, + CBC_PARAM_DBL_ARTIFICIALCOST, + CBC_PARAM_DBL_DEXTRA3, + CBC_PARAM_DBL_SMALLBAB, + CBC_PARAM_DBL_DEXTRA4, + CBC_PARAM_DBL_DEXTRA5, + + CLP_PARAM_INT_SOLVERLOGLEVEL = 101, +#ifndef COIN_HAS_CBC + CLP_PARAM_INT_LOGLEVEL = 101, +#endif + CLP_PARAM_INT_MAXFACTOR, + CLP_PARAM_INT_PERTVALUE, + CLP_PARAM_INT_MAXITERATION, + CLP_PARAM_INT_PRESOLVEPASS, + CLP_PARAM_INT_IDIOT, + CLP_PARAM_INT_SPRINT, + CLP_PARAM_INT_OUTPUTFORMAT, + CLP_PARAM_INT_SLPVALUE, + CLP_PARAM_INT_PRESOLVEOPTIONS, + CLP_PARAM_INT_PRINTOPTIONS, + CLP_PARAM_INT_SPECIALOPTIONS, + CLP_PARAM_INT_SUBSTITUTION, + CLP_PARAM_INT_DUALIZE, + CLP_PARAM_INT_VERBOSE, + CLP_PARAM_INT_CPP, + CLP_PARAM_INT_PROCESSTUNE, + CLP_PARAM_INT_USESOLUTION, + CLP_PARAM_INT_RANDOMSEED, + CLP_PARAM_INT_MORESPECIALOPTIONS, + CLP_PARAM_INT_DECOMPOSE_BLOCKS, + + CBC_PARAM_INT_STRONGBRANCHING = 151, + CBC_PARAM_INT_CUTDEPTH, + CBC_PARAM_INT_MAXNODES, + CBC_PARAM_INT_NUMBERBEFORE, + CBC_PARAM_INT_NUMBERANALYZE, + CBC_PARAM_INT_MIPOPTIONS, + CBC_PARAM_INT_MOREMIPOPTIONS, + CBC_PARAM_INT_MAXHOTITS, + CBC_PARAM_INT_FPUMPITS, + CBC_PARAM_INT_MAXSOLS, + CBC_PARAM_INT_FPUMPTUNE, + CBC_PARAM_INT_TESTOSI, + CBC_PARAM_INT_EXTRA1, + CBC_PARAM_INT_EXTRA2, + CBC_PARAM_INT_EXTRA3, + CBC_PARAM_INT_EXTRA4, + CBC_PARAM_INT_DEPTHMINIBAB, + CBC_PARAM_INT_CUTPASSINTREE, + CBC_PARAM_INT_THREADS, + CBC_PARAM_INT_CUTPASS, + CBC_PARAM_INT_VUBTRY, + CBC_PARAM_INT_DENSE, + CBC_PARAM_INT_EXPERIMENT, + CBC_PARAM_INT_DIVEOPT, + CBC_PARAM_INT_DIVEOPTSOLVES, + CBC_PARAM_INT_STRATEGY, + CBC_PARAM_INT_SMALLFACT, + CBC_PARAM_INT_HOPTIONS, + CBC_PARAM_INT_CUTLENGTH, + CBC_PARAM_INT_FPUMPTUNE2, +#ifdef COIN_HAS_CBC + CLP_PARAM_INT_LOGLEVEL , +#endif + CBC_PARAM_INT_MAXSAVEDSOLS, + CBC_PARAM_INT_RANDOMSEED, + CBC_PARAM_INT_MULTIPLEROOTS, + CBC_PARAM_INT_STRONG_STRATEGY, + CBC_PARAM_INT_EXTRA_VARIABLES, + CBC_PARAM_INT_MAX_SLOW_CUTS, + CBC_PARAM_INT_MOREMOREMIPOPTIONS, + + CLP_PARAM_STR_DIRECTION = 201, + CLP_PARAM_STR_DUALPIVOT, + CLP_PARAM_STR_SCALING, + CLP_PARAM_STR_ERRORSALLOWED, + CLP_PARAM_STR_KEEPNAMES, + CLP_PARAM_STR_SPARSEFACTOR, + CLP_PARAM_STR_PRIMALPIVOT, + CLP_PARAM_STR_PRESOLVE, + CLP_PARAM_STR_CRASH, + CLP_PARAM_STR_BIASLU, + CLP_PARAM_STR_PERTURBATION, + CLP_PARAM_STR_MESSAGES, + CLP_PARAM_STR_AUTOSCALE, + CLP_PARAM_STR_CHOLESKY, + CLP_PARAM_STR_KKT, + CLP_PARAM_STR_BARRIERSCALE, + CLP_PARAM_STR_GAMMA, + CLP_PARAM_STR_CROSSOVER, + CLP_PARAM_STR_PFI, + CLP_PARAM_STR_INTPRINT, + CLP_PARAM_STR_VECTOR, + CLP_PARAM_STR_FACTORIZATION, + CLP_PARAM_STR_ALLCOMMANDS, + CLP_PARAM_STR_TIME_MODE, + CLP_PARAM_STR_ABCWANTED, + CLP_PARAM_STR_BUFFER_MODE, + + CBC_PARAM_STR_NODESTRATEGY = 251, + CBC_PARAM_STR_BRANCHSTRATEGY, + CBC_PARAM_STR_CUTSSTRATEGY, + CBC_PARAM_STR_HEURISTICSTRATEGY, + CBC_PARAM_STR_GOMORYCUTS, + CBC_PARAM_STR_PROBINGCUTS, + CBC_PARAM_STR_KNAPSACKCUTS, + CBC_PARAM_STR_REDSPLITCUTS, + CBC_PARAM_STR_ROUNDING, + CBC_PARAM_STR_SOLVER, + CBC_PARAM_STR_CLIQUECUTS, + CBC_PARAM_STR_COSTSTRATEGY, + CBC_PARAM_STR_FLOWCUTS, + CBC_PARAM_STR_MIXEDCUTS, + CBC_PARAM_STR_TWOMIRCUTS, + CBC_PARAM_STR_PREPROCESS, + CBC_PARAM_STR_FPUMP, + CBC_PARAM_STR_GREEDY, + CBC_PARAM_STR_COMBINE, + CBC_PARAM_STR_PROXIMITY, + CBC_PARAM_STR_LOCALTREE, + CBC_PARAM_STR_SOS, + CBC_PARAM_STR_LANDPCUTS, + CBC_PARAM_STR_RINS, + CBC_PARAM_STR_RESIDCUTS, + CBC_PARAM_STR_RENS, + CBC_PARAM_STR_DIVINGS, + CBC_PARAM_STR_DIVINGC, + CBC_PARAM_STR_DIVINGF, + CBC_PARAM_STR_DIVINGG, + CBC_PARAM_STR_DIVINGL, + CBC_PARAM_STR_DIVINGP, + CBC_PARAM_STR_DIVINGV, + CBC_PARAM_STR_DINS, + CBC_PARAM_STR_PIVOTANDFIX, + CBC_PARAM_STR_RANDROUND, + CBC_PARAM_STR_NAIVE, + CBC_PARAM_STR_ZEROHALFCUTS, + CBC_PARAM_STR_CPX, + CBC_PARAM_STR_CROSSOVER2, + CBC_PARAM_STR_PIVOTANDCOMPLEMENT, + CBC_PARAM_STR_VND, + CBC_PARAM_STR_LAGOMORYCUTS, + CBC_PARAM_STR_LATWOMIRCUTS, + CBC_PARAM_STR_REDSPLIT2CUTS, + CBC_PARAM_STR_GMICUTS, + CBC_PARAM_STR_CUTOFF_CONSTRAINT, + CBC_PARAM_STR_DW, + CBC_PARAM_STR_ORBITAL, + + CLP_PARAM_ACTION_DIRECTORY = 301, + CLP_PARAM_ACTION_DIRSAMPLE, + CLP_PARAM_ACTION_DIRNETLIB, + CBC_PARAM_ACTION_DIRMIPLIB, + CLP_PARAM_ACTION_IMPORT, + CLP_PARAM_ACTION_EXPORT, + CLP_PARAM_ACTION_RESTORE, + CLP_PARAM_ACTION_SAVE, + CLP_PARAM_ACTION_DUALSIMPLEX, + CLP_PARAM_ACTION_PRIMALSIMPLEX, + CLP_PARAM_ACTION_EITHERSIMPLEX, + CLP_PARAM_ACTION_MAXIMIZE, + CLP_PARAM_ACTION_MINIMIZE, + CLP_PARAM_ACTION_EXIT, + CLP_PARAM_ACTION_STDIN, + CLP_PARAM_ACTION_UNITTEST, + CLP_PARAM_ACTION_NETLIB_EITHER, + CLP_PARAM_ACTION_NETLIB_DUAL, + CLP_PARAM_ACTION_NETLIB_PRIMAL, + CLP_PARAM_ACTION_SOLUTION, + CLP_PARAM_ACTION_SAVESOL, + CLP_PARAM_ACTION_TIGHTEN, + CLP_PARAM_ACTION_FAKEBOUND, + CLP_PARAM_ACTION_HELP, + CLP_PARAM_ACTION_PLUSMINUS, + CLP_PARAM_ACTION_NETWORK, + CLP_PARAM_ACTION_ALLSLACK, + CLP_PARAM_ACTION_REVERSE, + CLP_PARAM_ACTION_BARRIER, + CLP_PARAM_ACTION_NETLIB_BARRIER, + CLP_PARAM_ACTION_NETLIB_TUNE, + CLP_PARAM_ACTION_REALLY_SCALE, + CLP_PARAM_ACTION_BASISIN, + CLP_PARAM_ACTION_BASISOUT, + CLP_PARAM_ACTION_SOLVECONTINUOUS, + CLP_PARAM_ACTION_CLEARCUTS, + CLP_PARAM_ACTION_VERSION, + CLP_PARAM_ACTION_STATISTICS, + CLP_PARAM_ACTION_DEBUG, + CLP_PARAM_ACTION_DUMMY, + CLP_PARAM_ACTION_PRINTMASK, + CLP_PARAM_ACTION_OUTDUPROWS, + CLP_PARAM_ACTION_USERCLP, + CLP_PARAM_ACTION_MODELIN, + CLP_PARAM_ACTION_CSVSTATISTICS, + CLP_PARAM_ACTION_STOREDFILE, + CLP_PARAM_ACTION_ENVIRONMENT, + CLP_PARAM_ACTION_PARAMETRICS, + CLP_PARAM_ACTION_GMPL_SOLUTION, + CLP_PARAM_ACTION_RESTORESOL, + + CBC_PARAM_ACTION_BAB = 361, + CBC_PARAM_ACTION_MIPLIB, + CBC_PARAM_ACTION_STRENGTHEN, + CBC_PARAM_ACTION_PRIORITYIN, + CBC_PARAM_ACTION_MIPSTART, + CBC_PARAM_ACTION_USERCBC, + CBC_PARAM_ACTION_DOHEURISTIC, + CLP_PARAM_ACTION_NEXTBESTSOLUTION, + + CBC_PARAM_NOTUSED_OSLSTUFF = 401, + CBC_PARAM_NOTUSED_CBCSTUFF, + + CBC_PARAM_NOTUSED_INVALID = 1000 +} ; +#include +#include + +/// Very simple class for setting parameters + +class CbcOrClpParam { +public: + /**@name Constructor and destructor */ + //@{ + /// Constructors + CbcOrClpParam ( ); + CbcOrClpParam (std::string name, std::string help, + double lower, double upper, CbcOrClpParameterType type, int display = 2); + CbcOrClpParam (std::string name, std::string help, + int lower, int upper, CbcOrClpParameterType type, int display = 2); + // Other strings will be added by insert + CbcOrClpParam (std::string name, std::string help, std::string firstValue, + CbcOrClpParameterType type, int whereUsed = 7, int display = 2); + // Action + CbcOrClpParam (std::string name, std::string help, + CbcOrClpParameterType type, int whereUsed = 7, int display = 2); + /// Copy constructor. + CbcOrClpParam(const CbcOrClpParam &); + /// Assignment operator. This copies the data + CbcOrClpParam & operator=(const CbcOrClpParam & rhs); + /// Destructor + ~CbcOrClpParam ( ); + //@} + + /**@name stuff */ + //@{ + /// Insert string (only valid for keywords) + void append(std::string keyWord); + /// Adds one help line + void addHelp(std::string keyWord); + /// Returns name + inline std::string name( ) const { + return name_; + } + /// Returns short help + inline std::string shortHelp( ) const { + return shortHelp_; + } + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(CbcModel & model, double value) ; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( CbcModel & model, double value , int & returnCode); + /// Gets a double parameter + double doubleParameter(CbcModel & model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(CbcModel & model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( CbcModel & model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(CbcModel & model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(ClpSimplex * model, double value) ; + /// Gets a double parameter + double doubleParameter(ClpSimplex * model) const; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( ClpSimplex * model, double value , int & returnCode); + /// Sets a int parameter (nonzero code if error) + int setIntParameter(ClpSimplex * model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( ClpSimplex * model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(ClpSimplex * model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(OsiSolverInterface * model, double value) ; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( OsiSolverInterface * model, double value , int & returnCode); + /// Gets a double parameter + double doubleParameter(OsiSolverInterface * model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(OsiSolverInterface * model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( OsiSolverInterface * model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(OsiSolverInterface * model) const; + /// Checks a double parameter (nonzero code if error) + int checkDoubleParameter(double value) const; + /// Returns name which could match + std::string matchName ( ) const; + /// Returns length of name for ptinting + int lengthMatchName ( ) const; + /// Returns parameter option which matches (-1 if none) + int parameterOption ( std::string check ) const; + /// Prints parameter options + void printOptions ( ) const; + /// Returns current parameter option + inline std::string currentOption ( ) const { + return definedKeyWords_[currentKeyWord_]; + } + /// Sets current parameter option + void setCurrentOption ( int value , bool printIt = false); + /// Sets current parameter option and returns printable string + const char * setCurrentOptionWithMessage ( int value ); + /// Sets current parameter option using string + void setCurrentOption (const std::string value ); + /// Sets current parameter option using string with message + const char * setCurrentOptionWithMessage (const std::string value ); + /// Returns current parameter option position + int currentOptionAsInteger ( ) const ; + /** Returns current parameter option position + but if fake keyword returns a fake value and sets + fakeInteger to true value. If not fake then fakeInteger is -COIN_INT_MAX + */ + int currentOptionAsInteger ( int & fakeInteger ) const; + /// Sets int value + void setIntValue ( int value ); + /// Sets int value with message + const char * setIntValueWithMessage ( int value ); + inline int intValue () const { + return intValue_; + } + /// Sets double value + void setDoubleValue ( double value ); + /// Sets double value with message + const char * setDoubleValueWithMessage ( double value ); + inline double doubleValue () const { + return doubleValue_; + } + /// Sets string value + void setStringValue ( std::string value ); + inline std::string stringValue () const { + return stringValue_; + } + /// Returns 1 if matches minimum, 2 if matches less, 0 if not matched + int matches (std::string input) const; + /// type + inline CbcOrClpParameterType type() const { + return type_; + } + /// whether to display + inline int displayThis() const { + return display_; + } + /// Set Long help + inline void setLonghelp(const std::string help) { + longHelp_ = help; + } + /// Print Long help + void printLongHelp() const; + /// Print action and string + void printString() const; + /** 7 if used everywhere, + 1 - used by clp + 2 - used by cbc + 4 - used by ampl + */ + inline int whereUsed() const { + return whereUsed_; + } + /// Gets value of fake keyword + inline int fakeKeyWord() const + { return fakeKeyWord_;} + /// Sets value of fake keyword + inline void setFakeKeyWord(int value, int fakeValue) + { fakeKeyWord_ = value; fakeValue_ = fakeValue;} + /// Sets value of fake keyword to current size of keywords + void setFakeKeyWord(int fakeValue); + +private: + /// gutsOfConstructor + void gutsOfConstructor(); + //@} +////////////////// data ////////////////// +private: + + /**@name data + We might as well throw all type data in - could derive? + */ + //@{ + // Type see CbcOrClpParameterType + CbcOrClpParameterType type_; + /// If double == okay + double lowerDoubleValue_; + double upperDoubleValue_; + /// If int == okay + int lowerIntValue_; + int upperIntValue_; + // Length of name + unsigned int lengthName_; + // Minimum match + unsigned int lengthMatch_; + /// set of valid strings + std::vector definedKeyWords_; + /// Name + std::string name_; + /// Short help + std::string shortHelp_; + /// Long help + std::string longHelp_; + /// Action + CbcOrClpParameterType action_; + /// Current keyWord (if a keyword parameter) + int currentKeyWord_; + /// Display on ? + int display_; + /// Integer parameter - current value + int intValue_; + /// Double parameter - current value + double doubleValue_; + /// String parameter - current value + std::string stringValue_; + /** 7 if used everywhere, + 1 - used by clp + 2 - used by cbc + 4 - used by ampl + */ + int whereUsed_; + /** If >=0 then integers allowed as a fake keyword + So minusnnnn would got to -nnnn in currentKeyword_ + and plusnnnn would go to fakeKeyword_+nnnn + */ + int fakeKeyWord_; + /// Return this as main value if an integer + int fakeValue_; + //@} +}; +/// Simple read stuff +std::string CoinReadNextField(); + +std::string CoinReadGetCommand(int argc, const char *argv[]); +std::string CoinReadGetString(int argc, const char *argv[]); +// valid 0 - okay, 1 bad, 2 not there +int CoinReadGetIntField(int argc, const char *argv[], int * valid); +double CoinReadGetDoubleField(int argc, const char *argv[], int * valid); +void CoinReadPrintit(const char * input); +void setCbcOrClpPrinting(bool yesNo); +#define CBCMAXPARAMETERS 250 +/* + Subroutine to establish the cbc parameter array. See the description of + class CbcOrClpParam for details. Pulled from C..Main() for clarity. +*/ +void establishParams (int &numberParameters, CbcOrClpParam *const parameters); +// Given a parameter type - returns its number in list +int whichParam (CbcOrClpParameterType name, + int numberParameters, CbcOrClpParam *const parameters); +// Dump/restore a solution to file +void saveSolution(const ClpSimplex * lpSolver, std::string fileName); +void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode); +#endif /* CbcOrClpParam_H */ diff --git a/thirdparty/linux/include/coin/ClpCholeskyBase.hpp b/thirdparty/linux/include/coin/ClpCholeskyBase.hpp new file mode 100644 index 0000000..815af01 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpCholeskyBase.hpp @@ -0,0 +1,294 @@ +/* $Id: ClpCholeskyBase.hpp 1722 2011-04-17 09:58:37Z stefan $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpCholeskyBase_H +#define ClpCholeskyBase_H + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" +//#define CLP_LONG_CHOLESKY 0 +#ifndef CLP_LONG_CHOLESKY +#define CLP_LONG_CHOLESKY 0 +#endif +/* valid combinations are + CLP_LONG_CHOLESKY 0 and COIN_LONG_WORK 0 + CLP_LONG_CHOLESKY 1 and COIN_LONG_WORK 1 + CLP_LONG_CHOLESKY 2 and COIN_LONG_WORK 1 +*/ +#if COIN_LONG_WORK==0 +#if CLP_LONG_CHOLESKY>0 +#define CHOLESKY_BAD_COMBINATION +#endif +#else +#if CLP_LONG_CHOLESKY==0 +#define CHOLESKY_BAD_COMBINATION +#endif +#endif +#ifdef CHOLESKY_BAD_COMBINATION +# warning("Bad combination of CLP_LONG_CHOLESKY and COIN_BIG_DOUBLE/COIN_LONG_WORK"); +"Bad combination of CLP_LONG_CHOLESKY and COIN_LONG_WORK" +#endif +#if CLP_LONG_CHOLESKY>1 +typedef long double longDouble; +#define CHOL_SMALL_VALUE 1.0e-15 +#elif CLP_LONG_CHOLESKY==1 +typedef double longDouble; +#define CHOL_SMALL_VALUE 1.0e-11 +#else +typedef double longDouble; +#define CHOL_SMALL_VALUE 1.0e-11 +#endif +class ClpInterior; +class ClpCholeskyDense; +class ClpMatrixBase; + +/** Base class for Clp Cholesky factorization + Will do better factorization. very crude ordering + + Derived classes may be using more sophisticated methods +*/ + +class ClpCholeskyBase { + +public: + /**@name Virtual methods that the derived classes may provide */ + //@{ + /** Orders rows and saves pointer to matrix.and model. + returns non-zero if not enough memory. + You can use preOrder to set up ADAT + If using default symbolic etc then must set sizeFactor_ to + size of input matrix to order (and to symbolic). + Also just permute_ and permuteInverse_ should be created */ + virtual int order(ClpInterior * model); + /** Does Symbolic factorization given permutation. + This is called immediately after order. If user provides this then + user must provide factorize and solve. Otherwise the default factorization is used + returns non-zero if not enough memory */ + virtual int symbolic(); + /** Factorize - filling in rowsDropped and returning number dropped. + If return code negative then out of memory */ + virtual int factorize(const CoinWorkDouble * diagonal, int * rowsDropped) ; + /** Uses factorization to solve. */ + virtual void solve (CoinWorkDouble * region) ; + /** Uses factorization to solve. - given as if KKT. + region1 is rows+columns, region2 is rows */ + virtual void solveKKT (CoinWorkDouble * region1, CoinWorkDouble * region2, const CoinWorkDouble * diagonal, + CoinWorkDouble diagonalScaleFactor); +private: + /// AMD ordering + int orderAMD(); +public: + //@} + + /**@name Gets */ + //@{ + /// status. Returns status + inline int status() const { + return status_; + } + /// numberRowsDropped. Number of rows gone + inline int numberRowsDropped() const { + return numberRowsDropped_; + } + /// reset numberRowsDropped and rowsDropped. + void resetRowsDropped(); + /// rowsDropped - which rows are gone + inline char * rowsDropped() const { + return rowsDropped_; + } + /// choleskyCondition. + inline double choleskyCondition() const { + return choleskyCondition_; + } + /// goDense i.e. use dense factoriaztion if > this (default 0.7). + inline double goDense() const { + return goDense_; + } + /// goDense i.e. use dense factoriaztion if > this (default 0.7). + inline void setGoDense(double value) { + goDense_ = value; + } + /// rank. Returns rank + inline int rank() const { + return numberRows_ - numberRowsDropped_; + } + /// Return number of rows + inline int numberRows() const { + return numberRows_; + } + /// Return size + inline CoinBigIndex size() const { + return sizeFactor_; + } + /// Return sparseFactor + inline longDouble * sparseFactor() const { + return sparseFactor_; + } + /// Return diagonal + inline longDouble * diagonal() const { + return diagonal_; + } + /// Return workDouble + inline longDouble * workDouble() const { + return workDouble_; + } + /// If KKT on + inline bool kkt() const { + return doKKT_; + } + /// Set KKT + inline void setKKT(bool yesNo) { + doKKT_ = yesNo; + } + /// Set integer parameter + inline void setIntegerParameter(int i, int value) { + integerParameters_[i] = value; + } + /// get integer parameter + inline int getIntegerParameter(int i) { + return integerParameters_[i]; + } + /// Set double parameter + inline void setDoubleParameter(int i, double value) { + doubleParameters_[i] = value; + } + /// get double parameter + inline double getDoubleParameter(int i) { + return doubleParameters_[i]; + } + //@} + + +public: + + /**@name Constructors, destructor + */ + //@{ + /** Constructor which has dense columns activated. + Default is off. */ + ClpCholeskyBase(int denseThreshold = -1); + /** Destructor (has to be public) */ + virtual ~ClpCholeskyBase(); + /// Copy + ClpCholeskyBase(const ClpCholeskyBase&); + /// Assignment + ClpCholeskyBase& operator=(const ClpCholeskyBase&); + //@} + //@{ + ///@name Other + /// Clone + virtual ClpCholeskyBase * clone() const; + + /// Returns type + inline int type() const { + if (doKKT_) return 100; + else return type_; + } +protected: + /// Sets type + inline void setType(int type) { + type_ = type; + } + /// model. + inline void setModel(ClpInterior * model) { + model_ = model; + } + //@} + + /**@name Symbolic, factor and solve */ + //@{ + /** Symbolic1 - works out size without clever stuff. + Uses upper triangular as much easier. + Returns size + */ + int symbolic1(const CoinBigIndex * Astart, const int * Arow); + /** Symbolic2 - Fills in indices + Uses lower triangular so can do cliques etc + */ + void symbolic2(const CoinBigIndex * Astart, const int * Arow); + /** Factorize - filling in rowsDropped and returning number dropped + in integerParam. + */ + void factorizePart2(int * rowsDropped) ; + /** solve - 1 just first half, 2 just second half - 3 both. + If 1 and 2 then diagonal has sqrt of inverse otherwise inverse + */ + void solve(CoinWorkDouble * region, int type); + /// Forms ADAT - returns nonzero if not enough memory + int preOrder(bool lowerTriangular, bool includeDiagonal, bool doKKT); + /// Updates dense part (broken out for profiling) + void updateDense(longDouble * d, /*longDouble * work,*/ int * first); + //@} + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// type (may be useful) if > 20 do KKT + int type_; + /// Doing full KKT (only used if default symbolic and factorization) + bool doKKT_; + /// Go dense at this fraction + double goDense_; + /// choleskyCondition. + double choleskyCondition_; + /// model. + ClpInterior * model_; + /// numberTrials. Number of trials before rejection + int numberTrials_; + /// numberRows. Number of Rows in factorization + int numberRows_; + /// status. Status of factorization + int status_; + /// rowsDropped + char * rowsDropped_; + /// permute inverse. + int * permuteInverse_; + /// main permute. + int * permute_; + /// numberRowsDropped. Number of rows gone + int numberRowsDropped_; + /// sparseFactor. + longDouble * sparseFactor_; + /// choleskyStart - element starts + CoinBigIndex * choleskyStart_; + /// choleskyRow (can be shorter than sparsefactor) + int * choleskyRow_; + /// Index starts + CoinBigIndex * indexStart_; + /// Diagonal + longDouble * diagonal_; + /// double work array + longDouble * workDouble_; + /// link array + int * link_; + // Integer work array + CoinBigIndex * workInteger_; + // Clique information + int * clique_; + /// sizeFactor. + CoinBigIndex sizeFactor_; + /// Size of index array + CoinBigIndex sizeIndex_; + /// First dense row + int firstDense_; + /// integerParameters + int integerParameters_[64]; + /// doubleParameters; + double doubleParameters_[64]; + /// Row copy of matrix + ClpMatrixBase * rowCopy_; + /// Dense indicators + char * whichDense_; + /// Dense columns (updated) + longDouble * denseColumn_; + /// Dense cholesky + ClpCholeskyDense * dense_; + /// Dense threshold (for taking out of Cholesky) + int denseThreshold_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpCholeskyDense.hpp b/thirdparty/linux/include/coin/ClpCholeskyDense.hpp new file mode 100644 index 0000000..d8428b6 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpCholeskyDense.hpp @@ -0,0 +1,162 @@ +/* $Id: ClpCholeskyDense.hpp 1910 2013-01-27 02:00:13Z stefan $ */ +/* + Copyright (C) 2003, International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef ClpCholeskyDense_H +#define ClpCholeskyDense_H + +#include "ClpCholeskyBase.hpp" +class ClpMatrixBase; + +class ClpCholeskyDense : public ClpCholeskyBase { + +public: + /**@name Virtual methods that the derived classes provides */ + /**@{*/ + /** Orders rows and saves pointer to matrix.and model. + Returns non-zero if not enough memory */ + virtual int order(ClpInterior * model) ; + /** Does Symbolic factorization given permutation. + This is called immediately after order. If user provides this then + user must provide factorize and solve. Otherwise the default factorization is used + returns non-zero if not enough memory */ + virtual int symbolic(); + /** Factorize - filling in rowsDropped and returning number dropped. + If return code negative then out of memory */ + virtual int factorize(const CoinWorkDouble * diagonal, int * rowsDropped) ; + /** Uses factorization to solve. */ + virtual void solve (CoinWorkDouble * region) ; + /**@}*/ + + /**@name Non virtual methods for ClpCholeskyDense */ + /**@{*/ + /** Reserves space. + If factor not NULL then just uses passed space + Returns non-zero if not enough memory */ + int reserveSpace(const ClpCholeskyBase * factor, int numberRows) ; + /** Returns space needed */ + CoinBigIndex space( int numberRows) const; + /** part 2 of Factorize - filling in rowsDropped */ + void factorizePart2(int * rowsDropped) ; + /** part 2 of Factorize - filling in rowsDropped - blocked */ + void factorizePart3(int * rowsDropped) ; + /** Forward part of solve */ + void solveF1(longDouble * a, int n, CoinWorkDouble * region); + void solveF2(longDouble * a, int n, CoinWorkDouble * region, CoinWorkDouble * region2); + /** Backward part of solve */ + void solveB1(longDouble * a, int n, CoinWorkDouble * region); + void solveB2(longDouble * a, int n, CoinWorkDouble * region, CoinWorkDouble * region2); + int bNumber(const longDouble * array, int &, int&); + /** A */ + inline longDouble * aMatrix() const { + return sparseFactor_; + } + /** Diagonal */ + inline longDouble * diagonal() const { + return diagonal_; + } + /**@}*/ + + + /**@name Constructors, destructor */ + /**@{*/ + /** Default constructor. */ + ClpCholeskyDense(); + /** Destructor */ + virtual ~ClpCholeskyDense(); + /** Copy */ + ClpCholeskyDense(const ClpCholeskyDense&); + /** Assignment */ + ClpCholeskyDense& operator=(const ClpCholeskyDense&); + /** Clone */ + virtual ClpCholeskyBase * clone() const ; + /**@}*/ + + +private: + /**@name Data members */ + /**@{*/ + /** Just borrowing space */ + bool borrowSpace_; + /**@}*/ +}; + +/* structure for C */ +typedef struct { + longDouble * diagonal_; + longDouble * a; + longDouble * work; + int * rowsDropped; + double doubleParameters_[1]; /* corresponds to 10 */ + int integerParameters_[2]; /* corresponds to 34, nThreads */ + int n; + int numberBlocks; +} ClpCholeskyDenseC; + +extern "C" { + void ClpCholeskySpawn(void *); +} +/**Non leaf recursive factor */ +void +ClpCholeskyCfactor(ClpCholeskyDenseC * thisStruct, + longDouble * a, int n, int numberBlocks, + longDouble * diagonal, longDouble * work, int * rowsDropped); + +/**Non leaf recursive triangle rectangle update */ +void +ClpCholeskyCtriRec(ClpCholeskyDenseC * thisStruct, + longDouble * aTri, int nThis, + longDouble * aUnder, longDouble * diagonal, + longDouble * work, + int nLeft, int iBlock, int jBlock, + int numberBlocks); +/**Non leaf recursive rectangle triangle update */ +void +ClpCholeskyCrecTri(ClpCholeskyDenseC * thisStruct, + longDouble * aUnder, int nTri, int nDo, + int iBlock, int jBlock, longDouble * aTri, + longDouble * diagonal, longDouble * work, + int numberBlocks); +/** Non leaf recursive rectangle rectangle update, + nUnder is number of rows in iBlock, + nUnderK is number of rows in kBlock +*/ +void +ClpCholeskyCrecRec(ClpCholeskyDenseC * thisStruct, + longDouble * above, int nUnder, int nUnderK, + int nDo, longDouble * aUnder, longDouble *aOther, + longDouble * work, + int iBlock, int jBlock, + int numberBlocks); +/**Leaf recursive factor */ +void +ClpCholeskyCfactorLeaf(ClpCholeskyDenseC * thisStruct, + longDouble * a, int n, + longDouble * diagonal, longDouble * work, + int * rowsDropped); +/**Leaf recursive triangle rectangle update */ +void +ClpCholeskyCtriRecLeaf(/*ClpCholeskyDenseC * thisStruct,*/ + longDouble * aTri, longDouble * aUnder, + longDouble * diagonal, longDouble * work, + int nUnder); +/**Leaf recursive rectangle triangle update */ +void +ClpCholeskyCrecTriLeaf(/*ClpCholeskyDenseC * thisStruct, */ + longDouble * aUnder, longDouble * aTri, + /*longDouble * diagonal,*/ longDouble * work, int nUnder); +/** Leaf recursive rectangle rectangle update, + nUnder is number of rows in iBlock, + nUnderK is number of rows in kBlock +*/ +void +ClpCholeskyCrecRecLeaf(/*ClpCholeskyDenseC * thisStruct, */ + const longDouble * COIN_RESTRICT above, + const longDouble * COIN_RESTRICT aUnder, + longDouble * COIN_RESTRICT aOther, + const longDouble * COIN_RESTRICT work, + int nUnder); +#endif diff --git a/thirdparty/linux/include/coin/ClpConfig.h b/thirdparty/linux/include/coin/ClpConfig.h new file mode 100644 index 0000000..f48e519 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpConfig.h @@ -0,0 +1,17 @@ +/* src/config_clp.h. Generated by configure. */ +/* src/config_clp.h.in. */ + +/* Define to 1, 2, 3, or 4 if Aboca should be build. */ +/* #undef CLP_HAS_ABC */ + +/* Version number of project */ +#define CLP_VERSION "1.16.9" + +/* Major Version number of project */ +#define CLP_VERSION_MAJOR 1 + +/* Minor Version number of project */ +#define CLP_VERSION_MINOR 16 + +/* Release Version number of project */ +#define CLP_VERSION_RELEASE 9 diff --git a/thirdparty/linux/include/coin/ClpConstraint.hpp b/thirdparty/linux/include/coin/ClpConstraint.hpp new file mode 100644 index 0000000..be43bb8 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpConstraint.hpp @@ -0,0 +1,125 @@ +/* $Id: ClpConstraint.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraint_H +#define ClpConstraint_H + + +//############################################################################# +class ClpSimplex; +class ClpModel; + +/** Constraint Abstract Base Class + +Abstract Base Class for describing a constraint or objective function + +*/ +class ClpConstraint { + +public: + + ///@name Stuff + //@{ + + /** Fills gradient. If Linear then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient undefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const = 0; + /// Constraint function value + virtual double functionValue (const ClpSimplex * model, + const double * solution, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) = 0; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) = 0; + /// Scale constraint + virtual void reallyScale(const double * columnScale) = 0; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which) const = 0; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const = 0; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraint(); + + /// Copy constructor + ClpConstraint(const ClpConstraint &); + + /// Assignment operator + ClpConstraint & operator=(const ClpConstraint& rhs); + + /// Destructor + virtual ~ClpConstraint (); + + /// Clone + virtual ClpConstraint * clone() const = 0; + + //@} + + ///@name Other + //@{ + /// Returns type, 0 linear, 1 nonlinear + inline int type() { + return type_; + } + /// Row number (-1 is objective) + inline int rowNumber() const { + return rowNumber_; + } + + /// Number of possible coefficients in gradient + virtual int numberCoefficients() const = 0; + + /// Stored constraint function value + inline double functionValue () const { + return functionValue_; + } + + /// Constraint offset + inline double offset () const { + return offset_; + } + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() {} + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Gradient at last evaluation + mutable double * lastGradient_; + /// Value of non-linear part of constraint + mutable double functionValue_; + /// Value of offset for constraint + mutable double offset_; + /// Type of constraint - linear is 1 + int type_; + /// Row number (-1 is objective) + int rowNumber_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpConstraintLinear.hpp b/thirdparty/linux/include/coin/ClpConstraintLinear.hpp new file mode 100644 index 0000000..fd0a4da --- /dev/null +++ b/thirdparty/linux/include/coin/ClpConstraintLinear.hpp @@ -0,0 +1,110 @@ +/* $Id: ClpConstraintLinear.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraintLinear_H +#define ClpConstraintLinear_H + +#include "ClpConstraint.hpp" + +//############################################################################# + +/** Linear Constraint Class + +*/ + +class ClpConstraintLinear : public ClpConstraint { + +public: + + ///@name Stuff + //@{ + + + /** Fills gradient. If Linear then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient udefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) ; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale constraint + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which) const ; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraintLinear(); + + /// Constructor from constraint + ClpConstraintLinear(int row, int numberCoefficients, int numberColumns, + const int * column, const double * element); + + /** Copy constructor . + */ + ClpConstraintLinear(const ClpConstraintLinear & rhs); + + /// Assignment operator + ClpConstraintLinear & operator=(const ClpConstraintLinear& rhs); + + /// Destructor + virtual ~ClpConstraintLinear (); + + /// Clone + virtual ClpConstraint * clone() const; + //@} + ///@name Gets and sets + //@{ + /// Number of coefficients + virtual int numberCoefficients() const; + /// Number of columns in linear constraint + inline int numberColumns() const { + return numberColumns_; + } + /// Columns + inline const int * column() const { + return column_; + } + /// Coefficients + inline const double * coefficient() const { + return coefficient_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Column + int * column_; + /// Coefficients + double * coefficient_; + /// Useful to have number of columns about + int numberColumns_; + /// Number of coefficients + int numberCoefficients_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpConstraintQuadratic.hpp b/thirdparty/linux/include/coin/ClpConstraintQuadratic.hpp new file mode 100644 index 0000000..2eff6cc --- /dev/null +++ b/thirdparty/linux/include/coin/ClpConstraintQuadratic.hpp @@ -0,0 +1,119 @@ +/* $Id: ClpConstraintQuadratic.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraintQuadratic_H +#define ClpConstraintQuadratic_H + +#include "ClpConstraint.hpp" + +//############################################################################# + +/** Quadratic Constraint Class + +*/ + +class ClpConstraintQuadratic : public ClpConstraint { + +public: + + ///@name Stuff + //@{ + + + /** Fills gradient. If Quadratic then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient udefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) ; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale constraint + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonquadratic columns to 1. + Returns number of nonquadratic columns + */ + virtual int markNonlinear(char * which) const ; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraintQuadratic(); + + /// Constructor from quadratic + ClpConstraintQuadratic(int row, int numberQuadraticColumns, int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element); + + /** Copy constructor . + */ + ClpConstraintQuadratic(const ClpConstraintQuadratic & rhs); + + /// Assignment operator + ClpConstraintQuadratic & operator=(const ClpConstraintQuadratic& rhs); + + /// Destructor + virtual ~ClpConstraintQuadratic (); + + /// Clone + virtual ClpConstraint * clone() const; + //@} + ///@name Gets and sets + //@{ + /// Number of coefficients + virtual int numberCoefficients() const; + /// Number of columns in constraint + inline int numberColumns() const { + return numberColumns_; + } + /// Column starts + inline CoinBigIndex * start() const { + return start_; + } + /// Columns + inline const int * column() const { + return column_; + } + /// Coefficients + inline const double * coefficient() const { + return coefficient_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Column starts + CoinBigIndex * start_; + /// Column (if -1 then linear coefficient) + int * column_; + /// Coefficients + double * coefficient_; + /// Useful to have number of columns about + int numberColumns_; + /// Number of coefficients in gradient + int numberCoefficients_; + /// Number of quadratic columns + int numberQuadraticColumns_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpDualRowDantzig.hpp b/thirdparty/linux/include/coin/ClpDualRowDantzig.hpp new file mode 100644 index 0000000..73b42b3 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpDualRowDantzig.hpp @@ -0,0 +1,71 @@ +/* $Id: ClpDualRowDantzig.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowDantzig_H +#define ClpDualRowDantzig_H + +#include "ClpDualRowPivot.hpp" + +//############################################################################# + +/** Dual Row Pivot Dantzig Algorithm Class + +This is simplest choice - choose largest infeasibility + +*/ + +class ClpDualRowDantzig : public ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow(); + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn); + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective); + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpDualRowDantzig(); + + /// Copy constructor + ClpDualRowDantzig(const ClpDualRowDantzig &); + + /// Assignment operator + ClpDualRowDantzig & operator=(const ClpDualRowDantzig& rhs); + + /// Destructor + virtual ~ClpDualRowDantzig (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpDualRowPivot.hpp b/thirdparty/linux/include/coin/ClpDualRowPivot.hpp new file mode 100644 index 0000000..f1f57a6 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpDualRowPivot.hpp @@ -0,0 +1,129 @@ +/* $Id: ClpDualRowPivot.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowPivot_H +#define ClpDualRowPivot_H + +class ClpSimplex; +class CoinIndexedVector; + +//############################################################################# + +/** Dual Row Pivot Abstract Base Class + +Abstract Base Class for describing an interface to an algorithm +to choose row pivot in dual simplex algorithm. For some algorithms +e.g. Dantzig choice then some functions may be null. + +*/ + +class ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow() = 0; + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn) = 0; + + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + Would be faster if we kept basic regions, but on other hand it + means everything is always in sync + */ + /* FIXME: this was pure virtul (=0). Why? */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective) = 0; + /** Saves any weights round factorization as pivot rows may change + Will be empty unless steepest edge (will save model) + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) for strong branching - initialize to 1 , infeasibilities + 6) scale back + 7) for strong branching - initialize full weights , infeasibilities + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// checks accuracy and may re-initialize (may be empty) + virtual void checkAccuracy(); + /// Gets rid of last update (may be empty) + virtual void unrollWeights(); + /// Gets rid of all arrays (may be empty) + virtual void clearArrays(); + /// Returns true if would not find any row + virtual bool looksOptimal() const { + return false; + } + /// Called when maximum pivots changes + virtual void maximumPivotsChanged() {} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpDualRowPivot(); + + /// Copy constructor + ClpDualRowPivot(const ClpDualRowPivot &); + + /// Assignment operator + ClpDualRowPivot & operator=(const ClpDualRowPivot& rhs); + + /// Destructor + virtual ~ClpDualRowPivot (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const = 0; + + //@} + + ///@name Other + //@{ + /// Returns model + inline ClpSimplex * model() { + return model_; + } + + /// Sets model (normally to NULL) + inline void setModel(ClpSimplex * newmodel) { + model_ = newmodel; + } + + /// Returns type (above 63 is extra information) + inline int type() { + return type_; + } + + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Pointer to model + ClpSimplex * model_; + /// Type of row pivot algorithm + int type_; + //@} +}; +#ifndef CLP_DUAL_COLUMN_MULTIPLIER +//#define CLP_DUAL_COLUMN_MULTIPLIER 0.99999 +#endif +#endif diff --git a/thirdparty/linux/include/coin/ClpDualRowSteepest.hpp b/thirdparty/linux/include/coin/ClpDualRowSteepest.hpp new file mode 100644 index 0000000..7e2cc62 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpDualRowSteepest.hpp @@ -0,0 +1,153 @@ +/* $Id: ClpDualRowSteepest.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowSteepest_H +#define ClpDualRowSteepest_H + +#include "ClpDualRowPivot.hpp" +class CoinIndexedVector; + + +//############################################################################# + +/** Dual Row Pivot Steepest Edge Algorithm Class + +See Forrest-Goldfarb paper for algorithm + +*/ + +class ClpDualRowSteepest : public ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow(); + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn); + + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective); + + /** Saves any weights round factorization as pivot rows may change + Save model + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) for strong branching - initialize (uninitialized) , infeasibilities + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// Pass in saved weights + void passInSavedWeights(const CoinIndexedVector * saved); + /// Get saved weights + inline CoinIndexedVector * savedWeights() + { return savedWeights_;} + /// Gets rid of last update + virtual void unrollWeights(); + /// Gets rid of all arrays + virtual void clearArrays(); + /// Returns true if would not find any row + virtual bool looksOptimal() const; + /// Called when maximum pivots changes + virtual void maximumPivotsChanged(); + //@} + + /** enums for persistence + */ + enum Persistence { + normal = 0x00, // create (if necessary) and destroy + keep = 0x01 // create (if necessary) and leave + }; + + ///@name Constructors and destructors + //@{ + /** Default Constructor + 0 is uninitialized, 1 full, 2 is partial uninitialized, + 3 starts as 2 but may switch to 1. + By partial is meant that the weights are updated as normal + but only part of the infeasible basic variables are scanned. + This can be faster on very easy problems. + */ + ClpDualRowSteepest(int mode = 3); + + /// Copy constructor + ClpDualRowSteepest(const ClpDualRowSteepest &); + + /// Assignment operator + ClpDualRowSteepest & operator=(const ClpDualRowSteepest& rhs); + + /// Fill most values + void fill(const ClpDualRowSteepest& rhs); + + /// Destructor + virtual ~ClpDualRowSteepest (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const; + + //@} + /**@name gets and sets */ + //@{ + /// Mode + inline int mode() const { + return mode_; + } + /// Set mode + inline void setMode(int mode) { + mode_ = mode; + } + /// Set/ get persistence + inline void setPersistence(Persistence life) { + persistence_ = life; + } + inline Persistence persistence() const { + return persistence_ ; + } +//@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /** Status + 0) Normal + -1) Needs initialization + 1) Weights are stored by sequence number + */ + int state_; + /** If 0 then we are using uninitialized weights, 1 then full, + if 2 then uninitialized partial, 3 switchable */ + int mode_; + /// Life of weights + Persistence persistence_; + /// weight array + double * weights_; + /// square of infeasibility array (just for infeasible rows) + CoinIndexedVector * infeasible_; + /// alternate weight array (so we can unroll) + CoinIndexedVector * alternateWeights_; + /// save weight array (so we can use checkpoint) + CoinIndexedVector * savedWeights_; + /// Dubious weights + int * dubiousWeights_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpDummyMatrix.hpp b/thirdparty/linux/include/coin/ClpDummyMatrix.hpp new file mode 100644 index 0000000..1b4a2d4 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpDummyMatrix.hpp @@ -0,0 +1,183 @@ +/* $Id: ClpDummyMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDummyMatrix_H +#define ClpDummyMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a dummy matrix as derived from ClpMatrixBase. + This is so you can do ClpPdco but may come in useful elsewhere. + It just has dimensions but no data +*/ + + +class ClpDummyMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return true; + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return numberElements_; + } + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const; + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in indDel. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in indDel. */ + virtual void deleteRows(const int numDel, const int * indDel); + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const {} + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return y + A * scalar *x in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return y + x * scalar * A in y. + @pre x must be of size numRows() + @pre y must be of size numColumns() */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + + using ClpMatrixBase::transposeTimes ; + /** Return x * scalar * A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x *A in z but + just for indices in y. + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + //@} + + /**@name Other */ + //@{ + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDummyMatrix(); + /// Constructor with data + ClpDummyMatrix(int numberColumns, int numberRows, + int numberElements); + /** Destructor */ + virtual ~ClpDummyMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDummyMatrix(const ClpDummyMatrix&); + /** The copy constructor from an CoinDummyMatrix. */ + ClpDummyMatrix(const CoinPackedMatrix&); + + ClpDummyMatrix& operator=(const ClpDummyMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// Number of elements + int numberElements_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpDynamicExampleMatrix.hpp b/thirdparty/linux/include/coin/ClpDynamicExampleMatrix.hpp new file mode 100644 index 0000000..81fe5ba --- /dev/null +++ b/thirdparty/linux/include/coin/ClpDynamicExampleMatrix.hpp @@ -0,0 +1,186 @@ +/* $Id: ClpDynamicExampleMatrix.hpp 1936 2013-04-09 10:29:27Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDynamicExampleMatrix_H +#define ClpDynamicExampleMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpDynamicMatrix.hpp" +class ClpSimplex; +/** This implements a dynamic matrix when we have a limit on the number of + "interesting rows". This version inherits from ClpDynamicMatrix and knows that + the real matrix is gub. This acts just like ClpDynamicMatrix but generates columns. + This "generates" columns by choosing from stored set. It is maent as a starting point + as to how you could use shortest path to generate columns. + + So it has its own copy of all data needed. It populates ClpDynamicWatrix with enough + to allow for gub keys and active variables. In turn ClpDynamicMatrix populates + a CoinPackedMatrix with active columns and rows. + + As there is one copy here and one in ClpDynamicmatrix these names end in Gen_ + + It is obviously more efficient to just use ClpDynamicMatrix but the ideas is to + show how much code a user would have to write. + + This does not work very well with bounds + +*/ + +class ClpDynamicExampleMatrix : public ClpDynamicMatrix { + +public: + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + + /** Creates a variable. This is called after partial pricing and will modify matrix. + Will update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /** If addColumn forces compression then this allows descendant to know what to do. + If >= then entry stayed in, if -1 then entry went out to lower bound.of zero. + Entries at upper bound (really nonzero) never go out (at present). + */ + virtual void packDown(const int * in, int numberToPack); + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDynamicExampleMatrix(); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + The contents of original matrix in model will be taken over and original matrix + will be sanitized so can be deleted (to avoid a very small memory leak) + */ + ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const int * startColumn, const int * row, + const double * element, const double * cost, + const double * columnLower = NULL, const double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL, + int numberIds = 0, const int *ids = NULL); +#if 0 + /// This constructor just takes over ownership (except for lower, upper) + ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets, + int numberColumns, int * starts, + const double * lower, const double * upper, + int * startColumn, int * row, + double * element, double * cost, + double * columnLower = NULL, double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL, + int numberIds = 0, const int *ids = NULL); +#endif + /** Destructor */ + virtual ~ClpDynamicExampleMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDynamicExampleMatrix(const ClpDynamicExampleMatrix&); + ClpDynamicExampleMatrix& operator=(const ClpDynamicExampleMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// Starts of each column + inline CoinBigIndex * startColumnGen() const { + return startColumnGen_; + } + /// rows + inline int * rowGen() const { + return rowGen_; + } + /// elements + inline double * elementGen() const { + return elementGen_; + } + /// costs + inline double * costGen() const { + return costGen_; + } + /// full starts + inline int * fullStartGen() const { + return fullStartGen_; + } + /// ids in next level matrix + inline int * idGen() const { + return idGen_; + } + /// Optional lower bounds on columns + inline double * columnLowerGen() const { + return columnLowerGen_; + } + /// Optional upper bounds on columns + inline double * columnUpperGen() const { + return columnUpperGen_; + } + /// size + inline int numberColumns() const { + return numberColumns_; + } + inline void setDynamicStatusGen(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatusGen_[sequence]; + st_byte = static_cast(st_byte & ~7); + st_byte = static_cast(st_byte | status); + } + inline DynamicStatus getDynamicStatusGen(int sequence) const { + return static_cast (dynamicStatusGen_[sequence] & 7); + } + /// Whether flagged + inline bool flaggedGen(int i) const { + return (dynamicStatusGen_[i] & 8) != 0; + } + inline void setFlaggedGen(int i) { + dynamicStatusGen_[i] = static_cast(dynamicStatusGen_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatusGen_[i] = static_cast(dynamicStatusGen_[i] & ~8); + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// size + int numberColumns_; + /// Starts of each column + CoinBigIndex * startColumnGen_; + /// rows + int * rowGen_; + /// elements + double * elementGen_; + /// costs + double * costGen_; + /// start of each set + int * fullStartGen_; + /// for status and which bound + unsigned char * dynamicStatusGen_; + /** identifier for each variable up one level (startColumn_, etc). This is + of length maximumGubColumns_. For this version it is just sequence number + at this level */ + int * idGen_; + /// Optional lower bounds on columns + double * columnLowerGen_; + /// Optional upper bounds on columns + double * columnUpperGen_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpDynamicMatrix.hpp b/thirdparty/linux/include/coin/ClpDynamicMatrix.hpp new file mode 100644 index 0000000..da4e144 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpDynamicMatrix.hpp @@ -0,0 +1,381 @@ +/* $Id: ClpDynamicMatrix.hpp 1755 2011-06-28 18:24:31Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDynamicMatrix_H +#define ClpDynamicMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpPackedMatrix.hpp" +class ClpSimplex; +/** This implements a dynamic matrix when we have a limit on the number of + "interesting rows". This version inherits from ClpPackedMatrix and knows that + the real matrix is gub. A later version could use shortest path to generate columns. + +*/ + +class ClpDynamicMatrix : public ClpPackedMatrix { + +public: + /// enums for status of various sorts + enum DynamicStatus { + soloKey = 0x00, + inSmall = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03 + }; + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big dynamic or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + + using ClpPackedMatrix::times ; + /** Return y + A * scalar *x in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + virtual void times(double scalar, + const double * x, double * y) const; + /// Modifies rhs offset + void modifyOffset(int sequence, double amount); + /// Gets key value when none in small + double keyValue(int iSet) const; + /** + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** Purely for column generation and similar ideas. Allows + matrix and any bounds or costs to be updated (sensibly). + Returns non-zero if any changes. + */ + virtual int refresh(ClpSimplex * model); + /** Creates a variable. This is called after partial pricing and will modify matrix. + Will update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /// Returns reduced cost of a variable + virtual double reducedCost( ClpSimplex * model, int sequence) const; + /// Does gub crash + void gubCrash(); + /// Writes out model (without names) + void writeMps(const char * name); + /// Populates initial matrix from dynamic status + void initialProblem(); + /** Adds in a column to gub structure (called from descendant) and returns sequence */ + int addColumn(int numberEntries, const int * row, const double * element, + double cost, double lower, double upper, int iSet, + DynamicStatus status); + /** If addColumn forces compression then this allows descendant to know what to do. + If >=0 then entry stayed in, if -1 then entry went out to lower bound.of zero. + Entries at upper bound (really nonzero) never go out (at present). + */ + virtual void packDown(const int * , int ) {} + /// Gets lower bound (to simplify coding) + inline double columnLower(int sequence) const { + if (columnLower_) return columnLower_[sequence]; + else return 0.0; + } + /// Gets upper bound (to simplify coding) + inline double columnUpper(int sequence) const { + if (columnUpper_) return columnUpper_[sequence]; + else return COIN_DBL_MAX; + } + + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDynamicMatrix(); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + The contents of original matrix in model will be taken over and original matrix + will be sanitized so can be deleted (to avoid a very small memory leak) + */ + ClpDynamicMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const CoinBigIndex * startColumn, const int * row, + const double * element, const double * cost, + const double * columnLower = NULL, const double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL); + + /** Destructor */ + virtual ~ClpDynamicMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDynamicMatrix(const ClpDynamicMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpDynamicMatrix(const CoinPackedMatrix&); + + ClpDynamicMatrix& operator=(const ClpDynamicMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// Status of row slacks + inline ClpSimplex::Status getStatus(int sequence) const { + return static_cast (status_[sequence] & 7); + } + inline void setStatus(int sequence, ClpSimplex::Status status) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast(st_byte & ~7); + st_byte = static_cast(st_byte | status); + } + /// Whether flagged slack + inline bool flaggedSlack(int i) const { + return (status_[i] & 8) != 0; + } + inline void setFlaggedSlack(int i) { + status_[i] = static_cast(status_[i] | 8); + } + inline void unsetFlaggedSlack(int i) { + status_[i] = static_cast(status_[i] & ~8); + } + /// Number of sets (dynamic rows) + inline int numberSets() const { + return numberSets_; + } + /// Number of possible gub variables + inline int numberGubEntries() const + { return startSet_[numberSets_];} + /// Sets + inline int * startSets() const + { return startSet_;} + /// Whether flagged + inline bool flagged(int i) const { + return (dynamicStatus_[i] & 8) != 0; + } + inline void setFlagged(int i) { + dynamicStatus_[i] = static_cast(dynamicStatus_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatus_[i] = static_cast(dynamicStatus_[i] & ~8); + } + inline void setDynamicStatus(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatus_[sequence]; + st_byte = static_cast(st_byte & ~7); + st_byte = static_cast(st_byte | status); + } + inline DynamicStatus getDynamicStatus(int sequence) const { + return static_cast (dynamicStatus_[sequence] & 7); + } + /// Saved value of objective offset + inline double objectiveOffset() const { + return objectiveOffset_; + } + /// Starts of each column + inline CoinBigIndex * startColumn() const { + return startColumn_; + } + /// rows + inline int * row() const { + return row_; + } + /// elements + inline double * element() const { + return element_; + } + /// costs + inline double * cost() const { + return cost_; + } + /// ids of active columns (just index here) + inline int * id() const { + return id_; + } + /// Optional lower bounds on columns + inline double * columnLower() const { + return columnLower_; + } + /// Optional upper bounds on columns + inline double * columnUpper() const { + return columnUpper_; + } + /// Lower bounds on sets + inline double * lowerSet() const { + return lowerSet_; + } + /// Upper bounds on sets + inline double * upperSet() const { + return upperSet_; + } + /// size + inline int numberGubColumns() const { + return numberGubColumns_; + } + /// first free + inline int firstAvailable() const { + return firstAvailable_; + } + /// first dynamic + inline int firstDynamic() const { + return firstDynamic_; + } + /// number of columns in dynamic model + inline int lastDynamic() const { + return lastDynamic_; + } + /// number of rows in original model + inline int numberStaticRows() const { + return numberStaticRows_; + } + /// size of working matrix (max) + inline int numberElements() const { + return numberElements_; + } + inline int * keyVariable() const { + return keyVariable_; + } + /// Switches off dj checking each factorization (for BIG models) + void switchOffCheck(); + /// Status region for gub slacks + inline unsigned char * gubRowStatus() const { + return status_; + } + /// Status region for gub variables + inline unsigned char * dynamicStatus() const { + return dynamicStatus_; + } + /// Returns which set a variable is in + int whichSet (int sequence) const; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Sum of dual infeasibilities + double sumDualInfeasibilities_; + /// Sum of primal infeasibilities + double sumPrimalInfeasibilities_; + /// Sum of Dual infeasibilities using tolerance based on error in duals + double sumOfRelaxedDualInfeasibilities_; + /// Sum of Primal infeasibilities using tolerance based on error in primals + double sumOfRelaxedPrimalInfeasibilities_; + /// Saved best dual on gub row in pricing + double savedBestGubDual_; + /// Saved best set in pricing + int savedBestSet_; + /// Backward pointer to pivot row !!! + int * backToPivotRow_; + /// Key variable of set (only accurate if none in small problem) + mutable int * keyVariable_; + /// Backward pointer to extra row + int * toIndex_; + // Reverse pointer from index to set + int * fromIndex_; + /// Number of sets (dynamic rows) + int numberSets_; + /// Number of active sets + int numberActiveSets_; + /// Saved value of objective offset + double objectiveOffset_; + /// Lower bounds on sets + double * lowerSet_; + /// Upper bounds on sets + double * upperSet_; + /// Status of slack on set + unsigned char * status_; + /// Pointer back to model + ClpSimplex * model_; + /// first free + int firstAvailable_; + /// first free when iteration started + int firstAvailableBefore_; + /// first dynamic + int firstDynamic_; + /// number of columns in dynamic model + int lastDynamic_; + /// number of rows in original model + int numberStaticRows_; + /// size of working matrix (max) + int numberElements_; + /// Number of dual infeasibilities + int numberDualInfeasibilities_; + /// Number of primal infeasibilities + int numberPrimalInfeasibilities_; + /** If pricing will declare victory (i.e. no check every factorization). + -1 - always check + 0 - don't check + 1 - in don't check mode but looks optimal + */ + int noCheck_; + /// Infeasibility weight when last full pass done + double infeasibilityWeight_; + /// size + int numberGubColumns_; + /// current maximum number of columns (then compress) + int maximumGubColumns_; + /// current maximum number of elemnts (then compress) + int maximumElements_; + /// Start of each set + int * startSet_; + /// next in chain + int * next_; + /// Starts of each column + CoinBigIndex * startColumn_; + /// rows + int * row_; + /// elements + double * element_; + /// costs + double * cost_; + /// ids of active columns (just index here) + int * id_; + /// for status and which bound + unsigned char * dynamicStatus_; + /// Optional lower bounds on columns + double * columnLower_; + /// Optional upper bounds on columns + double * columnUpper_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpEventHandler.hpp b/thirdparty/linux/include/coin/ClpEventHandler.hpp new file mode 100644 index 0000000..aeed324 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpEventHandler.hpp @@ -0,0 +1,187 @@ +/* $Id: ClpEventHandler.hpp 2156 2015-08-07 14:51:42Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpEventHandler_H +#define ClpEventHandler_H + +#include "ClpSimplex.hpp" +/** Base class for Clp event handling + +This is just here to allow for event handling. By event I mean a Clp event +e.g. end of values pass. + +One use would be to let a user handle a system event e.g. Control-C. This could be done +by deriving a class MyEventHandler which knows about such events. If one occurs +MyEventHandler::event() could clear event status and return 3 (stopped). + +Clp would then return to user code. + +As it is called every iteration this should be fine grained enough. + +User can derive and construct from CbcModel - not pretty + +*/ + +class ClpEventHandler { + +public: + /** enums for what sort of event. + + These will also be returned in ClpModel::secondaryStatus() as int + */ + enum Event { + endOfIteration = 100, // used to set secondary status + endOfFactorization, // after gutsOfSolution etc + endOfValuesPass, + node, // for Cbc + treeStatus, // for Cbc + solution, // for Cbc + theta, // hit in parametrics + pivotRow, // used to choose pivot row + presolveStart, // ClpSolve presolve start + presolveSize, // sees if ClpSolve presolve too big or too small + presolveInfeasible, // ClpSolve presolve infeasible + presolveBeforeSolve, // ClpSolve presolve before solve + presolveAfterFirstSolve, // ClpSolve presolve after solve + presolveAfterSolve, // ClpSolve presolve after solve + presolveEnd, // ClpSolve presolve end + goodFactorization, // before gutsOfSolution + complicatedPivotIn, // in modifyCoefficients + noCandidateInPrimal, // tentative end + looksEndInPrimal, // About to declare victory (or defeat) + endInPrimal, // Victory (or defeat) + beforeStatusOfProblemInPrimal, + startOfStatusOfProblemInPrimal, + complicatedPivotOut, // in modifyCoefficients + noCandidateInDual, // tentative end + looksEndInDual, // About to declare victory (or defeat) + endInDual, // Victory (or defeat) + beforeStatusOfProblemInDual, + startOfStatusOfProblemInDual, + startOfIterationInDual, + updateDualsInDual, + endOfCreateRim, + slightlyInfeasible, + modifyMatrixInMiniPresolve, + moreMiniPresolve, + modifyMatrixInMiniPostsolve, + startOfCrossover, // in Idiot + noTheta // At end (because no pivot) + }; + /**@name Virtual method that the derived classes should provide. + The base class instance does nothing and as event() is only useful method + it would not be very useful NOT providing one! + */ + //@{ + /** This can do whatever it likes. If return code -1 then carries on + if 0 sets ClpModel::status() to 5 (stopped by event) and will return to user. + At present if <-1 carries on and if >0 acts as if 0 - this may change. + For ClpSolve 2 -> too big return status of -2 and -> too small 3 + */ + virtual int event(Event whichEvent); + /** This can do whatever it likes. Return code -1 means no action. + This passes in something + */ + virtual int eventWithInfo(Event whichEvent, void * info) ; + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + ClpEventHandler(ClpSimplex * model = NULL); + /** Destructor */ + virtual ~ClpEventHandler(); + // Copy + ClpEventHandler(const ClpEventHandler&); + // Assignment + ClpEventHandler& operator=(const ClpEventHandler&); + /// Clone + virtual ClpEventHandler * clone() const; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setSimplex(ClpSimplex * model); + /// Get model + inline ClpSimplex * simplex() const { + return model_; + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to simplex + ClpSimplex * model_; + //@} +}; +/** Base class for Clp disaster handling + +This is here to allow for disaster handling. By disaster I mean that Clp +would otherwise give up + +*/ + +class ClpDisasterHandler { + +public: + /**@name Virtual methods that the derived classe should provide. + */ + //@{ + /// Into simplex + virtual void intoSimplex() = 0; + /// Checks if disaster + virtual bool check() const = 0; + /// saves information for next attempt + virtual void saveInfo() = 0; + /// Type of disaster 0 can fix, 1 abort + virtual int typeOfDisaster(); + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + ClpDisasterHandler(ClpSimplex * model = NULL); + /** Destructor */ + virtual ~ClpDisasterHandler(); + // Copy + ClpDisasterHandler(const ClpDisasterHandler&); + // Assignment + ClpDisasterHandler& operator=(const ClpDisasterHandler&); + /// Clone + virtual ClpDisasterHandler * clone() const = 0; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setSimplex(ClpSimplex * model); + /// Get model + inline ClpSimplex * simplex() const { + return model_; + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to simplex + ClpSimplex * model_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/ClpFactorization.hpp b/thirdparty/linux/include/coin/ClpFactorization.hpp new file mode 100644 index 0000000..dda8ff7 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpFactorization.hpp @@ -0,0 +1,432 @@ +/* $Id: ClpFactorization.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpFactorization_H +#define ClpFactorization_H + + +#include "CoinPragma.hpp" + +#include "CoinFactorization.hpp" +class ClpMatrixBase; +class ClpSimplex; +class ClpNetworkBasis; +class CoinOtherFactorization; +#ifndef CLP_MULTIPLE_FACTORIZATIONS +#define CLP_MULTIPLE_FACTORIZATIONS 4 +#endif +#ifdef CLP_MULTIPLE_FACTORIZATIONS +#include "CoinDenseFactorization.hpp" +#include "ClpSimplex.hpp" +#endif +#ifndef COIN_FAST_CODE +#define COIN_FAST_CODE +#endif +#ifndef CLP_FACTORIZATION_NEW_TIMING +#define CLP_FACTORIZATION_NEW_TIMING 1 +#endif + +/** This just implements CoinFactorization when an ClpMatrixBase object + is passed. If a network then has a dummy CoinFactorization and + a genuine ClpNetworkBasis object +*/ +class ClpFactorization +#ifndef CLP_MULTIPLE_FACTORIZATIONS + : public CoinFactorization +#endif +{ + + //friend class CoinFactorization; + +public: + /**@name factorization */ + //@{ + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + if increasingRows_ >1. + Allows scaling + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize (ClpSimplex * model, int solveType, bool valuesPass); + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpFactorization(); + /** Destructor */ + ~ClpFactorization(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor from an CoinFactorization. */ + ClpFactorization(const CoinFactorization&); + /** The copy constructor. */ + ClpFactorization(const ClpFactorization&, int denseIfSmaller = 0); +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /** The copy constructor from an CoinOtherFactorization. */ + ClpFactorization(const CoinOtherFactorization&); +#endif + ClpFactorization& operator=(const ClpFactorization&); + //@} + + /* **** below here is so can use networkish basis */ + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + int replaceColumn ( const ClpSimplex * model, + CoinIndexedVector * regionSparse, + CoinIndexedVector * tableauColumn, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying = false, + double acceptablePivot = 1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room + region1 starts as zero and is zero at end */ + int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2); + /** Updates one column (FTRAN) from region2 + region1 starts as zero and is zero at end */ + int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute = false) const; + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room. + Also updates region3 + region1 starts as zero and is zero at end */ + int updateTwoColumnsFT ( CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermuteRegion3 = false) ; + /// For debug (no statistics update) + int updateColumnForDebug ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute = false) const; + /** Updates one column (BTRAN) from region2 + region1 starts as zero and is zero at end */ + int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /**@name Lifted from CoinFactorization */ + //@{ + /// Total number of elements in factorization + inline int numberElements ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElements(); + else return coinFactorizationB_->numberElements() ; + } + /// Returns address of permute region + inline int *permute ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->permute(); + else return coinFactorizationB_->permute() ; + } + /// Returns address of pivotColumn region (also used for permuting) + inline int *pivotColumn ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivotColumn(); + else return coinFactorizationB_->permute() ; + } + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->maximumPivots(); + else return coinFactorizationB_->maximumPivots() ; + } + /// Set maximum number of pivots between factorizations + inline void maximumPivots ( int value) { + if (coinFactorizationA_) coinFactorizationA_->maximumPivots(value); + else coinFactorizationB_->maximumPivots(value); + } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivots(); + else return coinFactorizationB_->pivots() ; + } + /// Whether larger areas needed + inline double areaFactor ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->areaFactor(); + else return 0.0 ; + } + /// Set whether larger areas needed + inline void areaFactor ( double value) { + if (coinFactorizationA_) coinFactorizationA_->areaFactor(value); + } + /// Zero tolerance + inline double zeroTolerance ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->zeroTolerance(); + else return coinFactorizationB_->zeroTolerance() ; + } + /// Set zero tolerance + inline void zeroTolerance ( double value) { + if (coinFactorizationA_) coinFactorizationA_->zeroTolerance(value); + else coinFactorizationB_->zeroTolerance(value); + } + /// Set tolerances to safer of existing and given + void saferTolerances ( double zeroTolerance, double pivotTolerance); + /** get sparse threshold */ + inline int sparseThreshold ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->sparseThreshold(); + else return 0 ; + } + /** Set sparse threshold */ + inline void sparseThreshold ( int value) { + if (coinFactorizationA_) coinFactorizationA_->sparseThreshold(value); + } + /// Returns status + inline int status ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->status(); + else return coinFactorizationB_->status() ; + } + /// Sets status + inline void setStatus ( int value) { + if (coinFactorizationA_) coinFactorizationA_->setStatus(value); + else coinFactorizationB_->setStatus(value) ; + } + /// Returns number of dense rows + inline int numberDense() const { + if (coinFactorizationA_) return coinFactorizationA_->numberDense(); + else return 0 ; + } +#if 1 + /// Returns number in U area + inline CoinBigIndex numberElementsU ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsU(); + else return -1 ; + } + /// Returns number in L area + inline CoinBigIndex numberElementsL ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsL(); + else return -1 ; + } + /// Returns number in R area + inline CoinBigIndex numberElementsR ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsR(); + else return 0 ; + } +#endif + bool timeToRefactorize() const; +#if CLP_FACTORIZATION_NEW_TIMING>1 + void statsRefactor(char when) const; +#endif + /// Level of detail of messages + inline int messageLevel ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->messageLevel(); + else return 1 ; + } + /// Set level of detail of messages + inline void messageLevel ( int value) { + if (coinFactorizationA_) coinFactorizationA_->messageLevel(value); + } + /// Get rid of all memory + inline void clearArrays() { + if (coinFactorizationA_) + coinFactorizationA_->clearArrays(); + else if (coinFactorizationB_) + coinFactorizationB_->clearArrays(); + } + /// Number of Rows after factorization + inline int numberRows ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberRows(); + else return coinFactorizationB_->numberRows() ; + } + /// Gets dense threshold + inline int denseThreshold() const { + if (coinFactorizationA_) return coinFactorizationA_->denseThreshold(); + else return 0 ; + } + /// Sets dense threshold + inline void setDenseThreshold(int value) { + if (coinFactorizationA_) coinFactorizationA_->setDenseThreshold(value); + } + /// Pivot tolerance + inline double pivotTolerance ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivotTolerance(); + else if (coinFactorizationB_) return coinFactorizationB_->pivotTolerance(); + return 1.0e-8 ; + } + /// Set pivot tolerance + inline void pivotTolerance ( double value) { + if (coinFactorizationA_) coinFactorizationA_->pivotTolerance(value); + else if (coinFactorizationB_) coinFactorizationB_->pivotTolerance(value); + } + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) { + if (coinFactorizationA_) coinFactorizationA_->relaxAccuracyCheck(value); + } + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + inline int persistenceFlag() const { + if (coinFactorizationA_) return coinFactorizationA_->persistenceFlag(); + else return 0 ; + } + inline void setPersistenceFlag(int value) { + if (coinFactorizationA_) coinFactorizationA_->setPersistenceFlag(value); + } + /// Delete all stuff (leaves as after CoinFactorization()) + inline void almostDestructor() { + if (coinFactorizationA_) + coinFactorizationA_->almostDestructor(); + else if (coinFactorizationB_) + coinFactorizationB_->clearArrays(); + } + /// Returns areaFactor but adjusted for dense + inline double adjustedAreaFactor() const { + if (coinFactorizationA_) return coinFactorizationA_->adjustedAreaFactor(); + else return 0.0 ; + } + inline void setBiasLU(int value) { + if (coinFactorizationA_) coinFactorizationA_->setBiasLU(value); + } + /// true if Forrest Tomlin update, false if PFI + inline void setForrestTomlin(bool value) { + if (coinFactorizationA_) coinFactorizationA_->setForrestTomlin(value); + } + /// Sets default values + inline void setDefaultValues() { + if (coinFactorizationA_) { + // row activities have negative sign +#ifndef COIN_FAST_CODE + coinFactorizationA_->slackValue(-1.0); +#endif + coinFactorizationA_->zeroTolerance(1.0e-13); + } + } + /// If nonzero force use of 1,dense 2,small 3,osl + void forceOtherFactorization(int which); + /// Get switch to osl if number rows <= this + inline int goOslThreshold() const { + return goOslThreshold_; + } + /// Set switch to osl if number rows <= this + inline void setGoOslThreshold(int value) { + goOslThreshold_ = value; + } + /// Get switch to dense if number rows <= this + inline int goDenseThreshold() const { + return goDenseThreshold_; + } + /// Set switch to dense if number rows <= this + inline void setGoDenseThreshold(int value) { + goDenseThreshold_ = value; + } + /// Get switch to small if number rows <= this + inline int goSmallThreshold() const { + return goSmallThreshold_; + } + /// Set switch to small if number rows <= this + inline void setGoSmallThreshold(int value) { + goSmallThreshold_ = value; + } + /// Go over to dense or small code if small enough + void goDenseOrSmall(int numberRows) ; + /// Sets factorization + void setFactorization(ClpFactorization & factorization); + /// Return 1 if dense code + inline int isDenseOrSmall() const { + return coinFactorizationB_ ? 1 : 0; + } +#else + inline bool timeToRefactorize() const { + return (pivots() * 3 > maximumPivots() * 2 && + numberElementsR() * 3 > (numberElementsL() + numberElementsU()) * 2 + 1000 && + !numberDense()); + } + /// Sets default values + inline void setDefaultValues() { + // row activities have negative sign +#ifndef COIN_FAST_CODE + slackValue(-1.0); +#endif + zeroTolerance(1.0e-13); + } + /// Go over to dense code + inline void goDense() {} +#endif + //@} + + /**@name other stuff */ + //@{ + /** makes a row copy of L for speed and to allow very sparse problems */ + void goSparse(); + /// Cleans up i.e. gets rid of network basis + void cleanUp(); + /// Says whether to redo pivot order + bool needToReorder() const; +#ifndef SLIM_CLP + /// Says if a network basis + inline bool networkBasis() const { + return (networkBasis_ != NULL); + } +#else + /// Says if a network basis + inline bool networkBasis() const { + return false; + } +#endif + /// Fills weighted row list + void getWeights(int * weights) const; + //@} + +////////////////// data ////////////////// +private: + + /**@name data */ + //@{ + /// Pointer to network basis +#ifndef SLIM_CLP + ClpNetworkBasis * networkBasis_; +#endif +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /// Pointer to CoinFactorization + CoinFactorization * coinFactorizationA_; + /// Pointer to CoinOtherFactorization + CoinOtherFactorization * coinFactorizationB_; +#ifdef CLP_REUSE_ETAS + /// Pointer to model + ClpSimplex * model_; +#endif + /// If nonzero force use of 1,dense 2,small 3,osl + int forceB_; + /// Switch to osl if number rows <= this + int goOslThreshold_; + /// Switch to small if number rows <= this + int goSmallThreshold_; + /// Switch to dense if number rows <= this + int goDenseThreshold_; +#endif +#ifdef CLP_FACTORIZATION_NEW_TIMING + /// For guessing when to re-factorize + mutable double shortestAverage_; + mutable double totalInR_; + mutable double totalInIncreasingU_; + mutable int endLengthU_; + mutable int lastNumberPivots_; + mutable int effectiveStartNumberU_; +#endif + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpGubDynamicMatrix.hpp b/thirdparty/linux/include/coin/ClpGubDynamicMatrix.hpp new file mode 100644 index 0000000..2d13e6d --- /dev/null +++ b/thirdparty/linux/include/coin/ClpGubDynamicMatrix.hpp @@ -0,0 +1,247 @@ +/* $Id: ClpGubDynamicMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpGubDynamicMatrix_H +#define ClpGubDynamicMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpGubMatrix.hpp" +/** This implements Gub rows plus a ClpPackedMatrix. + This a dynamic version which stores the gub part and dynamically creates matrix. + All bounds are assumed to be zero and infinity + + This is just a simple example for real column generation +*/ + +class ClpGubDynamicMatrix : public ClpGubMatrix { + +public: + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /** This is local to Gub to allow synchronization: + mode=0 when status of basis is good + mode=1 when variable is flagged + mode=2 when all variables unflagged (returns number flagged) + mode=3 just reset costs (primal) + mode=4 correct number of dual infeasibilities + mode=5 return 4 if time to re-factorize + mode=8 - make sure set is clean + mode=9 - adjust lower, upper on set by incoming + */ + virtual int synchronize(ClpSimplex * model, int mode); + /// Sets up an effective RHS and does gub crash if needed + virtual void useEffectiveRhs(ClpSimplex * model, bool cheapest = true); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /// Add a new variable to a set + void insertNonBasic(int sequence, int iSet); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + + using ClpPackedMatrix::times ; + /** Return y + A * scalar *x in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + virtual void times(double scalar, + const double * x, double * y) const; + /** Just for debug + Returns sum and number of primal infeasibilities. Recomputes keys + */ + virtual int checkFeasible(ClpSimplex * model, double & sum) const; + /// Cleans data after setWarmStart + void cleanData(ClpSimplex * model); + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpGubDynamicMatrix(); + /** Destructor */ + virtual ~ClpGubDynamicMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpGubDynamicMatrix(const ClpGubDynamicMatrix&); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + */ + ClpGubDynamicMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const int * startColumn, const int * row, + const double * element, const double * cost, + const double * lowerColumn = NULL, const double * upperColumn = NULL, + const unsigned char * status = NULL); + + ClpGubDynamicMatrix& operator=(const ClpGubDynamicMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// enums for status of various sorts + enum DynamicStatus { + inSmall = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03 + }; + /// Whether flagged + inline bool flagged(int i) const { + return (dynamicStatus_[i] & 8) != 0; + } + inline void setFlagged(int i) { + dynamicStatus_[i] = static_cast(dynamicStatus_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatus_[i] = static_cast(dynamicStatus_[i] & ~8); + } + inline void setDynamicStatus(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatus_[sequence]; + st_byte = static_cast(st_byte & ~7); + st_byte = static_cast(st_byte | status); + } + inline DynamicStatus getDynamicStatus(int sequence) const { + return static_cast (dynamicStatus_[sequence] & 7); + } + /// Saved value of objective offset + inline double objectiveOffset() const { + return objectiveOffset_; + } + /// Starts of each column + inline CoinBigIndex * startColumn() const { + return startColumn_; + } + /// rows + inline int * row() const { + return row_; + } + /// elements + inline double * element() const { + return element_; + } + /// costs + inline double * cost() const { + return cost_; + } + /// full starts + inline int * fullStart() const { + return fullStart_; + } + /// ids of active columns (just index here) + inline int * id() const { + return id_; + } + /// Optional lower bounds on columns + inline double * lowerColumn() const { + return lowerColumn_; + } + /// Optional upper bounds on columns + inline double * upperColumn() const { + return upperColumn_; + } + /// Optional true lower bounds on sets + inline double * lowerSet() const { + return lowerSet_; + } + /// Optional true upper bounds on sets + inline double * upperSet() const { + return upperSet_; + } + /// size + inline int numberGubColumns() const { + return numberGubColumns_; + } + /// first free + inline int firstAvailable() const { + return firstAvailable_; + } + /// set first free + inline void setFirstAvailable(int value) { + firstAvailable_ = value; + } + /// first dynamic + inline int firstDynamic() const { + return firstDynamic_; + } + /// number of columns in dynamic model + inline int lastDynamic() const { + return lastDynamic_; + } + /// size of working matrix (max) + inline int numberElements() const { + return numberElements_; + } + /// Status region for gub slacks + inline unsigned char * gubRowStatus() const { + return status_; + } + /// Status region for gub variables + inline unsigned char * dynamicStatus() const { + return dynamicStatus_; + } + /// Returns which set a variable is in + int whichSet (int sequence) const; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Saved value of objective offset + double objectiveOffset_; + /// Starts of each column + CoinBigIndex * startColumn_; + /// rows + int * row_; + /// elements + double * element_; + /// costs + double * cost_; + /// full starts + int * fullStart_; + /// ids of active columns (just index here) + int * id_; + /// for status and which bound + unsigned char * dynamicStatus_; + /// Optional lower bounds on columns + double * lowerColumn_; + /// Optional upper bounds on columns + double * upperColumn_; + /// Optional true lower bounds on sets + double * lowerSet_; + /// Optional true upper bounds on sets + double * upperSet_; + /// size + int numberGubColumns_; + /// first free + int firstAvailable_; + /// saved first free + int savedFirstAvailable_; + /// first dynamic + int firstDynamic_; + /// number of columns in dynamic model + int lastDynamic_; + /// size of working matrix (max) + int numberElements_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpGubMatrix.hpp b/thirdparty/linux/include/coin/ClpGubMatrix.hpp new file mode 100644 index 0000000..26c3f62 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpGubMatrix.hpp @@ -0,0 +1,358 @@ +/* $Id: ClpGubMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpGubMatrix_H +#define ClpGubMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpPackedMatrix.hpp" +class ClpSimplex; +/** This implements Gub rows plus a ClpPackedMatrix. + + There will be a version using ClpPlusMinusOne matrix but + there is no point doing one with ClpNetworkMatrix (although + an embedded network is attractive). + +*/ + +class ClpGubMatrix : public ClpPackedMatrix { + +public: + /**@name Main functions provided */ + //@{ + /** Returns a new matrix in reverse order without gaps (GUB wants NULL) */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /// Returns number of hidden rows e.g. gub + virtual int hiddenRows() const; + //@} + + /**@name Matrix times vector methods */ + //@{ + + using ClpPackedMatrix::transposeTimes ; + /** Return x * scalar * A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x * scalar * A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x *A in z but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** expands an updated column to allow for extra rows which the main + solver does not know about and returns number added if mode 0. + If mode 1 deletes extra entries + + This active in Gub + */ + virtual int extendUpdated(ClpSimplex * model, CoinIndexedVector * update, int mode); + /** + mode=0 - Set up before "update" and "times" for primal solution using extended rows + mode=1 - Cleanup primal solution after "times" using extended rows. + mode=2 - Check (or report on) primal infeasibilities + */ + virtual void primalExpanded(ClpSimplex * model, int mode); + /** + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /// Sets up an effective RHS and does gub crash if needed + virtual void useEffectiveRhs(ClpSimplex * model, bool cheapest = true); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + /** This is local to Gub to allow synchronization: + mode=0 when status of basis is good + mode=1 when variable is flagged + mode=2 when all variables unflagged (returns number flagged) + mode=3 just reset costs (primal) + mode=4 correct number of dual infeasibilities + mode=5 return 4 if time to re-factorize + mode=6 - return 1 if there may be changing bounds on variable (column generation) + mode=7 - do extra restores for column generation + mode=8 - make sure set is clean + mode=9 - adjust lower, upper on set by incoming + */ + virtual int synchronize(ClpSimplex * model, int mode); + /// Correct sequence in and out to give true value + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpGubMatrix(); + /** Destructor */ + virtual ~ClpGubMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpGubMatrix(const ClpGubMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpGubMatrix(const CoinPackedMatrix&); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpGubMatrix (const ClpGubMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + ClpGubMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /** This takes over ownership (for space reasons) */ + ClpGubMatrix(CoinPackedMatrix * matrix); + + /** This takes over ownership (for space reasons) and is the + real constructor*/ + ClpGubMatrix(ClpPackedMatrix * matrix, int numberSets, + const int * start, const int * end, + const double * lower, const double * upper, + const unsigned char * status = NULL); + + ClpGubMatrix& operator=(const ClpGubMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /** redoes next_ for a set. */ + void redoSet(ClpSimplex * model, int newKey, int oldKey, int iSet); + //@} + /**@name gets and sets */ + //@{ + /// Status + inline ClpSimplex::Status getStatus(int sequence) const { + return static_cast (status_[sequence] & 7); + } + inline void setStatus(int sequence, ClpSimplex::Status status) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast(st_byte & ~7); + st_byte = static_cast(st_byte | status); + } + /// To flag a variable + inline void setFlagged( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 64); + } + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~64); + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + /// To say key is above ub + inline void setAbove( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast(iStat & ~24); + status_[sequence] = static_cast(iStat | 16); + } + /// To say key is feasible + inline void setFeasible( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast(iStat & ~24); + status_[sequence] = static_cast(iStat | 8); + } + /// To say key is below lb + inline void setBelow( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast(iStat & ~24); + status_[sequence] = iStat; + } + inline double weight( int sequence) const { + int iStat = status_[sequence] & 31; + iStat = iStat >> 3; + return static_cast (iStat - 1); + } + /// Starts + inline int * start() const { + return start_; + } + /// End + inline int * end() const { + return end_; + } + /// Lower bounds on sets + inline double * lower() const { + return lower_; + } + /// Upper bounds on sets + inline double * upper() const { + return upper_; + } + /// Key variable of set + inline int * keyVariable() const { + return keyVariable_; + } + /// Backward pointer to set number + inline int * backward() const { + return backward_; + } + /// Number of sets (gub rows) + inline int numberSets() const { + return numberSets_; + } + /// Switches off dj checking each factorization (for BIG models) + void switchOffCheck(); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Sum of dual infeasibilities + double sumDualInfeasibilities_; + /// Sum of primal infeasibilities + double sumPrimalInfeasibilities_; + /// Sum of Dual infeasibilities using tolerance based on error in duals + double sumOfRelaxedDualInfeasibilities_; + /// Sum of Primal infeasibilities using tolerance based on error in primals + double sumOfRelaxedPrimalInfeasibilities_; + /// Infeasibility weight when last full pass done + double infeasibilityWeight_; + /// Starts + int * start_; + /// End + int * end_; + /// Lower bounds on sets + double * lower_; + /// Upper bounds on sets + double * upper_; + /// Status of slacks + mutable unsigned char * status_; + /// Saved status of slacks + unsigned char * saveStatus_; + /// Saved key variables + int * savedKeyVariable_; + /// Backward pointer to set number + int * backward_; + /// Backward pointer to pivot row !!! + int * backToPivotRow_; + /// Change in costs for keys + double * changeCost_; + /// Key variable of set + mutable int * keyVariable_; + /** Next basic variable in set - starts at key and end with -(set+1). + Now changes to -(nonbasic+1). + next_ has extra space for 2* longest set */ + mutable int * next_; + /// Backward pointer to index in CoinIndexedVector + int * toIndex_; + // Reverse pointer from index to set + int * fromIndex_; + /// Pointer back to model + ClpSimplex * model_; + /// Number of dual infeasibilities + int numberDualInfeasibilities_; + /// Number of primal infeasibilities + int numberPrimalInfeasibilities_; + /** If pricing will declare victory (i.e. no check every factorization). + -1 - always check + 0 - don't check + 1 - in don't check mode but looks optimal + */ + int noCheck_; + /// Number of sets (gub rows) + int numberSets_; + /// Number in vector without gub extension + int saveNumber_; + /// Pivot row of possible next key + int possiblePivotKey_; + /// Gub slack in (set number or -1) + int gubSlackIn_; + /// First gub variables (same as start_[0] at present) + int firstGub_; + /// last gub variable (same as end_[numberSets_-1] at present) + int lastGub_; + /** type of gub - 0 not contiguous, 1 contiguous + add 8 bit to say no ubs on individual variables */ + int gubType_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpInterior.hpp b/thirdparty/linux/include/coin/ClpInterior.hpp new file mode 100644 index 0000000..7f87e1e --- /dev/null +++ b/thirdparty/linux/include/coin/ClpInterior.hpp @@ -0,0 +1,570 @@ +/* $Id: ClpInterior.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Tomlin (pdco) + John Forrest (standard predictor-corrector) + + Note JJF has added arrays - this takes more memory but makes + flow easier to understand and hopefully easier to extend + + */ +#ifndef ClpInterior_H +#define ClpInterior_H + +#include +#include +#include "ClpModel.hpp" +#include "ClpMatrixBase.hpp" +#include "ClpSolve.hpp" +#include "CoinDenseVector.hpp" +class ClpLsqr; +class ClpPdcoBase; +/// ******** DATA to be moved into protected section of ClpInterior +typedef struct { + double atolmin; + double r3norm; + double LSdamp; + double* deltay; +} Info; +/// ******** DATA to be moved into protected section of ClpInterior + +typedef struct { + double atolold; + double atolnew; + double r3ratio; + int istop; + int itncg; +} Outfo; +/// ******** DATA to be moved into protected section of ClpInterior + +typedef struct { + double gamma; + double delta; + int MaxIter; + double FeaTol; + double OptTol; + double StepTol; + double x0min; + double z0min; + double mu0; + int LSmethod; // 1=Cholesky 2=QR 3=LSQR + int LSproblem; // See below + int LSQRMaxIter; + double LSQRatol1; // Initial atol + double LSQRatol2; // Smallest atol (unless atol1 is smaller) + double LSQRconlim; + int wait; +} Options; +class Lsqr; +class ClpCholeskyBase; +// ***** END +/** This solves LPs using interior point methods + + It inherits from ClpModel and all its arrays are created at + algorithm time. + +*/ + +class ClpInterior : public ClpModel { + friend void ClpInteriorUnitTest(const std::string & mpsDir, + const std::string & netlibDir); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpInterior ( ); + + /// Copy constructor. + ClpInterior(const ClpInterior &); + /// Copy constructor from model. + ClpInterior(const ClpModel &); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + */ + ClpInterior (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true); + /// Assignment operator. This copies the data + ClpInterior & operator=(const ClpInterior & rhs); + /// Destructor + ~ClpInterior ( ); + // Ones below are just ClpModel with some changes + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • rowub: all rows have upper bound infinity +
  • rowlb: all rows have lower bound -infinity +
  • obj: all variables have 0 objective coefficient +
+ */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /** Borrow model. This is so we dont have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm. + This is same as ClpModel one. */ + void borrowModel(ClpModel & otherModel); + /** Return model - updates any scalars */ + void returnModel(ClpModel & otherModel); + //@} + + /**@name Functions most useful to user */ + //@{ + /** Pdco algorithm - see ClpPdco.hpp for method */ + int pdco(); + // ** Temporary version + int pdco( ClpPdcoBase * stuff, Options &options, Info &info, Outfo &outfo); + /// Primal-Dual Predictor-Corrector barrier + int primalDual(); + //@} + + /**@name most useful gets and sets */ + //@{ + /// If problem is primal feasible + inline bool primalFeasible() const { + return (sumPrimalInfeasibilities_ <= 1.0e-5); + } + /// If problem is dual feasible + inline bool dualFeasible() const { + return (sumDualInfeasibilities_ <= 1.0e-5); + } + /// Current (or last) algorithm + inline int algorithm() const { + return algorithm_; + } + /// Set algorithm + inline void setAlgorithm(int value) { + algorithm_ = value; + } + /// Sum of dual infeasibilities + inline CoinWorkDouble sumDualInfeasibilities() const { + return sumDualInfeasibilities_; + } + /// Sum of primal infeasibilities + inline CoinWorkDouble sumPrimalInfeasibilities() const { + return sumPrimalInfeasibilities_; + } + /// dualObjective. + inline CoinWorkDouble dualObjective() const { + return dualObjective_; + } + /// primalObjective. + inline CoinWorkDouble primalObjective() const { + return primalObjective_; + } + /// diagonalNorm + inline CoinWorkDouble diagonalNorm() const { + return diagonalNorm_; + } + /// linearPerturbation + inline CoinWorkDouble linearPerturbation() const { + return linearPerturbation_; + } + inline void setLinearPerturbation(CoinWorkDouble value) { + linearPerturbation_ = value; + } + /// projectionTolerance + inline CoinWorkDouble projectionTolerance() const { + return projectionTolerance_; + } + inline void setProjectionTolerance(CoinWorkDouble value) { + projectionTolerance_ = value; + } + /// diagonalPerturbation + inline CoinWorkDouble diagonalPerturbation() const { + return diagonalPerturbation_; + } + inline void setDiagonalPerturbation(CoinWorkDouble value) { + diagonalPerturbation_ = value; + } + /// gamma + inline CoinWorkDouble gamma() const { + return gamma_; + } + inline void setGamma(CoinWorkDouble value) { + gamma_ = value; + } + /// delta + inline CoinWorkDouble delta() const { + return delta_; + } + inline void setDelta(CoinWorkDouble value) { + delta_ = value; + } + /// ComplementarityGap + inline CoinWorkDouble complementarityGap() const { + return complementarityGap_; + } + //@} + + /**@name most useful gets and sets */ + //@{ + /// Largest error on Ax-b + inline CoinWorkDouble largestPrimalError() const { + return largestPrimalError_; + } + /// Largest error on basic duals + inline CoinWorkDouble largestDualError() const { + return largestDualError_; + } + /// Maximum iterations + inline int maximumBarrierIterations() const { + return maximumBarrierIterations_; + } + inline void setMaximumBarrierIterations(int value) { + maximumBarrierIterations_ = value; + } + /// Set cholesky (and delete present one) + void setCholesky(ClpCholeskyBase * cholesky); + /// Return number fixed to see if worth presolving + int numberFixed() const; + /** fix variables interior says should be. If reallyFix false then just + set values to exact bounds */ + void fixFixed(bool reallyFix = true); + /// Primal erturbation vector + inline CoinWorkDouble * primalR() const { + return primalR_; + } + /// Dual erturbation vector + inline CoinWorkDouble * dualR() const { + return dualR_; + } + //@} + +protected: + /**@name protected methods */ + //@{ + /// Does most of deletion + void gutsOfDelete(); + /// Does most of copying + void gutsOfCopy(const ClpInterior & rhs); + /// Returns true if data looks okay, false if not + bool createWorkingData(); + void deleteWorkingData(); + /// Sanity check on input rim data + bool sanityCheck(); + /// This does housekeeping + int housekeeping(); + //@} +public: + /**@name public methods */ + //@{ + /// Raw objective value (so always minimize) + inline CoinWorkDouble rawObjectiveValue() const { + return objectiveValue_; + } + /// Returns 1 if sequence indicates column + inline int isColumn(int sequence) const { + return sequence < numberColumns_ ? 1 : 0; + } + /// Returns sequence number within section + inline int sequenceWithin(int sequence) const { + return sequence < numberColumns_ ? sequence : sequence - numberColumns_; + } + /// Checks solution + void checkSolution(); + /** Modifies djs to allow for quadratic. + returns quadratic offset */ + CoinWorkDouble quadraticDjs(CoinWorkDouble * djRegion, const CoinWorkDouble * solution, + CoinWorkDouble scaleFactor); + + /// To say a variable is fixed + inline void setFixed( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 1) ; + } + inline void clearFixed( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~1) ; + } + inline bool fixed(int sequence) const { + return ((status_[sequence] & 1) != 0); + } + + /// To flag a variable + inline void setFlagged( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 2) ; + } + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~2) ; + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 2) != 0); + } + + /// To say a variable is fixed OR free + inline void setFixedOrFree( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 4) ; + } + inline void clearFixedOrFree( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~4) ; + } + inline bool fixedOrFree(int sequence) const { + return ((status_[sequence] & 4) != 0); + } + + /// To say a variable has lower bound + inline void setLowerBound( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 8) ; + } + inline void clearLowerBound( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~8) ; + } + inline bool lowerBound(int sequence) const { + return ((status_[sequence] & 8) != 0); + } + + /// To say a variable has upper bound + inline void setUpperBound( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 16) ; + } + inline void clearUpperBound( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~16) ; + } + inline bool upperBound(int sequence) const { + return ((status_[sequence] & 16) != 0); + } + + /// To say a variable has fake lower bound + inline void setFakeLower( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 32) ; + } + inline void clearFakeLower( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~32) ; + } + inline bool fakeLower(int sequence) const { + return ((status_[sequence] & 32) != 0); + } + + /// To say a variable has fake upper bound + inline void setFakeUpper( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 64) ; + } + inline void clearFakeUpper( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~64) ; + } + inline bool fakeUpper(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + //@} + +////////////////// data ////////////////// +protected: + + /**@name data. Many arrays have a row part and a column part. + There is a single array with both - columns then rows and + then normally two arrays pointing to rows and columns. The + single array is the owner of memory + */ + //@{ + /// Largest error on Ax-b + CoinWorkDouble largestPrimalError_; + /// Largest error on basic duals + CoinWorkDouble largestDualError_; + /// Sum of dual infeasibilities + CoinWorkDouble sumDualInfeasibilities_; + /// Sum of primal infeasibilities + CoinWorkDouble sumPrimalInfeasibilities_; + /// Worst complementarity + CoinWorkDouble worstComplementarity_; + /// +public: + CoinWorkDouble xsize_; + CoinWorkDouble zsize_; +protected: + /// Working copy of lower bounds (Owner of arrays below) + CoinWorkDouble * lower_; + /// Row lower bounds - working copy + CoinWorkDouble * rowLowerWork_; + /// Column lower bounds - working copy + CoinWorkDouble * columnLowerWork_; + /// Working copy of upper bounds (Owner of arrays below) + CoinWorkDouble * upper_; + /// Row upper bounds - working copy + CoinWorkDouble * rowUpperWork_; + /// Column upper bounds - working copy + CoinWorkDouble * columnUpperWork_; + /// Working copy of objective + CoinWorkDouble * cost_; +public: + /// Rhs + CoinWorkDouble * rhs_; + CoinWorkDouble * x_; + CoinWorkDouble * y_; + CoinWorkDouble * dj_; +protected: + /// Pointer to Lsqr object + ClpLsqr * lsqrObject_; + /// Pointer to stuff + ClpPdcoBase * pdcoStuff_; + /// Below here is standard barrier stuff + /// mu. + CoinWorkDouble mu_; + /// objectiveNorm. + CoinWorkDouble objectiveNorm_; + /// rhsNorm. + CoinWorkDouble rhsNorm_; + /// solutionNorm. + CoinWorkDouble solutionNorm_; + /// dualObjective. + CoinWorkDouble dualObjective_; + /// primalObjective. + CoinWorkDouble primalObjective_; + /// diagonalNorm. + CoinWorkDouble diagonalNorm_; + /// stepLength + CoinWorkDouble stepLength_; + /// linearPerturbation + CoinWorkDouble linearPerturbation_; + /// diagonalPerturbation + CoinWorkDouble diagonalPerturbation_; + // gamma from Saunders and Tomlin regularized + CoinWorkDouble gamma_; + // delta from Saunders and Tomlin regularized + CoinWorkDouble delta_; + /// targetGap + CoinWorkDouble targetGap_; + /// projectionTolerance + CoinWorkDouble projectionTolerance_; + /// maximumRHSError. maximum Ax + CoinWorkDouble maximumRHSError_; + /// maximumBoundInfeasibility. + CoinWorkDouble maximumBoundInfeasibility_; + /// maximumDualError. + CoinWorkDouble maximumDualError_; + /// diagonalScaleFactor. + CoinWorkDouble diagonalScaleFactor_; + /// scaleFactor. For scaling objective + CoinWorkDouble scaleFactor_; + /// actualPrimalStep + CoinWorkDouble actualPrimalStep_; + /// actualDualStep + CoinWorkDouble actualDualStep_; + /// smallestInfeasibility + CoinWorkDouble smallestInfeasibility_; + /// historyInfeasibility. +#define LENGTH_HISTORY 5 + CoinWorkDouble historyInfeasibility_[LENGTH_HISTORY]; + /// complementarityGap. + CoinWorkDouble complementarityGap_; + /// baseObjectiveNorm + CoinWorkDouble baseObjectiveNorm_; + /// worstDirectionAccuracy + CoinWorkDouble worstDirectionAccuracy_; + /// maximumRHSChange + CoinWorkDouble maximumRHSChange_; + /// errorRegion. i.e. Ax + CoinWorkDouble * errorRegion_; + /// rhsFixRegion. + CoinWorkDouble * rhsFixRegion_; + /// upperSlack + CoinWorkDouble * upperSlack_; + /// lowerSlack + CoinWorkDouble * lowerSlack_; + /// diagonal + CoinWorkDouble * diagonal_; + /// solution + CoinWorkDouble * solution_; + /// work array + CoinWorkDouble * workArray_; + /// delta X + CoinWorkDouble * deltaX_; + /// delta Y + CoinWorkDouble * deltaY_; + /// deltaZ. + CoinWorkDouble * deltaZ_; + /// deltaW. + CoinWorkDouble * deltaW_; + /// deltaS. + CoinWorkDouble * deltaSU_; + CoinWorkDouble * deltaSL_; + /// Primal regularization array + CoinWorkDouble * primalR_; + /// Dual regularization array + CoinWorkDouble * dualR_; + /// rhs B + CoinWorkDouble * rhsB_; + /// rhsU. + CoinWorkDouble * rhsU_; + /// rhsL. + CoinWorkDouble * rhsL_; + /// rhsZ. + CoinWorkDouble * rhsZ_; + /// rhsW. + CoinWorkDouble * rhsW_; + /// rhs C + CoinWorkDouble * rhsC_; + /// zVec + CoinWorkDouble * zVec_; + /// wVec + CoinWorkDouble * wVec_; + /// cholesky. + ClpCholeskyBase * cholesky_; + /// numberComplementarityPairs i.e. ones with lower and/or upper bounds (not fixed) + int numberComplementarityPairs_; + /// numberComplementarityItems_ i.e. number of active bounds + int numberComplementarityItems_; + /// Maximum iterations + int maximumBarrierIterations_; + /// gonePrimalFeasible. + bool gonePrimalFeasible_; + /// goneDualFeasible. + bool goneDualFeasible_; + /// Which algorithm being used + int algorithm_; + //@} +}; +//############################################################################# +/** A function that tests the methods in the ClpInterior class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. + + It also does some testing of ClpFactorization class + */ +void +ClpInteriorUnitTest(const std::string & mpsDir, + const std::string & netlibDir); + + +#endif diff --git a/thirdparty/linux/include/coin/ClpLinearObjective.hpp b/thirdparty/linux/include/coin/ClpLinearObjective.hpp new file mode 100644 index 0000000..ff035d4 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpLinearObjective.hpp @@ -0,0 +1,103 @@ +/* $Id: ClpLinearObjective.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpLinearObjective_H +#define ClpLinearObjective_H + +#include "ClpObjective.hpp" + +//############################################################################# + +/** Linear Objective Class + +*/ + +class ClpLinearObjective : public ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns objective coefficients. + + Offset is always set to 0.0. All other parameters unused. + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, double & offset, bool refresh, + int includeLinear = 2); + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts); + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj); + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const ; + /// Resize objective + virtual void resize(int newNumberColumns) ; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale objective + virtual void reallyScale(const double * columnScale) ; + + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpLinearObjective(); + + /// Constructor from objective + ClpLinearObjective(const double * objective, int numberColumns); + + /// Copy constructor + ClpLinearObjective(const ClpLinearObjective &); + /** Subset constructor. Duplicates are allowed + and order is as given. + */ + ClpLinearObjective (const ClpLinearObjective &rhs, int numberColumns, + const int * whichColumns) ; + + /// Assignment operator + ClpLinearObjective & operator=(const ClpLinearObjective& rhs); + + /// Destructor + virtual ~ClpLinearObjective (); + + /// Clone + virtual ClpObjective * clone() const; + /** Subset clone. Duplicates are allowed + and order is as given. + */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Objective + double * objective_; + /// number of columns + int numberColumns_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpMatrixBase.hpp b/thirdparty/linux/include/coin/ClpMatrixBase.hpp new file mode 100644 index 0000000..06dc523 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpMatrixBase.hpp @@ -0,0 +1,524 @@ +/* $Id: ClpMatrixBase.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpMatrixBase_H +#define ClpMatrixBase_H + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" + +#include "CoinPackedMatrix.hpp" +class CoinIndexedVector; +class ClpSimplex; +class ClpModel; +// Compilers can produce better code if they know about __restrict +#ifndef COIN_RESTRICT +#ifdef COIN_USE_RESTRICT +#define COIN_RESTRICT __restrict +#else +#define COIN_RESTRICT +#endif +#endif + +/** Abstract base class for Clp Matrices + +Since this class is abstract, no object of this type can be created. + +If a derived class provides all methods then all Clp algorithms +should work. Some can be very inefficient e.g. getElements etc is +only used for tightening bounds for dual and the copies are +deleted. Many methods can just be dummy i.e. abort(); if not +all features are being used. So if column generation was being done +then it makes no sense to do steepest edge so there would be +no point providing subsetTransposeTimes. +*/ + +class ClpMatrixBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const = 0; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const = 0; + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const = 0; + /** Number of columns. */ + virtual int getNumCols() const = 0; + /** Number of rows. */ + virtual int getNumRows() const = 0; + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const = 0; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const = 0; + + virtual const CoinBigIndex * getVectorStarts() const = 0; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const = 0 ; + /** The length of a single major-dimension vector. */ + virtual int getVectorLength(int index) const ; + /** Delete the columns whose indices are listed in indDel. */ + virtual void deleteCols(const int numDel, const int * indDel) = 0; + /** Delete the rows whose indices are listed in indDel. */ + virtual void deleteRows(const int numDel, const int * indDel) = 0; +#ifndef CLP_NO_VECTOR + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#endif + /** Modify one element of packed matrix. An element may be added. + This works for either ordering If the new element is zero it will be + deleted unless keepZero true */ + virtual void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false); + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); + + /** Returns a new matrix in reverse order without gaps + Is allowed to return NULL if doesn't want to have row copy */ + virtual ClpMatrixBase * reverseOrderedCopy() const { + return NULL; + } + + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic) = 0; + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element) = 0; + /** Creates scales for column copy (rowCopy in model may be modified) + default does not allow scaling + returns non-zero if no scaling done */ + virtual int scale(ClpModel * , const ClpSimplex * = NULL) const { + return 1; + } + /** Scales rowCopy if column copy scaled + Only called if scales already exist */ + virtual void scaleRowCopy(ClpModel * ) const { } + /// Returns true if can create row copy + virtual bool canGetRowCopy() const { + return true; + } + /** Realy really scales column copy + Only called if scales already exist. + Up to user to delete */ + inline virtual ClpMatrixBase * scaledColumnCopy(ClpModel * ) const { + return this->clone(); + } + + /** Checks if all elements are in valid range. Can just + return true if you are not paranoid. For Clp I will + probably expect no zeros. Code can modify matrix to get rid of + small elements. + check bits (can be turned off to save time) : + 1 - check if matrix has gaps + 2 - check if zero elements + 4 - check and compress duplicates + 8 - report on large and small + */ + virtual bool allElementsInRange(ClpModel * , + double , double , + int = 15) { + return true; + } + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + If returns zeros then can't tell anything */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const = 0; + /** Unpacks a column into an CoinIndexedvector + ** in packed format + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const = 0; + /** Purely for column generation and similar ideas. Allows + matrix and any bounds or costs to be updated (sensibly). + Returns non-zero if any changes. + */ + virtual int refresh(ClpSimplex * ) { + return 0; + } + + // Really scale matrix + virtual void reallyScale(const double * rowScale, const double * columnScale); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + Default returns vector of ones + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const = 0; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const = 0; + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const = 0; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Returns number of hidden rows e.g. gub + virtual int hiddenRows() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /** expands an updated column to allow for extra rows which the main + solver does not know about and returns number added. + + This will normally be a no-op - it is in for GUB but may get extended to + general non-overlapping and embedded networks. + + mode 0 - extend + mode 1 - delete etc + */ + virtual int extendUpdated(ClpSimplex * model, CoinIndexedVector * update, int mode); + /** + utility primal function for dealing with dynamic constraints + mode=0 - Set up before "update" and "times" for primal solution using extended rows + mode=1 - Cleanup primal solution after "times" using extended rows. + mode=2 - Check (or report on) primal infeasibilities + */ + virtual void primalExpanded(ClpSimplex * model, int mode); + /** + utility dual function for dealing with dynamic constraints + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + general utility function for dealing with dynamic constraints + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs and bounds + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /** Creates a variable. This is called after partial pricing and may modify matrix. + May update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /** Just for debug if odd type matrix. + Returns number of primal infeasibilities. */ + virtual int checkFeasible(ClpSimplex * model, double & sum) const ; + /// Returns reduced cost of a variable + double reducedCost(ClpSimplex * model, int sequence) const; + /// Correct sequence in and out to give true value (if both -1 maybe do whole matrix) + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} + + //--------------------------------------------------------------------------- + /**@name Matrix times vector methods + They can be faster if scalar is +- 1 + Also for simplex I am not using basic/non-basic split */ + //@{ + /** Return y + A * x * scalar in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + virtual void times(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y) const = 0; + /** And for scaling - default aborts for when scaling not supported + (unless pointers NULL when as normal) + */ + virtual void times(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y, + const double * COIN_RESTRICT rowScale, + const double * COIN_RESTRICT columnScale) const; + /** Return y + x * scalar * A in y. + @pre x must be of size numRows() + @pre y must be of size numColumns() */ + virtual void transposeTimes(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y) const = 0; + /** And for scaling - default aborts for when scaling not supported + (unless pointers NULL when as normal) + */ + virtual void transposeTimes(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y, + const double * COIN_RESTRICT rowScale, + const double * COIN_RESTRICT columnScale, + double * COIN_RESTRICT spare = NULL) const; +#if COIN_LONG_WORK + // For long double versions (aborts if not supported) + virtual void times(CoinWorkDouble scalar, + const CoinWorkDouble * COIN_RESTRICT x, CoinWorkDouble * COIN_RESTRICT y) const ; + virtual void transposeTimes(CoinWorkDouble scalar, + const CoinWorkDouble * COIN_RESTRICT x, CoinWorkDouble * COIN_RESTRICT y) const ; +#endif + /** Return x * scalar *A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const = 0; + /** Return x *A in z but + just for indices in y. + This is only needed for primal steepest edge. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const = 0; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * , + const CoinIndexedVector * ) const { + return false; + } + /// Updates two arrays for steepest and does devex weights (need not be coded) + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights (need not be coded) + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /** Return x *A in z but + just for number indices in y. + Default cheats with fake CoinIndexedVector and + then calls subsetTransposeTimes */ + virtual void listTransposeTimes(const ClpSimplex * model, + double * x, + int * y, + int number, + double * z) const; + //@} + //@{ + ///@name Other + /// Clone + virtual ClpMatrixBase * clone() const = 0; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given. + Derived classes need not provide this as it may not always make + sense */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const; + /// Gets rid of any mutable by products + virtual void backToBasics() {} + /** Returns type. + The types which code may need to know about are: + 1 - ClpPackedMatrix + 11 - ClpNetworkMatrix + 12 - ClpPlusMinusOneMatrix + */ + inline int type() const { + return type_; + } + /// Sets type + void setType(int newtype) { + type_ = newtype; + } + /// Sets up an effective RHS + void useEffectiveRhs(ClpSimplex * model); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + /// If rhsOffset used this is iteration last refreshed + inline int lastRefresh() const { + return lastRefresh_; + } + /// If rhsOffset used this is refresh frequency (0==off) + inline int refreshFrequency() const { + return refreshFrequency_; + } + inline void setRefreshFrequency(int value) { + refreshFrequency_ = value; + } + /// whether to skip dual checks most of time + inline bool skipDualCheck() const { + return skipDualCheck_; + } + inline void setSkipDualCheck(bool yes) { + skipDualCheck_ = yes; + } + /** Partial pricing tuning parameter - minimum number of "objects" to scan. + e.g. number of Gub sets but could be number of variables */ + inline int minimumObjectsScan() const { + return minimumObjectsScan_; + } + inline void setMinimumObjectsScan(int value) { + minimumObjectsScan_ = value; + } + /// Partial pricing tuning parameter - minimum number of negative reduced costs to get + inline int minimumGoodReducedCosts() const { + return minimumGoodReducedCosts_; + } + inline void setMinimumGoodReducedCosts(int value) { + minimumGoodReducedCosts_ = value; + } + /// Current start of search space in matrix (as fraction) + inline double startFraction() const { + return startFraction_; + } + inline void setStartFraction(double value) { + startFraction_ = value; + } + /// Current end of search space in matrix (as fraction) + inline double endFraction() const { + return endFraction_; + } + inline void setEndFraction(double value) { + endFraction_ = value; + } + /// Current best reduced cost + inline double savedBestDj() const { + return savedBestDj_; + } + inline void setSavedBestDj(double value) { + savedBestDj_ = value; + } + /// Initial number of negative reduced costs wanted + inline int originalWanted() const { + return originalWanted_; + } + inline void setOriginalWanted(int value) { + originalWanted_ = value; + } + /// Current number of negative reduced costs which we still need + inline int currentWanted() const { + return currentWanted_; + } + inline void setCurrentWanted(int value) { + currentWanted_ = value; + } + /// Current best sequence + inline int savedBestSequence() const { + return savedBestSequence_; + } + inline void setSavedBestSequence(int value) { + savedBestSequence_ = value; + } + //@} + + +protected: + + /**@name Constructors, destructor
+ NOTE: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + ClpMatrixBase(); + /** Destructor (has to be public) */ +public: + virtual ~ClpMatrixBase(); +protected: + // Copy + ClpMatrixBase(const ClpMatrixBase&); + // Assignment + ClpMatrixBase& operator=(const ClpMatrixBase&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /** Effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive */ + double * rhsOffset_; + /// Current start of search space in matrix (as fraction) + double startFraction_; + /// Current end of search space in matrix (as fraction) + double endFraction_; + /// Best reduced cost so far + double savedBestDj_; + /// Initial number of negative reduced costs wanted + int originalWanted_; + /// Current number of negative reduced costs which we still need + int currentWanted_; + /// Saved best sequence in pricing + int savedBestSequence_; + /// type (may be useful) + int type_; + /// If rhsOffset used this is iteration last refreshed + int lastRefresh_; + /// If rhsOffset used this is refresh frequency (0==off) + int refreshFrequency_; + /// Partial pricing tuning parameter - minimum number of "objects" to scan + int minimumObjectsScan_; + /// Partial pricing tuning parameter - minimum number of negative reduced costs to get + int minimumGoodReducedCosts_; + /// True sequence in (i.e. from larger problem) + int trueSequenceIn_; + /// True sequence out (i.e. from larger problem) + int trueSequenceOut_; + /// whether to skip dual checks most of time + bool skipDualCheck_; + //@} +}; +// bias for free variables +#define FREE_BIAS 1.0e1 +// Acceptance criteria for free variables +#define FREE_ACCEPT 1.0e2 + +#endif diff --git a/thirdparty/linux/include/coin/ClpMessage.hpp b/thirdparty/linux/include/coin/ClpMessage.hpp new file mode 100644 index 0000000..5eb3653 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpMessage.hpp @@ -0,0 +1,131 @@ +/* $Id: ClpMessage.hpp 1926 2013-03-26 15:23:38Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpMessage_H +#define ClpMessage_H + + +#include "CoinPragma.hpp" +#include + +// This deals with Clp messages (as against Osi messages etc) + +#include "CoinMessageHandler.hpp" +enum CLP_Message { + CLP_SIMPLEX_FINISHED, + CLP_SIMPLEX_INFEASIBLE, + CLP_SIMPLEX_UNBOUNDED, + CLP_SIMPLEX_STOPPED, + CLP_SIMPLEX_ERROR, + CLP_SIMPLEX_INTERRUPT, + CLP_SIMPLEX_STATUS, + CLP_DUAL_BOUNDS, + CLP_SIMPLEX_ACCURACY, + CLP_SIMPLEX_BADFACTOR, + CLP_SIMPLEX_BOUNDTIGHTEN, + CLP_SIMPLEX_INFEASIBILITIES, + CLP_SIMPLEX_FLAG, + CLP_SIMPLEX_GIVINGUP, + CLP_DUAL_CHECKB, + CLP_DUAL_ORIGINAL, + CLP_SIMPLEX_PERTURB, + CLP_PRIMAL_ORIGINAL, + CLP_PRIMAL_WEIGHT, + CLP_PRIMAL_OPTIMAL, + CLP_SINGULARITIES, + CLP_MODIFIEDBOUNDS, + CLP_RIMSTATISTICS1, + CLP_RIMSTATISTICS2, + CLP_RIMSTATISTICS3, + CLP_POSSIBLELOOP, + CLP_SMALLELEMENTS, + CLP_DUPLICATEELEMENTS, + CLP_SIMPLEX_HOUSE1, + CLP_SIMPLEX_HOUSE2, + CLP_SIMPLEX_NONLINEAR, + CLP_SIMPLEX_FREEIN, + CLP_SIMPLEX_PIVOTROW, + CLP_DUAL_CHECK, + CLP_PRIMAL_DJ, + CLP_PACKEDSCALE_INITIAL, + CLP_PACKEDSCALE_WHILE, + CLP_PACKEDSCALE_FINAL, + CLP_PACKEDSCALE_FORGET, + CLP_INITIALIZE_STEEP, + CLP_UNABLE_OPEN, + CLP_BAD_BOUNDS, + CLP_BAD_MATRIX, + CLP_LOOP, + CLP_IMPORT_RESULT, + CLP_IMPORT_ERRORS, + CLP_EMPTY_PROBLEM, + CLP_CRASH, + CLP_END_VALUES_PASS, + CLP_QUADRATIC_BOTH, + CLP_QUADRATIC_PRIMAL_DETAILS, + CLP_IDIOT_ITERATION, + CLP_INFEASIBLE, + CLP_MATRIX_CHANGE, + CLP_TIMING, + CLP_INTERVAL_TIMING, + CLP_SPRINT, + CLP_BARRIER_ITERATION, + CLP_BARRIER_OBJECTIVE_GAP, + CLP_BARRIER_GONE_INFEASIBLE, + CLP_BARRIER_CLOSE_TO_OPTIMAL, + CLP_BARRIER_COMPLEMENTARITY, + CLP_BARRIER_EXIT2, + CLP_BARRIER_STOPPING, + CLP_BARRIER_EXIT, + CLP_BARRIER_SCALING, + CLP_BARRIER_MU, + CLP_BARRIER_INFO, + CLP_BARRIER_END, + CLP_BARRIER_ACCURACY, + CLP_BARRIER_SAFE, + CLP_BARRIER_NEGATIVE_GAPS, + CLP_BARRIER_REDUCING, + CLP_BARRIER_DIAGONAL, + CLP_BARRIER_SLACKS, + CLP_BARRIER_DUALINF, + CLP_BARRIER_KILLED, + CLP_BARRIER_ABS_DROPPED, + CLP_BARRIER_ABS_ERROR, + CLP_BARRIER_FEASIBLE, + CLP_BARRIER_STEP, + CLP_BARRIER_KKT, + CLP_RIM_SCALE, + CLP_SLP_ITER, + CLP_COMPLICATED_MODEL, + CLP_BAD_STRING_VALUES, + CLP_CRUNCH_STATS, + CLP_PARAMETRICS_STATS, + CLP_PARAMETRICS_STATS2, +#ifndef NO_FATHOM_PRINT + CLP_FATHOM_STATUS, + CLP_FATHOM_SOLUTION, + CLP_FATHOM_FINISH, +#endif + CLP_GENERAL, + CLP_GENERAL2, + CLP_GENERAL_WARNING, + CLP_DUMMY_END +}; + +/** This deals with Clp messages (as against Osi messages etc) + */ +class ClpMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /** Constructor */ + ClpMessage(Language language = us_en); + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpModel.hpp b/thirdparty/linux/include/coin/ClpModel.hpp new file mode 100644 index 0000000..4a22539 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpModel.hpp @@ -0,0 +1,1307 @@ +/* $Id: ClpModel.hpp 2074 2014-12-10 09:43:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpModel_H +#define ClpModel_H + +#include "ClpConfig.h" + +#include +#include +#include +#include +#include +//#ifndef COIN_USE_CLP +//#define COIN_USE_CLP +//#endif +#include "ClpPackedMatrix.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinTypes.hpp" +#include "CoinFinite.hpp" +#include "ClpParameters.hpp" +#include "ClpObjective.hpp" +class ClpEventHandler; +/** This is the base class for Linear and quadratic Models + This knows nothing about the algorithm, but it seems to + have a reasonable amount of information + + I would welcome suggestions for what should be in this and + how it relates to OsiSolverInterface. Some methods look + very similar. + +*/ +class CoinBuild; +class CoinModel; +class ClpModel { + +public: + + /**@name Constructors and destructor + Note - copy methods copy ALL data so can chew up memory + until other copy is freed + */ + //@{ + /// Default constructor + ClpModel (bool emptyMessages = false ); + + /** Copy constructor. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 auto-but-as-initialSolve-in-bab + */ + ClpModel(const ClpModel & rhs, int scalingMode = -1); + /// Assignment operator. This copies the data + ClpModel & operator=(const ClpModel & rhs); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + */ + ClpModel (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true); + /// Destructor + ~ClpModel ( ); + //@} + + /**@name Load model - loads some stuff and initializes others */ + //@{ + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • rowub: all rows have upper bound infinity +
  • rowlb: all rows have lower bound -infinity +
  • obj: all variables have 0 objective coefficient +
+ */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** This loads a model from a coinModel object - returns number of errors. + + modelObject not const as may be changed as part of process + If tryPlusMinusOne then will try adding as +-1 matrix + */ + int loadProblem ( CoinModel & modelObject, bool tryPlusMinusOne = false); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** Load up quadratic objective. This is stored as a CoinPackedMatrix */ + void loadQuadraticObjective(const int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element); + void loadQuadraticObjective ( const CoinPackedMatrix& matrix); + /// Get rid of quadratic objective + void deleteQuadraticObjective(); + /// This just loads up a row objective + void setRowObjective(const double * rowObjective); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /// Read GMPL files from the given filenames + int readGMPL(const char *filename, const char * dataName, + bool keepNames = false); + /// Copy in integer informations + void copyInIntegerInformation(const char * information); + /// Drop integer informations + void deleteIntegerInformation(); + /** Set the index-th variable to be a continuous variable */ + void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + void setInteger(int index); + /** Return true if the index-th variable is an integer variable */ + bool isInteger(int index) const; + /// Resizes rim part of model + void resize (int newNumberRows, int newNumberColumns); + /// Deletes rows + void deleteRows(int number, const int * which); + /// Add one row + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower = -COIN_DBL_MAX, + double rowUpper = COIN_DBL_MAX); + /// Add rows + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinBigIndex * rowStarts, const int * columns, + const double * elements); + /// Add rows + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinBigIndex * rowStarts, const int * rowLengths, + const int * columns, + const double * elements); +#ifndef CLP_NO_VECTOR + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinPackedVectorBase * const * rows); +#endif + /** Add rows from a build object. + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + Returns number of errors e.g. duplicates + */ + int addRows(const CoinBuild & buildObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /** Add rows from a model object. returns + -1 if object in bad state (i.e. has column information) + otherwise number of errors. + + modelObject non const as can be regularized as part of build + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + */ + int addRows(CoinModel & modelObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + + /// Deletes columns + void deleteColumns(int number, const int * which); + /// Deletes rows AND columns (keeps old sizes) + void deleteRowsAndColumns(int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + /// Add one column + void addColumn(int numberInColumn, + const int * rows, + const double * elements, + double columnLower = 0.0, + double columnUpper = COIN_DBL_MAX, + double objective = 0.0); + /// Add columns + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinBigIndex * columnStarts, const int * rows, + const double * elements); + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinBigIndex * columnStarts, const int * columnLengths, + const int * rows, + const double * elements); +#ifndef CLP_NO_VECTOR + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinPackedVectorBase * const * columns); +#endif + /** Add columns from a build object + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + Returns number of errors e.g. duplicates + */ + int addColumns(const CoinBuild & buildObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /** Add columns from a model object. returns + -1 if object in bad state (i.e. has row information) + otherwise number of errors + modelObject non const as can be regularized as part of build + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + */ + int addColumns(CoinModel & modelObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /// Modify one element of a matrix + inline void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false) { + matrix_->modifyCoefficient(row, column, newElement, keepZero); + } + /** Change row lower bounds */ + void chgRowLower(const double * rowLower); + /** Change row upper bounds */ + void chgRowUpper(const double * rowUpper); + /** Change column lower bounds */ + void chgColumnLower(const double * columnLower); + /** Change column upper bounds */ + void chgColumnUpper(const double * columnUpper); + /** Change objective coefficients */ + void chgObjCoefficients(const double * objIn); + /** Borrow model. This is so we don't have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm */ + void borrowModel(ClpModel & otherModel); + /** Return model - nulls all arrays so can be deleted safely + also updates any scalars */ + void returnModel(ClpModel & otherModel); + + /// Create empty ClpPackedMatrix + void createEmptyMatrix(); + /** Really clean up matrix (if ClpPackedMatrix). + a) eliminate all duplicate AND small elements in matrix + b) remove all gaps and set extraGap_ and extraMajor_ to 0.0 + c) reallocate arrays and make max lengths equal to lengths + d) orders elements + returns number of elements eliminated or -1 if not ClpPackedMatrix + */ + int cleanMatrix(double threshold = 1.0e-20); + /// Copy contents - resizing if necessary - otherwise re-use memory + void copy(const ClpMatrixBase * from, ClpMatrixBase * & to); +#ifndef CLP_NO_STD + /// Drops names - makes lengthnames 0 and names empty + void dropNames(); + /// Copies in names + void copyNames(const std::vector & rowNames, + const std::vector & columnNames); + /// Copies in Row names - modifies names first .. last-1 + void copyRowNames(const std::vector & rowNames, int first, int last); + /// Copies in Column names - modifies names first .. last-1 + void copyColumnNames(const std::vector & columnNames, int first, int last); + /// Copies in Row names - modifies names first .. last-1 + void copyRowNames(const char * const * rowNames, int first, int last); + /// Copies in Column names - modifies names first .. last-1 + void copyColumnNames(const char * const * columnNames, int first, int last); + /// Set name of row + void setRowName(int rowIndex, std::string & name) ; + /// Set name of col + void setColumnName(int colIndex, std::string & name) ; +#endif + /** Find a network subset. + rotate array should be numberRows. On output + -1 not in network + 0 in network as is + 1 in network with signs swapped + Returns number of network rows + */ + int findNetwork(char * rotate, double fractionNeeded = 0.75); + /** This creates a coinModel object + */ + CoinModel * createCoinModel() const; + + /** Write the problem in MPS format to the specified file. + + Row and column names may be null. + formatType is +
    +
  • 0 - normal +
  • 1 - extra accuracy +
  • 2 - IEEE hex +
+ + Returns non-zero on I/O error + */ + int writeMps(const char *filename, + int formatType = 0, int numberAcross = 2, + double objSense = 0.0) const ; + //@} + /**@name gets and sets */ + //@{ + /// Number of rows + inline int numberRows() const { + return numberRows_; + } + inline int getNumRows() const { + return numberRows_; + } + /// Number of columns + inline int getNumCols() const { + return numberColumns_; + } + inline int numberColumns() const { + return numberColumns_; + } + /// Primal tolerance to use + inline double primalTolerance() const { + return dblParam_[ClpPrimalTolerance]; + } + void setPrimalTolerance( double value) ; + /// Dual tolerance to use + inline double dualTolerance() const { + return dblParam_[ClpDualTolerance]; + } + void setDualTolerance( double value) ; + /// Primal objective limit + inline double primalObjectiveLimit() const { + return dblParam_[ClpPrimalObjectiveLimit]; + } + void setPrimalObjectiveLimit(double value); + /// Dual objective limit + inline double dualObjectiveLimit() const { + return dblParam_[ClpDualObjectiveLimit]; + } + void setDualObjectiveLimit(double value); + /// Objective offset + inline double objectiveOffset() const { + return dblParam_[ClpObjOffset]; + } + void setObjectiveOffset(double value); + /// Presolve tolerance to use + inline double presolveTolerance() const { + return dblParam_[ClpPresolveTolerance]; + } +#ifndef CLP_NO_STD + inline const std::string & problemName() const { + return strParam_[ClpProbName]; + } +#endif + /// Number of iterations + inline int numberIterations() const { + return numberIterations_; + } + inline int getIterationCount() const { + return numberIterations_; + } + inline void setNumberIterations(int numberIterationsNew) { + numberIterations_ = numberIterationsNew; + } + /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/ + inline int solveType() const { + return solveType_; + } + inline void setSolveType(int type) { + solveType_ = type; + } + /// Maximum number of iterations + inline int maximumIterations() const { + return intParam_[ClpMaxNumIteration]; + } + void setMaximumIterations(int value); + /// Maximum time in seconds (from when set called) + inline double maximumSeconds() const { + return dblParam_[ClpMaxSeconds]; + } + void setMaximumSeconds(double value); + void setMaximumWallSeconds(double value); + /// Returns true if hit maximum iterations (or time) + bool hitMaximumIterations() const; + /** Status of problem: + -1 - unknown e.g. before solve or if postSolve says not optimal + 0 - optimal + 1 - primal infeasible + 2 - dual infeasible + 3 - stopped on iterations or time + 4 - stopped due to errors + 5 - stopped by event handler (virtual int ClpEventHandler::event()) + */ + inline int status() const { + return problemStatus_; + } + inline int problemStatus() const { + return problemStatus_; + } + /// Set problem status + inline void setProblemStatus(int problemStatusNew) { + problemStatus_ = problemStatusNew; + } + /** Secondary status of problem - may get extended + 0 - none + 1 - primal infeasible because dual limit reached OR (probably primal + infeasible but can't prove it - main status was 4) + 2 - scaled problem optimal - unscaled problem has primal infeasibilities + 3 - scaled problem optimal - unscaled problem has dual infeasibilities + 4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities + 5 - giving up in primal with flagged variables + 6 - failed due to empty problem check + 7 - postSolve says not optimal + 8 - failed due to bad element check + 9 - status was 3 and stopped on time + 10 - status was 3 but stopped as primal feasible + 100 up - translation of enum from ClpEventHandler + */ + inline int secondaryStatus() const { + return secondaryStatus_; + } + inline void setSecondaryStatus(int newstatus) { + secondaryStatus_ = newstatus; + } + /// Are there a numerical difficulties? + inline bool isAbandoned() const { + return problemStatus_ == 4; + } + /// Is optimality proven? + inline bool isProvenOptimal() const { + return problemStatus_ == 0; + } + /// Is primal infeasiblity proven? + inline bool isProvenPrimalInfeasible() const { + return problemStatus_ == 1; + } + /// Is dual infeasiblity proven? + inline bool isProvenDualInfeasible() const { + return problemStatus_ == 2; + } + /// Is the given primal objective limit reached? + bool isPrimalObjectiveLimitReached() const ; + /// Is the given dual objective limit reached? + bool isDualObjectiveLimitReached() const ; + /// Iteration limit reached? + inline bool isIterationLimitReached() const { + return problemStatus_ == 3; + } + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + inline double getObjSense() const { + return optimizationDirection_; + } + void setOptimizationDirection(double value); + /// Primal row solution + inline double * primalRowSolution() const { + return rowActivity_; + } + inline const double * getRowActivity() const { + return rowActivity_; + } + /// Primal column solution + inline double * primalColumnSolution() const { + return columnActivity_; + } + inline const double * getColSolution() const { + return columnActivity_; + } + inline void setColSolution(const double * input) { + memcpy(columnActivity_, input, numberColumns_ * sizeof(double)); + } + /// Dual row solution + inline double * dualRowSolution() const { + return dual_; + } + inline const double * getRowPrice() const { + return dual_; + } + /// Reduced costs + inline double * dualColumnSolution() const { + return reducedCost_; + } + inline const double * getReducedCost() const { + return reducedCost_; + } + /// Row lower + inline double* rowLower() const { + return rowLower_; + } + inline const double* getRowLower() const { + return rowLower_; + } + /// Row upper + inline double* rowUpper() const { + return rowUpper_; + } + inline const double* getRowUpper() const { + return rowUpper_; + } + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + void setObjectiveCoefficient( int elementIndex, double elementValue ); + /** Set an objective function coefficient */ + inline void setObjCoeff( int elementIndex, double elementValue ) { + setObjectiveCoefficient( elementIndex, elementValue); + } + + /** Set a single column lower bound
+ Use -DBL_MAX for -infinity. */ + void setColumnLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound
+ Use DBL_MAX for infinity. */ + void setColumnUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + void setColumnBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously
+ The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + either bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + void setColumnSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single column lower bound
+ Use -DBL_MAX for -infinity. */ + inline void setColLower( int elementIndex, double elementValue ) { + setColumnLower(elementIndex, elementValue); + } + /** Set a single column upper bound
+ Use DBL_MAX for infinity. */ + inline void setColUpper( int elementIndex, double elementValue ) { + setColumnUpper(elementIndex, elementValue); + } + + /** Set a single column lower and upper bound */ + inline void setColBounds( int elementIndex, + double lower, double upper ) { + setColumnBounds(elementIndex, lower, upper); + } + + /** Set the bounds on a number of columns simultaneously
+ @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + either bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + inline void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList) { + setColumnSetBounds(indexFirst, indexLast, boundList); + } + + /** Set a single row lower bound
+ Use -DBL_MAX for -infinity. */ + void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound
+ Use DBL_MAX for infinity. */ + void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the bounds on a number of rows simultaneously
+ @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + either bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + //@} + /// Scaling + inline const double * rowScale() const { + return rowScale_; + } + inline const double * columnScale() const { + return columnScale_; + } + inline const double * inverseRowScale() const { + return inverseRowScale_; + } + inline const double * inverseColumnScale() const { + return inverseColumnScale_; + } + inline double * mutableRowScale() const { + return rowScale_; + } + inline double * mutableColumnScale() const { + return columnScale_; + } + inline double * mutableInverseRowScale() const { + return inverseRowScale_; + } + inline double * mutableInverseColumnScale() const { + return inverseColumnScale_; + } + inline double * swapRowScale(double * newScale) { + double * oldScale = rowScale_; + rowScale_ = newScale; + return oldScale; + } + void setRowScale(double * scale) ; + void setColumnScale(double * scale); + /// Scaling of objective + inline double objectiveScale() const { + return objectiveScale_; + } + inline void setObjectiveScale(double value) { + objectiveScale_ = value; + } + /// Scaling of rhs and bounds + inline double rhsScale() const { + return rhsScale_; + } + inline void setRhsScale(double value) { + rhsScale_ = value; + } + /// Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3 auto, 4 auto-but-as-initialSolve-in-bab + void scaling(int mode = 1); + /** If we constructed a "really" scaled model then this reverses the operation. + Quantities may not be exactly as they were before due to rounding errors */ + void unscale(); + /// Gets scalingFlag + inline int scalingFlag() const { + return scalingFlag_; + } + /// Objective + inline double * objective() const { + if (objective_) { + double offset; + return objective_->gradient(NULL, NULL, offset, false); + } else { + return NULL; + } + } + inline double * objective(const double * solution, double & offset, bool refresh = true) const { + offset = 0.0; + if (objective_) { + return objective_->gradient(NULL, solution, offset, refresh); + } else { + return NULL; + } + } + inline const double * getObjCoefficients() const { + if (objective_) { + double offset; + return objective_->gradient(NULL, NULL, offset, false); + } else { + return NULL; + } + } + /// Row Objective + inline double * rowObjective() const { + return rowObjective_; + } + inline const double * getRowObjCoefficients() const { + return rowObjective_; + } + /// Column Lower + inline double * columnLower() const { + return columnLower_; + } + inline const double * getColLower() const { + return columnLower_; + } + /// Column Upper + inline double * columnUpper() const { + return columnUpper_; + } + inline const double * getColUpper() const { + return columnUpper_; + } + /// Matrix (if not ClpPackedmatrix be careful about memory leak + inline CoinPackedMatrix * matrix() const { + if ( matrix_ == NULL ) return NULL; + else return matrix_->getPackedMatrix(); + } + /// Number of elements in matrix + inline int getNumElements() const { + return matrix_->getNumElements(); + } + /** Small element value - elements less than this set to zero, + default is 1.0e-20 */ + inline double getSmallElementValue() const { + return smallElement_; + } + inline void setSmallElementValue(double value) { + smallElement_ = value; + } + /// Row Matrix + inline ClpMatrixBase * rowCopy() const { + return rowCopy_; + } + /// Set new row matrix + void setNewRowCopy(ClpMatrixBase * newCopy); + /// Clp Matrix + inline ClpMatrixBase * clpMatrix() const { + return matrix_; + } + /// Scaled ClpPackedMatrix + inline ClpPackedMatrix * clpScaledMatrix() const { + return scaledMatrix_; + } + /// Sets pointer to scaled ClpPackedMatrix + inline void setClpScaledMatrix(ClpPackedMatrix * scaledMatrix) { + delete scaledMatrix_; + scaledMatrix_ = scaledMatrix; + } + /// Swaps pointer to scaled ClpPackedMatrix + inline ClpPackedMatrix * swapScaledMatrix(ClpPackedMatrix * scaledMatrix) { + ClpPackedMatrix * oldMatrix = scaledMatrix_; + scaledMatrix_ = scaledMatrix; + return oldMatrix; + } + /** Replace Clp Matrix (current is not deleted unless told to + and new is used) + So up to user to delete current. This was used where + matrices were being rotated. ClpModel takes ownership. + */ + void replaceMatrix(ClpMatrixBase * matrix, bool deleteCurrent = false); + /** Replace Clp Matrix (current is not deleted unless told to + and new is used) So up to user to delete current. This was used where + matrices were being rotated. This version changes CoinPackedMatrix + to ClpPackedMatrix. ClpModel takes ownership. + */ + inline void replaceMatrix(CoinPackedMatrix * newmatrix, + bool deleteCurrent = false) { + replaceMatrix(new ClpPackedMatrix(newmatrix), deleteCurrent); + } + /// Objective value + inline double objectiveValue() const { + return objectiveValue_ * optimizationDirection_ - dblParam_[ClpObjOffset]; + } + inline void setObjectiveValue(double value) { + objectiveValue_ = (value + dblParam_[ClpObjOffset]) / optimizationDirection_; + } + inline double getObjValue() const { + return objectiveValue_ * optimizationDirection_ - dblParam_[ClpObjOffset]; + } + /// Integer information + inline char * integerInformation() const { + return integerType_; + } + /** Infeasibility/unbounded ray (NULL returned if none/wrong) + Up to user to use delete [] on these arrays. */ + double * infeasibilityRay(bool fullRay=false) const; + double * unboundedRay() const; + /// For advanced users - no need to delete - sign not changed + inline double * ray() const + { return ray_;} + /// just test if infeasibility or unbounded Ray exists + inline bool rayExists() const { + return (ray_!=NULL); + } + /// just delete ray if exists + inline void deleteRay() { + delete [] ray_; + ray_=NULL; + } + /// Access internal ray storage. Users should call infeasibilityRay() or unboundedRay() instead. + inline const double * internalRay() const { + return ray_; + } + /// See if status (i.e. basis) array exists (partly for OsiClp) + inline bool statusExists() const { + return (status_ != NULL); + } + /// Return address of status (i.e. basis) array (char[numberRows+numberColumns]) + inline unsigned char * statusArray() const { + return status_; + } + /** Return copy of status (i.e. basis) array (char[numberRows+numberColumns]), + use delete [] */ + unsigned char * statusCopy() const; + /// Copy in status (basis) vector + void copyinStatus(const unsigned char * statusArray); + + /// User pointer for whatever reason + inline void setUserPointer (void * pointer) { + userPointer_ = pointer; + } + inline void * getUserPointer () const { + return userPointer_; + } + /// Trusted user pointer + inline void setTrustedUserPointer (ClpTrustedData * pointer) { + trustedUserPointer_ = pointer; + } + inline ClpTrustedData * getTrustedUserPointer () const { + return trustedUserPointer_; + } + /// What has changed in model (only for masochistic users) + inline int whatsChanged() const { + return whatsChanged_; + } + inline void setWhatsChanged(int value) { + whatsChanged_ = value; + } + /// Number of threads (not really being used) + inline int numberThreads() const { + return numberThreads_; + } + inline void setNumberThreads(int value) { + numberThreads_ = value; + } + //@} + /**@name Message handling */ + //@{ + /// Pass in Message handler (not deleted at end) + void passInMessageHandler(CoinMessageHandler * handler); + /// Pass in Message handler (not deleted at end) and return current + CoinMessageHandler * pushMessageHandler(CoinMessageHandler * handler, + bool & oldDefault); + /// back to previous message handler + void popMessageHandler(CoinMessageHandler * oldHandler, bool oldDefault); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) { + newLanguage(language); + } + /// Overrides message handler with a default one + void setDefaultMessageHandler(); + /// Return handler + inline CoinMessageHandler * messageHandler() const { + return handler_; + } + /// Return messages + inline CoinMessages messages() const { + return messages_; + } + /// Return pointer to messages + inline CoinMessages * messagesPointer() { + return & messages_; + } + /// Return Coin messages + inline CoinMessages coinMessages() const { + return coinMessages_; + } + /// Return pointer to Coin messages + inline CoinMessages * coinMessagesPointer() { + return & coinMessages_; + } + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + inline void setLogLevel(int value) { + handler_->setLogLevel(value); + } + inline int logLevel() const { + return handler_->logLevel(); + } + /// Return true if default handler + inline bool defaultHandler() const { + return defaultHandler_; + } + /// Pass in Event handler (cloned and deleted at end) + void passInEventHandler(const ClpEventHandler * eventHandler); + /// Event handler + inline ClpEventHandler * eventHandler() const { + return eventHandler_; + } + /// Thread specific random number generator + inline CoinThreadRandom * randomNumberGenerator() { + return &randomNumberGenerator_; + } + /// Thread specific random number generator + inline CoinThreadRandom & mutableRandomNumberGenerator() { + return randomNumberGenerator_; + } + /// Set seed for thread specific random number generator + inline void setRandomSeed(int value) { + randomNumberGenerator_.setSeed(value); + } + /// length of names (0 means no names0 + inline int lengthNames() const { + return lengthNames_; + } +#ifndef CLP_NO_STD + /// length of names (0 means no names0 + inline void setLengthNames(int value) { + lengthNames_ = value; + } + /// Row names + inline const std::vector * rowNames() const { + return &rowNames_; + } + inline const std::string& rowName(int iRow) const { + return rowNames_[iRow]; + } + /// Return name or Rnnnnnnn + std::string getRowName(int iRow) const; + /// Column names + inline const std::vector * columnNames() const { + return &columnNames_; + } + inline const std::string& columnName(int iColumn) const { + return columnNames_[iColumn]; + } + /// Return name or Cnnnnnnn + std::string getColumnName(int iColumn) const; +#endif + /// Objective methods + inline ClpObjective * objectiveAsObject() const { + return objective_; + } + void setObjective(ClpObjective * objective); + inline void setObjectivePointer(ClpObjective * newobjective) { + objective_ = newobjective; + } + /** Solve a problem with no elements - return status and + dual and primal infeasibilites */ + int emptyProblem(int * infeasNumber = NULL, double * infeasSum = NULL, bool printMessage = true); + + //@} + + /**@name Matrix times vector methods + They can be faster if scalar is +- 1 + These are covers so user need not worry about scaling + Also for simplex I am not using basic/non-basic split */ + //@{ + /** Return y + A * x * scalar in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + void times(double scalar, + const double * x, double * y) const; + /** Return y + x * scalar * A in y. + @pre x must be of size numRows() + @pre y must be of size numColumns() */ + void transposeTimes(double scalar, + const double * x, double * y) const ; + //@} + + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the volume algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + + ** once it has been decided where solver sits this may be redone + */ + //@{ + /// Set an integer parameter + bool setIntParam(ClpIntParam key, int value) ; + /// Set an double parameter + bool setDblParam(ClpDblParam key, double value) ; +#ifndef CLP_NO_STD + /// Set an string parameter + bool setStrParam(ClpStrParam key, const std::string & value); +#endif + // Get an integer parameter + inline bool getIntParam(ClpIntParam key, int& value) const { + if (key < ClpLastIntParam) { + value = intParam_[key]; + return true; + } else { + return false; + } + } + // Get an double parameter + inline bool getDblParam(ClpDblParam key, double& value) const { + if (key < ClpLastDblParam) { + value = dblParam_[key]; + return true; + } else { + return false; + } + } +#ifndef CLP_NO_STD + // Get a string parameter + inline bool getStrParam(ClpStrParam key, std::string& value) const { + if (key < ClpLastStrParam) { + value = strParam_[key]; + return true; + } else { + return false; + } + } +#endif + /// Create C++ lines to get to current state + void generateCpp( FILE * fp); + /** For advanced options + 1 - Don't keep changing infeasibility weight + 2 - Keep nonLinearCost round solves + 4 - Force outgoing variables to exact bound (primal) + 8 - Safe to use dense initial factorization + 16 -Just use basic variables for operation if column generation + 32 -Create ray even in BAB + 64 -Treat problem as feasible until last minute (i.e. minimize infeasibilities) + 128 - Switch off all matrix sanity checks + 256 - No row copy + 512 - If not in values pass, solution guaranteed, skip as much as possible + 1024 - In branch and bound + 2048 - Don't bother to re-factorize if < 20 iterations + 4096 - Skip some optimality checks + 8192 - Do Primal when cleaning up primal + 16384 - In fast dual (so we can switch off things) + 32768 - called from Osi + 65536 - keep arrays around as much as possible (also use maximumR/C) + 131072 - transposeTimes is -1.0 and can skip basic and fixed + 262144 - extra copy of scaled matrix + 524288 - Clp fast dual + 1048576 - don't need to finish dual (can return 3) + 2097152 - zero costs! + 4194304 - don't scale integer variables + 8388608 - Idiot when not really sure about it + NOTE - many applications can call Clp but there may be some short cuts + which are taken which are not guaranteed safe from all applications. + Vetted applications will have a bit set and the code may test this + At present I expect a few such applications - if too many I will + have to re-think. It is up to application owner to change the code + if she/he needs these short cuts. I will not debug unless in Coin + repository. See COIN_CLP_VETTED comments. + 0x01000000 is Cbc (and in branch and bound) + 0x02000000 is in a different branch and bound + */ + inline unsigned int specialOptions() const { + return specialOptions_; + } + void setSpecialOptions(unsigned int value); +#define COIN_CBC_USING_CLP 0x01000000 + inline bool inCbcBranchAndBound() const { + return (specialOptions_ & COIN_CBC_USING_CLP) != 0; + } + //@} + + /**@name private or protected methods */ + //@{ +protected: + /// Does most of deletion (0 = all, 1 = most) + void gutsOfDelete(int type); + /** Does most of copying + If trueCopy 0 then just points to arrays + If -1 leaves as much as possible */ + void gutsOfCopy(const ClpModel & rhs, int trueCopy = 1); + /// gets lower and upper bounds on rows + void getRowBound(int iRow, double& lower, double& upper) const; + /// puts in format I like - 4 array matrix - may make row copy + void gutsOfLoadModel ( int numberRows, int numberColumns, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// Does much of scaling + void gutsOfScaling(); + /// Objective value - always minimize + inline double rawObjectiveValue() const { + return objectiveValue_; + } + /// If we are using maximumRows_ and Columns_ + inline bool permanentArrays() const { + return (specialOptions_ & 65536) != 0; + } + /// Start using maximumRows_ and Columns_ + void startPermanentArrays(); + /// Stop using maximumRows_ and Columns_ + void stopPermanentArrays(); + /// Create row names as char ** + const char * const * rowNamesAsChar() const; + /// Create column names as char ** + const char * const * columnNamesAsChar() const; + /// Delete char * version of names + void deleteNamesAsChar(const char * const * names, int number) const; + /// On stopped - sets secondary status + void onStopped(); + //@} + + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + double optimizationDirection_; + /// Array of double parameters + double dblParam_[ClpLastDblParam]; + /// Objective value + double objectiveValue_; + /// Small element value + double smallElement_; + /// Scaling of objective + double objectiveScale_; + /// Scaling of rhs and bounds + double rhsScale_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// Row activities + double * rowActivity_; + /// Column activities + double * columnActivity_; + /// Duals + double * dual_; + /// Reduced costs + double * reducedCost_; + /// Row lower + double* rowLower_; + /// Row upper + double* rowUpper_; + /// Objective + ClpObjective * objective_; + /// Row Objective (? sign) - may be NULL + double * rowObjective_; + /// Column Lower + double * columnLower_; + /// Column Upper + double * columnUpper_; + /// Packed matrix + ClpMatrixBase * matrix_; + /// Row copy if wanted + ClpMatrixBase * rowCopy_; + /// Scaled packed matrix + ClpPackedMatrix * scaledMatrix_; + /// Infeasible/unbounded ray + double * ray_; + /// Row scale factors for matrix + double * rowScale_; + /// Column scale factors + double * columnScale_; + /// Inverse row scale factors for matrix (end of rowScale_) + double * inverseRowScale_; + /// Inverse column scale factors for matrix (end of columnScale_) + double * inverseColumnScale_; + /** Scale flag, 0 none, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic, + 5 geometric on rows */ + int scalingFlag_; + /** Status (i.e. basis) Region. I know that not all algorithms need a status + array, but it made sense for things like crossover and put + all permanent stuff in one place. No assumption is made + about what is in status array (although it might be good to reserve + bottom 3 bits (i.e. 0-7 numeric) for classic status). This + is number of columns + number of rows long (in that order). + */ + unsigned char * status_; + /// Integer information + char * integerType_; + /// User pointer for whatever reason + void * userPointer_; + /// Trusted user pointer e.g. for heuristics + ClpTrustedData * trustedUserPointer_; + /// Array of integer parameters + int intParam_[ClpLastIntParam]; + /// Number of iterations + int numberIterations_; + /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/ + int solveType_; + /** Whats changed since last solve. This is a work in progress + It is designed so careful people can make go faster. + It is only used when startFinishOptions used in dual or primal. + Bit 1 - number of rows/columns has not changed (so work arrays valid) + 2 - matrix has not changed + 4 - if matrix has changed only by adding rows + 8 - if matrix has changed only by adding columns + 16 - row lbs not changed + 32 - row ubs not changed + 64 - column objective not changed + 128 - column lbs not changed + 256 - column ubs not changed + 512 - basis not changed (up to user to set this to 0) + top bits may be used internally + shift by 65336 is 3 all same, 1 all except col bounds + */ +#define ROW_COLUMN_COUNTS_SAME 1 +#define MATRIX_SAME 2 +#define MATRIX_JUST_ROWS_ADDED 4 +#define MATRIX_JUST_COLUMNS_ADDED 8 +#define ROW_LOWER_SAME 16 +#define ROW_UPPER_SAME 32 +#define OBJECTIVE_SAME 64 +#define COLUMN_LOWER_SAME 128 +#define COLUMN_UPPER_SAME 256 +#define BASIS_SAME 512 +#define ALL_SAME 65339 +#define ALL_SAME_EXCEPT_COLUMN_BOUNDS 65337 + unsigned int whatsChanged_; + /// Status of problem + int problemStatus_; + /// Secondary status of problem + int secondaryStatus_; + /// length of names (0 means no names) + int lengthNames_; + /// Number of threads (not very operational) + int numberThreads_; + /** For advanced options + See get and set for meaning + */ + unsigned int specialOptions_; + /// Message handler + CoinMessageHandler * handler_; + /// Flag to say if default handler (so delete) + bool defaultHandler_; + /// Thread specific random number generator + CoinThreadRandom randomNumberGenerator_; + /// Event handler + ClpEventHandler * eventHandler_; +#ifndef CLP_NO_STD + /// Row names + std::vector rowNames_; + /// Column names + std::vector columnNames_; +#endif + /// Messages + CoinMessages messages_; + /// Coin messages + CoinMessages coinMessages_; + /// Maximum number of columns in model + int maximumColumns_; + /// Maximum number of rows in model + int maximumRows_; + /// Maximum number of columns (internal arrays) in model + int maximumInternalColumns_; + /// Maximum number of rows (internal arrays) in model + int maximumInternalRows_; + /// Base packed matrix + CoinPackedMatrix baseMatrix_; + /// Base row copy + CoinPackedMatrix baseRowCopy_; + /// Saved row scale factors for matrix + double * savedRowScale_; + /// Saved column scale factors + double * savedColumnScale_; +#ifndef CLP_NO_STD + /// Array of string parameters + std::string strParam_[ClpLastStrParam]; +#endif + //@} +}; +/** This is a tiny class where data can be saved round calls. + */ +class ClpDataSave { + +public: + /**@name Constructors and destructor + */ + //@{ + /// Default constructor + ClpDataSave ( ); + + /// Copy constructor. + ClpDataSave(const ClpDataSave &); + /// Assignment operator. This copies the data + ClpDataSave & operator=(const ClpDataSave & rhs); + /// Destructor + ~ClpDataSave ( ); + + //@} + +////////////////// data ////////////////// +public: + + /**@name data - with same names as in other classes*/ + //@{ + double dualBound_; + double infeasibilityCost_; + double pivotTolerance_; + double zeroFactorizationTolerance_; + double zeroSimplexTolerance_; + double acceptablePivot_; + double objectiveScale_; + int sparseThreshold_; + int perturbation_; + int forceFactorization_; + int scalingFlag_; + unsigned int specialOptions_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpNetworkMatrix.hpp b/thirdparty/linux/include/coin/ClpNetworkMatrix.hpp new file mode 100644 index 0000000..ec650a4 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpNetworkMatrix.hpp @@ -0,0 +1,229 @@ +/* $Id: ClpNetworkMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNetworkMatrix_H +#define ClpNetworkMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a simple network matrix as derived from ClpMatrixBase. + +If you want more sophisticated version then you could inherit from this. +Also you might want to allow networks with gain */ + +class ClpNetworkMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return true; + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return 2 * numberColumns_; + } + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return indices_; + } + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in indDel. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in indDel. */ + virtual void deleteRows(const int numDel, const int * indDel); + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#ifndef SLIM_CLP + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); +#endif + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis( + const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed format + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + virtual void releasePackedMatrix() const ; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return y + A * scalar *x in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return y + x * scalar * A in y. + @pre x must be of size numRows() + @pre y must be of size numColumns() */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, double * spare = NULL) const; + /** Return x * scalar * A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x *A in z but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + //@} + + /**@name Other */ + //@{ + /// Return true if really network, false if has slacks + inline bool trueNetwork() const { + return trueNetwork_; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNetworkMatrix(); + /** Constructor from two arrays */ + ClpNetworkMatrix(int numberColumns, const int * head, + const int * tail); + /** Destructor */ + virtual ~ClpNetworkMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpNetworkMatrix(const ClpNetworkMatrix&); + /** The copy constructor from an CoinNetworkMatrix. */ + ClpNetworkMatrix(const CoinPackedMatrix&); + + ClpNetworkMatrix& operator=(const ClpNetworkMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpNetworkMatrix (const ClpNetworkMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// For fake CoinPackedMatrix + mutable CoinPackedMatrix * matrix_; + mutable int * lengths_; + /// Data -1, then +1 rows in pairs (row==-1 if one entry) + int * indices_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// True if all entries have two elements + bool trueNetwork_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpNode.hpp b/thirdparty/linux/include/coin/ClpNode.hpp new file mode 100644 index 0000000..671d62f --- /dev/null +++ b/thirdparty/linux/include/coin/ClpNode.hpp @@ -0,0 +1,349 @@ +/* $Id: ClpNode.hpp 1910 2013-01-27 02:00:13Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNode_H +#define ClpNode_H + +#include "CoinPragma.hpp" + +// This implements all stuff for Clp fathom +/** This contains what is in a Clp "node" + + */ + +class ClpFactorization; +class ClpDualRowSteepest; +class ClpNodeStuff; +class ClpNode { + +public: + /**@name Useful methods */ + //@{ + /** Applies node to model + 0 - just tree bounds + 1 - tree bounds and basis etc + 2 - saved bounds and basis etc + */ + void applyNode(ClpSimplex * model, int doBoundsEtc ); + /// Choose a new variable + void chooseVariable(ClpSimplex * model, ClpNodeStuff * info); + /// Fix on reduced costs + int fixOnReducedCosts(ClpSimplex * model); + /// Create odd arrays + void createArrays(ClpSimplex * model); + /// Clean up as crunch is different model + void cleanUpForCrunch(); + //@} + + /**@name Gets and sets */ + //@{ + /// Objective value + inline double objectiveValue() const { + return objectiveValue_; + } + /// Set objective value + inline void setObjectiveValue(double value) { + objectiveValue_ = value; + } + /// Primal solution + inline const double * primalSolution() const { + return primalSolution_; + } + /// Dual solution + inline const double * dualSolution() const { + return dualSolution_; + } + /// Initial value of integer variable + inline double branchingValue() const { + return branchingValue_; + } + /// Sum infeasibilities + inline double sumInfeasibilities() const { + return sumInfeasibilities_; + } + /// Number infeasibilities + inline int numberInfeasibilities() const { + return numberInfeasibilities_; + } + /// Relative depth + inline int depth() const { + return depth_; + } + /// Estimated solution value + inline double estimatedSolution() const { + return estimatedSolution_; + } + /** Way for integer variable -1 down , +1 up */ + int way() const; + /// Return true if branch exhausted + bool fathomed() const; + /// Change state of variable i.e. go other way + void changeState(); + /// Sequence number of integer variable (-1 if none) + inline int sequence() const { + return sequence_; + } + /// If odd arrays exist + inline bool oddArraysExist() const { + return lower_ != NULL; + } + /// Status array + inline const unsigned char * statusArray() const { + return status_; + } + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNode(); + /// Constructor from model + ClpNode (ClpSimplex * model, const ClpNodeStuff * stuff, int depth); + /// Does work of constructor (partly so gdb will work) + void gutsOfConstructor(ClpSimplex * model, const ClpNodeStuff * stuff, + int arraysExist, int depth); + /** Destructor */ + virtual ~ClpNode(); + //@} + + /**@name Copy methods (at present illegal - will abort) */ + //@{ + /** The copy constructor. */ + ClpNode(const ClpNode&); + /// Operator = + ClpNode& operator=(const ClpNode&); + //@} + +protected: +// For state of branch + typedef struct { + unsigned int firstBranch: 1; // nonzero if first branch on variable is up + unsigned int branch: 2; // 0 means do first branch next, 1 second, 2 finished + unsigned int spare: 29; + } branchState; + /**@name Data */ + //@{ + /// Initial value of integer variable + double branchingValue_; + /// Value of objective + double objectiveValue_; + /// Sum of infeasibilities + double sumInfeasibilities_; + /// Estimated solution value + double estimatedSolution_; + /// Factorization + ClpFactorization * factorization_; + /// Steepest edge weights + ClpDualRowSteepest * weights_; + /// Status vector + unsigned char * status_; + /// Primal solution + double * primalSolution_; + /// Dual solution + double * dualSolution_; + /// Integer lower bounds (only used in fathomMany) + int * lower_; + /// Integer upper bounds (only used in fathomMany) + int * upper_; + /// Pivot variables for factorization + int * pivotVariables_; + /// Variables fixed by reduced costs (at end of branch) 0x10000000 added if fixed to UB + int * fixed_; + /// State of branch + branchState branchState_; + /// Sequence number of integer variable (-1 if none) + int sequence_; + /// Number of infeasibilities + int numberInfeasibilities_; + /// Relative depth + int depth_; + /// Number fixed by reduced cost + int numberFixed_; + /// Flags - 1 duals scaled + int flags_; + /// Maximum number fixed by reduced cost + int maximumFixed_; + /// Maximum rows so far + int maximumRows_; + /// Maximum columns so far + int maximumColumns_; + /// Maximum Integers so far + int maximumIntegers_; + //@} +}; +class ClpNodeStuff { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNodeStuff(); + /** Destructor */ + virtual ~ClpNodeStuff(); + //@} + + /**@name Copy methods (only copies ints etc, nulls arrays) */ + //@{ + /** The copy constructor. */ + ClpNodeStuff(const ClpNodeStuff&); + /// Operator = + ClpNodeStuff& operator=(const ClpNodeStuff&); + /// Zaps stuff 1 - arrays, 2 ints, 3 both + void zap(int type); + //@} + + + /**@name Fill methods */ + //@{ + /** Fill with pseudocosts */ + void fillPseudoCosts(const double * down, const double * up, + const int * priority, + const int * numberDown, const int * numberUp, + const int * numberDownInfeasible, const int * numberUpInfeasible, + int number); + /// Update pseudo costs + void update(int way, int sequence, double change, bool feasible); + /// Return maximum number of nodes + int maximumNodes() const; + /// Return maximum space for nodes + int maximumSpace() const; + //@} + +public: + /**@name Data */ + //@{ + /// Integer tolerance + double integerTolerance_; + /// Integer increment + double integerIncrement_; + /// Small change in branch + double smallChange_; + /// Down pseudo costs + double * downPseudo_; + /// Up pseudo costs + double * upPseudo_; + /// Priority + int * priority_; + /// Number of times down + int * numberDown_; + /// Number of times up + int * numberUp_; + /// Number of times down infeasible + int * numberDownInfeasible_; + /// Number of times up infeasible + int * numberUpInfeasible_; + /// Copy of costs (local) + double * saveCosts_; + /// Array of ClpNodes + ClpNode ** nodeInfo_; + /// Large model if crunched + ClpSimplex * large_; + /// Which rows in large model + int * whichRow_; + /// Which columns in large model + int * whichColumn_; +#ifndef NO_FATHOM_PRINT + /// Cbc's message handler + CoinMessageHandler * handler_; +#endif + /// Number bounds in large model + int nBound_; + /// Save of specialOptions_ (local) + int saveOptions_; + /** Options to pass to solver + 1 - create external reduced costs for columns + 2 - create external reduced costs for rows + 4 - create external row activity (columns always done) + Above only done if feasible + 32 - just create up to nDepth_+1 nodes + 65536 - set if activated + */ + int solverOptions_; + /// Maximum number of nodes to do + int maximumNodes_; + /// Number before trust from CbcModel + int numberBeforeTrust_; + /// State of search from CbcModel + int stateOfSearch_; + /// Number deep + int nDepth_; + /// Number nodes returned (-1 if fathom aborted) + int nNodes_; + /// Number of nodes explored + int numberNodesExplored_; + /// Number of iterations + int numberIterations_; + /// Type of presolve - 0 none, 1 crunch + int presolveType_; +#ifndef NO_FATHOM_PRINT + /// Depth passed in + int startingDepth_; + /// Node at which called + int nodeCalled_; +#endif + //@} +}; +class ClpHashValue { + +public: + /**@name Useful methods */ + //@{ + /// Return index or -1 if not found + int index(double value) const; + /// Add value to list and return index + int addValue(double value) ; + /// Number of different entries + inline int numberEntries() const { + return numberHash_; + } + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpHashValue(); + /** Useful constructor. */ + ClpHashValue(ClpSimplex * model); + /** Destructor */ + virtual ~ClpHashValue(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpHashValue(const ClpHashValue&); + /// = + ClpHashValue& operator=(const ClpHashValue&); + //@} +private: + /**@name private stuff */ + //@{ + /** returns hash */ + int hash(double value) const; + /// Resizes + void resize(bool increaseMax); + //@} + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Data + // for hashing + typedef struct { + double value; + int index, next; + } CoinHashLink; + /// Hash table + mutable CoinHashLink *hash_; + /// Number of entries in hash table + int numberHash_; + /// Maximum number of entries in hash table i.e. size + int maxHash_; + /// Last used space + int lastUsed_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/ClpNonLinearCost.hpp b/thirdparty/linux/include/coin/ClpNonLinearCost.hpp new file mode 100644 index 0000000..1007865 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpNonLinearCost.hpp @@ -0,0 +1,401 @@ +/* $Id: ClpNonLinearCost.hpp 1769 2011-07-26 09:31:51Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNonLinearCost_H +#define ClpNonLinearCost_H + + +#include "CoinPragma.hpp" + +class ClpSimplex; +class CoinIndexedVector; + +/** Trivial class to deal with non linear costs + + I don't make any explicit assumptions about convexity but I am + sure I do make implicit ones. + + One interesting idea for normal LP's will be to allow non-basic + variables to come into basis as infeasible i.e. if variable at + lower bound has very large positive reduced cost (when problem + is infeasible) could it reduce overall problem infeasibility more + by bringing it into basis below its lower bound. + + Another feature would be to automatically discover when problems + are convex piecewise linear and re-formulate to use non-linear. + I did some work on this many years ago on "grade" problems, but + while it improved primal interior point algorithms were much better + for that particular problem. +*/ +/* status has original status and current status + 0 - below lower so stored is upper + 1 - in range + 2 - above upper so stored is lower + 4 - (for current) - same as original +*/ +#define CLP_BELOW_LOWER 0 +#define CLP_FEASIBLE 1 +#define CLP_ABOVE_UPPER 2 +#define CLP_SAME 4 +inline int originalStatus(unsigned char status) +{ + return (status & 15); +} +inline int currentStatus(unsigned char status) +{ + return (status >> 4); +} +inline void setOriginalStatus(unsigned char & status, int value) +{ + status = static_cast(status & ~15); + status = static_cast(status | value); +} +inline void setCurrentStatus(unsigned char &status, int value) +{ + status = static_cast(status & ~(15 << 4)); + status = static_cast(status | (value << 4)); +} +inline void setInitialStatus(unsigned char &status) +{ + status = static_cast(CLP_FEASIBLE | (CLP_SAME << 4)); +} +inline void setSameStatus(unsigned char &status) +{ + status = static_cast(status & ~(15 << 4)); + status = static_cast(status | (CLP_SAME << 4)); +} +// Use second version to get more speed +//#define FAST_CLPNON +#ifndef FAST_CLPNON +#define CLP_METHOD1 ((method_&1)!=0) +#define CLP_METHOD2 ((method_&2)!=0) +#else +#define CLP_METHOD1 (false) +#define CLP_METHOD2 (true) +#endif +class ClpNonLinearCost { + +public: + +public: + + /**@name Constructors, destructor */ + //@{ + /// Default constructor. + ClpNonLinearCost(); + /** Constructor from simplex. + This will just set up wasteful arrays for linear, but + later may do dual analysis and even finding duplicate columns . + */ + ClpNonLinearCost(ClpSimplex * model, int method = 1); + /** Constructor from simplex and list of non-linearities (columns only) + First lower of each column has to match real lower + Last lower has to be <= upper (if == then cost ignored) + This could obviously be changed to make more user friendly + */ + ClpNonLinearCost(ClpSimplex * model, const int * starts, + const double * lower, const double * cost); + /// Destructor + ~ClpNonLinearCost(); + // Copy + ClpNonLinearCost(const ClpNonLinearCost&); + // Assignment + ClpNonLinearCost& operator=(const ClpNonLinearCost&); + //@} + + + /**@name Actual work in primal */ + //@{ + /** Changes infeasible costs and computes number and cost of infeas + Puts all non-basic (non free) variables to bounds + and all free variables to zero if oldTolerance is non-zero + - but does not move those <= oldTolerance away*/ + void checkInfeasibilities(double oldTolerance = 0.0); + /** Changes infeasible costs for each variable + The indices are row indices and need converting to sequences + */ + void checkInfeasibilities(int numberInArray, const int * index); + /** Puts back correct infeasible costs for each variable + The input indices are row indices and need converting to sequences + for costs. + On input array is empty (but indices exist). On exit just + changed costs will be stored as normal CoinIndexedVector + */ + void checkChanged(int numberInArray, CoinIndexedVector * update); + /** Goes through one bound for each variable. + If multiplier*work[iRow]>0 goes down, otherwise up. + The indices are row indices and need converting to sequences + Temporary offsets may be set + Rhs entries are increased + */ + void goThru(int numberInArray, double multiplier, + const int * index, const double * work, + double * rhs); + /** Takes off last iteration (i.e. offsets closer to 0) + */ + void goBack(int numberInArray, const int * index, + double * rhs); + /** Puts back correct infeasible costs for each variable + The input indices are row indices and need converting to sequences + for costs. + At the end of this all temporary offsets are zero + */ + void goBackAll(const CoinIndexedVector * update); + /// Temporary zeroing of feasible costs + void zapCosts(); + /// Refreshes costs always makes row costs zero + void refreshCosts(const double * columnCosts); + /// Puts feasible bounds into lower and upper + void feasibleBounds(); + /// Refresh - assuming regions OK + void refresh(); + /** Sets bounds and cost for one variable + Returns change in cost + May need to be inline for speed */ + double setOne(int sequence, double solutionValue); + /** Sets bounds and infeasible cost and true cost for one variable + This is for gub and column generation etc */ + void setOne(int sequence, double solutionValue, double lowerValue, double upperValue, + double costValue = 0.0); + /** Sets bounds and cost for outgoing variable + may change value + Returns direction */ + int setOneOutgoing(int sequence, double &solutionValue); + /// Returns nearest bound + double nearest(int sequence, double solutionValue); + /** Returns change in cost - one down if alpha >0.0, up if <0.0 + Value is current - new + */ + inline double changeInCost(int sequence, double alpha) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (alpha > 0.0) + returnValue = cost_[iRange] - cost_[iRange-1]; + else + returnValue = cost_[iRange] - cost_[iRange+1]; + } + if (CLP_METHOD2) { + returnValue = (alpha > 0.0) ? infeasibilityWeight_ : -infeasibilityWeight_; + } + return returnValue; + } + inline double changeUpInCost(int sequence) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (iRange + 1 != start_[sequence+1] && !infeasible(iRange + 1)) + returnValue = cost_[iRange] - cost_[iRange+1]; + else + returnValue = -1.0e100; + } + if (CLP_METHOD2) { + returnValue = -infeasibilityWeight_; + } + return returnValue; + } + inline double changeDownInCost(int sequence) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (iRange != start_[sequence] && !infeasible(iRange - 1)) + returnValue = cost_[iRange] - cost_[iRange-1]; + else + returnValue = 1.0e100; + } + if (CLP_METHOD2) { + returnValue = infeasibilityWeight_; + } + return returnValue; + } + /// This also updates next bound + inline double changeInCost(int sequence, double alpha, double &rhs) { + double returnValue = 0.0; +#ifdef NONLIN_DEBUG + double saveRhs = rhs; +#endif + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (alpha > 0.0) { + assert(iRange - 1 >= start_[sequence]); + offset_[sequence]--; + rhs += lower_[iRange] - lower_[iRange-1]; + returnValue = alpha * (cost_[iRange] - cost_[iRange-1]); + } else { + assert(iRange + 1 < start_[sequence+1] - 1); + offset_[sequence]++; + rhs += lower_[iRange+2] - lower_[iRange+1]; + returnValue = alpha * (cost_[iRange] - cost_[iRange+1]); + } + } + if (CLP_METHOD2) { +#ifdef NONLIN_DEBUG + double saveRhs1 = rhs; + rhs = saveRhs; +#endif + unsigned char iStatus = status_[sequence]; + int iWhere = currentStatus(iStatus); + if (iWhere == CLP_SAME) + iWhere = originalStatus(iStatus); + // rhs always increases + if (iWhere == CLP_FEASIBLE) { + if (alpha > 0.0) { + // going below + iWhere = CLP_BELOW_LOWER; + rhs = COIN_DBL_MAX; + } else { + // going above + iWhere = CLP_ABOVE_UPPER; + rhs = COIN_DBL_MAX; + } + } else if (iWhere == CLP_BELOW_LOWER) { + assert (alpha < 0); + // going feasible + iWhere = CLP_FEASIBLE; + rhs += bound_[sequence] - model_->upperRegion()[sequence]; + } else { + assert (iWhere == CLP_ABOVE_UPPER); + // going feasible + iWhere = CLP_FEASIBLE; + rhs += model_->lowerRegion()[sequence] - bound_[sequence]; + } + setCurrentStatus(status_[sequence], iWhere); +#ifdef NONLIN_DEBUG + assert(saveRhs1 == rhs); +#endif + returnValue = fabs(alpha) * infeasibilityWeight_; + } + return returnValue; + } + /// Returns current lower bound + inline double lower(int sequence) const { + return lower_[whichRange_[sequence] + offset_[sequence]]; + } + /// Returns current upper bound + inline double upper(int sequence) const { + return lower_[whichRange_[sequence] + offset_[sequence] + 1]; + } + /// Returns current cost + inline double cost(int sequence) const { + return cost_[whichRange_[sequence] + offset_[sequence]]; + } + //@} + + + /**@name Gets and sets */ + //@{ + /// Number of infeasibilities + inline int numberInfeasibilities() const { + return numberInfeasibilities_; + } + /// Change in cost + inline double changeInCost() const { + return changeCost_; + } + /// Feasible cost + inline double feasibleCost() const { + return feasibleCost_; + } + /// Feasible cost with offset and direction (i.e. for reporting) + double feasibleReportCost() const; + /// Sum of infeasibilities + inline double sumInfeasibilities() const { + return sumInfeasibilities_; + } + /// Largest infeasibility + inline double largestInfeasibility() const { + return largestInfeasibility_; + } + /// Average theta + inline double averageTheta() const { + return averageTheta_; + } + inline void setAverageTheta(double value) { + averageTheta_ = value; + } + inline void setChangeInCost(double value) { + changeCost_ = value; + } + inline void setMethod(int value) { + method_ = value; + } + /// See if may want to look both ways + inline bool lookBothWays() const { + return bothWays_; + } + //@} + ///@name Private functions to deal with infeasible regions + inline bool infeasible(int i) const { + return ((infeasible_[i>>5] >> (i & 31)) & 1) != 0; + } + inline void setInfeasible(int i, bool trueFalse) { + unsigned int & value = infeasible_[i>>5]; + int bit = i & 31; + if (trueFalse) + value |= (1 << bit); + else + value &= ~(1 << bit); + } + inline unsigned char * statusArray() const { + return status_; + } + /// For debug + void validate(); + //@} + +private: + /**@name Data members */ + //@{ + /// Change in cost because of infeasibilities + double changeCost_; + /// Feasible cost + double feasibleCost_; + /// Current infeasibility weight + double infeasibilityWeight_; + /// Largest infeasibility + double largestInfeasibility_; + /// Sum of infeasibilities + double sumInfeasibilities_; + /// Average theta - kept here as only for primal + double averageTheta_; + /// Number of rows (mainly for checking and copy) + int numberRows_; + /// Number of columns (mainly for checking and copy) + int numberColumns_; + /// Starts for each entry (columns then rows) + int * start_; + /// Range for each entry (columns then rows) + int * whichRange_; + /// Temporary range offset for each entry (columns then rows) + int * offset_; + /** Lower bound for each range (upper bound is next lower). + For various reasons there is always an infeasible range + at bottom - even if lower bound is - infinity */ + double * lower_; + /// Cost for each range + double * cost_; + /// Model + ClpSimplex * model_; + // Array to say which regions are infeasible + unsigned int * infeasible_; + /// Number of infeasibilities found + int numberInfeasibilities_; + // new stuff + /// Contains status at beginning and current + unsigned char * status_; + /// Bound which has been replaced in lower_ or upper_ + double * bound_; + /// Feasible cost array + double * cost2_; + /// Method 1 old, 2 new, 3 both! + int method_; + /// If all non-linear costs convex + bool convex_; + /// If we should look both ways for djs + bool bothWays_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpObjective.hpp b/thirdparty/linux/include/coin/ClpObjective.hpp new file mode 100644 index 0000000..f98903a --- /dev/null +++ b/thirdparty/linux/include/coin/ClpObjective.hpp @@ -0,0 +1,134 @@ +/* $Id: ClpObjective.hpp 1825 2011-11-20 16:02:57Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpObjective_H +#define ClpObjective_H + + +//############################################################################# +class ClpSimplex; +class ClpModel; + +/** Objective Abstract Base Class + +Abstract Base Class for describing an objective function + +*/ +class ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns gradient. If Linear then solution may be NULL, + also returns an offset (to be added to current one) + If refresh is false then uses last solution + Uses model for scaling + includeLinear 0 - no, 1 as is, 2 as feasible + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, + double & offset, bool refresh, + int includeLinear = 2) = 0; + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts) = 0; + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj) = 0; + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const = 0; + /// Resize objective + virtual void resize(int newNumberColumns) = 0; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) = 0; + /// Scale objective + virtual void reallyScale(const double * columnScale) = 0; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which); + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() {} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpObjective(); + + /// Copy constructor + ClpObjective(const ClpObjective &); + + /// Assignment operator + ClpObjective & operator=(const ClpObjective& rhs); + + /// Destructor + virtual ~ClpObjective (); + + /// Clone + virtual ClpObjective * clone() const = 0; + /** Subset clone. Duplicates are allowed + and order is as given. + Derived classes need not provide this as it may not always make + sense */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + //@} + + ///@name Other + //@{ + /// Returns type (above 63 is extra information) + inline int type() const { + return type_; + } + /// Sets type (above 63 is extra information) + inline void setType(int value) { + type_ = value; + } + /// Whether activated + inline int activated() const { + return activated_; + } + /// Set whether activated + inline void setActivated(int value) { + activated_ = value; + } + + /// Objective offset + inline double nonlinearOffset () const { + return offset_; + } + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Value of non-linear part of objective + double offset_; + /// Type of objective - linear is 1 + int type_; + /// Whether activated + int activated_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpPackedMatrix.hpp b/thirdparty/linux/include/coin/ClpPackedMatrix.hpp new file mode 100644 index 0000000..ec0c0b9 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpPackedMatrix.hpp @@ -0,0 +1,638 @@ +/* $Id: ClpPackedMatrix.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPackedMatrix_H +#define ClpPackedMatrix_H + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements CoinPackedMatrix as derived from ClpMatrixBase. + + It adds a few methods that know about model as well as matrix + + For details see CoinPackedMatrix */ + +class ClpPackedMatrix2; +class ClpPackedMatrix3; +class ClpPackedMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const { + return matrix_; + } + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return matrix_->isColOrdered(); + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return matrix_->getNumElements(); + } + /** Number of columns. */ + virtual int getNumCols() const { + return matrix_->getNumCols(); + } + /** Number of rows. */ + virtual int getNumRows() const { + return matrix_->getNumRows(); + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const { + return matrix_->getElements(); + } + /// Mutable elements + inline double * getMutableElements() const { + return matrix_->getMutableElements(); + } + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return matrix_->getIndices(); + } + + virtual const CoinBigIndex * getVectorStarts() const { + return matrix_->getVectorStarts(); + } + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const { + return matrix_->getVectorLengths(); + } + /** The length of a single major-dimension vector. */ + virtual int getVectorLength(int index) const { + return matrix_->getVectorSize(index); + } + + /** Delete the columns whose indices are listed in indDel. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in indDel. */ + virtual void deleteRows(const int numDel, const int * indDel); +#ifndef CLP_NO_VECTOR + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#endif + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); + /** Replace the elements of a vector. The indices remain the same. + This is only needed if scaling and a row copy is used. + At most the number specified will be replaced. + The index is between 0 and major dimension of matrix */ + virtual void replaceVector(const int index, + const int numReplace, const double * newElements) { + matrix_->replaceVector(index, numReplace, newElements); + } + /** Modify one element of packed matrix. An element may be added. + This works for either ordering If the new element is zero it will be + deleted unless keepZero true */ + virtual void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false) { + matrix_->modifyCoefficient(row, column, newElement, keepZero); + } + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Creates scales for column copy (rowCopy in model may be modified) + returns non-zero if no scaling done */ + virtual int scale(ClpModel * model, const ClpSimplex * baseModel = NULL) const ; + /** Scales rowCopy if column copy scaled + Only called if scales already exist */ + virtual void scaleRowCopy(ClpModel * model) const ; + /// Creates scaled column copy if scales exist + void createScaledMatrix(ClpSimplex * model) const; + /** Realy really scales column copy + Only called if scales already exist. + Up to user ro delete */ + virtual ClpMatrixBase * scaledColumnCopy(ClpModel * model) const ; + /** Checks if all elements are in valid range. Can just + return true if you are not paranoid. For Clp I will + probably expect no zeros. Code can modify matrix to get rid of + small elements. + check bits (can be turned off to save time) : + 1 - check if matrix has gaps + 2 - check if zero elements + 4 - check and compress duplicates + 8 - report on large and small + */ + virtual bool allElementsInRange(ClpModel * model, + double smallest, double largest, + int check = 15); + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const { } + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /// makes sure active columns correct + virtual int refresh(ClpSimplex * model); + // Really scale matrix + virtual void reallyScale(const double * rowScale, const double * columnScale); + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return y + A * scalar *x in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return y + x * scalar * A in y. + @pre x must be of size numRows() + @pre y must be of size numColumns() */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, + double * spare = NULL) const; + /** Return y - pi * A in y. + @pre pi must be of size numRows() + @pre y must be of size numColumns() + This just does subset (but puts in correct place in y) */ + void transposeTimesSubset( int number, + const int * which, + const double * pi, double * y, + const double * rowScale, + const double * columnScale, + double * spare = NULL) const; + /** Return x * scalar * A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x * scalar * A + y in z. + Note - If x packed mode - then z packed mode + This does by column and knows no gaps + Squashes small elements and knows about ClpSimplex */ + void transposeTimesByColumn(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x * scalar * A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x *A in z but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * model, + const CoinIndexedVector * pi) const; + /// Updates two arrays for steepest + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Sets up an effective RHS + void useEffectiveRhs(ClpSimplex * model); +#if COIN_LONG_WORK + // For long double versions + virtual void times(CoinWorkDouble scalar, + const CoinWorkDouble * x, CoinWorkDouble * y) const ; + virtual void transposeTimes(CoinWorkDouble scalar, + const CoinWorkDouble * x, CoinWorkDouble * y) const ; +#endif +//@} + + /**@name Other */ + //@{ + /// Returns CoinPackedMatrix (non const) + inline CoinPackedMatrix * matrix() const { + return matrix_; + } + /** Just sets matrix_ to NULL so it can be used elsewhere. + used in GUB + */ + inline void setMatrixNull() { + matrix_ = NULL; + } + /// Say we want special column copy + inline void makeSpecialColumnCopy() { + flags_ |= 16; + } + /// Say we don't want special column copy + void releaseSpecialColumnCopy(); + /// Are there zeros? + inline bool zeros() const { + return ((flags_ & 1) != 0); + } + /// Do we want special column copy + inline bool wantsSpecialColumnCopy() const { + return ((flags_ & 16) != 0); + } + /// Flags + inline int flags() const { + return flags_; + } + /// Sets flags_ correctly + inline void checkGaps() { + flags_ = (matrix_->hasGaps()) ? (flags_ | 2) : (flags_ & (~2)); + } + /// number of active columns (normally same as number of columns) + inline int numberActiveColumns() const + { return numberActiveColumns_;} + /// Set number of active columns (normally same as number of columns) + inline void setNumberActiveColumns(int value) + { numberActiveColumns_ = value;} + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix(); + /** Destructor */ + virtual ~ClpPackedMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix(const ClpPackedMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpPackedMatrix(const CoinPackedMatrix&); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpPackedMatrix (const ClpPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + ClpPackedMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /** This takes over ownership (for space reasons) */ + ClpPackedMatrix(CoinPackedMatrix * matrix); + + ClpPackedMatrix& operator=(const ClpPackedMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /// Copy contents - resizing if necessary - otherwise re-use memory + virtual void copy(const ClpPackedMatrix * from); + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /// make special row copy + void specialRowCopy(ClpSimplex * model, const ClpMatrixBase * rowCopy); + /// make special column copy + void specialColumnCopy(ClpSimplex * model); + /// Correct sequence in and out to give true value + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} +private: + /// Meat of transposeTimes by column when not scaled + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const double tolerance) const; + /// Meat of transposeTimes by column when scaled + int gutsOfTransposeTimesScaled(const double * COIN_RESTRICT pi, + const double * COIN_RESTRICT columnScale, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const double tolerance) const; + /// Meat of transposeTimes by column when not scaled and skipping + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + const double tolerance) const; + /** Meat of transposeTimes by column when not scaled and skipping + and doing part of dualColumn */ + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + int * COIN_RESTRICT spareIndex, + double * COIN_RESTRICT spareArray, + const double * COIN_RESTRICT reducedCost, + double & upperTheta, + double & bestPossible, + double acceptablePivot, + double dualTolerance, + int & numberRemaining, + const double zeroTolerance) const; + /// Meat of transposeTimes by column when scaled and skipping + int gutsOfTransposeTimesScaled(const double * COIN_RESTRICT pi, + const double * COIN_RESTRICT columnScale, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + const double tolerance) const; + /// Meat of transposeTimes by row n > K if packed - returns number nonzero + int gutsOfTransposeTimesByRowGEK(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + int numberColumns, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n > 2 if packed - returns number nonzero + int gutsOfTransposeTimesByRowGE3(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + double * COIN_RESTRICT array2, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n > 2 if packed - returns number nonzero + int gutsOfTransposeTimesByRowGE3a(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + int * COIN_RESTRICT lookup, + char * COIN_RESTRICT marked, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n == 2 if packed + void gutsOfTransposeTimesByRowEQ2(const CoinIndexedVector * piVector, CoinIndexedVector * output, + CoinIndexedVector * spareVector, const double tolerance, const double scalar) const; + /// Meat of transposeTimes by row n == 1 if packed + void gutsOfTransposeTimesByRowEQ1(const CoinIndexedVector * piVector, CoinIndexedVector * output, + const double tolerance, const double scalar) const; + /// Gets rid of special copies + void clearCopies(); + + +protected: + /// Check validity + void checkFlags(int type) const; + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Data + CoinPackedMatrix * matrix_; + /// number of active columns (normally same as number of columns) + int numberActiveColumns_; + /** Flags - + 1 - has zero elements + 2 - has gaps + 4 - has special row copy + 8 - has special column copy + 16 - wants special column copy + */ + mutable int flags_; + /// Special row copy + ClpPackedMatrix2 * rowCopy_; + /// Special column copy + ClpPackedMatrix3 * columnCopy_; + //@} +}; +#ifdef THREAD +#include +typedef struct { + double acceptablePivot; + const ClpSimplex * model; + double * spare; + int * spareIndex; + double * arrayTemp; + int * indexTemp; + int * numberInPtr; + double * bestPossiblePtr; + double * upperThetaPtr; + int * posFreePtr; + double * freePivotPtr; + int * numberOutPtr; + const unsigned short * count; + const double * pi; + const CoinBigIndex * rowStart; + const double * element; + const unsigned short * column; + int offset; + int numberInRowArray; + int numberLook; +} dualColumn0Struct; +#endif +class ClpPackedMatrix2 { + +public: + /**@name Useful methods */ + //@{ + /** Return x * -1 * A in z. + Note - x packed and z will be packed mode + Squashes small elements and knows about ClpSimplex */ + void transposeTimes(const ClpSimplex * model, + const CoinPackedMatrix * rowCopy, + const CoinIndexedVector * x, + CoinIndexedVector * spareArray, + CoinIndexedVector * z) const; + /// Returns true if copy has useful information + inline bool usefulInfo() const { + return rowStart_ != NULL; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix2(); + /** Constructor from copy. */ + ClpPackedMatrix2(ClpSimplex * model, const CoinPackedMatrix * rowCopy); + /** Destructor */ + virtual ~ClpPackedMatrix2(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix2(const ClpPackedMatrix2&); + ClpPackedMatrix2& operator=(const ClpPackedMatrix2&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of blocks + int numberBlocks_; + /// Number of rows + int numberRows_; + /// Column offset for each block (plus one at end) + int * offset_; + /// Counts of elements in each part of row + mutable unsigned short * count_; + /// Row starts + mutable CoinBigIndex * rowStart_; + /// columns within block + unsigned short * column_; + /// work arrays + double * work_; +#ifdef THREAD + pthread_t * threadId_; + dualColumn0Struct * info_; +#endif + //@} +}; +typedef struct { + CoinBigIndex startElements_; // point to data + int startIndices_; // point to column_ + int numberInBlock_; + int numberPrice_; // at beginning + int numberElements_; // number elements per column +} blockStruct; +class ClpPackedMatrix3 { + +public: + /**@name Useful methods */ + //@{ + /** Return x * -1 * A in z. + Note - x packed and z will be packed mode + Squashes small elements and knows about ClpSimplex */ + void transposeTimes(const ClpSimplex * model, + const double * pi, + CoinIndexedVector * output) const; + /// Updates two arrays for steepest + void transposeTimes2(const ClpSimplex * model, + const double * pi, CoinIndexedVector * dj1, + const double * piWeight, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix3(); + /** Constructor from copy. */ + ClpPackedMatrix3(ClpSimplex * model, const CoinPackedMatrix * columnCopy); + /** Destructor */ + virtual ~ClpPackedMatrix3(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix3(const ClpPackedMatrix3&); + ClpPackedMatrix3& operator=(const ClpPackedMatrix3&); + //@} + /**@name Sort methods */ + //@{ + /** Sort blocks */ + void sortBlocks(const ClpSimplex * model); + /// Swap one variable + void swapOne(const ClpSimplex * model, const ClpPackedMatrix * matrix, + int iColumn); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of blocks + int numberBlocks_; + /// Number of columns + int numberColumns_; + /// Column indices and reverse lookup (within block) + int * column_; + /// Starts for odd/long vectors + CoinBigIndex * start_; + /// Rows + int * row_; + /// Elements + double * element_; + /// Blocks (ordinary start at 0 and go to first block) + blockStruct * block_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpParameters.hpp b/thirdparty/linux/include/coin/ClpParameters.hpp new file mode 100644 index 0000000..7252d2b --- /dev/null +++ b/thirdparty/linux/include/coin/ClpParameters.hpp @@ -0,0 +1,126 @@ +/* $Id: ClpParameters.hpp 2046 2014-08-14 04:13:10Z tkr $ */ +// Copyright (C) 2000, 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _ClpParameters_H +#define _ClpParameters_H + +/** This is where to put any useful stuff. + +*/ +enum ClpIntParam { + /** The maximum number of iterations Clp can execute in the simplex methods + */ + ClpMaxNumIteration = 0, + /** The maximum number of iterations Clp can execute in hotstart before + terminating */ + ClpMaxNumIterationHotStart, + /** The name discipline; specifies how the solver will handle row and + column names. + - 0: Auto names: Names cannot be set by the client. Names of the form + Rnnnnnnn or Cnnnnnnn are generated on demand when a name for a + specific row or column is requested; nnnnnnn is derived from the row + or column index. Requests for a vector of names return a vector with + zero entries. + - 1: Lazy names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to the largest index of a name supplied by the client; + some entries in the vector may be null strings. + - 2: Full names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to match the constraint system, and all entries will + contain either the name specified by the client or a generated name. + */ + ClpNameDiscipline, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastIntParam +}; + +enum ClpDblParam { + /** Set Dual objective limit. This is to be used as a termination criteria + in methods where the dual objective monotonically changes (dual + simplex). */ + ClpDualObjectiveLimit, + /** Primal objective limit. This is to be used as a termination + criteria in methods where the primal objective monotonically changes + (e.g., primal simplex) */ + ClpPrimalObjectiveLimit, + /** The maximum amount the dual constraints can be violated and still be + considered feasible. */ + ClpDualTolerance, + /** The maximum amount the primal constraints can be violated and still be + considered feasible. */ + ClpPrimalTolerance, + /** Objective function constant. This the value of the constant term in + the objective function. */ + ClpObjOffset, + /// Maximum time in seconds - after, this action is as max iterations + ClpMaxSeconds, + /// Maximum wallclock running time in seconds - after, this action is as max iterations + ClpMaxWallSeconds, + /// Tolerance to use in presolve + ClpPresolveTolerance, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastDblParam +}; + + +enum ClpStrParam { + /** Name of the problem. This is the found on the Name card of + an mps file. */ + ClpProbName = 0, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastStrParam +}; + +/// Copy (I don't like complexity of Coin version) +template inline void +ClpDisjointCopyN( const T * array, const int size, T * newArray) +{ + memcpy(reinterpret_cast (newArray), array, size * sizeof(T)); +} +/// And set +template inline void +ClpFillN( T * array, const int size, T value) +{ + int i; + for (i = 0; i < size; i++) + array[i] = value; +} +/// This returns a non const array filled with input from scalar or actual array +template inline T* +ClpCopyOfArray( const T * array, const int size, T value) +{ + T * arrayNew = new T[size]; + if (array) + ClpDisjointCopyN(array, size, arrayNew); + else + ClpFillN ( arrayNew, size, value); + return arrayNew; +} + +/// This returns a non const array filled with actual array (or NULL) +template inline T* +ClpCopyOfArray( const T * array, const int size) +{ + if (array) { + T * arrayNew = new T[size]; + ClpDisjointCopyN(array, size, arrayNew); + return arrayNew; + } else { + return NULL; + } +} +/// For a structure to be used by trusted code +typedef struct { + int typeStruct; // allocated as 1,2 etc + int typeCall; + void * data; +} ClpTrustedData; +#endif diff --git a/thirdparty/linux/include/coin/ClpPdcoBase.hpp b/thirdparty/linux/include/coin/ClpPdcoBase.hpp new file mode 100644 index 0000000..cb8fd8f --- /dev/null +++ b/thirdparty/linux/include/coin/ClpPdcoBase.hpp @@ -0,0 +1,103 @@ +/* $Id: ClpPdcoBase.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPdcoBase_H +#define ClpPdcoBase_H + +#include "CoinPragma.hpp" + +#include "CoinPackedMatrix.hpp" +#include "CoinDenseVector.hpp" +class ClpInterior; + +/** Abstract base class for tailoring everything for Pcdo + + Since this class is abstract, no object of this type can be created. + + If a derived class provides all methods then all ClpPcdo algorithms + should work. + + Eventually we should be able to use ClpObjective and ClpMatrixBase. +*/ + +class ClpPdcoBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + virtual void matVecMult(ClpInterior * model, int mode, double * x, double * y) const = 0; + + virtual void getGrad(ClpInterior * model, CoinDenseVector &x, CoinDenseVector &grad) const = 0; + + virtual void getHessian(ClpInterior * model, CoinDenseVector &x, CoinDenseVector &H) const = 0; + + virtual double getObj(ClpInterior * model, CoinDenseVector &x) const = 0; + + virtual void matPrecon(ClpInterior * model, double delta, double * x, double * y) const = 0; + + //@} + //@{ + ///@name Other + /// Clone + virtual ClpPdcoBase * clone() const = 0; + /// Returns type + inline int type() const { + return type_; + }; + /// Sets type + inline void setType(int type) { + type_ = type; + }; + /// Returns size of d1 + inline int sizeD1() const { + return 1; + }; + /// Returns d1 as scalar + inline double getD1() const { + return d1_; + }; + /// Returns size of d2 + inline int sizeD2() const { + return 1; + }; + /// Returns d2 as scalar + inline double getD2() const { + return d2_; + }; + //@} + + +protected: + + /**@name Constructors, destructor
+ NOTE: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + ClpPdcoBase(); + /** Destructor (has to be public) */ +public: + virtual ~ClpPdcoBase(); +protected: + // Copy + ClpPdcoBase(const ClpPdcoBase&); + // Assignment + ClpPdcoBase& operator=(const ClpPdcoBase&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Should be dense vectors + double d1_; + double d2_; + /// type (may be useful) + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpPlusMinusOneMatrix.hpp b/thirdparty/linux/include/coin/ClpPlusMinusOneMatrix.hpp new file mode 100644 index 0000000..0cf27a4 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpPlusMinusOneMatrix.hpp @@ -0,0 +1,290 @@ +/* $Id: ClpPlusMinusOneMatrix.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPlusMinusOneMatrix_H +#define ClpPlusMinusOneMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a simple +- one matrix as derived from ClpMatrixBase. + +*/ + +class ClpPlusMinusOneMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const ; + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const; + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return indices_; + } + // and for advanced use + int * getMutableIndices() const { + return indices_; + } + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in indDel. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in indDel. */ + virtual void deleteRows(const int numDel, const int * indDel); + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#ifndef SLIM_CLP + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); +#endif + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis( + const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + virtual void releasePackedMatrix() const; + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + /// Just checks matrix valid - will say if dimensions not quite right if detail + void checkValid(bool detail) const; + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return y + A * scalar *x in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return y + x * scalar * A in y. + @pre x must be of size numRows() + @pre y must be of size numColumns() */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, double * spare = NULL) const; + /** Return x * scalar * A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x * scalar * A + y in z. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return x *A in z but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * model, + const CoinIndexedVector * pi) const; + /// Updates two arrays for steepest + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + //@} + + /**@name Other */ + //@{ + /// Return starts of +1s + inline CoinBigIndex * startPositive() const { + return startPositive_; + } + /// Return starts of -1s + inline CoinBigIndex * startNegative() const { + return startNegative_; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPlusMinusOneMatrix(); + /** Destructor */ + virtual ~ClpPlusMinusOneMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPlusMinusOneMatrix(const ClpPlusMinusOneMatrix&); + /** The copy constructor from an CoinPlusMinusOneMatrix. + If not a valid matrix then getIndices will be NULL and + startPositive[0] will have number of +1, + startPositive[1] will have number of -1, + startPositive[2] will have number of others, + */ + ClpPlusMinusOneMatrix(const CoinPackedMatrix&); + /// Constructor from arrays + ClpPlusMinusOneMatrix(int numberRows, int numberColumns, + bool columnOrdered, const int * indices, + const CoinBigIndex * startPositive, const CoinBigIndex * startNegative); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpPlusMinusOneMatrix (const ClpPlusMinusOneMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + ClpPlusMinusOneMatrix& operator=(const ClpPlusMinusOneMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /// pass in copy (object takes ownership) + void passInCopy(int numberRows, int numberColumns, + bool columnOrdered, int * indices, + CoinBigIndex * startPositive, CoinBigIndex * startNegative); + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// For fake CoinPackedMatrix + mutable CoinPackedMatrix * matrix_; + mutable int * lengths_; + /// Start of +1's for each + CoinBigIndex * COIN_RESTRICT startPositive_; + /// Start of -1's for each + CoinBigIndex * COIN_RESTRICT startNegative_; + /// Data -1, then +1 rows in pairs (row==-1 if one entry) + int * COIN_RESTRICT indices_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; +#ifdef CLP_PLUS_ONE_MATRIX + /** Other flags (could have columnOrdered_?) + 1 bit - says just +1 + */ + mutable int otherFlags_; +#endif + /// True if column ordered + bool columnOrdered_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpPresolve.hpp b/thirdparty/linux/include/coin/ClpPresolve.hpp new file mode 100644 index 0000000..5e28289 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpPresolve.hpp @@ -0,0 +1,299 @@ +/* $Id: ClpPresolve.hpp 2134 2015-03-22 16:40:43Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPresolve_H +#define ClpPresolve_H +#include "ClpSimplex.hpp" + +class CoinPresolveAction; +#include "CoinPresolveMatrix.hpp" +/** This is the Clp interface to CoinPresolve + +*/ +class ClpPresolve { +public: + /**@name Main Constructor, destructor */ + //@{ + /// Default constructor + ClpPresolve(); + + /// Virtual destructor + virtual ~ClpPresolve(); + //@} + /**@name presolve - presolves a model, transforming the model + * and saving information in the ClpPresolve object needed for postsolving. + * This underlying (protected) method is virtual; the idea is that in the future, + * one could override this method to customize how the various + * presolve techniques are applied. + + This version of presolve returns a pointer to a new presolved + model. NULL if infeasible or unbounded. + This should be paired with postsolve + below. The advantage of going back to original model is that it + will be exactly as it was i.e. 0.0 will not become 1.0e-19. + If keepIntegers is true then bounds may be tightened in + original. Bounds will be moved by up to feasibilityTolerance + to try and stay feasible. + Names will be dropped in presolved model if asked + */ + ClpSimplex * presolvedModel(ClpSimplex & si, + double feasibilityTolerance = 0.0, + bool keepIntegers = true, + int numberPasses = 5, + bool dropNames = false, + bool doRowObjective = false, + const char * prohibitedRows=NULL, + const char * prohibitedColumns=NULL); +#ifndef CLP_NO_STD + /** This version saves data in a file. The passed in model + is updated to be presolved model. + Returns non-zero if infeasible*/ + int presolvedModelToFile(ClpSimplex &si, std::string fileName, + double feasibilityTolerance = 0.0, + bool keepIntegers = true, + int numberPasses = 5, + bool dropNames = false, + bool doRowObjective = false); +#endif + /** Return pointer to presolved model, + Up to user to destroy */ + ClpSimplex * model() const; + /// Return pointer to original model + ClpSimplex * originalModel() const; + /// Set pointer to original model + void setOriginalModel(ClpSimplex * model); + + /// return pointer to original columns + const int * originalColumns() const; + /// return pointer to original rows + const int * originalRows() const; + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + */ + inline void setNonLinearValue(double value) { + nonLinearValue_ = value; + } + inline double nonLinearValue() const { + return nonLinearValue_; + } + /// Whether we want to do dual part of presolve + inline bool doDual() const { + return (presolveActions_ & 1) == 0; + } + inline void setDoDual(bool doDual) { + if (doDual) presolveActions_ &= ~1; + else presolveActions_ |= 1; + } + /// Whether we want to do singleton part of presolve + inline bool doSingleton() const { + return (presolveActions_ & 2) == 0; + } + inline void setDoSingleton(bool doSingleton) { + if (doSingleton) presolveActions_ &= ~2; + else presolveActions_ |= 2; + } + /// Whether we want to do doubleton part of presolve + inline bool doDoubleton() const { + return (presolveActions_ & 4) == 0; + } + inline void setDoDoubleton(bool doDoubleton) { + if (doDoubleton) presolveActions_ &= ~4; + else presolveActions_ |= 4; + } + /// Whether we want to do tripleton part of presolve + inline bool doTripleton() const { + return (presolveActions_ & 8) == 0; + } + inline void setDoTripleton(bool doTripleton) { + if (doTripleton) presolveActions_ &= ~8; + else presolveActions_ |= 8; + } + /// Whether we want to do tighten part of presolve + inline bool doTighten() const { + return (presolveActions_ & 16) == 0; + } + inline void setDoTighten(bool doTighten) { + if (doTighten) presolveActions_ &= ~16; + else presolveActions_ |= 16; + } + /// Whether we want to do forcing part of presolve + inline bool doForcing() const { + return (presolveActions_ & 32) == 0; + } + inline void setDoForcing(bool doForcing) { + if (doForcing) presolveActions_ &= ~32; + else presolveActions_ |= 32; + } + /// Whether we want to do impliedfree part of presolve + inline bool doImpliedFree() const { + return (presolveActions_ & 64) == 0; + } + inline void setDoImpliedFree(bool doImpliedfree) { + if (doImpliedfree) presolveActions_ &= ~64; + else presolveActions_ |= 64; + } + /// Whether we want to do dupcol part of presolve + inline bool doDupcol() const { + return (presolveActions_ & 128) == 0; + } + inline void setDoDupcol(bool doDupcol) { + if (doDupcol) presolveActions_ &= ~128; + else presolveActions_ |= 128; + } + /// Whether we want to do duprow part of presolve + inline bool doDuprow() const { + return (presolveActions_ & 256) == 0; + } + inline void setDoDuprow(bool doDuprow) { + if (doDuprow) presolveActions_ &= ~256; + else presolveActions_ |= 256; + } + /// Whether we want to do dependency part of presolve + inline bool doDependency() const { + return (presolveActions_ & 32768) != 0; + } + inline void setDoDependency(bool doDependency) { + if (doDependency) presolveActions_ |= 32768; + else presolveActions_ &= ~32768; + } + /// Whether we want to do singleton column part of presolve + inline bool doSingletonColumn() const { + return (presolveActions_ & 512) == 0; + } + inline void setDoSingletonColumn(bool doSingleton) { + if (doSingleton) presolveActions_ &= ~512; + else presolveActions_ |= 512; + } + /// Whether we want to do gubrow part of presolve + inline bool doGubrow() const { + return (presolveActions_ & 1024) == 0; + } + inline void setDoGubrow(bool doGubrow) { + if (doGubrow) presolveActions_ &= ~1024; + else presolveActions_ |= 1024; + } + /// Whether we want to do twoxtwo part of presolve + inline bool doTwoxTwo() const { + return (presolveActions_ & 2048) != 0; + } + inline void setDoTwoxtwo(bool doTwoxTwo) { + if (!doTwoxTwo) presolveActions_ &= ~2048; + else presolveActions_ |= 2048; + } + /// Whether we want to allow duplicate intersections + inline bool doIntersection() const { + return (presolveActions_ & 4096) != 0; + } + inline void setDoIntersection(bool doIntersection) { + if (doIntersection) presolveActions_ &= ~4096; + else presolveActions_ |= 4096; + } + /** How much we want to zero small values from aggregation - ratio + 0 - 1.0e-12, 1 1.0e-11, 2 1.0e-10, 3 1.0e-9 */ + inline int zeroSmall() const { + return (presolveActions_&(8192|16384))>>13; + } + inline void setZeroSmall(int value) { + presolveActions_ &= ~(8192|16384); + presolveActions_ |= value<<13; + } + /// Set whole group + inline int presolveActions() const { + return presolveActions_ & 0xffff; + } + inline void setPresolveActions(int action) { + presolveActions_ = (presolveActions_ & 0xffff0000) | (action & 0xffff); + } + /// Substitution level + inline void setSubstitution(int value) { + substitution_ = value; + } + /// Asks for statistics + inline void statistics() { + presolveActions_ |= 0x80000000; + } + /// Return presolve status (0,1,2) + int presolveStatus() const; + + /**@name postsolve - postsolve the problem. If the problem + has not been solved to optimality, there are no guarantees. + If you are using an algorithm like simplex that has a concept + of "basic" rows/cols, then set updateStatus + + Note that if you modified the original problem after presolving, + then you must ``undo'' these modifications before calling postsolve. + This version updates original*/ + virtual void postsolve(bool updateStatus = true); + + /// Gets rid of presolve actions (e.g.when infeasible) + void destroyPresolve(); + + /**@name private or protected data */ +private: + /// Original model - must not be destroyed before postsolve + ClpSimplex * originalModel_; + + /// ClpPresolved model - up to user to destroy by deleteClpPresolvedModel + ClpSimplex * presolvedModel_; + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + One could also allow for cases where sign of coefficient is known. + */ + double nonLinearValue_; + /// Original column numbers + int * originalColumn_; + /// Original row numbers + int * originalRow_; + /// Row objective + double * rowObjective_; + /// The list of transformations applied. + const CoinPresolveAction *paction_; + + /// The postsolved problem will expand back to its former size + /// as postsolve transformations are applied. + /// It is efficient to allocate data structures for the final size + /// of the problem rather than expand them as needed. + /// These fields give the size of the original problem. + int ncols_; + int nrows_; + CoinBigIndex nelems_; + /// Number of major passes + int numberPasses_; + /// Substitution level + int substitution_; +#ifndef CLP_NO_STD + /// Name of saved model file + std::string saveFile_; +#endif + /** Whether we want to skip dual part of presolve etc. + 512 bit allows duplicate column processing on integer columns + and dual stuff on integers + */ + int presolveActions_; +protected: + /// If you want to apply the individual presolve routines differently, + /// or perhaps add your own to the mix, + /// define a derived class and override this method + virtual const CoinPresolveAction *presolve(CoinPresolveMatrix *prob); + + /// Postsolving is pretty generic; just apply the transformations + /// in reverse order. + /// You will probably only be interested in overriding this method + /// if you want to add code to test for consistency + /// while debugging new presolve techniques. + virtual void postsolve(CoinPostsolveMatrix &prob); + /** This is main part of Presolve */ + virtual ClpSimplex * gutsOfPresolvedModel(ClpSimplex * originalModel, + double feasibilityTolerance, + bool keepIntegers, + int numberPasses, + bool dropNames, + bool doRowObjective, + const char * prohibitedRows=NULL, + const char * prohibitedColumns=NULL); +}; +#endif diff --git a/thirdparty/linux/include/coin/ClpPrimalColumnDantzig.hpp b/thirdparty/linux/include/coin/ClpPrimalColumnDantzig.hpp new file mode 100644 index 0000000..7289ead --- /dev/null +++ b/thirdparty/linux/include/coin/ClpPrimalColumnDantzig.hpp @@ -0,0 +1,72 @@ +/* $Id: ClpPrimalColumnDantzig.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalColumnDantzig_H +#define ClpPrimalColumnDantzig_H + +#include "ClpPrimalColumnPivot.hpp" + +//############################################################################# + +/** Primal Column Pivot Dantzig Algorithm Class + +This is simplest choice - choose largest infeasibility + +*/ + +class ClpPrimalColumnDantzig : public ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none. + Lumbers over all columns - slow + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + Can just do full price if you really want to be slow + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + + /// Just sets model + virtual void saveWeights(ClpSimplex * model, int) { + model_ = model; + } + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpPrimalColumnDantzig(); + + /// Copy constructor + ClpPrimalColumnDantzig(const ClpPrimalColumnDantzig &); + + /// Assignment operator + ClpPrimalColumnDantzig & operator=(const ClpPrimalColumnDantzig& rhs); + + /// Destructor + virtual ~ClpPrimalColumnDantzig (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpPrimalColumnPivot.hpp b/thirdparty/linux/include/coin/ClpPrimalColumnPivot.hpp new file mode 100644 index 0000000..678da30 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpPrimalColumnPivot.hpp @@ -0,0 +1,155 @@ +/* $Id: ClpPrimalColumnPivot.hpp 1732 2011-05-31 08:09:41Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalcolumnPivot_H +#define ClpPrimalcolumnPivot_H + +class ClpSimplex; +class CoinIndexedVector; + +//############################################################################# + +/** Primal Column Pivot Abstract Base Class + +Abstract Base Class for describing an interface to an algorithm +to choose column pivot in primal simplex algorithm. For some algorithms +e.g. Dantzig choice then some functions may be null. For Dantzig +the only one of any importance is pivotColumn. + +If you wish to inherit from this look at ClpPrimalColumnDantzig.cpp +as that is simplest version. +*/ + +class ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none + + Normally updates reduced costs using result of last iteration + before selecting incoming column. + + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + + Inside pivotColumn the pivotRow_ and reduced cost from last iteration + are also used. + + So in the simplest case i.e. feasible we compute the row of the + tableau corresponding to last pivot and add a multiple of this + to current reduced costs. + + We can use other arrays to help updates + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2) = 0; + + /// Updates weights - part 1 (may be empty) + virtual void updateWeights(CoinIndexedVector * input); + + /** Saves any weights round factorization as pivot rows may change + Will be empty unless steepest edge (will save model) + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) forces some initialization e.g. weights + Also sets model + */ + virtual void saveWeights(ClpSimplex * model, int mode) = 0; + /** Signals pivot row choice: + -2 (default) - use normal pivot row choice + -1 to numberRows-1 - use this (will be checked) + way should be -1 to go to lower bound, +1 to upper bound + */ + virtual int pivotRow(double & way) { + way = 0; + return -2; + } + /// Gets rid of all arrays (may be empty) + virtual void clearArrays(); + /// Returns true if would not find any column + virtual bool looksOptimal() const { + return looksOptimal_; + } + /// Sets optimality flag (for advanced use) + virtual void setLooksOptimal(bool flag) { + looksOptimal_ = flag; + } + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpPrimalColumnPivot(); + + /// Copy constructor + ClpPrimalColumnPivot(const ClpPrimalColumnPivot &); + + /// Assignment operator + ClpPrimalColumnPivot & operator=(const ClpPrimalColumnPivot& rhs); + + /// Destructor + virtual ~ClpPrimalColumnPivot (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const = 0; + + //@} + + ///@name Other + //@{ + /// Returns model + inline ClpSimplex * model() { + return model_; + } + /// Sets model + inline void setModel(ClpSimplex * newmodel) { + model_ = newmodel; + } + + /// Returns type (above 63 is extra information) + inline int type() { + return type_; + } + + /** Returns number of extra columns for sprint algorithm - 0 means off. + Also number of iterations before recompute + */ + virtual int numberSprintColumns(int & numberIterations) const; + /// Switch off sprint idea + virtual void switchOffSprint(); + /// Called when maximum pivots changes + virtual void maximumPivotsChanged() {} + + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Pointer to model + ClpSimplex * model_; + /// Type of column pivot algorithm + int type_; + /// Says if looks optimal (normally computed) + bool looksOptimal_; + //@} +}; +#ifndef CLP_PRIMAL_SLACK_MULTIPLIER +#define CLP_PRIMAL_SLACK_MULTIPLIER 1.01 +#endif +#endif diff --git a/thirdparty/linux/include/coin/ClpPrimalColumnSteepest.hpp b/thirdparty/linux/include/coin/ClpPrimalColumnSteepest.hpp new file mode 100644 index 0000000..2da7542 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpPrimalColumnSteepest.hpp @@ -0,0 +1,247 @@ +/* $Id: ClpPrimalColumnSteepest.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalColumnSteepest_H +#define ClpPrimalColumnSteepest_H + +#include "ClpPrimalColumnPivot.hpp" +#include + +//############################################################################# +class CoinIndexedVector; + + +/** Primal Column Pivot Steepest Edge Algorithm Class + +See Forrest-Goldfarb paper for algorithm + +*/ + + +class ClpPrimalColumnSteepest : public ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none. + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + Parts of operation split out into separate functions for + profiling and speed + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// For quadratic or funny nonlinearities + int pivotColumnOldMethod(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Just update djs + void justDjs(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs doing partial pricing (dantzig) + int partialPricing(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + int numberWanted, + int numberLook); + /// Update djs, weights for Devex using djs + void djsAndDevex(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Steepest using djs + void djsAndSteepest(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Devex using pivot row + void djsAndDevex2(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Steepest using pivot row + void djsAndSteepest2(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update weights for Devex + void justDevex(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update weights for Steepest + void justSteepest(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Updates two arrays for steepest + void transposeTimes2(const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + CoinIndexedVector * spare, double scaleFactor); + + /// Updates weights - part 1 - also checks accuracy + virtual void updateWeights(CoinIndexedVector * input); + + /// Checks accuracy - just for debug + void checkAccuracy(int sequence, double relativeTolerance, + CoinIndexedVector * rowArray1, + CoinIndexedVector * rowArray2); + + /// Initialize weights + void initializeWeights(); + + /** Save weights - this may initialize weights as well + mode is - + 1) before factorization + 2) after factorization + 3) just redo infeasibilities + 4) restore weights + 5) at end of values pass (so need initialization) + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// Gets rid of last update + virtual void unrollWeights(); + /// Gets rid of all arrays + virtual void clearArrays(); + /// Returns true if would not find any column + virtual bool looksOptimal() const; + /// Called when maximum pivots changes + virtual void maximumPivotsChanged(); + //@} + + /**@name gets and sets */ + //@{ + /// Mode + inline int mode() const { + return mode_; + } + /** Returns number of extra columns for sprint algorithm - 0 means off. + Also number of iterations before recompute + */ + virtual int numberSprintColumns(int & numberIterations) const; + /// Switch off sprint idea + virtual void switchOffSprint(); + +//@} + + /** enums for persistence + */ + enum Persistence { + normal = 0x00, // create (if necessary) and destroy + keep = 0x01 // create (if necessary) and leave + }; + + ///@name Constructors and destructors + //@{ + /** Default Constructor + 0 is exact devex, 1 full steepest, 2 is partial exact devex + 3 switches between 0 and 2 depending on factorization + 4 starts as partial dantzig/devex but then may switch between 0 and 2. + By partial exact devex is meant that the weights are updated as normal + but only part of the nonbasic variables are scanned. + This can be faster on very easy problems. + */ + ClpPrimalColumnSteepest(int mode = 3); + + /// Copy constructor + ClpPrimalColumnSteepest(const ClpPrimalColumnSteepest & rhs); + + /// Assignment operator + ClpPrimalColumnSteepest & operator=(const ClpPrimalColumnSteepest& rhs); + + /// Destructor + virtual ~ClpPrimalColumnSteepest (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const; + + //@} + + ///@name Private functions to deal with devex + /** reference would be faster using ClpSimplex's status_, + but I prefer to keep modularity. + */ + inline bool reference(int i) const { + return ((reference_[i>>5] >> (i & 31)) & 1) != 0; + } + inline void setReference(int i, bool trueFalse) { + unsigned int & value = reference_[i>>5]; + int bit = i & 31; + if (trueFalse) + value |= (1 << bit); + else + value &= ~(1 << bit); + } + /// Set/ get persistence + inline void setPersistence(Persistence life) { + persistence_ = life; + } + inline Persistence persistence() const { + return persistence_ ; + } + + //@} + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + // Update weight + double devex_; + /// weight array + double * weights_; + /// square of infeasibility array (just for infeasible columns) + CoinIndexedVector * infeasible_; + /// alternate weight array (so we can unroll) + CoinIndexedVector * alternateWeights_; + /// save weight array (so we can use checkpoint) + double * savedWeights_; + // Array for exact devex to say what is in reference framework + unsigned int * reference_; + /** Status + 0) Normal + -1) Needs initialization + 1) Weights are stored by sequence number + */ + int state_; + /** + 0 is exact devex, 1 full steepest, 2 is partial exact devex + 3 switches between 0 and 2 depending on factorization + 4 starts as partial dantzig/devex but then may switch between 0 and 2. + 5 is always partial dantzig + By partial exact devex is meant that the weights are updated as normal + but only part of the nonbasic variables are scanned. + This can be faster on very easy problems. + + New dubious option is >=10 which does mini-sprint + + */ + int mode_; + /// Life of weights + Persistence persistence_; + /// Number of times switched from partial dantzig to 0/2 + int numberSwitched_; + // This is pivot row (or pivot sequence round re-factorization) + int pivotSequence_; + // This is saved pivot sequence + int savedPivotSequence_; + // This is saved outgoing variable + int savedSequenceOut_; + // Iteration when last rectified + int lastRectified_; + // Size of factorization at invert (used to decide algorithm) + int sizeFactorization_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpQuadraticObjective.hpp b/thirdparty/linux/include/coin/ClpQuadraticObjective.hpp new file mode 100644 index 0000000..a52b097 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpQuadraticObjective.hpp @@ -0,0 +1,155 @@ +/* $Id: ClpQuadraticObjective.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpQuadraticObjective_H +#define ClpQuadraticObjective_H + +#include "ClpObjective.hpp" +#include "CoinPackedMatrix.hpp" + +//############################################################################# + +/** Quadratic Objective Class + +*/ + +class ClpQuadraticObjective : public ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns gradient. If Quadratic then solution may be NULL, + also returns an offset (to be added to current one) + If refresh is false then uses last solution + Uses model for scaling + includeLinear 0 - no, 1 as is, 2 as feasible + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, double & offset, bool refresh, + int includeLinear = 2); + /// Resize objective + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts); + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj); + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const ; + virtual void resize(int newNumberColumns) ; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale objective + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which); + + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpQuadraticObjective(); + + /// Constructor from objective + ClpQuadraticObjective(const double * linearObjective, int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element, + int numberExtendedColumns_ = -1); + + /** Copy constructor . + If type is -1 then make sure half symmetric, + if +1 then make sure full + */ + ClpQuadraticObjective(const ClpQuadraticObjective & rhs, int type = 0); + /** Subset constructor. Duplicates are allowed + and order is as given. + */ + ClpQuadraticObjective (const ClpQuadraticObjective &rhs, int numberColumns, + const int * whichColumns) ; + + /// Assignment operator + ClpQuadraticObjective & operator=(const ClpQuadraticObjective& rhs); + + /// Destructor + virtual ~ClpQuadraticObjective (); + + /// Clone + virtual ClpObjective * clone() const; + /** Subset clone. Duplicates are allowed + and order is as given. + */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + /** Load up quadratic objective. This is stored as a CoinPackedMatrix */ + void loadQuadraticObjective(const int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element, + int numberExtendedColumns = -1); + void loadQuadraticObjective ( const CoinPackedMatrix& matrix); + /// Get rid of quadratic objective + void deleteQuadraticObjective(); + //@} + ///@name Gets and sets + //@{ + /// Quadratic objective + inline CoinPackedMatrix * quadraticObjective() const { + return quadraticObjective_; + } + /// Linear objective + inline double * linearObjective() const { + return objective_; + } + /// Length of linear objective which could be bigger + inline int numberExtendedColumns() const { + return numberExtendedColumns_; + } + /// Number of columns in quadratic objective + inline int numberColumns() const { + return numberColumns_; + } + /// If a full or half matrix + inline bool fullMatrix() const { + return fullMatrix_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Quadratic objective + CoinPackedMatrix * quadraticObjective_; + /// Objective + double * objective_; + /// Gradient + double * gradient_; + /// Useful to have number of columns about + int numberColumns_; + /// Also length of linear objective which could be bigger + int numberExtendedColumns_; + /// True if full symmetric matrix, false if half + bool fullMatrix_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpSimplex.hpp b/thirdparty/linux/include/coin/ClpSimplex.hpp new file mode 100644 index 0000000..bab4506 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpSimplex.hpp @@ -0,0 +1,1797 @@ +/* $Id: ClpSimplex.hpp 2114 2015-02-10 12:12:46Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplex_H +#define ClpSimplex_H + +#include +#include +#include "ClpModel.hpp" +#include "ClpMatrixBase.hpp" +#include "ClpSolve.hpp" +#include "ClpConfig.h" +class ClpDualRowPivot; +class ClpPrimalColumnPivot; +class ClpFactorization; +class CoinIndexedVector; +class ClpNonLinearCost; +class ClpNodeStuff; +class CoinStructuredModel; +class OsiClpSolverInterface; +class CoinWarmStartBasis; +class ClpDisasterHandler; +class ClpConstraint; +/* + May want to use Clp defaults so that with ABC defined but not used + it behaves as Clp (and ABC used will be different than if not defined) + */ +#ifdef ABC_INHERIT +#ifndef CLP_INHERIT_MODE +#define CLP_INHERIT_MODE 1 +#endif +#ifndef ABC_CLP_DEFAULTS +#define ABC_CLP_DEFAULTS 0 +#endif +#else +#undef ABC_CLP_DEFAULTS +#define ABC_CLP_DEFAULTS 1 +#endif +#ifdef CLP_HAS_ABC +#include "AbcCommon.hpp" +class AbcTolerancesEtc; +class AbcSimplex; +#include "CoinAbcCommon.hpp" +#endif +/** This solves LPs using the simplex method + + It inherits from ClpModel and all its arrays are created at + algorithm time. Originally I tried to work with model arrays + but for simplicity of coding I changed to single arrays with + structural variables then row variables. Some coding is still + based on old style and needs cleaning up. + + For a description of algorithms: + + for dual see ClpSimplexDual.hpp and at top of ClpSimplexDual.cpp + for primal see ClpSimplexPrimal.hpp and at top of ClpSimplexPrimal.cpp + + There is an algorithm data member. + for primal variations + and - for dual variations + +*/ + +class ClpSimplex : public ClpModel { + friend void ClpSimplexUnitTest(const std::string & mpsDir); + +public: + /** enums for status of various sorts. + First 4 match CoinWarmStartBasis, + isFixed means fixed at lower bound and out of basis + */ + enum Status { + isFree = 0x00, + basic = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03, + superBasic = 0x04, + isFixed = 0x05 + }; + // For Dual + enum FakeBound { + noFake = 0x00, + lowerFake = 0x01, + upperFake = 0x02, + bothFake = 0x03 + }; + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSimplex (bool emptyMessages = false ); + + /** Copy constructor. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) + */ + ClpSimplex(const ClpSimplex & rhs, int scalingMode = -1); + /** Copy constructor from model. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) + */ + ClpSimplex(const ClpModel & rhs, int scalingMode = -1); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + Can optionally modify rhs to take into account variables NOT in list + in this case duplicates are not allowed (also see getbackSolution) + */ + ClpSimplex (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true, + bool fixOthers = false); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + Can optionally modify rhs to take into account variables NOT in list + in this case duplicates are not allowed (also see getbackSolution) + */ + ClpSimplex (const ClpSimplex * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true, + bool fixOthers = false); + /** This constructor modifies original ClpSimplex and stores + original stuff in created ClpSimplex. It is only to be used in + conjunction with originalModel */ + ClpSimplex (ClpSimplex * wholeModel, + int numberColumns, const int * whichColumns); + /** This copies back stuff from miniModel and then deletes miniModel. + Only to be used with mini constructor */ + void originalModel(ClpSimplex * miniModel); + inline int abcState() const + { return abcState_;} + inline void setAbcState(int state) + { abcState_=state;} +#ifdef ABC_INHERIT + inline AbcSimplex * abcSimplex() const + { return abcSimplex_;} + inline void setAbcSimplex(AbcSimplex * simplex) + { abcSimplex_=simplex;} + /// Returns 0 if dual can be skipped + int doAbcDual(); + /// Returns 0 if primal can be skipped + int doAbcPrimal(int ifValuesPass); +#endif + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + void setPersistenceFlag(int value); + /// Save a copy of model with certain state - normally without cuts + void makeBaseModel(); + /// Switch off base model + void deleteBaseModel(); + /// See if we have base model + inline ClpSimplex * baseModel() const { + return baseModel_; + } + /** Reset to base model (just size and arrays needed) + If model NULL use internal copy + */ + void setToBaseModel(ClpSimplex * model = NULL); + /// Assignment operator. This copies the data + ClpSimplex & operator=(const ClpSimplex & rhs); + /// Destructor + ~ClpSimplex ( ); + // Ones below are just ClpModel with some changes + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • rowub: all rows have upper bound infinity +
  • rowlb: all rows have lower bound -infinity +
  • obj: all variables have 0 objective coefficient +
+ */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** This loads a model from a coinModel object - returns number of errors. + If keepSolution true and size is same as current then + keeps current status and solution + */ + int loadProblem ( CoinModel & modelObject, bool keepSolution = false); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /// Read GMPL files from the given filenames + int readGMPL(const char *filename, const char * dataName, + bool keepNames = false); + /// Read file in LP format from file with name filename. + /// See class CoinLpIO for description of this format. + int readLp(const char *filename, const double epsilon = 1e-5); + /** Borrow model. This is so we dont have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm. + This is same as ClpModel one, but sets scaling on etc. */ + void borrowModel(ClpModel & otherModel); + void borrowModel(ClpSimplex & otherModel); + /// Pass in Event handler (cloned and deleted at end) + void passInEventHandler(const ClpEventHandler * eventHandler); + /// Puts solution back into small model + void getbackSolution(const ClpSimplex & smallModel, const int * whichRow, const int * whichColumn); + /** Load nonlinear part of problem from AMPL info + Returns 0 if linear + 1 if quadratic objective + 2 if quadratic constraints + 3 if nonlinear objective + 4 if nonlinear constraints + -1 on failure + */ + int loadNonLinear(void * info, int & numberConstraints, + ClpConstraint ** & constraints); +#ifdef ABC_INHERIT + /// Loads tolerances etc + void loadTolerancesEtc(const AbcTolerancesEtc & data); + /// Unloads tolerances etc + void unloadTolerancesEtc(AbcTolerancesEtc & data); +#endif + //@} + + /**@name Functions most useful to user */ + //@{ + /** General solve algorithm which can do presolve. + See ClpSolve.hpp for options + */ + int initialSolve(ClpSolve & options); + /// Default initial solve + int initialSolve(); + /// Dual initial solve + int initialDualSolve(); + /// Primal initial solve + int initialPrimalSolve(); + /// Barrier initial solve + int initialBarrierSolve(); + /// Barrier initial solve, not to be followed by crossover + int initialBarrierNoCrossSolve(); + /** Dual algorithm - see ClpSimplexDual.hpp for method. + ifValuesPass==2 just does values pass and then stops. + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + */ + int dual(int ifValuesPass = 0, int startFinishOptions = 0); + // If using Debug + int dualDebug(int ifValuesPass = 0, int startFinishOptions = 0); + /** Primal algorithm - see ClpSimplexPrimal.hpp for method. + ifValuesPass==2 just does values pass and then stops. + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + */ + int primal(int ifValuesPass = 0, int startFinishOptions = 0); + /** Solves nonlinear problem using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + */ + int nonlinearSLP(int numberPasses, double deltaTolerance); + /** Solves problem with nonlinear constraints using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + */ + int nonlinearSLP(int numberConstraints, ClpConstraint ** constraints, + int numberPasses, double deltaTolerance); + /** Solves using barrier (assumes you have good cholesky factor code). + Does crossover to simplex if asked*/ + int barrier(bool crossover = true); + /** Solves non-linear using reduced gradient. Phase = 0 get feasible, + =1 use solution */ + int reducedGradient(int phase = 0); + /// Solve using structure of model and maybe in parallel + int solve(CoinStructuredModel * model); +#ifdef ABC_INHERIT + /** solvetype 0 for dual, 1 for primal + startup 1 for values pass + interrupt whether to pass across interrupt handler + add 10 to return AbcSimplex + */ + AbcSimplex * dealWithAbc(int solveType,int startUp,bool interrupt=false); + //void dealWithAbc(int solveType,int startUp,bool interrupt=false); +#endif + /** This loads a model from a CoinStructuredModel object - returns number of errors. + If originalOrder then keep to order stored in blocks, + otherwise first column/rows correspond to first block - etc. + If keepSolution true and size is same as current then + keeps current status and solution + */ + int loadProblem ( CoinStructuredModel & modelObject, + bool originalOrder = true, bool keepSolution = false); + /** + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + + return code as dual/primal + */ + int cleanup(int cleanupScaling); + /** Dual ranging. + This computes increase/decrease in cost for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + For non-basic variables the information is trivial to compute and the change in cost is just minus the + reduced cost and the sequence number will be that of the non-basic variables. + For basic variables a ratio test is between the reduced costs for non-basic variables + and the row of the tableau corresponding to the basic variable. + The increase/decrease value is always >= 0.0 + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + If valueIncrease/Decrease not NULL (both must be NULL or both non NULL) then these are filled with + the value of variable if such a change in cost were made (the existing bounds are ignored) + + Returns non-zero if infeasible unbounded etc + */ + int dualRanging(int numberCheck, const int * which, + double * costIncrease, int * sequenceIncrease, + double * costDecrease, int * sequenceDecrease, + double * valueIncrease = NULL, double * valueDecrease = NULL); + /** Primal ranging. + This computes increase/decrease in value for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + This should only be used for non-basic variabls as otherwise information is pretty useless + For basic variables the sequence number will be that of the basic variables. + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + Returns non-zero if infeasible unbounded etc + */ + int primalRanging(int numberCheck, const int * which, + double * valueIncrease, int * sequenceIncrease, + double * valueDecrease, int * sequenceDecrease); + /** + Modifies coefficients etc and if necessary pivots in and out. + All at same status will be done (basis may go singular). + User can tell which others have been done (i.e. if status matches). + If called from outside will change status and return 0. + If called from event handler returns non-zero if user has to take action. + indices>=numberColumns are slacks (obviously no coefficients) + status array is (char) Status enum + */ + int modifyCoefficientsAndPivot(int number, + const int * which, + const CoinBigIndex * start, + const int * row, + const double * newCoefficient, + const unsigned char * newStatus=NULL, + const double * newLower=NULL, + const double * newUpper=NULL, + const double * newObjective=NULL); + /** Take out duplicate rows (includes scaled rows and intersections). + On exit whichRows has rows to delete - return code is number can be deleted + or -1 if would be infeasible. + If tolerance is -1.0 use primalTolerance for equality rows and infeasibility + If cleanUp not zero then spend more time trying to leave more stable row + and make row bounds exact multiple of cleanUp if close enough + */ + int outDuplicateRows(int numberLook,int * whichRows, bool noOverlaps=false, double tolerance=-1.0, + double cleanUp=0.0); + /** Try simple crash like techniques to get closer to primal feasibility + returns final sum of infeasibilities */ + double moveTowardsPrimalFeasible(); + /** Try simple crash like techniques to remove super basic slacks + but only if > threshold */ + void removeSuperBasicSlacks(int threshold=0); + /** Mini presolve (faster) + Char arrays must be numberRows and numberColumns long + on entry second part must be filled in as follows - + 0 - possible + >0 - take out and do something (depending on value - TBD) + -1 row/column can't vanish but can have entries removed/changed + -2 don't touch at all + on exit <=0 ones will be in presolved problem + struct will be created and will be long enough + (information on length etc in first entry) + user must delete struct + */ + ClpSimplex * miniPresolve(char * rowType, char * columnType,void ** info); + /// After mini presolve + void miniPostsolve(const ClpSimplex * presolvedModel,void * info); + /// mini presolve and solve + void miniSolve(char * rowType, char *columnType,int algorithm, int startUp); + /** Write the basis in MPS format to the specified file. + If writeValues true writes values of structurals + (and adds VALUES to end of NAME card) + + Row and column names may be null. + formatType is +
    +
  • 0 - normal +
  • 1 - extra accuracy +
  • 2 - IEEE hex (later) +
+ + Returns non-zero on I/O error + */ + int writeBasis(const char *filename, + bool writeValues = false, + int formatType = 0) const; + /** Read a basis from the given filename, + returns -1 on file error, 0 if no values, 1 if values */ + int readBasis(const char *filename); + /// Returns a basis (to be deleted by user) + CoinWarmStartBasis * getBasis() const; + /// Passes in factorization + void setFactorization( ClpFactorization & factorization); + // Swaps factorization + ClpFactorization * swapFactorization( ClpFactorization * factorization); + /// Copies in factorization to existing one + void copyFactorization( ClpFactorization & factorization); + /** Tightens primal bounds to make dual faster. Unless + fixed or doTight>10, bounds are slightly looser than they could be. + This is to make dual go faster and is probably not needed + with a presolve. Returns non-zero if problem infeasible. + + Fudge for branch and bound - put bounds on columns of factor * + largest value (at continuous) - should improve stability + in branch and bound on infeasible branches (0.0 is off) + */ + int tightenPrimalBounds(double factor = 0.0, int doTight = 0, bool tightIntegers = false); + /** Crash - at present just aimed at dual, returns + -2 if dual preferred and crash basis created + -1 if dual preferred and all slack basis preferred + 0 if basis going in was not all slack + 1 if primal preferred and all slack basis preferred + 2 if primal preferred and crash basis created. + + if gap between bounds <="gap" variables can be flipped + ( If pivot -1 then can be made super basic!) + + If "pivot" is + -1 No pivoting - always primal + 0 No pivoting (so will just be choice of algorithm) + 1 Simple pivoting e.g. gub + 2 Mini iterations + */ + int crash(double gap, int pivot); + /// Sets row pivot choice algorithm in dual + void setDualRowPivotAlgorithm(ClpDualRowPivot & choice); + /// Sets column pivot choice algorithm in primal + void setPrimalColumnPivotAlgorithm(ClpPrimalColumnPivot & choice); + /// Create a hotstart point of the optimization process + void markHotStart(void * & saveStuff); + /// Optimize starting from the hotstart + void solveFromHotStart(void * saveStuff); + /// Delete the snapshot + void unmarkHotStart(void * saveStuff); + /** For strong branching. On input lower and upper are new bounds + while on output they are change in objective function values + (>1.0e50 infeasible). + Return code is 0 if nothing interesting, -1 if infeasible both + ways and +1 if infeasible one way (check values to see which one(s)) + Solutions are filled in as well - even down, odd up - also + status and number of iterations + */ + int strongBranching(int numberVariables, const int * variables, + double * newLower, double * newUpper, + double ** outputSolution, + int * outputStatus, int * outputIterations, + bool stopOnFirstInfeasible = true, + bool alwaysFinish = false, + int startFinishOptions = 0); + /// Fathom - 1 if solution + int fathom(void * stuff); + /** Do up to N deep - returns + -1 - no solution nNodes_ valid nodes + >= if solution and that node gives solution + ClpNode array is 2**N long. Values for N and + array are in stuff (nNodes_ also in stuff) */ + int fathomMany(void * stuff); + /// Double checks OK + double doubleCheck(); + /// Starts Fast dual2 + int startFastDual2(ClpNodeStuff * stuff); + /// Like Fast dual + int fastDual2(ClpNodeStuff * stuff); + /// Stops Fast dual2 + void stopFastDual2(ClpNodeStuff * stuff); + /** Deals with crunch aspects + mode 0 - in + 1 - out with solution + 2 - out without solution + returns small model or NULL + */ + ClpSimplex * fastCrunch(ClpNodeStuff * stuff, int mode); + //@} + + /**@name Needed for functionality of OsiSimplexInterface */ + //@{ + /** Pivot in a variable and out a variable. Returns 0 if okay, + 1 if inaccuracy forced re-factorization, -1 if would be singular. + Also updates primal/dual infeasibilities. + Assumes sequenceIn_ and pivotRow_ set and also directionIn and Out. + */ + int pivot(); + + /** Pivot in a variable and choose an outgoing one. Assumes primal + feasible - will not go through a bound. Returns step length in theta + Returns ray in ray_ (or NULL if no pivot) + Return codes as before but -1 means no acceptable pivot + */ + int primalPivotResult(); + + /** Pivot out a variable and choose an incoing one. Assumes dual + feasible - will not go through a reduced cost. + Returns step length in theta + Return codes as before but -1 means no acceptable pivot + */ + int dualPivotResultPart1(); + /** Do actual pivot + state is 0 if need tableau column, 1 if in rowArray_[1] + */ + int pivotResultPart2(int algorithm,int state); + + /** Common bits of coding for dual and primal. Return 0 if okay, + 1 if bad matrix, 2 if very bad factorization + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + + */ + int startup(int ifValuesPass, int startFinishOptions = 0); + void finish(int startFinishOptions = 0); + + /** Factorizes and returns true if optimal. Used by user */ + bool statusOfProblem(bool initial = false); + /// If user left factorization frequency then compute + void defaultFactorizationFrequency(); + /// Copy across enabled stuff from one solver to another + void copyEnabledStuff(const ClpSimplex * rhs); + //@} + + /**@name most useful gets and sets */ + //@{ + /// If problem is primal feasible + inline bool primalFeasible() const { + return (numberPrimalInfeasibilities_ == 0); + } + /// If problem is dual feasible + inline bool dualFeasible() const { + return (numberDualInfeasibilities_ == 0); + } + /// factorization + inline ClpFactorization * factorization() const { + return factorization_; + } + /// Sparsity on or off + bool sparseFactorization() const; + void setSparseFactorization(bool value); + /// Factorization frequency + int factorizationFrequency() const; + void setFactorizationFrequency(int value); + /// Dual bound + inline double dualBound() const { + return dualBound_; + } + void setDualBound(double value); + /// Infeasibility cost + inline double infeasibilityCost() const { + return infeasibilityCost_; + } + void setInfeasibilityCost(double value); + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + /** Perturbation: + 50 - switch on perturbation + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + others are for playing + */ + inline int perturbation() const { + return perturbation_; + } + void setPerturbation(int value); + /// Current (or last) algorithm + inline int algorithm() const { + return algorithm_; + } + /// Set algorithm + inline void setAlgorithm(int value) { + algorithm_ = value; + } + /// Return true if the objective limit test can be relied upon + bool isObjectiveLimitTestValid() const ; + /// Sum of dual infeasibilities + inline double sumDualInfeasibilities() const { + return sumDualInfeasibilities_; + } + inline void setSumDualInfeasibilities(double value) { + sumDualInfeasibilities_ = value; + } + /// Sum of relaxed dual infeasibilities + inline double sumOfRelaxedDualInfeasibilities() const { + return sumOfRelaxedDualInfeasibilities_; + } + inline void setSumOfRelaxedDualInfeasibilities(double value) { + sumOfRelaxedDualInfeasibilities_ = value; + } + /// Number of dual infeasibilities + inline int numberDualInfeasibilities() const { + return numberDualInfeasibilities_; + } + inline void setNumberDualInfeasibilities(int value) { + numberDualInfeasibilities_ = value; + } + /// Number of dual infeasibilities (without free) + inline int numberDualInfeasibilitiesWithoutFree() const { + return numberDualInfeasibilitiesWithoutFree_; + } + /// Sum of primal infeasibilities + inline double sumPrimalInfeasibilities() const { + return sumPrimalInfeasibilities_; + } + inline void setSumPrimalInfeasibilities(double value) { + sumPrimalInfeasibilities_ = value; + } + /// Sum of relaxed primal infeasibilities + inline double sumOfRelaxedPrimalInfeasibilities() const { + return sumOfRelaxedPrimalInfeasibilities_; + } + inline void setSumOfRelaxedPrimalInfeasibilities(double value) { + sumOfRelaxedPrimalInfeasibilities_ = value; + } + /// Number of primal infeasibilities + inline int numberPrimalInfeasibilities() const { + return numberPrimalInfeasibilities_; + } + inline void setNumberPrimalInfeasibilities(int value) { + numberPrimalInfeasibilities_ = value; + } + /** Save model to file, returns 0 if success. This is designed for + use outside algorithms so does not save iterating arrays etc. + It does not save any messaging information. + Does not save scaling values. + It does not know about all types of virtual functions. + */ + int saveModel(const char * fileName); + /** Restore model from file, returns 0 if success, + deletes current model */ + int restoreModel(const char * fileName); + + /** Just check solution (for external use) - sets sum of + infeasibilities etc. + If setToBounds 0 then primal column values not changed + and used to compute primal row activity values. If 1 or 2 + then status used - so all nonbasic variables set to + indicated bound and if any values changed (or ==2) basic values re-computed. + */ + void checkSolution(int setToBounds = 0); + /** Just check solution (for internal use) - sets sum of + infeasibilities etc. */ + void checkSolutionInternal(); + /// Check unscaled primal solution but allow for rounding error + void checkUnscaledSolution(); + /// Useful row length arrays (0,1,2,3,4,5) + inline CoinIndexedVector * rowArray(int index) const { + return rowArray_[index]; + } + /// Useful column length arrays (0,1,2,3,4,5) + inline CoinIndexedVector * columnArray(int index) const { + return columnArray_[index]; + } + //@} + + /******************** End of most useful part **************/ + /**@name Functions less likely to be useful to casual user */ + //@{ + /** Given an existing factorization computes and checks + primal and dual solutions. Uses input arrays for variables at + bounds. Returns feasibility states */ + int getSolution ( const double * rowActivities, + const double * columnActivities); + /** Given an existing factorization computes and checks + primal and dual solutions. Uses current problem arrays for + bounds. Returns feasibility states */ + int getSolution (); + /** Constructs a non linear cost from list of non-linearities (columns only) + First lower of each column is taken as real lower + Last lower is taken as real upper and cost ignored + + Returns nonzero if bad data e.g. lowers not monotonic + */ + int createPiecewiseLinearCosts(const int * starts, + const double * lower, const double * gradient); + /// dual row pivot choice + inline ClpDualRowPivot * dualRowPivot() const { + return dualRowPivot_; + } + /// primal column pivot choice + inline ClpPrimalColumnPivot * primalColumnPivot() const { + return primalColumnPivot_; + } + /// Returns true if model looks OK + inline bool goodAccuracy() const { + return (largestPrimalError_ < 1.0e-7 && largestDualError_ < 1.0e-7); + } + /** Return model - updates any scalars */ + void returnModel(ClpSimplex & otherModel); + /** Factorizes using current basis. + solveType - 1 iterating, 0 initial, -1 external + If 10 added then in primal values pass + Return codes are as from ClpFactorization unless initial factorization + when total number of singularities is returned. + Special case is numberRows_+1 -> all slack basis. + */ + int internalFactorize(int solveType); + /// Save data + ClpDataSave saveData() ; + /// Restore data + void restoreData(ClpDataSave saved); + /// Clean up status + void cleanStatus(); + /// Factorizes using current basis. For external use + int factorize(); + /** Computes duals from scratch. If givenDjs then + allows for nonzero basic djs */ + void computeDuals(double * givenDjs); + /// Computes primals from scratch + void computePrimals ( const double * rowActivities, + const double * columnActivities); + /** Adds multiple of a column into an array */ + void add(double * array, + int column, double multiplier) const; + /** + Unpacks one column of the matrix into indexed array + Uses sequenceIn_ + Also applies scaling if needed + */ + void unpack(CoinIndexedVector * rowArray) const ; + /** + Unpacks one column of the matrix into indexed array + Slack if sequence>= numberColumns + Also applies scaling if needed + */ + void unpack(CoinIndexedVector * rowArray, int sequence) const; + /** + Unpacks one column of the matrix into indexed array + ** as packed vector + Uses sequenceIn_ + Also applies scaling if needed + */ + void unpackPacked(CoinIndexedVector * rowArray) ; + /** + Unpacks one column of the matrix into indexed array + ** as packed vector + Slack if sequence>= numberColumns + Also applies scaling if needed + */ + void unpackPacked(CoinIndexedVector * rowArray, int sequence); +#ifndef CLP_USER_DRIVEN +protected: +#endif + /** + This does basis housekeeping and does values for in/out variables. + Can also decide to re-factorize + */ + int housekeeping(double objectiveChange); + /** This sets largest infeasibility and most infeasible and sum + and number of infeasibilities (Primal) */ + void checkPrimalSolution(const double * rowActivities = NULL, + const double * columnActivies = NULL); + /** This sets largest infeasibility and most infeasible and sum + and number of infeasibilities (Dual) */ + void checkDualSolution(); + /** This sets sum and number of infeasibilities (Dual and Primal) */ + void checkBothSolutions(); + /** If input negative scales objective so maximum <= -value + and returns scale factor used. If positive unscales and also + redoes dual stuff + */ + double scaleObjective(double value); + /// Solve using Dantzig-Wolfe decomposition and maybe in parallel + int solveDW(CoinStructuredModel * model, ClpSolve & options); + /// Solve using Benders decomposition and maybe in parallel + int solveBenders(CoinStructuredModel * model, ClpSolve & options); +public: + /** For advanced use. When doing iterative solves things can get + nasty so on values pass if incoming solution has largest + infeasibility < incomingInfeasibility throw out variables + from basis until largest infeasibility < allowedInfeasibility + or incoming largest infeasibility. + If allowedInfeasibility>= incomingInfeasibility this is + always possible altough you may end up with an all slack basis. + + Defaults are 1.0,10.0 + */ + void setValuesPassAction(double incomingInfeasibility, + double allowedInfeasibility); + /** Get a clean factorization - i.e. throw out singularities + may do more later */ + int cleanFactorization(int ifValuesPass); + //@} + /**@name most useful gets and sets */ + //@{ +public: + /// Initial value for alpha accuracy calculation (-1.0 off) + inline double alphaAccuracy() const { + return alphaAccuracy_; + } + inline void setAlphaAccuracy(double value) { + alphaAccuracy_ = value; + } +public: + /// Objective value + //inline double objectiveValue() const { + //return (objectiveValue_-bestPossibleImprovement_)*optimizationDirection_ - dblParam_[ClpObjOffset]; + //} + /// Set disaster handler + inline void setDisasterHandler(ClpDisasterHandler * handler) { + disasterArea_ = handler; + } + /// Get disaster handler + inline ClpDisasterHandler * disasterHandler() const { + return disasterArea_; + } + /// Large bound value (for complementarity etc) + inline double largeValue() const { + return largeValue_; + } + void setLargeValue( double value) ; + /// Largest error on Ax-b + inline double largestPrimalError() const { + return largestPrimalError_; + } + /// Largest error on basic duals + inline double largestDualError() const { + return largestDualError_; + } + /// Largest error on Ax-b + inline void setLargestPrimalError(double value) { + largestPrimalError_ = value; + } + /// Largest error on basic duals + inline void setLargestDualError(double value) { + largestDualError_ = value; + } + /// Get zero tolerance + inline double zeroTolerance() const { + return zeroTolerance_;/*factorization_->zeroTolerance();*/ + } + /// Set zero tolerance + inline void setZeroTolerance( double value) { + zeroTolerance_ = value; + } + /// Basic variables pivoting on which rows + inline int * pivotVariable() const { + return pivotVariable_; + } + /// If automatic scaling on + inline bool automaticScaling() const { + return automaticScale_ != 0; + } + inline void setAutomaticScaling(bool onOff) { + automaticScale_ = onOff ? 1 : 0; + } + /// Current dual tolerance + inline double currentDualTolerance() const { + return dualTolerance_; + } + inline void setCurrentDualTolerance(double value) { + dualTolerance_ = value; + } + /// Current primal tolerance + inline double currentPrimalTolerance() const { + return primalTolerance_; + } + inline void setCurrentPrimalTolerance(double value) { + primalTolerance_ = value; + } + /// How many iterative refinements to do + inline int numberRefinements() const { + return numberRefinements_; + } + void setNumberRefinements( int value) ; + /// Alpha (pivot element) for use by classes e.g. steepestedge + inline double alpha() const { + return alpha_; + } + inline void setAlpha(double value) { + alpha_ = value; + } + /// Reduced cost of last incoming for use by classes e.g. steepestedge + inline double dualIn() const { + return dualIn_; + } + /// Set reduced cost of last incoming to force error + inline void setDualIn(double value) { + dualIn_ = value; + } + /// Pivot Row for use by classes e.g. steepestedge + inline int pivotRow() const { + return pivotRow_; + } + inline void setPivotRow(int value) { + pivotRow_ = value; + } + /// value of incoming variable (in Dual) + double valueIncomingDual() const; + //@} + +#ifndef CLP_USER_DRIVEN +protected: +#endif + /**@name protected methods */ + //@{ + /** May change basis and then returns number changed. + Computation of solutions may be overriden by given pi and solution + */ + int gutsOfSolution ( double * givenDuals, + const double * givenPrimals, + bool valuesPass = false); + /// Does most of deletion (0 = all, 1 = most, 2 most + factorization) + void gutsOfDelete(int type); + /// Does most of copying + void gutsOfCopy(const ClpSimplex & rhs); + /** puts in format I like (rowLower,rowUpper) also see StandardMatrix + 1 bit does rows (now and columns), (2 bit does column bounds), 4 bit does objective(s). + 8 bit does solution scaling in + 16 bit does rowArray and columnArray indexed vectors + and makes row copy if wanted, also sets columnStart_ etc + Also creates scaling arrays if needed. It does scaling if needed. + 16 also moves solutions etc in to work arrays + On 16 returns false if problem "bad" i.e. matrix or bounds bad + If startFinishOptions is -1 then called by user in getSolution + so do arrays but keep pivotVariable_ + */ + bool createRim(int what, bool makeRowCopy = false, int startFinishOptions = 0); + /// Does rows and columns + void createRim1(bool initial); + /// Does objective + void createRim4(bool initial); + /// Does rows and columns and objective + void createRim5(bool initial); + /** releases above arrays and does solution scaling out. May also + get rid of factorization data - + 0 get rid of nothing, 1 get rid of arrays, 2 also factorization + */ + void deleteRim(int getRidOfFactorizationData = 2); + /// Sanity check on input rim data (after scaling) - returns true if okay + bool sanityCheck(); + //@} +public: + /**@name public methods */ + //@{ + /** Return row or column sections - not as much needed as it + once was. These just map into single arrays */ + inline double * solutionRegion(int section) const { + if (!section) return rowActivityWork_; + else return columnActivityWork_; + } + inline double * djRegion(int section) const { + if (!section) return rowReducedCost_; + else return reducedCostWork_; + } + inline double * lowerRegion(int section) const { + if (!section) return rowLowerWork_; + else return columnLowerWork_; + } + inline double * upperRegion(int section) const { + if (!section) return rowUpperWork_; + else return columnUpperWork_; + } + inline double * costRegion(int section) const { + if (!section) return rowObjectiveWork_; + else return objectiveWork_; + } + /// Return region as single array + inline double * solutionRegion() const { + return solution_; + } + inline double * djRegion() const { + return dj_; + } + inline double * lowerRegion() const { + return lower_; + } + inline double * upperRegion() const { + return upper_; + } + inline double * costRegion() const { + return cost_; + } + inline Status getStatus(int sequence) const { + return static_cast (status_[sequence] & 7); + } + inline void setStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast(st_byte & ~7); + st_byte = static_cast(st_byte | newstatus); + } + /// Start or reset using maximumRows_ and Columns_ - true if change + bool startPermanentArrays(); + /** Normally the first factorization does sparse coding because + the factorization could be singular. This allows initial dense + factorization when it is known to be safe + */ + void setInitialDenseFactorization(bool onOff); + bool initialDenseFactorization() const; + /** Return sequence In or Out */ + inline int sequenceIn() const { + return sequenceIn_; + } + inline int sequenceOut() const { + return sequenceOut_; + } + /** Set sequenceIn or Out */ + inline void setSequenceIn(int sequence) { + sequenceIn_ = sequence; + } + inline void setSequenceOut(int sequence) { + sequenceOut_ = sequence; + } + /** Return direction In or Out */ + inline int directionIn() const { + return directionIn_; + } + inline int directionOut() const { + return directionOut_; + } + /** Set directionIn or Out */ + inline void setDirectionIn(int direction) { + directionIn_ = direction; + } + inline void setDirectionOut(int direction) { + directionOut_ = direction; + } + /// Value of Out variable + inline double valueOut() const { + return valueOut_; + } + /// Set value of out variable + inline void setValueOut(double value) { + valueOut_ = value; + } + /// Dual value of Out variable + inline double dualOut() const { + return dualOut_; + } + /// Set dual value of out variable + inline void setDualOut(double value) { + dualOut_ = value; + } + /// Set lower of out variable + inline void setLowerOut(double value) { + lowerOut_ = value; + } + /// Set upper of out variable + inline void setUpperOut(double value) { + upperOut_ = value; + } + /// Set theta of out variable + inline void setTheta(double value) { + theta_ = value; + } + /// Returns 1 if sequence indicates column + inline int isColumn(int sequence) const { + return sequence < numberColumns_ ? 1 : 0; + } + /// Returns sequence number within section + inline int sequenceWithin(int sequence) const { + return sequence < numberColumns_ ? sequence : sequence - numberColumns_; + } + /// Return row or column values + inline double solution(int sequence) { + return solution_[sequence]; + } + /// Return address of row or column values + inline double & solutionAddress(int sequence) { + return solution_[sequence]; + } + inline double reducedCost(int sequence) { + return dj_[sequence]; + } + inline double & reducedCostAddress(int sequence) { + return dj_[sequence]; + } + inline double lower(int sequence) { + return lower_[sequence]; + } + /// Return address of row or column lower bound + inline double & lowerAddress(int sequence) { + return lower_[sequence]; + } + inline double upper(int sequence) { + return upper_[sequence]; + } + /// Return address of row or column upper bound + inline double & upperAddress(int sequence) { + return upper_[sequence]; + } + inline double cost(int sequence) { + return cost_[sequence]; + } + /// Return address of row or column cost + inline double & costAddress(int sequence) { + return cost_[sequence]; + } + /// Return original lower bound + inline double originalLower(int iSequence) const { + if (iSequence < numberColumns_) return columnLower_[iSequence]; + else + return rowLower_[iSequence-numberColumns_]; + } + /// Return original lower bound + inline double originalUpper(int iSequence) const { + if (iSequence < numberColumns_) return columnUpper_[iSequence]; + else + return rowUpper_[iSequence-numberColumns_]; + } + /// Theta (pivot change) + inline double theta() const { + return theta_; + } + /** Best possible improvement using djs (primal) or + obj change by flipping bounds to make dual feasible (dual) */ + inline double bestPossibleImprovement() const { + return bestPossibleImprovement_; + } + /// Return pointer to details of costs + inline ClpNonLinearCost * nonLinearCost() const { + return nonLinearCost_; + } + /** Return more special options + 1 bit - if presolve says infeasible in ClpSolve return + 2 bit - if presolved problem infeasible return + 4 bit - keep arrays like upper_ around + 8 bit - if factorization kept can still declare optimal at once + 16 bit - if checking replaceColumn accuracy before updating + 32 bit - say optimal if primal feasible! + 64 bit - give up easily in dual (and say infeasible) + 128 bit - no objective, 0-1 and in B&B + 256 bit - in primal from dual or vice versa + 512 bit - alternative use of solveType_ + 1024 bit - don't do row copy of factorization + 2048 bit - perturb in complete fathoming + 4096 bit - try more for complete fathoming + 8192 bit - don't even think of using primal if user asks for dual (and vv) + 16384 bit - in initialSolve so be more flexible + 32768 bit - don't swap algorithms from dual if small infeasibility + 65536 bit - perturb in postsolve cleanup (even if < 10000 rows) + 131072 bit (*3) initial stateDualColumn + 524288 bit - stop when primal feasible + */ + inline int moreSpecialOptions() const { + return moreSpecialOptions_; + } + /** Set more special options + 1 bit - if presolve says infeasible in ClpSolve return + 2 bit - if presolved problem infeasible return + 4 bit - keep arrays like upper_ around + 8 bit - no free or superBasic variables + 16 bit - if checking replaceColumn accuracy before updating + 32 bit - say optimal if primal feasible! + 64 bit - give up easily in dual (and say infeasible) + 128 bit - no objective, 0-1 and in B&B + 256 bit - in primal from dual or vice versa + 512 bit - alternative use of solveType_ + 1024 bit - don't do row copy of factorization + 2048 bit - perturb in complete fathoming + 4096 bit - try more for complete fathoming + 8192 bit - don't even think of using primal if user asks for dual (and vv) + 16384 bit - in initialSolve so be more flexible + 32768 bit - don't swap algorithms from dual if small infeasibility + 65536 bit - perturb in postsolve cleanup (even if < 10000 rows) + 131072 bit (*3) initial stateDualColumn + 524288 bit - stop when primal feasible + 1048576 bit - don't perturb even if long time + 2097152 bit - no primal in fastDual2 if feasible + 4194304 bit - tolerances have been changed by code + 8388608 bit - tolerances are dynamic (at first) + */ + inline void setMoreSpecialOptions(int value) { + moreSpecialOptions_ = value; + } + //@} + /**@name status methods */ + //@{ + inline void setFakeBound(int sequence, FakeBound fakeBound) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast(st_byte & ~24); + st_byte = static_cast(st_byte | (fakeBound << 3)); + } + inline FakeBound getFakeBound(int sequence) const { + return static_cast ((status_[sequence] >> 3) & 3); + } + inline void setRowStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence+numberColumns_]; + st_byte = static_cast(st_byte & ~7); + st_byte = static_cast(st_byte | newstatus); + } + inline Status getRowStatus(int sequence) const { + return static_cast (status_[sequence+numberColumns_] & 7); + } + inline void setColumnStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast(st_byte & ~7); + st_byte = static_cast(st_byte | newstatus); + } + inline Status getColumnStatus(int sequence) const { + return static_cast (status_[sequence] & 7); + } + inline void setPivoted( int sequence) { + status_[sequence] = static_cast(status_[sequence] | 32); + } + inline void clearPivoted( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~32); + } + inline bool pivoted(int sequence) const { + return (((status_[sequence] >> 5) & 1) != 0); + } + /// To flag a variable (not inline to allow for column generation) + void setFlagged( int sequence); + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast(status_[sequence] & ~64); + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + /// To say row active in primal pivot row choice + inline void setActive( int iRow) { + status_[iRow] = static_cast(status_[iRow] | 128); + } + inline void clearActive( int iRow) { + status_[iRow] = static_cast(status_[iRow] & ~128); + } + inline bool active(int iRow) const { + return ((status_[iRow] & 128) != 0); + } + /// To say perturbed + inline void setPerturbed( int iSequence) { + status_[iSequence] = static_cast(status_[iSequence] | 128); + } + inline void clearPerturbed( int iSequence) { + status_[iSequence] = static_cast(status_[iSequence] & ~128); + } + inline bool perturbed(int iSequence) const { + return ((status_[iSequence] & 128) != 0); + } + /** Set up status array (can be used by OsiClp). + Also can be used to set up all slack basis */ + void createStatus() ; + /** Sets up all slack basis and resets solution to + as it was after initial load or readMps */ + void allSlackBasis(bool resetSolution = false); + + /// So we know when to be cautious + inline int lastBadIteration() const { + return lastBadIteration_; + } + /// Set so we know when to be cautious + inline void setLastBadIteration(int value) { + lastBadIteration_=value; + } + /// Progress flag - at present 0 bit says artificials out + inline int progressFlag() const { + return (progressFlag_ & 3); + } + /// For dealing with all issues of cycling etc + inline ClpSimplexProgress * progress() + { return &progress_;} + /// Force re-factorization early value + inline int forceFactorization() const { + return forceFactorization_ ; + } + /// Force re-factorization early + inline void forceFactorization(int value) { + forceFactorization_ = value; + } + /// Raw objective value (so always minimize in primal) + inline double rawObjectiveValue() const { + return objectiveValue_; + } + /// Compute objective value from solution and put in objectiveValue_ + void computeObjectiveValue(bool useWorkingSolution = false); + /// Compute minimization objective value from internal solution without perturbation + double computeInternalObjectiveValue(); + /** Infeasibility/unbounded ray (NULL returned if none/wrong) + Up to user to use delete [] on these arrays. */ + double * infeasibilityRay(bool fullRay=false) const; + /** Number of extra rows. These are ones which will be dynamically created + each iteration. This is for GUB but may have other uses. + */ + inline int numberExtraRows() const { + return numberExtraRows_; + } + /** Maximum number of basic variables - can be more than number of rows if GUB + */ + inline int maximumBasic() const { + return maximumBasic_; + } + /// Iteration when we entered dual or primal + inline int baseIteration() const { + return baseIteration_; + } + /// Create C++ lines to get to current state + void generateCpp( FILE * fp, bool defaultFactor = false); + /// Gets clean and emptyish factorization + ClpFactorization * getEmptyFactorization(); + /// May delete or may make clean and emptyish factorization + void setEmptyFactorization(); + /// Move status and solution across + void moveInfo(const ClpSimplex & rhs, bool justStatus = false); + //@} + + ///@name Basis handling + // These are only to be used using startFinishOptions (ClpSimplexDual, ClpSimplexPrimal) + // *** At present only without scaling + // *** Slacks havve -1.0 element (so == row activity) - take care + ///Get a row of the tableau (slack part in slack if not NULL) + void getBInvARow(int row, double* z, double * slack = NULL); + + ///Get a row of the basis inverse + void getBInvRow(int row, double* z); + + ///Get a column of the tableau + void getBInvACol(int col, double* vec); + + ///Get a column of the basis inverse + void getBInvCol(int col, double* vec); + + /** Get basic indices (order of indices corresponds to the + order of elements in a vector retured by getBInvACol() and + getBInvCol()). + */ + void getBasics(int* index); + + //@} + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + void setObjectiveCoefficient( int elementIndex, double elementValue ); + /** Set an objective function coefficient */ + inline void setObjCoeff( int elementIndex, double elementValue ) { + setObjectiveCoefficient( elementIndex, elementValue); + } + + /** Set a single column lower bound
+ Use -DBL_MAX for -infinity. */ + void setColumnLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound
+ Use DBL_MAX for infinity. */ + void setColumnUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + void setColumnBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously
+ The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + either bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + void setColumnSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single column lower bound
+ Use -DBL_MAX for -infinity. */ + inline void setColLower( int elementIndex, double elementValue ) { + setColumnLower(elementIndex, elementValue); + } + /** Set a single column upper bound
+ Use DBL_MAX for infinity. */ + inline void setColUpper( int elementIndex, double elementValue ) { + setColumnUpper(elementIndex, elementValue); + } + + /** Set a single column lower and upper bound */ + inline void setColBounds( int elementIndex, + double newlower, double newupper ) { + setColumnBounds(elementIndex, newlower, newupper); + } + + /** Set the bounds on a number of columns simultaneously
+ @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + either bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + inline void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList) { + setColumnSetBounds(indexFirst, indexLast, boundList); + } + + /** Set a single row lower bound
+ Use -DBL_MAX for -infinity. */ + void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound
+ Use DBL_MAX for infinity. */ + void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the bounds on a number of rows simultaneously
+ @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + either bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + /// Resizes rim part of model + void resize (int newNumberRows, int newNumberColumns); + + //@} + +////////////////// data ////////////////// +protected: + + /**@name data. Many arrays have a row part and a column part. + There is a single array with both - columns then rows and + then normally two arrays pointing to rows and columns. The + single array is the owner of memory + */ + //@{ + /** Best possible improvement using djs (primal) or + obj change by flipping bounds to make dual feasible (dual) */ + double bestPossibleImprovement_; + /// Zero tolerance + double zeroTolerance_; + /// Sequence of worst (-1 if feasible) + int columnPrimalSequence_; + /// Sequence of worst (-1 if feasible) + int rowPrimalSequence_; + /// "Best" objective value + double bestObjectiveValue_; + /// More special options - see set for details + int moreSpecialOptions_; + /// Iteration when we entered dual or primal + int baseIteration_; + /// Primal tolerance needed to make dual feasible (0 == Primal, <0 == Dual + int algorithm_; + /** Now for some reliability aids + This forces re-factorization early */ + int forceFactorization_; + /** Perturbation: + -50 to +50 - perturb by this power of ten (-6 sounds good) + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + */ + int perturbation_; + /// Saved status regions + unsigned char * saveStatus_; + /** Very wasteful way of dealing with infeasibilities in primal. + However it will allow non-linearities and use of dual + analysis. If it doesn't work it can easily be replaced. + */ + ClpNonLinearCost * nonLinearCost_; + /// So we know when to be cautious + int lastBadIteration_; + /// So we know when to open up again + int lastFlaggedIteration_; + /// Can be used for count of fake bounds (dual) or fake costs (primal) + int numberFake_; + /// Can be used for count of changed costs (dual) or changed bounds (primal) + int numberChanged_; + /// Progress flag - at present 0 bit says artificials out, 1 free in + int progressFlag_; + /// First free/super-basic variable (-1 if none) + int firstFree_; + /** Number of extra rows. These are ones which will be dynamically created + each iteration. This is for GUB but may have other uses. + */ + int numberExtraRows_; + /** Maximum number of basic variables - can be more than number of rows if GUB + */ + int maximumBasic_; + /// If may skip final factorize then allow up to this pivots (default 20) + int dontFactorizePivots_; + /** For advanced use. When doing iterative solves things can get + nasty so on values pass if incoming solution has largest + infeasibility < incomingInfeasibility throw out variables + from basis until largest infeasibility < allowedInfeasibility. + if allowedInfeasibility>= incomingInfeasibility this is + always possible altough you may end up with an all slack basis. + + Defaults are 1.0,10.0 + */ + double incomingInfeasibility_; + double allowedInfeasibility_; + /// Automatic scaling of objective and rhs and bounds + int automaticScale_; + /// Maximum perturbation array size (take out when code rewritten) + int maximumPerturbationSize_; + /// Perturbation array (maximumPerturbationSize_) + double * perturbationArray_; + /// A copy of model with certain state - normally without cuts + ClpSimplex * baseModel_; + /// For dealing with all issues of cycling etc + ClpSimplexProgress progress_; +#ifdef ABC_INHERIT + AbcSimplex * abcSimplex_; +#define CLP_ABC_WANTED 1 +#define CLP_ABC_WANTED_PARALLEL 2 +#define CLP_ABC_FULL_DONE 8 + // bits 256,512,1024 for crash +#endif +#define CLP_ABC_BEEN_FEASIBLE 65536 + int abcState_; + /// Number of degenerate pivots since last perturbed + int numberDegeneratePivots_; +public: + /// Spare int array for passing information [0]!=0 switches on + mutable int spareIntArray_[4]; + /// Spare double array for passing information [0]!=0 switches on + mutable double spareDoubleArray_[4]; +protected: + /// Allow OsiClp certain perks + friend class OsiClpSolverInterface; + /// And OsiCLP + friend class OsiCLPSolverInterface; + //@} +}; +//############################################################################# +/** A function that tests the methods in the ClpSimplex class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. + + It also does some testing of ClpFactorization class + */ +void +ClpSimplexUnitTest(const std::string & mpsDir); + +// For Devex stuff +#define DEVEX_TRY_NORM 1.0e-4 +#define DEVEX_ADD_ONE 1.0 +#if defined(ABC_INHERIT) || defined(CBC_THREAD) || defined(THREADS_IN_ANALYZE) +// Use pthreads +#include +typedef struct { + double result; + //const CoinIndexedVector * constVector; // can get rid of + //CoinIndexedVector * vectors[2]; // can get rid of + void * extraInfo; + void * extraInfo2; + int status; + int stuff[4]; +} CoinThreadInfo; +class CoinPthreadStuff { +public: + /**@name Constructors and destructor and copy */ + //@{ + /** Main constructor + */ + CoinPthreadStuff (int numberThreads=0, + void * parallelManager(void * stuff)=NULL); + /// Assignment operator. This copies the data + CoinPthreadStuff & operator=(const CoinPthreadStuff & rhs); + /// Destructor + ~CoinPthreadStuff ( ); + /// set stop start + inline void setStopStart(int value) + { stopStart_=value;} +#ifndef NUMBER_THREADS +#define NUMBER_THREADS 8 +#endif + // For waking up thread + inline pthread_mutex_t * mutexPointer(int which,int thread=0) + { return mutex_+which+3*thread;} +#ifdef PTHREAD_BARRIER_SERIAL_THREAD + inline pthread_barrier_t * barrierPointer() + { return &barrier_;} +#endif + inline int whichLocked(int thread=0) const + { return locked_[thread];} + inline CoinThreadInfo * threadInfoPointer(int thread=0) + { return threadInfo_+thread;} + void startParallelTask(int type,int iThread,void * info=NULL); + int waitParallelTask(int type, int & iThread,bool allowIdle); + void waitAllTasks(); + /// so thread can find out which one it is + int whichThread() const; + void sayIdle(int iThread); + //void startThreads(int numberThreads); + //void stopThreads(); + // For waking up thread + pthread_mutex_t mutex_[3*(NUMBER_THREADS+1)]; +#ifdef PTHREAD_BARRIER_SERIAL_THREAD + pthread_barrier_t barrier_; +#endif + CoinThreadInfo threadInfo_[NUMBER_THREADS+1]; + pthread_t abcThread_[NUMBER_THREADS+1]; + int locked_[NUMBER_THREADS+1]; + int stopStart_; + int numberThreads_; +}; +void * clp_parallelManager(void * stuff); +#endif +#endif diff --git a/thirdparty/linux/include/coin/ClpSimplexDual.hpp b/thirdparty/linux/include/coin/ClpSimplexDual.hpp new file mode 100644 index 0000000..77cc577 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpSimplexDual.hpp @@ -0,0 +1,300 @@ +/* $Id: ClpSimplexDual.hpp 1761 2011-07-06 16:06:24Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexDual_H +#define ClpSimplexDual_H + +#include "ClpSimplex.hpp" + +/** This solves LPs using the dual simplex method + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexDual : public ClpSimplex { + +public: + + /**@name Description of algorithm */ + //@{ + /** Dual algorithm + + Method + + It tries to be a single phase approach with a weight of 1.0 being + given to getting optimal and a weight of updatedDualBound_ being + given to getting dual feasible. In this version I have used the + idea that this weight can be thought of as a fake bound. If the + distance between the lower and upper bounds on a variable is less + than the feasibility weight then we are always better off flipping + to other bound to make dual feasible. If the distance is greater + then we make up a fake bound updatedDualBound_ away from one bound. + If we end up optimal or primal infeasible, we check to see if + bounds okay. If so we have finished, if not we increase updatedDualBound_ + and continue (after checking if unbounded). I am undecided about + free variables - there is coding but I am not sure about it. At + present I put them in basis anyway. + + The code is designed to take advantage of sparsity so arrays are + seldom zeroed out from scratch or gone over in their entirety. + The only exception is a full scan to find outgoing variable for + Dantzig row choice. For steepest edge we keep an updated list + of infeasibilities (actually squares). + On easy problems we don't need full scan - just + pick first reasonable. + + One problem is how to tackle degeneracy and accuracy. At present + I am using the modification of costs which I put in OSL and some + of what I think is the dual analog of Gill et al. + I am still not sure of the exact details. + + The flow of dual is three while loops as follows: + + while (not finished) { + + while (not clean solution) { + + Factorize and/or clean up solution by flipping variables so + dual feasible. If looks finished check fake dual bounds. + Repeat until status is iterating (-1) or finished (0,1,2) + + } + + while (status==-1) { + + Iterate until no pivot in or out or time to re-factorize. + + Flow is: + + choose pivot row (outgoing variable). if none then + we are primal feasible so looks as if done but we need to + break and check bounds etc. + + Get pivot row in tableau + + Choose incoming column. If we don't find one then we look + primal infeasible so break and check bounds etc. (Also the + pivot tolerance is larger after any iterations so that may be + reason) + + If we do find incoming column, we may have to adjust costs to + keep going forwards (anti-degeneracy). Check pivot will be stable + and if unstable throw away iteration and break to re-factorize. + If minor error re-factorize after iteration. + + Update everything (this may involve flipping variables to stay + dual feasible. + + } + + } + + TODO's (or maybe not) + + At present we never check we are going forwards. I overdid that in + OSL so will try and make a last resort. + + Needs partial scan pivot out option. + + May need other anti-degeneracy measures, especially if we try and use + loose tolerances as a way to solve in fewer iterations. + + I like idea of dynamic scaling. This gives opportunity to decouple + different implications of scaling for accuracy, iteration count and + feasibility tolerance. + + for use of exotic parameter startFinishoptions see Clpsimplex.hpp + */ + + int dual(int ifValuesPass, int startFinishOptions = 0); + /** For strong branching. On input lower and upper are new bounds + while on output they are change in objective function values + (>1.0e50 infeasible). + Return code is 0 if nothing interesting, -1 if infeasible both + ways and +1 if infeasible one way (check values to see which one(s)) + Solutions are filled in as well - even down, odd up - also + status and number of iterations + */ + int strongBranching(int numberVariables, const int * variables, + double * newLower, double * newUpper, + double ** outputSolution, + int * outputStatus, int * outputIterations, + bool stopOnFirstInfeasible = true, + bool alwaysFinish = false, + int startFinishOptions = 0); + /// This does first part of StrongBranching + ClpFactorization * setupForStrongBranching(char * arrays, int numberRows, + int numberColumns, bool solveLp = false); + /// This cleans up after strong branching + void cleanupAfterStrongBranching(ClpFactorization * factorization); + //@} + + /**@name Functions used in dual */ + //@{ + /** This has the flow between re-factorizations + Broken out for clarity and will be used by strong branching + + Reasons to come out: + -1 iterations etc + -2 inaccuracy + -3 slight inaccuracy (and done iterations) + +0 looks optimal (might be unbounded - but we will investigate) + +1 looks infeasible + +3 max iterations + + If givenPi not NULL then in values pass + */ + int whileIterating(double * & givenPi, int ifValuesPass); + /** The duals are updated by the given arrays. + Returns number of infeasibilities. + After rowArray and columnArray will just have those which + have been flipped. + Variables may be flipped between bounds to stay dual feasible. + The output vector has movement of primal + solution (row length array) */ + int updateDualsInDual(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * outputArray, + double theta, + double & objectiveChange, + bool fullRecompute); + /** The duals are updated by the given arrays. + This is in values pass - so no changes to primal is made + */ + void updateDualsInValuesPass(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double theta); + /** While updateDualsInDual sees what effect is of flip + this does actual flipping. + */ + void flipBounds(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray); + /** + Row array has row part of pivot row + Column array has column part. + This chooses pivot column. + Spare arrays are used to save pivots which will go infeasible + We will check for basic so spare array will never overflow. + If necessary will modify costs + For speed, we may need to go to a bucket approach when many + variables are being flipped. + Returns best possible pivot value + */ + double dualColumn(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * spareArray, + CoinIndexedVector * spareArray2, + double accpetablePivot, + CoinBigIndex * dubiousWeights); + /// Does first bit of dualColumn + int dualColumn0(const CoinIndexedVector * rowArray, + const CoinIndexedVector * columnArray, + CoinIndexedVector * spareArray, + double acceptablePivot, + double & upperReturn, double &bestReturn, double & badFree); + /** + Row array has row part of pivot row + Column array has column part. + This sees what is best thing to do in dual values pass + if sequenceIn==sequenceOut can change dual on chosen row and leave variable in basis + */ + void checkPossibleValuesMove(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double acceptablePivot); + /** + Row array has row part of pivot row + Column array has column part. + This sees what is best thing to do in branch and bound cleanup + If sequenceIn_ < 0 then can't do anything + */ + void checkPossibleCleanup(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double acceptablePivot); + /** + This sees if we can move duals in dual values pass. + This is done before any pivoting + */ + void doEasyOnesInValuesPass(double * givenReducedCosts); + /** + Chooses dual pivot row + Would be faster with separate region to scan + and will have this (with square of infeasibility) when steepest + For easy problems we can just choose one of the first rows we look at + + If alreadyChosen >=0 then in values pass and that row has been + selected + */ + void dualRow(int alreadyChosen); + /** Checks if any fake bounds active - if so returns number and modifies + updatedDualBound_ and everything. + Free variables will be left as free + Returns number of bounds changed if >=0 + Returns -1 if not initialize and no effect + Fills in changeVector which can be used to see if unbounded + and cost of change vector + If 2 sets to original (just changed) + */ + int changeBounds(int initialize, CoinIndexedVector * outputArray, + double & changeCost); + /** As changeBounds but just changes new bounds for a single variable. + Returns true if change */ + bool changeBound( int iSequence); + /// Restores bound to original bound + void originalBound(int iSequence); + /** Checks if tentative optimal actually means unbounded in dual + Returns -3 if not, 2 if is unbounded */ + int checkUnbounded(CoinIndexedVector * ray, CoinIndexedVector * spare, + double changeCost); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInDual(int & lastCleaned, int type, + double * givenDjs, ClpDataSave & saveData, + int ifValuesPass); + /** Perturbs problem (method depends on perturbation()) + returns nonzero if should go to dual */ + int perturb(); + /** Fast iterations. Misses out a lot of initialization. + Normally stops on maximum iterations, first re-factorization + or tentative optimum. If looks interesting then continues as + normal. Returns 0 if finished properly, 1 otherwise. + */ + int fastDual(bool alwaysFinish = false); + /** Checks number of variables at fake bounds. This is used by fastDual + so can exit gracefully before end */ + int numberAtFakeBound(); + + /** Pivot in a variable and choose an outgoing one. Assumes dual + feasible - will not go through a reduced cost. Returns step length in theta + Return codes as before but -1 means no acceptable pivot + */ + int pivotResultPart1(); + /** Get next free , -1 if none */ + int nextSuperBasic(); + /** Startup part of dual (may be extended to other algorithms) + returns 0 if good, 1 if bad */ + int startupSolve(int ifValuesPass, double * saveDuals, int startFinishOptions); + void finishSolve(int startFinishOptions); + void gutsOfDual(int ifValuesPass, double * & saveDuals, int initialStatus, + ClpDataSave & saveData); + //int dual2(int ifValuesPass,int startFinishOptions=0); + void resetFakeBounds(int type); + + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/ClpSimplexNonlinear.hpp b/thirdparty/linux/include/coin/ClpSimplexNonlinear.hpp new file mode 100644 index 0000000..6c1088b --- /dev/null +++ b/thirdparty/linux/include/coin/ClpSimplexNonlinear.hpp @@ -0,0 +1,117 @@ +/* $Id: ClpSimplexNonlinear.hpp 2025 2014-03-19 12:49:55Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexNonlinear_H +#define ClpSimplexNonlinear_H + +class ClpNonlinearInfo; +class ClpQuadraticObjective; +class ClpConstraint; + +#include "ClpSimplexPrimal.hpp" + +/** This solves non-linear LPs using the primal simplex method + + It inherits from ClpSimplexPrimal. It has no data of its own and + is never created - only cast from a ClpSimplexPrimal object at algorithm time. + If needed create new class and pass around + +*/ + +class ClpSimplexNonlinear : public ClpSimplexPrimal { + +public: + + /**@name Description of algorithm */ + //@{ + /** Primal algorithms for reduced gradient + At present we have two algorithms: + + */ + /// A reduced gradient method. + int primal(); + /** Primal algorithm for quadratic + Using a semi-trust region approach as for pooling problem + This is in because I have it lying around + */ + int primalSLP(int numberPasses, double deltaTolerance, + int otherOptions=0); + /// May use a cut approach for solving any LP + int primalDualCuts(char * rowsIn, int startUp, int algorithm); + /** Primal algorithm for nonlinear constraints + Using a semi-trust region approach as for pooling problem + This is in because I have it lying around + + */ + int primalSLP(int numberConstraints, ClpConstraint ** constraints, + int numberPasses, double deltaTolerance); + + /** Creates direction vector. note longArray is long enough + for rows and columns. If numberNonBasic 0 then is updated + otherwise mode is ignored and those are used. + Norms are only for those > 1.0e3*dualTolerance + If mode is nonzero then just largest dj */ + void directionVector (CoinIndexedVector * longArray, + CoinIndexedVector * spare1, CoinIndexedVector * spare2, + int mode, + double & normFlagged, double & normUnflagged, + int & numberNonBasic); + /// Main part. + int whileIterating (int & pivotMode); + /** + longArray has direction + pivotMode - + 0 - use all dual infeasible variables + 1 - largest dj + while >= 10 trying startup phase + Returns 0 - can do normal iteration (basis change) + 1 - no basis change + 2 - if wants singleton + 3 - if time to re-factorize + If sequenceIn_ >=0 then that will be incoming variable + */ + int pivotColumn(CoinIndexedVector * longArray, + CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * spare, + int & pivotMode, + double & solutionError, + double * array1); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInPrimal(int & lastCleaned, int type, + ClpSimplexProgress * progress, + bool doFactorization, + double & bestObjectiveWhenFlagged); + /** Do last half of an iteration. + Return codes + Reasons to come out normal mode + -1 normal + -2 factorize now - good iteration + -3 slight inaccuracy - refactorize - iteration done + -4 inaccuracy - refactorize - no iteration + -5 something flagged - go round again + +2 looks unbounded + +3 max iterations (iteration done) + + */ + int pivotNonlinearResult(); + //@} + +}; +#endif + diff --git a/thirdparty/linux/include/coin/ClpSimplexOther.hpp b/thirdparty/linux/include/coin/ClpSimplexOther.hpp new file mode 100644 index 0000000..c5014ec --- /dev/null +++ b/thirdparty/linux/include/coin/ClpSimplexOther.hpp @@ -0,0 +1,277 @@ +/* $Id: ClpSimplexOther.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexOther_H +#define ClpSimplexOther_H + +#include "ClpSimplex.hpp" + +/** This is for Simplex stuff which is neither dual nor primal + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexOther : public ClpSimplex { + +public: + + /**@name Methods */ + //@{ + /** Dual ranging. + This computes increase/decrease in cost for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + For non-basic variables the information is trivial to compute and the change in cost is just minus the + reduced cost and the sequence number will be that of the non-basic variables. + For basic variables a ratio test is between the reduced costs for non-basic variables + and the row of the tableau corresponding to the basic variable. + The increase/decrease value is always >= 0.0 + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + If valueIncrease/Decrease not NULL (both must be NULL or both non NULL) then these are filled with + the value of variable if such a change in cost were made (the existing bounds are ignored) + + When here - guaranteed optimal + */ + void dualRanging(int numberCheck, const int * which, + double * costIncrease, int * sequenceIncrease, + double * costDecrease, int * sequenceDecrease, + double * valueIncrease = NULL, double * valueDecrease = NULL); + /** Primal ranging. + This computes increase/decrease in value for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + This should only be used for non-basic variabls as otherwise information is pretty useless + For basic variables the sequence number will be that of the basic variables. + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + When here - guaranteed optimal + */ + void primalRanging(int numberCheck, const int * which, + double * valueIncrease, int * sequenceIncrease, + double * valueDecrease, int * sequenceDecrease); + /** Parametrics + This is an initial slow version. + The code uses current bounds + theta * change (if change array not NULL) + and similarly for objective. + It starts at startingTheta and returns ending theta in endingTheta. + If reportIncrement 0.0 it will report on any movement + If reportIncrement >0.0 it will report at startingTheta+k*reportIncrement. + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, if error on ranges -1, otherwise 0. + Normal report is just theta and objective but + if event handler exists it may do more + On exit endingTheta is maximum reached (can be used for next startingTheta) + */ + int parametrics(double startingTheta, double & endingTheta, double reportIncrement, + const double * changeLowerBound, const double * changeUpperBound, + const double * changeLowerRhs, const double * changeUpperRhs, + const double * changeObjective); + /** Version of parametrics which reads from file + See CbcClpParam.cpp for details of format + Returns -2 if unable to open file */ + int parametrics(const char * dataFile); + /** Parametrics + This is an initial slow version. + The code uses current bounds + theta * change (if change array not NULL) + It starts at startingTheta and returns ending theta in endingTheta. + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, if error on ranges -1, otherwise 0. + Event handler may do more + On exit endingTheta is maximum reached (can be used for next startingTheta) + */ + int parametrics(double startingTheta, double & endingTheta, + const double * changeLowerBound, const double * changeUpperBound, + const double * changeLowerRhs, const double * changeUpperRhs); + int parametricsObj(double startingTheta, double & endingTheta, + const double * changeObjective); + /// Finds best possible pivot + double bestPivot(bool justColumns=false); + typedef struct { + double startingTheta; + double endingTheta; + double maxTheta; + double acceptableMaxTheta; // if this far then within tolerances + double * lowerChange; // full array of lower bound changes + int * lowerList; // list of lower bound changes + double * upperChange; // full array of upper bound changes + int * upperList; // list of upper bound changes + char * markDone; // mark which ones looked at + int * backwardBasic; // from sequence to pivot row + int * lowerActive; + double * lowerGap; + double * lowerCoefficient; + int * upperActive; + double * upperGap; + double * upperCoefficient; + int unscaledChangesOffset; + bool firstIteration; // so can update rhs for accuracy + } parametricsData; + +private: + /** Parametrics - inner loop + This first attempt is when reportIncrement non zero and may + not report endingTheta correctly + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, otherwise 0. + Normal report is just theta and objective but + if event handler exists it may do more + */ + int parametricsLoop(parametricsData & paramData, double reportIncrement, + const double * changeLower, const double * changeUpper, + const double * changeObjective, ClpDataSave & data, + bool canTryQuick); + int parametricsLoop(parametricsData & paramData, + ClpDataSave & data,bool canSkipFactorization=false); + int parametricsObjLoop(parametricsData & paramData, + ClpDataSave & data,bool canSkipFactorization=false); + /** Refactorizes if necessary + Checks if finished. Updates status. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInParametrics(int type, ClpDataSave & saveData); + void statusOfProblemInParametricsObj(int type, ClpDataSave & saveData); + /** This has the flow between re-factorizations + + Reasons to come out: + -1 iterations etc + -2 inaccuracy + -3 slight inaccuracy (and done iterations) + +0 looks optimal (might be unbounded - but we will investigate) + +1 looks infeasible + +3 max iterations + */ + int whileIterating(parametricsData & paramData, double reportIncrement, + const double * changeObjective); + /** Computes next theta and says if objective or bounds (0= bounds, 1 objective, -1 none). + theta is in theta_. + type 1 bounds, 2 objective, 3 both. + */ + int nextTheta(int type, double maxTheta, parametricsData & paramData, + const double * changeObjective); + int whileIteratingObj(parametricsData & paramData); + int nextThetaObj(double maxTheta, parametricsData & paramData); + /// Restores bound to original bound + void originalBound(int iSequence, double theta, const double * changeLower, + const double * changeUpper); + /// Compute new rowLower_ etc (return negative if infeasible - otherwise largest change) + double computeRhsEtc(parametricsData & paramData); + /// Redo lower_ from rowLower_ etc + void redoInternalArrays(); + /** + Row array has row part of pivot row + Column array has column part. + This is used in dual ranging + */ + void checkDualRatios(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double & costIncrease, int & sequenceIncrease, double & alphaIncrease, + double & costDecrease, int & sequenceDecrease, double & alphaDecrease); + /** + Row array has pivot column + This is used in primal ranging + */ + void checkPrimalRatios(CoinIndexedVector * rowArray, + int direction); + /// Returns new value of whichOther when whichIn enters basis + double primalRanging1(int whichIn, int whichOther); + +public: + /** Write the basis in MPS format to the specified file. + If writeValues true writes values of structurals + (and adds VALUES to end of NAME card) + + Row and column names may be null. + formatType is +
    +
  • 0 - normal +
  • 1 - extra accuracy +
  • 2 - IEEE hex (later) +
+ + Returns non-zero on I/O error + */ + int writeBasis(const char *filename, + bool writeValues = false, + int formatType = 0) const; + /// Read a basis from the given filename + int readBasis(const char *filename); + /** Creates dual of a problem if looks plausible + (defaults will always create model) + fractionRowRanges is fraction of rows allowed to have ranges + fractionColumnRanges is fraction of columns allowed to have ranges + */ + ClpSimplex * dualOfModel(double fractionRowRanges = 1.0, double fractionColumnRanges = 1.0) const; + /** Restores solution from dualized problem + non-zero return code indicates minor problems + */ + int restoreFromDual(const ClpSimplex * dualProblem, + bool checkAccuracy=false); + /** Sets solution in dualized problem + non-zero return code indicates minor problems + */ + int setInDual(ClpSimplex * dualProblem); + /** Does very cursory presolve. + rhs is numberRows, whichRows is 3*numberRows and whichColumns is 2*numberColumns. + */ + ClpSimplex * crunch(double * rhs, int * whichRows, int * whichColumns, + int & nBound, bool moreBounds = false, bool tightenBounds = false); + /** After very cursory presolve. + rhs is numberRows, whichRows is 3*numberRows and whichColumns is 2*numberColumns. + */ + void afterCrunch(const ClpSimplex & small, + const int * whichRows, const int * whichColumns, + int nBound); + /** Returns gub version of model or NULL + whichRows has to be numberRows + whichColumns has to be numberRows+numberColumns */ + ClpSimplex * gubVersion(int * whichRows, int * whichColumns, + int neededGub, + int factorizationFrequency=50); + /// Sets basis from original + void setGubBasis(ClpSimplex &original,const int * whichRows, + const int * whichColumns); + /// Restores basis to original + void getGubBasis(ClpSimplex &original,const int * whichRows, + const int * whichColumns) const; + /// Quick try at cleaning up duals if postsolve gets wrong + void cleanupAfterPostsolve(); + /** Tightens integer bounds - returns number tightened or -1 if infeasible + */ + int tightenIntegerBounds(double * rhsSpace); + /** Expands out all possible combinations for a knapsack + If buildObj NULL then just computes space needed - returns number elements + On entry numberOutput is maximum allowed, on exit it is number needed or + -1 (as will be number elements) if maximum exceeded. numberOutput will have at + least space to return values which reconstruct input. + Rows returned will be original rows but no entries will be returned for + any rows all of whose entries are in knapsack. So up to user to allow for this. + If reConstruct >=0 then returns number of entrie which make up item "reConstruct" + in expanded knapsack. Values in buildRow and buildElement; + */ + int expandKnapsack(int knapsackRow, int & numberOutput, + double * buildObj, CoinBigIndex * buildStart, + int * buildRow, double * buildElement, int reConstruct = -1) const; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/ClpSimplexPrimal.hpp b/thirdparty/linux/include/coin/ClpSimplexPrimal.hpp new file mode 100644 index 0000000..d78e54e --- /dev/null +++ b/thirdparty/linux/include/coin/ClpSimplexPrimal.hpp @@ -0,0 +1,244 @@ +/* $Id: ClpSimplexPrimal.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexPrimal_H +#define ClpSimplexPrimal_H + +#include "ClpSimplex.hpp" + +/** This solves LPs using the primal simplex method + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexPrimal : public ClpSimplex { + +public: + + /**@name Description of algorithm */ + //@{ + /** Primal algorithm + + Method + + It tries to be a single phase approach with a weight of 1.0 being + given to getting optimal and a weight of infeasibilityCost_ being + given to getting primal feasible. In this version I have tried to + be clever in a stupid way. The idea of fake bounds in dual + seems to work so the primal analogue would be that of getting + bounds on reduced costs (by a presolve approach) and using + these for being above or below feasible region. I decided to waste + memory and keep these explicitly. This allows for non-linear + costs! I have not tested non-linear costs but will be glad + to do something if a reasonable example is provided. + + The code is designed to take advantage of sparsity so arrays are + seldom zeroed out from scratch or gone over in their entirety. + The only exception is a full scan to find incoming variable for + Dantzig row choice. For steepest edge we keep an updated list + of dual infeasibilities (actually squares). + On easy problems we don't need full scan - just + pick first reasonable. This method has not been coded. + + One problem is how to tackle degeneracy and accuracy. At present + I am using the modification of costs which I put in OSL and which was + extended by Gill et al. I am still not sure whether we will also + need explicit perturbation. + + The flow of primal is three while loops as follows: + + while (not finished) { + + while (not clean solution) { + + Factorize and/or clean up solution by changing bounds so + primal feasible. If looks finished check fake primal bounds. + Repeat until status is iterating (-1) or finished (0,1,2) + + } + + while (status==-1) { + + Iterate until no pivot in or out or time to re-factorize. + + Flow is: + + choose pivot column (incoming variable). if none then + we are primal feasible so looks as if done but we need to + break and check bounds etc. + + Get pivot column in tableau + + Choose outgoing row. If we don't find one then we look + primal unbounded so break and check bounds etc. (Also the + pivot tolerance is larger after any iterations so that may be + reason) + + If we do find outgoing row, we may have to adjust costs to + keep going forwards (anti-degeneracy). Check pivot will be stable + and if unstable throw away iteration and break to re-factorize. + If minor error re-factorize after iteration. + + Update everything (this may involve changing bounds on + variables to stay primal feasible. + + } + + } + + TODO's (or maybe not) + + At present we never check we are going forwards. I overdid that in + OSL so will try and make a last resort. + + Needs partial scan pivot in option. + + May need other anti-degeneracy measures, especially if we try and use + loose tolerances as a way to solve in fewer iterations. + + I like idea of dynamic scaling. This gives opportunity to decouple + different implications of scaling for accuracy, iteration count and + feasibility tolerance. + + for use of exotic parameter startFinishoptions see Clpsimplex.hpp + */ + + int primal(int ifValuesPass = 0, int startFinishOptions = 0); + //@} + + /**@name For advanced users */ + //@{ + /// Do not change infeasibility cost and always say optimal + void alwaysOptimal(bool onOff); + bool alwaysOptimal() const; + /** Normally outgoing variables can go out to slightly negative + values (but within tolerance) - this is to help stability and + and degeneracy. This can be switched off + */ + void exactOutgoing(bool onOff); + bool exactOutgoing() const; + //@} + + /**@name Functions used in primal */ + //@{ + /** This has the flow between re-factorizations + + Returns a code to say where decision to exit was made + Problem status set to: + + -2 re-factorize + -4 Looks optimal/infeasible + -5 Looks unbounded + +3 max iterations + + valuesOption has original value of valuesPass + */ + int whileIterating(int valuesOption); + + /** Do last half of an iteration. This is split out so people can + force incoming variable. If solveType_ is 2 then this may + re-factorize while normally it would exit to re-factorize. + Return codes + Reasons to come out (normal mode/user mode): + -1 normal + -2 factorize now - good iteration/ NA + -3 slight inaccuracy - refactorize - iteration done/ same but factor done + -4 inaccuracy - refactorize - no iteration/ NA + -5 something flagged - go round again/ pivot not possible + +2 looks unbounded + +3 max iterations (iteration done) + + With solveType_ ==2 this should + Pivot in a variable and choose an outgoing one. Assumes primal + feasible - will not go through a bound. Returns step length in theta + Returns ray in ray_ + */ + int pivotResult(int ifValuesPass = 0); + + + /** The primals are updated by the given array. + Returns number of infeasibilities. + After rowArray will have cost changes for use next iteration + */ + int updatePrimalsInPrimal(CoinIndexedVector * rowArray, + double theta, + double & objectiveChange, + int valuesPass); + /** + Row array has pivot column + This chooses pivot row. + Rhs array is used for distance to next bound (for speed) + For speed, we may need to go to a bucket approach when many + variables go through bounds + If valuesPass non-zero then compute dj for direction + */ + void primalRow(CoinIndexedVector * rowArray, + CoinIndexedVector * rhsArray, + CoinIndexedVector * spareArray, + int valuesPass); + /** + Chooses primal pivot column + updateArray has cost updates (also use pivotRow_ from last iteration) + Would be faster with separate region to scan + and will have this (with square of infeasibility) when steepest + For easy problems we can just choose one of the first columns we look at + */ + void primalColumn(CoinIndexedVector * updateArray, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + + /** Checks if tentative optimal actually means unbounded in primal + Returns -3 if not, 2 if is unbounded */ + int checkUnbounded(CoinIndexedVector * ray, CoinIndexedVector * spare, + double changeCost); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + saveModel is normally NULL but may not be if doing Sprint + */ + void statusOfProblemInPrimal(int & lastCleaned, int type, + ClpSimplexProgress * progress, + bool doFactorization, + int ifValuesPass, + ClpSimplex * saveModel = NULL); + /// Perturbs problem (method depends on perturbation()) + void perturb(int type); + /// Take off effect of perturbation and say whether to try dual + bool unPerturb(); + /// Unflag all variables and return number unflagged + int unflag(); + /** Get next superbasic -1 if none, + Normal type is 1 + If type is 3 then initializes sorted list + if 2 uses list. + */ + int nextSuperBasic(int superBasicType, CoinIndexedVector * columnArray); + + /// Create primal ray + void primalRay(CoinIndexedVector * rowArray); + /// Clears all bits and clears rowArray[1] etc + void clearAll(); + + /// Sort of lexicographic resolve + int lexSolve(); + + //@} +}; +#endif + diff --git a/thirdparty/linux/include/coin/ClpSolve.hpp b/thirdparty/linux/include/coin/ClpSolve.hpp new file mode 100644 index 0000000..b455cd2 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpSolve.hpp @@ -0,0 +1,446 @@ +/* $Id: ClpSolve.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSolve_H +#define ClpSolve_H + +/** + This is a very simple class to guide algorithms. It is used to tidy up + passing parameters to initialSolve and maybe for output from that + +*/ + +class ClpSolve { + +public: + + /** enums for solve function */ + enum SolveType { + useDual = 0, + usePrimal, + usePrimalorSprint, + useBarrier, + useBarrierNoCross, + automatic, + tryDantzigWolfe, + tryBenders, + notImplemented + }; + enum PresolveType { + presolveOn = 0, + presolveOff, + presolveNumber, + presolveNumberCost + }; + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSolve ( ); + /// Constructor when you really know what you are doing + ClpSolve ( SolveType method, PresolveType presolveType, + int numberPasses, int options[6], + int extraInfo[6], int independentOptions[3]); + /// Generates code for above constructor + void generateCpp(FILE * fp); + /// Copy constructor. + ClpSolve(const ClpSolve &); + /// Assignment operator. This copies the data + ClpSolve & operator=(const ClpSolve & rhs); + /// Destructor + ~ClpSolve ( ); + //@} + + /**@name Functions most useful to user */ + //@{ + /** Special options - bits + 0 4 - use crash (default allslack in dual, idiot in primal) + 8 - all slack basis in primal + 2 16 - switch off interrupt handling + 3 32 - do not try and make plus minus one matrix + 64 - do not use sprint even if problem looks good + */ + /** which translation is: + which: + 0 - startup in Dual (nothing if basis exists).: + 0 - no basis + 1 - crash + 2 - use initiative about idiot! but no crash + 1 - startup in Primal (nothing if basis exists): + 0 - use initiative + 1 - use crash + 2 - use idiot and look at further info + 3 - use sprint and look at further info + 4 - use all slack + 5 - use initiative but no idiot + 6 - use initiative but no sprint + 7 - use initiative but no crash + 8 - do allslack or idiot + 9 - do allslack or sprint + 10 - slp before + 11 - no nothing and primal(0) + 2 - interrupt handling - 0 yes, 1 no (for threadsafe) + 3 - whether to make +- 1matrix - 0 yes, 1 no + 4 - for barrier + 0 - dense cholesky + 1 - Wssmp allowing some long columns + 2 - Wssmp not allowing long columns + 3 - Wssmp using KKT + 4 - Using Florida ordering + 8 - bit set to do scaling + 16 - set to be aggressive with gamma/delta? + 32 - Use KKT + 5 - for presolve + 1 - switch off dual stuff + 6 - extra switches + + */ + void setSpecialOption(int which, int value, int extraInfo = -1); + int getSpecialOption(int which) const; + + /// Solve types + void setSolveType(SolveType method, int extraInfo = -1); + SolveType getSolveType(); + + // Presolve types + void setPresolveType(PresolveType amount, int extraInfo = -1); + PresolveType getPresolveType(); + int getPresolvePasses() const; + /// Extra info for idiot (or sprint) + int getExtraInfo(int which) const; + /** Say to return at once if infeasible, + default is to solve */ + void setInfeasibleReturn(bool trueFalse); + inline bool infeasibleReturn() const { + return independentOptions_[0] != 0; + } + /// Whether we want to do dual part of presolve + inline bool doDual() const { + return (independentOptions_[1] & 1) == 0; + } + inline void setDoDual(bool doDual_) { + if (doDual_) independentOptions_[1] &= ~1; + else independentOptions_[1] |= 1; + } + /// Whether we want to do singleton part of presolve + inline bool doSingleton() const { + return (independentOptions_[1] & 2) == 0; + } + inline void setDoSingleton(bool doSingleton_) { + if (doSingleton_) independentOptions_[1] &= ~2; + else independentOptions_[1] |= 2; + } + /// Whether we want to do doubleton part of presolve + inline bool doDoubleton() const { + return (independentOptions_[1] & 4) == 0; + } + inline void setDoDoubleton(bool doDoubleton_) { + if (doDoubleton_) independentOptions_[1] &= ~4; + else independentOptions_[1] |= 4; + } + /// Whether we want to do tripleton part of presolve + inline bool doTripleton() const { + return (independentOptions_[1] & 8) == 0; + } + inline void setDoTripleton(bool doTripleton_) { + if (doTripleton_) independentOptions_[1] &= ~8; + else independentOptions_[1] |= 8; + } + /// Whether we want to do tighten part of presolve + inline bool doTighten() const { + return (independentOptions_[1] & 16) == 0; + } + inline void setDoTighten(bool doTighten_) { + if (doTighten_) independentOptions_[1] &= ~16; + else independentOptions_[1] |= 16; + } + /// Whether we want to do forcing part of presolve + inline bool doForcing() const { + return (independentOptions_[1] & 32) == 0; + } + inline void setDoForcing(bool doForcing_) { + if (doForcing_) independentOptions_[1] &= ~32; + else independentOptions_[1] |= 32; + } + /// Whether we want to do impliedfree part of presolve + inline bool doImpliedFree() const { + return (independentOptions_[1] & 64) == 0; + } + inline void setDoImpliedFree(bool doImpliedfree) { + if (doImpliedfree) independentOptions_[1] &= ~64; + else independentOptions_[1] |= 64; + } + /// Whether we want to do dupcol part of presolve + inline bool doDupcol() const { + return (independentOptions_[1] & 128) == 0; + } + inline void setDoDupcol(bool doDupcol_) { + if (doDupcol_) independentOptions_[1] &= ~128; + else independentOptions_[1] |= 128; + } + /// Whether we want to do duprow part of presolve + inline bool doDuprow() const { + return (independentOptions_[1] & 256) == 0; + } + inline void setDoDuprow(bool doDuprow_) { + if (doDuprow_) independentOptions_[1] &= ~256; + else independentOptions_[1] |= 256; + } + /// Whether we want to do singleton column part of presolve + inline bool doSingletonColumn() const { + return (independentOptions_[1] & 512) == 0; + } + inline void setDoSingletonColumn(bool doSingleton_) { + if (doSingleton_) independentOptions_[1] &= ~512; + else independentOptions_[1] |= 512; + } + /// Whether we want to kill small substitutions + inline bool doKillSmall() const { + return (independentOptions_[1] & 8192) == 0; + } + inline void setDoKillSmall(bool doKill) { + if (doKill) independentOptions_[1] &= ~8192; + else independentOptions_[1] |= 8192; + } + /// Set whole group + inline int presolveActions() const { + return independentOptions_[1] & 0xffff; + } + inline void setPresolveActions(int action) { + independentOptions_[1] = (independentOptions_[1] & 0xffff0000) | (action & 0xffff); + } + /// Largest column for substitution (normally 3) + inline int substitution() const { + return independentOptions_[2]; + } + inline void setSubstitution(int value) { + independentOptions_[2] = value; + } + inline void setIndependentOption(int type,int value) { + independentOptions_[type] = value; + } + inline int independentOption(int type) const { + return independentOptions_[type]; + } + //@} + +////////////////// data ////////////////// +private: + + /**@name data. + */ + //@{ + /// Solve type + SolveType method_; + /// Presolve type + PresolveType presolveType_; + /// Amount of presolve + int numberPasses_; + /// Options - last is switch for OsiClp + int options_[7]; + /// Extra information + int extraInfo_[7]; + /** Extra algorithm dependent options + 0 - if set return from clpsolve if infeasible + 1 - To be copied over to presolve options + 2 - max substitution level + If Dantzig Wolfe/benders 0 is number blocks, 2 is #passes (notional) + */ + int independentOptions_[3]; + //@} +}; + +/// For saving extra information to see if looping. +class ClpSimplexProgress { + +public: + + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSimplexProgress ( ); + + /// Constructor from model + ClpSimplexProgress ( ClpSimplex * model ); + + /// Copy constructor. + ClpSimplexProgress(const ClpSimplexProgress &); + + /// Assignment operator. This copies the data + ClpSimplexProgress & operator=(const ClpSimplexProgress & rhs); + /// Destructor + ~ClpSimplexProgress ( ); + /// Resets as much as possible + void reset(); + /// Fill from model + void fillFromModel ( ClpSimplex * model ); + + //@} + + /**@name Check progress */ + //@{ + /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken, + >=0 if give up and use as problem status + */ + int looping ( ); + /// Start check at beginning of whileIterating + void startCheck(); + /// Returns cycle length in whileIterating + int cycle(int in, int out, int wayIn, int wayOut); + + /// Returns previous objective (if -1) - current if (0) + double lastObjective(int back = 1) const; + /// Set real primal infeasibility and move back + void setInfeasibility(double value); + /// Returns real primal infeasibility (if -1) - current if (0) + double lastInfeasibility(int back = 1) const; + /// Returns number of primal infeasibilities (if -1) - current if (0) + int numberInfeasibilities(int back = 1) const; + /// Modify objective e.g. if dual infeasible in dual + void modifyObjective(double value); + /// Returns previous iteration number (if -1) - current if (0) + int lastIterationNumber(int back = 1) const; + /// clears all iteration numbers (to switch off panic) + void clearIterationNumbers(); + /// Odd state + inline void newOddState() { + oddState_ = - oddState_ - 1; + } + inline void endOddState() { + oddState_ = abs(oddState_); + } + inline void clearOddState() { + oddState_ = 0; + } + inline int oddState() const { + return oddState_; + } + /// number of bad times + inline int badTimes() const { + return numberBadTimes_; + } + inline void clearBadTimes() { + numberBadTimes_ = 0; + } + /// number of really bad times + inline int reallyBadTimes() const { + return numberReallyBadTimes_; + } + inline void incrementReallyBadTimes() { + numberReallyBadTimes_++; + } + /// number of times flagged + inline int timesFlagged() const { + return numberTimesFlagged_; + } + inline void clearTimesFlagged() { + numberTimesFlagged_ = 0; + } + inline void incrementTimesFlagged() { + numberTimesFlagged_++; + } + + //@} + /**@name Data */ +#define CLP_PROGRESS 5 + //#define CLP_PROGRESS_WEIGHT 10 + //@{ + /// Objective values + double objective_[CLP_PROGRESS]; + /// Sum of infeasibilities for algorithm + double infeasibility_[CLP_PROGRESS]; + /// Sum of real primal infeasibilities for primal + double realInfeasibility_[CLP_PROGRESS]; +#ifdef CLP_PROGRESS_WEIGHT + /// Objective values for weights + double objectiveWeight_[CLP_PROGRESS_WEIGHT]; + /// Sum of infeasibilities for algorithm for weights + double infeasibilityWeight_[CLP_PROGRESS_WEIGHT]; + /// Sum of real primal infeasibilities for primal for weights + double realInfeasibilityWeight_[CLP_PROGRESS_WEIGHT]; + /// Drop for weights + double drop_; + /// Best? for weights + double best_; +#endif + /// Initial weight for weights + double initialWeight_; +#define CLP_CYCLE 12 + /// For cycle checking + //double obj_[CLP_CYCLE]; + int in_[CLP_CYCLE]; + int out_[CLP_CYCLE]; + char way_[CLP_CYCLE]; + /// Pointer back to model so we can get information + ClpSimplex * model_; + /// Number of infeasibilities + int numberInfeasibilities_[CLP_PROGRESS]; + /// Iteration number at which occurred + int iterationNumber_[CLP_PROGRESS]; +#ifdef CLP_PROGRESS_WEIGHT + /// Number of infeasibilities for weights + int numberInfeasibilitiesWeight_[CLP_PROGRESS_WEIGHT]; + /// Iteration number at which occurred for weights + int iterationNumberWeight_[CLP_PROGRESS_WEIGHT]; +#endif + /// Number of times checked (so won't stop too early) + int numberTimes_; + /// Number of times it looked like loop + int numberBadTimes_; + /// Number really bad times + int numberReallyBadTimes_; + /// Number of times no iterations as flagged + int numberTimesFlagged_; + /// If things are in an odd state + int oddState_; + //@} +}; + +#include "ClpConfig.h" +#ifdef CLP_HAS_ABC +#include "AbcCommon.hpp" +/// For saving extra information to see if looping. +class AbcSimplexProgress : public ClpSimplexProgress { + +public: + + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + AbcSimplexProgress ( ); + + /// Constructor from model + AbcSimplexProgress ( ClpSimplex * model ); + + /// Copy constructor. + AbcSimplexProgress(const AbcSimplexProgress &); + + /// Assignment operator. This copies the data + AbcSimplexProgress & operator=(const AbcSimplexProgress & rhs); + /// Destructor + ~AbcSimplexProgress ( ); + + //@} + + /**@name Check progress */ + //@{ + /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken, + >=0 if give up and use as problem status + */ + int looping ( ); + + //@} + /**@name Data */ + //@} +}; +#endif +#endif diff --git a/thirdparty/linux/include/coin/Clp_C_Interface.h b/thirdparty/linux/include/coin/Clp_C_Interface.h new file mode 100644 index 0000000..b91b2d2 --- /dev/null +++ b/thirdparty/linux/include/coin/Clp_C_Interface.h @@ -0,0 +1,525 @@ +/* $Id: Clp_C_Interface.h 2019 2014-01-31 05:18:01Z stefan $ */ +/* + Copyright (C) 2002, 2003 International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef ClpSimplexC_H +#define ClpSimplexC_H + +/* include all defines and ugly stuff */ +#include "Coin_C_defines.h" + +#if defined (CLP_EXTERN_C) +typedef struct { + ClpSolve options; +} Clp_Solve; +#else +typedef void Clp_Solve; +#endif + +/** This is a first "C" interface to Clp. + It has similarities to the OSL V3 interface + and only has most common functions +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /**@name Version info + * + * A Clp library has a version number of the form .., + * where each of major, minor, and release are nonnegative integers. + * For a checkout of the Clp stable branch, release is 9999. + * For a checkout of the Clp development branch, major, minor, and release are 9999. + */ + /*@{*/ + /** Clp library version number as string. */ + COINLIBAPI const char* COINLINKAGE Clp_Version(void); + /** Major number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionMajor(void); + /** Minor number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionMinor(void); + /** Release number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionRelease(void); + /*@}*/ + + /**@name Constructors and destructor + These do not have an exact analogue in C++. + The user does not need to know structure of Clp_Simplex or Clp_Solve. + + For (almost) all Clp_* functions outside this group there is an exact C++ + analogue created by taking the first parameter out, removing the Clp_ + from name and applying the method to an object of type ClpSimplex. + + Similarly, for all ClpSolve_* functions there is an exact C++ + analogue created by taking the first parameter out, removing the ClpSolve_ + from name and applying the method to an object of type ClpSolve. + */ + /*@{*/ + + /** Default constructor */ + COINLIBAPI Clp_Simplex * COINLINKAGE Clp_newModel(void); + /** Destructor */ + COINLIBAPI void COINLINKAGE Clp_deleteModel(Clp_Simplex * model); + /** Default constructor */ + COINLIBAPI Clp_Solve * COINLINKAGE ClpSolve_new(); + /** Destructor */ + COINLIBAPI void COINLINKAGE ClpSolve_delete(Clp_Solve * solve); + /*@}*/ + + /**@name Load model - loads some stuff and initializes others */ + /*@{*/ + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • rowub: all rows have upper bound infinity +
  • rowlb: all rows have lower bound -infinity +
  • obj: all variables have 0 objective coefficient +
+ */ + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + COINLIBAPI void COINLINKAGE Clp_loadProblem (Clp_Simplex * model, const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /* read quadratic part of the objective (the matrix part) */ + COINLIBAPI void COINLINKAGE + Clp_loadQuadraticObjective(Clp_Simplex * model, + const int numberColumns, + const CoinBigIndex * start, + const int * column, + const double * element); + /** Read an mps file from the given filename */ + COINLIBAPI int COINLINKAGE Clp_readMps(Clp_Simplex * model, const char *filename, + int keepNames, + int ignoreErrors); + /** Copy in integer informations */ + COINLIBAPI void COINLINKAGE Clp_copyInIntegerInformation(Clp_Simplex * model, const char * information); + /** Drop integer informations */ + COINLIBAPI void COINLINKAGE Clp_deleteIntegerInformation(Clp_Simplex * model); + /** Resizes rim part of model */ + COINLIBAPI void COINLINKAGE Clp_resize (Clp_Simplex * model, int newNumberRows, int newNumberColumns); + /** Deletes rows */ + COINLIBAPI void COINLINKAGE Clp_deleteRows(Clp_Simplex * model, int number, const int * which); + /** Add rows */ + COINLIBAPI void COINLINKAGE Clp_addRows(Clp_Simplex * model, int number, const double * rowLower, + const double * rowUpper, + const int * rowStarts, const int * columns, + const double * elements); + + /** Deletes columns */ + COINLIBAPI void COINLINKAGE Clp_deleteColumns(Clp_Simplex * model, int number, const int * which); + /** Add columns */ + COINLIBAPI void COINLINKAGE Clp_addColumns(Clp_Simplex * model, int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const int * columnStarts, const int * rows, + const double * elements); + /** Change row lower bounds */ + COINLIBAPI void COINLINKAGE Clp_chgRowLower(Clp_Simplex * model, const double * rowLower); + /** Change row upper bounds */ + COINLIBAPI void COINLINKAGE Clp_chgRowUpper(Clp_Simplex * model, const double * rowUpper); + /** Change column lower bounds */ + COINLIBAPI void COINLINKAGE Clp_chgColumnLower(Clp_Simplex * model, const double * columnLower); + /** Change column upper bounds */ + COINLIBAPI void COINLINKAGE Clp_chgColumnUpper(Clp_Simplex * model, const double * columnUpper); + /** Change objective coefficients */ + COINLIBAPI void COINLINKAGE Clp_chgObjCoefficients(Clp_Simplex * model, const double * objIn); + /** Drops names - makes lengthnames 0 and names empty */ + COINLIBAPI void COINLINKAGE Clp_dropNames(Clp_Simplex * model); + /** Copies in names */ + COINLIBAPI void COINLINKAGE Clp_copyNames(Clp_Simplex * model, const char * const * rowNames, + const char * const * columnNames); + + /*@}*/ + /**@name gets and sets - you will find some synonyms at the end of this file */ + /*@{*/ + /** Number of rows */ + COINLIBAPI int COINLINKAGE Clp_numberRows(Clp_Simplex * model); + /** Number of columns */ + COINLIBAPI int COINLINKAGE Clp_numberColumns(Clp_Simplex * model); + /** Primal tolerance to use */ + COINLIBAPI double COINLINKAGE Clp_primalTolerance(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setPrimalTolerance(Clp_Simplex * model, double value) ; + /** Dual tolerance to use */ + COINLIBAPI double COINLINKAGE Clp_dualTolerance(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualTolerance(Clp_Simplex * model, double value) ; + /** Dual objective limit */ + COINLIBAPI double COINLINKAGE Clp_dualObjectiveLimit(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualObjectiveLimit(Clp_Simplex * model, double value); + /** Objective offset */ + COINLIBAPI double COINLINKAGE Clp_objectiveOffset(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setObjectiveOffset(Clp_Simplex * model, double value); + /** Fills in array with problem name */ + COINLIBAPI void COINLINKAGE Clp_problemName(Clp_Simplex * model, int maxNumberCharacters, char * array); + /* Sets problem name. Must have \0 at end. */ + COINLIBAPI int COINLINKAGE + Clp_setProblemName(Clp_Simplex * model, int maxNumberCharacters, char * array); + /** Number of iterations */ + COINLIBAPI int COINLINKAGE Clp_numberIterations(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setNumberIterations(Clp_Simplex * model, int numberIterations); + /** Maximum number of iterations */ + COINLIBAPI int maximumIterations(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setMaximumIterations(Clp_Simplex * model, int value); + /** Maximum time in seconds (from when set called) */ + COINLIBAPI double COINLINKAGE Clp_maximumSeconds(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setMaximumSeconds(Clp_Simplex * model, double value); + /** Returns true if hit maximum iterations (or time) */ + COINLIBAPI int COINLINKAGE Clp_hitMaximumIterations(Clp_Simplex * model); + /** Status of problem: + 0 - optimal + 1 - primal infeasible + 2 - dual infeasible + 3 - stopped on iterations etc + 4 - stopped due to errors + */ + COINLIBAPI int COINLINKAGE Clp_status(Clp_Simplex * model); + /** Set problem status */ + COINLIBAPI void COINLINKAGE Clp_setProblemStatus(Clp_Simplex * model, int problemStatus); + /** Secondary status of problem - may get extended + 0 - none + 1 - primal infeasible because dual limit reached + 2 - scaled problem optimal - unscaled has primal infeasibilities + 3 - scaled problem optimal - unscaled has dual infeasibilities + 4 - scaled problem optimal - unscaled has both dual and primal infeasibilities + */ + COINLIBAPI int COINLINKAGE Clp_secondaryStatus(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setSecondaryStatus(Clp_Simplex * model, int status); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI double COINLINKAGE Clp_optimizationDirection(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setOptimizationDirection(Clp_Simplex * model, double value); + /** Primal row solution */ + COINLIBAPI double * COINLINKAGE Clp_primalRowSolution(Clp_Simplex * model); + /** Primal column solution */ + COINLIBAPI double * COINLINKAGE Clp_primalColumnSolution(Clp_Simplex * model); + /** Dual row solution */ + COINLIBAPI double * COINLINKAGE Clp_dualRowSolution(Clp_Simplex * model); + /** Reduced costs */ + COINLIBAPI double * COINLINKAGE Clp_dualColumnSolution(Clp_Simplex * model); + /** Row lower */ + COINLIBAPI double* COINLINKAGE Clp_rowLower(Clp_Simplex * model); + /** Row upper */ + COINLIBAPI double* COINLINKAGE Clp_rowUpper(Clp_Simplex * model); + /** Objective */ + COINLIBAPI double * COINLINKAGE Clp_objective(Clp_Simplex * model); + /** Column Lower */ + COINLIBAPI double * COINLINKAGE Clp_columnLower(Clp_Simplex * model); + /** Column Upper */ + COINLIBAPI double * COINLINKAGE Clp_columnUpper(Clp_Simplex * model); + /** Number of elements in matrix */ + COINLIBAPI int COINLINKAGE Clp_getNumElements(Clp_Simplex * model); + /* Column starts in matrix */ + COINLIBAPI const CoinBigIndex * COINLINKAGE Clp_getVectorStarts(Clp_Simplex * model); + /* Row indices in matrix */ + COINLIBAPI const int * COINLINKAGE Clp_getIndices(Clp_Simplex * model); + /* Column vector lengths in matrix */ + COINLIBAPI const int * COINLINKAGE Clp_getVectorLengths(Clp_Simplex * model); + /* Element values in matrix */ + COINLIBAPI const double * COINLINKAGE Clp_getElements(Clp_Simplex * model); + /** Objective value */ + COINLIBAPI double COINLINKAGE Clp_objectiveValue(Clp_Simplex * model); + /** Integer information */ + COINLIBAPI char * COINLINKAGE Clp_integerInformation(Clp_Simplex * model); + /** Gives Infeasibility ray. + * + * Use Clp_freeRay to free the returned array. + * + * @return infeasibility ray, or NULL returned if none/wrong. + */ + COINLIBAPI double * COINLINKAGE Clp_infeasibilityRay(Clp_Simplex * model); + /** Gives ray in which the problem is unbounded. + * + * Use Clp_freeRay to free the returned array. + * + * @return unbounded ray, or NULL returned if none/wrong. + */ + COINLIBAPI double * COINLINKAGE Clp_unboundedRay(Clp_Simplex * model); + /** Frees a infeasibility or unbounded ray. */ + COINLIBAPI void COINLINKAGE Clp_freeRay(Clp_Simplex * model, double * ray); + /** See if status array exists (partly for OsiClp) */ + COINLIBAPI int COINLINKAGE Clp_statusExists(Clp_Simplex * model); + /** Return address of status array (char[numberRows+numberColumns]) */ + COINLIBAPI unsigned char * COINLINKAGE Clp_statusArray(Clp_Simplex * model); + /** Copy in status vector */ + COINLIBAPI void COINLINKAGE Clp_copyinStatus(Clp_Simplex * model, const unsigned char * statusArray); + /* status values are as in ClpSimplex.hpp i.e. 0 - free, 1 basic, 2 at upper, + 3 at lower, 4 superbasic, (5 fixed) */ + /* Get variable basis info */ + COINLIBAPI int COINLINKAGE Clp_getColumnStatus(Clp_Simplex * model, int sequence); + /* Get row basis info */ + COINLIBAPI int COINLINKAGE Clp_getRowStatus(Clp_Simplex * model, int sequence); + /* Set variable basis info (and value if at bound) */ + COINLIBAPI void COINLINKAGE Clp_setColumnStatus(Clp_Simplex * model, + int sequence, int value); + /* Set row basis info (and value if at bound) */ + COINLIBAPI void COINLINKAGE Clp_setRowStatus(Clp_Simplex * model, + int sequence, int value); + + /** User pointer for whatever reason */ + COINLIBAPI void COINLINKAGE Clp_setUserPointer (Clp_Simplex * model, void * pointer); + COINLIBAPI void * COINLINKAGE Clp_getUserPointer (Clp_Simplex * model); + /*@}*/ + /**@name Message handling. Call backs are handled by ONE function */ + /*@{*/ + /** Pass in Callback function. + Message numbers up to 1000000 are Clp, Coin ones have 1000000 added */ + COINLIBAPI void COINLINKAGE Clp_registerCallBack(Clp_Simplex * model, + clp_callback userCallBack); + /** Unset Callback function */ + COINLIBAPI void COINLINKAGE Clp_clearCallBack(Clp_Simplex * model); + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + COINLIBAPI void COINLINKAGE Clp_setLogLevel(Clp_Simplex * model, int value); + COINLIBAPI int COINLINKAGE Clp_logLevel(Clp_Simplex * model); + /** length of names (0 means no names0 */ + COINLIBAPI int COINLINKAGE Clp_lengthNames(Clp_Simplex * model); + /** Fill in array (at least lengthNames+1 long) with a row name */ + COINLIBAPI void COINLINKAGE Clp_rowName(Clp_Simplex * model, int iRow, char * name); + /** Fill in array (at least lengthNames+1 long) with a column name */ + COINLIBAPI void COINLINKAGE Clp_columnName(Clp_Simplex * model, int iColumn, char * name); + + /*@}*/ + + + /**@name Functions most useful to user */ + /*@{*/ + /** General solve algorithm which can do presolve. + See ClpSolve.hpp for options + */ + COINLIBAPI int COINLINKAGE Clp_initialSolve(Clp_Simplex * model); + /** Pass solve options. (Exception to direct analogue rule) */ + COINLIBAPI int COINLINKAGE Clp_initialSolveWithOptions(Clp_Simplex * model, Clp_Solve *); + /** Dual initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialDualSolve(Clp_Simplex * model); + /** Primal initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialPrimalSolve(Clp_Simplex * model); + /** Barrier initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialBarrierSolve(Clp_Simplex * model); + /** Barrier initial solve, no crossover */ + COINLIBAPI int COINLINKAGE Clp_initialBarrierNoCrossSolve(Clp_Simplex * model); + /** Dual algorithm - see ClpSimplexDual.hpp for method */ + COINLIBAPI int COINLINKAGE Clp_dual(Clp_Simplex * model, int ifValuesPass); + /** Primal algorithm - see ClpSimplexPrimal.hpp for method */ + COINLIBAPI int COINLINKAGE Clp_primal(Clp_Simplex * model, int ifValuesPass); +#ifndef SLIM_CLP + /** Solve the problem with the idiot code */ + COINLIBAPI void COINLINKAGE Clp_idiot(Clp_Simplex * model, int tryhard); +#endif + /** Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */ + COINLIBAPI void COINLINKAGE Clp_scaling(Clp_Simplex * model, int mode); + /** Gets scalingFlag */ + COINLIBAPI int COINLINKAGE Clp_scalingFlag(Clp_Simplex * model); + /** Crash - at present just aimed at dual, returns + -2 if dual preferred and crash basis created + -1 if dual preferred and all slack basis preferred + 0 if basis going in was not all slack + 1 if primal preferred and all slack basis preferred + 2 if primal preferred and crash basis created. + + if gap between bounds <="gap" variables can be flipped + + If "pivot" is + 0 No pivoting (so will just be choice of algorithm) + 1 Simple pivoting e.g. gub + 2 Mini iterations + */ + COINLIBAPI int COINLINKAGE Clp_crash(Clp_Simplex * model, double gap, int pivot); + /*@}*/ + + + /**@name most useful gets and sets */ + /*@{*/ + /** If problem is primal feasible */ + COINLIBAPI int COINLINKAGE Clp_primalFeasible(Clp_Simplex * model); + /** If problem is dual feasible */ + COINLIBAPI int COINLINKAGE Clp_dualFeasible(Clp_Simplex * model); + /** Dual bound */ + COINLIBAPI double COINLINKAGE Clp_dualBound(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualBound(Clp_Simplex * model, double value); + /** Infeasibility cost */ + COINLIBAPI double COINLINKAGE Clp_infeasibilityCost(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setInfeasibilityCost(Clp_Simplex * model, double value); + /** Perturbation: + 50 - switch on perturbation + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + others are for playing + */ + COINLIBAPI int COINLINKAGE Clp_perturbation(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setPerturbation(Clp_Simplex * model, int value); + /** Current (or last) algorithm */ + COINLIBAPI int COINLINKAGE Clp_algorithm(Clp_Simplex * model); + /** Set algorithm */ + COINLIBAPI void COINLINKAGE Clp_setAlgorithm(Clp_Simplex * model, int value); + /** Sum of dual infeasibilities */ + COINLIBAPI double COINLINKAGE Clp_sumDualInfeasibilities(Clp_Simplex * model); + /** Number of dual infeasibilities */ + COINLIBAPI int COINLINKAGE Clp_numberDualInfeasibilities(Clp_Simplex * model); + /** Sum of primal infeasibilities */ + COINLIBAPI double COINLINKAGE Clp_sumPrimalInfeasibilities(Clp_Simplex * model); + /** Number of primal infeasibilities */ + COINLIBAPI int COINLINKAGE Clp_numberPrimalInfeasibilities(Clp_Simplex * model); + /** Save model to file, returns 0 if success. This is designed for + use outside algorithms so does not save iterating arrays etc. + It does not save any messaging information. + Does not save scaling values. + It does not know about all types of virtual functions. + */ + COINLIBAPI int COINLINKAGE Clp_saveModel(Clp_Simplex * model, const char * fileName); + /** Restore model from file, returns 0 if success, + deletes current model */ + COINLIBAPI int COINLINKAGE Clp_restoreModel(Clp_Simplex * model, const char * fileName); + + /** Just check solution (for external use) - sets sum of + infeasibilities etc */ + COINLIBAPI void COINLINKAGE Clp_checkSolution(Clp_Simplex * model); + /*@}*/ + + /******************** End of most useful part **************/ + /**@name gets and sets - some synonyms */ + /*@{*/ + /** Number of rows */ + COINLIBAPI int COINLINKAGE Clp_getNumRows(Clp_Simplex * model); + /** Number of columns */ + COINLIBAPI int COINLINKAGE Clp_getNumCols(Clp_Simplex * model); + /** Number of iterations */ + COINLIBAPI int COINLINKAGE Clp_getIterationCount(Clp_Simplex * model); + /** Are there a numerical difficulties? */ + COINLIBAPI int COINLINKAGE Clp_isAbandoned(Clp_Simplex * model); + /** Is optimality proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenOptimal(Clp_Simplex * model); + /** Is primal infeasiblity proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenPrimalInfeasible(Clp_Simplex * model); + /** Is dual infeasiblity proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenDualInfeasible(Clp_Simplex * model); + /** Is the given primal objective limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isPrimalObjectiveLimitReached(Clp_Simplex * model) ; + /** Is the given dual objective limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isDualObjectiveLimitReached(Clp_Simplex * model) ; + /** Iteration limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isIterationLimitReached(Clp_Simplex * model); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI double COINLINKAGE Clp_getObjSense(Clp_Simplex * model); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI void COINLINKAGE Clp_setObjSense(Clp_Simplex * model, double objsen); + /** Primal row solution */ + COINLIBAPI const double * COINLINKAGE Clp_getRowActivity(Clp_Simplex * model); + /** Primal column solution */ + COINLIBAPI const double * COINLINKAGE Clp_getColSolution(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setColSolution(Clp_Simplex * model, const double * input); + /** Dual row solution */ + COINLIBAPI const double * COINLINKAGE Clp_getRowPrice(Clp_Simplex * model); + /** Reduced costs */ + COINLIBAPI const double * COINLINKAGE Clp_getReducedCost(Clp_Simplex * model); + /** Row lower */ + COINLIBAPI const double* COINLINKAGE Clp_getRowLower(Clp_Simplex * model); + /** Row upper */ + COINLIBAPI const double* COINLINKAGE Clp_getRowUpper(Clp_Simplex * model); + /** Objective */ + COINLIBAPI const double * COINLINKAGE Clp_getObjCoefficients(Clp_Simplex * model); + /** Column Lower */ + COINLIBAPI const double * COINLINKAGE Clp_getColLower(Clp_Simplex * model); + /** Column Upper */ + COINLIBAPI const double * COINLINKAGE Clp_getColUpper(Clp_Simplex * model); + /** Objective value */ + COINLIBAPI double COINLINKAGE Clp_getObjValue(Clp_Simplex * model); + /** Print model for debugging purposes */ + COINLIBAPI void COINLINKAGE Clp_printModel(Clp_Simplex * model, const char * prefix); + /* Small element value - elements less than this set to zero, + default is 1.0e-20 */ + COINLIBAPI double COINLINKAGE Clp_getSmallElementValue(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setSmallElementValue(Clp_Simplex * model, double value); + /*@}*/ + + + /**@name Get and set ClpSolve options + */ + /*@{*/ + COINLIBAPI void COINLINKAGE ClpSolve_setSpecialOption(Clp_Solve *, int which, int value, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getSpecialOption(Clp_Solve *, int which); + + /** method: (see ClpSolve::SolveType) + 0 - dual simplex + 1 - primal simplex + 2 - primal or sprint + 3 - barrier + 4 - barrier no crossover + 5 - automatic + 6 - not implemented + -- pass extraInfo == -1 for default behavior */ + COINLIBAPI void COINLINKAGE ClpSolve_setSolveType(Clp_Solve *, int method, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getSolveType(Clp_Solve *); + + /** amount: (see ClpSolve::PresolveType) + 0 - presolve on + 1 - presolve off + 2 - presolve number + 3 - presolve number cost + -- pass extraInfo == -1 for default behavior */ + COINLIBAPI void COINLINKAGE ClpSolve_setPresolveType(Clp_Solve *, int amount, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getPresolveType(Clp_Solve *); + + COINLIBAPI int COINLINKAGE ClpSolve_getPresolvePasses(Clp_Solve *); + COINLIBAPI int COINLINKAGE ClpSolve_getExtraInfo(Clp_Solve *, int which); + COINLIBAPI void COINLINKAGE ClpSolve_setInfeasibleReturn(Clp_Solve *, int trueFalse); + COINLIBAPI int COINLINKAGE ClpSolve_infeasibleReturn(Clp_Solve *); + + COINLIBAPI int COINLINKAGE ClpSolve_doDual(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDual(Clp_Solve *, int doDual); + + COINLIBAPI int COINLINKAGE ClpSolve_doSingleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoSingleton(Clp_Solve *, int doSingleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doDoubleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDoubleton(Clp_Solve *, int doDoubleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doTripleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoTripleton(Clp_Solve *, int doTripleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doTighten(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoTighten(Clp_Solve *, int doTighten); + + COINLIBAPI int COINLINKAGE ClpSolve_doForcing(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoForcing(Clp_Solve *, int doForcing); + + COINLIBAPI int COINLINKAGE ClpSolve_doImpliedFree(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoImpliedFree(Clp_Solve *, int doImpliedFree); + + COINLIBAPI int COINLINKAGE ClpSolve_doDupcol(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDupcol(Clp_Solve *, int doDupcol); + + COINLIBAPI int COINLINKAGE ClpSolve_doDuprow(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDuprow(Clp_Solve *, int doDuprow); + + COINLIBAPI int COINLINKAGE ClpSolve_doSingletonColumn(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoSingletonColumn(Clp_Solve *, int doSingleton); + + COINLIBAPI int COINLINKAGE ClpSolve_presolveActions(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setPresolveActions(Clp_Solve *, int action); + + COINLIBAPI int COINLINKAGE ClpSolve_substitution(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setSubstitution(Clp_Solve *, int value); + + /*@}*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/linux/include/coin/CoinAlloc.hpp b/thirdparty/linux/include/coin/CoinAlloc.hpp new file mode 100644 index 0000000..8f6b08c --- /dev/null +++ b/thirdparty/linux/include/coin/CoinAlloc.hpp @@ -0,0 +1,176 @@ +/* $Id: CoinAlloc.hpp 1438 2011-06-09 18:14:12Z stefan $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinAlloc_hpp +#define CoinAlloc_hpp + +#include "CoinUtilsConfig.h" +#include + +#if !defined(COINUTILS_MEMPOOL_MAXPOOLED) +# define COINUTILS_MEMPOOL_MAXPOOLED -1 +#endif + +#if (COINUTILS_MEMPOOL_MAXPOOLED >= 0) + +#ifndef COINUTILS_MEMPOOL_ALIGNMENT +#define COINUTILS_MEMPOOL_ALIGNMENT 16 +#endif + +/* Note: + This memory pool implementation assumes that sizeof(size_t) and + sizeof(void*) are both <= COINUTILS_MEMPOOL_ALIGNMENT. + Choosing an alignment of 4 will cause segfault on 64-bit platforms and may + lead to bad performance on 32-bit platforms. So 8 is a mnimum recommended + alignment. Probably 16 does not waste too much space either and may be even + better for performance. One must play with it. +*/ + +//############################################################################# + +#if (COINUTILS_MEMPOOL_ALIGNMENT == 16) +static const std::size_t CoinAllocPtrShift = 4; +static const std::size_t CoinAllocRoundMask = ~((std::size_t)15); +#elif (COINUTILS_MEMPOOL_ALIGNMENT == 8) +static const std::size_t CoinAllocPtrShift = 3; +static const std::size_t CoinAllocRoundMask = ~((std::size_t)7); +#else +#error "COINUTILS_MEMPOOL_ALIGNMENT must be defined as 8 or 16 (or this code needs to be changed :-)" +#endif + +//############################################################################# + +#ifndef COIN_MEMPOOL_SAVE_BLOCKHEADS +# define COIN_MEMPOOL_SAVE_BLOCKHEADS 0 +#endif + +//############################################################################# + +class CoinMempool +{ +private: +#if (COIN_MEMPOOL_SAVE_BLOCKHEADS == 1) + char** block_heads; + std::size_t block_num; + std::size_t max_block_num; +#endif +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_t mutex_; +#endif + int last_block_size_; + char* first_free_; + const std::size_t entry_size_; + +private: + CoinMempool(const CoinMempool&); + CoinMempool& operator=(const CoinMempool&); + +private: + char* allocate_new_block(); + inline void lock_mutex() { +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_lock(&mutex_); +#endif + } + inline void unlock_mutex() { +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_unlock(&mutex_); +#endif + } + +public: + CoinMempool(std::size_t size = 0); + ~CoinMempool(); + + char* alloc(); + inline void dealloc(char *p) + { + char** pp = (char**)p; + lock_mutex(); + *pp = first_free_; + first_free_ = p; + unlock_mutex(); + } +}; + +//############################################################################# + +/** A memory pool allocator. + + If a request arrives for allocating \c n bytes then it is first + rounded up to the nearest multiple of \c sizeof(void*) (this is \c + n_roundup), then one more \c sizeof(void*) is added to this + number. If the result is no more than maxpooled_ then + the appropriate pool is used to get a chunk of memory, if not, + then malloc is used. In either case, the size of the allocated + chunk is written into the first \c sizeof(void*) bytes and a + pointer pointing afterwards is returned. +*/ + +class CoinAlloc +{ +private: + CoinMempool* pool_; + int maxpooled_; +public: + CoinAlloc(); + ~CoinAlloc() {} + + inline void* alloc(const std::size_t n) + { + if (maxpooled_ <= 0) { + return std::malloc(n); + } + char *p = NULL; + const std::size_t to_alloc = + ((n+COINUTILS_MEMPOOL_ALIGNMENT-1) & CoinAllocRoundMask) + + COINUTILS_MEMPOOL_ALIGNMENT; + CoinMempool* pool = NULL; + if (maxpooled_ > 0 && to_alloc >= (size_t)maxpooled_) { + p = static_cast(std::malloc(to_alloc)); + if (p == NULL) throw std::bad_alloc(); + } else { + pool = pool_ + (to_alloc >> CoinAllocPtrShift); + p = pool->alloc(); + } + *((CoinMempool**)p) = pool; + return static_cast(p+COINUTILS_MEMPOOL_ALIGNMENT); + } + + inline void dealloc(void* p) + { + if (maxpooled_ <= 0) { + std::free(p); + return; + } + if (p) { + char* base = static_cast(p)-COINUTILS_MEMPOOL_ALIGNMENT; + CoinMempool* pool = *((CoinMempool**)base); + if (!pool) { + std::free(base); + } else { + pool->dealloc(base); + } + } + } +}; + +extern CoinAlloc CoinAllocator; + +//############################################################################# + +#if defined(COINUTILS_MEMPOOL_OVERRIDE_NEW) && (COINUTILS_MEMPOOL_OVERRIDE_NEW == 1) +void* operator new(std::size_t size) throw (std::bad_alloc); +void* operator new[](std::size_t) throw (std::bad_alloc); +void operator delete(void*) throw(); +void operator delete[](void*) throw(); +void* operator new(std::size_t, const std::nothrow_t&) throw(); +void* operator new[](std::size_t, const std::nothrow_t&) throw(); +void operator delete(void*, const std::nothrow_t&) throw(); +void operator delete[](void*, const std::nothrow_t&) throw(); +#endif + +#endif /*(COINUTILS_MEMPOOL_MAXPOOLED >= 0)*/ +#endif diff --git a/thirdparty/linux/include/coin/CoinBuild.hpp b/thirdparty/linux/include/coin/CoinBuild.hpp new file mode 100644 index 0000000..770c269 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinBuild.hpp @@ -0,0 +1,149 @@ +/* $Id: CoinBuild.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinBuild_H +#define CoinBuild_H + + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" +#include "CoinFinite.hpp" + + +/** + In many cases it is natural to build a model by adding one row at a time. In Coin this + is inefficient so this class gives some help. An instance of CoinBuild can be built up + more efficiently and then added to the Clp/OsiModel in one go. + + It may be more efficient to have fewer arrays and re-allocate them but this should + give a large gain over addRow. + + I have now extended it to columns. + +*/ + +class CoinBuild { + +public: + /**@name Useful methods */ + //@{ + /// add a row + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower=-COIN_DBL_MAX, + double rowUpper=COIN_DBL_MAX); + /// add a column + void addColumn(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0); + /// add a column + inline void addCol(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0) + { addColumn(numberInColumn, rows, elements, columnLower, columnUpper, objectiveValue);} + /// Return number of rows or maximum found so far + inline int numberRows() const + { return (type_==0) ? numberItems_ : numberOther_;} + /// Return number of columns or maximum found so far + inline int numberColumns() const + { return (type_==1) ? numberItems_ : numberOther_;} + /// Return number of elements + inline CoinBigIndex numberElements() const + { return numberElements_;} + /** Returns number of elements in a row and information in row + */ + int row(int whichRow, double & rowLower, double & rowUpper, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current row and information in row + Used as rows may be stored in a chain + */ + int currentRow(double & rowLower, double & rowUpper, + const int * & indices, const double * & elements) const; + /// Set current row + void setCurrentRow(int whichRow); + /// Returns current row number + int currentRow() const; + /** Returns number of elements in a column and information in column + */ + int column(int whichColumn, + double & columnLower, double & columnUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current column and information in column + Used as columns may be stored in a chain + */ + int currentColumn( double & columnLower, double & columnUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /// Set current column + void setCurrentColumn(int whichColumn); + /// Returns current column number + int currentColumn() const; + /// Returns type + inline int type() const + { return type_;} + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinBuild(); + /** Constructor with type 0==for addRow, 1== for addColumn. */ + CoinBuild(int type); + /** Destructor */ + ~CoinBuild(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinBuild(const CoinBuild&); + /// = + CoinBuild& operator=(const CoinBuild&); + //@} +private: + /// Set current + void setMutableCurrent(int which) const; + /// add a item + void addItem(int numberInItem, const int * indices, + const double * elements, + double itemLower, + double itemUpper, double objectiveValue); + /** Returns number of elements in a item and information in item + */ + int item(int whichItem, + double & itemLower, double & itemUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current item and information in item + Used as items may be stored in a chain + */ + int currentItem( double & itemLower, double & itemUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /// Set current item + void setCurrentItem(int whichItem); + /// Returns current item number + int currentItem() const; + +private: + /**@name Data members */ + //@{ + /// Current number of items + int numberItems_; + /// Current number of other dimension i.e. Columns if addRow (i.e. max) + int numberOther_; + /// Current number of elements + CoinBigIndex numberElements_; + /// Current item pointer + mutable double * currentItem_; + /// First item pointer + double * firstItem_; + /// Last item pointer + double * lastItem_; + /// Type of build - 0 for row, 1 for column, -1 unset + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinDenseFactorization.hpp b/thirdparty/linux/include/coin/CoinDenseFactorization.hpp new file mode 100644 index 0000000..3ba7528 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinDenseFactorization.hpp @@ -0,0 +1,419 @@ +/* $Id: CoinDenseFactorization.hpp 1759 2014-11-18 11:07:23Z forrest $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +/* + Authors + + John Forrest + + */ +#ifndef CoinDenseFactorization_H +#define CoinDenseFactorization_H + +#include +#include +#include +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinFactorization.hpp" +#if COIN_FACTORIZATION_DENSE_CODE == 2 +#undef COIN_FACTORIZATION_DENSE_CODE +#endif +class CoinPackedMatrix; +/// Abstract base class which also has some scalars so can be used from Dense or Simp +class CoinOtherFactorization { + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinOtherFactorization ( ); + /// Copy constructor + CoinOtherFactorization ( const CoinOtherFactorization &other); + + /// Destructor + virtual ~CoinOtherFactorization ( ); + /// = copy + CoinOtherFactorization & operator = ( const CoinOtherFactorization & other ); + + /// Clone + virtual CoinOtherFactorization * clone() const = 0; + //@} + + /**@name general stuff such as status */ + //@{ + /// Returns status + inline int status ( ) const { + return status_; + } + /// Sets status + inline void setStatus ( int value) + { status_=value; } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + return numberPivots_; + } + /// Sets number of pivots since factorization + inline void setPivots ( int value ) + { numberPivots_=value; } + /// Set number of Rows after factorization + inline void setNumberRows(int value) + { numberRows_ = value; } + /// Number of Rows after factorization + inline int numberRows ( ) const { + return numberRows_; + } + /// Total number of columns in factorization + inline int numberColumns ( ) const { + return numberColumns_; + } + /// Number of good columns in factorization + inline int numberGoodColumns ( ) const { + return numberGoodU_; + } + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) + { relaxCheck_ = value;} + inline double getAccuracyCheck() const + { return relaxCheck_;} + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + return maximumPivots_ ; + } + /// Set maximum pivots + virtual void maximumPivots ( int value ); + + /// Pivot tolerance + inline double pivotTolerance ( ) const { + return pivotTolerance_ ; + } + void pivotTolerance ( double value ); + /// Zero tolerance + inline double zeroTolerance ( ) const { + return zeroTolerance_ ; + } + void zeroTolerance ( double value ); +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + inline double slackValue ( ) const { + return slackValue_ ; + } + void slackValue ( double value ); +#endif + /// Returns array to put basis elements in + virtual CoinFactorizationDouble * elements() const; + /// Returns pivot row + virtual int * pivotRow() const; + /// Returns work area + virtual CoinFactorizationDouble * workArea() const; + /// Returns int work area + virtual int * intWorkArea() const; + /// Number of entries in each row + virtual int * numberInRow() const; + /// Number of entries in each column + virtual int * numberInColumn() const; + /// Returns array to put basis starts in + virtual CoinBigIndex * starts() const; + /// Returns permute back + virtual int * permuteBack() const; + /** Get solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + inline int solveMode() const + { return solveMode_ ;} + /** Set solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + inline void setSolveMode(int value) + { solveMode_ = value;} + /// Returns true if wants tableauColumn in replaceColumn + virtual bool wantsTableauColumn() const; + /** Useful information for factorization + 0 - iteration number + whereFrom is 0 for factorize and 1 for replaceColumn + */ + virtual void setUsefulInformation(const int * info,int whereFrom); + /// Get rid of all memory + virtual void clearArrays() {} + //@} + /**@name virtual general stuff such as permutation */ + //@{ + /// Returns array to put basis indices in + virtual int * indices() const = 0; + /// Returns permute in + virtual int * permute() const = 0; + /// Total number of elements in factorization + virtual int numberElements ( ) const = 0; + //@} + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ) = 0; + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ) = 0; + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ) = 0; + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable) = 0; + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns) = 0; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8)=0; + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) = 0; + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const = 0; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false) = 0; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const = 0; + //@} + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Pivot tolerance + double pivotTolerance_; + /// Zero tolerance + double zeroTolerance_; +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + double slackValue_; +#else +#ifndef slackValue_ +#define slackValue_ -1.0 +#endif +#endif + /// Relax check on accuracy in replaceColumn + double relaxCheck_; + /// Number of elements after factorization + CoinBigIndex factorElements_; + /// Number of Rows in factorization + int numberRows_; + /// Number of Columns in factorization + int numberColumns_; + /// Number factorized in U (not row singletons) + int numberGoodU_; + /// Maximum number of pivots before factorization + int maximumPivots_; + /// Number pivots since last factorization + int numberPivots_; + /// Status of factorization + int status_; + /// Maximum rows ever (i.e. use to copy arrays etc) + int maximumRows_; + /// Maximum length of iterating area + CoinBigIndex maximumSpace_; + /// Pivot row + int * pivotRow_; + /** Elements of factorization and updates + length is maxR*maxR+maxSpace + will always be long enough so can have nR*nR ints in maxSpace + */ + CoinFactorizationDouble * elements_; + /// Work area of numberRows_ + CoinFactorizationDouble * workArea_; + /** Solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + int solveMode_; + //@} +}; +/** This deals with Factorization and Updates + This is a simple dense version so other people can write a better one + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + + + +class CoinDenseFactorization : public CoinOtherFactorization { + friend void CoinDenseFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinDenseFactorization ( ); + /// Copy constructor + CoinDenseFactorization ( const CoinDenseFactorization &other); + + /// Destructor + virtual ~CoinDenseFactorization ( ); + /// = copy + CoinDenseFactorization & operator = ( const CoinDenseFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + //@} + + /**@name general stuff such as number of elements */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual inline int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool = false) + { return updateColumn(regionSparse,regionSparse2);} + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + /// Returns array to put basis indices in + virtual inline int * indices() const + { return reinterpret_cast (elements_+numberRows_*numberRows_);} + /// Returns permute in + virtual inline int * permute() const + { return NULL;/*pivotRow_*/;} + //@} + + /// The real work of desstructor + void gutsOfDestructor(); + /// The real work of constructor + void gutsOfInitialize(); + /// The real work of copy + void gutsOfCopy(const CoinDenseFactorization &other); + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/CoinDenseVector.hpp b/thirdparty/linux/include/coin/CoinDenseVector.hpp new file mode 100644 index 0000000..77ff9af --- /dev/null +++ b/thirdparty/linux/include/coin/CoinDenseVector.hpp @@ -0,0 +1,383 @@ +/* $Id: CoinDenseVector.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinDenseVector_H +#define CoinDenseVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include +#include +#include +#include "CoinHelperFunctions.hpp" + +//############################################################################# +/** A function that tests the methods in the CoinDenseVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ + template void + CoinDenseVectorUnitTest(T dummy); + +//############################################################################# +/** Dense Vector + +Stores a dense (or expanded) vector of floating point values. +Type of vector elements is controlled by templating. +(Some working quantities such as accumulated sums +are explicitly declared of type double). This allows the +components of the vector integer, single or double precision. + +Here is a sample usage: +@verbatim + const int ne = 4; + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its value + CoinDenseVector r(ne,el); + + // access each element + assert( r.getElements()[0]==10. ); + assert( r.getElements()[1]==40. ); + assert( r.getElements()[2]== 1. ); + assert( r.getElements()[3]==50. ); + + // Test for equality + CoinDenseVector r1; + r1=r; + + // Add dense vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinDenseVector add = r + r1; + assert( add[0] == 10.+10. ); + assert( add[1] == 40.+40. ); + assert( add[2] == 1.+ 1. ); + assert( add[3] == 50.+50. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +template class CoinDenseVector { +private: + /**@name Private member data */ + //@{ + /// Size of element vector + int nElements_; + ///Vector elements + T * elements_; + //@} + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getNumElements() const { return nElements_; } + inline int size() const { return nElements_; } + /// Get element values + inline const T * getElements() const { return elements_; } + /// Get element values + inline T * getElements() { return elements_; } + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Reset the vector (i.e. set all elemenets to zero) + void clear(); + /** Assignment operator */ + CoinDenseVector & operator=(const CoinDenseVector &); + /** Member of array operator */ + T & operator[](int index) const; + + /** Set vector size, and elements. + Size is the length of the elements vector. + The element vector is copied into this class instance's + member data. */ + void setVector(int size, const T * elems); + + + /** Elements set to have the same scalar value */ + void setConstant(int size, T elems); + + + /** Set an existing element in the dense vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, T element); + /** Resize the dense vector to be the first newSize elements. + If length is decreased, vector is truncated. If increased + new entries, set to new default element */ + void resize(int newSize, T fill=T()); + + /** Append a dense vector to this dense vector */ + void append(const CoinDenseVector &); + //@} + + /**@name norms, sum and scale */ + //@{ + /// 1-norm of vector + inline T oneNorm() const { + T norm = 0; + for (int i=0; ivalue
to every entry + void operator+=(T value); + /// subtract value from every entry + void operator-=(T value); + /// multiply every entry by value + void operator*=(T value); + /// divide every entry by value + void operator/=(T value); + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinDenseVector(); + /** Alternate Constructors - set elements to vector of Ts */ + CoinDenseVector(int size, const T * elems); + /** Alternate Constructors - set elements to same scalar value */ + CoinDenseVector(int size, T element=T()); + /** Copy constructors */ + CoinDenseVector(const CoinDenseVector &); + + /** Destructor */ + ~CoinDenseVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfSetVector(int size, const T * elems); + /// Set all elements to a given value + void gutsOfSetConstant(int size, T value); + //@} +}; + +//############################################################################# + +/**@name Arithmetic operators on dense vectors. + + NOTE: Because these methods return an object (they can't + return a reference, though they could return a pointer...) they are + very inefficient... + */ +//@{ +/// Return the sum of two dense vectors +template inline +CoinDenseVector operator+(const CoinDenseVector& op1, + const CoinDenseVector& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i inline +CoinDenseVector operator-(const CoinDenseVector& op1, + const CoinDenseVector& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i inline +CoinDenseVector operator*(const CoinDenseVector& op1, + const CoinDenseVector& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i inline +CoinDenseVector operator/(const CoinDenseVector& op1, + const CoinDenseVector& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; iop1
and the specified operation is + done entry-wise with the given value. */ +//@{ +/// Return the sum of a dense vector and a constant +template inline +CoinDenseVector operator+(const CoinDenseVector& op1, T value){ + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i inline +CoinDenseVector operator-(const CoinDenseVector& op1, T value){ + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i inline +CoinDenseVector operator*(const CoinDenseVector& op1, T value){ + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i inline +CoinDenseVector operator/(const CoinDenseVector& op1, T value){ + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i inline +CoinDenseVector operator+(T value, const CoinDenseVector& op1){ + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i inline +CoinDenseVector operator-(T value, const CoinDenseVector& op1){ + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i inline +CoinDenseVector operator*(T value, const CoinDenseVector& op1){ + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i inline +CoinDenseVector operator/(T value, const CoinDenseVector& op1){ + int size = op1.size(); + CoinDenseVector op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i + +//------------------------------------------------------------------- +// +// Attempt to provide an std::distance function +// that will work on multiple platforms +// +//------------------------------------------------------------------- + +/** CoinDistance + +This is the Coin implementation of the std::function that is +designed to work on multiple platforms. +*/ +template +void coinDistance(ForwardIterator first, ForwardIterator last, + Distance& n) +{ +#if defined(__SUNPRO_CC) + n = 0; + std::distance(first,last,n); +#else + n = std::distance(first,last); +#endif +} + +template +size_t coinDistance(ForwardIterator first, ForwardIterator last) +{ + size_t retVal; +#if defined(__SUNPRO_CC) + retVal = 0; + std::distance(first,last,retVal); +#else + retVal = std::distance(first,last); +#endif + return retVal; +} + +#endif diff --git a/thirdparty/linux/include/coin/CoinError.hpp b/thirdparty/linux/include/coin/CoinError.hpp new file mode 100644 index 0000000..704cfea --- /dev/null +++ b/thirdparty/linux/include/coin/CoinError.hpp @@ -0,0 +1,257 @@ +/* $Id: CoinError.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinError_H +#define CoinError_H + +#include +#include +#include +#include + +#include "CoinUtilsConfig.h" +#include "CoinPragma.hpp" + +/** A function to block the popup windows that windows creates when the code + crashes */ +void WindowsErrorPopupBlocker(); + +//------------------------------------------------------------------- +// +// Error class used to throw exceptions +// +// Errors contain: +// +//------------------------------------------------------------------- + +/** Error Class thrown by an exception + +This class is used when exceptions are thrown. +It contains: +
    +
  • message text +
  • name of method throwing exception +
  • name of class throwing exception or hint +
  • name of file if assert +
  • line number +
+ For asserts class=> optional hint +*/ +class CoinError { + friend void CoinErrorUnitTest(); + +private: + CoinError() + : + message_(), + method_(), + class_(), + file_(), + lineNumber_() + { + // nothing to do here + } + +public: + + //------------------------------------------------------------------- + // Get methods + //------------------------------------------------------------------- + /**@name Get error attributes */ + //@{ + /// get message text + inline const std::string & message() const + { return message_; } + /// get name of method instantiating error + inline const std::string & methodName() const + { return method_; } + /// get name of class instantiating error (or hint for assert) + inline const std::string & className() const + { return class_; } + /// get name of file for assert + inline const std::string & fileName() const + { return file_; } + /// get line number of assert (-1 if not assert) + inline int lineNumber() const + { return lineNumber_; } + /// Just print (for asserts) + inline void print(bool doPrint = true) const + { + if (! doPrint) + return; + if (lineNumber_<0) { + std::cout< +#include +#include +#include +#include +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" + +class CoinPackedMatrix; +/** This deals with Factorization and Updates + + This class started with a parallel simplex code I was writing in the + mid 90's. The need for parallelism led to many complications and + I have simplified as much as I could to get back to this. + + I was aiming at problems where I might get speed-up so I was looking at dense + problems or ones with structure. This led to permuting input and output + vectors and to increasing the number of rows each rank-one update. This is + still in as a minor overhead. + + I have also put in handling for hyper-sparsity. I have taken out + all outer loop unrolling, dense matrix handling and most of the + book-keeping for slacks. Also I always use FTRAN approach to updating + even if factorization fairly dense. All these could improve performance. + + I blame some of the coding peculiarities on the history of the code + but mostly it is just because I can't do elegant code (or useful + comments). + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + + +class CoinFactorization { + friend void CoinFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinFactorization ( ); + /// Copy constructor + CoinFactorization ( const CoinFactorization &other); + + /// Destructor + ~CoinFactorization ( ); + /// Delete all stuff (leaves as after CoinFactorization()) + void almostDestructor(); + /// Debug show object (shows one representation) + void show_self ( ) const; + /// Debug - save on file - 0 if no error + int saveFactorization (const char * file ) const; + /** Debug - restore from file - 0 if no error on file. + If factor true then factorizes as if called from ClpFactorization + */ + int restoreFactorization (const char * file , bool factor=false) ; + /// Debug - sort so can compare + void sort ( ) const; + /// = copy + CoinFactorization & operator = ( const CoinFactorization & other ); + //@} + + /**@name Do factorization */ + //@{ + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize ( const CoinPackedMatrix & matrix, + int rowIsBasic[], int columnIsBasic[] , + double areaFactor = 0.0 ); + /** When given as triplets. + Actually does factorization. maximumL is guessed maximum size of L part of + final factorization, maximumU of U part. These are multiplied by + areaFactor which can be computed by user or internally. + Arrays are copied in. I could add flag to delete arrays to save a + bit of memory. + If status okay, permutation has pivot rows - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -99 memory */ + int factorize ( int numberRows, + int numberColumns, + CoinBigIndex numberElements, + CoinBigIndex maximumL, + CoinBigIndex maximumU, + const int indicesRow[], + const int indicesColumn[], const double elements[] , + int permutation[], + double areaFactor = 0.0); + /** Two part version for maximum flexibility + This part creates arrays for user to fill. + estimateNumberElements is safe estimate of number + returns 0 -okay, -99 memory */ + int factorizePart1 ( int numberRows, + int numberColumns, + CoinBigIndex estimateNumberElements, + int * indicesRow[], + int * indicesColumn[], + CoinFactorizationDouble * elements[], + double areaFactor = 0.0); + /** This is part two of factorization + Arrays belong to factorization and were returned by part 1 + If status okay, permutation has pivot rows - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -99 memory */ + int factorizePart2 (int permutation[],int exactNumberElements); + /// Condition number - product of pivots after factorization + double conditionNumber() const; + + //@} + + /**@name general stuff such as permutation or status */ + //@{ + /// Returns status + inline int status ( ) const { + return status_; + } + /// Sets status + inline void setStatus ( int value) + { status_=value; } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + return numberPivots_; + } + /// Sets number of pivots since factorization + inline void setPivots ( int value ) + { numberPivots_=value; } + /// Returns address of permute region + inline int *permute ( ) const { + return permute_.array(); + } + /// Returns address of pivotColumn region (also used for permuting) + inline int *pivotColumn ( ) const { + return pivotColumn_.array(); + } + /// Returns address of pivot region + inline CoinFactorizationDouble *pivotRegion ( ) const { + return pivotRegion_.array(); + } + /// Returns address of permuteBack region + inline int *permuteBack ( ) const { + return permuteBack_.array(); + } + /// Returns address of lastRow region + inline int *lastRow ( ) const { + return lastRow_.array(); + } + /** Returns address of pivotColumnBack region (also used for permuting) + Now uses firstCount to save memory allocation */ + inline int *pivotColumnBack ( ) const { + //return firstCount_.array(); + return pivotColumnBack_.array(); + } + /// Start of each row in L + inline CoinBigIndex * startRowL() const + { return startRowL_.array();} + + /// Start of each column in L + inline CoinBigIndex * startColumnL() const + { return startColumnL_.array();} + + /// Index of column in row for L + inline int * indexColumnL() const + { return indexColumnL_.array();} + + /// Row indices of L + inline int * indexRowL() const + { return indexRowL_.array();} + + /// Elements in L (row copy) + inline CoinFactorizationDouble * elementByRowL() const + { return elementByRowL_.array();} + + /// Number of Rows after iterating + inline int numberRowsExtra ( ) const { + return numberRowsExtra_; + } + /// Set number of Rows after factorization + inline void setNumberRows(int value) + { numberRows_ = value; } + /// Number of Rows after factorization + inline int numberRows ( ) const { + return numberRows_; + } + /// Number in L + inline CoinBigIndex numberL() const + { return numberL_;} + + /// Base of L + inline CoinBigIndex baseL() const + { return baseL_;} + /// Maximum of Rows after iterating + inline int maximumRowsExtra ( ) const { + return maximumRowsExtra_; + } + /// Total number of columns in factorization + inline int numberColumns ( ) const { + return numberColumns_; + } + /// Total number of elements in factorization + inline int numberElements ( ) const { + return totalElements_; + } + /// Length of FT vector + inline int numberForrestTomlin ( ) const { + return numberInColumn_.array()[numberColumnsExtra_]; + } + /// Number of good columns in factorization + inline int numberGoodColumns ( ) const { + return numberGoodU_; + } + /// Whether larger areas needed + inline double areaFactor ( ) const { + return areaFactor_; + } + inline void areaFactor ( double value ) { + areaFactor_=value; + } + /// Returns areaFactor but adjusted for dense + double adjustedAreaFactor() const; + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) + { relaxCheck_ = value;} + inline double getAccuracyCheck() const + { return relaxCheck_;} + /// Level of detail of messages + inline int messageLevel ( ) const { + return messageLevel_ ; + } + void messageLevel ( int value ); + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + return maximumPivots_ ; + } + void maximumPivots ( int value ); + + /// Gets dense threshold + inline int denseThreshold() const + { return denseThreshold_;} + /// Sets dense threshold + inline void setDenseThreshold(int value) + { denseThreshold_ = value;} + /// Pivot tolerance + inline double pivotTolerance ( ) const { + return pivotTolerance_ ; + } + void pivotTolerance ( double value ); + /// Zero tolerance + inline double zeroTolerance ( ) const { + return zeroTolerance_ ; + } + void zeroTolerance ( double value ); +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + inline double slackValue ( ) const { + return slackValue_ ; + } + void slackValue ( double value ); +#endif + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + /// true if Forrest Tomlin update, false if PFI + inline bool forrestTomlin() const + { return doForrestTomlin_;} + inline void setForrestTomlin(bool value) + { doForrestTomlin_=value;} + /// True if FT update and space + inline bool spaceForForrestTomlin() const + { + CoinBigIndex start = startColumnU_.array()[maximumColumnsExtra_]; + CoinBigIndex space = lengthAreaU_ - ( start + numberRowsExtra_ ); + return (space>=0)&&doForrestTomlin_; + } + //@} + + /**@name some simple stuff */ + //@{ + + /// Returns number of dense rows + inline int numberDense() const + { return numberDense_;} + + /// Returns number in U area + inline CoinBigIndex numberElementsU ( ) const { + return lengthU_; + } + /// Setss number in U area + inline void setNumberElementsU(CoinBigIndex value) + { lengthU_ = value; } + /// Returns length of U area + inline CoinBigIndex lengthAreaU ( ) const { + return lengthAreaU_; + } + /// Returns number in L area + inline CoinBigIndex numberElementsL ( ) const { + return lengthL_; + } + /// Returns length of L area + inline CoinBigIndex lengthAreaL ( ) const { + return lengthAreaL_; + } + /// Returns number in R area + inline CoinBigIndex numberElementsR ( ) const { + return lengthR_; + } + /// Number of compressions done + inline CoinBigIndex numberCompressions() const + { return numberCompressions_;} + /// Number of entries in each row + inline int * numberInRow() const + { return numberInRow_.array();} + /// Number of entries in each column + inline int * numberInColumn() const + { return numberInColumn_.array();} + /// Elements of U + inline CoinFactorizationDouble * elementU() const + { return elementU_.array();} + /// Row indices of U + inline int * indexRowU() const + { return indexRowU_.array();} + /// Start of each column in U + inline CoinBigIndex * startColumnU() const + { return startColumnU_.array();} + /// Maximum number of Columns after iterating + inline int maximumColumnsExtra() + { return maximumColumnsExtra_;} + /** L to U bias + 0 - U bias, 1 - some U bias, 2 some L bias, 3 L bias + */ + inline int biasLU() const + { return biasLU_;} + inline void setBiasLU(int value) + { biasLU_=value;} + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + inline int persistenceFlag() const + { return persistenceFlag_;} + void setPersistenceFlag(int value); + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + /** Combines BtranU and delete elements + If deleted is NULL then delete elements + otherwise store where elements are + */ + void replaceColumnU ( CoinIndexedVector * regionSparse, + CoinBigIndex * deleted, + int internalPivotRow); +#ifdef ABC_USE_COIN_FACTORIZATION + /** returns empty fake vector carved out of existing + later - maybe use associated arrays */ + CoinIndexedVector * fakeVector(CoinIndexedVector * vector, + int already=0) const; + void deleteFakeVector(CoinIndexedVector * vector, + CoinIndexedVector * fakeVector) const; + /** Checks if can replace one Column to basis, + returns update alpha + Fills in region for use later + partial update already in U */ + double checkReplacePart1 ( CoinIndexedVector * regionSparse, + int pivotRow); + /** Checks if can replace one Column to basis, + returns update alpha + Fills in region for use later + partial update in vector */ + double checkReplacePart1 ( CoinIndexedVector * regionSparse, + CoinIndexedVector * partialUpdate, + int pivotRow); + /** Checks if can replace one Column in basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room, 5 max pivots */ + int checkReplacePart2 ( int pivotRow, + double btranAlpha, + double ftranAlpha, + double ftAlpha, + double acceptablePivot = 1.0e-8); + /** Replaces one Column to basis, + partial update already in U */ + void replaceColumnPart3 ( CoinIndexedVector * regionSparse, + int pivotRow, + double alpha ); + /** Replaces one Column to basis, + partial update in vector */ + void replaceColumnPart3 ( CoinIndexedVector * regionSparse, + CoinIndexedVector * partialUpdate, + int pivotRow, + double alpha ); + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + long regions + */ + int updateColumnFT ( CoinIndexedVector & regionSparse); + int updateColumnFTPart1 ( CoinIndexedVector & regionSparse) ; + void updateColumnFTPart2 ( CoinIndexedVector & regionSparse) ; + /** Updates one column (FTRAN) - long region + Tries to do FT update + puts partial update in vector */ + void updateColumnFT ( CoinIndexedVector & regionSparseFT, + CoinIndexedVector & partialUpdate, + int which); + /** Updates one column (FTRAN) long region */ + int updateColumn ( CoinIndexedVector & regionSparse) const; + /** Updates one column (FTRAN) from regionFT + Tries to do FT update + number returned is negative if no room. + Also updates regionOther - long region*/ + int updateTwoColumnsFT ( CoinIndexedVector & regionSparseFT, + CoinIndexedVector & regionSparseOther); + /** Updates one column (BTRAN) - long region*/ + int updateColumnTranspose ( CoinIndexedVector & regionSparse) const; + /** Updates one column (FTRAN) - long region */ + void updateColumnCpu ( CoinIndexedVector & regionSparse,int whichCpu) const; + /** Updates one column (BTRAN) - long region */ + void updateColumnTransposeCpu ( CoinIndexedVector & regionSparse,int whichCpu) const; + /** Updates one full column (FTRAN) - long region */ + void updateFullColumn ( CoinIndexedVector & regionSparse) const; + /** Updates one full column (BTRAN) - long region */ + void updateFullColumnTranspose ( CoinIndexedVector & regionSparse) const; + /** Updates one column for dual steepest edge weights (FTRAN) - long region */ + void updateWeights ( CoinIndexedVector & regionSparse) const; + /// Returns true if wants tableauColumn in replaceColumn + inline bool wantsTableauColumn() const + {return false;} + /// Pivot tolerance + inline double minimumPivotTolerance ( ) const { + return pivotTolerance_ ; + } + inline void minimumPivotTolerance ( double value ) + { pivotTolerance(value);} + /// Says parallel + inline void setParallelMode(int value) + { parallelMode_=value;} + /// Sets solve mode + inline void setSolveMode(int value) + { parallelMode_ &= 3;parallelMode_ |= (value<<2);} + /// Sets solve mode + inline int solveMode() const + { return parallelMode_ >> 2;} + /// Update partial Ftran by R update + void updatePartialUpdate(CoinIndexedVector & partialUpdate); + /// Makes a non-singular basis by replacing variables + void makeNonSingular(int * COIN_RESTRICT sequence); +#endif + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2); + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room. + Also updates region3 + region1 starts as zero and is zero at end */ + int updateTwoColumnsFT ( CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermuteRegion3=false) ; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + /** makes a row copy of L for speed and to allow very sparse problems */ + void goSparse(); + /** get sparse threshold */ + inline int sparseThreshold ( ) const + { return sparseThreshold_;} + /** set sparse threshold */ + void sparseThreshold ( int value ); + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization (return code number elements) + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + //@} + + /**@name various updates - none of which have been written! */ + //@{ + + /** Adds given elements to Basis and updates factorization, + can increase size of basis. Returns rank */ + int add ( CoinBigIndex numberElements, + int indicesRow[], + int indicesColumn[], double elements[] ); + + /** Adds one Column to basis, + can increase size of basis. Returns rank */ + int addColumn ( CoinBigIndex numberElements, + int indicesRow[], double elements[] ); + + /** Adds one Row to basis, + can increase size of basis. Returns rank */ + int addRow ( CoinBigIndex numberElements, + int indicesColumn[], double elements[] ); + + /// Deletes one Column from basis, returns rank + int deleteColumn ( int Row ); + /// Deletes one Row from basis, returns rank + int deleteRow ( int Row ); + + /** Replaces one Row in basis, + At present assumes just a singleton on row is in basis + returns 0=OK, 1=Probably OK, 2=singular, 3 no space */ + int replaceRow ( int whichRow, int numberElements, + const int indicesColumn[], const double elements[] ); + /// Takes out all entries for given rows + void emptyRows(int numberToEmpty, const int which[]); + //@} + /**@name used by ClpFactorization */ + /// See if worth going sparse + void checkSparse(); + /// For statistics +#if 0 //def CLP_FACTORIZATION_INSTRUMENT + inline bool collectStatistics() const + { return collectStatistics_;} + /// For statistics + inline void setCollectStatistics(bool onOff) const + { collectStatistics_ = onOff;} +#else + inline bool collectStatistics() const + { return true;} + /// For statistics + inline void setCollectStatistics(bool onOff) const + { } +#endif + /// The real work of constructors etc 0 just scalars, 1 bit normal + void gutsOfDestructor(int type=1); + /// 1 bit - tolerances etc, 2 more, 4 dummy arrays + void gutsOfInitialize(int type); + void gutsOfCopy(const CoinFactorization &other); + + /// Reset all sparsity etc statistics + void resetStatistics(); + + + //@} + + /**@name used by factorization */ + /// Gets space for a factorization, called by constructors + void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /** PreProcesses raw triplet data. + state is 0 - triplets, 1 - some counts etc , 2 - .. */ + void preProcess ( int state, + int possibleDuplicates = -1 ); + /// Does most of factorization + int factor ( ); +protected: + /** Does sparse phase of factorization + return code is <0 error, 0= finished */ + int factorSparse ( ); + /** Does sparse phase of factorization (for smaller problems) + return code is <0 error, 0= finished */ + int factorSparseSmall ( ); + /** Does sparse phase of factorization (for larger problems) + return code is <0 error, 0= finished */ + int factorSparseLarge ( ); + /** Does dense phase of factorization + return code is <0 error, 0= finished */ + int factorDense ( ); + + /// Pivots when just one other row so faster? + bool pivotOneOtherRow ( int pivotRow, + int pivotColumn ); + /// Does one pivot on Row Singleton in factorization + bool pivotRowSingleton ( int pivotRow, + int pivotColumn ); + /// Does one pivot on Column Singleton in factorization + bool pivotColumnSingleton ( int pivotRow, + int pivotColumn ); + + /** Gets space for one Column with given length, + may have to do compression (returns True if successful), + also moves existing vector, + extraNeeded is over and above present */ + bool getColumnSpace ( int iColumn, + int extraNeeded ); + + /** Reorders U so contiguous and in order (if there is space) + Returns true if it could */ + bool reorderU(); + /** getColumnSpaceIterateR. Gets space for one extra R element in Column + may have to do compression (returns true) + also moves existing vector */ + bool getColumnSpaceIterateR ( int iColumn, double value, + int iRow); + /** getColumnSpaceIterate. Gets space for one extra U element in Column + may have to do compression (returns true) + also moves existing vector. + Returns -1 if no memory or where element was put + Used by replaceRow (turns off R version) */ + CoinBigIndex getColumnSpaceIterate ( int iColumn, double value, + int iRow); + /** Gets space for one Row with given length, + may have to do compression (returns True if successful), + also moves existing vector */ + bool getRowSpace ( int iRow, int extraNeeded ); + + /** Gets space for one Row with given length while iterating, + may have to do compression (returns True if successful), + also moves existing vector */ + bool getRowSpaceIterate ( int iRow, + int extraNeeded ); + /// Checks that row and column copies look OK + void checkConsistency ( ); + /// Adds a link in chain of equal counts + inline void addLink ( int index, int count ) { + int *nextCount = nextCount_.array(); + int *firstCount = firstCount_.array(); + int *lastCount = lastCount_.array(); + int next = firstCount[count]; + lastCount[index] = -2 - count; + if ( next < 0 ) { + //first with that count + firstCount[count] = index; + nextCount[index] = -1; + } else { + firstCount[count] = index; + nextCount[index] = next; + lastCount[next] = index; + }} + /// Deletes a link in chain of equal counts + inline void deleteLink ( int index ) { + int *nextCount = nextCount_.array(); + int *firstCount = firstCount_.array(); + int *lastCount = lastCount_.array(); + int next = nextCount[index]; + int last = lastCount[index]; + if ( last >= 0 ) { + nextCount[last] = next; + } else { + int count = -last - 2; + + firstCount[count] = next; + } + if ( next >= 0 ) { + lastCount[next] = last; + } + nextCount[index] = -2; + lastCount[index] = -2; + return; + } + /// Separate out links with same row/column count + void separateLinks(int count,bool rowsFirst); + /// Cleans up at end of factorization + void cleanup ( ); + + /// Updates part of column (FTRANL) + void updateColumnL ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when densish + void updateColumnLDensish ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when sparse + void updateColumnLSparse ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when sparsish + void updateColumnLSparsish ( CoinIndexedVector * region, int * indexIn ) const; + + /// Updates part of column (FTRANR) without FT update + void updateColumnR ( CoinIndexedVector * region ) const; + /** Updates part of column (FTRANR) with FT update. + Also stores update after L and R */ + void updateColumnRFT ( CoinIndexedVector * region, int * indexIn ); + + /// Updates part of column (FTRANU) + void updateColumnU ( CoinIndexedVector * region, int * indexIn) const; + + /// Updates part of column (FTRANU) when sparse + void updateColumnUSparse ( CoinIndexedVector * regionSparse, + int * indexIn) const; + /// Updates part of column (FTRANU) when sparsish + void updateColumnUSparsish ( CoinIndexedVector * regionSparse, + int * indexIn) const; + /// Updates part of column (FTRANU) + int updateColumnUDensish ( double * COIN_RESTRICT region, + int * COIN_RESTRICT regionIndex) const; + /// Updates part of 2 columns (FTRANU) real work + void updateTwoColumnsUDensish ( + int & numberNonZero1, + double * COIN_RESTRICT region1, + int * COIN_RESTRICT index1, + int & numberNonZero2, + double * COIN_RESTRICT region2, + int * COIN_RESTRICT index2) const; + /// Updates part of column PFI (FTRAN) (after rest) + void updateColumnPFI ( CoinIndexedVector * regionSparse) const; + /// Permutes back at end of updateColumn + void permuteBack ( CoinIndexedVector * regionSparse, + CoinIndexedVector * outVector) const; + + /// Updates part of column transpose PFI (BTRAN) (before rest) + void updateColumnTransposePFI ( CoinIndexedVector * region) const; + /** Updates part of column transpose (BTRANU), + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeU ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when sparsish, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUSparsish ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when densish, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUDensish ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when sparse, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUSparse ( CoinIndexedVector * region) const; + /** Updates part of column transpose (BTRANU) by column + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUByColumn ( CoinIndexedVector * region, + int smallestIndex) const; + + /// Updates part of column transpose (BTRANR) + void updateColumnTransposeR ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANR) when dense + void updateColumnTransposeRDensish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANR) when sparse + void updateColumnTransposeRSparse ( CoinIndexedVector * region ) const; + + /// Updates part of column transpose (BTRANL) + void updateColumnTransposeL ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when densish by column + void updateColumnTransposeLDensish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when densish by row + void updateColumnTransposeLByRow ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when sparsish by row + void updateColumnTransposeLSparsish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when sparse (by Row) + void updateColumnTransposeLSparse ( CoinIndexedVector * region ) const; +public: + /** Replaces one Column to basis for PFI + returns 0=OK, 1=Probably OK, 2=singular, 3=no room. + In this case region is not empty - it is incoming variable (updated) + */ + int replaceColumnPFI ( CoinIndexedVector * regionSparse, + int pivotRow, double alpha); +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; + /********************************* START LARGE TEMPLATE ********/ +#ifdef INT_IS_8 +#define COINFACTORIZATION_BITS_PER_INT 64 +#define COINFACTORIZATION_SHIFT_PER_INT 6 +#define COINFACTORIZATION_MASK_PER_INT 0x3f +#else +#define COINFACTORIZATION_BITS_PER_INT 32 +#define COINFACTORIZATION_SHIFT_PER_INT 5 +#define COINFACTORIZATION_MASK_PER_INT 0x1f +#endif + template inline bool + pivot ( int pivotRow, + int pivotColumn, + CoinBigIndex pivotRowPosition, + CoinBigIndex pivotColumnPosition, + CoinFactorizationDouble work[], + unsigned int workArea2[], + int increment2, + T markRow[] , + int largeInteger) +{ + int *indexColumnU = indexColumnU_.array(); + CoinBigIndex *startColumnU = startColumnU_.array(); + int *numberInColumn = numberInColumn_.array(); + CoinFactorizationDouble *elementU = elementU_.array(); + int *indexRowU = indexRowU_.array(); + CoinBigIndex *startRowU = startRowU_.array(); + int *numberInRow = numberInRow_.array(); + CoinFactorizationDouble *elementL = elementL_.array(); + int *indexRowL = indexRowL_.array(); + int *saveColumn = saveColumn_.array(); + int *nextRow = nextRow_.array(); + int *lastRow = lastRow_.array() ; + + //store pivot columns (so can easily compress) + int numberInPivotRow = numberInRow[pivotRow] - 1; + CoinBigIndex startColumn = startColumnU[pivotColumn]; + int numberInPivotColumn = numberInColumn[pivotColumn] - 1; + CoinBigIndex endColumn = startColumn + numberInPivotColumn + 1; + int put = 0; + CoinBigIndex startRow = startRowU[pivotRow]; + CoinBigIndex endRow = startRow + numberInPivotRow + 1; + + if ( pivotColumnPosition < 0 ) { + for ( pivotColumnPosition = startRow; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + int iColumn = indexColumnU[pivotColumnPosition]; + if ( iColumn != pivotColumn ) { + saveColumn[put++] = iColumn; + } else { + break; + } + } + } else { + for (CoinBigIndex i = startRow ; i < pivotColumnPosition ; i++ ) { + saveColumn[put++] = indexColumnU[i]; + } + } + assert (pivotColumnPosition lengthAreaL_ ) { + //need more memory + if ((messageLevel_&4)!=0) + printf("more memory needed in middle of invert\n"); + return false; + } + //l+=currentAreaL_->elementByColumn-elementL; + CoinBigIndex lSave = l; + + CoinBigIndex * startColumnL = startColumnL_.array(); + startColumnL[numberGoodL_] = l; //for luck and first time + numberGoodL_++; + startColumnL[numberGoodL_] = l + numberInPivotColumn; + lengthL_ += numberInPivotColumn; + if ( pivotRowPosition < 0 ) { + for ( pivotRowPosition = startColumn; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRowU[pivotRowPosition]; + if ( iRow != pivotRow ) { + indexRowL[l] = iRow; + elementL[l] = elementU[pivotRowPosition]; + markRow[iRow] = static_cast(l - lSave); + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + } else { + break; + } + } + } else { + CoinBigIndex i; + + for ( i = startColumn; i < pivotRowPosition; i++ ) { + int iRow = indexRowU[i]; + + markRow[iRow] = static_cast(l - lSave); + indexRowL[l] = iRow; + elementL[l] = elementU[i]; + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + } + assert (pivotRowPosition(l - lSave); + indexRowL[l] = iRow; + elementL[l] = elementU[pivotRowPosition]; + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + markRow[pivotRow] = static_cast(largeInteger); + //compress pivot column (move pivot to front including saved) + numberInColumn[pivotColumn] = 0; + //use end of L for temporary space + int *indexL = &indexRowL[lSave]; + CoinFactorizationDouble *multipliersL = &elementL[lSave]; + + //adjust + int j; + + for ( j = 0; j < numberInPivotColumn; j++ ) { + multipliersL[j] *= pivotMultiplier; + } + //zero out fill + CoinBigIndex iErase; + for ( iErase = 0; iErase < increment2 * numberInPivotRow; + iErase++ ) { + workArea2[iErase] = 0; + } + CoinBigIndex added = numberInPivotRow * numberInPivotColumn; + unsigned int *temp2 = workArea2; + int * nextColumn = nextColumn_.array(); + + //pack down and move to work + int jColumn; + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + int iColumn = saveColumn[jColumn]; + CoinBigIndex startColumn = startColumnU[iColumn]; + CoinBigIndex endColumn = startColumn + numberInColumn[iColumn]; + int iRow = indexRowU[startColumn]; + CoinFactorizationDouble value = elementU[startColumn]; + double largest; + CoinBigIndex put = startColumn; + CoinBigIndex positionLargest = -1; + CoinFactorizationDouble thisPivotValue = 0.0; + + //compress column and find largest not updated + bool checkLargest; + int mark = markRow[iRow]; + + if ( mark == largeInteger+1 ) { + largest = fabs ( value ); + positionLargest = put; + put++; + checkLargest = false; + } else { + //need to find largest + largest = 0.0; + checkLargest = true; + if ( mark != largeInteger ) { + //will be updated + work[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + CoinBigIndex i; + for ( i = startColumn + 1; i < endColumn; i++ ) { + iRow = indexRowU[i]; + value = elementU[i]; + int mark = markRow[iRow]; + + if ( mark == largeInteger+1 ) { + //keep + indexRowU[put] = iRow; + elementU[put] = value; + if ( checkLargest ) { + double absValue = fabs ( value ); + + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + } + put++; + } else if ( mark != largeInteger ) { + //will be updated + work[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + //slot in pivot + elementU[put] = elementU[startColumn]; + indexRowU[put] = indexRowU[startColumn]; + if ( positionLargest == startColumn ) { + positionLargest = put; //follow if was largest + } + put++; + elementU[startColumn] = thisPivotValue; + indexRowU[startColumn] = pivotRow; + //clean up counts + startColumn++; + numberInColumn[iColumn] = put - startColumn; + int * numberInColumnPlus = numberInColumnPlus_.array(); + numberInColumnPlus[iColumn]++; + startColumnU[iColumn]++; + //how much space have we got + int next = nextColumn[iColumn]; + CoinBigIndex space; + + space = startColumnU[next] - put - numberInColumnPlus[next]; + //assume no zero elements + if ( numberInPivotColumn > space ) { + //getColumnSpace also moves fixed part + if ( !getColumnSpace ( iColumn, numberInPivotColumn ) ) { + return false; + } + //redo starts + if (positionLargest >= 0) + positionLargest = positionLargest + startColumnU[iColumn] - startColumn; + startColumn = startColumnU[iColumn]; + put = startColumn + numberInColumn[iColumn]; + } + double tolerance = zeroTolerance_; + + int *nextCount = nextCount_.array(); + for ( j = 0; j < numberInPivotColumn; j++ ) { + value = work[j] - thisPivotValue * multipliersL[j]; + double absValue = fabs ( value ); + + if ( absValue > tolerance ) { + work[j] = 0.0; + assert (put largest ) { + largest = absValue; + positionLargest = put; + } + put++; + } else { + work[j] = 0.0; + added--; + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + if ( temp2[word] & ( 1 << bit ) ) { + //take out of row list + iRow = indexL[j]; + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != iColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + } else { + //make sure won't be added + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + } + } + } + numberInColumn[iColumn] = put - startColumn; + //move largest + if ( positionLargest >= 0 ) { + value = elementU[positionLargest]; + iRow = indexRowU[positionLargest]; + elementU[positionLargest] = elementU[startColumn]; + indexRowU[positionLargest] = indexRowU[startColumn]; + elementU[startColumn] = value; + indexRowU[startColumn] = iRow; + } + //linked list for column + if ( nextCount[iColumn + numberRows_] != -2 ) { + //modify linked list + deleteLink ( iColumn + numberRows_ ); + addLink ( iColumn + numberRows_, numberInColumn[iColumn] ); + } + temp2 += increment2; + } + //get space for row list + unsigned int *putBase = workArea2; + int bigLoops = numberInPivotColumn >> COINFACTORIZATION_SHIFT_PER_INT; + int i = 0; + + // do linked lists and update counts + while ( bigLoops ) { + bigLoops--; + int bit; + for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRowU[next] - startRowU[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + return false; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRowU[iRow] + number; + int saveIndex = indexColumnU[startRowU[next]]; + + //add in + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + indexColumnU[end] = saveColumn[jColumn]; + end += test; + } + //put back next one in case zapped + indexColumnU[startRowU[next]] = saveIndex; + markRow[iRow] = static_cast(largeInteger+1); + number = end - startRowU[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + putBase++; + } /* endwhile */ + int bit; + + for ( bit = 0; i < numberInPivotColumn; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRowU[next] - startRowU[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + return false; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRowU[iRow] + number; + int saveIndex; + + saveIndex = indexColumnU[startRowU[next]]; + + //add in + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + + indexColumnU[end] = saveColumn[jColumn]; + end += test; + } + indexColumnU[startRowU[next]] = saveIndex; + markRow[iRow] = static_cast(largeInteger+1); + number = end - startRowU[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + markRow[pivotRow] = static_cast(largeInteger+1); + //modify linked list for pivots + deleteLink ( pivotRow ); + deleteLink ( pivotColumn + numberRows_ ); + totalElements_ += added; + return true; +} + + /********************************* END LARGE TEMPLATE ********/ + //@} +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Pivot tolerance + double pivotTolerance_; + /// Zero tolerance + double zeroTolerance_; +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + double slackValue_; +#else +#ifndef slackValue_ +#define slackValue_ -1.0 +#endif +#endif + /// How much to multiply areas by + double areaFactor_; + /// Relax check on accuracy in replaceColumn + double relaxCheck_; + /// Number of Rows in factorization + int numberRows_; + /// Number of Rows after iterating + int numberRowsExtra_; + /// Maximum number of Rows after iterating + int maximumRowsExtra_; + /// Number of Columns in factorization + int numberColumns_; + /// Number of Columns after iterating + int numberColumnsExtra_; + /// Maximum number of Columns after iterating + int maximumColumnsExtra_; + /// Number factorized in U (not row singletons) + int numberGoodU_; + /// Number factorized in L + int numberGoodL_; + /// Maximum number of pivots before factorization + int maximumPivots_; + /// Number pivots since last factorization + int numberPivots_; + /// Number of elements in U (to go) + /// or while iterating total overall + CoinBigIndex totalElements_; + /// Number of elements after factorization + CoinBigIndex factorElements_; + /// Pivot order for each Column + CoinIntArrayWithLength pivotColumn_; + /// Permutation vector for pivot row order + CoinIntArrayWithLength permute_; + /// DePermutation vector for pivot row order + CoinIntArrayWithLength permuteBack_; + /// Inverse Pivot order for each Column + CoinIntArrayWithLength pivotColumnBack_; + /// Status of factorization + int status_; + + /** 0 - no increasing rows - no permutations, + 1 - no increasing rows but permutations + 2 - increasing rows + - taken out as always 2 */ + //int increasingRows_; + + /// Number of trials before rejection + int numberTrials_; + /// Start of each Row as pointer + CoinBigIndexArrayWithLength startRowU_; + + /// Number in each Row + CoinIntArrayWithLength numberInRow_; + + /// Number in each Column + CoinIntArrayWithLength numberInColumn_; + + /// Number in each Column including pivoted + CoinIntArrayWithLength numberInColumnPlus_; + + /** First Row/Column with count of k, + can tell which by offset - Rows then Columns */ + CoinIntArrayWithLength firstCount_; + + /// Next Row/Column with count + CoinIntArrayWithLength nextCount_; + + /// Previous Row/Column with count + CoinIntArrayWithLength lastCount_; + + /// Next Column in memory order + CoinIntArrayWithLength nextColumn_; + + /// Previous Column in memory order + CoinIntArrayWithLength lastColumn_; + + /// Next Row in memory order + CoinIntArrayWithLength nextRow_; + + /// Previous Row in memory order + CoinIntArrayWithLength lastRow_; + + /// Columns left to do in a single pivot + CoinIntArrayWithLength saveColumn_; + + /// Marks rows to be updated + CoinIntArrayWithLength markRow_; + + /// Detail in messages + int messageLevel_; + + /// Larger of row and column size + int biggerDimension_; + + /// Base address for U (may change) + CoinIntArrayWithLength indexColumnU_; + + /// Pivots for L + CoinIntArrayWithLength pivotRowL_; + + /// Inverses of pivot values + CoinFactorizationDoubleArrayWithLength pivotRegion_; + + /// Number of slacks at beginning of U + int numberSlacks_; + + /// Number in U + int numberU_; + + /// Maximum space used in U + CoinBigIndex maximumU_; + + /// Base of U is always 0 + //int baseU_; + + /// Length of U + CoinBigIndex lengthU_; + + /// Length of area reserved for U + CoinBigIndex lengthAreaU_; + +/// Elements of U + CoinFactorizationDoubleArrayWithLength elementU_; + +/// Row indices of U + CoinIntArrayWithLength indexRowU_; + +/// Start of each column in U + CoinBigIndexArrayWithLength startColumnU_; + +/// Converts rows to columns in U + CoinBigIndexArrayWithLength convertRowToColumnU_; + + /// Number in L + CoinBigIndex numberL_; + +/// Base of L + CoinBigIndex baseL_; + + /// Length of L + CoinBigIndex lengthL_; + + /// Length of area reserved for L + CoinBigIndex lengthAreaL_; + + /// Elements of L + CoinFactorizationDoubleArrayWithLength elementL_; + + /// Row indices of L + CoinIntArrayWithLength indexRowL_; + + /// Start of each column in L + CoinBigIndexArrayWithLength startColumnL_; + + /// true if Forrest Tomlin update, false if PFI + bool doForrestTomlin_; + + /// Number in R + int numberR_; + + /// Length of R stuff + CoinBigIndex lengthR_; + + /// length of area reserved for R + CoinBigIndex lengthAreaR_; + + /// Elements of R + CoinFactorizationDouble *elementR_; + + /// Row indices for R + int *indexRowR_; + + /// Start of columns for R + CoinBigIndexArrayWithLength startColumnR_; + + /// Dense area + double * denseArea_; + + /// Dense area - actually used (for alignment etc) + double * denseAreaAddress_; + + /// Dense permutation + int * densePermute_; + + /// Number of dense rows + int numberDense_; + + /// Dense threshold + int denseThreshold_; + + /// First work area + CoinFactorizationDoubleArrayWithLength workArea_; + + /// Second work area + CoinUnsignedIntArrayWithLength workArea2_; + + /// Number of compressions done + CoinBigIndex numberCompressions_; + +public: + /// Below are all to collect + mutable double ftranCountInput_; + mutable double ftranCountAfterL_; + mutable double ftranCountAfterR_; + mutable double ftranCountAfterU_; + mutable double btranCountInput_; + mutable double btranCountAfterU_; + mutable double btranCountAfterR_; + mutable double btranCountAfterL_; + + /// We can roll over factorizations + mutable int numberFtranCounts_; + mutable int numberBtranCounts_; + + /// While these are average ratios collected over last period + double ftranAverageAfterL_; + double ftranAverageAfterR_; + double ftranAverageAfterU_; + double btranAverageAfterU_; + double btranAverageAfterR_; + double btranAverageAfterL_; +protected: + + /// For statistics +#if 0 + mutable bool collectStatistics_; +#else +#define collectStatistics_ 1 +#endif + + /// Below this use sparse technology - if 0 then no L row copy + int sparseThreshold_; + + /// And one for "sparsish" + int sparseThreshold2_; + + /// Start of each row in L + CoinBigIndexArrayWithLength startRowL_; + + /// Index of column in row for L + CoinIntArrayWithLength indexColumnL_; + + /// Elements in L (row copy) + CoinFactorizationDoubleArrayWithLength elementByRowL_; + + /// Sparse regions + mutable CoinIntArrayWithLength sparse_; + /** L to U bias + 0 - U bias, 1 - some U bias, 2 some L bias, 3 L bias + */ + int biasLU_; + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + int persistenceFlag_; +#ifdef ABC_USE_COIN_FACTORIZATION + /// Says if parallel + int parallelMode_; +#endif + //@} +}; +// Dense coding +#ifdef COIN_HAS_LAPACK +#ifndef COIN_FACTORIZATION_DENSE_CODE +#define COIN_FACTORIZATION_DENSE_CODE 1 +#endif +#endif +#ifdef COIN_FACTORIZATION_DENSE_CODE +/* Type of Fortran integer translated into C */ +#ifndef ipfint +//typedef ipfint FORTRAN_INTEGER_TYPE ; +typedef int ipfint; +typedef const int cipfint; +#endif +#endif +#endif +// Extra for ugly include +#ifdef UGLY_COIN_FACTOR_CODING +#define FAC_UNSET (FAC_SET+1) +{ + goodPivot=false; + //store pivot columns (so can easily compress) + CoinBigIndex startColumnThis = startColumn[iPivotColumn]; + CoinBigIndex endColumn = startColumnThis + numberDoColumn + 1; + int put = 0; + CoinBigIndex startRowThis = startRow[iPivotRow]; + CoinBigIndex endRow = startRowThis + numberDoRow + 1; + if ( pivotColumnPosition < 0 ) { + for ( pivotColumnPosition = startRowThis; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + int iColumn = indexColumn[pivotColumnPosition]; + if ( iColumn != iPivotColumn ) { + saveColumn[put++] = iColumn; + } else { + break; + } + } + } else { + for (CoinBigIndex i = startRowThis ; i < pivotColumnPosition ; i++ ) { + saveColumn[put++] = indexColumn[i]; + } + } + assert (pivotColumnPosition lengthAreaL_ ) { + //need more memory + if ((messageLevel_&4)!=0) + printf("more memory needed in middle of invert\n"); + goto BAD_PIVOT; + } + //l+=currentAreaL_->elementByColumn-elementL; + CoinBigIndex lSave = l; + + CoinBigIndex * startColumnL = startColumnL_.array(); + startColumnL[numberGoodL_] = l; //for luck and first time + numberGoodL_++; + startColumnL[numberGoodL_] = l + numberDoColumn; + lengthL_ += numberDoColumn; + if ( pivotRowPosition < 0 ) { + for ( pivotRowPosition = startColumnThis; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRow[pivotRowPosition]; + if ( iRow != iPivotRow ) { + indexRowL[l] = iRow; + elementL[l] = element[pivotRowPosition]; + markRow[iRow] = l - lSave; + l++; + //take out of row list + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iPivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + } else { + break; + } + } + } else { + CoinBigIndex i; + + for ( i = startColumnThis; i < pivotRowPosition; i++ ) { + int iRow = indexRow[i]; + + markRow[iRow] = l - lSave; + indexRowL[l] = iRow; + elementL[l] = element[i]; + l++; + //take out of row list + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iPivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + } + assert (pivotRowPosition= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + markRow[iPivotRow] = FAC_SET; + //compress pivot column (move pivot to front including saved) + numberInColumn[iPivotColumn] = 0; + //use end of L for temporary space + int *indexL = &indexRowL[lSave]; + CoinFactorizationDouble *multipliersL = &elementL[lSave]; + + //adjust + int j; + + for ( j = 0; j < numberDoColumn; j++ ) { + multipliersL[j] *= pivotMultiplier; + } + //zero out fill + CoinBigIndex iErase; + for ( iErase = 0; iErase < increment2 * numberDoRow; + iErase++ ) { + workArea2[iErase] = 0; + } + CoinBigIndex added = numberDoRow * numberDoColumn; + unsigned int *temp2 = workArea2; + int * nextColumn = nextColumn_.array(); + + //pack down and move to work + int jColumn; + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + int iColumn = saveColumn[jColumn]; + CoinBigIndex startColumnThis = startColumn[iColumn]; + CoinBigIndex endColumn = startColumnThis + numberInColumn[iColumn]; + int iRow = indexRow[startColumnThis]; + CoinFactorizationDouble value = element[startColumnThis]; + double largest; + CoinBigIndex put = startColumnThis; + CoinBigIndex positionLargest = -1; + CoinFactorizationDouble thisPivotValue = 0.0; + + //compress column and find largest not updated + bool checkLargest; + int mark = markRow[iRow]; + + if ( mark == FAC_UNSET ) { + largest = fabs ( value ); + positionLargest = put; + put++; + checkLargest = false; + } else { + //need to find largest + largest = 0.0; + checkLargest = true; + if ( mark != FAC_SET ) { + //will be updated + workArea[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + CoinBigIndex i; + for ( i = startColumnThis + 1; i < endColumn; i++ ) { + iRow = indexRow[i]; + value = element[i]; + int mark = markRow[iRow]; + + if ( mark == FAC_UNSET ) { + //keep + indexRow[put] = iRow; + element[put] = value; + if ( checkLargest ) { + double absValue = fabs ( value ); + + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + } + put++; + } else if ( mark != FAC_SET ) { + //will be updated + workArea[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + //slot in pivot + element[put] = element[startColumnThis]; + indexRow[put] = indexRow[startColumnThis]; + if ( positionLargest == startColumnThis ) { + positionLargest = put; //follow if was largest + } + put++; + element[startColumnThis] = thisPivotValue; + indexRow[startColumnThis] = iPivotRow; + //clean up counts + startColumnThis++; + numberInColumn[iColumn] = put - startColumnThis; + int * numberInColumnPlus = numberInColumnPlus_.array(); + numberInColumnPlus[iColumn]++; + startColumn[iColumn]++; + //how much space have we got + int next = nextColumn[iColumn]; + CoinBigIndex space; + + space = startColumn[next] - put - numberInColumnPlus[next]; + //assume no zero elements + if ( numberDoColumn > space ) { + //getColumnSpace also moves fixed part + if ( !getColumnSpace ( iColumn, numberDoColumn ) ) { + goto BAD_PIVOT; + } + //redo starts + positionLargest = positionLargest + startColumn[iColumn] - startColumnThis; + startColumnThis = startColumn[iColumn]; + put = startColumnThis + numberInColumn[iColumn]; + } + double tolerance = zeroTolerance_; + + int *nextCount = nextCount_.array(); + for ( j = 0; j < numberDoColumn; j++ ) { + value = workArea[j] - thisPivotValue * multipliersL[j]; + double absValue = fabs ( value ); + + if ( absValue > tolerance ) { + workArea[j] = 0.0; + element[put] = value; + indexRow[put] = indexL[j]; + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + put++; + } else { + workArea[j] = 0.0; + added--; + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + if ( temp2[word] & ( 1 << bit ) ) { + //take out of row list + iRow = indexL[j]; + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + } else { + //make sure won't be added + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + } + } + } + numberInColumn[iColumn] = put - startColumnThis; + //move largest + if ( positionLargest >= 0 ) { + value = element[positionLargest]; + iRow = indexRow[positionLargest]; + element[positionLargest] = element[startColumnThis]; + indexRow[positionLargest] = indexRow[startColumnThis]; + element[startColumnThis] = value; + indexRow[startColumnThis] = iRow; + } + //linked list for column + if ( nextCount[iColumn + numberRows_] != -2 ) { + //modify linked list + deleteLink ( iColumn + numberRows_ ); + addLink ( iColumn + numberRows_, numberInColumn[iColumn] ); + } + temp2 += increment2; + } + //get space for row list + unsigned int *putBase = workArea2; + int bigLoops = numberDoColumn >> COINFACTORIZATION_SHIFT_PER_INT; + int i = 0; + + // do linked lists and update counts + while ( bigLoops ) { + bigLoops--; + int bit; + for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRow[next] - startRow[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + goto BAD_PIVOT; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRow[iRow] + number; + int saveIndex = indexColumn[startRow[next]]; + + //add in + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + indexColumn[end] = saveColumn[jColumn]; + end += test; + } + //put back next one in case zapped + indexColumn[startRow[next]] = saveIndex; + markRow[iRow] = FAC_UNSET; + number = end - startRow[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + putBase++; + } /* endwhile */ + int bit; + + for ( bit = 0; i < numberDoColumn; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRow[next] - startRow[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + goto BAD_PIVOT; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRow[iRow] + number; + int saveIndex; + + saveIndex = indexColumn[startRow[next]]; + + //add in + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + + indexColumn[end] = saveColumn[jColumn]; + end += test; + } + indexColumn[startRow[next]] = saveIndex; + markRow[iRow] = FAC_UNSET; + number = end - startRow[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + markRow[iPivotRow] = FAC_UNSET; + //modify linked list for pivots + deleteLink ( iPivotRow ); + deleteLink ( iPivotColumn + numberRows_ ); + totalElements_ += added; + goodPivot= true; + // **** UGLY UGLY UGLY + } + BAD_PIVOT: + + ; +} +#undef FAC_UNSET +#endif diff --git a/thirdparty/linux/include/coin/CoinFileIO.hpp b/thirdparty/linux/include/coin/CoinFileIO.hpp new file mode 100644 index 0000000..20be1a9 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinFileIO.hpp @@ -0,0 +1,166 @@ +/* $Id: CoinFileIO.hpp 1439 2011-06-13 16:31:21Z stefan $ */ +// Copyright (C) 2005, COIN-OR. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinFileIO_H +#define CoinFileIO_H + +#include + +/// Base class for FileIO classes. +class CoinFileIOBase +{ +public: + /// Constructor. + /// @param fileName The name of the file used by this object. + CoinFileIOBase (const std::string &fileName); + + /// Destructor. + ~CoinFileIOBase (); + + /// Return the name of the file used by this object. + const char *getFileName () const; + + /// Return the method of reading being used + inline std::string getReadType () const + { return readType_.c_str();} +protected: + std::string readType_; +private: + CoinFileIOBase (); + CoinFileIOBase (const CoinFileIOBase &); + + std::string fileName_; +}; + +/// Abstract base class for file input classes. +class CoinFileInput: public CoinFileIOBase +{ +public: + /// indicates whether CoinFileInput supports gzip'ed files + static bool haveGzipSupport(); + /// indicates whether CoinFileInput supports bzip2'ed files + static bool haveBzip2Support(); + + /// Factory method, that creates a CoinFileInput (more precisely + /// a subclass of it) for the file specified. This method reads the + /// first few bytes of the file and determines if this is a compressed + /// or a plain file and returns the correct subclass to handle it. + /// If the file does not exist or uses a compression not compiled in + /// an exception is thrown. + /// @param fileName The file that should be read. + static CoinFileInput *create (const std::string &fileName); + + /// Constructor (don't use this, use the create method instead). + /// @param fileName The name of the file used by this object. + CoinFileInput (const std::string &fileName); + + /// Destructor. + virtual ~CoinFileInput (); + + /// Read a block of data from the file, similar to fread. + /// @param buffer Address of a buffer to store the data into. + /// @param size Number of bytes to read (buffer should be large enough). + /// @return Number of bytes read. + virtual int read (void *buffer, int size) = 0; + + /// Reads up to (size-1) characters an stores them into the buffer, + /// similar to fgets. + /// Reading ends, when EOF or a newline occurs or (size-1) characters have + /// been read. The resulting string is terminated with '\0'. If reading + /// ends due to an encoutered newline, the '\n' is put into the buffer, + /// before the '\0' is appended. + /// @param buffer The buffer to put the string into. + /// @param size The size of the buffer in characters. + /// @return buffer on success, or 0 if no characters have been read. + virtual char *gets (char *buffer, int size) = 0; +}; + +/// Abstract base class for file output classes. +class CoinFileOutput: public CoinFileIOBase +{ +public: + + /// The compression method. + enum Compression { + COMPRESS_NONE = 0, ///< No compression. + COMPRESS_GZIP = 1, ///< gzip compression. + COMPRESS_BZIP2 = 2 ///< bzip2 compression. + }; + + /// Returns whether the specified compression method is supported + /// (i.e. was compiled into COIN). + static bool compressionSupported (Compression compression); + + /// Factory method, that creates a CoinFileOutput (more precisely + /// a subclass of it) for the file specified. If the compression method + /// is not supported an exception is thrown (so use compressionSupported + /// first, if this is a problem). The reason for not providing direct + /// access to the subclasses (and using such a method instead) is that + /// depending on the build configuration some of the classes are not + /// available (or functional). This way we can handle all required ifdefs + /// here instead of polluting other files. + /// @param fileName The file that should be read. + /// @param compression Compression method used. + static CoinFileOutput *create (const std::string &fileName, + Compression compression); + + /// Constructor (don't use this, use the create method instead). + /// @param fileName The name of the file used by this object. + CoinFileOutput (const std::string &fileName); + + /// Destructor. + virtual ~CoinFileOutput (); + + /// Write a block of data to the file, similar to fwrite. + /// @param buffer Address of a buffer containing the data to be written. + /// @param size Number of bytes to write. + /// @return Number of bytes written. + virtual int write (const void * buffer, int size) = 0; + + /// Write a string to the file (like fputs). + /// Just as with fputs no trailing newline is inserted! + /// The terminating '\0' is not written to the file. + /// The default implementation determines the length of the string + /// and calls write on it. + /// @param s The zero terminated string to be written. + /// @return true on success, false on error. + virtual bool puts (const char *s); + + /// Convenience method: just a 'puts(s.c_str())'. + inline bool puts (const std::string &s) + { + return puts (s.c_str ()); + } +}; + +/*! \relates CoinFileInput + \brief Test if the given string looks like an absolute file path + + The criteria are: + - unix: string begins with `/' + - windows: string begins with `\' or with `drv:' (drive specifier) +*/ +bool fileAbsPath (const std::string &path) ; + +/*! \relates CoinFileInput + \brief Test if the file is readable, using likely versions of the file + name, and return the name that worked. + + The file name is constructed from \p name using the following rules: +
    +
  • An absolute path is not modified. +
  • If the name begins with `~', an attempt is made to replace `~' + with the value of the environment variable HOME. +
  • If a default prefix (\p dfltPrefix) is provided, it is + prepended to the name. +
+ If the constructed file name cannot be opened, and CoinUtils was built + with support for compressed files, fileCoinReadable will try any + standard extensions for supported compressed files. + + The value returned in \p name is the file name that actually worked. +*/ +bool fileCoinReadable(std::string &name, + const std::string &dfltPrefix = std::string("")); +#endif diff --git a/thirdparty/linux/include/coin/CoinFinite.hpp b/thirdparty/linux/include/coin/CoinFinite.hpp new file mode 100644 index 0000000..71b5b65 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinFinite.hpp @@ -0,0 +1,34 @@ +/* $Id: CoinFinite.hpp 1762 2014-12-29 20:37:12Z tkr $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* Defines COIN_DBL_MAX and relatives and provides CoinFinite and CoinIsnan. */ + +#ifndef CoinFinite_H +#define CoinFinite_H + +#include + +//============================================================================= +// Smallest positive double value and Plus infinity (double and int) + +#if 1 +const double COIN_DBL_MIN = (std::numeric_limits::min)(); +const double COIN_DBL_MAX = (std::numeric_limits::max)(); +const int COIN_INT_MAX = (std::numeric_limits::max)(); +const double COIN_INT_MAX_AS_DOUBLE = (std::numeric_limits::max)(); +#else +#define COIN_DBL_MIN (std::numeric_limits::min()) +#define COIN_DBL_MAX (std::numeric_limits::max()) +#define COIN_INT_MAX (std::numeric_limits::max()) +#define COIN_INT_MAX_AS_DOUBLE (std::numeric_limits::max()) +#endif + +/** checks if a double value is finite (not infinity and not NaN) */ +extern bool CoinFinite(double val); + +/** checks if a double value is not a number */ +extern bool CoinIsnan(double val); + +#endif diff --git a/thirdparty/linux/include/coin/CoinFloatEqual.hpp b/thirdparty/linux/include/coin/CoinFloatEqual.hpp new file mode 100644 index 0000000..d5edfff --- /dev/null +++ b/thirdparty/linux/include/coin/CoinFloatEqual.hpp @@ -0,0 +1,177 @@ +/* $Id: CoinFloatEqual.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinFloatEqual_H +#define CoinFloatEqual_H + +#include +#include + +#include "CoinFinite.hpp" + +/*! \file CoinFloatEqual.hpp + \brief Function objects for testing equality of real numbers. + + Two objects are provided; one tests for equality to an absolute tolerance, + one to a scaled tolerance. The tests will handle IEEE floating point, but + note that infinity == infinity. Mathematicians are rolling in their graves, + but this matches the behaviour for the common practice of using + DBL_MAX (numeric_limits::max(), or similar + large finite number) as infinity. + +

+ Example usage: + @verbatim + double d1 = 3.14159 ; + double d2 = d1 ; + double d3 = d1+.0001 ; + + CoinAbsFltEq eq1 ; + CoinAbsFltEq eq2(.001) ; + + assert( eq1(d1,d2) ) ; + assert( !eq1(d1,d3) ) ; + assert( eq2(d1,d3) ) ; + @endverbatim + CoinRelFltEq follows the same pattern. */ + +/*! \brief Equality to an absolute tolerance + + Operands are considered equal if their difference is within an epsilon ; + the test does not consider the relative magnitude of the operands. +*/ + +class CoinAbsFltEq +{ + public: + + //! Compare function + + inline bool operator() (const double f1, const double f2) const + + { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; + if (f1 == f2) return true ; + return (fabs(f1-f2) < epsilon_) ; } + + /*! \name Constructors and destructors */ + //@{ + + /*! \brief Default constructor + + Default tolerance is 1.0e-10. + */ + + CoinAbsFltEq () : epsilon_(1.e-10) {} + + //! Alternate constructor with epsilon as a parameter + + CoinAbsFltEq (const double epsilon) : epsilon_(epsilon) {} + + //! Destructor + + virtual ~CoinAbsFltEq () {} + + //! Copy constructor + + CoinAbsFltEq (const CoinAbsFltEq& src) : epsilon_(src.epsilon_) {} + + //! Assignment + + CoinAbsFltEq& operator= (const CoinAbsFltEq& rhs) + + { if (this != &rhs) epsilon_ = rhs.epsilon_ ; + return (*this) ; } + + //@} + + private: + + /*! \name Private member data */ + //@{ + + //! Equality tolerance. + + double epsilon_ ; + + //@} + +} ; + + + +/*! \brief Equality to a scaled tolerance + + Operands are considered equal if their difference is within a scaled + epsilon calculated as epsilon_*(1+CoinMax(|f1|,|f2|)). +*/ + +class CoinRelFltEq +{ + public: + + //! Compare function + + inline bool operator() (const double f1, const double f2) const + + { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; + if (f1 == f2) return true ; + if (!CoinFinite(f1) || !CoinFinite(f2)) return false ; + + double tol = (fabs(f1)>fabs(f2))?fabs(f1):fabs(f2) ; + + return (fabs(f1-f2) <= epsilon_*(1+tol)) ; } + + /*! \name Constructors and destructors */ + //@{ + +#ifndef COIN_FLOAT + /*! Default constructor + + Default tolerance is 1.0e-10. + */ + CoinRelFltEq () : epsilon_(1.e-10) {} +#else + /*! Default constructor + + Default tolerance is 1.0e-6. + */ + CoinRelFltEq () : epsilon_(1.e-6) {} ; // as float +#endif + + //! Alternate constructor with epsilon as a parameter + + CoinRelFltEq (const double epsilon) : epsilon_(epsilon) {} + + //! Destructor + + virtual ~CoinRelFltEq () {} + + //! Copy constructor + + CoinRelFltEq (const CoinRelFltEq & src) : epsilon_(src.epsilon_) {} + + //! Assignment + + CoinRelFltEq& operator= (const CoinRelFltEq& rhs) + + { if (this != &rhs) epsilon_ = rhs.epsilon_ ; + return (*this) ; } + + //@} + +private: + + /*! \name Private member data */ + //@{ + + //! Base equality tolerance + + double epsilon_ ; + + //@} + +} ; + +#endif diff --git a/thirdparty/linux/include/coin/CoinHelperFunctions.hpp b/thirdparty/linux/include/coin/CoinHelperFunctions.hpp new file mode 100644 index 0000000..3409bbc --- /dev/null +++ b/thirdparty/linux/include/coin/CoinHelperFunctions.hpp @@ -0,0 +1,1111 @@ +/* $Id: CoinHelperFunctions.hpp 1679 2013-12-05 11:27:45Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinHelperFunctions_H +#define CoinHelperFunctions_H + +#include "CoinUtilsConfig.h" + +#if defined(_MSC_VER) +# include +# include +# define getcwd _getcwd +# include +#else +# include +#endif +//#define USE_MEMCPY + +#include +#include +#include +#include "CoinTypes.hpp" +#include "CoinError.hpp" + +// Compilers can produce better code if they know about __restrict +#ifndef COIN_RESTRICT +#ifdef COIN_USE_RESTRICT +#define COIN_RESTRICT __restrict +#else +#define COIN_RESTRICT +#endif +#endif + +//############################################################################# + +/** This helper function copies an array to another location using Duff's + device (for a speedup of ~2). The arrays are given by pointers to their + first entries and by the size of the source array. Overlapping arrays are + handled correctly. */ + +template inline void +CoinCopyN(register const T* from, const int size, register T* to) +{ + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinCopyN", ""); +#endif + + register int n = (size + 7) / 8; + if (to > from) { + register const T* downfrom = from + size; + register T* downto = to + size; + // Use Duff's device to copy + switch (size % 8) { + case 0: do{ *--downto = *--downfrom; + case 7: *--downto = *--downfrom; + case 6: *--downto = *--downfrom; + case 5: *--downto = *--downfrom; + case 4: *--downto = *--downfrom; + case 3: *--downto = *--downfrom; + case 2: *--downto = *--downfrom; + case 1: *--downto = *--downfrom; + }while(--n>0); + } + } else { + // Use Duff's device to copy + --from; + --to; + switch (size % 8) { + case 0: do{ *++to = *++from; + case 7: *++to = *++from; + case 6: *++to = *++from; + case 5: *++to = *++from; + case 4: *++to = *++from; + case 3: *++to = *++from; + case 2: *++to = *++from; + case 1: *++to = *++from; + }while(--n>0); + } + } +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location using Duff's + device (for a speedup of ~2). The source array is given by its first and + "after last" entry; the target array is given by its first entry. + Overlapping arrays are handled correctly. + + All of the various CoinCopyN variants use an int for size. On 64-bit + architectures, the address diff last-first will be a 64-bit quantity. + Given that everything else uses an int, I'm going to choose to kick + the difference down to int. -- lh, 100823 -- +*/ +template inline void +CoinCopy(register const T* first, register const T* last, register T* to) +{ + CoinCopyN(first, static_cast(last-first), to); +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The arrays are given by pointers to their first + entries and by the size of the source array. + + Note JJF - the speed claim seems to be false on IA32 so I have added + CoinMemcpyN which can be used for atomic data */ +template inline void +CoinDisjointCopyN(register const T* from, const int size, register T* to) +{ +#ifndef _MSC_VER + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinDisjointCopyN", ""); +#endif + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinDisjointCopyN", ""); +#endif + + for (register int n = size / 8; n > 0; --n, from += 8, to += 8) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to[4] = from[4]; + to[5] = from[5]; + to[6] = from[6]; + to[7] = from[7]; + } + switch (size % 8) { + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + } +#else + CoinCopyN(from, size, to); +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The source array is given by its first and "after + last" entry; the target array is given by its first entry. */ +template inline void +CoinDisjointCopy(register const T* first, register const T* last, + register T* to) +{ + CoinDisjointCopyN(first, static_cast(last - first), to); +} + +//----------------------------------------------------------------------------- + +/*! \brief Return an array of length \p size filled with input from \p array, + or null if \p array is null. +*/ + +template inline T* +CoinCopyOfArray( const T * array, const int size) +{ + if (array) { + T * arrayNew = new T[size]; + std::memcpy(arrayNew,array,size*sizeof(T)); + return arrayNew; + } else { + return NULL; + } +} + + +/*! \brief Return an array of length \p size filled with first copySize from \p array, + or null if \p array is null. +*/ + +template inline T* +CoinCopyOfArrayPartial( const T * array, const int size,const int copySize) +{ + if (array||size) { + T * arrayNew = new T[size]; + assert (copySize<=size); + std::memcpy(arrayNew,array,copySize*sizeof(T)); + return arrayNew; + } else { + return NULL; + } +} + +/*! \brief Return an array of length \p size filled with input from \p array, + or filled with (scalar) \p value if \p array is null +*/ + +template inline T* +CoinCopyOfArray( const T * array, const int size, T value) +{ + T * arrayNew = new T[size]; + if (array) { + std::memcpy(arrayNew,array,size*sizeof(T)); + } else { + int i; + for (i=0;i inline T* +CoinCopyOfArrayOrZero( const T * array , const int size) +{ + T * arrayNew = new T[size]; + if (array) { + std::memcpy(arrayNew,array,size*sizeof(T)); + } else { + std::memset(arrayNew,0,size*sizeof(T)); + } + return arrayNew; +} + + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The arrays are given by pointers to their first + entries and by the size of the source array. + + Note JJF - the speed claim seems to be false on IA32 so I have added + alternative coding if USE_MEMCPY defined*/ +#ifndef COIN_USE_RESTRICT +template inline void +CoinMemcpyN(register const T* from, const int size, register T* to) +{ +#ifndef _MSC_VER +#ifdef USE_MEMCPY + // Use memcpy - seems a lot faster on Intel with gcc +#ifndef NDEBUG + // Some debug so check + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinMemcpyN", ""); + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinMemcpyN", ""); +#endif +#endif + std::memcpy(to,from,size*sizeof(T)); +#else + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinMemcpyN", ""); +#endif + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinMemcpyN", ""); +#endif + + for (register int n = size / 8; n > 0; --n, from += 8, to += 8) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to[4] = from[4]; + to[5] = from[5]; + to[6] = from[6]; + to[7] = from[7]; + } + switch (size % 8) { + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + } +#endif +#else + CoinCopyN(from, size, to); +#endif +} +#else +template inline void +CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to) +{ +#ifdef USE_MEMCPY + std::memcpy(to,from,size*sizeof(T)); +#else + T * COIN_RESTRICT put = to; + const T * COIN_RESTRICT get = from; + for ( ; 0 inline void +CoinMemcpy(register const T* first, register const T* last, + register T* to) +{ + CoinMemcpyN(first, static_cast(last - first), to); +} + +//############################################################################# + +/** This helper function fills an array with a given value. For speed 8 entries + are filled at a time. The array is given by a pointer to its first entry + and its size. + + Note JJF - the speed claim seems to be false on IA32 so I have added + CoinZero to allow for memset. */ +template inline void +CoinFillN(register T* to, const int size, register const T value) +{ + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinFillN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, to += 8) { + to[0] = value; + to[1] = value; + to[2] = value; + to[3] = value; + to[4] = value; + to[5] = value; + to[6] = value; + to[7] = value; + } + switch (size % 8) { + case 7: to[6] = value; + case 6: to[5] = value; + case 5: to[4] = value; + case 4: to[3] = value; + case 3: to[2] = value; + case 2: to[1] = value; + case 1: to[0] = value; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --to; + switch (size % 8) { + case 0: do{ *++to = value; + case 7: *++to = value; + case 6: *++to = value; + case 5: *++to = value; + case 4: *++to = value; + case 3: *++to = value; + case 2: *++to = value; + case 1: *++to = value; + }while(--n>0); + } +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function fills an array with a given value. For speed 8 + entries are filled at a time. The array is given by its first and "after + last" entry. */ +template inline void +CoinFill(register T* first, register T* last, const T value) +{ + CoinFillN(first, last - first, value); +} + +//############################################################################# + +/** This helper function fills an array with zero. For speed 8 entries + are filled at a time. The array is given by a pointer to its first entry + and its size. + + Note JJF - the speed claim seems to be false on IA32 so I have allowed + for memset as an alternative */ +template inline void +CoinZeroN(register T* to, const int size) +{ +#ifdef USE_MEMCPY + // Use memset - seems faster on Intel with gcc +#ifndef NDEBUG + // Some debug so check + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinZeroN", ""); +#endif + memset(to,0,size*sizeof(T)); +#else + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinZeroN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, to += 8) { + to[0] = 0; + to[1] = 0; + to[2] = 0; + to[3] = 0; + to[4] = 0; + to[5] = 0; + to[6] = 0; + to[7] = 0; + } + switch (size % 8) { + case 7: to[6] = 0; + case 6: to[5] = 0; + case 5: to[4] = 0; + case 4: to[3] = 0; + case 3: to[2] = 0; + case 2: to[1] = 0; + case 1: to[0] = 0; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --to; + switch (size % 8) { + case 0: do{ *++to = 0; + case 7: *++to = 0; + case 6: *++to = 0; + case 5: *++to = 0; + case 4: *++to = 0; + case 3: *++to = 0; + case 2: *++to = 0; + case 1: *++to = 0; + }while(--n>0); + } +#endif +#endif +} +/// This Debug helper function checks an array is all zero +inline void +CoinCheckDoubleZero(double * to, const int size) +{ + int n=0; + for (int j=0;j inline void +CoinZero(register T* first, register T* last) +{ + CoinZeroN(first, last - first); +} + +//############################################################################# + +/** Returns strdup or NULL if original NULL */ +inline char * CoinStrdup(const char * name) +{ + char* dup = NULL; + if (name) { + const int len = static_cast(strlen(name)); + dup = static_cast(malloc(len+1)); + CoinMemcpyN(name, len, dup); + dup[len] = 0; + } + return dup; +} + +//############################################################################# + +/** Return the larger (according to operator<() of the arguments. + This function was introduced because for some reason compiler tend to + handle the max() function differently. */ +template inline T +CoinMax(register const T x1, register const T x2) +{ + return (x1 > x2) ? x1 : x2; +} + +//----------------------------------------------------------------------------- + +/** Return the smaller (according to operator<() of the arguments. + This function was introduced because for some reason compiler tend to + handle the min() function differently. */ +template inline T +CoinMin(register const T x1, register const T x2) +{ + return (x1 < x2) ? x1 : x2; +} + +//----------------------------------------------------------------------------- + +/** Return the absolute value of the argument. This function was introduced + because for some reason compiler tend to handle the abs() function + differently. */ +template inline T +CoinAbs(const T value) +{ + return value<0 ? -value : value; +} + +//############################################################################# + +/** This helper function tests whether the entries of an array are sorted + according to operator<. The array is given by a pointer to its first entry + and by its size. */ +template inline bool +CoinIsSorted(register const T* first, const int size) +{ + if (size == 0) + return true; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("negative number of entries", "CoinIsSorted", ""); +#endif +#if 1 + // size1 is the number of comparisons to be made + const int size1 = size - 1; + for (register int n = size1 / 8; n > 0; --n, first += 8) { + if (first[8] < first[7]) return false; + if (first[7] < first[6]) return false; + if (first[6] < first[5]) return false; + if (first[5] < first[4]) return false; + if (first[4] < first[3]) return false; + if (first[3] < first[2]) return false; + if (first[2] < first[1]) return false; + if (first[1] < first[0]) return false; + } + + switch (size1 % 8) { + case 7: if (first[7] < first[6]) return false; + case 6: if (first[6] < first[5]) return false; + case 5: if (first[5] < first[4]) return false; + case 4: if (first[4] < first[3]) return false; + case 3: if (first[3] < first[2]) return false; + case 2: if (first[2] < first[1]) return false; + case 1: if (first[1] < first[0]) return false; + case 0: break; + } +#else + register const T* next = first; + register const T* last = first + size; + for (++next; next != last; first = next, ++next) + if (*next < *first) + return false; +#endif + return true; +} + +//----------------------------------------------------------------------------- + +/** This helper function tests whether the entries of an array are sorted + according to operator<. The array is given by its first and "after + last" entry. */ +template inline bool +CoinIsSorted(register const T* first, register const T* last) +{ + return CoinIsSorted(first, static_cast(last - first)); +} + +//############################################################################# + +/** This helper function fills an array with the values init, init+1, init+2, + etc. For speed 8 entries are filled at a time. The array is given by a + pointer to its first entry and its size. */ +template inline void +CoinIotaN(register T* first, const int size, register T init) +{ + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("negative number of entries", "CoinIotaN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, first += 8, init += 8) { + first[0] = init; + first[1] = init + 1; + first[2] = init + 2; + first[3] = init + 3; + first[4] = init + 4; + first[5] = init + 5; + first[6] = init + 6; + first[7] = init + 7; + } + switch (size % 8) { + case 7: first[6] = init + 6; + case 6: first[5] = init + 5; + case 5: first[4] = init + 4; + case 4: first[3] = init + 3; + case 3: first[2] = init + 2; + case 2: first[1] = init + 1; + case 1: first[0] = init; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --first; + --init; + switch (size % 8) { + case 0: do{ *++first = ++init; + case 7: *++first = ++init; + case 6: *++first = ++init; + case 5: *++first = ++init; + case 4: *++first = ++init; + case 3: *++first = ++init; + case 2: *++first = ++init; + case 1: *++first = ++init; + }while(--n>0); + } +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function fills an array with the values init, init+1, init+2, + etc. For speed 8 entries are filled at a time. The array is given by its + first and "after last" entry. */ +template inline void +CoinIota(T* first, const T* last, T init) +{ + CoinIotaN(first, last-first, init); +} + +//############################################################################# + +/** This helper function deletes certain entries from an array. The array is + given by pointers to its first and "after last" entry (first two + arguments). The positions of the entries to be deleted are given in the + integer array specified by the last two arguments (again, first and "after + last" entry). */ +template inline T * +CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast, + const int * firstDelPos, const int * lastDelPos) +{ + int delNum = static_cast(lastDelPos - firstDelPos); + if (delNum == 0) + return arrayLast; + + if (delNum < 0) + throw CoinError("trying to delete negative number of entries", + "CoinDeleteEntriesFromArray", ""); + + int * delSortedPos = NULL; + if (! (CoinIsSorted(firstDelPos, lastDelPos) && + std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) { + // the positions of the to be deleted is either not sorted or not unique + delSortedPos = new int[delNum]; + CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos); + std::sort(delSortedPos, delSortedPos + delNum); + delNum = static_cast(std::unique(delSortedPos, + delSortedPos+delNum) - delSortedPos); + } + const int * delSorted = delSortedPos ? delSortedPos : firstDelPos; + + const int last = delNum - 1; + int size = delSorted[0]; + for (int i = 0; i < last; ++i) { + const int copyFirst = delSorted[i] + 1; + const int copyLast = delSorted[i+1]; + CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast, + arrayFirst + size); + size += copyLast - copyFirst; + } + const int copyFirst = delSorted[last] + 1; + const int copyLast = static_cast(arrayLast - arrayFirst); + CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast, + arrayFirst + size); + size += copyLast - copyFirst; + + if (delSortedPos) + delete[] delSortedPos; + + return arrayFirst + size; +} + +//############################################################################# + +#define COIN_OWN_RANDOM_32 + +#if defined COIN_OWN_RANDOM_32 +/* Thanks to Stefano Gliozzi for providing an operating system + independent random number generator. */ + +/*! \brief Return a random number between 0 and 1 + + A platform-independent linear congruential generator. For a given seed, the + generated sequence is always the same regardless of the (32-bit) + architecture. This allows to build & test in different environments, getting + in most cases the same optimization path. + + Set \p isSeed to true and supply an integer seed to set the seed + (vid. #CoinSeedRandom) + + \todo Anyone want to volunteer an upgrade for 64-bit architectures? +*/ +inline double CoinDrand48 (bool isSeed = false, unsigned int seed = 1) +{ + static unsigned int last = 123456; + if (isSeed) { + last = seed; + } else { + last = 1664525*last+1013904223; + return ((static_cast (last))/4294967296.0); + } + return (0.0); +} + +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) +{ + CoinDrand48(true, iseed); +} + +#else // COIN_OWN_RANDOM_32 + +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__) + +/// Return a random number between 0 and 1 +inline double CoinDrand48() { return rand() / (double) RAND_MAX; } +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); } + +#else + +/// Return a random number between 0 and 1 +inline double CoinDrand48() { return drand48(); } +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); } + +#endif + +#endif // COIN_OWN_RANDOM_32 + +//############################################################################# + +/** This function figures out whether file names should contain slashes or + backslashes as directory separator */ +inline char CoinFindDirSeparator() +{ + int size = 1000; + char* buf = 0; + while (true) { + buf = new char[size]; + if (getcwd(buf, size)) + break; + delete[] buf; + buf = 0; + size = 2*size; + } + // if first char is '/' then it's unix and the dirsep is '/'. otherwise we + // assume it's dos and the dirsep is '\' + char dirsep = buf[0] == '/' ? '/' : '\\'; + delete[] buf; + return dirsep; +} +//############################################################################# + +inline int CoinStrNCaseCmp(const char* s0, const char* s1, + const size_t len) +{ + for (size_t i = 0; i < len; ++i) { + if (s0[i] == 0) { + return s1[i] == 0 ? 0 : -1; + } + if (s1[i] == 0) { + return 1; + } + const int c0 = std::tolower(s0[i]); + const int c1 = std::tolower(s1[i]); + if (c0 < c1) + return -1; + if (c0 > c1) + return 1; + } + return 0; +} + +//############################################################################# + +/// Swap the arguments. +template inline void CoinSwap (T &x, T &y) +{ + T t = x; + x = y; + y = t; +} + +//############################################################################# + +/** This helper function copies an array to file + Returns 0 if OK, 1 if bad write. +*/ + +template inline int +CoinToFile( const T* array, CoinBigIndex size, FILE * fp) +{ + CoinBigIndex numberWritten; + if (array&&size) { + numberWritten = + static_cast(fwrite(&size,sizeof(int),1,fp)); + if (numberWritten!=1) + return 1; + numberWritten = + static_cast(fwrite(array,sizeof(T),size_t(size),fp)); + if (numberWritten!=size) + return 1; + } else { + size = 0; + numberWritten = + static_cast(fwrite(&size,sizeof(int),1,fp)); + if (numberWritten!=1) + return 1; + } + return 0; +} + +//############################################################################# + +/** This helper function copies an array from file and creates with new. + Passed in array is ignored i.e. not deleted. + But if NULL and size does not match and newSize 0 then leaves as NULL and 0 + Returns 0 if OK, 1 if bad read, 2 if size did not match. +*/ + +template inline int +CoinFromFile( T* &array, CoinBigIndex size, FILE * fp, CoinBigIndex & newSize) +{ + CoinBigIndex numberRead; + numberRead = + static_cast(fread(&newSize,sizeof(int),1,fp)); + if (numberRead!=1) + return 1; + int returnCode=0; + if (size!=newSize&&(newSize||array)) + returnCode=2; + if (newSize) { + array = new T [newSize]; + numberRead = + static_cast(fread(array,sizeof(T),newSize,fp)); + if (numberRead!=newSize) + returnCode=1; + } else { + array = NULL; + } + return returnCode; +} + +//############################################################################# + +/// Cube Root +#if 0 +inline double CoinCbrt(double x) +{ +#if defined(_MSC_VER) + return pow(x,(1./3.)); +#else + return cbrt(x); +#endif +} +#endif + +//----------------------------------------------------------------------------- + +/// This helper returns "sizeof" as an int +#define CoinSizeofAsInt(type) (static_cast(sizeof(type))) +/// This helper returns "strlen" as an int +inline int +CoinStrlenAsInt(const char * string) +{ + return static_cast(strlen(string)); +} + +/** Class for thread specific random numbers +*/ +#if defined COIN_OWN_RANDOM_32 +class CoinThreadRandom { +public: + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + CoinThreadRandom() + { seed_=12345678;} + /** Constructor wih seed. */ + CoinThreadRandom(int seed) + { + seed_ = seed; + } + /** Destructor */ + ~CoinThreadRandom() {} + // Copy + CoinThreadRandom(const CoinThreadRandom & rhs) + { seed_ = rhs.seed_;} + // Assignment + CoinThreadRandom& operator=(const CoinThreadRandom & rhs) + { + if (this != &rhs) { + seed_ = rhs.seed_; + } + return *this; + } + + //@} + + /**@name Sets/gets */ + + //@{ + /** Set seed. */ + inline void setSeed(int seed) + { + seed_ = seed; + } + /** Get seed. */ + inline unsigned int getSeed() const + { + return seed_; + } + /// return a random number + inline double randomDouble() const + { + double retVal; + seed_ = 1664525*(seed_)+1013904223; + retVal = ((static_cast (seed_))/4294967296.0); + return retVal; + } + /// make more random (i.e. for startup) + inline void randomize(int n=0) + { + if (!n) + n=seed_ & 255; + for (int i=0;i +#include "CoinFinite.hpp" +#ifndef CLP_NO_VECTOR +#include "CoinPackedVectorBase.hpp" +#endif +#include "CoinSort.hpp" +#include "CoinHelperFunctions.hpp" +#include + +#ifndef COIN_FLOAT +#define COIN_INDEXED_TINY_ELEMENT 1.0e-50 +#define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-100 +#else +#define COIN_INDEXED_TINY_ELEMENT 1.0e-35 +#define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-39 +#endif + +/** Indexed Vector + +This stores values unpacked but apart from that is a bit like CoinPackedVector. +It is designed to be lightweight in normal use. + +It now has a "packed" mode when it is even more like CoinPackedVector + +Indices array has capacity_ extra chars which are zeroed and can +be used for any purpose - but must be re-zeroed + +Stores vector of indices and associated element values. +Supports sorting of indices. + +Does not support negative indices. + +Does NOT support testing for duplicates + +*** getElements is no longer supported + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 } + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its valuex1 + CoinIndexedVector r(ne,inx,el); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // sort Elements in increasing order + r.sortIncrElement(); + + // access each index and element + assert( r.getIndices ()[0]== 0 ); + assert( r.getIndices ()[1]== 1 ); + assert( r.getIndices ()[2]== 4 ); + assert( r.getIndices ()[3]== 2 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Tests for equality and equivalence + CoinIndexedVector r1; + r1=r; + assert( r==r1 ); + assert( r.equivalent(r1) ); + r.sortIncrElement(); + assert( r!=r1 ); + assert( r.equivalent(r1) ); + + // Add indexed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinIndexedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinIndexedVector { + friend void CoinIndexedVectorUnitTest(); + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getNumElements() const { return nElements_; } + /// Get indices of elements + inline const int * getIndices() const { return indices_; } + /// Get element values + // ** No longer supported virtual const double * getElements() const ; + /// Get indices of elements + inline int * getIndices() { return indices_; } + /** Get the vector as a dense vector. This is normal storage method. + The user should not not delete [] this. + */ + inline double * denseVector() const { return elements_; } + /// For very temporary use when user needs to borrow a dense vector + inline void setDenseVector(double * array) + { elements_ = array;} + /// For very temporary use when user needs to borrow an index vector + inline void setIndexVector(int * array) + { indices_ = array;} + /** Access the i'th element of the full storage vector. + */ + double & operator[](int i) const; + + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Set the size + inline void setNumElements(int value) { nElements_ = value; + if (!nElements_) packedMode_=false;} + /// Reset the vector (as if were just created an empty vector). This leaves arrays! + void clear(); + /// Reset the vector (as if were just created an empty vector) + void empty(); + /** Assignment operator. */ + CoinIndexedVector & operator=(const CoinIndexedVector &); +#ifndef CLP_NO_VECTOR + /** Assignment operator from a CoinPackedVectorBase.
+ NOTE: This assumes no duplicates */ + CoinIndexedVector & operator=(const CoinPackedVectorBase & rhs); +#endif + /** Copy the contents of one vector into another. If multiplier is 1 + It is the equivalent of = but if vectors are same size does + not re-allocate memory just clears and copies */ + void copy(const CoinIndexedVector & rhs, double multiplier=1.0); + + /** Borrow ownership of the arguments to this vector. + Size is the length of the unpacked elements vector. */ + void borrowVector(int size, int numberIndices, int* inds, double* elems); + + /** Return ownership of the arguments to this vector. + State after is empty . + */ + void returnVector(); + + /** Set vector numberIndices, indices, and elements. + NumberIndices is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. Assumed to have no duplicates */ + void setVector(int numberIndices, const int * inds, const double * elems); + + /** Set vector size, indices, and elements. + Size is the length of the unpacked elements vector. + The indices and elements vectors are copied into this class instance's + member data. We do not check for duplicate indices */ + void setVector(int size, int numberIndices, const int * inds, const double * elems); + + /** Elements set to have the same scalar value */ + void setConstant(int size, const int * inds, double elems); + + /** Indices are not specified and are taken to be 0,1,...,size-1 */ + void setFull(int size, const double * elems); + + /** Set an existing element in the indexed vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, double element); + + /// Insert an element into the vector + void insert(int index, double element); + /// Insert a nonzero element into the vector + inline void quickInsert(int index, double element) + { + assert (!elements_[index]); + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny */ + void add(int index, double element); + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny. + This version does no checking */ + inline void quickAdd(int index, double element) + { + if (elements_[index]) { + element += elements_[index]; + if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + elements_[index] = element; + } else { + elements_[index] = 1.0e-100; + } + } else if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + } + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny. + This knows element is nonzero + This version does no checking */ + inline void quickAddNonZero(int index, double element) + { + assert (element); + if (elements_[index]) { + element += elements_[index]; + if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + elements_[index] = element; + } else { + elements_[index] = COIN_DBL_MIN; + } + } else { + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + } + /** Makes nonzero tiny. + This version does no checking */ + inline void zero(int index) + { + if (elements_[index]) + elements_[index] = COIN_DBL_MIN; + } + /** set all small values to zero and return number remaining + - < tolerance => 0.0 */ + int clean(double tolerance); + /// Same but packs down + int cleanAndPack(double tolerance); + /// Same but packs down and is safe (i.e. if order is odd) + int cleanAndPackSafe(double tolerance); + /// Mark as packed + inline void setPacked() + { packedMode_ = true;} +#ifndef NDEBUG + /// For debug check vector is clear i.e. no elements + void checkClear(); + /// For debug check vector is clean i.e. elements match indices + void checkClean(); +#else + inline void checkClear() {}; + inline void checkClean() {}; +#endif + /// Scan dense region and set up indices (returns number found) + int scan(); + /** Scan dense region from start to < end and set up indices + returns number found + */ + int scan(int start, int end); + /** Scan dense region and set up indices (returns number found). + Only ones >= tolerance */ + int scan(double tolerance); + /** Scan dense region from start to < end and set up indices + returns number found. Only >= tolerance + */ + int scan(int start, int end, double tolerance); + /// These are same but pack down + int scanAndPack(); + int scanAndPack(int start, int end); + int scanAndPack(double tolerance); + int scanAndPack(int start, int end, double tolerance); + /// Create packed array + void createPacked(int number, const int * indices, + const double * elements); + /// Create unpacked array + void createUnpacked(int number, const int * indices, + const double * elements); + /// Create unpacked singleton + void createOneUnpackedElement(int index, double element); + /// This is mainly for testing - goes from packed to indexed + void expand(); +#ifndef CLP_NO_VECTOR + /// Append a CoinPackedVector to the end + void append(const CoinPackedVectorBase & caboose); +#endif + /// Append a CoinIndexedVector to the end (with extra space) + void append(const CoinIndexedVector & caboose); + /// Append a CoinIndexedVector to the end and modify indices + void append(CoinIndexedVector & other,int adjustIndex,bool zapElements=false); + + /// Swap values in positions i and j of indices and elements + void swap(int i, int j); + + /// Throw away all entries in rows >= newSize + void truncate(int newSize); + /// Print out + void print() const; + //@} + /**@name Arithmetic operators. */ + //@{ + /// add value to every entry + void operator+=(double value); + /// subtract value from every entry + void operator-=(double value); + /// multiply every entry by value + void operator*=(double value); + /// divide every entry by value (** 0 vanishes) + void operator/=(double value); + //@} + + /**@name Comparison operators on two indexed vectors */ + //@{ +#ifndef CLP_NO_VECTOR + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinPackedVectorBase & rhs) const; + /// Not equal + bool operator!=(const CoinPackedVectorBase & rhs) const; +#endif + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinIndexedVector & rhs) const; + /// Not equal + bool operator!=(const CoinIndexedVector & rhs) const; + /// Equal with a tolerance (returns -1 or position of inequality). + int isApproximatelyEqual(const CoinIndexedVector & rhs, double tolerance=1.0e-8) const; + //@} + + /**@name Index methods */ + //@{ + /// Get value of maximum index + int getMaxIndex() const; + /// Get value of minimum index + int getMinIndex() const; + //@} + + + /**@name Sorting */ + //@{ + /** Sort the indexed storage vector (increasing indices). */ + void sort() + { std::sort(indices_,indices_+nElements_); } + + void sortIncrIndex() + { std::sort(indices_,indices_+nElements_); } + + void sortDecrIndex(); + + void sortIncrElement(); + + void sortDecrElement(); + void sortPacked(); + + //@} + + //############################################################################# + + /**@name Arithmetic operators on packed vectors. + + NOTE: These methods operate on those positions where at + least one of the arguments has a value listed. At those positions the + appropriate operation is executed, Otherwise the result of the operation is + considered 0.
+ NOTE 2: Because these methods return an object (they can't + return a reference, though they could return a pointer...) they are + very inefficient... + */ +//@{ +/// Return the sum of two indexed vectors +CoinIndexedVector operator+( + const CoinIndexedVector& op2); + +/// Return the difference of two indexed vectors +CoinIndexedVector operator-( + const CoinIndexedVector& op2); + +/// Return the element-wise product of two indexed vectors +CoinIndexedVector operator*( + const CoinIndexedVector& op2); + +/// Return the element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) +CoinIndexedVector operator/( + const CoinIndexedVector& op2); +/// The sum of two indexed vectors +void operator+=(const CoinIndexedVector& op2); + +/// The difference of two indexed vectors +void operator-=( const CoinIndexedVector& op2); + +/// The element-wise product of two indexed vectors +void operator*=(const CoinIndexedVector& op2); + +/// The element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) +void operator/=(const CoinIndexedVector& op2); +//@} + + /**@name Memory usage */ + //@{ + /** Reserve space. + If one knows the eventual size of the indexed vector, + then it may be more efficient to reserve the space. + */ + void reserve(int n); + /** capacity returns the size which could be accomodated without + having to reallocate storage. + */ + inline int capacity() const { return capacity_; } + inline void setCapacity(int value) + { capacity_ = value; } + /// Sets packed mode + inline void setPackedMode(bool yesNo) + { packedMode_=yesNo;} + /// Gets packed mode + inline bool packedMode() const + { return packedMode_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinIndexedVector(); + /** Alternate Constructors - set elements to vector of doubles */ + CoinIndexedVector(int size, const int * inds, const double * elems); + /** Alternate Constructors - set elements to same scalar value */ + CoinIndexedVector(int size, const int * inds, double element); + /** Alternate Constructors - construct full storage with indices 0 through + size-1. */ + CoinIndexedVector(int size, const double * elements); + /** Alternate Constructors - just size */ + CoinIndexedVector(int size); + /** Copy constructor. */ + CoinIndexedVector(const CoinIndexedVector &); + /** Copy constructor.2 */ + CoinIndexedVector(const CoinIndexedVector *); +#ifndef CLP_NO_VECTOR + /** Copy constructor from a PackedVectorBase. */ + CoinIndexedVector(const CoinPackedVectorBase & rhs); +#endif + /** Destructor */ + ~CoinIndexedVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfSetVector(int size, + const int * inds, const double * elems); + void gutsOfSetVector(int size, int numberIndices, + const int * inds, const double * elems); + void gutsOfSetPackedVector(int size, int numberIndices, + const int * inds, const double * elems); + /// + void gutsOfSetConstant(int size, + const int * inds, double value); + //@} + +protected: + /**@name Private member data */ + //@{ + /// Vector indices + int * indices_; + ///Vector elements + double * elements_; + /// Size of indices and packed elements vectors + int nElements_; + /// Amount of memory allocated for indices_, and elements_. + int capacity_; + /// Offset to get where new allocated array + int offset_; + /// If true then is operating in packed mode + bool packedMode_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CoinIndexedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinIndexedVectorUnitTest(); +/** Pointer with length in bytes + + This has a pointer to an array and the number of bytes in array. + If number of bytes==-1 then + CoinConditionalNew deletes existing pointer and returns new pointer + of correct size (and number bytes still -1). + CoinConditionalDelete deletes existing pointer and NULLs it. + So behavior is as normal (apart from New deleting pointer which will have + no effect with good coding practices. + If number of bytes >=0 then + CoinConditionalNew just returns existing pointer if array big enough + otherwise deletes existing pointer, allocates array with spare 1%+64 bytes + and updates number of bytes + CoinConditionalDelete sets number of bytes = -size-2 and then array + returns NULL +*/ +class CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_; } + /// Get the size + inline int rawSize() const + { return size_; } + /// See if persistence already on + inline bool switchedOn() const + { return size_!=-1; } + /// Get the capacity (just read it) + inline int capacity() const + { return (size_>-2) ? size_ : (-size_)-2; } + /// Set the capacity to >=0 if <=-2 + inline void setCapacity() + { if (size_<=-2) size_ = (-size_)-2; } + /// Get Array + inline const char * array() const + { return (size_>-2) ? array_ : NULL; } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value; } + /// Set the size to -1 + inline void switchOff() + { size_ = -1; } + /// Set the size to -2 and alignment + inline void switchOn(int alignment=3) + { size_ = -2; alignment_=alignment;} + /// Does what is needed to set persistence + void setPersistence(int flag,int currentLength); + /// Zero out array + void clear(); + /// Swaps memory between two members + void swap(CoinArrayWithLength & other); + /// Extend a persistent array keeping data (size in bytes) + void extend(int newSize); + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + char * conditionalNew(long sizeWanted); + /// Conditionally deletes + void conditionalDelete(); + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinArrayWithLength() + : array_(NULL),size_(-1),offset_(0),alignment_(0) + { } + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinArrayWithLength(int size) + : size_(-1),offset_(0),alignment_(0) + { array_=new char [size];} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + mode>0 size_ set to size and zeroed + if size<=0 just does alignment + If abs(mode) >2 then align on that as power of 2 + */ + CoinArrayWithLength(int size, int mode); + /** Copy constructor. */ + CoinArrayWithLength(const CoinArrayWithLength & rhs); + /** Copy constructor.2 */ + CoinArrayWithLength(const CoinArrayWithLength * rhs); + /** Assignment operator. */ + CoinArrayWithLength& operator=(const CoinArrayWithLength & rhs); + /** Assignment with length (if -1 use internal length) */ + void copy(const CoinArrayWithLength & rhs, int numberBytes=-1); + /** Assignment with length - does not copy */ + void allocate(const CoinArrayWithLength & rhs, int numberBytes); + /** Destructor */ + ~CoinArrayWithLength (); + /// Get array with alignment + void getArray(int size); + /// Really get rid of array with alignment + void reallyFreeArray(); + /// Get enough space (if more needed then do at least needed) + void getCapacity(int numberBytes,int numberIfNeeded=-1); + //@} + +protected: + /**@name Private member data */ + //@{ + /// Array + char * array_; + /// Size of array in bytes + CoinBigIndex size_; + /// Offset of array + int offset_; + /// Alignment wanted (power of 2) + int alignment_; + //@} +}; +/// double * version + +class CoinDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(double); } + /// Get Array + inline double * array() const + { return reinterpret_cast ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(double); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline double * conditionalNew(int sizeWanted) + { return reinterpret_cast ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast ((sizeWanted)*CoinSizeofAsInt(double)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(double)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(double),mode) {} + /** Copy constructor. */ + inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinDoubleArrayWithLength& operator=(const CoinDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinFactorizationDouble * version + +class CoinFactorizationDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(CoinFactorizationDouble); } + /// Get Array + inline CoinFactorizationDouble * array() const + { return reinterpret_cast ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(CoinFactorizationDouble); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline CoinFactorizationDouble * conditionalNew(int sizeWanted) + { return reinterpret_cast (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast (( sizeWanted)*CoinSizeofAsInt(CoinFactorizationDouble)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinFactorizationDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinFactorizationDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(CoinFactorizationDouble)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinFactorizationDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(CoinFactorizationDouble),mode) {} + /** Copy constructor. */ + inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinFactorizationDoubleArrayWithLength& operator=(const CoinFactorizationDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinFactorizationLongDouble * version + +class CoinFactorizationLongDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(long double); } + /// Get Array + inline long double * array() const + { return reinterpret_cast ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(long double); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline long double * conditionalNew(int sizeWanted) + { return reinterpret_cast (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast (( sizeWanted)*CoinSizeofAsInt(long double)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinFactorizationLongDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinFactorizationLongDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(long double)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinFactorizationLongDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(long double),mode) {} + /** Copy constructor. */ + inline CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinFactorizationLongDoubleArrayWithLength& operator=(const CoinFactorizationLongDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// int * version + +class CoinIntArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(int); } + /// Get Array + inline int * array() const + { return reinterpret_cast ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(int); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline int * conditionalNew(int sizeWanted) + { return reinterpret_cast (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast (( sizeWanted)*CoinSizeofAsInt(int)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinIntArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinIntArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(int)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinIntArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(int),mode) {} + /** Copy constructor. */ + inline CoinIntArrayWithLength(const CoinIntArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinIntArrayWithLength(const CoinIntArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinIntArrayWithLength& operator=(const CoinIntArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinBigIndex * version + +class CoinBigIndexArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(CoinBigIndex); } + /// Get Array + inline CoinBigIndex * array() const + { return reinterpret_cast ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(CoinBigIndex); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline CoinBigIndex * conditionalNew(int sizeWanted) + { return reinterpret_cast (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast (( sizeWanted)*CoinSizeofAsInt(CoinBigIndex)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinBigIndexArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinBigIndexArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(CoinBigIndex)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinBigIndexArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(CoinBigIndex),mode) {} + /** Copy constructor. */ + inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinBigIndexArrayWithLength& operator=(const CoinBigIndexArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// unsigned int * version + +class CoinUnsignedIntArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(unsigned int); } + /// Get Array + inline unsigned int * array() const + { return reinterpret_cast ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(unsigned int); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline unsigned int * conditionalNew(int sizeWanted) + { return reinterpret_cast (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast (( sizeWanted)*CoinSizeofAsInt(unsigned int)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinUnsignedIntArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinUnsignedIntArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(unsigned int)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinUnsignedIntArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(unsigned int),mode) {} + /** Copy constructor. */ + inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinUnsignedIntArrayWithLength& operator=(const CoinUnsignedIntArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// void * version + +class CoinVoidStarArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(void *); } + /// Get Array + inline void ** array() const + { return reinterpret_cast ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(void *); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline void ** conditionalNew(int sizeWanted) + { return reinterpret_cast ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast ((sizeWanted)*CoinSizeofAsInt(void *)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinVoidStarArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinVoidStarArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(void *)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinVoidStarArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(void *),mode) {} + /** Copy constructor. */ + inline CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinVoidStarArrayWithLength& operator=(const CoinVoidStarArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// arbitrary version + +class CoinArbitraryArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/lengthInBytes_; } + /// Get Array + inline void ** array() const + { return reinterpret_cast ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*lengthInBytes_; } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline char * conditionalNew(int length, int sizeWanted) + { lengthInBytes_=length;return reinterpret_cast ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast + ((sizeWanted)*lengthInBytes_) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinArbitraryArrayWithLength(int length=1) + { array_=NULL; size_=-1;lengthInBytes_=length;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinArbitraryArrayWithLength(int length, int size) + { array_=new char [size*length]; size_=-1; lengthInBytes_=length;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinArbitraryArrayWithLength(int length, int size, int mode) + : CoinArrayWithLength(size*length,mode) {lengthInBytes_=length;} + /** Copy constructor. */ + inline CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinArbitraryArrayWithLength& operator=(const CoinArbitraryArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} + +protected: + /**@name Private member data */ + //@{ + /// Length in bytes + int lengthInBytes_; + //@} +}; +class CoinPartitionedVector : public CoinIndexedVector { + +public: +#ifndef COIN_PARTITIONS +#define COIN_PARTITIONS 8 +#endif + /**@name Get methods. */ + //@{ + /// Get the size of a partition + inline int getNumElements(int partition) const { assert (partition + +#include "CoinPackedMatrix.hpp" +#include "CoinMessage.hpp" +class CoinSet; + +const int MAX_OBJECTIVES = 2; + +typedef int COINColumnIndex; + + /** Class to read and write Lp files + + Lp file format: + +/ this is a comment
+\ this too
+ Min
+ obj: x0 + x1 + 3 x2 - 4.5 xyr + 1
+ s.t.
+ cons1: x0 - x2 - 2.3 x4 <= 4.2 / this is another comment
+ c2: x1 + x2 >= 1
+ cc: x1 + x2 + xyr = 2
+ Bounds
+ 0 <= x1 <= 3
+ 1 >= x2
+ x3 = 1
+ -2 <= x4 <= Inf
+ xyr free
+ Integers
+ x0
+ Generals
+ x1 xyr
+ Binaries
+ x2
+ End + +Notes:

    +
  • Keywords are: Min, Max, Minimize, Maximize, s.t., Subject To, + Bounds, Integers, Generals, Binaries, End, Free, Inf. +
  • Keywords are not case sensitive and may be in plural or singular form. + They should not be used as objective, row or column names. +
  • Bounds, Integers, Generals, Binaries sections are optional. +
  • Generals and Integers are synonymous. +
  • Bounds section (if any) must come before Integers, Generals, and + Binaries sections. +
  • Row names must be followed by ':' without blank space. + Row names are optional. If row names are present, + they must be distinct (if the k-th constraint has no given name, its name + is set automatically to "consk" for k=0,...,). + For valid row names, see the method is_invalid_name(). +
  • Column names must be followed by a blank space. They must be distinct. + For valid column names, see the method is_invalid_name(). +
  • Multiple objectives may be specified, but when there are multiple + objectives, they must have names (to indicate where each one starts). +
  • The objective function names must be followed by ':' without blank space. + If there is a single objective, the objective function name is optional. + If no name is given, the name is set to "obj" by default. + For valid objective function names, see the method is_invalid_name(). +
  • Ranged constraints are written as two constraints. + If a name is given for a ranged constraint, the upper bound constraint + has that name and the lower bound constraint has that name with "_low" + as suffix. This should be kept in mind when assigning names to ranged + constraint, as the resulting name must be distinct from all the other + names and be considered valid by the method is_invalid_name(). +
  • At most one term related to any single variable may appear in the + objective function; if more than one term are present, only the last + one is taken into account. + At most one constant term may appear in the objective function; + if present, it must appear last. +
  • Default bounds are 0 for lower bound and +infinity for upper bound. +
  • Free variables get default lower bound -infinity and + default upper bound +infinity. Writing "x0 Free" in an + LP file means "set lower bound on x0 to -infinity". +
  • If more than one upper (resp. lower) bound on a variable appears in + the Bounds section, the last one is the one taken into + account. The bounds for a binary variable are set to 0/1 only if this + bound is stronger than the bound obtained from the Bounds section. +
  • Numbers larger than DBL_MAX (or larger than 1e+400) in the input file + might crash the code. +
  • A comment must start with '\' or '/'. That symbol must either be + the first character of a line or be preceded by a blank space. The + comment ends at the end of the + line. Comments are skipped while reading an Lp file and they may be + inserted anywhere. +
+*/ +class CoinLpIO { + friend void CoinLpIOUnitTest(const std::string & lpDir); +public: + + /**@name Constructor and Destructor */ + //@{ + /// Default Constructor + CoinLpIO(); + + /// Does the heavy lifting for destruct and assignment. + void gutsOfDestructor(); + + /// Does the heavy lifting for copy and assignment + void gutsOfCopy(const CoinLpIO &); + + /// assignment operator + CoinLpIO & operator = (const CoinLpIO& rhs) ; + + /// Copy constructor + CoinLpIO (const CoinLpIO &); + + /// Destructor + ~CoinLpIO(); + + /** Free the vector previous_names_[section] and set + card_previous_names_[section] to 0. + section = 0 for row names, + section = 1 for column names. + */ + void freePreviousNames(const int section); + + /// Free all memory (except memory related to hash tables and objName_). + void freeAll(); + //@} + + /** A quick inlined function to convert from lb/ub style constraint + definition to sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + + /**@name Queries */ + //@{ + + /// Get the problem name + const char * getProblemName() const; + + /// Set problem name + void setProblemName(const char *name); + + /// Get number of columns + int getNumCols() const; + + /// Get number of rows + int getNumRows() const; + + /// Get number of nonzero elements + int getNumElements() const; + + /// Get pointer to array[getNumCols()] of column lower bounds + const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + const double * getColUpper() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + const double * getRowUpper() const; + /** Get pointer to array[getNumRows()] of constraint senses. +
    +
  • 'L': <= constraint +
  • 'E': = constraint +
  • 'G': >= constraint +
  • 'R': ranged constraint +
  • 'N': free constraint +
+ */ + const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of constraint right-hand sides. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint right-hand side (rhs) is set as +
    +
  • if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] +
  • if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] +
  • if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] +
  • if rowsense()[i] == 'N' then rhs()[i] == 0.0 +
+ */ + const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint range (rowrange) is set as +
    +
  • if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] +
  • if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 +
+ Put another way, only ranged constraints have a nontrivial value for + rowrange. + */ + const double * getRowRange() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const int getNumObjectives() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const double * getObjCoefficients() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients for objective j + const double * getObjCoefficients(int j) const; + + /// Get pointer to row-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByCol() const; + + /// Get objective function name + const char * getObjName() const; + + /// Get objective function name for objective j + const char * getObjName(int j) const; + + /// Get pointer to array[*card_prev] of previous row names. + /// The value of *card_prev might be different than getNumRows()+1 if + /// non distinct + /// row names were present or if no previous names were saved or if + /// the object was holding a different problem before. + void getPreviousRowNames(char const * const * prev, + int *card_prev) const; + + /// Get pointer to array[*card_prev] of previous column names. + /// The value of *card_prev might be different than getNumCols() if non + /// distinct column names were present of if no previous names were saved, + /// or if the object was holding a different problem before. + void getPreviousColNames(char const * const * prev, + int *card_prev) const; + + /// Get pointer to array[getNumRows()+1] of row names, including + /// objective function name as last entry. + char const * const * getRowNames() const; + + /// Get pointer to array[getNumCols()] of column names + char const * const *getColNames() const; + + /// Return the row name for the specified index. + /// Return the objective function name if index = getNumRows(). + /// Return 0 if the index is out of range or if row names are not defined. + const char * rowName(int index) const; + + /// Return the column name for the specified index. + /// Return 0 if the index is out of range or if column names are not + /// defined. + const char * columnName(int index) const; + + /// Return the index for the specified row name. + /// Return getNumRows() for the objective function name. + /// Return -1 if the name is not found. + int rowIndex(const char * name) const; + + /// Return the index for the specified column name. + /// Return -1 if the name is not found. + int columnIndex(const char * name) const; + + ///Returns the (constant) objective offset + double objectiveOffset() const; + + ///Returns the (constant) objective offset for objective j + double objectiveOffset(int j) const; + + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_[0] = value;} + + /// Set objective offset + inline void setObjectiveOffset(double value, int j) + { objectiveOffset_[j] = value;} + + /// Return true if a column is an integer (binary or general + /// integer) variable + bool isInteger(int columnNumber) const; + + /// Get characteristic vector of integer variables + const char * integerColumns() const; + //@} + + /**@name Parameters */ + //@{ + /// Get infinity + double getInfinity() const; + + /// Set infinity. Any number larger is considered infinity. + /// Default: DBL_MAX + void setInfinity(const double); + + /// Get epsilon + double getEpsilon() const; + + /// Set epsilon. + /// Default: 1e-5. + void setEpsilon(const double); + + /// Get numberAcross, the number of monomials to be printed per line + int getNumberAcross() const; + + /// Set numberAcross. + /// Default: 10. + void setNumberAcross(const int); + + /// Get decimals, the number of digits to write after the decimal point + int getDecimals() const; + + /// Set decimals. + /// Default: 5 + void setDecimals(const int); + //@} + + /**@name Public methods */ + //@{ + /** Set the data of the object. + Set it from the coefficient matrix m, the lower bounds + collb, the upper bounds colub, objective function obj_coeff, + integrality vector integrality, lower/upper bounds on the constraints. + The sense of optimization of the objective function is assumed to be + a minimization. + Numbers larger than DBL_MAX (or larger than 1e+400) + might crash the code. There are two version. The second one is for + setting multiple objectives. + */ + void setLpDataWithoutRowAndColNames( + const CoinPackedMatrix& m, + const double* collb, const double* colub, + const double* obj_coeff, + const char* integrality, + const double* rowlb, const double* rowub); + + void setLpDataWithoutRowAndColNames( + const CoinPackedMatrix& m, + const double* collb, const double* colub, + const double* obj_coeff[MAX_OBJECTIVES], + int num_objectives, + const char* integrality, + const double* rowlb, const double* rowub); + + /** Return 0 if buff is a valid name for a row, a column or objective + function, return a positive number otherwise. + If parameter ranged = true, the name is intended for a ranged + constraint.
+ Return 1 if the name has more than 100 characters (96 characters + for a ranged constraint name, as "_low" will be added to the name).
+ Return 2 if the name starts with a number.
+ Return 3 if the name is not built with + the letters a to z, A to Z, the numbers 0 to 9 or the characters + " ! # $ % & ( ) . ; ? @ _ ' ` { } ~
+ Return 4 if the name is a keyword.
+ Return 5 if the name is empty or NULL. */ + int is_invalid_name(const char *buff, const bool ranged) const; + + /** Return 0 if each of the card_vnames entries of vnames is a valid name, + return a positive number otherwise. The return value, if not 0, is the + return value of is_invalid_name() for the last invalid name + in vnames. If check_ranged = true, the names are row names and + names for ranged constaints must be checked for additional restrictions + since "_low" will be added to the name if an Lp file is written. + When check_ranged = true, card_vnames must have getNumRows()+1 entries, + with entry vnames[getNumRows()] being the + name of the objective function. + For a description of valid names and return values, see the method + is_invalid_name(). + + This method must not be called with check_ranged = true before + setLpDataWithoutRowAndColNames() has been called, since access + to the indices of all the ranged constraints is required. + */ + int are_invalid_names(char const * const *vnames, + const int card_vnames, + const bool check_ranged) const; + + /// Set objective function name to the default "obj" and row + /// names to the default "cons0", "cons1", ... + void setDefaultRowNames(); + + /// Set column names to the default "x0", "x1", ... + void setDefaultColNames(); + + /** Set the row and column names. + The array rownames must either be NULL or have exactly getNumRows()+1 + distinct entries, + each of them being a valid name (see is_invalid_name()) and the + last entry being the intended name for the objective function. + If rownames is NULL, existing row names and objective function + name are not changed. + If rownames is deemed invalid, default row names and objective function + name are used (see setDefaultRowNames()). The memory location of + array rownames (or its entries) should not be related + to the memory location of the array (or entries) obtained from + getRowNames() or getPreviousRowNames(), as the call to + setLpDataRowAndColNames() modifies the corresponding arrays. + Unpredictable results + are obtained if this requirement is ignored. + + Similar remarks apply to the array colnames, which must either be + NULL or have exactly getNumCols() entries. + */ + void setLpDataRowAndColNames(char const * const * const rownames, + char const * const * const colnames); + + /** Write the data in Lp format in the file with name filename. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + Write objective function name and row names if useRowNames = true. + + Ranged constraints are written as two constraints. + If row names are used, the upper bound constraint has the + name of the original ranged constraint and the + lower bound constraint has for name the original name with + "_low" as suffix. If doing so creates two identical row names, + default row names are used (see setDefaultRowNames()). + */ + int writeLp(const char *filename, + const double epsilon, + const int numberAcross, + const int decimals, + const bool useRowNames = true); + + /** Write the data in Lp format in the file pointed to by the paramater fp. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + Write objective function name and row names if useRowNames = true. + + Ranged constraints are written as two constraints. + If row names are used, the upper bound constraint has the + name of the original ranged constraint and the + lower bound constraint has for name the original name with + "_low" as suffix. If doing so creates two identical row names, + default row names are used (see setDefaultRowNames()). + */ + int writeLp(FILE *fp, + const double epsilon, + const int numberAcross, + const int decimals, + const bool useRowNames = true); + + /// Write the data in Lp format in the file with name filename. + /// Write objective function name and row names if useRowNames = true. + int writeLp(const char *filename, const bool useRowNames = true); + + /// Write the data in Lp format in the file pointed to by the parameter fp. + /// Write objective function name and row names if useRowNames = true. + int writeLp(FILE *fp, const bool useRowNames = true); + + /// Read the data in Lp format from the file with name filename, using + /// the given value for epsilon. If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(const char *filename, const double epsilon); + + /// Read the data in Lp format from the file with name filename. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(const char *filename); + + /// Read the data in Lp format from the file stream, using + /// the given value for epsilon. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(FILE *fp, const double epsilon); + + /// Read the data in Lp format from the file stream. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(FILE *fp); + + /// Dump the data. Low level method for debugging. + void print() const; + + /// Load in SOS stuff + void loadSOS(int numberSets,const CoinSet * sets); + + /// Load in SOS stuff + void loadSOS(int numberSets,const CoinSet ** sets); + + /// Number of SOS sets + inline int numberSets() const + { return numberSets_;} + + /// Set information + inline CoinSet ** setInformation() const + { return set_;} + //@} +/**@name Message handling */ +//@{ + /** Pass in Message handler + + Supply a custom message handler. It will not be destroyed when the + CoinMpsIO object is destroyed. + */ + void passInMessageHandler(CoinMessageHandler * handler); + + /// Set the language for messages. + void newLanguage(CoinMessages::Language language); + + /// Set the language for messages. + inline void setLanguage(CoinMessages::Language language) {newLanguage(language);} + + /// Return the message handler + inline CoinMessageHandler * messageHandler() const {return handler_;} + + /// Return the messages + inline CoinMessages messages() {return messages_;} + /// Return the messages pointer + inline CoinMessages * messagesPointer() {return & messages_;} +//@} + +protected: + /// Problem name + char * problemName_; + + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the message handler is the default handler. + + If true, the handler will be destroyed when the CoinMpsIO + object is destroyed; if false, it will not be destroyed. + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + + /// Number of rows + int numberRows_; + + /// Number of columns + int numberColumns_; + + /// Number of elements + int numberElements_; + + /// Pointer to column-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByColumn_; + + /// Pointer to row-wise copy of problem matrix coefficients. + CoinPackedMatrix *matrixByRow_; + + /// Pointer to dense vector of row lower bounds + double * rowlower_; + + /// Pointer to dense vector of row upper bounds + double * rowupper_; + + /// Pointer to dense vector of column lower bounds + double * collower_; + + /// Pointer to dense vector of column upper bounds + double * colupper_; + + /// Pointer to dense vector of row rhs + mutable double * rhs_; + + /** Pointer to dense vector of slack variable upper bounds for ranged + constraints (undefined for non-ranged constraints) + */ + mutable double *rowrange_; + + /// Pointer to dense vector of row senses + mutable char * rowsense_; + + /// Pointer to dense vector of objective coefficients + double * objective_[MAX_OBJECTIVES]; + + /// Number of objectives + int num_objectives_; + + /// Constant offset for objective value + double objectiveOffset_[MAX_OBJECTIVES]; + + /// Pointer to dense vector specifying if a variable is continuous + /// (0) or integer (1). + char * integerType_; + + /// Pointer to sets + CoinSet ** set_; + + /// Number of sets + int numberSets_; + + /// Current file name + char * fileName_; + + /// Value to use for infinity + double infinity_; + + /// Value to use for epsilon + double epsilon_; + + /// Number of monomials printed in a row + int numberAcross_; + + /// Number of decimals printed for coefficients + int decimals_; + + /// Objective function name + char *objName_[MAX_OBJECTIVES]; + + /** Row names (including objective function name) + and column names when stopHash() for the corresponding + section was last called or for initial names (deemed invalid) + read from a file.
+ section = 0 for row names, + section = 1 for column names. */ + char **previous_names_[2]; + + /// card_previous_names_[section] holds the number of entries in the vector + /// previous_names_[section]. + /// section = 0 for row names, + /// section = 1 for column names. + int card_previous_names_[2]; + + /// Row names (including objective function name) + /// and column names (linked to Hash tables). + /// section = 0 for row names, + /// section = 1 for column names. + char **names_[2]; + + typedef struct { + int index, next; + } CoinHashLink; + + /// Maximum number of entries in a hash table section. + /// section = 0 for row names, + /// section = 1 for column names. + int maxHash_[2]; + + /// Number of entries in a hash table section. + /// section = 0 for row names, + /// section = 1 for column names. + int numberHash_[2]; + + /// Hash tables with two sections. + /// section = 0 for row names (including objective function name), + /// section = 1 for column names. + mutable CoinHashLink *hash_[2]; + + /// Build the hash table for the given names. The parameter number is + /// the cardinality of parameter names. Remove duplicate names. + /// + /// section = 0 for row names, + /// section = 1 for column names. + void startHash(char const * const * const names, + const COINColumnIndex number, + int section); + + /// Delete hash storage. If section = 0, it also frees objName_. + /// section = 0 for row names, + /// section = 1 for column names. + void stopHash(int section); + + /// Return the index of the given name, return -1 if the name is not found. + /// Return getNumRows() for the objective function name. + /// section = 0 for row names (including objective function name), + /// section = 1 for column names. + COINColumnIndex findHash(const char *name, int section) const; + + /// Insert thisName in the hash table if not present yet; does nothing + /// if the name is already in. + /// section = 0 for row names, + /// section = 1 for column names. + void insertHash(const char *thisName, int section); + + /// Write a coefficient. + /// print_1 = 0 : do not print the value 1. + void out_coeff(FILE *fp, double v, int print_1) const; + + /// Locate the objective function. + /// Return 1 if found the keyword "Minimize" or one of its variants, + /// -1 if found keyword "Maximize" or one of its variants. + int find_obj(FILE *fp) const; + + /// Return an integer indicating if the keyword "subject to" or one + /// of its variants has been read. + /// Return 1 if buff is the keyword "s.t" or one of its variants. + /// Return 2 if buff is the keyword "subject" or one of its variants. + /// Return 0 otherwise. + int is_subject_to(const char *buff) const; + + /// Return 1 if the first character of buff is a number. + /// Return 0 otherwise. + int first_is_number(const char *buff) const; + + /// Return 1 if the first character of buff is '/' or '\'. + /// Return 0 otherwise. + int is_comment(const char *buff) const; + + /// Read the file fp until buff contains an end of line + void skip_comment(char *buff, FILE *fp) const; + + /// Put in buff the next string that is not part of a comment + void scan_next(char *buff, FILE *fp) const; + + /// Return 1 if buff is the keyword "free" or one of its variants. + /// Return 0 otherwise. + int is_free(const char *buff) const; + + /// Return 1 if buff is the keyword "inf" or one of its variants. + /// Return 0 otherwise. + int is_inf(const char *buff) const; + + /// Return an integer indicating the inequality sense read. + /// Return 0 if buff is '<='. + /// Return 1 if buff is '='. + /// Return 2 if buff is '>='. + /// Return -1 otherwise. + int is_sense(const char *buff) const; + + /// Return an integer indicating if one of the keywords "Bounds", "Integers", + /// "Generals", "Binaries", "Semi-continuous", "Sos", "End", or one + /// of their variants has been read. (note Semi-continuous not coded) + /// Return 1 if buff is the keyword "Bounds" or one of its variants. + /// Return 2 if buff is the keyword "Integers" or "Generals" or one of their + /// variants. + /// Return 3 if buff is the keyword "Binaries" or one of its variants. + /// Return 4 if buff is the keyword "Semi-continuous" or one of its variants. + /// Return 5 if buff is the keyword "Sos" or one of its variants. + /// Return 6 if buff is the keyword "End" or one of its variants. + /// Return 0 otherwise. + int is_keyword(const char *buff) const; + + /// Read a monomial of the objective function. + /// Return 1 if "subject to" or one of its variants has been read. + int read_monom_obj(FILE *fp, double *coeff, char **name, int *cnt, + char **obj_name, int *num_objectives, int *obj_starts); + + /// Read a monomial of a constraint. + /// Return a positive number if the sense of the inequality has been + /// read (see method is_sense() for the return code). + /// Return -1 otherwise. + int read_monom_row(FILE *fp, char *start_str, double *coeff, char **name, + int cnt_coeff) const; + + /// Reallocate vectors related to number of coefficients. + void realloc_coeff(double **coeff, char ***colNames, int *maxcoeff) const; + + /// Reallocate vectors related to rows. + void realloc_row(char ***rowNames, int **start, double **rhs, + double **rowlow, double **rowup, int *maxrow) const; + + /// Reallocate vectors related to columns. + void realloc_col(double **collow, double **colup, char **is_int, + int *maxcol) const; + + /// Read a constraint. + void read_row(FILE *fp, char *buff, double **pcoeff, char ***pcolNames, + int *cnt_coeff, int *maxcoeff, + double *rhs, double *rowlow, double *rowup, + int *cnt_row, double inf) const; + + /** Check that current objective name and all row names are distinct + including row names obtained by adding "_low" for ranged constraints. + If there is a conflict in the names, they are replaced by default + row names (see setDefaultRowNames()). + + This method must not be called before + setLpDataWithoutRowAndColNames() has been called, since access + to the indices of all the ranged constraints is required. + + This method must not be called before + setLpDataRowAndColNames() has been called, since access + to all the row names is required. + */ + void checkRowNames(); + + /** Check that current column names are distinct. + If not, they are replaced by default + column names (see setDefaultColNames()). + + This method must not be called before + setLpDataRowAndColNames() has been called, since access + to all the column names is required. + */ + void checkColNames(); + +}; + +void +CoinLpIOUnitTest(const std::string& lpDir); + + +#endif diff --git a/thirdparty/linux/include/coin/CoinMessage.hpp b/thirdparty/linux/include/coin/CoinMessage.hpp new file mode 100644 index 0000000..cfdcd49 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinMessage.hpp @@ -0,0 +1,96 @@ +/* $Id: CoinMessage.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMessage_H +#define CoinMessage_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +/*! \file + + This file contains the enum for the standard set of Coin messages and a + class definition whose sole purpose is to supply a constructor. The text + ot the messages is defined in CoinMessage.cpp, + + CoinMessageHandler.hpp contains the generic facilities for message + handling. +*/ + +#include "CoinMessageHandler.hpp" + +/*! \brief Symbolic names for the standard set of COIN messages */ + +enum COIN_Message +{ + COIN_MPS_LINE=0, + COIN_MPS_STATS, + COIN_MPS_ILLEGAL, + COIN_MPS_BADIMAGE, + COIN_MPS_DUPOBJ, + COIN_MPS_DUPROW, + COIN_MPS_NOMATCHROW, + COIN_MPS_NOMATCHCOL, + COIN_MPS_FILE, + COIN_MPS_BADFILE1, + COIN_MPS_BADFILE2, + COIN_MPS_EOF, + COIN_MPS_RETURNING, + COIN_MPS_CHANGED, + COIN_SOLVER_MPS, + COIN_PRESOLVE_COLINFEAS, + COIN_PRESOLVE_ROWINFEAS, + COIN_PRESOLVE_COLUMNBOUNDA, + COIN_PRESOLVE_COLUMNBOUNDB, + COIN_PRESOLVE_NONOPTIMAL, + COIN_PRESOLVE_STATS, + COIN_PRESOLVE_INFEAS, + COIN_PRESOLVE_UNBOUND, + COIN_PRESOLVE_INFEASUNBOUND, + COIN_PRESOLVE_INTEGERMODS, + COIN_PRESOLVE_POSTSOLVE, + COIN_PRESOLVE_NEEDS_CLEANING, + COIN_PRESOLVE_PASS, +# if PRESOLVE_DEBUG + COIN_PRESOLDBG_FIRSTCHECK, + COIN_PRESOLDBG_RCOSTACC, + COIN_PRESOLDBG_RCOSTSTAT, + COIN_PRESOLDBG_STATSB, + COIN_PRESOLDBG_DUALSTAT, +# endif + COIN_GENERAL_INFO, + COIN_GENERAL_INFO2, + COIN_GENERAL_WARNING, + COIN_DUMMY_END +}; + + +/*! \class CoinMessage + \brief The standard set of Coin messages + + This class provides convenient access to the standard set of Coin messages. + In a nutshell, it's a CoinMessages object with a constructor that + preloads the standard Coin messages. +*/ + +class CoinMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /*! \brief Constructor + + Build a CoinMessages object and load it with the standard set of + Coin messages. + */ + CoinMessage(Language language=us_en); + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinMessageHandler.hpp b/thirdparty/linux/include/coin/CoinMessageHandler.hpp new file mode 100644 index 0000000..7922630 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinMessageHandler.hpp @@ -0,0 +1,666 @@ +/* $Id: CoinMessageHandler.hpp 1514 2011-12-10 23:35:23Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMessageHandler_H +#define CoinMessageHandler_H + +#include "CoinUtilsConfig.h" +#include "CoinPragma.hpp" + +#include +#include +#include +#include + +/** \file CoinMessageHandler.hpp + \brief This is a first attempt at a message handler. + + The COIN Project is in favo(u)r of multi-language support. This implementation + of a message handler tries to make it as lightweight as possible in the sense + that only a subset of messages need to be defined --- the rest default to US + English. + + The default handler at present just prints to stdout or to a FILE pointer + + \todo + This needs to be worked over for correct operation with ISO character codes. +*/ + +/* + I (jjf) am strongly in favo(u)r of language support for an open + source project, but I have tried to make it as lightweight as + possible in the sense that only a subset of messages need to be + defined - the rest default to US English. There will be different + sets of messages for each component - so at present there is a + Clp component and a Coin component. + + Because messages are only used in a controlled environment and have no + impact on code and are tested by other tests I have included tests such + as language and derivation in other unit tests. +*/ +/* + Where there are derived classes I (jjf) have started message numbers at 1001. +*/ + + +/** \brief Class for one massaged message. + + A message consists of a text string with formatting codes (#message_), + an integer identifier (#externalNumber_) which also determines the severity + level (#severity_) of the message, and a detail (logging) level (#detail_). + + CoinOneMessage is just a container to hold this information. The + interpretation is set by CoinMessageHandler, which see. + */ + +class CoinOneMessage { + +public: + /**@name Constructors etc */ + //@{ + /** Default constructor. */ + CoinOneMessage(); + /** Normal constructor */ + CoinOneMessage(int externalNumber, char detail, + const char * message); + /** Destructor */ + ~CoinOneMessage(); + /** The copy constructor */ + CoinOneMessage(const CoinOneMessage&); + /** assignment operator. */ + CoinOneMessage& operator=(const CoinOneMessage&); + //@} + + /**@name Useful stuff */ + //@{ + /// Replace message text (e.g., text in a different language) + void replaceMessage(const char * message); + //@} + + /**@name Get and set methods */ + //@{ + /** Get message ID number */ + inline int externalNumber() const + {return externalNumber_;} + /** \brief Set message ID number + + In the default CoinMessageHandler, this number is printed in the message + prefix and is used to determine the message severity level. + */ + inline void setExternalNumber(int number) + {externalNumber_=number;} + /// Severity + inline char severity() const + {return severity_;} + /// Set detail level + inline void setDetail(int level) + {detail_=static_cast (level);} + /// Get detail level + inline int detail() const + {return detail_;} + /// Return the message text + inline char * message() const + {return message_;} + //@} + + /**@name member data */ + //@{ + /// number to print out (also determines severity) + int externalNumber_; + /// Will only print if detail matches + char detail_; + /// Severity + char severity_; + /// Messages (in correct language) (not all 400 may exist) + mutable char message_[400]; + //@} +}; + +/** \brief Class to hold and manipulate an array of massaged messages. + + Note that the message index used to reference a message in the array of + messages is completely distinct from the external ID number stored with the + message. +*/ + +class CoinMessages { + +public: + /** \brief Supported languages + + These are the languages that are supported. At present only + us_en is serious and the rest are for testing. + */ + enum Language { + us_en = 0, + uk_en, + it + }; + + /**@name Constructors etc */ + //@{ + /** Constructor with number of messages. */ + CoinMessages(int numberMessages=0); + /** Destructor */ + ~CoinMessages(); + /** The copy constructor */ + CoinMessages(const CoinMessages&); + /** assignment operator. */ + CoinMessages& operator=(const CoinMessages&); + //@} + + /**@name Useful stuff */ + //@{ + /*! \brief Installs a new message in the specified index position + + Any existing message is replaced, and a copy of the specified message is + installed. + */ + void addMessage(int messageNumber, const CoinOneMessage & message); + /*! \brief Replaces the text of the specified message + + Any existing text is deleted and the specified text is copied into the + specified message. + */ + void replaceMessage(int messageNumber, const char * message); + /** Language. Need to think about iso codes */ + inline Language language() const + {return language_;} + /** Set language */ + void setLanguage(Language newlanguage) + {language_ = newlanguage;} + /// Change detail level for one message + void setDetailMessage(int newLevel, int messageNumber); + /** \brief Change detail level for several messages + + messageNumbers is expected to contain the indices of the messages to be + changed. + If numberMessages >= 10000 or messageNumbers is NULL, the detail level + is changed on all messages. + */ + void setDetailMessages(int newLevel, int numberMessages, + int * messageNumbers); + /** Change detail level for all messages with low <= ID number < high */ + void setDetailMessages(int newLevel, int low, int high); + + /// Returns class + inline int getClass() const + { return class_;} + /// Moves to compact format + void toCompact(); + /// Moves from compact format + void fromCompact(); + //@} + + /**@name member data */ + //@{ + /// Number of messages + int numberMessages_; + /// Language + Language language_; + /// Source (null-terminated string, maximum 4 characters). + char source_[5]; + /// Class - see later on before CoinMessageHandler + int class_; + /** Length of fake CoinOneMessage array. + First you get numberMessages_ pointers which point to stuff + */ + int lengthMessages_; + /// Messages + CoinOneMessage ** message_; + //@} +}; + +// for convenience eol +enum CoinMessageMarker { + CoinMessageEol = 0, + CoinMessageNewline = 1 +}; + +/** Base class for message handling + + The default behavior is described here: messages are printed, and (if the + severity is sufficiently high) execution will be aborted. Inherit and + redefine the methods #print and #checkSeverity to augment the behaviour. + + Messages can be printed with or without a prefix; the prefix will consist + of a source string, the external ID number, and a letter code, + e.g., Clp6024W. + A prefix makes the messages look less nimble but is very useful + for "grep" etc. + +

Usage

+ + The general approach to using the COIN messaging facility is as follows: +
    +
  • Define your messages. For each message, you must supply an external + ID number, a log (detail) level, and a format string. Typically, you + define a convenience structure for this, something that's easy to + use to create an array of initialised message definitions at compile + time. +
  • Create a CoinMessages object, sized to accommodate the number of + messages you've defined. (Incremental growth will happen if + necessary as messages are loaded, but it's inefficient.) +
  • Load the messages into the CoinMessages object. Typically this + entails creating a CoinOneMessage object for each message and + passing it as a parameter to CoinMessages::addMessage(). You specify + the message's internal ID as the other parameter to addMessage. +
  • Create and use a CoinMessageHandler object to print messages. +
+ See, for example, CoinMessage.hpp and CoinMessage.cpp for an example of + the first three steps. `Format codes' below has a simple example of + printing a message. + +

External ID numbers and severity

+ + CoinMessageHandler assumes the following relationship between the + external ID number of a message and the severity of the message: + \li <3000 are informational ('I') + \li <6000 warnings ('W') + \li <9000 non-fatal errors ('E') + \li >=9000 aborts the program (after printing the message) ('S') + +

Log (detail) levels

+ + The default behaviour is that a message will print if its detail level + is less than or equal to the handler's log level. If all you want to + do is set a single log level for the handler, use #setLogLevel(int). + + If you want to get fancy, here's how it really works: There's an array, + #logLevels_, which you can manipulate with #setLogLevel(int,int). Each + entry logLevels_[i] specifies the log level for messages of class i (see + CoinMessages::class_). If logLevels_[0] is set to the magic number -1000 + you get the simple behaviour described above, whatever the class of the + messages. If logLevels_[0] is set to a valid log level (>= 0), then + logLevels_[i] really is the log level for messages of class i. + +

Format codes

+ + CoinMessageHandler can print integers (normal, long, and long long), + doubles, characters, and strings. See the descriptions of the + various << operators. + + When processing a standard message with a format string, the formatting + codes specified in the format string will be passed to the sprintf + function, along with the argument. When generating a message with no + format string, each << operator uses a simple format code appropriate for + its argument. Consult the documentation for the standard printf facility + for further information on format codes. + + The special format code `%?' provides a hook to enable or disable + printing. For each `%?' code, there must be a corresponding call to + printing(bool). This provides a way to define optional parts in + messages, delineated by the code `%?' in the format string. Printing can + be suppressed for these optional parts, but any operands must still be + supplied. For example, given the message string + \verbatim + "A message with%? an optional integer %d and%? a double %g." + \endverbatim + installed in CoinMessages \c exampleMsgs with index 5, and + \c CoinMessageHandler \c hdl, the code + \code + hdl.message(5,exampleMsgs) ; + hdl.printing(true) << 42 ; + hdl.printing(true) << 53.5 << CoinMessageEol ; + \endcode + will print + \verbatim + A message with an optional integer 42 and a double 53.5. + \endverbatim + while + \code + hdl.message(5,exampleMsgs) ; + hdl.printing(false) << 42 ; + hdl.printing(true) << 53.5 << CoinMessageEol ; + \endcode + will print + \verbatim + A message with a double 53.5. + \endverbatim + + For additional examples of usage, see CoinMessageHandlerUnitTest in + CoinMessageHandlerTest.cpp. +*/ + +class CoinMessageHandler { + +friend bool CoinMessageHandlerUnitTest () ; + +public: + /**@name Virtual methods that the derived classes may provide */ + //@{ + /** Print message, return 0 normally. + */ + virtual int print() ; + /** Check message severity - if too bad then abort + */ + virtual void checkSeverity() ; + //@} + + /**@name Constructors etc */ + //@{ + /// Constructor + CoinMessageHandler(); + /// Constructor to put to file pointer (won't be closed) + CoinMessageHandler(FILE *fp); + /** Destructor */ + virtual ~CoinMessageHandler(); + /** The copy constructor */ + CoinMessageHandler(const CoinMessageHandler&); + /** Assignment operator. */ + CoinMessageHandler& operator=(const CoinMessageHandler&); + /// Clone + virtual CoinMessageHandler * clone() const; + //@} + /**@name Get and set methods */ + //@{ + /// Get detail level of a message. + inline int detail(int messageNumber, const CoinMessages &normalMessage) const + { return normalMessage.message_[messageNumber]->detail();} + /** Get current log (detail) level. */ + inline int logLevel() const + { return logLevel_;} + /** \brief Set current log (detail) level. + + If the log level is equal or greater than the detail level of a message, + the message will be printed. A rough convention for the amount of output + expected is + - 0 - none + - 1 - minimal + - 2 - normal low + - 3 - normal high + - 4 - verbose + + Please assign log levels to messages accordingly. Log levels of 8 and + above (8,16,32, etc.) are intended for selective debugging. + The logical AND of the log level specified in the message and the current + log level is used to determine if the message is printed. (In other words, + you're using individual bits to determine which messages are printed.) + */ + void setLogLevel(int value); + /** Get alternative log level. */ + inline int logLevel(int which) const + { return logLevels_[which];} + /*! \brief Set alternative log level value. + + Can be used to store alternative log level information within the handler. + */ + void setLogLevel(int which, int value); + + /// Set the number of significant digits for printing floating point numbers + void setPrecision(unsigned int new_precision); + /// Current number of significant digits for printing floating point numbers + inline int precision() { return (g_precision_) ; } + + /// Switch message prefix on or off. + void setPrefix(bool yesNo); + /// Current setting for printing message prefix. + bool prefix() const; + /*! \brief Values of double fields already processed. + + As the parameter for a double field is processed, the value is saved + and can be retrieved using this function. + */ + inline double doubleValue(int position) const + { return doubleValue_[position];} + /*! \brief Number of double fields already processed. + + Incremented each time a field of type double is processed. + */ + inline int numberDoubleFields() const + {return static_cast(doubleValue_.size());} + /*! \brief Values of integer fields already processed. + + As the parameter for a integer field is processed, the value is saved + and can be retrieved using this function. + */ + inline int intValue(int position) const + { return longValue_[position];} + /*! \brief Number of integer fields already processed. + + Incremented each time a field of type integer is processed. + */ + inline int numberIntFields() const + {return static_cast(longValue_.size());} + /*! \brief Values of char fields already processed. + + As the parameter for a char field is processed, the value is saved + and can be retrieved using this function. + */ + inline char charValue(int position) const + { return charValue_[position];} + /*! \brief Number of char fields already processed. + + Incremented each time a field of type char is processed. + */ + inline int numberCharFields() const + {return static_cast(charValue_.size());} + /*! \brief Values of string fields already processed. + + As the parameter for a string field is processed, the value is saved + and can be retrieved using this function. + */ + inline std::string stringValue(int position) const + { return stringValue_[position];} + /*! \brief Number of string fields already processed. + + Incremented each time a field of type string is processed. + */ + inline int numberStringFields() const + {return static_cast(stringValue_.size());} + + /// Current message + inline CoinOneMessage currentMessage() const + {return currentMessage_;} + /// Source of current message + inline std::string currentSource() const + {return source_;} + /// Output buffer + inline const char * messageBuffer() const + {return messageBuffer_;} + /// Highest message number (indicates any errors) + inline int highestNumber() const + {return highestNumber_;} + /// Get current file pointer + inline FILE * filePointer() const + { return fp_;} + /// Set new file pointer + inline void setFilePointer(FILE * fp) + { fp_ = fp;} + //@} + + /**@name Actions to create a message */ + //@{ + /*! \brief Start a message + + Look up the specified message. A prefix will be generated if enabled. + The message will be printed if the current log level is equal or greater + than the log level of the message. + */ + CoinMessageHandler &message(int messageNumber, + const CoinMessages &messages) ; + + /*! \brief Start or continue a message + + With detail = -1 (default), does nothing except return a reference to the + handler. (I.e., msghandler.message() << "foo" is precisely equivalent + to msghandler << "foo".) If \p msgDetail is >= 0, is will be used + as the detail level to determine whether the message should print + (assuming class 0). + + This can be used with any of the << operators. One use is to start + a message which will be constructed entirely from scratch. Another + use is continuation of a message after code that interrupts the usual + sequence of << operators. + */ + CoinMessageHandler & message(int detail = -1) ; + + /*! \brief Print a complete message + + Generate a standard prefix and append \c msg `as is'. This is intended as + a transition mechanism. The standard prefix is generated (if enabled), + and \c msg is appended. The message must be ended with a CoinMessageEol + marker. Attempts to add content with << will have no effect. + + The default value of \p detail will not change printing status. If + \p detail is >= 0, it will be used as the detail level to determine + whether the message should print (assuming class 0). + + */ + CoinMessageHandler &message(int externalNumber, const char *source, + const char *msg, + char severity, int detail = -1) ; + + /*! \brief Process an integer parameter value. + + The default format code is `%d'. + */ + CoinMessageHandler & operator<< (int intvalue); +#if COIN_BIG_INDEX==1 + /*! \brief Process a long integer parameter value. + + The default format code is `%ld'. + */ + CoinMessageHandler & operator<< (long longvalue); +#endif +#if COIN_BIG_INDEX==2 + /*! \brief Process a long long integer parameter value. + + The default format code is `%ld'. + */ + CoinMessageHandler & operator<< (long long longvalue); +#endif + /*! \brief Process a double parameter value. + + The default format code is `%d'. + */ + CoinMessageHandler & operator<< (double doublevalue); + /*! \brief Process a STL string parameter value. + + The default format code is `%g'. + */ + CoinMessageHandler & operator<< (const std::string& stringvalue); + /*! \brief Process a char parameter value. + + The default format code is `%s'. + */ + CoinMessageHandler & operator<< (char charvalue); + /*! \brief Process a C-style string parameter value. + + The default format code is `%c'. + */ + CoinMessageHandler & operator<< (const char *stringvalue); + /*! \brief Process a marker. + + The default format code is `%s'. + */ + CoinMessageHandler & operator<< (CoinMessageMarker); + /** Finish (and print) the message. + + Equivalent to using the CoinMessageEol marker. + */ + int finish(); + /*! \brief Enable or disable printing of an optional portion of a message. + + Optional portions of a message are delimited by `%?' markers, and + printing processes one %? marker. If \c onOff is true, the subsequent + portion of the message (to the next %? marker or the end of the format + string) will be printed. If \c onOff is false, printing is suppressed. + Parameters must still be supplied, whether printing is suppressed or not. + See the class documentation for an example. + */ + CoinMessageHandler & printing(bool onOff); + + //@} + + /** Log levels will be by type and will then use type + given in CoinMessage::class_ + + - 0 - Branch and bound code or similar + - 1 - Solver + - 2 - Stuff in Coin directory + - 3 - Cut generators + */ +#define COIN_NUM_LOG 4 +/// Maximum length of constructed message (characters) +#define COIN_MESSAGE_HANDLER_MAX_BUFFER_SIZE 1000 +protected: + /**@name Protected member data */ + //@{ + /// values in message + std::vector doubleValue_; + std::vector longValue_; + std::vector charValue_; + std::vector stringValue_; + /// Log level + int logLevel_; + /// Log levels + int logLevels_[COIN_NUM_LOG]; + /// Whether we want prefix (may get more subtle so is int) + int prefix_; + /// Current message + CoinOneMessage currentMessage_; + /// Internal number for use with enums + int internalNumber_; + /// Format string for message (remainder) + char * format_; + /// Output buffer + char messageBuffer_[COIN_MESSAGE_HANDLER_MAX_BUFFER_SIZE]; + /// Position in output buffer + char * messageOut_; + /// Current source of message + std::string source_; + /** 0 - Normal. + 1 - Put in values, move along format, but don't print. + 2 - A complete message was provided; nothing more to do but print + when CoinMessageEol is processed. Any << operators are treated + as noops. + 3 - do nothing except look for CoinMessageEol (i.e., the message + detail level was not sufficient to cause it to print). + */ + int printStatus_; + /// Highest message number (indicates any errors) + int highestNumber_; + /// File pointer + FILE * fp_; + /// Current format for floating point numbers + char g_format_[8]; + /// Current number of significant digits for floating point numbers + int g_precision_ ; + //@} + +private: + + /** The body of the copy constructor and the assignment operator */ + void gutsOfCopy(const CoinMessageHandler &rhs) ; + + /*! \brief Internal function to locate next format code. + + Intended for internal use. Side effects modify the format string. + */ + char *nextPerCent(char *start, const bool initial = false) ; + + /*! \brief Internal printing function. + + Makes it easier to split up print into clean, print and check severity + */ + int internalPrint() ; + + /// Decide if this message should print. + void calcPrintStatus(int msglvl, int msgclass) ; + + +}; + +//############################################################################# +/** A function that tests the methods in the CoinMessageHandler class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +bool +CoinMessageHandlerUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin/CoinModel.hpp b/thirdparty/linux/include/coin/CoinModel.hpp new file mode 100644 index 0000000..6d1ff5b --- /dev/null +++ b/thirdparty/linux/include/coin/CoinModel.hpp @@ -0,0 +1,1054 @@ +/* $Id: CoinModel.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinModel_H +#define CoinModel_H + +#include "CoinModelUseful.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinFinite.hpp" +class CoinBaseModel { + +public: + + + /**@name Constructors, destructor */ + //@{ + /// Default Constructor + CoinBaseModel (); + + /// Copy constructor + CoinBaseModel ( const CoinBaseModel &rhs); + + /// Assignment operator + CoinBaseModel & operator=( const CoinBaseModel& rhs); + + /// Clone + virtual CoinBaseModel * clone() const=0; + + /// Destructor + virtual ~CoinBaseModel () ; + //@} + + /**@name For getting information */ + //@{ + /// Return number of rows + inline int numberRows() const + { return numberRows_;} + /// Return number of columns + inline int numberColumns() const + { return numberColumns_;} + /// Return number of elements + virtual CoinBigIndex numberElements() const = 0; + /** Returns the (constant) objective offset + This is the RHS entry for the objective row + */ + inline double objectiveOffset() const + { return objectiveOffset_;} + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_=value;} + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + /// Get print level 0 - off, 1 - errors, 2 - more + inline int logLevel() const + { return logLevel_;} + /// Set print level 0 - off, 1 - errors, 2 - more + void setLogLevel(int value); + /// Return the problem name + inline const char * getProblemName() const + { return problemName_.c_str();} + /// Set problem name + void setProblemName(const char *name) ; + /// Set problem name + void setProblemName(const std::string &name) ; + /// Return the row block name + inline const std::string & getRowBlock() const + { return rowBlockName_;} + /// Set row block name + inline void setRowBlock(const std::string &name) + { rowBlockName_ = name;} + /// Return the column block name + inline const std::string & getColumnBlock() const + { return columnBlockName_;} + /// Set column block name + inline void setColumnBlock(const std::string &name) + { columnBlockName_ = name;} + /// Pass in message handler + void setMessageHandler(CoinMessageHandler * handler); + //@} + +protected: + /**@name Data members */ + //@{ + /// Current number of rows + int numberRows_; + /// Current number of columns + int numberColumns_; + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + double optimizationDirection_; + /// Objective offset to be passed on + double objectiveOffset_; + /// Problem name + std::string problemName_; + /// Rowblock name + std::string rowBlockName_; + /// Columnblock name + std::string columnBlockName_; + /// Message handler (Passed in) + CoinMessageHandler * handler_; + /// Messages + CoinMessages messages_; + + /** Print level. + I could have gone for full message handling but this should normally + be silent and lightweight. + -1 - use passed in message handler + 0 - no output + 1 - on errors + 2 - more detailed + */ + int logLevel_; + //@} + /// data + +}; + +/** + This is a simple minded model which is stored in a format which makes + it easier to construct and modify but not efficient for algorithms. It has + to be passed across to ClpModel or OsiSolverInterface by addRows, addCol(umn)s + or loadProblem. + + It may have up to four parts - + 1) A matrix of doubles (or strings - see note A) + 2) Column information including integer information and names + 3) Row information including names + 4) Quadratic objective (not implemented - but see A) + + This class is meant to make it more efficient to build a model. It is at + its most efficient when all additions are done as addRow or as addCol but + not mixed. If only 1 and 2 exist then solver.addColumns may be used to pass to solver, + if only 1 and 3 exist then solver.addRows may be used. Otherwise solver.loadProblem + must be used. + + If addRows and addColumns are mixed or if individual elements are set then the + speed will drop to some extent and more memory will be used. + + It is also possible to iterate over existing elements and to access columns and rows + by name. Again each of these use memory and cpu time. However memory is unlikely + to be critical as most algorithms will use much more. + + Notes: + A) Although this could be used to pass nonlinear information around the + only use at present is to have named values e.g. value1 which can then be + set to a value after model is created. I have no idea whether that could + be useful but I thought it might be fun. + Quadratic terms are allowed in strings! A solver could try and use this + if so - the convention is that 0.5* quadratic is stored + + B) This class could be useful for modeling. +*/ + +class CoinModel : public CoinBaseModel { + +public: + /**@name Useful methods for building model */ + //@{ + /** add a row - numberInRow may be zero */ + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower=-COIN_DBL_MAX, + double rowUpper=COIN_DBL_MAX, const char * name=NULL); + /// add a column - numberInColumn may be zero */ + void addColumn(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0, + const char * name=NULL, bool isInteger=false); + /// add a column - numberInColumn may be zero */ + inline void addCol(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0, + const char * name=NULL, bool isInteger=false) + { addColumn(numberInColumn, rows, elements, columnLower, columnUpper, objectiveValue, + name,isInteger);} + /// Sets value for row i and column j + inline void operator() (int i,int j,double value) + { setElement(i,j,value);} + /// Sets value for row i and column j + void setElement(int i,int j,double value) ; + /** Gets sorted row - user must provide enough space + (easiest is allocate number of columns). + If column or element NULL then just returns number + Returns number of elements + */ + int getRow(int whichRow, int * column, double * element); + /** Gets sorted column - user must provide enough space + (easiest is allocate number of rows). + If row or element NULL then just returns number + Returns number of elements + */ + int getColumn(int whichColumn, int * column, double * element); + /// Sets quadratic value for column i and j + void setQuadraticElement(int i,int j,double value) ; + /// Sets value for row i and column j as string + inline void operator() (int i,int j,const char * value) + { setElement(i,j,value);} + /// Sets value for row i and column j as string + void setElement(int i,int j,const char * value) ; + /// Associates a string with a value. Returns string id (or -1 if does not exist) + int associateElement(const char * stringValue, double value); + /** Sets rowLower (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowLower(int whichRow,double rowLower); + /** Sets rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowUpper(int whichRow,double rowUpper); + /** Sets rowLower and rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowBounds(int whichRow,double rowLower,double rowUpper); + /** Sets name (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowName(int whichRow,const char * rowName); + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnLower(int whichColumn,double columnLower); + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnUpper(int whichColumn,double columnUpper); + /** Sets columnLower and columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnBounds(int whichColumn,double columnLower,double columnUpper); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnObjective(int whichColumn,double columnObjective); + /** Sets name (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnName(int whichColumn,const char * columnName); + /** Sets integer state (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnIsInteger(int whichColumn,bool columnIsInteger); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setObjective(int whichColumn,double columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets integer state (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setIsInteger(int whichColumn,bool columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setInteger(int whichColumn) + { setColumnIsInteger( whichColumn, true);} + /** Sets continuous (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setContinuous(int whichColumn) + { setColumnIsInteger( whichColumn, false);} + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColLower(int whichColumn,double columnLower) + { setColumnLower( whichColumn, columnLower);} + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColUpper(int whichColumn,double columnUpper) + { setColumnUpper( whichColumn, columnUpper);} + /** Sets columnLower and columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColBounds(int whichColumn,double columnLower,double columnUpper) + { setColumnBounds( whichColumn, columnLower, columnUpper);} + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColObjective(int whichColumn,double columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets name (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColName(int whichColumn,const char * columnName) + { setColumnName( whichColumn, columnName);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColIsInteger(int whichColumn,bool columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Sets rowLower (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowLower(int whichRow,const char * rowLower); + /** Sets rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowUpper(int whichRow,const char * rowUpper); + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnLower(int whichColumn,const char * columnLower); + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnUpper(int whichColumn,const char * columnUpper); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnObjective(int whichColumn,const char * columnObjective); + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnIsInteger(int whichColumn,const char * columnIsInteger); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setObjective(int whichColumn,const char * columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setIsInteger(int whichColumn,const char * columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Deletes all entries in row and bounds. Will be ignored by + writeMps etc and will be packed down if asked for. */ + void deleteRow(int whichRow); + /** Deletes all entries in column and bounds and objective. Will be ignored by + writeMps etc and will be packed down if asked for. */ + void deleteColumn(int whichColumn); + /** Deletes all entries in column and bounds. If last column the number of columns + will be decremented and true returned. */ + inline void deleteCol(int whichColumn) + { deleteColumn(whichColumn);} + /// Takes element out of matrix - returning position (<0 if not there); + int deleteElement(int row, int column); + /// Takes element out of matrix when position known + void deleteThisElement(int row, int column,int position); + /** Packs down all rows i.e. removes empty rows permanently. Empty rows + have no elements and feasible bounds. returns number of rows deleted. */ + int packRows(); + /** Packs down all columns i.e. removes empty columns permanently. Empty columns + have no elements and no objective. returns number of columns deleted. */ + int packColumns(); + /** Packs down all columns i.e. removes empty columns permanently. Empty columns + have no elements and no objective. returns number of columns deleted. */ + inline int packCols() + { return packColumns();} + /** Packs down all rows and columns. i.e. removes empty rows and columns permanently. + Empty rows have no elements and feasible bounds. + Empty columns have no elements and no objective. + returns number of rows+columns deleted. */ + int pack(); + + /** Sets columnObjective array + */ + void setObjective(int numberColumns,const double * objective) ; + /** Sets columnLower array + */ + void setColumnLower(int numberColumns,const double * columnLower); + /** Sets columnLower array + */ + inline void setColLower(int numberColumns,const double * columnLower) + { setColumnLower( numberColumns, columnLower);} + /** Sets columnUpper array + */ + void setColumnUpper(int numberColumns,const double * columnUpper); + /** Sets columnUpper array + */ + inline void setColUpper(int numberColumns,const double * columnUpper) + { setColumnUpper( numberColumns, columnUpper);} + /** Sets rowLower array + */ + void setRowLower(int numberRows,const double * rowLower); + /** Sets rowUpper array + */ + void setRowUpper(int numberRows,const double * rowUpper); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written +
    +
  • 0: plain text (default) +
  • 1: gzip compressed (.gz is appended to \c filename) +
  • 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) +
+ If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file +
    +
  • 0: normal precision (default) +
  • 1: extra accuracy +
  • 2: IEEE hex +
+ + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + not const as may change model e.g. fill in default bounds + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; + + /** Check two models against each other. Return nonzero if different. + Ignore names if that set. + May modify both models by cleaning up + */ + int differentModel(CoinModel & other, bool ignoreNames); + //@} + + + /**@name For structured models */ + //@{ + /// Pass in CoinPackedMatrix (and switch off element updates) + void passInMatrix(const CoinPackedMatrix & matrix); + /** Convert elements to CoinPackedMatrix (and switch off element updates). + Returns number of errors */ + int convertMatrix(); + /// Return a pointer to CoinPackedMatrix (or NULL) + inline const CoinPackedMatrix * packedMatrix() const + { return packedMatrix_;} + /// Return pointers to original rows (for decomposition) + inline const int * originalRows() const + { return rowType_;} + /// Return pointers to original columns (for decomposition) + inline const int * originalColumns() const + { return columnType_;} + //@} + + + /**@name For getting information */ + //@{ + /// Return number of elements + inline CoinBigIndex numberElements() const + { return numberElements_;} + /// Return elements as triples + inline const CoinModelTriple * elements() const + { return elements_;} + /// Returns value for row i and column j + inline double operator() (int i,int j) const + { return getElement(i,j);} + /// Returns value for row i and column j + double getElement(int i,int j) const; + /// Returns value for row rowName and column columnName + inline double operator() (const char * rowName,const char * columnName) const + { return getElement(rowName,columnName);} + /// Returns value for row rowName and column columnName + double getElement(const char * rowName,const char * columnName) const; + /// Returns quadratic value for columns i and j + double getQuadraticElement(int i,int j) const; + /** Returns value for row i and column j as string. + Returns NULL if does not exist. + Returns "Numeric" if not a string + */ + const char * getElementAsString(int i,int j) const; + /** Returns pointer to element for row i column j. + Only valid until next modification. + NULL if element does not exist */ + double * pointer (int i,int j) const; + /** Returns position in elements for row i column j. + Only valid until next modification. + -1 if element does not exist */ + int position (int i,int j) const; + + + /** Returns first element in given row - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink firstInRow(int whichRow) const ; + /** Returns last element in given row - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInRow(int whichRow) const ; + /** Returns first element in given column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink firstInColumn(int whichColumn) const ; + /** Returns last element in given column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInColumn(int whichColumn) const ; + /** Returns next element in current row or column - index is -1 if none. + Index is given by .index and value by .value. + User could also tell because input.next would be NULL + */ + CoinModelLink next(CoinModelLink & current) const ; + /** Returns previous element in current row or column - index is -1 if none. + Index is given by .index and value by .value. + User could also tell because input.previous would be NULL + May not be correct if matrix updated. + */ + CoinModelLink previous(CoinModelLink & current) const ; + /** Returns first element in given quadratic column - index is -1 if none. + Index is given by .index and value by .value + May not be correct if matrix updated. + */ + CoinModelLink firstInQuadraticColumn(int whichColumn) const ; + /** Returns last element in given quadratic column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInQuadraticColumn(int whichColumn) const ; + /** Gets rowLower (if row does not exist then -COIN_DBL_MAX) + */ + double getRowLower(int whichRow) const ; + /** Gets rowUpper (if row does not exist then +COIN_DBL_MAX) + */ + double getRowUpper(int whichRow) const ; + /** Gets name (if row does not exist then NULL) + */ + const char * getRowName(int whichRow) const ; + inline double rowLower(int whichRow) const + { return getRowLower(whichRow);} + /** Gets rowUpper (if row does not exist then COIN_DBL_MAX) + */ + inline double rowUpper(int whichRow) const + { return getRowUpper(whichRow) ;} + /** Gets name (if row does not exist then NULL) + */ + inline const char * rowName(int whichRow) const + { return getRowName(whichRow);} + /** Gets columnLower (if column does not exist then 0.0) + */ + double getColumnLower(int whichColumn) const ; + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + double getColumnUpper(int whichColumn) const ; + /** Gets columnObjective (if column does not exist then 0.0) + */ + double getColumnObjective(int whichColumn) const ; + /** Gets name (if column does not exist then NULL) + */ + const char * getColumnName(int whichColumn) const ; + /** Gets if integer (if column does not exist then false) + */ + bool getColumnIsInteger(int whichColumn) const ; + /** Gets columnLower (if column does not exist then 0.0) + */ + inline double columnLower(int whichColumn) const + { return getColumnLower(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline double columnUpper(int whichColumn) const + { return getColumnUpper(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double columnObjective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double objective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets name (if column does not exist then NULL) + */ + inline const char * columnName(int whichColumn) const + { return getColumnName(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool columnIsInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool isInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets columnLower (if column does not exist then 0.0) + */ + inline double getColLower(int whichColumn) const + { return getColumnLower(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline double getColUpper(int whichColumn) const + { return getColumnUpper(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double getColObjective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets name (if column does not exist then NULL) + */ + inline const char * getColName(int whichColumn) const + { return getColumnName(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool getColIsInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets rowLower (if row does not exist then -COIN_DBL_MAX) + */ + const char * getRowLowerAsString(int whichRow) const ; + /** Gets rowUpper (if row does not exist then +COIN_DBL_MAX) + */ + const char * getRowUpperAsString(int whichRow) const ; + inline const char * rowLowerAsString(int whichRow) const + { return getRowLowerAsString(whichRow);} + /** Gets rowUpper (if row does not exist then COIN_DBL_MAX) + */ + inline const char * rowUpperAsString(int whichRow) const + { return getRowUpperAsString(whichRow) ;} + /** Gets columnLower (if column does not exist then 0.0) + */ + const char * getColumnLowerAsString(int whichColumn) const ; + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + const char * getColumnUpperAsString(int whichColumn) const ; + /** Gets columnObjective (if column does not exist then 0.0) + */ + const char * getColumnObjectiveAsString(int whichColumn) const ; + /** Gets if integer (if column does not exist then false) + */ + const char * getColumnIsIntegerAsString(int whichColumn) const ; + /** Gets columnLower (if column does not exist then 0.0) + */ + inline const char * columnLowerAsString(int whichColumn) const + { return getColumnLowerAsString(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline const char * columnUpperAsString(int whichColumn) const + { return getColumnUpperAsString(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline const char * columnObjectiveAsString(int whichColumn) const + { return getColumnObjectiveAsString(whichColumn);} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline const char * objectiveAsString(int whichColumn) const + { return getColumnObjectiveAsString(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline const char * columnIsIntegerAsString(int whichColumn) const + { return getColumnIsIntegerAsString(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline const char * isIntegerAsString(int whichColumn) const + { return getColumnIsIntegerAsString(whichColumn);} + /// Row index from row name (-1 if no names or no match) + int row(const char * rowName) const; + /// Column index from column name (-1 if no names or no match) + int column(const char * columnName) const; + /// Returns type + inline int type() const + { return type_;} + /// returns unset value + inline double unsetValue() const + { return -1.23456787654321e-97;} + /// Creates a packed matrix - return number of errors + int createPackedMatrix(CoinPackedMatrix & matrix, + const double * associated); + /** Fills in startPositive and startNegative with counts for +-1 matrix. + If not +-1 then startPositive[0]==-1 otherwise counts and + startPositive[numberColumns]== size + - return number of errors + */ + int countPlusMinusOne(CoinBigIndex * startPositive, CoinBigIndex * startNegative, + const double * associated); + /** Creates +-1 matrix given startPositive and startNegative counts for +-1 matrix. + */ + void createPlusMinusOne(CoinBigIndex * startPositive, CoinBigIndex * startNegative, + int * indices, + const double * associated); + /// Creates copies of various arrays - return number of errors + int createArrays(double * & rowLower, double * & rowUpper, + double * & columnLower, double * & columnUpper, + double * & objective, int * & integerType, + double * & associated); + /// Says if strings exist + inline bool stringsExist() const + { return string_.numberItems()!=0;} + /// Return string array + inline const CoinModelHash * stringArray() const + { return &string_;} + /// Returns associated array + inline double * associatedArray() const + { return associated_;} + /// Return rowLower array + inline double * rowLowerArray() const + { return rowLower_;} + /// Return rowUpper array + inline double * rowUpperArray() const + { return rowUpper_;} + /// Return columnLower array + inline double * columnLowerArray() const + { return columnLower_;} + /// Return columnUpper array + inline double * columnUpperArray() const + { return columnUpper_;} + /// Return objective array + inline double * objectiveArray() const + { return objective_;} + /// Return integerType array + inline int * integerTypeArray() const + { return integerType_;} + /// Return row names array + inline const CoinModelHash * rowNames() const + { return &rowName_;} + /// Return column names array + inline const CoinModelHash * columnNames() const + { return &columnName_;} + /// Reset row names + inline void zapRowNames() + { rowName_=CoinModelHash();} + /// Reset column names + inline void zapColumnNames() + { columnName_=CoinModelHash();} + /// Returns array of 0 or nonzero if can be a cut (or returns NULL) + inline const int * cutMarker() const + { return cut_;} + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + /// Return pointer to more information + inline void * moreInfo() const + { return moreInfo_;} + /// Set pointer to more information + inline void setMoreInfo(void * info) + { moreInfo_ = info;} + /** Returns which parts of model are set + 1 - matrix + 2 - rhs + 4 - row names + 8 - column bounds and/or objective + 16 - column names + 32 - integer types + */ + int whatIsSet() const; + //@} + + /**@name for block models - matrix will be CoinPackedMatrix */ + //@{ + /*! \brief Load in a problem by copying the arguments. The constraints on + the rows are given by lower and upper bounds. + + If a pointer is 0 then the following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • rowub: all rows have upper bound infinity +
  • rowlb: all rows have lower bound -infinity +
  • obj: all variables have 0 objective coefficient +
+ + Note that the default values for rowub and rowlb produce the + constraint -infty <= ax <= infty. This is probably not what you want. + */ + void loadBlock (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + /*! \brief Load in a problem by copying the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + If a pointer is 0 then the following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • obj: all variables have 0 objective coefficient +
  • rowsen: all rows are >= +
  • rowrhs: all right hand sides are 0 +
  • rowrng: 0 for the ranged rows +
+ + Note that the default values for rowsen, rowrhs, and rowrng produce the + constraint ax >= 0. + */ + void loadBlock (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) ; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by lower and upper bounds. + + The matrix vectors must be gap-free. Note that start must + have numcols+1 entries so that the length of the last column + can be calculated as start[numcols]-start[numcols-1]. + + See the previous loadBlock method using rowlb and rowub for default + argument values. + */ + void loadBlock (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by sense/rhs/range triplets. + + The matrix vectors must be gap-free. Note that start must + have numcols+1 entries so that the length of the last column + can be calculated as start[numcols]-start[numcols-1]. + + See the previous loadBlock method using sense/rhs/range for default + argument values. + */ + void loadBlock (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) ; + + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModel(); + /** Constructor with sizes. */ + CoinModel(int firstRows, int firstColumns, int firstElements,bool noNames=false); + /** Read a problem in MPS or GAMS format from the given filename. + */ + CoinModel(const char *fileName, int allowStrings=0); + /** Read a problem from AMPL nl file + NOTE - as I can't work out configure etc the source code is in Cbc_ampl.cpp! + */ + CoinModel( int nonLinear, const char * fileName,const void * info); + /// From arrays + CoinModel(int numberRows, int numberColumns, + const CoinPackedMatrix * matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective); + /// Clone + virtual CoinBaseModel * clone() const; + + /** Destructor */ + virtual ~CoinModel(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModel(const CoinModel&); + /// = + CoinModel& operator=(const CoinModel&); + //@} + + /**@name For debug */ + //@{ + /// Checks that links are consistent + void validateLinks() const; + //@} +private: + /// Resize + void resize(int maximumRows, int maximumColumns, int maximumElements); + /// Fill in default row information + void fillRows(int which,bool forceCreation,bool fromAddRow=false); + /// Fill in default column information + void fillColumns(int which,bool forceCreation,bool fromAddColumn=false); + /** Fill in default linked list information (1= row, 2 = column) + Marked as const as list is mutable */ + void fillList(int which, CoinModelLinkedList & list,int type) const ; + /** Create a linked list and synchronize free + type 1 for row 2 for column + Marked as const as list is mutable */ + void createList(int type) const; + /// Adds one string, returns index + int addString(const char * string); + /** Gets a double from a string possibly containing named strings, + returns unset if not found + */ + double getDoubleFromString(CoinYacc & info, const char * string); + /// Frees value memory + void freeStringMemory(CoinYacc & info); +public: + /// Fills in all associated - returning number of errors + int computeAssociated(double * associated); + /** Gets correct form for a quadratic row - user to delete + If row is not quadratic then returns which other variables are involved + with tiny (1.0e-100) elements and count of total number of variables which could not + be put in quadratic form + */ + CoinPackedMatrix * quadraticRow(int rowNumber,double * linear, + int & numberBad) const; + /// Replaces a quadratic row + void replaceQuadraticRow(int rowNumber,const double * linear, const CoinPackedMatrix * quadraticPart); + /** If possible return a model where if all variables marked nonzero are fixed + the problem will be linear. At present may only work if quadratic. + Returns NULL if not possible + */ + CoinModel * reorder(const char * mark) const; + /** Expands out all possible combinations for a knapsack + If buildObj NULL then just computes space needed - returns number elements + On entry numberOutput is maximum allowed, on exit it is number needed or + -1 (as will be number elements) if maximum exceeded. numberOutput will have at + least space to return values which reconstruct input. + Rows returned will be original rows but no entries will be returned for + any rows all of whose entries are in knapsack. So up to user to allow for this. + If reConstruct >=0 then returns number of entrie which make up item "reConstruct" + in expanded knapsack. Values in buildRow and buildElement; + */ + int expandKnapsack(int knapsackRow, int & numberOutput,double * buildObj, CoinBigIndex * buildStart, + int * buildRow, double * buildElement,int reConstruct=-1) const; + /// Sets cut marker array + void setCutMarker(int size,const int * marker); + /// Sets priority array + void setPriorities(int size,const int * priorities); + /// priorities (given for all columns (-1 if not integer) + inline const int * priorities() const + { return priority_;} + /// For decomposition set original row and column indices + void setOriginalIndices(const int * row, const int * column); + +private: + /** Read a problem from AMPL nl file + so not constructor so gdb will work + */ + void gdb( int nonLinear, const char * fileName, const void * info); + /// returns jColumn (-2 if linear term, -1 if unknown) and coefficient + int decodeBit(char * phrase, char * & nextPhrase, double & coefficient, bool ifFirst) const; + /// Aborts with message about packedMatrix + void badType() const; + /**@name Data members */ + //@{ + /// Maximum number of rows + int maximumRows_; + /// Maximum number of columns + int maximumColumns_; + /// Current number of elements + int numberElements_; + /// Maximum number of elements + int maximumElements_; + /// Current number of quadratic elements + int numberQuadraticElements_; + /// Maximum number of quadratic elements + int maximumQuadraticElements_; + /// Row lower + double * rowLower_; + /// Row upper + double * rowUpper_; + /// Row names + CoinModelHash rowName_; + /** Row types. + Has information - at present + bit 0 - rowLower is a string + bit 1 - rowUpper is a string + NOTE - if converted to CoinPackedMatrix - may be indices of + original rows (i.e. when decomposed) + */ + int * rowType_; + /// Objective + double * objective_; + /// Column Lower + double * columnLower_; + /// Column Upper + double * columnUpper_; + /// Column names + CoinModelHash columnName_; + /// Integer information + int * integerType_; + /// Strings + CoinModelHash string_; + /** Column types. + Has information - at present + bit 0 - columnLower is a string + bit 1 - columnUpper is a string + bit 2 - objective is a string + bit 3 - integer setting is a string + NOTE - if converted to CoinPackedMatrix - may be indices of + original columns (i.e. when decomposed) + */ + int * columnType_; + /// If simple then start of each row/column + int * start_; + /// Actual elements + CoinModelTriple * elements_; + /// Actual elements as CoinPackedMatrix + CoinPackedMatrix * packedMatrix_; + /// Hash for elements + mutable CoinModelHash2 hashElements_; + /// Linked list for rows + mutable CoinModelLinkedList rowList_; + /// Linked list for columns + mutable CoinModelLinkedList columnList_; + /// Actual quadratic elements (always linked lists) + CoinModelTriple * quadraticElements_; + /// Hash for quadratic elements + mutable CoinModelHash2 hashQuadraticElements_; + /// Array for sorting indices + int * sortIndices_; + /// Array for sorting elements + double * sortElements_; + /// Size of sort arrays + int sortSize_; + /// Linked list for quadratic rows + mutable CoinModelLinkedList quadraticRowList_; + /// Linked list for quadratic columns + mutable CoinModelLinkedList quadraticColumnList_; + /// Size of associated values + int sizeAssociated_; + /// Associated values + double * associated_; + /// Number of SOS - all these are done in one go e.g. from ampl + int numberSOS_; + /// SOS starts + int * startSOS_; + /// SOS members + int * memberSOS_; + /// SOS type + int * typeSOS_; + /// SOS priority + int * prioritySOS_; + /// SOS reference + double * referenceSOS_; + /// priorities (given for all columns (-1 if not integer) + int * priority_; + /// Nonzero if row is cut - done in one go e.g. from ampl + int * cut_; + /// Pointer to more information + void * moreInfo_; + /** Type of build - + -1 unset, + 0 for row, + 1 for column, + 2 linked. + 3 matrix is CoinPackedMatrix (and at present can't be modified); + */ + mutable int type_; + /// True if no names EVER being used (for users who know what they are doing) + bool noNames_; + /** Links present (could be tested by sizes of objects) + 0 - none, + 1 - row links, + 2 - column links, + 3 - both + */ + mutable int links_; + //@} +}; +/// Just function of single variable x +double getFunctionValueFromString(const char * string, const char * x, double xValue); +/// faster version +double getDoubleFromString(CoinYacc & info, const char * string, const char * x, double xValue); +#endif diff --git a/thirdparty/linux/include/coin/CoinModelUseful.hpp b/thirdparty/linux/include/coin/CoinModelUseful.hpp new file mode 100644 index 0000000..f9eeea3 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinModelUseful.hpp @@ -0,0 +1,441 @@ +/* $Id: CoinModelUseful.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinModelUseful_H +#define CoinModelUseful_H + + +#include +#include +#include +#include +#include +#include +#include + + +#include "CoinPragma.hpp" + +/** + This is for various structures/classes needed by CoinModel. + + CoinModelLink + CoinModelLinkedList + CoinModelHash +*/ +/// for going through row or column + +class CoinModelLink { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelLink(); + /** Destructor */ + ~CoinModelLink(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelLink(const CoinModelLink&); + /// = + CoinModelLink& operator=(const CoinModelLink&); + //@} + + /**@name Sets and gets method */ + //@{ + /// Get row + inline int row() const + { return row_;} + /// Get column + inline int column() const + { return column_;} + /// Get value + inline double value() const + { return value_;} + /// Get value + inline double element() const + { return value_;} + /// Get position + inline int position() const + { return position_;} + /// Get onRow + inline bool onRow() const + { return onRow_;} + /// Set row + inline void setRow(int row) + { row_=row;} + /// Set column + inline void setColumn(int column) + { column_=column;} + /// Set value + inline void setValue(double value) + { value_=value;} + /// Set value + inline void setElement(double value) + { value_=value;} + /// Set position + inline void setPosition(int position) + { position_=position;} + /// Set onRow + inline void setOnRow(bool onRow) + { onRow_=onRow;} + //@} + +private: + /**@name Data members */ + //@{ + /// Row + int row_; + /// Column + int column_; + /// Value as double + double value_; + /// Position in data + int position_; + /// If on row chain + bool onRow_; + //@} +}; + +/// for linked lists +// for specifying triple +typedef struct { + // top bit is nonzero if string + // rest is row + unsigned int row; + //CoinModelRowIndex row; + int column; + double value; // If string then index into strings +} CoinModelTriple; +inline int rowInTriple(const CoinModelTriple & triple) +{ return triple.row&0x7fffffff;} +inline void setRowInTriple(CoinModelTriple & triple,int iRow) +{ triple.row = iRow|(triple.row&0x80000000);} +inline bool stringInTriple(const CoinModelTriple & triple) +{ return (triple.row&0x80000000)!=0;} +inline void setStringInTriple(CoinModelTriple & triple,bool string) +{ triple.row = (string ? 0x80000000 : 0)|(triple.row&0x7fffffff);} +inline void setRowAndStringInTriple(CoinModelTriple & triple, + int iRow,bool string) +{ triple.row = (string ? 0x80000000 : 0)|iRow;} +/// for names and hashing +// for hashing +typedef struct { + int index, next; +} CoinModelHashLink; + +/* Function type. */ +typedef double (*func_t) (double); + +/// For string evaluation +/* Data type for links in the chain of symbols. */ +struct symrec +{ + char *name; /* name of symbol */ + int type; /* type of symbol: either VAR or FNCT */ + union + { + double var; /* value of a VAR */ + func_t fnctptr; /* value of a FNCT */ + } value; + struct symrec *next; /* link field */ +}; + +typedef struct symrec symrec; + +class CoinYacc { +private: + CoinYacc(const CoinYacc& rhs); + CoinYacc& operator=(const CoinYacc& rhs); + +public: + CoinYacc() : symtable(NULL), symbuf(NULL), length(0), unsetValue(0) {} + ~CoinYacc() + { + if (length) { + free(symbuf); + symbuf = NULL; + } + symrec* s = symtable; + while (s) { + free(s->name); + symtable = s; + s = s->next; + free(symtable); + } + } + +public: + symrec * symtable; + char * symbuf; + int length; + double unsetValue; +}; + +class CoinModelHash { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelHash(); + /** Destructor */ + ~CoinModelHash(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelHash(const CoinModelHash&); + /// = + CoinModelHash& operator=(const CoinModelHash&); + //@} + + /**@name sizing (just increases) */ + //@{ + /// Resize hash (also re-hashs) + void resize(int maxItems,bool forceReHash=false); + /// Number of items i.e. rows if just row names + inline int numberItems() const + { return numberItems_;} + /// Set number of items + void setNumberItems(int number); + /// Maximum number of items + inline int maximumItems() const + { return maximumItems_;} + /// Names + inline const char *const * names() const + { return names_;} + //@} + + /**@name hashing */ + //@{ + /// Returns index or -1 + int hash(const char * name) const; + /// Adds to hash + void addHash(int index, const char * name); + /// Deletes from hash + void deleteHash(int index); + /// Returns name at position (or NULL) + const char * name(int which) const; + /// Returns non const name at position (or NULL) + char * getName(int which) const; + /// Sets name at position (does not create) + void setName(int which,char * name ) ; + /// Validates + void validateHash() const; +private: + /// Returns a hash value + int hashValue(const char * name) const; +public: + //@} +private: + /**@name Data members */ + //@{ + /// Names + char ** names_; + /// hash + CoinModelHashLink * hash_; + /// Number of items + int numberItems_; + /// Maximum number of items + int maximumItems_; + /// Last slot looked at + int lastSlot_; + //@} +}; +/// For int,int hashing +class CoinModelHash2 { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelHash2(); + /** Destructor */ + ~CoinModelHash2(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelHash2(const CoinModelHash2&); + /// = + CoinModelHash2& operator=(const CoinModelHash2&); + //@} + + /**@name sizing (just increases) */ + //@{ + /// Resize hash (also re-hashs) + void resize(int maxItems, const CoinModelTriple * triples,bool forceReHash=false); + /// Number of items + inline int numberItems() const + { return numberItems_;} + /// Set number of items + void setNumberItems(int number); + /// Maximum number of items + inline int maximumItems() const + { return maximumItems_;} + //@} + + /**@name hashing */ + //@{ + /// Returns index or -1 + int hash(int row, int column, const CoinModelTriple * triples) const; + /// Adds to hash + void addHash(int index, int row, int column, const CoinModelTriple * triples); + /// Deletes from hash + void deleteHash(int index, int row, int column); +private: + /// Returns a hash value + int hashValue(int row, int column) const; +public: + //@} +private: + /**@name Data members */ + //@{ + /// hash + CoinModelHashLink * hash_; + /// Number of items + int numberItems_; + /// Maximum number of items + int maximumItems_; + /// Last slot looked at + int lastSlot_; + //@} +}; +class CoinModelLinkedList { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelLinkedList(); + /** Destructor */ + ~CoinModelLinkedList(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelLinkedList(const CoinModelLinkedList&); + /// = + CoinModelLinkedList& operator=(const CoinModelLinkedList&); + //@} + + /**@name sizing (just increases) */ + //@{ + /** Resize list - for row list maxMajor is maximum rows. + */ + void resize(int maxMajor,int maxElements); + /** Create list - for row list maxMajor is maximum rows. + type 0 row list, 1 column list + */ + void create(int maxMajor,int maxElements, + int numberMajor, int numberMinor, + int type, + int numberElements, const CoinModelTriple * triples); + /// Number of major items i.e. rows if just row links + inline int numberMajor() const + { return numberMajor_;} + /// Maximum number of major items i.e. rows if just row links + inline int maximumMajor() const + { return maximumMajor_;} + /// Number of elements + inline int numberElements() const + { return numberElements_;} + /// Maximum number of elements + inline int maximumElements() const + { return maximumElements_;} + /// First on free chain + inline int firstFree() const + { return first_[maximumMajor_];} + /// Last on free chain + inline int lastFree() const + { return last_[maximumMajor_];} + /// First on chain + inline int first(int which) const + { return first_[which];} + /// Last on chain + inline int last(int which) const + { return last_[which];} + /// Next array + inline const int * next() const + { return next_;} + /// Previous array + inline const int * previous() const + { return previous_;} + //@} + + /**@name does work */ + //@{ + /** Adds to list - easy case i.e. add row to row list + Returns where chain starts + */ + int addEasy(int majorIndex, int numberOfElements, const int * indices, + const double * elements, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Adds to list - hard case i.e. add row to column list + */ + void addHard(int minorIndex, int numberOfElements, const int * indices, + const double * elements, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Adds to list - hard case i.e. add row to column list + This is when elements have been added to other copy + */ + void addHard(int first, const CoinModelTriple * triples, + int firstFree, int lastFree,const int * nextOther); + /** Deletes from list - same case i.e. delete row from row list + */ + void deleteSame(int which, CoinModelTriple * triples, + CoinModelHash2 & hash, bool zapTriples); + /** Deletes from list - other case i.e. delete row from column list + This is when elements have been deleted from other copy + */ + void updateDeleted(int which, CoinModelTriple * triples, + CoinModelLinkedList & otherList); + /** Deletes one element from Row list + */ + void deleteRowOne(int position, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Update column list for one element when + one element deleted from row copy + */ + void updateDeletedOne(int position, const CoinModelTriple * triples); + /// Fills first,last with -1 + void fill(int first,int last); + /** Puts in free list from other list */ + void synchronize(CoinModelLinkedList & other); + /// Checks that links are consistent + void validateLinks(const CoinModelTriple * triples) const; + //@} +private: + /**@name Data members */ + //@{ + /// Previous - maximumElements long + int * previous_; + /// Next - maximumElements long + int * next_; + /// First - maximumMajor+1 long (last free element chain) + int * first_; + /// Last - maximumMajor+1 long (last free element chain) + int * last_; + /// Number of major items i.e. rows if just row links + int numberMajor_; + /// Maximum number of major items i.e. rows if just row links + int maximumMajor_; + /// Number of elements + int numberElements_; + /// Maximum number of elements + int maximumElements_; + /// 0 row list, 1 column list + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinMpsIO.hpp b/thirdparty/linux/include/coin/CoinMpsIO.hpp new file mode 100644 index 0000000..8f0226a --- /dev/null +++ b/thirdparty/linux/include/coin/CoinMpsIO.hpp @@ -0,0 +1,1056 @@ +/* $Id: CoinMpsIO.hpp 1642 2013-10-16 00:43:14Z tkr $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMpsIO_H +#define CoinMpsIO_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include +#include + +#include "CoinUtilsConfig.h" +#include "CoinPackedMatrix.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinFileIO.hpp" +class CoinModel; + +/// The following lengths are in decreasing order (for 64 bit etc) +/// Large enough to contain element index +/// This is already defined as CoinBigIndex +/// Large enough to contain column index +typedef int COINColumnIndex; + +/// Large enough to contain row index (or basis) +typedef int COINRowIndex; + +// We are allowing free format - but there is a limit! +// User can override by using CXXFLAGS += -DCOIN_MAX_FIELD_LENGTH=nnn +#ifndef COIN_MAX_FIELD_LENGTH +#define COIN_MAX_FIELD_LENGTH 160 +#endif +#define MAX_CARD_LENGTH 5*COIN_MAX_FIELD_LENGTH+80 + +enum COINSectionType { COIN_NO_SECTION, COIN_NAME_SECTION, COIN_ROW_SECTION, + COIN_COLUMN_SECTION, + COIN_RHS_SECTION, COIN_RANGES_SECTION, COIN_BOUNDS_SECTION, + COIN_ENDATA_SECTION, COIN_EOF_SECTION, COIN_QUADRATIC_SECTION, + COIN_CONIC_SECTION,COIN_QUAD_SECTION,COIN_SOS_SECTION, + COIN_BASIS_SECTION,COIN_UNKNOWN_SECTION +}; + +enum COINMpsType { COIN_N_ROW, COIN_E_ROW, COIN_L_ROW, COIN_G_ROW, + COIN_BLANK_COLUMN, COIN_S1_COLUMN, COIN_S2_COLUMN, COIN_S3_COLUMN, + COIN_INTORG, COIN_INTEND, COIN_SOSEND, COIN_UNSET_BOUND, + COIN_UP_BOUND, COIN_FX_BOUND, COIN_LO_BOUND, COIN_FR_BOUND, + COIN_MI_BOUND, COIN_PL_BOUND, COIN_BV_BOUND, + COIN_UI_BOUND, COIN_LI_BOUND, COIN_BOTH_BOUNDS_SET, + COIN_SC_BOUND, COIN_S1_BOUND, COIN_S2_BOUND, + COIN_BS_BASIS, COIN_XL_BASIS, COIN_XU_BASIS, + COIN_LL_BASIS, COIN_UL_BASIS, COIN_UNKNOWN_MPS_TYPE +}; +class CoinMpsIO; +/// Very simple code for reading MPS data +class CoinMpsCardReader { + +public: + + /**@name Constructor and destructor */ + //@{ + /// Constructor expects file to be open + /// This one takes gzFile if fp null + CoinMpsCardReader ( CoinFileInput *input, CoinMpsIO * reader ); + + /// Destructor + ~CoinMpsCardReader ( ); + //@} + + + /**@name card stuff */ + //@{ + /// Read to next section + COINSectionType readToNextSection ( ); + /// Gets next field and returns section type e.g. COIN_COLUMN_SECTION + COINSectionType nextField ( ); + /** Gets next field for .gms file and returns type. + -1 - EOF + 0 - what we expected (and processed so pointer moves past) + 1 - not what we expected + leading blanks always ignored + input types + 0 - anything - stops on non blank card + 1 - name (in columnname) + 2 - value + 3 - value name pair + 4 - equation type + 5 - ; + */ + int nextGmsField ( int expectedType ); + /// Returns current section type + inline COINSectionType whichSection ( ) const { + return section_; + } + /// Sets current section type + inline void setWhichSection(COINSectionType section ) { + section_=section; + } + /// Sees if free format. + inline bool freeFormat() const + { return freeFormat_;} + /// Sets whether free format. Mainly for blank RHS etc + inline void setFreeFormat(bool yesNo) + { freeFormat_=yesNo;} + /// Only for first field on card otherwise BLANK_COLUMN + /// e.g. COIN_E_ROW + inline COINMpsType mpsType ( ) const { + return mpsType_; + } + /// Reads and cleans card - taking out trailing blanks - return 1 if EOF + int cleanCard(); + /// Returns row name of current field + inline const char *rowName ( ) const { + return rowName_; + } + /// Returns column name of current field + inline const char *columnName ( ) const { + return columnName_; + } + /// Returns value in current field + inline double value ( ) const { + return value_; + } + /// Returns value as string in current field + inline const char *valueString ( ) const { + return valueString_; + } + /// Whole card (for printing) + inline const char *card ( ) const { + return card_; + } + /// Whole card - so we look at it (not const so nextBlankOr will work for gms reader) + inline char *mutableCard ( ) { + return card_; + } + /// set position (again so gms reader will work) + inline void setPosition(char * position) + { position_=position;} + /// get position (again so gms reader will work) + inline char * getPosition() const + { return position_;} + /// Returns card number + inline CoinBigIndex cardNumber ( ) const { + return cardNumber_; + } + /// Returns file input + inline CoinFileInput * fileInput ( ) const { + return input_; + } + /// Sets whether strings allowed + inline void setStringsAllowed() + { stringsAllowed_=true;} + //@} + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Current value + double value_; + /// Current card image + char card_[MAX_CARD_LENGTH]; + /// Current position within card image + char *position_; + /// End of card + char *eol_; + /// Current COINMpsType + COINMpsType mpsType_; + /// Current row name + char rowName_[COIN_MAX_FIELD_LENGTH]; + /// Current column name + char columnName_[COIN_MAX_FIELD_LENGTH]; + /// File input + CoinFileInput *input_; + /// Which section we think we are in + COINSectionType section_; + /// Card number + CoinBigIndex cardNumber_; + /// Whether free format. Just for blank RHS etc + bool freeFormat_; + /// Whether IEEE - 0 no, 1 INTEL, 2 not INTEL + int ieeeFormat_; + /// If all names <= 8 characters then allow embedded blanks + bool eightChar_; + /// MpsIO + CoinMpsIO * reader_; + /// Message handler + CoinMessageHandler * handler_; + /// Messages + CoinMessages messages_; + /// Current element as characters (only if strings allowed) + char valueString_[COIN_MAX_FIELD_LENGTH]; + /// Whether strings allowed + bool stringsAllowed_; + //@} +public: + /**@name methods */ + //@{ + /// type - 0 normal, 1 INTEL IEEE, 2 other IEEE + double osi_strtod(char * ptr, char ** output, int type); + /// remove blanks + static void strcpyAndCompress ( char *to, const char *from ); + /// + static char * nextBlankOr ( char *image ); + /// For strings + double osi_strtod(char * ptr, char ** output); + //@} + +}; + +//############################################################################# +#ifdef USE_SBB +class SbbObject; +class SbbModel; +#endif +/// Very simple class for containing data on set +class CoinSet { + +public: + + /**@name Constructor and destructor */ + //@{ + /// Default constructor + CoinSet ( ); + /// Constructor + CoinSet ( int numberEntries, const int * which); + + /// Copy constructor + CoinSet (const CoinSet &); + + /// Assignment operator + CoinSet & operator=(const CoinSet& rhs); + + /// Destructor + virtual ~CoinSet ( ); + //@} + + + /**@name gets */ + //@{ + /// Returns number of entries + inline int numberEntries ( ) const + { return numberEntries_; } + /// Returns type of set - 1 =SOS1, 2 =SOS2 + inline int setType ( ) const + { return setType_; } + /// Returns list of variables + inline const int * which ( ) const + { return which_; } + /// Returns weights + inline const double * weights ( ) const + { return weights_; } + //@} + +#ifdef USE_SBB + /**@name Use in sbb */ + //@{ + /// returns an object of type SbbObject + virtual SbbObject * sbbObject(SbbModel * model) const + { return NULL;} + //@} +#endif + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Number of entries + int numberEntries_; + /// type of set + int setType_; + /// Which variables are in set + int * which_; + /// Weights + double * weights_; + //@} +}; + +//############################################################################# +/// Very simple class for containing SOS set +class CoinSosSet : public CoinSet{ + +public: + + /**@name Constructor and destructor */ + //@{ + /// Constructor + CoinSosSet ( int numberEntries, const int * which, const double * weights, int type); + + /// Destructor + virtual ~CoinSosSet ( ); + //@} + + +#ifdef USE_SBB + /**@name Use in sbb */ + //@{ + /// returns an object of type SbbObject + virtual SbbObject * sbbObject(SbbModel * model) const ; + //@} +#endif + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + //@} +}; + +//############################################################################# + +/** MPS IO Interface + + This class can be used to read in mps files without a solver. After + reading the file, the CoinMpsIO object contains all relevant data, which + may be more than a particular OsiSolverInterface allows for. Items may + be deleted to allow for flexibility of data storage. + + The implementation makes the CoinMpsIO object look very like a dummy solver, + as the same conventions are used. +*/ + +class CoinMpsIO { + friend void CoinMpsIOUnitTest(const std::string & mpsDir); + +public: + +/** @name Methods to retrieve problem information + + These methods return information about the problem held by the CoinMpsIO + object. + + Querying an object that has no data associated with it result in zeros for + the number of rows and columns, and NULL pointers from the methods that + return vectors. Const pointers returned from any data-query method are + always valid +*/ +//@{ + /// Get number of columns + int getNumCols() const; + + /// Get number of rows + int getNumRows() const; + + /// Get number of nonzero elements + int getNumElements() const; + + /// Get pointer to array[getNumCols()] of column lower bounds + const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of constraint senses. +
    +
  • 'L': <= constraint +
  • 'E': = constraint +
  • 'G': >= constraint +
  • 'R': ranged constraint +
  • 'N': free constraint +
+ */ + const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of constraint right-hand sides. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint right-hand side (rhs) is set as +
    +
  • if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] +
  • if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] +
  • if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] +
  • if rowsense()[i] == 'N' then rhs()[i] == 0.0 +
+ */ + const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint range (rowrange) is set as +
    +
  • if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] +
  • if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 +
+ Put another way, only range constraints have a nontrivial value for + rowrange. + */ + const double * getRowRange() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + const double * getRowUpper() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const double * getObjCoefficients() const; + + /// Get pointer to row-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByCol() const; + + /// Return true if column is a continuous variable + bool isContinuous(int colNumber) const; + + /** Return true if a column is an integer variable + + Note: This function returns true if the the column + is a binary or general integer variable. + */ + bool isInteger(int columnNumber) const; + + /** Returns array[getNumCols()] specifying if a variable is integer. + + At present, simply coded as zero (continuous) and non-zero (integer) + May be extended at a later date. + */ + const char * integerColumns() const; + + /** Returns the row name for the specified index. + + Returns 0 if the index is out of range. + */ + const char * rowName(int index) const; + + /** Returns the column name for the specified index. + + Returns 0 if the index is out of range. + */ + const char * columnName(int index) const; + + /** Returns the index for the specified row name + + Returns -1 if the name is not found. + Returns numberRows for the objective row and > numberRows for + dropped free rows. + */ + int rowIndex(const char * name) const; + + /** Returns the index for the specified column name + + Returns -1 if the name is not found. + */ + int columnIndex(const char * name) const; + + /** Returns the (constant) objective offset + + This is the RHS entry for the objective row + */ + double objectiveOffset() const; + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_=value;} + + /// Return the problem name + const char * getProblemName() const; + + /// Return the objective name + const char * getObjectiveName() const; + + /// Return the RHS vector name + const char * getRhsName() const; + + /// Return the range vector name + const char * getRangeName() const; + + /// Return the bound vector name + const char * getBoundName() const; + /// Number of string elements + inline int numberStringElements() const + { return numberStringElements_;} + /// String element + inline const char * stringElement(int i) const + { return stringElements_[i];} +//@} + + +/** @name Methods to set problem information + + Methods to load a problem into the CoinMpsIO object. +*/ +//@{ + + /// Set the problem data + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub, + char const * const * const colnames, + char const * const * const rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub, + const std::vector & colnames, + const std::vector & rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const char* rowsen, const double* rowrhs, + const double* rowrng, + char const * const * const colnames, + char const * const * const rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const char* rowsen, const double* rowrhs, + const double* rowrng, + const std::vector & colnames, + const std::vector & rownames); + + /** Pass in an array[getNumCols()] specifying if a variable is integer. + + At present, simply coded as zero (continuous) and non-zero (integer) + May be extended at a later date. + */ + void copyInIntegerInformation(const char * integerInformation); + + /// Set problem name + void setProblemName(const char *name) ; + + /// Set objective name + void setObjectiveName(const char *name) ; + +//@} + +/** @name Parameter set/get methods + + Methods to set and retrieve MPS IO parameters. +*/ + +//@{ + /// Set infinity + void setInfinity(double value); + + /// Get infinity + double getInfinity() const; + + /// Set default upper bound for integer variables + void setDefaultBound(int value); + + /// Get default upper bound for integer variables + int getDefaultBound() const; + /// Whether to allow string elements + inline int allowStringElements() const + { return allowStringElements_;} + /// Whether to allow string elements (0 no, 1 yes, 2 yes and try flip) + inline void setAllowStringElements(int yesNo) + { allowStringElements_ = yesNo;} + /** Small element value - elements less than this set to zero on input + default is 1.0e-14 */ + inline double getSmallElementValue() const + { return smallElement_;} + inline void setSmallElementValue(double value) + { smallElement_=value;} +//@} + + +/** @name Methods for problem input and output + + Methods to read and write MPS format problem files. + + The read and write methods return the number of errors that occurred during + the IO operation, or -1 if no file is opened. + + \note + If the CoinMpsIO class was compiled with support for libz then + readMps will automatically try to append .gz to the file name and open it as + a compressed file if the specified file name cannot be opened. + (Automatic append of the .bz2 suffix when libbz is used is on the TODO list.) + + \todo + Allow for file pointers and positioning +*/ + +//@{ + /// Set the current file name for the CoinMpsIO object + void setFileName(const char * name); + + /// Get the current file name for the CoinMpsIO object + const char * getFileName() const; + + /** Read a problem in MPS format from the given filename. + + Use "stdin" or "-" to read from stdin. + */ + int readMps(const char *filename, const char *extension = "mps"); + + /** Read a problem in MPS format from the given filename. + + Use "stdin" or "-" to read from stdin. + But do sets as well + */ + int readMps(const char *filename, const char *extension , + int & numberSets, CoinSet **& sets); + + /** Read a problem in MPS format from a previously opened file + + More precisely, read a problem using a CoinMpsCardReader object already + associated with this CoinMpsIO object. + + \todo + Provide an interface that will allow a client to associate a + CoinMpsCardReader object with a CoinMpsIO object by setting the + cardReader_ field. + */ + int readMps(); + /// and + int readMps(int & numberSets, CoinSet **& sets); + /** Read a basis in MPS format from the given filename. + If VALUES on NAME card and solution not NULL fills in solution + status values as for CoinWarmStartBasis (but one per char) + -1 file error, 0 normal, 1 has solution values + + Use "stdin" or "-" to read from stdin. + + If sizes of names incorrect - read without names + */ + int readBasis(const char *filename, const char *extension , + double * solution, unsigned char *rowStatus, unsigned char *columnStatus, + const std::vector & colnames,int numberColumns, + const std::vector & rownames, int numberRows); + + /** Read a problem in GAMS format from the given filename. + + Use "stdin" or "-" to read from stdin. + if convertObjective then massages objective column + */ + int readGms(const char *filename, const char *extension = "gms",bool convertObjective=false); + + /** Read a problem in GAMS format from the given filename. + + Use "stdin" or "-" to read from stdin. + But do sets as well + */ + int readGms(const char *filename, const char *extension , + int & numberSets, CoinSet **& sets); + + /** Read a problem in GAMS format from a previously opened file + + More precisely, read a problem using a CoinMpsCardReader object already + associated with this CoinMpsIO object. + + */ + // Not for now int readGms(); + /// and + int readGms(int & numberSets, CoinSet **& sets); + /** Read a problem in GMPL (subset of AMPL) format from the given filenames. + */ + int readGMPL(const char *modelName, const char * dataName=NULL, bool keepNames=false); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written +
    +
  • 0: plain text (default) +
  • 1: gzip compressed (.gz is appended to \c filename) +
  • 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) +
+ If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file +
    +
  • 0: normal precision (default) +
  • 1: extra accuracy +
  • 2: IEEE hex +
+ + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + \param quadratic specifies quadratic objective to be output + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, + CoinPackedMatrix * quadratic = NULL, + int numberSOS=0,const CoinSet * setInfo=NULL) const; + + /// Return card reader object so can see what last card was e.g. QUADOBJ + inline const CoinMpsCardReader * reader() const + { return cardReader_;} + + /** Read in a quadratic objective from the given filename. + + If filename is NULL (or the same as the currently open file) then + reading continues from the current file. + If not, the file is closed and the specified file is opened. + + Code should be added to + general MPS reader to read this if QSECTION + Data is assumed to be Q and objective is c + 1/2 xT Q x + No assumption is made for symmetry, positive definite, etc. + No check is made for duplicates or non-triangular if checkSymmetry==0. + If 1 checks lower triangular (so off diagonal should be 2*Q) + if 2 makes lower triangular and assumes full Q (but adds off diagonals) + + Arrays should be deleted by delete [] + + Returns number of errors: +
    +
  • -1: bad file +
  • -2: no Quadratic section +
  • -3: an empty section +
  • +n: then matching errors etc (symmetry forced) +
  • -4: no matching errors but fails triangular test + (triangularity forced) +
+ columnStart is numberColumns+1 long, others numberNonZeros + */ + int readQuadraticMps(const char * filename, + int * &columnStart, int * &column, double * &elements, + int checkSymmetry); + + /** Read in a list of cones from the given filename. + + If filename is NULL (or the same as the currently open file) then + reading continues from the current file. + If not, the file is closed and the specified file is opened. + + Code should be added to + general MPS reader to read this if CSECTION + No checking is done that in unique cone + + Arrays should be deleted by delete [] + + Returns number of errors, -1 bad file, -2 no conic section, + -3 empty section + + columnStart is numberCones+1 long, other number of columns in matrix + + coneType is 1 for QUAD, 2 for RQUAD (numberCones long) +*/ + int readConicMps(const char * filename, + int * &columnStart, int * &column, int * &coneType, int & numberCones); + /// Set whether to move objective from matrix + inline void setConvertObjective(bool trueFalse) + { convertObjective_=trueFalse;} + /// copies in strings from a CoinModel - returns number + int copyStringElements(const CoinModel * model); + //@} + +/** @name Constructors and destructors */ +//@{ + /// Default Constructor + CoinMpsIO(); + + /// Copy constructor + CoinMpsIO (const CoinMpsIO &); + + /// Assignment operator + CoinMpsIO & operator=(const CoinMpsIO& rhs); + + /// Destructor + ~CoinMpsIO (); +//@} + + +/**@name Message handling */ +//@{ + /** Pass in Message handler + + Supply a custom message handler. It will not be destroyed when the + CoinMpsIO object is destroyed. + */ + void passInMessageHandler(CoinMessageHandler * handler); + + /// Set the language for messages. + void newLanguage(CoinMessages::Language language); + + /// Set the language for messages. + inline void setLanguage(CoinMessages::Language language) {newLanguage(language);} + + /// Return the message handler + inline CoinMessageHandler * messageHandler() const {return handler_;} + + /// Return the messages + inline CoinMessages messages() {return messages_;} + /// Return the messages pointer + inline CoinMessages * messagesPointer() {return & messages_;} +//@} + + +/**@name Methods to release storage + + These methods allow the client to reduce the storage used by the CoinMpsIO + object be selectively releasing unneeded problem information. +*/ +//@{ + /** Release all information which can be re-calculated. + + E.g., row sense, copies of rows, hash tables for names. + */ + void releaseRedundantInformation(); + + /// Release all row information (lower, upper) + void releaseRowInformation(); + + /// Release all column information (lower, upper, objective) + void releaseColumnInformation(); + + /// Release integer information + void releaseIntegerInformation(); + + /// Release row names + void releaseRowNames(); + + /// Release column names + void releaseColumnNames(); + + /// Release matrix information + void releaseMatrixInformation(); + //@} + +protected: + +/**@name Miscellaneous helper functions */ + //@{ + + /// Utility method used several times to implement public methods + void + setMpsDataWithoutRowAndColNames( + const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub); + void + setMpsDataColAndRowNames( + const std::vector & colnames, + const std::vector & rownames); + void + setMpsDataColAndRowNames( + char const * const * const colnames, + char const * const * const rownames); + + + /// Does the heavy lifting for destruct and assignment. + void gutsOfDestructor(); + + /// Does the heavy lifting for copy and assignment. + void gutsOfCopy(const CoinMpsIO &); + + /// Clears problem data from the CoinMpsIO object. + void freeAll(); + + + /** A quick inlined function to convert from lb/ub style constraint + definition to sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + /** A quick inlined function to convert from sense/rhs/range stryle + constraint definition to lb/ub style */ + inline void + convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const; + + /** Deal with a filename + + As the name says. + Returns +1 if the file name is new, 0 if it's the same as before + (i.e., matches fileName_), and -1 if there's an error and the file + can't be opened. + Handles automatic append of .gz suffix when compiled with libz. + + \todo + Add automatic append of .bz2 suffix when compiled with libbz. + */ + + int dealWithFileName(const char * filename, const char * extension, + CoinFileInput * &input); + /** Add string to list + iRow==numberRows is objective, nr+1 is lo, nr+2 is up + iColumn==nc is rhs (can't cope with ranges at present) + */ + void addString(int iRow,int iColumn, const char * value); + /// Decode string + void decodeString(int iString, int & iRow, int & iColumn, const char * & value) const; + //@} + + + // for hashing + typedef struct { + int index, next; + } CoinHashLink; + + /**@name Hash table methods */ + //@{ + /// Creates hash list for names (section = 0 for rows, 1 columns) + void startHash ( char **names, const int number , int section ); + /// This one does it when names are already in + void startHash ( int section ) const; + /// Deletes hash storage + void stopHash ( int section ); + /// Finds match using hash, -1 not found + int findHash ( const char *name , int section ) const; + //@} + + /**@name Cached problem information */ + //@{ + /// Problem name + char * problemName_; + + /// Objective row name + char * objectiveName_; + + /// Right-hand side vector name + char * rhsName_; + + /// Range vector name + char * rangeName_; + + /// Bounds vector name + char * boundName_; + + /// Number of rows + int numberRows_; + + /// Number of columns + int numberColumns_; + + /// Number of coefficients + CoinBigIndex numberElements_; + + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /** Pointer to dense vector of slack variable upper bounds for range + constraints (undefined for non-range rows) + */ + mutable double *rowrange_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByRow_; + + /// Pointer to column-wise copy of problem matrix coefficients. + CoinPackedMatrix *matrixByColumn_; + + /// Pointer to dense vector of row lower bounds + double * rowlower_; + + /// Pointer to dense vector of row upper bounds + double * rowupper_; + + /// Pointer to dense vector of column lower bounds + double * collower_; + + /// Pointer to dense vector of column upper bounds + double * colupper_; + + /// Pointer to dense vector of objective coefficients + double * objective_; + + /// Constant offset for objective value (i.e., RHS value for OBJ row) + double objectiveOffset_; + + + /** Pointer to dense vector specifying if a variable is continuous + (0) or integer (1). + */ + char * integerType_; + + /** Row and column names + Linked to hash table sections (0 - row names, 1 column names) + */ + char **names_[2]; + //@} + + /** @name Hash tables */ + //@{ + /// Current file name + char * fileName_; + + /// Number of entries in a hash table section + int numberHash_[2]; + + /// Hash tables (two sections, 0 - row names, 1 - column names) + mutable CoinHashLink *hash_[2]; + //@} + + /** @name CoinMpsIO object parameters */ + //@{ + /// Upper bound when no bounds for integers + int defaultBound_; + + /// Value to use for infinity + double infinity_; + /// Small element value + double smallElement_; + + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the message handler is the default handler. + + If true, the handler will be destroyed when the CoinMpsIO + object is destroyed; if false, it will not be destroyed. + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + /// Card reader + CoinMpsCardReader * cardReader_; + /// If .gms file should it be massaged to move objective + bool convertObjective_; + /// Whether to allow string elements + int allowStringElements_; + /// Maximum number of string elements + int maximumStringElements_; + /// Number of string elements + int numberStringElements_; + /// String elements + char ** stringElements_; + //@} + +}; + +//############################################################################# +/** A function that tests the methods in the CoinMpsIO class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. Also, if this method is compiled with + optimization, the compilation takes 10-15 minutes and the machine pages + (has 256M core memory!)... */ +void +CoinMpsIOUnitTest(const std::string & mpsDir); +// Function to return number in most efficient way +// section is 0 for columns, 1 for rhs,ranges and 2 for bounds +/* formatType is + 0 - normal and 8 character names + 1 - extra accuracy + 2 - IEEE hex - INTEL + 3 - IEEE hex - not INTEL +*/ +void +CoinConvertDouble(int section, int formatType, double value, char outputValue[24]); + +#endif + diff --git a/thirdparty/linux/include/coin/CoinOslFactorization.hpp b/thirdparty/linux/include/coin/CoinOslFactorization.hpp new file mode 100644 index 0000000..0b51b01 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinOslFactorization.hpp @@ -0,0 +1,280 @@ +/* $Id: CoinOslFactorization.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 1987, 2009, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* + Authors + + John Forrest + + */ +#ifndef CoinOslFactorization_H +#define CoinOslFactorization_H +#include +#include +#include +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinDenseFactorization.hpp" +class CoinPackedMatrix; +/** This deals with Factorization and Updates + This is ripped off from OSL!!!!!!!!! + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + +typedef struct {int suc, pre;} EKKHlink; +typedef struct _EKKfactinfo { + double drtpiv; + double demark; + double zpivlu; + double zeroTolerance; + double areaFactor; + int *xrsadr; + int *xcsadr; + int *xrnadr; + int *xcnadr; + int *krpadr; + int *kcpadr; + int *mpermu; + int *bitArray; + int * back; + char * nonzero; + double * trueStart; + mutable double *kadrpm; + int *R_etas_index; + int *R_etas_start; + double *R_etas_element; + + int *xecadr; + int *xeradr; + double *xeeadr; + double *xe2adr; + EKKHlink * kp1adr; + EKKHlink * kp2adr; + double * kw1adr; + double * kw2adr; + double * kw3adr; + int * hpivcoR; + int nrow; + int nrowmx; + int firstDoRow; + int firstLRow; + int maxinv; + int nnetas; + int iterin; + int iter0; + int invok; + int nbfinv; + int num_resets; + int nnentl; + int nnentu; +#ifdef CLP_REUSE_ETAS + int save_nnentu; +#endif + int ndenuc; + int npivots; /* use as xpivsq in factorization */ + int kmxeta; + int xnetal; + int first_dense; + int last_dense; + int iterno; + int numberSlacks; + int lastSlack; + int firstNonSlack; + int xnetalval; + int lstart; + int if_sparse_update; + mutable int packedMode; + int switch_off_sparse_update; + int nuspike; + bool rows_ok; /* replaces test using mrstrt[1] */ +#ifdef CLP_REUSE_ETAS + mutable int reintro; +#endif + int nR_etas; + int sortedEta; /* if vector for F-T is sorted */ + int lastEtaCount; + int ifvsol; + int eta_size; + int last_eta_size; + int maxNNetas; +} EKKfactinfo; + +class CoinOslFactorization : public CoinOtherFactorization { + friend void CoinOslFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinOslFactorization ( ); + /// Copy constructor + CoinOslFactorization ( const CoinOslFactorization &other); + + /// Destructor + virtual ~CoinOslFactorization ( ); + /// = copy + CoinOslFactorization & operator = ( const CoinOslFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize ( const CoinPackedMatrix & matrix, + int rowIsBasic[], int columnIsBasic[] , + double areaFactor = 0.0 ); + //@} + + /**@name general stuff such as number of elements */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns array to put basis elements in + virtual CoinFactorizationDouble * elements() const; + /// Returns pivot row + virtual int * pivotRow() const; + /// Returns work area + virtual CoinFactorizationDouble * workArea() const; + /// Returns int work area + virtual int * intWorkArea() const; + /// Number of entries in each row + virtual int * numberInRow() const; + /// Number of entries in each column + virtual int * numberInColumn() const; + /// Returns array to put basis starts in + virtual CoinBigIndex * starts() const; + /// Returns permute back + virtual int * permuteBack() const; + /// Returns true if wants tableauColumn in replaceColumn + virtual bool wantsTableauColumn() const; + /** Useful information for factorization + 0 - iteration number + whereFrom is 0 for factorize and 1 for replaceColumn + */ + virtual void setUsefulInformation(const int * info,int whereFrom); + /// Set maximum pivots + virtual void maximumPivots ( int value ); + + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + /// Condition number - product of pivots after factorization + double conditionNumber() const; + /// Get rid of all memory + virtual void clearArrays(); + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false); + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + //inline void clearArrays() + //{ gutsOfDestructor();} + /// Returns array to put basis indices in + virtual int * indices() const; + /// Returns permute in + virtual inline int * permute() const + { return NULL;/*pivotRow_*/;} + //@} + + /// The real work of desstructor + void gutsOfDestructor(bool clearFact=true); + /// The real work of constructor + void gutsOfInitialize(bool zapFact=true); + /// The real work of copy + void gutsOfCopy(const CoinOslFactorization &other); + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Osl factorization data + EKKfactinfo factInfo_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/CoinPackedMatrix.hpp b/thirdparty/linux/include/coin/CoinPackedMatrix.hpp new file mode 100644 index 0000000..c6837ac --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPackedMatrix.hpp @@ -0,0 +1,947 @@ +/* $Id: CoinPackedMatrix.hpp 1560 2012-11-24 00:29:01Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedMatrix_H +#define CoinPackedMatrix_H + +#include "CoinError.hpp" +#include "CoinTypes.hpp" +#ifndef CLP_NO_VECTOR +#include "CoinPackedVectorBase.hpp" +#include "CoinShallowPackedVector.hpp" +#else +class CoinRelFltEq; +#endif + +/** Sparse Matrix Base Class + + This class is intended to represent sparse matrices using row-major + or column-major ordering. The representation is very efficient for + adding, deleting, or retrieving major-dimension vectors. Adding + a minor-dimension vector is less efficient, but can be helped by + providing "extra" space as described in the next paragraph. Deleting + a minor-dimension vector requires inspecting all coefficients in the + matrix. Retrieving a minor-dimension vector would incur the same cost + and is not supported (except in the sense that you can write a loop to + retrieve all coefficients one at a time). Consider physically transposing + the matrix, or keeping a second copy with the other major-vector ordering. + + The sparse represention can be completely compact or it can have "extra" + space available at the end of each major vector. Incorporating extra + space into the sparse matrix representation can improve performance in + cases where new data needs to be inserted into the packed matrix against + the major-vector orientation (e.g, inserting a row into a matrix stored + in column-major order). + + For example if the matrix: + @verbatim + 3 1 0 -2 -1 0 0 -1 + 0 2 1.1 0 0 0 0 0 + 0 0 1 0 0 1 0 0 + 0 0 0 2.8 0 0 -1.2 0 + 5.6 0 0 0 1 0 0 1.9 + + was stored by rows (with no extra space) in + CoinPackedMatrix r then: + r.getElements() returns a vector containing: + 3 1 -2 -1 -1 2 1.1 1 1 2.8 -1.2 5.6 1 1.9 + r.getIndices() returns a vector containing: + 0 1 3 4 7 1 2 2 5 3 6 0 4 7 + r.getVectorStarts() returns a vector containing: + 0 5 7 9 11 14 + r.getNumElements() returns 14. + r.getMajorDim() returns 5. + r.getVectorSize(0) returns 5. + r.getVectorSize(1) returns 2. + r.getVectorSize(2) returns 2. + r.getVectorSize(3) returns 2. + r.getVectorSize(4) returns 3. + + If stored by columns (with no extra space) then: + c.getElements() returns a vector containing: + 3 5.6 1 2 1.1 1 -2 2.8 -1 1 1 -1.2 -1 1.9 + c.getIndices() returns a vector containing: + 0 4 0 1 1 2 0 3 0 4 2 3 0 4 + c.getVectorStarts() returns a vector containing: + 0 2 4 6 8 10 11 12 14 + c.getNumElements() returns 14. + c.getMajorDim() returns 8. + @endverbatim + + Compiling this class with CLP_NO_VECTOR defined will excise all methods + which use CoinPackedVectorBase, CoinPackedVector, or CoinShallowPackedVector + as parameters or return types. + + Compiling this class with COIN_FAST_CODE defined removes index range checks. +*/ +class CoinPackedMatrix { + friend void CoinPackedMatrixUnitTest(); + +public: + + + //--------------------------------------------------------------------------- + /**@name Query members */ + //@{ + /** Return the current setting of the extra gap. */ + inline double getExtraGap() const { return extraGap_; } + /** Return the current setting of the extra major. */ + inline double getExtraMajor() const { return extraMajor_; } + + /** Reserve sufficient space for appending major-ordered vectors. + If create is true, empty columns are created (for column generation) */ + void reserve(const int newMaxMajorDim, const CoinBigIndex newMaxSize, + bool create=false); + /** Clear the data, but do not free any arrays */ + void clear(); + + /** Whether the packed matrix is column major ordered or not. */ + inline bool isColOrdered() const { return colOrdered_; } + + /** Whether the packed matrix has gaps or not. */ + inline bool hasGaps() const { return (size_vectorStarts array + + See #start_. + */ + inline int getSizeVectorStarts() const + { return ((majorDim_ > 0)?(majorDim_+1):(0)) ; } + + /*! \brief The size of the vectorLengths array + + See #length_. + */ + inline int getSizeVectorLengths() const { return majorDim_; } + + /*! \brief The positions where the major-dimension vectors start in + elements and indices. + + See #start_. + */ + inline const CoinBigIndex * getVectorStarts() const { return start_; } + + /*! \brief The lengths of the major-dimension vectors. + + See #length_. + */ + inline const int * getVectorLengths() const { return length_; } + + /** The position of the first element in the i'th major-dimension vector. + */ + CoinBigIndex getVectorFirst(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorFirst", "CoinPackedMatrix"); +#endif + return start_[i]; + } + /** The position of the last element (well, one entry past the + last) in the i'th major-dimension vector. */ + CoinBigIndex getVectorLast(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorLast", "CoinPackedMatrix"); +#endif + return start_[i] + length_[i]; + } + /** The length of i'th vector. */ + inline int getVectorSize(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorSize", "CoinPackedMatrix"); +#endif + return length_[i]; + } +#ifndef CLP_NO_VECTOR + /** Return the i'th vector in matrix. */ + const CoinShallowPackedVector getVector(int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vector", "CoinPackedMatrix"); +#endif + return CoinShallowPackedVector(length_[i], + index_ + start_[i], + element_ + start_[i], + false); + } +#endif + /** Returns an array containing major indices. The array is + getNumElements long and if getVectorStarts() is 0,2,5 then + the array would start 0,0,1,1,1,2... + This method is provided to go back from a packed format + to a triple format. It returns NULL if there are gaps in + matrix so user should use removeGaps() if there are any gaps. + It does this as this array has to match getElements() and + getIndices() and because it makes no sense otherwise. + The returned array is allocated with new int[], + free it with delete[]. */ + int * getMajorIndices() const; + //@} + + //--------------------------------------------------------------------------- + /**@name Modifying members */ + //@{ + /*! \brief Set the dimensions of the matrix. + + The method name is deceptive; the effect is to append empty columns + and/or rows to the matrix to reach the specified dimensions. + A negative number for either dimension means that that dimension + doesn't change. An exception will be thrown if the specified dimensions + are smaller than the current dimensions. + */ + void setDimensions(int numrows, int numcols); + + /** Set the extra gap to be allocated to the specified value. */ + void setExtraGap(const double newGap); + /** Set the extra major to be allocated to the specified value. */ + void setExtraMajor(const double newMajor); +#ifndef CLP_NO_VECTOR + /*! Append a column to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the column vector specifies a nonexistent row index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendCol(const CoinPackedVectorBase& vec); +#endif + /*! Append a column to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the column vector specifies a nonexistent row index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendCol(const int vecsize, + const int *vecind, const double *vecelem); +#ifndef CLP_NO_VECTOR + /*! Append a set of columns to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if any of the column vectors specify a nonexistent row index. Otherwise + the method assumes that every index fits into the matrix. + */ + void appendCols(const int numcols, + const CoinPackedVectorBase * const * cols); +#endif + /*! Append a set of columns to the end of the matrix. + + Returns the number of errors (nonexistent or duplicate row index). + No error checking is performed if \p numberRows < 0. + */ + int appendCols(const int numcols, + const CoinBigIndex * columnStarts, const int * row, + const double * element, int numberRows=-1); +#ifndef CLP_NO_VECTOR + /*! Append a row to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the row vector specifies a nonexistent column index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendRow(const CoinPackedVectorBase& vec); +#endif + /*! Append a row to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the row vector specifies a nonexistent column index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendRow(const int vecsize, + const int *vecind, const double *vecelem); +#ifndef CLP_NO_VECTOR + /*! Append a set of rows to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if any of the row vectors specify a nonexistent column index. Otherwise + the method assumes that every index fits into the matrix. + */ + void appendRows(const int numrows, + const CoinPackedVectorBase * const * rows); +#endif + /*! Append a set of rows to the end of the matrix. + + Returns the number of errors (nonexistent or duplicate column index). + No error checking is performed if \p numberColumns < 0. + */ + int appendRows(const int numrows, + const CoinBigIndex * rowStarts, const int * column, + const double * element, int numberColumns=-1); + + /** Append the argument to the "right" of the current matrix. Imagine this + as adding new columns (don't worry about how the matrices are ordered, + that is taken care of). An exception is thrown if the number of rows + is different in the matrices. */ + void rightAppendPackedMatrix(const CoinPackedMatrix& matrix); + /** Append the argument to the "bottom" of the current matrix. Imagine this + as adding new rows (don't worry about how the matrices are ordered, + that is taken care of). An exception is thrown if the number of columns + is different in the matrices. */ + void bottomAppendPackedMatrix(const CoinPackedMatrix& matrix); + + /** Delete the columns whose indices are listed in indDel. */ + void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in indDel. */ + void deleteRows(const int numDel, const int * indDel); + + /** Replace the elements of a vector. The indices remain the same. + At most the number specified will be replaced. + The index is between 0 and major dimension of matrix */ + void replaceVector(const int index, + const int numReplace, const double * newElements); + /** Modify one element of packed matrix. An element may be added. + This works for either ordering + If the new element is zero it will be deleted unless + keepZero true */ + void modifyCoefficient(int row, int column, double newElement, + bool keepZero=false); + /** Return one element of packed matrix. + This works for either ordering + If it is not present will return 0.0 */ + double getCoefficient(int row, int column) const; + + /** Eliminate all elements in matrix whose + absolute value is less than threshold. + The column starts are not affected. Returns number of elements + eliminated. Elements eliminated are at end of each vector + */ + int compress(double threshold); + /** Eliminate all duplicate AND small elements in matrix + The column starts are not affected. Returns number of elements + eliminated. + */ + int eliminateDuplicates(double threshold); + /** Sort all columns so indices are increasing.in each column */ + void orderMatrix(); + /** Really clean up matrix. + a) eliminate all duplicate AND small elements in matrix + b) remove all gaps and set extraGap_ and extraMajor_ to 0.0 + c) reallocate arrays and make max lengths equal to lengths + d) orders elements + returns number of elements eliminated + */ + int cleanMatrix(double threshold=1.0e-20); + //@} + + //--------------------------------------------------------------------------- + /**@name Methods that reorganize the whole matrix */ + //@{ + /** Remove the gaps from the matrix if there were any + Can also remove small elements fabs() <= removeValue*/ + void removeGaps(double removeValue=-1.0); + + /** Extract a submatrix from matrix. Those major-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. Does not allow duplicates. */ + void submatrixOf(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor); + /** Extract a submatrix from matrix. Those major-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. Allows duplicates and keeps order. */ + void submatrixOfWithDuplicates(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor); +#if 0 + /** Extract a submatrix from matrix. Those major/minor-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. */ + void submatrixOf(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor, + const int numMinor, const int * indMinor); +#endif + + /** Copy method. This method makes an exact replica of the argument, + including the extra space parameters. */ + void copyOf(const CoinPackedMatrix& rhs); + /** Copy the arguments to the matrix. If len is a NULL pointer + then the matrix is assumed to have no gaps in it and len + will be created accordingly. */ + void copyOf(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor=0.0, const double extraGap=0.0); + /** Copy method. This method makes an exact replica of the argument, + including the extra space parameters. + If there is room it will re-use arrays */ + void copyReuseArrays(const CoinPackedMatrix& rhs); + + /*! \brief Make a reverse-ordered copy. + + This method makes an exact replica of the argument with the major + vector orientation changed from row (column) to column (row). + The extra space parameters are also copied and reversed. + (Cf. #reverseOrdering, which does the same thing in place.) + */ + void reverseOrderedCopyOf(const CoinPackedMatrix& rhs); + + /** Assign the arguments to the matrix. If len is a NULL + pointer then the matrix is assumed to have no gaps in it and + len will be created accordingly.
+ NOTE 1: After this method returns the pointers + passed to the method will be NULL pointers!
+ NOTE 2: When the matrix is eventually destructed the + arrays will be deleted by delete[]. Hence one should use + this method ONLY if all array swere allocated by new[]! */ + void assignMatrix(const bool colordered, + const int minor, const int major, + const CoinBigIndex numels, + double *& elem, int *& ind, + CoinBigIndex *& start, int *& len, + const int maxmajor = -1, const CoinBigIndex maxsize = -1); + + + + /** Assignment operator. This copies out the data, but uses the current + matrix's extra space parameters. */ + CoinPackedMatrix & operator=(const CoinPackedMatrix& rhs); + + /*! \brief Reverse the ordering of the packed matrix. + + Change the major vector orientation of the matrix data structures from + row (column) to column (row). (Cf. #reverseOrderedCopyOf, which does + the same thing but produces a new matrix.) + */ + void reverseOrdering(); + + /*! \brief Transpose the matrix. + + \note + If you start with a column-ordered matrix and invoke transpose, you + will have a row-ordered transposed matrix. To change the major vector + orientation (e.g., to transform a column-ordered matrix to a + column-ordered transposed matrix), invoke transpose() followed by + #reverseOrdering(). + */ + void transpose(); + + /*! \brief Swap the content of two packed matrices. */ + void swap(CoinPackedMatrix& matrix); + + //@} + + //--------------------------------------------------------------------------- + /**@name Matrix times vector methods */ + //@{ + /** Return A * x in y. + @pre x must be of size numColumns() + @pre y must be of size numRows() */ + void times(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return A * x in y. Same as the previous + method, just x is given in the form of a packed vector. */ + void times(const CoinPackedVectorBase& x, double * y) const; +#endif + /** Return x * A in y. + @pre x must be of size numRows() + @pre y must be of size numColumns() */ + void transposeTimes(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return x * A in y. Same as the previous + method, just x is given in the form of a packed vector. */ + void transposeTimes(const CoinPackedVectorBase& x, double * y) const; +#endif + //@} + + //--------------------------------------------------------------------------- + /**@name Helper functions used internally, but maybe useful externally. + + These methods do not worry about testing whether the packed matrix is + row or column major ordered; they operate under the assumption that the + correct version is invoked. In fact, a number of other methods simply + just call one of these after testing the ordering of the matrix. */ + //@{ + + //------------------------------------------------------------------------- + /**@name Queries */ + //@{ + /** Count the number of entries in every minor-dimension vector and + return an array containing these lengths. The returned array is + allocated with new int[], free it with + delete[]. */ + int * countOrthoLength() const; + /** Count the number of entries in every minor-dimension vector and + fill in an array containing these lengths. */ + void countOrthoLength(int * counts) const; + /** Major dimension. For row ordered matrix this would be the number of + rows. */ + inline int getMajorDim() const { return majorDim_; } + /** Set major dimension. For row ordered matrix this would be the number of + rows. Use with great care.*/ + inline void setMajorDim(int value) { majorDim_ = value; } + /** Minor dimension. For row ordered matrix this would be the number of + columns. */ + inline int getMinorDim() const { return minorDim_; } + /** Set minor dimension. For row ordered matrix this would be the number of + columns. Use with great care.*/ + inline void setMinorDim(int value) { minorDim_ = value; } + /** Current maximum for major dimension. For row ordered matrix this many + rows can be added without reallocating the vector related to the + major dimension (start_ and length_). */ + inline int getMaxMajorDim() const { return maxMajorDim_; } + + /** Dump the matrix on stdout. When in dire straits this method can + help. */ + void dumpMatrix(const char* fname = NULL) const; + + /// Print a single matrix element. + void printMatrixElement(const int row_val, const int col_val) const; + //@} + + //------------------------------------------------------------------------- + /*! @name Append vectors + + \details + When compiled with COIN_DEBUG defined these methods throw an exception + if the major (minor) vector contains an index that's invalid for the + minor (major) dimension. Otherwise the methods assume that every index + fits into the matrix. + */ + //@{ +#ifndef CLP_NO_VECTOR + /** Append a major-dimension vector to the end of the matrix. */ + void appendMajorVector(const CoinPackedVectorBase& vec); +#endif + /** Append a major-dimension vector to the end of the matrix. */ + void appendMajorVector(const int vecsize, const int *vecind, + const double *vecelem); +#ifndef CLP_NO_VECTOR + /** Append several major-dimensonvectors to the end of the matrix */ + void appendMajorVectors(const int numvecs, + const CoinPackedVectorBase * const * vecs); + + /** Append a minor-dimension vector to the end of the matrix. */ + void appendMinorVector(const CoinPackedVectorBase& vec); +#endif + /** Append a minor-dimension vector to the end of the matrix. */ + void appendMinorVector(const int vecsize, const int *vecind, + const double *vecelem); +#ifndef CLP_NO_VECTOR + /** Append several minor-dimension vectors to the end of the matrix */ + void appendMinorVectors(const int numvecs, + const CoinPackedVectorBase * const * vecs); +#endif + /*! \brief Append a set of rows (columns) to the end of a column (row) + ordered matrix. + + This case is when we know there are no gaps and majorDim_ will not + change. + + \todo + This method really belongs in the group of protected methods with + #appendMinor; there are no safeties here even with COIN_DEBUG. + Apparently this method was needed in ClpPackedMatrix and giving it + proper visibility was too much trouble. Should be moved. + */ + void appendMinorFast(const int number, + const CoinBigIndex * starts, const int * index, + const double * element); + //@} + + //------------------------------------------------------------------------- + /*! \name Append matrices + + \details + We'll document these methods assuming that the current matrix is + column major ordered (Hence in the ...SameOrdered() + methods the argument is column ordered, in the + OrthoOrdered() methods the argument is row ordered.) + */ + //@{ + /** Append the columns of the argument to the right end of this matrix. + @pre minorDim_ == matrix.minorDim_
+ This method throws an exception if the minor dimensions are not the + same. */ + void majorAppendSameOrdered(const CoinPackedMatrix& matrix); + /** Append the columns of the argument to the bottom end of this matrix. + @pre majorDim_ == matrix.majorDim_
+ This method throws an exception if the major dimensions are not the + same. */ + void minorAppendSameOrdered(const CoinPackedMatrix& matrix); + /** Append the rows of the argument to the right end of this matrix. + @pre minorDim_ == matrix.majorDim_
+ This method throws an exception if the minor dimension of the + current matrix is not the same as the major dimension of the + argument matrix. */ + void majorAppendOrthoOrdered(const CoinPackedMatrix& matrix); + /** Append the rows of the argument to the bottom end of this matrix. + @pre majorDim_ == matrix.minorDim_
+ This method throws an exception if the major dimension of the + current matrix is not the same as the minor dimension of the + argument matrix. */ + void minorAppendOrthoOrdered(const CoinPackedMatrix& matrix); + //@} + + //----------------------------------------------------------------------- + /**@name Delete vectors */ + //@{ + /** Delete the major-dimension vectors whose indices are listed in + indDel. */ + void deleteMajorVectors(const int numDel, const int * indDel); + /** Delete the minor-dimension vectors whose indices are listed in + indDel. */ + void deleteMinorVectors(const int numDel, const int * indDel); + //@} + + //----------------------------------------------------------------------- + /**@name Various dot products. */ + //@{ + /** Return A * x (multiplied from the "right" direction) in + y. + @pre x must be of size majorDim() + @pre y must be of size minorDim() */ + void timesMajor(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return A * x (multiplied from the "right" direction) in + y. Same as the previous method, just x is + given in the form of a packed vector. */ + void timesMajor(const CoinPackedVectorBase& x, double * y) const; +#endif + /** Return A * x (multiplied from the "right" direction) in + y. + @pre x must be of size minorDim() + @pre y must be of size majorDim() */ + void timesMinor(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return A * x (multiplied from the "right" direction) in + y. Same as the previous method, just x is + given in the form of a packed vector. */ + void timesMinor(const CoinPackedVectorBase& x, double * y) const; +#endif + //@} + //@} + + //-------------------------------------------------------------------------- + /**@name Logical Operations. */ + //@{ +#ifndef CLP_NO_VECTOR + /*! \brief Test for equivalence. + + Two matrices are equivalent if they are both row- or column-ordered, + they have the same dimensions, and each (major) vector is equivalent. + The operator used to test for equality can be specified using the + \p FloatEqual template parameter. + */ + template bool + isEquivalent(const CoinPackedMatrix& rhs, const FloatEqual& eq) const + { + // Both must be column order or both row ordered and must be of same size + if ((isColOrdered() ^ rhs.isColOrdered()) || + (getNumCols() != rhs.getNumCols()) || + (getNumRows() != rhs.getNumRows()) || + (getNumElements() != rhs.getNumElements())) + return false; + + for (int i=getMajorDim()-1; i >= 0; --i) { + CoinShallowPackedVector pv = getVector(i); + CoinShallowPackedVector rhsPv = rhs.getVector(i); + if ( !pv.isEquivalent(rhsPv,eq) ) + return false; + } + return true; + } + + /*! \brief Test for equivalence and report differences + + Equivalence is defined as for #isEquivalent. In addition, this method will + print differences to std::cerr. Intended for use in unit tests and + for debugging. + */ + bool isEquivalent2(const CoinPackedMatrix& rhs) const; +#else + /*! \brief Test for equivalence. + + Two matrices are equivalent if they are both row- or column-ordered, + they have the same dimensions, and each (major) vector is equivalent. + This method is optimised for speed. CoinPackedVector#isEquivalent is + replaced with more efficient code for repeated comparison of + equal-length vectors. The CoinRelFltEq operator is used. + */ + bool isEquivalent(const CoinPackedMatrix& rhs, const CoinRelFltEq & eq) const; +#endif + /*! \brief Test for equivalence. + + The test for element equality is the default CoinRelFltEq operator. + */ + bool isEquivalent(const CoinPackedMatrix& rhs) const; + //@} + + //-------------------------------------------------------------------------- + /*! \name Non-const methods + + These are to be used with great care when doing column generation, etc. + */ + //@{ + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with #start_ and #length_. */ + inline double * getMutableElements() const { return element_; } + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with #start_ and + #length_. */ + inline int * getMutableIndices() const { return index_; } + + /** The positions where the major-dimension vectors start in #element_ and + #index_. */ + inline CoinBigIndex * getMutableVectorStarts() const { return start_; } + /** The lengths of the major-dimension vectors. */ + inline int * getMutableVectorLengths() const { return length_; } + /// Change the size of the bulk store after modifying - be careful + inline void setNumElements(CoinBigIndex value) + { size_ = value;} + /*! NULLify element array + + Used when space is very tight. Does not free the space! + */ + inline void nullElementArray() {element_=NULL;} + + /*! NULLify start array + + Used when space is very tight. Does not free the space! + */ + inline void nullStartArray() {start_=NULL;} + + /*! NULLify length array + + Used when space is very tight. Does not free the space! + */ + inline void nullLengthArray() {length_=NULL;} + + /*! NULLify index array + + Used when space is very tight. Does not free the space! + */ + inline void nullIndexArray() {index_=NULL;} + //@} + + //-------------------------------------------------------------------------- + /*! \name Constructors and destructors */ + //@{ + /// Default Constructor creates an empty column ordered packed matrix + CoinPackedMatrix(); + + /// A constructor where the ordering and the gaps are specified + CoinPackedMatrix(const bool colordered, + const double extraMajor, const double extraGap); + + CoinPackedMatrix(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor, const double extraGap); + + CoinPackedMatrix(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len); + + /** Create packed matrix from triples. + If colordered is true then the created matrix will be column ordered. + Duplicate matrix elements are allowed. The created matrix will have + the sum of the duplicates.
+ For example if:
+ rowIndices[0]=2; colIndices[0]=5; elements[0]=2.0
+ rowIndices[1]=2; colIndices[1]=5; elements[1]=0.5
+ then the created matrix will contain a value of 2.5 in row 2 and column 5.
+ The matrix is created without gaps. + */ + CoinPackedMatrix(const bool colordered, + const int * rowIndices, + const int * colIndices, + const double * elements, + CoinBigIndex numels ); + + /// Copy constructor + CoinPackedMatrix(const CoinPackedMatrix& m); + + /*! \brief Copy constructor with fine tuning + + This constructor allows for the specification of an exact amount of extra + space and/or reverse ordering. + + \p extraForMajor is the exact number of spare major vector slots after + any possible reverse ordering. If \p extraForMajor < 0, all gaps and small + elements will be removed from the copy, otherwise gaps and small elements + are preserved. + + \p extraElements is the exact number of spare element entries. + + The usual multipliers, #extraMajor_ and #extraGap_, are set to zero. + */ + CoinPackedMatrix(const CoinPackedMatrix &m, + int extraForMajor, int extraElements, + bool reverseOrdering = false) ; + + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + CoinPackedMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /// Destructor + virtual ~CoinPackedMatrix(); + //@} + + /*! \name Debug Utilities */ + //@{ + /*! \brief Scan the matrix for anomalies. + + Returns the number of anomalies. Scans the structure for gaps, + obviously bogus indices and coefficients, and inconsistencies. Gaps + are not an error unless #hasGaps() says the matrix should be + gap-free. Zeroes are not an error unless \p zeroesAreError is set to + true. + + Values for verbosity are: + - 0: No messages, just the return value + - 1: Messages about errors + - 2: If there are no errors, a message indicating the matrix was + checked is printed (positive confirmation). + - 3: Adds a bit more information about the matrix. + - 4: Prints warnings about zeroes even if they're not considered + errors. + + Obviously bogus coefficients are coefficients that are NaN or have + absolute value greater than 1e50. Zeros have absolute value less + than 1e-50. + */ + int verifyMtx(int verbosity = 1, bool zeroesAreError = false) const ; + //@} + + //-------------------------------------------------------------------------- +protected: + void gutsOfDestructor(); + void gutsOfCopyOf(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor=0.0, const double extraGap=0.0); + /// When no gaps we can do faster + void gutsOfCopyOfNoGaps(const bool colordered, + const int minor, const int major, + const double * elem, const int * ind, + const CoinBigIndex * start); + void gutsOfOpEqual(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len); + void resizeForAddingMajorVectors(const int numVec, const int * lengthVec); + void resizeForAddingMinorVectors(const int * addedEntries); + + /*! \brief Append a set of rows (columns) to the end of a row (colum) + ordered matrix. + + If \p numberOther > 0 the method will check if any of the new rows + (columns) contain duplicate indices or invalid indices and return the + number of errors. A valid minor index must satisfy + \code 0 <= k < numberOther \endcode + If \p numberOther < 0 no checking is performed. + */ + int appendMajor(const int number, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther=-1); + /*! \brief Append a set of rows (columns) to the end of a column (row) + ordered matrix. + + If \p numberOther > 0 the method will check if any of the new rows + (columns) contain duplicate indices or indices outside the current + range for the major dimension and return the number of violations. + If \p numberOther <= 0 the major dimension will be expanded as + necessary and there are no checks for duplicate indices. + */ + int appendMinor(const int number, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther=-1); + +private: + inline CoinBigIndex getLastStart() const { + return majorDim_ == 0 ? 0 : start_[majorDim_]; + } + + //-------------------------------------------------------------------------- +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /** A flag indicating whether the matrix is column or row major ordered. */ + bool colOrdered_; + /** This much times more space should be allocated for each major-dimension + vector (with respect to the number of entries in the vector) when the + matrix is resized. The purpose of these gaps is to allow fast insertion + of new minor-dimension vectors. */ + double extraGap_; + /** his much times more space should be allocated for major-dimension + vectors when the matrix is resized. The purpose of these gaps is to + allow fast addition of new major-dimension vectors. */ + double extraMajor_; + + /** List of nonzero element values. The entries in the gaps between + major-dimension vectors are undefined. */ + double *element_; + /** List of nonzero element minor-dimension indices. The entries in the gaps + between major-dimension vectors are undefined. */ + int *index_; + /** Starting positions of major-dimension vectors. */ + CoinBigIndex *start_; + /** Lengths of major-dimension vectors. */ + int *length_; + + /// number of vectors in matrix + int majorDim_; + /// size of other dimension + int minorDim_; + /// the number of nonzero entries + CoinBigIndex size_; + + /// max space allocated for major-dimension + int maxMajorDim_; + /// max space allocated for entries + CoinBigIndex maxSize_; + //@} +}; + +//############################################################################# +/*! \brief Test the methods in the CoinPackedMatrix class. + + The only reason for it not to be a member method is that this way + it doesn't have to be compiled into the library. And that's a gain, + because the library should be compiled with optimization on, but this + method should be compiled with debugging. +*/ +void +CoinPackedMatrixUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin/CoinPackedVector.hpp b/thirdparty/linux/include/coin/CoinPackedVector.hpp new file mode 100644 index 0000000..9ea1feb --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPackedVector.hpp @@ -0,0 +1,657 @@ +/* $Id: CoinPackedVector.hpp 1509 2011-12-05 13:50:48Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedVector_H +#define CoinPackedVector_H + +#include + +#include "CoinPragma.hpp" +#include "CoinPackedVectorBase.hpp" +#include "CoinSort.hpp" + +#ifdef COIN_FAST_CODE +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_NOTEST_DUPLICATE +#endif +#endif + +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE true +#else +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE false +#endif +/** Sparse Vector + +Stores vector of indices and associated element values. +Supports sorting of vector while maintaining the original indices. + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 } + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its value + CoinPackedVector r(ne,inx,el); + + // access each index and element + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access original position of index + assert( r.originalPosition()[0]==0 ); + assert( r.originalPosition()[1]==1 ); + assert( r.originalPosition()[2]==2 ); + assert( r.originalPosition()[3]==3 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // sort Elements in increasing order + r.sortIncrElement(); + + // access each index and element + assert( r.indices ()[0]== 0 ); + assert( r.elements()[0]== 1. ); + assert( r.indices ()[1]== 1 ); + assert( r.elements()[1]==10. ); + assert( r.indices ()[2]== 4 ); + assert( r.elements()[2]==40. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access original position of index + assert( r.originalPosition()[0]==2 ); + assert( r.originalPosition()[1]==0 ); + assert( r.originalPosition()[2]==1 ); + assert( r.originalPosition()[3]==3 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Restore orignal sort order + r.sortOriginalOrder(); + + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // Tests for equality and equivalence + CoinPackedVector r1; + r1=r; + assert( r==r1 ); + assert( r.equivalent(r1) ); + r.sortIncrElement(); + assert( r!=r1 ); + assert( r.equivalent(r1) ); + + // Add packed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinPackedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinPackedVector : public CoinPackedVectorBase { + friend void CoinPackedVectorUnitTest(); + +public: + /**@name Get methods. */ + //@{ + /// Get the size + virtual int getNumElements() const { return nElements_; } + /// Get indices of elements + virtual const int * getIndices() const { return indices_; } + /// Get element values + virtual const double * getElements() const { return elements_; } + /// Get indices of elements + int * getIndices() { return indices_; } + /// Get the size + inline int getVectorNumElements() const { return nElements_; } + /// Get indices of elements + inline const int * getVectorIndices() const { return indices_; } + /// Get element values + inline const double * getVectorElements() const { return elements_; } + /// Get element values + double * getElements() { return elements_; } + /** Get pointer to int * vector of original postions. + If the packed vector has not been sorted then this + function returns the vector: 0, 1, 2, ..., size()-1. */ + const int * getOriginalPosition() const { return origIndices_; } + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Reset the vector (as if were just created an empty vector) + void clear(); + /** Assignment operator.
+ NOTE: This operator keeps the current + testForDuplicateIndex setting, and affter copying the data + it acts accordingly. */ + CoinPackedVector & operator=(const CoinPackedVector &); + /** Assignment operator from a CoinPackedVectorBase.
+ NOTE: This operator keeps the current + testForDuplicateIndex setting, and affter copying the data + it acts accordingly. */ + CoinPackedVector & operator=(const CoinPackedVectorBase & rhs); + + /** Assign the ownership of the arguments to this vector. + Size is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. The last argument indicates whether this vector will have + to be tested for duplicate indices. + */ + void assignVector(int size, int*& inds, double*& elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Set vector size, indices, and elements. + Size is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. The last argument specifies whether this vector will have + to be checked for duplicate indices whenever that can happen. */ + void setVector(int size, const int * inds, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Elements set to have the same scalar value */ + void setConstant(int size, const int * inds, double elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Indices are not specified and are taken to be 0,1,...,size-1 */ + void setFull(int size, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Indices are not specified and are taken to be 0,1,...,size-1, + but only where non zero*/ + void setFullNonZero(int size, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Set an existing element in the packed vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, double element); + + /// Insert an element into the vector + void insert(int index, double element); + /// Append a CoinPackedVector to the end + void append(const CoinPackedVectorBase & caboose); + + /// Swap values in positions i and j of indices and elements + void swap(int i, int j); + + /** Resize the packed vector to be the first newSize elements. + Problem with truncate: what happens with origIndices_ ??? */ + void truncate(int newSize); + //@} + + /**@name Arithmetic operators. */ + //@{ + /// add value to every entry + void operator+=(double value); + /// subtract value from every entry + void operator-=(double value); + /// multiply every entry by value + void operator*=(double value); + /// divide every entry by value + void operator/=(double value); + //@} + + /**@name Sorting */ + //@{ + /** Sort the packed storage vector. + Typcical usages: +
 
+       packedVector.sort(CoinIncrIndexOrdered());   //increasing indices
+       packedVector.sort(CoinIncrElementOrdered()); // increasing elements
+       
+ */ + template + void sort(const CoinCompare3 & tc) + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + tc); } + + void sortIncrIndex() + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + CoinFirstLess_3()); } + + void sortDecrIndex() + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + CoinFirstGreater_3()); } + + void sortIncrElement() + { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_, + CoinFirstLess_3()); } + + void sortDecrElement() + { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_, + CoinFirstGreater_3()); } + + + /** Sort in original order. + If the vector has been sorted, then this method restores + to its orignal sort order. + */ + void sortOriginalOrder(); + //@} + + /**@name Memory usage */ + //@{ + /** Reserve space. + If one knows the eventual size of the packed vector, + then it may be more efficient to reserve the space. + */ + void reserve(int n); + /** capacity returns the size which could be accomodated without + having to reallocate storage. + */ + int capacity() const { return capacity_; } + //@} + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinPackedVector(bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** \brief Alternate Constructors - set elements to vector of doubles + + This constructor copies the vectors provided as parameters. + */ + CoinPackedVector(int size, const int * inds, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** \brief Alternate Constructors - set elements to vector of doubles + + This constructor takes ownership of the vectors passed as parameters. + \p inds and \p elems will be NULL on return. + */ + CoinPackedVector(int capacity, int size, int *&inds, double *&elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Alternate Constructors - set elements to same scalar value */ + CoinPackedVector(int size, const int * inds, double element, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Alternate Constructors - construct full storage with indices 0 through + size-1. */ + CoinPackedVector(int size, const double * elements, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Copy constructor. */ + CoinPackedVector(const CoinPackedVector &); + /** Copy constructor from a PackedVectorBase. */ + CoinPackedVector(const CoinPackedVectorBase & rhs); + /** Destructor */ + virtual ~CoinPackedVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal date + void gutsOfSetVector(int size, + const int * inds, const double * elems, + bool testForDuplicateIndex, + const char * method); + /// + void gutsOfSetConstant(int size, + const int * inds, double value, + bool testForDuplicateIndex, + const char * method); + //@} + +private: + /**@name Private member data */ + //@{ + /// Vector indices + int * indices_; + ///Vector elements + double * elements_; + /// Size of indices and elements vectors + int nElements_; + /// original unsorted indices + int * origIndices_; + /// Amount of memory allocated for indices_, origIndices_, and elements_. + int capacity_; + //@} +}; + +//############################################################################# + +/**@name Arithmetic operators on packed vectors. + + NOTE: These methods operate on those positions where at + least one of the arguments has a value listed. At those positions the + appropriate operation is executed, Otherwise the result of the operation is + considered 0.
+ NOTE 2: There are two kind of operators here. One is used + like "c = binaryOp(a, b)", the other is used like "binaryOp(c, a, b)", but + they are really the same. The first is much more natural to use, but it + involves the creation of a temporary object (the function *must* return an + object), while the second form puts the result directly into the argument + "c". Therefore, depending on the circumstances, the second form can be + significantly faster. + */ +//@{ +template void +binaryOp(CoinPackedVector& retVal, + const CoinPackedVectorBase& op1, double value, + BinaryFunction bf) +{ + retVal.clear(); + const int s = op1.getNumElements(); + if (s > 0) { + retVal.reserve(s); + const int * inds = op1.getIndices(); + const double * elems = op1.getElements(); + for (int i=0; i inline void +binaryOp(CoinPackedVector& retVal, + double value, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + binaryOp(retVal, op2, value, bf); +} + +template void +binaryOp(CoinPackedVector& retVal, + const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + retVal.clear(); + const int s1 = op1.getNumElements(); + const int s2 = op2.getNumElements(); +/* + Replaced || with &&, in response to complaint from Sven deVries, who + rightly points out || is not appropriate for additive operations. && + should be ok as long as binaryOp is understood not to create something + from nothing. -- lh, 04.06.11 +*/ + if (s1 == 0 && s2 == 0) + return; + + retVal.reserve(s1+s2); + + const int * inds1 = op1.getIndices(); + const double * elems1 = op1.getElements(); + const int * inds2 = op2.getIndices(); + const double * elems2 = op2.getElements(); + + int i; + // loop once for each element in op1 + for ( i=0; i CoinPackedVector +binaryOp(const CoinPackedVectorBase& op1, double value, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, value, bf); + return retVal; +} + +template CoinPackedVector +binaryOp(double value, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op2, value, bf); + return retVal; +} + +template CoinPackedVector +binaryOp(const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, bf); + return retVal; +} + +//----------------------------------------------------------------------------- +/// Return the sum of two packed vectors +inline CoinPackedVector operator+(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::plus()); + return retVal; +} + +/// Return the difference of two packed vectors +inline CoinPackedVector operator-(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::minus()); + return retVal; +} + +/// Return the element-wise product of two packed vectors +inline CoinPackedVector operator*(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::multiplies()); + return retVal; +} + +/// Return the element-wise ratio of two packed vectors +inline CoinPackedVector operator/(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::divides()); + return retVal; +} +//@} + +/// Returns the dot product of two CoinPackedVector objects whose elements are +/// doubles. Use this version if the vectors are *not* guaranteed to be sorted. +inline double sparseDotProduct(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2){ + int len, i; + double acc = 0.0; + CoinPackedVector retVal; + + CoinPackedVector retval = op1*op2; + len = retval.getNumElements(); + double * CParray = retval.getElements(); + + for(i = 0; i < len; i++){ + acc += CParray[i]; + } +return acc; +} + + +/// Returns the dot product of two sorted CoinPackedVector objects. +/// The vectors should be sorted in ascending order of indices. +inline double sortedSparseDotProduct(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2){ + int i, j, len1, len2; + double acc = 0.0; + + const double* v1val = op1.getElements(); + const double* v2val = op2.getElements(); + const int* v1ind = op1.getIndices(); + const int* v2ind = op2.getIndices(); + + len1 = op1.getNumElements(); + len2 = op2.getNumElements(); + + i = 0; + j = 0; + + while(i < len1 && j < len2){ + if(v1ind[i] == v2ind[j]){ + acc += v1val[i] * v2val[j]; + i++; + j++; + } + else if(v2ind[j] < v1ind[i]){ + j++; + } + else{ + i++; + } // end if-else-elseif + } // end while + return acc; + } + + +//----------------------------------------------------------------------------- + +/**@name Arithmetic operators on packed vector and a constant.
+ These functions create a packed vector as a result. That packed vector will + have the same indices as op1 and the specified operation is + done entry-wise with the given value. */ +//@{ +/// Return the sum of a packed vector and a constant +inline CoinPackedVector +operator+(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal += value; + return retVal; +} + +/// Return the difference of a packed vector and a constant +inline CoinPackedVector +operator-(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal -= value; + return retVal; +} + +/// Return the element-wise product of a packed vector and a constant +inline CoinPackedVector +operator*(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal *= value; + return retVal; +} + +/// Return the element-wise ratio of a packed vector and a constant +inline CoinPackedVector +operator/(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal /= value; + return retVal; +} + +//----------------------------------------------------------------------------- + +/// Return the sum of a constant and a packed vector +inline CoinPackedVector +operator+(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + retVal += value; + return retVal; +} + +/// Return the difference of a constant and a packed vector +inline CoinPackedVector +operator-(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + const int size = retVal.getNumElements(); + double* elems = retVal.getElements(); + for (int i = 0; i < size; ++i) { + elems[i] = value - elems[i]; + } + return retVal; +} + +/// Return the element-wise product of a constant and a packed vector +inline CoinPackedVector +operator*(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + retVal *= value; + return retVal; +} + +/// Return the element-wise ratio of a a constant and packed vector +inline CoinPackedVector +operator/(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + const int size = retVal.getNumElements(); + double* elems = retVal.getElements(); + for (int i = 0; i < size; ++i) { + elems[i] = value / elems[i]; + } + return retVal; +} +//@} + +//############################################################################# +/** A function that tests the methods in the CoinPackedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinPackedVectorUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin/CoinPackedVectorBase.hpp b/thirdparty/linux/include/coin/CoinPackedVectorBase.hpp new file mode 100644 index 0000000..dccc1cd --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPackedVectorBase.hpp @@ -0,0 +1,269 @@ +/* $Id: CoinPackedVectorBase.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedVectorBase_H +#define CoinPackedVectorBase_H + +#include +#include +#include "CoinPragma.hpp" +#include "CoinError.hpp" + +class CoinPackedVector; + +/** Abstract base class for various sparse vectors. + + Since this class is abstract, no object of this type can be created. The + sole purpose of this class is to provide access to a constant + packed vector. All members of this class are const methods, they can't + change the object. */ + +class CoinPackedVectorBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + /// Get length of indices and elements vectors + virtual int getNumElements() const = 0; + /// Get indices of elements + virtual const int * getIndices() const = 0; + /// Get element values + virtual const double * getElements() const = 0; + //@} + + /**@name Methods related to whether duplicate-index checking is performed. + + If the checking for duplicate indices is turned off, then + some CoinPackedVector methods may not work correctly if there + are duplicate indices. + Turning off the checking for duplicate indices may result in + better run time performance. + */ + //@{ + /** \brief Set to the argument value whether to test for duplicate indices + in the vector whenever they can occur. + + Calling this method with \p test set to true will trigger an immediate + check for duplicate indices. + */ + void setTestForDuplicateIndex(bool test) const; + /** \brief Set to the argument value whether to test for duplicate indices + in the vector whenever they can occur BUT we know that right + now the vector has no duplicate indices. + + Calling this method with \p test set to true will not trigger + an immediate check for duplicate indices; instead, it's assumed that + the result of the test will be true. + */ + void setTestForDuplicateIndexWhenTrue(bool test) const; + /** Returns true if the vector should be tested for duplicate indices when + they can occur. */ + bool testForDuplicateIndex() const { return testForDuplicateIndex_; } + /// Just sets test stuff false without a try etc + inline void setTestsOff() const + { testForDuplicateIndex_=false; testedDuplicateIndex_=false;} + //@} + + /**@name Methods for getting info on the packed vector as a full vector */ + //@{ + /** Get the vector as a dense vector. The argument specifies how long this + dense vector is.
+ NOTE: The user needs to delete[] this + pointer after it's not needed anymore. + */ + double * denseVector(int denseSize) const; + /** Access the i'th element of the full storage vector. + If the i'th is not stored, then zero is returned. The initial use of + this method has some computational and storage overhead associated with + it.
+ NOTE: This is very expensive. It is probably + much better to use denseVector(). + */ + double operator[](int i) const; + //@} + + /**@name Index methods */ + //@{ + /// Get value of maximum index + int getMaxIndex() const; + /// Get value of minimum index + int getMinIndex() const; + + /// Throw an exception if there are duplicate indices + void duplicateIndex(const char* methodName = NULL, + const char * className = NULL) const; + + /** Return true if the i'th element of the full storage vector exists in + the packed storage vector.*/ + bool isExistingIndex(int i) const; + + /** Return the position of the i'th element of the full storage vector. + If index does not exist then -1 is returned */ + int findIndex(int i) const; + + //@} + + /**@name Comparison operators on two packed vectors */ + //@{ + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinPackedVectorBase & rhs) const; + /// Not equal + bool operator!=(const CoinPackedVectorBase & rhs) const; + +#if 0 + // LL: This should be implemented eventually. It is useful to have. + /** Lexicographic comparisons of two packed vectors. Returns + negative/0/positive depending on whether \c this is + smaller/equal.greater than \c rhs */ + int lexCompare(const CoinPackedVectorBase& rhs); +#endif + + /** This method establishes an ordering on packed vectors. It is complete + ordering, but not the same as lexicographic ordering. However, it is + quick and dirty to compute and thus it is useful to keep packed vectors + in a heap when all we care is to quickly check whether a particular + vector is already in the heap or not. Returns negative/0/positive + depending on whether \c this is smaller/equal.greater than \c rhs. */ + int compare(const CoinPackedVectorBase& rhs) const; + + /** equivalent - If shallow packed vector A & B are equivalent, then they + are still equivalent no matter how they are sorted. + In this method the FloatEqual function operator can be specified. The + default equivalence test is that the entries are relatively equal.
+ NOTE: This is a relatively expensive method as it + sorts the two shallow packed vectors. + */ + template bool + isEquivalent(const CoinPackedVectorBase& rhs, const FloatEqual& eq) const + { + if (getNumElements() != rhs.getNumElements()) + return false; + + duplicateIndex("equivalent", "CoinPackedVector"); + rhs.duplicateIndex("equivalent", "CoinPackedVector"); + + std::map mv; + const int * inds = getIndices(); + const double * elems = getElements(); + int i; + for ( i = getNumElements() - 1; i >= 0; --i) { + mv.insert(std::make_pair(inds[i], elems[i])); + } + + std::map mvRhs; + inds = rhs.getIndices(); + elems = rhs.getElements(); + for ( i = getNumElements() - 1; i >= 0; --i) { + mvRhs.insert(std::make_pair(inds[i], elems[i])); + } + + std::map::const_iterator mvI = mv.begin(); + std::map::const_iterator mvIlast = mv.end(); + std::map::const_iterator mvIrhs = mvRhs.begin(); + while (mvI != mvIlast) { + if (mvI->first != mvIrhs->first || ! eq(mvI->second, mvIrhs->second)) + return false; + ++mvI; + ++mvIrhs; + } + return true; + } + + bool isEquivalent(const CoinPackedVectorBase& rhs) const; + //@} + + + /**@name Arithmetic operators. */ + //@{ + /// Create the dot product with a full vector + double dotProduct(const double* dense) const; + + /// Return the 1-norm of the vector + double oneNorm() const; + + /// Return the square of the 2-norm of the vector + double normSquare() const; + + /// Return the 2-norm of the vector + double twoNorm() const; + + /// Return the infinity-norm of the vector + double infNorm() const; + + /// Sum elements of vector. + double sum() const; + //@} + +protected: + + /**@name Constructors, destructor + NOTE: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + CoinPackedVectorBase(); + +public: + /** Destructor */ + virtual ~CoinPackedVectorBase(); + //@} + +private: + /**@name Disabled methods */ + //@{ + /** The copy constructor.
+ This must be at least protected, but we make it private. The reason is + that when, say, a shallow packed vector is created, first the + underlying class, it this one is constructed. However, at that point we + don't know how much of the data members of this class we need to copy + over. Therefore the copy constructor is not used. */ + CoinPackedVectorBase(const CoinPackedVectorBase&); + /** This class provides const access to packed vectors, so there's + no need to provide an assignment operator. */ + CoinPackedVectorBase& operator=(const CoinPackedVectorBase&); + //@} + +protected: + + /**@name Protected methods */ + //@{ + /// Find Maximum and Minimum Indices + void findMaxMinIndices() const; + + /// Return indexSetPtr_ (create it if necessary). + std::set * indexSet(const char* methodName = NULL, + const char * className = NULL) const; + + /// Delete the indexSet + void clearIndexSet() const; + void clearBase() const; + void copyMaxMinIndex(const CoinPackedVectorBase & x) const { + maxIndex_ = x.maxIndex_; + minIndex_ = x.minIndex_; + } + //@} + +private: + /**@name Protected member data */ + //@{ + /// Contains max index value or -infinity + mutable int maxIndex_; + /// Contains minimum index value or infinity + mutable int minIndex_; + /** Store the indices in a set. This set is only created if it is needed. + Its primary use is testing for duplicate indices. + */ + mutable std::set * indexSetPtr_; + /** True if the vector should be tested for duplicate indices when they can + occur. */ + mutable bool testForDuplicateIndex_; + /** True if the vector has already been tested for duplicate indices. Most + of the operations in CoinPackedVector preserves this flag. */ + mutable bool testedDuplicateIndex_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinParam.hpp b/thirdparty/linux/include/coin/CoinParam.hpp new file mode 100644 index 0000000..30cccc2 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinParam.hpp @@ -0,0 +1,644 @@ +/* $Id: CoinParam.hpp 1493 2011-11-01 16:56:07Z tkr $ */ +#ifndef CoinParam_H +#define CoinParam_H + +/* + Copyright (C) 2002, International Business Machines + Corporation and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ + +/*! \file CoinParam.hpp + \brief Declaration of a class for command line parameters. +*/ + +#include +#include +#include + +/*! \class CoinParam + \brief A base class for `keyword value' command line parameters. + + The underlying paradigm is that a parameter specifies an action to be + performed on a target object. The base class provides two function + pointers, a `push' function and a `pull' function. By convention, a push + function will set some value in the target object or perform some action + using the target object. A `pull' function will retrieve some value from + the target object. This is only a convention, however; CoinParam and + associated utilities make no use of these functions and have no hardcoded + notion of how they should be used. + + The action to be performed, and the target object, will be specific to a + particular application. It is expected that users will derive + application-specific parameter classes from this base class. A derived + class will typically add fields and methods to set/get a code for the + action to be performed (often, an enum class) and the target object (often, + a pointer or reference). + + Facilities provided by the base class and associated utility routines + include: +
    +
  • Support for common parameter types with numeric, string, or + keyword values. +
  • Support for short and long help messages. +
  • Pointers to `push' and `pull' functions as described above. +
  • Command line parsing and keyword matching. +
+ All utility routines are declared in the #CoinParamUtils namespace. + + The base class recognises five types of parameters: actions (which require + no value); numeric parameters with integer or real (double) values; keyword + parameters, where the value is one of a defined set of value-keywords; + and string parameters (where the value is a string). + The base class supports the definition of a valid range, a default value, + and short and long help messages for a parameter. + + As defined by the #CoinParamFunc typedef, push and pull functions + should take a single parameter, a pointer to a CoinParam. Typically this + object will actually be a derived class as described above, and the + implementation function will have access to all capabilities of CoinParam and + of the derived class. + + When specified as command line parameters, the expected syntax is `-keyword + value' or `-keyword=value'. You can also use the Gnu double-dash style, + `--keyword'. Spaces around the `=' will \e not work. + + The keyword (name) for a parameter can be defined with an `!' to mark the + minimal match point. For example, allow!ableGap will be considered matched + by the strings `allow', `allowa', `allowab', \e etc. Similarly, the + value-keyword strings for keyword parameters can be defined with `!' to + mark the minimal match point. Matching of keywords and value-keywords is + \e not case sensitive. +*/ + +class CoinParam +{ + +public: + +/*! \name Subtypes */ +//@{ + + /*! \brief Enumeration for the types of parameters supported by CoinParam + + CoinParam provides support for several types of parameters: +
    +
  • Action parameters, which require no value. +
  • Integer and double numeric parameters, with upper and lower bounds. +
  • String parameters that take an arbitrary string value. +
  • Keyword parameters that take a defined set of string (value-keyword) + values. Value-keywords are associated with integers in the order in + which they are added, starting from zero. +
+ */ + typedef enum { coinParamInvalid = 0, + coinParamAct, coinParamInt, coinParamDbl, + coinParamStr, coinParamKwd } CoinParamType ; + + /*! \brief Type declaration for push and pull functions. + + By convention, a return code of 0 indicates execution without error, >0 + indicates nonfatal error, and <0 indicates fatal error. This is only + convention, however; the base class makes no use of the push and pull + functions and has no hardcoded interpretation of the return code. + */ + typedef int (*CoinParamFunc)(CoinParam *param) ; + +//@} + +/*! \name Constructors and Destructors + + Be careful how you specify parameters for the constructors! Some compilers + are entirely too willing to convert almost anything to bool. +*/ +//@{ + + /*! \brief Default constructor */ + + CoinParam() ; + + /*! \brief Constructor for a parameter with a double value + + The default value is 0.0. Be careful to clearly indicate that \p lower and + \p upper are real (double) values to distinguish this constructor from the + constructor for an integer parameter. + */ + CoinParam(std::string name, std::string help, + double lower, double upper, double dflt = 0.0, + bool display = true) ; + + /*! \brief Constructor for a parameter with an integer value + + The default value is 0. + */ + CoinParam(std::string name, std::string help, + int lower, int upper, int dflt = 0, + bool display = true) ; + + /*! \brief Constructor for a parameter with keyword values + + The string supplied as \p firstValue becomes the first value-keyword. + Additional value-keywords can be added using appendKwd(). It's necessary + to specify both the first value-keyword (\p firstValue) and the default + value-keyword index (\p dflt) in order to distinguish this constructor + from the constructors for string and action parameters. + + Value-keywords are associated with an integer, starting with zero and + increasing as each keyword is added. The value-keyword given as \p + firstValue will be associated with the integer zero. The integer supplied + for \p dflt can be any value, as long as it will be valid once all + value-keywords have been added. + */ + CoinParam(std::string name, std::string help, + std::string firstValue, int dflt, bool display = true) ; + + /*! \brief Constructor for a string parameter + + For some compilers, the default value (\p dflt) must be specified + explicitly with type std::string to distinguish the constructor for a + string parameter from the constructor for an action parameter. For + example, use std::string("default") instead of simply "default", or use a + variable of type std::string. + */ + CoinParam(std::string name, std::string help, + std::string dflt, bool display = true) ; + + /*! \brief Constructor for an action parameter */ + + CoinParam(std::string name, std::string help, + bool display = true) ; + + /*! \brief Copy constructor */ + + CoinParam(const CoinParam &orig) ; + + /*! \brief Clone */ + + virtual CoinParam *clone() ; + + /*! \brief Assignment */ + + CoinParam &operator=(const CoinParam &rhs) ; + + /*! \brief Destructor */ + + virtual ~CoinParam() ; + +//@} + +/*! \name Methods to query and manipulate the value(s) of a parameter */ +//@{ + + /*! \brief Add an additional value-keyword to a keyword parameter */ + + void appendKwd(std::string kwd) ; + + /*! \brief Return the integer associated with the specified value-keyword + + Returns -1 if no value-keywords match the specified string. + */ + int kwdIndex(std::string kwd) const ; + + /*! \brief Return the value-keyword that is the current value of the + keyword parameter + */ + std::string kwdVal() const ; + + /*! \brief Set the value of the keyword parameter using the integer + associated with a value-keyword. + + If \p printIt is true, the corresponding value-keyword string will be + echoed to std::cout. + */ + void setKwdVal(int value, bool printIt = false) ; + + /*! \brief Set the value of the keyword parameter using a value-keyword + string. + + The given string will be tested against the set of value-keywords for + the parameter using the shortest match rules. + */ + void setKwdVal(const std::string value ) ; + + /*! \brief Prints the set of value-keywords defined for this keyword + parameter + */ + void printKwds() const ; + + + /*! \brief Set the value of a string parameter */ + + void setStrVal(std::string value) ; + + /*! \brief Get the value of a string parameter */ + + std::string strVal() const ; + + + /*! \brief Set the value of a double parameter */ + + void setDblVal(double value) ; + + /*! \brief Get the value of a double parameter */ + + double dblVal() const ; + + + /*! \brief Set the value of a integer parameter */ + + void setIntVal(int value) ; + + /*! \brief Get the value of a integer parameter */ + + int intVal() const ; + + + /*! \brief Add a short help string to a parameter */ + + inline void setShortHelp(const std::string help) { shortHelp_ = help ; } + + /*! \brief Retrieve the short help string */ + + inline std::string shortHelp() const { return (shortHelp_) ; } + + /*! \brief Add a long help message to a parameter + + See printLongHelp() for a description of how messages are broken into + lines. + */ + inline void setLongHelp(const std::string help) { longHelp_ = help ; } + + /*! \brief Retrieve the long help message */ + + inline std::string longHelp() const { return (longHelp_) ; } + + /*! \brief Print long help + + Prints the long help string, plus the valid range and/or keywords if + appropriate. The routine makes a best effort to break the message into + lines appropriate for an 80-character line. Explicit line breaks in the + message will be observed. The short help string will be used if + long help is not available. + */ + void printLongHelp() const ; + +//@} + +/*! \name Methods to query and manipulate a parameter object */ +//@{ + + /*! \brief Return the type of the parameter */ + + inline CoinParamType type() const { return (type_) ; } + + /*! \brief Set the type of the parameter */ + + inline void setType(CoinParamType type) { type_ = type ; } + + /*! \brief Return the parameter keyword (name) string */ + + inline std::string name() const { return (name_) ; } + + /*! \brief Set the parameter keyword (name) string */ + + inline void setName(std::string name) { name_ = name ; processName() ; } + + /*! \brief Check if the specified string matches the parameter keyword (name) + string + + Returns 1 if the string matches and meets the minimum match length, + 2 if the string matches but doesn't meet the minimum match length, + and 0 if the string doesn't match. Matches are \e not case-sensitive. + */ + int matches (std::string input) const ; + + /*! \brief Return the parameter keyword (name) string formatted to show + the minimum match length + + For example, if the parameter name was defined as allow!ableGap, the + string returned by matchName would be allow(ableGap). + */ + std::string matchName() const ; + + /*! \brief Set visibility of parameter + + Intended to control whether the parameter is shown when a list of + parameters is processed. Used by CoinParamUtils::printHelp when printing + help messages for a list of parameters. + */ + inline void setDisplay(bool display) { display_ = display ; } + + /*! \brief Get visibility of parameter */ + + inline bool display() const { return (display_) ; } + + /*! \brief Get push function */ + + inline CoinParamFunc pushFunc() { return (pushFunc_) ; } + + /*! \brief Set push function */ + + inline void setPushFunc(CoinParamFunc func) { pushFunc_ = func ; } + + /*! \brief Get pull function */ + + inline CoinParamFunc pullFunc() { return (pullFunc_) ; } + + /*! \brief Set pull function */ + + inline void setPullFunc(CoinParamFunc func) { pullFunc_ = func ; } + +//@} + +private: + +/*! \name Private methods */ +//@{ + + /*! Process a name for efficient matching */ + void processName() ; + +//@} + +/*! \name Private parameter data */ +//@{ + /// Parameter type (see #CoinParamType) + CoinParamType type_ ; + + /// Parameter name + std::string name_ ; + + /// Length of parameter name + size_t lengthName_ ; + + /*! \brief Minimum length required to declare a match for the parameter + name. + */ + size_t lengthMatch_ ; + + /// Lower bound on value for a double parameter + double lowerDblValue_ ; + + /// Upper bound on value for a double parameter + double upperDblValue_ ; + + /// Double parameter - current value + double dblValue_ ; + + /// Lower bound on value for an integer parameter + int lowerIntValue_ ; + + /// Upper bound on value for an integer parameter + int upperIntValue_ ; + + /// Integer parameter - current value + int intValue_ ; + + /// String parameter - current value + std::string strValue_ ; + + /// Set of valid value-keywords for a keyword parameter + std::vector definedKwds_ ; + + /*! \brief Current value for a keyword parameter (index into #definedKwds_) + */ + int currentKwd_ ; + + /// Push function + CoinParamFunc pushFunc_ ; + + /// Pull function + CoinParamFunc pullFunc_ ; + + /// Short help + std::string shortHelp_ ; + + /// Long help + std::string longHelp_ ; + + /// Display when processing lists of parameters? + bool display_ ; +//@} + +} ; + +/*! \relatesalso CoinParam + \brief A type for a parameter vector. +*/ +typedef std::vector CoinParamVec ; + +/*! \relatesalso CoinParam + \brief A stream output function for a CoinParam object. +*/ +std::ostream &operator<< (std::ostream &s, const CoinParam ¶m) ; + +/* + Bring in the utility functions for parameter handling (CbcParamUtils). +*/ + +/*! \brief Utility functions for processing CoinParam parameters. + + The functions in CoinParamUtils support command line or interactive + parameter processing and a help facility. Consult the `Related Functions' + section of the CoinParam class documentation for individual function + documentation. +*/ +namespace CoinParamUtils { + /*! \relatesalso CoinParam + \brief Take command input from the file specified by src. + + Use stdin for \p src to specify interactive prompting for commands. + */ + void setInputSrc(FILE *src) ; + + /*! \relatesalso CoinParam + \brief Returns true if command line parameters are being processed. + */ + bool isCommandLine() ; + + /*! \relatesalso CoinParam + \brief Returns true if parameters are being obtained from stdin. + */ + bool isInteractive() ; + + /*! \relatesalso CoinParam + \brief Attempt to read a string from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if a string is parsed + without error, 2 if no field is present. + */ + std::string getStringField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Attempt to read an integer from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if an integer is parsed + without error, 1 if there's a parse error, and 2 if no field is present. + */ + int getIntField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Attempt to read a real (double) from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if a real number is parsed + without error, 1 if there's a parse error, and 2 if no field is present. + */ + double getDoubleField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Scan a parameter vector for parameters whose keyword (name) string + matches \p name using minimal match rules. + + \p matchNdx is set to the index of the last parameter that meets the + minimal match criteria (but note there should be at most one matching + parameter if the parameter vector is properly configured). \p shortCnt + is set to the number of short matches (should be zero for a properly + configured parameter vector if a minimal match is found). The return + value is the number of matches satisfying the minimal match requirement + (should be 0 or 1 in a properly configured vector). + */ + int matchParam(const CoinParamVec ¶mVec, std::string name, + int &matchNdx, int &shortCnt) ; + + /*! \relatesalso CoinParam + \brief Get the next command keyword (name) + + To be precise, return the next field from the current command input + source, after a bit of processing. In command line mode (isCommandLine() + returns true) the next field will normally be of the form `-keyword' or + `--keyword' (\e i.e., a parameter keyword), and the string returned would + be `keyword'. In interactive mode (isInteractive() returns true), the + user will be prompted if necessary. It is assumed that the user knows + not to use the `-' or `--' prefixes unless specifying parameters on the + command line. + + There are a number of special cases if we're in command line mode. The + order of processing of the raw string goes like this: +
    +
  • A stand-alone `-' is forced to `stdin'. +
  • A stand-alone '--' is returned as a word; interpretation is up to + the client. +
  • A prefix of '-' or '--' is stripped from the string. +
+ If the result is the string `stdin', command processing shifts to + interactive mode and the user is immediately prompted for a new command. + + Whatever results from the above sequence is returned to the user as the + return value of the function. An empty string indicates end of input. + + \p prompt will be used only if it's necessary to prompt the user in + interactive mode. + */ + + std::string getCommand(int argc, const char *argv[], + const std::string prompt, std::string *pfx = 0) ; + + /*! \relatesalso CoinParam + \brief Look up the command keyword (name) in the parameter vector. + Print help if requested. + + In the most straightforward use, \p name is a string without `?', and the + value returned is the index in \p paramVec of the single parameter that + matched \p name. One or more '?' characters at the end of \p name is a + query for information. The routine prints short (one '?') or long (more + than one '?') help messages for a query. Help is also printed in the case + where the name is ambiguous (some of the matches did not meet the minimal + match length requirement). + + Note that multiple matches meeting the minimal match requirement is a + configuration error. The mimimal match length for the parameters + involved is too short. + + If provided as parameters, on return +
    +
  • \p matchCnt will be set to the number of matches meeting the + minimal match requirement +
  • \p shortCnt will be set to the number of matches that did not + meet the miminal match requirement +
  • \p queryCnt will be set to the number of '?' characters at the + end of the name +
+ + The return values are: +
    +
  • >0: index in \p paramVec of the single unique match for \p name +
  • -1: a query was detected (one or more '?' characters at the end + of \p name +
  • -2: one or more short matches, not a query +
  • -3: no matches, not a query +
  • -4: multiple matches meeting the minimal match requirement + (configuration error) +
+ */ + int lookupParam(std::string name, CoinParamVec ¶mVec, + int *matchCnt = 0, int *shortCnt = 0, int *queryCnt = 0) ; + + /*! \relatesalso CoinParam + \brief Utility to print a long message as filled lines of text + + The routine makes a best effort to break lines without exceeding the + standard 80 character line length. Explicit newlines in \p msg will + be obeyed. + */ + void printIt(const char *msg) ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help given a short match or explicit + request for help. + + The two really are related, in that a query (a string that ends with + one or more `?' characters) will often result in a short match. The + routine expects that \p name matches a single parameter, and does not + look for multiple matches. + + If called with \p matchNdx < 0, the routine will look up \p name in \p + paramVec and print the full name from the parameter. If called with \p + matchNdx > 0, it just prints the name from the specified parameter. If + the name is a query, short (one '?') or long (more than one '?') help + is printed. + + */ void shortOrHelpOne(CoinParamVec ¶mVec,int matchNdx, std::string + name, int numQuery) ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help given multiple matches. + + If the name is not a query, or asks for short help (\e i.e., contains + zero or one '?' characters), the list of matching names is printed. If + the name asks for long help (contains two or more '?' characters), + short help is printed for each matching name. + */ + void shortOrHelpMany(CoinParamVec ¶mVec, + std::string name, int numQuery) ; + + /*! \relatesalso CoinParam + \brief Print a generic `how to use the command interface' help message. + + The message is hard coded to match the behaviour of the parsing utilities. + */ + void printGenericHelp() ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help messages for one or more + parameters. + + Intended as a utility to implement explicit `help' commands. Help will be + printed for all parameters in \p paramVec from \p firstParam to \p + lastParam, inclusive. If \p shortHelp is true, short help messages will + be printed. If \p longHelp is true, long help messages are printed. \p + shortHelp overrules \p longHelp. If neither is true, only command + keywords are printed. \p prefix is printed before each line; it's an + imperfect attempt at indentation. + */ + void printHelp(CoinParamVec ¶mVec, int firstParam, int lastParam, + std::string prefix, + bool shortHelp, bool longHelp, bool hidden) ; +} + + +#endif /* CoinParam_H */ + diff --git a/thirdparty/linux/include/coin/CoinPragma.hpp b/thirdparty/linux/include/coin/CoinPragma.hpp new file mode 100644 index 0000000..b9f8cd2 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPragma.hpp @@ -0,0 +1,26 @@ +/* $Id: CoinPragma.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPragma_H +#define CoinPragma_H + +//------------------------------------------------------------------- +// +// This is a file which can contain Pragma's that are +// generally applicable to any source file. +// +//------------------------------------------------------------------- + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +// Turn off compiler warning: +// "empty controlled statement found; is this the intent?" +# pragma warning(disable:4390) +// Turn off compiler warning about deprecated functions +# pragma warning(disable:4996) +#endif + +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveDoubleton.hpp b/thirdparty/linux/include/coin/CoinPresolveDoubleton.hpp new file mode 100644 index 0000000..3ad8cd2 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveDoubleton.hpp @@ -0,0 +1,73 @@ +/* $Id: CoinPresolveDoubleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDoubleton_H +#define CoinPresolveDoubleton_H + +#define DOUBLETON 5 + +/*! \class doubleton_action + \brief Solve ax+by=c for y and substitute y out of the problem. + + This moves the bounds information for y onto x, making y free and allowing + us to substitute it away. + \verbatim + a x + b y = c + l1 <= x <= u1 + l2 <= y <= u2 ==> + + l2 <= (c - a x) / b <= u2 + b/-a > 0 ==> (b l2 - c) / -a <= x <= (b u2 - c) / -a + b/-a < 0 ==> (b u2 - c) / -a <= x <= (b l2 - c) / -a + \endverbatim +*/ +class doubleton_action : public CoinPresolveAction { + public: + struct action { + + double clox; + double cupx; + double costx; + + double costy; + + double rlo; + + double coeffx; + double coeffy; + + double *colel; + + int icolx; + int icoly; + int row; + int ncolx; + int ncoly; + }; + + const int nactions_; + const action *const actions_; + + private: + doubleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("doubleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~doubleton_action(); +}; +#endif + + diff --git a/thirdparty/linux/include/coin/CoinPresolveDual.hpp b/thirdparty/linux/include/coin/CoinPresolveDual.hpp new file mode 100644 index 0000000..b021ce0 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveDual.hpp @@ -0,0 +1,85 @@ +/* $Id: CoinPresolveDual.hpp 1510 2011-12-08 23:56:01Z lou $ */ + +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDual_H +#define CoinPresolveDual_H + +/*! \class remove_dual_action + \brief Attempt to fix variables by bounding reduced costs + + The reduced cost of x_j is d_j = c_j - y*a_j (1). Assume minimization, + so that at optimality d_j >= 0 for x_j nonbasic at lower bound, and + d_j <= 0 for x_j nonbasic at upper bound. + + For a slack variable s_i, c_(n+i) = 0 and a_(n+i) is a unit vector, hence + d_(n+i) = -y_i. If s_i has a finite lower bound and no upper bound, we + must have y_i <= 0 at optimality. Similarly, if s_i has no lower bound and a + finite upper bound, we must have y_i >= 0. + + For a singleton variable x_j, d_j = c_j - y_i*a_ij. Given x_j with a + single finite bound, we can bound d_j greater or less than 0 at + optimality, and that allows us to calculate an upper or lower bound on y_i + (depending on the bound on d_j and the sign of a_ij). + + Now we have bounds on some subset of the y_i, and we can use these to + calculate upper and lower bounds on the d_j, using bound propagation on + (1). If we can manage to bound some d_j as strictly positive or strictly + negative, then at optimality the corresponding variable must be nonbasic + at its lower or upper bound, respectively. If the required bound is lacking, + the problem is unbounded. +*/ + +class remove_dual_action : public CoinPresolveAction { + + public: + + /// Destructor + ~remove_dual_action () ; + + /// Name + inline const char *name () const { return ("remove_dual_action") ; } + + /*! \brief Attempt to fix variables by bounding reduced costs + + Always scans all variables. Propagates bounds on reduced costs until there's + no change or until some set of variables can be fixed. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + + /*! \brief Postsolve + + In addition to fixing variables (handled by make_fixed_action), we may + need use our own postsolve to restore constraint bounds. + */ + void postsolve (CoinPostsolveMatrix *prob) const ; + + private: + + /// Postsolve (bound restore) instruction + struct action { + double rlo_ ; ///< restored row lower bound + double rup_ ; ///< restored row upper bound + int ndx_ ; ///< row index + } ; + + /// Constructor with postsolve actions. + remove_dual_action(int nactions, const action *actions, + const CoinPresolveAction *next) + : CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) + {} + + /// Count of bound restore entries + const int nactions_ ; + /// Bound restore entries + const action *actions_ ; + +} ; +#endif + + diff --git a/thirdparty/linux/include/coin/CoinPresolveDupcol.hpp b/thirdparty/linux/include/coin/CoinPresolveDupcol.hpp new file mode 100644 index 0000000..16d3c91 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveDupcol.hpp @@ -0,0 +1,226 @@ +/* $Id: CoinPresolveDupcol.hpp 1817 2015-03-22 16:43:28Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDupcol_H +#define CoinPresolveDupcol_H + +#include "CoinPresolveMatrix.hpp" + +/*! + \file +*/ + +#define DUPCOL 10 + +/*! \class dupcol_action + \brief Detect and remove duplicate columns + + The general technique is to sum the coefficients a_(*,j) of each column. + Columns with identical sums are duplicates. The obvious problem is that, + e.g., [1 0 1 0] and [0 1 0 1] both add to 2. To minimize the + chances of false positives, the coefficients of each row are multipled by + a random number r_i, so that we sum r_i*a_ij. + + Candidate columns are checked to confirm they are identical. Where the + columns have the same objective coefficient, the two are combined. If the + columns have different objective coefficients, complications ensue. In order + to remove the duplicate, it must be possible to fix the variable at a bound. +*/ + +class dupcol_action : public CoinPresolveAction { + dupcol_action(); + dupcol_action(const dupcol_action& rhs); + dupcol_action& operator=(const dupcol_action& rhs); + + struct action { + double thislo; + double thisup; + double lastlo; + double lastup; + int ithis; + int ilast; + + double *colels; + int nincol; + }; + + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + + dupcol_action(int nactions, const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~dupcol_action(); + +}; + + +/*! \class duprow_action + \brief Detect and remove duplicate rows + + The algorithm to detect duplicate rows is as outlined for dupcol_action. + + If the feasible interval for one constraint is strictly contained in the + other, the tighter (contained) constraint is kept. If the feasible + intervals are disjoint, the problem is infeasible. If the feasible + intervals overlap, both constraints are kept. + + duprow_action is definitely a work in progress; #postsolve is + unimplemented. + This doesn't matter as it uses useless_constraint. +*/ + +class duprow_action : public CoinPresolveAction { + struct action { + int row; + double lbound; + double ubound; + }; + + const int nactions_; + const action *const actions_; + + duprow_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + duprow_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + //~duprow_action() { delete[]actions_; } +}; + +class duprow3_action : public CoinPresolveAction { + struct action { + int row; + double lbound; + double ubound; + }; + + const int nactions_; + const action *const actions_; + + duprow3_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + duprow3_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + //~duprow_action() { delete[]actions_; } +}; + +/*! \class gubrow_action + \brief Detect and remove entries whose sum is known + + If we have an equality row where all entries same then + For other rows where all entries for that equality row are same + then we can delete entries and modify rhs + gubrow_action is definitely a work in progress; #postsolve is + unimplemented. +*/ + +class gubrow_action : public CoinPresolveAction { + struct action { + int row; + double lbound; + double ubound; + }; + + const int nactions_; + const action *const actions_; + + gubrow_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + gubrow_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + //~gubrow_action() { delete[]actions_; } +}; + +/*! \class twoxtwo_action + \brief Detect interesting 2 by 2 blocks + + If a variable has two entries and for each row there are only + two entries with same other variable then we can get rid of + one constraint and modify costs. + + This is a work in progress - I need more examples +*/ + +class twoxtwo_action : public CoinPresolveAction { + struct action { + double lbound_row; + double ubound_row; + double lbound_col; + double ubound_col; + double cost_col; + double cost_othercol; + int row; + int col; + int othercol; + }; + + const int nactions_; + const action *const actions_; + + twoxtwo_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + twoxtwo_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + ~twoxtwo_action() { delete [] actions_; } +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CoinPresolveEmpty.hpp b/thirdparty/linux/include/coin/CoinPresolveEmpty.hpp new file mode 100644 index 0000000..336f1fd --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveEmpty.hpp @@ -0,0 +1,116 @@ +/* $Id: CoinPresolveEmpty.hpp 1561 2012-11-24 00:32:16Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveEmpty_H +#define CoinPresolveEmpty_H + +/*! \file + + Drop/reinsert empty rows/columns. +*/ + +const int DROP_ROW = 3; +const int DROP_COL = 4; + +/*! \class drop_empty_cols_action + \brief Physically removes empty columns in presolve, and reinserts + empty columns in postsolve. + + Physical removal of rows and columns should be the last activities + performed during presolve. Do them exactly once. The row-major matrix + is not maintained by this transform. + + To physically drop the columns, CoinPrePostsolveMatrix::mcstrt_ and + CoinPrePostsolveMatrix::hincol_ are compressed, along with column bounds, + objective, and (if present) the column portions of the solution. This + renumbers the columns. drop_empty_cols_action::presolve will reconstruct + CoinPresolveMatrix::clink_. + + \todo Confirm correct behaviour with solution in presolve. +*/ + +class drop_empty_cols_action : public CoinPresolveAction { +private: + const int nactions_; + + struct action { + double clo; + double cup; + double cost; + double sol; + int jcol; + }; + const action *const actions_; + + drop_empty_cols_action(int nactions, + const action *const actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) + {} + + public: + const char *name() const { return ("drop_empty_cols_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const int *ecols, + int necols, + const CoinPresolveAction*); + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_empty_cols_action() { deleteAction(actions_,action*); } +}; + + +/*! \class drop_empty_rows_action + \brief Physically removes empty rows in presolve, and reinserts + empty rows in postsolve. + + Physical removal of rows and columns should be the last activities + performed during presolve. Do them exactly once. The row-major matrix + is not maintained by this transform. + + To physically drop the rows, the rows are renumbered, excluding empty + rows. This involves rewriting CoinPrePostsolveMatrix::hrow_ and compressing + the row bounds and (if present) the row portions of the solution. + + \todo Confirm behaviour when a solution is present in presolve. +*/ +class drop_empty_rows_action : public CoinPresolveAction { +private: + struct action { + double rlo; + double rup; + int row; + int fill_row; // which row was moved into position row to fill it + }; + + const int nactions_; + const action *const actions_; + + drop_empty_rows_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("drop_empty_rows_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_empty_rows_action() { deleteAction(actions_,action*); } +}; +#endif + diff --git a/thirdparty/linux/include/coin/CoinPresolveFixed.hpp b/thirdparty/linux/include/coin/CoinPresolveFixed.hpp new file mode 100644 index 0000000..dc59207 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveFixed.hpp @@ -0,0 +1,181 @@ +/* $Id: CoinPresolveFixed.hpp 1510 2011-12-08 23:56:01Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveFixed_H +#define CoinPresolveFixed_H +#define FIXED_VARIABLE 1 + +/*! \class remove_fixed_action + \brief Excise fixed variables from the model. + + Implements the action of virtually removing one or more fixed variables + x_j from the model by substituting the value sol_j in each constraint. + Specifically, for each constraint i where a_ij != 0, rlo_i and rup_i + are adjusted by -a_ij*sol_j and a_ij is set to 0. + + There is an implicit assumption that the variable already has the correct + value. If this isn't true, corrections to row activity may be incorrect. + If you want to guard against this possibility, consider make_fixed_action. + + Actual removal of the empty column from the matrix is handled by + drop_empty_cols_action. Correction of the objective function is done there. +*/ +class remove_fixed_action : public CoinPresolveAction { + public: + /*! \brief Structure to hold information necessary to reintroduce a + column into the problem representation. + */ + struct action { + int col; ///< column index of variable + int start; ///< start of coefficients in #colels_ and #colrows_ + double sol; ///< value of variable + }; + /// Array of row indices for coefficients of excised columns + int *colrows_; + /// Array of coefficients of excised columns + double *colels_; + /// Number of entries in #actions_ + int nactions_; + /// Vector specifying variable(s) affected by this object + action *actions_; + + private: + /*! \brief Constructor */ + remove_fixed_action(int nactions, + action *actions, + double * colels, + int * colrows, + const CoinPresolveAction *next); + + public: + /// Returns string "remove_fixed_action". + const char *name() const; + + /*! \brief Excise the specified columns. + + Remove the specified columns (\p nfcols, \p fcols) from the problem + representation (\p prob), leaving the appropriate postsolve object + linked as the head of the list of postsolve objects (currently headed + by \p next). + */ + static const remove_fixed_action *presolve(CoinPresolveMatrix *prob, + int *fcols, + int nfcols, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + /// Destructor + virtual ~remove_fixed_action(); +}; + + +/*! \relates remove_fixed_action + \brief Scan the problem for fixed columns and remove them. + + A front end to collect a list of columns with equal bounds and hand them to + remove_fixed_action::presolve() for processing. +*/ + +const CoinPresolveAction *remove_fixed(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + +/*! \class make_fixed_action + \brief Fix a variable at a specified bound. + + Implements the action of fixing a variable by forcing both bounds to the same + value and forcing the value of the variable to match. + + If the bounds are already equal, and the value of the variable is already + correct, consider remove_fixed_action. +*/ +class make_fixed_action : public CoinPresolveAction { + + /// Structure to preserve the bound overwritten when fixing a variable + struct action { + double bound; ///< Value of bound overwritten to fix variable. + int col ; ///< column index of variable + }; + + /// Number of preserved bounds + int nactions_; + /// Vector of preserved bounds, one for each variable fixed in this object + const action *actions_; + + /*! \brief True to fix at lower bound, false to fix at upper bound. + + Note that this applies to all variables fixed in this object. + */ + const bool fix_to_lower_; + + /*! \brief The postsolve object with the information required to repopulate + the fixed columns. + */ + const remove_fixed_action *faction_; + + /*! \brief Constructor */ + make_fixed_action(int nactions, const action *actions, bool fix_to_lower, + const remove_fixed_action *faction, + const CoinPresolveAction *next) + : CoinPresolveAction(next), + nactions_(nactions), actions_(actions), + fix_to_lower_(fix_to_lower), + faction_(faction) + {} + + public: + /// Returns string "make_fixed_action". + const char *name() const; + + /*! \brief Perform actions to fix variables and return postsolve object + + For each specified variable (\p nfcols, \p fcols), fix the variable to + the specified bound (\p fix_to_lower) by setting the variable's bounds + to be equal in \p prob. Create a postsolve object, link it at the head of + the list of postsolve objects (\p next), and return the object. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + int *fcols, + int nfcols, + bool fix_to_lower, + const CoinPresolveAction *next); + + /*! \brief Postsolve (unfix variables) + + Back out the variables fixed by the presolve side of this object. + */ + void postsolve(CoinPostsolveMatrix *prob) const; + + /// Destructor + virtual ~make_fixed_action() { + deleteAction(actions_,action*); + delete faction_; + } +}; + +/*! \relates make_fixed_action + \brief Scan variables and fix any with equal bounds + + A front end to collect a list of columns with equal bounds and hand them to + make_fixed_action::presolve() for processing. +*/ + +const CoinPresolveAction *make_fixed(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + +/*! \brief Transfer costs from singleton variables + \relates make_fixed_action + + Transfers costs from singleton variables in equalities onto the other + variables. Will also transfer costs from one integer variable to other + integer variables with zero cost if there's a net gain in integer variables + with non-zero cost. + + The relation to make_fixed_action is tenuous, but this transform should be + attempted before the initial round of variable fixing. +*/ +void transferCosts(CoinPresolveMatrix * prob); +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveForcing.hpp b/thirdparty/linux/include/coin/CoinPresolveForcing.hpp new file mode 100644 index 0000000..ee5a641 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveForcing.hpp @@ -0,0 +1,61 @@ +/* $Id: CoinPresolveForcing.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveForcing_H +#define CoinPresolveForcing_H + +#include "CoinPresolveMatrix.hpp" + +/*! + \file +*/ + +#define IMPLIED_BOUND 7 + +/*! \class forcing_constraint_action + \brief Detect and process forcing constraints and useless constraints + + A constraint is useless if the bounds on the variables prevent the constraint + from ever being violated. + + A constraint is a forcing constraint if the bounds on the constraint force + the value of an involved variable to one of its bounds. A constraint can + force more than one variable. +*/ +class forcing_constraint_action : public CoinPresolveAction { + forcing_constraint_action(); + forcing_constraint_action(const forcing_constraint_action& rhs); + forcing_constraint_action& operator=(const forcing_constraint_action& rhs); +public: + struct action { + const int *rowcols; + const double *bounds; + int row; + int nlo; + int nup; + }; +private: + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + +public: + forcing_constraint_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~forcing_constraint_action(); +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveImpliedFree.hpp b/thirdparty/linux/include/coin/CoinPresolveImpliedFree.hpp new file mode 100644 index 0000000..8215b98 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveImpliedFree.hpp @@ -0,0 +1,60 @@ +/* $Id: CoinPresolveImpliedFree.hpp 1694 2014-04-29 02:08:35Z tkr $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveImpliedFree_H +#define CoinPresolveImpliedFree_H + +/*! + \file +*/ + +#define IMPLIED_FREE 9 + +/*! \class implied_free_action + \brief Detect and process implied free variables + + Consider a singleton variable x (i.e., a variable involved in only + one constraint). Suppose that the bounds on that constraint, combined with + the bounds on the other variables involved in the constraint, are such that + even the worst case values of the other variables still imply bounds for x + which are tighter than the variable's original bounds. Since x can never + reach its upper or lower bounds, it is an implied free variable. Both x and + the constraint can be deleted from the problem. + + A similar transform for the case where the variable is not a natural column + singleton is handled by #subst_constraint_action. +*/ +class implied_free_action : public CoinPresolveAction { + struct action { + int row, col; + double clo, cup; + double rlo, rup; + const double *rowels; + const double *costs; + int ninrow; + }; + + const int nactions_; + const action *const actions_; + + implied_free_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const CoinPresolveAction *next, + int & fillLevel); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~implied_free_action(); +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveIsolated.hpp b/thirdparty/linux/include/coin/CoinPresolveIsolated.hpp new file mode 100644 index 0000000..38c700f --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveIsolated.hpp @@ -0,0 +1,51 @@ +/* $Id: CoinPresolveIsolated.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveIsolated_H +#define CoinPresolveIsolated_H + +#include "CoinPresolveMatrix.hpp" + +class isolated_constraint_action : public CoinPresolveAction { + isolated_constraint_action(); + isolated_constraint_action(const isolated_constraint_action& rhs); + isolated_constraint_action& operator=(const isolated_constraint_action& rhs); + + double rlo_; + double rup_; + int row_; + int ninrow_; + // the arrays are owned by the class and must be deleted at destruction + const int *rowcols_; + const double *rowels_; + const double *costs_; + + isolated_constraint_action(double rlo, + double rup, + int row, + int ninrow, + const int *rowcols, + const double *rowels, + const double *costs, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + rlo_(rlo), rup_(rup), row_(row), ninrow_(ninrow), + rowcols_(rowcols), rowels_(rowels), costs_(costs) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + int row, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~isolated_constraint_action(); +}; + + + +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveMatrix.hpp b/thirdparty/linux/include/coin/CoinPresolveMatrix.hpp new file mode 100644 index 0000000..e608738 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveMatrix.hpp @@ -0,0 +1,1842 @@ +/* $Id: CoinPresolveMatrix.hpp 1761 2014-12-10 09:43:07Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveMatrix_H +#define CoinPresolveMatrix_H + +#include "CoinPragma.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinMessage.hpp" +#include "CoinTime.hpp" + +#include +#include +#include +#include +#include + +#if PRESOLVE_DEBUG > 0 +#include "CoinFinite.hpp" +#endif + +/*! \file + + Declarations for CoinPresolveMatrix and CoinPostsolveMatrix and their + common base class CoinPrePostsolveMatrix. Also declarations for + CoinPresolveAction and a number of non-member utility functions. +*/ + + +#if defined(_MSC_VER) +// Avoid MS Compiler problem in recognizing type to delete +// by casting to type. +// Is this still necessary? -- lh, 111202 -- +#define deleteAction(array,type) delete [] ((type) array) +#else +#define deleteAction(array,type) delete [] array +#endif + +/* + Define PRESOLVE_DEBUG and PRESOLVE_CONSISTENCY on the configure command + line or in a Makefile! See comments in CoinPresolvePsdebug.hpp. +*/ +#if PRESOLVE_DEBUG > 0 || PRESOLVE_CONSISTENCY > 0 + +#define PRESOLVE_STMT(s) s + +#define PRESOLVEASSERT(x) \ + ((x) ? 1 : ((std::cerr << "FAILED ASSERTION at line " \ + << __LINE__ << ": " #x "\n"), abort(), 0)) + +inline void DIE(const char *s) { std::cout << s ; abort() ; } + +/*! \brief Indicate column or row present at start of postsolve + + This code is used during postsolve in [cr]done to indicate columns and rows + that are present in the presolved system (i.e., present at the start of + postsolve processing). + + \todo + There are a bunch of these code definitions, scattered through presolve + files. They should be collected in one place. +*/ +#define PRESENT_IN_REDUCED '\377' + +#else + +#define PRESOLVEASSERT(x) {} +#define PRESOLVE_STMT(s) {} + +inline void DIE(const char *) {} + +#endif + +/* + Unclear why these are separate from standard debug. +*/ +#ifndef PRESOLVE_DETAIL +#define PRESOLVE_DETAIL_PRINT(s) {} +#else +#define PRESOLVE_DETAIL_PRINT(s) s +#endif + +/*! \brief Zero tolerance + + OSL had a fixed zero tolerance; we still use that here. +*/ +const double ZTOLDP = 1e-12 ; +/*! \brief Alternate zero tolerance + + Use a different one if we are doing doubletons, etc. +*/ +const double ZTOLDP2 = 1e-10 ; + +/// The usual finite infinity +#define PRESOLVE_INF COIN_DBL_MAX +/// And a small infinity +#define PRESOLVE_SMALL_INF 1.0e20 +/// Check for infinity using finite infinity +#define PRESOLVEFINITE(n) (-PRESOLVE_INF < (n) && (n) < PRESOLVE_INF) + + +class CoinPostsolveMatrix ; + +/*! \class CoinPresolveAction + \brief Abstract base class of all presolve routines. + + The details will make more sense after a quick overview of the grand plan: + A presolve object is handed a problem object, which it is expected to + modify in some useful way. Assuming that it succeeds, the presolve object + should create a postsolve object, i.e., an object that contains + instructions for backing out the presolve transform to recover the original + problem. These postsolve objects are accumulated in a linked list, with each + successive presolve action adding its postsolve action to the head of the + list. The end result of all this is a presolved problem object, and a list + of postsolve objects. The presolved problem object is then handed to a + solver for optimization, and the problem object augmented with the + results. The list of postsolve objects is then traversed. Each of them + (un)modifies the problem object, with the end result being the original + problem, augmented with solution information. + + The problem object representation is CoinPrePostsolveMatrix and subclasses. + Check there for details. The \c CoinPresolveAction class and subclasses + represent the presolve and postsolve objects. + + In spite of the name, the only information held in a \c CoinPresolveAction + object is the information needed to postsolve (i.e., the information + needed to back out the presolve transformation). This information is not + expected to change, so the fields are all \c const. + + A subclass of \c CoinPresolveAction, implementing a specific pre/postsolve + action, is expected to declare a static function that attempts to perform a + presolve transformation. This function will be handed a CoinPresolveMatrix + to transform, and a pointer to the head of the list of postsolve objects. + If the transform is successful, the function will create a new + \c CoinPresolveAction object, link it at the head of the list of postsolve + objects, and return a pointer to the postsolve object it has just created. + Otherwise, it should return 0. It is expected that these static functions + will be the only things that can create new \c CoinPresolveAction objects; + this is expressed by making each subclass' constructor(s) private. + + Every subclass must also define a \c postsolve method. + This function will be handed a CoinPostsolveMatrix to transform. + + It is the client's responsibility to implement presolve and postsolve driver + routines. See OsiPresolve for examples. + + \note Since the only fields in a \c CoinPresolveAction are \c const, anything + one can do with a variable declared \c CoinPresolveAction* can also be + done with a variable declared \c const \c CoinPresolveAction* It is + expected that all derived subclasses of \c CoinPresolveAction also have + this property. +*/ +class CoinPresolveAction +{ + public: + /*! \brief Stub routine to throw exceptions. + + Exceptions are inefficient, particularly with g++. Even with xlC, the + use of exceptions adds a long prologue to a routine. Therefore, rather + than use throw directly in the routine, I use it in a stub routine. + */ + static void throwCoinError(const char *error, const char *ps_routine) + { throw CoinError(error, ps_routine, "CoinPresolve"); } + + /*! \brief The next presolve transformation + + Set at object construction. + */ + const CoinPresolveAction *next; + + /*! \brief Construct a postsolve object and add it to the transformation list. + + This is an `add to head' operation. This object will point to the + one passed as the parameter. + */ + CoinPresolveAction(const CoinPresolveAction *next) : next(next) {} + /// modify next (when building rather than passing) + inline void setNext(const CoinPresolveAction *nextAction) + { next = nextAction;} + + /*! \brief A name for debug printing. + + It is expected that the name is not stored in the transform itself. + */ + virtual const char *name() const = 0; + + /*! \brief Apply the postsolve transformation for this particular + presolve action. + */ + virtual void postsolve(CoinPostsolveMatrix *prob) const = 0; + + /*! \brief Virtual destructor. */ + virtual ~CoinPresolveAction() {} +}; + +/* + These are needed for OSI-aware constructors associated with + CoinPrePostsolveMatrix, CoinPresolveMatrix, and CoinPostsolveMatrix. +*/ +class ClpSimplex; +class OsiSolverInterface; + +/* + CoinWarmStartBasis is required for methods in CoinPrePostsolveMatrix + that accept/return a CoinWarmStartBasis object. +*/ +class CoinWarmStartBasis ; + +/*! \class CoinPrePostsolveMatrix + \brief Collects all the information about the problem that is needed + in both presolve and postsolve. + + In a bit more detail, a column-major representation of the constraint + matrix and upper and lower bounds on variables and constraints, plus row + and column solutions, reduced costs, and status. There's also a set of + arrays holding the original row and column numbers. + + As presolve and postsolve transform the matrix, it will occasionally be + necessary to expand the number of entries in a column. There are two + aspects: +
    +
  • During postsolve, the constraint system is expected to grow as + the smaller presolved system is transformed back to the original + system. +
  • During both pre- and postsolve, transforms can increase the number + of coefficients in a row or column. (See the + variable substitution, doubleton, and tripleton transforms.) +
+ + The first is addressed by the members #ncols0_, #nrows0_, and #nelems0_. + These should be set (via constructor parameters) to values large enough + for the largest size taken on by the constraint system. Typically, this + will be the size of the original constraint system. + + The second is addressed by a generous allocation of extra (empty) space + for the arrays used to hold coefficients and row indices. When columns + must be expanded, they are moved into the empty space. When it is used up, + the arrays are compacted. When compaction fails to produce sufficient + space, presolve/postsolve will fail. + + CoinPrePostsolveMatrix isn't really intended to be used `bare' --- the + expectation is that it'll be used through CoinPresolveMatrix or + CoinPostsolveMatrix. Some of the functions needed to load a problem are + defined in the derived classes. + + When CoinPresolve is applied when reoptimising, we need to be prepared to + accept a basis and modify it in step with the presolve actions (otherwise + we throw away all the advantages of warm start for reoptimization). But + other solution components (#acts_, #rowduals_, #sol_, and #rcosts_) are + needed only for postsolve, where they're used in places to determine the + proper action(s) when restoring rows or columns. If presolve is provided + with a solution, it will modify it in step with the presolve actions. + Moving the solution components from CoinPrePostsolveMatrix to + CoinPostsolveMatrix would break a lot of code. It's not clear that it's + worth it, and it would preclude upgrades to the presolve side that might + make use of any of these. -- lh, 080501 -- + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ + +class CoinPrePostsolveMatrix +{ + public: + + /*! \name Constructors & Destructors */ + + //@{ + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. On + the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPrePostsolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPrePostsolveMatrix(const OsiSolverInterface * si, + int ncols_, + int nrows_, + CoinBigIndex nelems_); + + /*! ClpOsi constructor + + See Clp code for the definition. + */ + CoinPrePostsolveMatrix(const ClpSimplex * si, + int ncols_, + int nrows_, + CoinBigIndex nelems_, + double bulkRatio); + + /// Destructor + ~CoinPrePostsolveMatrix(); + //@} + + /*! \brief Enum for status of various sorts + + Matches CoinWarmStartBasis::Status and adds superBasic. Most code that + converts between CoinPrePostsolveMatrix::Status and + CoinWarmStartBasis::Status will break if this correspondence is broken. + + superBasic is an unresolved problem: there's no analogue in + CoinWarmStartBasis::Status. + */ + enum Status { + isFree = 0x00, + basic = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03, + superBasic = 0x04 + }; + + /*! \name Functions to work with variable status + + Functions to work with the CoinPrePostsolveMatrix::Status enum and + related vectors. + + \todo + Why are we futzing around with three bit status? A holdover from the + packed arrays of CoinWarmStartBasis? Big swaths of the presolve code + manipulates colstat_ and rowstat_ as unsigned char arrays using simple + assignment to set values. + */ + //@{ + + /// Set row status (i.e., status of artificial for this row) + inline void setRowStatus(int sequence, Status status) + { + unsigned char & st_byte = rowstat_[sequence]; + st_byte = static_cast(st_byte & (~7)) ; + st_byte = static_cast(st_byte | status) ; + } + /// Get row status + inline Status getRowStatus(int sequence) const + {return static_cast (rowstat_[sequence]&7);} + /// Check if artificial for this row is basic + inline bool rowIsBasic(int sequence) const + {return (static_cast (rowstat_[sequence]&7)==basic);} + /// Set column status (i.e., status of primal variable) + inline void setColumnStatus(int sequence, Status status) + { + unsigned char & st_byte = colstat_[sequence]; + st_byte = static_cast(st_byte & (~7)) ; + st_byte = static_cast(st_byte | status) ; + +# ifdef PRESOLVE_DEBUG + switch (status) + { case isFree: + { if (clo_[sequence] > -PRESOLVE_INF || cup_[sequence] < PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " isFree, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case basic: + { break ; } + case atUpperBound: + { if (cup_[sequence] >= PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " atUpperBound, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case atLowerBound: + { if (clo_[sequence] <= -PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " atLowerBound, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case superBasic: + { if (clo_[sequence] <= -PRESOLVE_INF && cup_[sequence] >= PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " superBasic, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + default: + { assert(false) ; + break ; } } +# endif + } + /// Get column (structural variable) status + inline Status getColumnStatus(int sequence) const + {return static_cast (colstat_[sequence]&7);} + /// Check if column (structural variable) is basic + inline bool columnIsBasic(int sequence) const + {return (static_cast (colstat_[sequence]&7)==basic);} + /*! \brief Set status of row (artificial variable) to the correct nonbasic + status given bounds and current value + */ + void setRowStatusUsingValue(int iRow); + /*! \brief Set status of column (structural variable) to the correct + nonbasic status given bounds and current value + */ + void setColumnStatusUsingValue(int iColumn); + /*! \brief Set column (structural variable) status vector */ + void setStructuralStatus(const char *strucStatus, int lenParam) ; + /*! \brief Set row (artificial variable) status vector */ + void setArtificialStatus(const char *artifStatus, int lenParam) ; + /*! \brief Set the status of all variables from a basis */ + void setStatus(const CoinWarmStartBasis *basis) ; + /*! \brief Get status in the form of a CoinWarmStartBasis */ + CoinWarmStartBasis *getStatus() ; + /*! \brief Return a print string for status of a column (structural + variable) + */ + const char *columnStatusString(int j) const ; + /*! \brief Return a print string for status of a row (artificial + variable) + */ + const char *rowStatusString(int i) const ; + //@} + + /*! \name Functions to load problem and solution information + + These functions can be used to load portions of the problem definition + and solution. See also the CoinPresolveMatrix and CoinPostsolveMatrix + classes. + */ + //@{ + /// Set the objective function offset for the original system. + void setObjOffset(double offset) ; + /*! \brief Set the objective sense (max/min) + + Coded as 1.0 for min, -1.0 for max. + Yes, there's a method, and a matching attribute. No, you really + don't want to set this to maximise. + */ + void setObjSense(double objSense) ; + /// Set the primal feasibility tolerance + void setPrimalTolerance(double primTol) ; + /// Set the dual feasibility tolerance + void setDualTolerance(double dualTol) ; + /// Set column lower bounds + void setColLower(const double *colLower, int lenParam) ; + /// Set column upper bounds + void setColUpper(const double *colUpper, int lenParam) ; + /// Set column solution + void setColSolution(const double *colSol, int lenParam) ; + /// Set objective coefficients + void setCost(const double *cost, int lenParam) ; + /// Set reduced costs + void setReducedCost(const double *redCost, int lenParam) ; + /// Set row lower bounds + void setRowLower(const double *rowLower, int lenParam) ; + /// Set row upper bounds + void setRowUpper(const double *rowUpper, int lenParam) ; + /// Set row solution + void setRowPrice(const double *rowSol, int lenParam) ; + /// Set row activity + void setRowActivity(const double *rowAct, int lenParam) ; + //@} + + /*! \name Functions to retrieve problem and solution information */ + //@{ + /// Get current number of columns + inline int getNumCols() const + { return (ncols_) ; } + /// Get current number of rows + inline int getNumRows() const + { return (nrows_) ; } + /// Get current number of non-zero coefficients + inline int getNumElems() const + { return (nelems_) ; } + /// Get column start vector for column-major packed matrix + inline const CoinBigIndex *getColStarts() const + { return (mcstrt_) ; } + /// Get column length vector for column-major packed matrix + inline const int *getColLengths() const + { return (hincol_) ; } + /// Get vector of row indices for column-major packed matrix + inline const int *getRowIndicesByCol() const + { return (hrow_) ; } + /// Get vector of elements for column-major packed matrix + inline const double *getElementsByCol() const + { return (colels_) ; } + /// Get column lower bounds + inline const double *getColLower() const + { return (clo_) ; } + /// Get column upper bounds + inline const double *getColUpper() const + { return (cup_) ; } + /// Get objective coefficients + inline const double *getCost() const + { return (cost_) ; } + /// Get row lower bounds + inline const double *getRowLower() const + { return (rlo_) ; } + /// Get row upper bounds + inline const double *getRowUpper() const + { return (rup_) ; } + /// Get column solution (primal variable values) + inline const double *getColSolution() const + { return (sol_) ; } + /// Get row activity (constraint lhs values) + inline const double *getRowActivity() const + { return (acts_) ; } + /// Get row solution (dual variables) + inline const double *getRowPrice() const + { return (rowduals_) ; } + /// Get reduced costs + inline const double *getReducedCost() const + { return (rcosts_) ; } + /// Count empty columns + inline int countEmptyCols() + { int empty = 0 ; + for (int i = 0 ; i < ncols_ ; i++) if (hincol_[i] == 0) empty++ ; + return (empty) ; } + //@} + + + /*! \name Message handling */ + //@{ + /// Return message handler + inline CoinMessageHandler *messageHandler() const + { return handler_; } + /*! \brief Set message handler + + The client retains responsibility for the handler --- it will not be + destroyed with the \c CoinPrePostsolveMatrix object. + */ + inline void setMessageHandler(CoinMessageHandler *handler) + { if (defaultHandler_ == true) + { delete handler_ ; + defaultHandler_ = false ; } + handler_ = handler ; } + /// Return messages + inline CoinMessages messages() const + { return messages_; } + //@} + + /*! \name Current and Allocated Size + + During pre- and postsolve, the matrix will change in size. During presolve + it will shrink; during postsolve it will grow. Hence there are two sets of + size variables, one for the current size and one for the allocated size. + (See the general comments for the CoinPrePostsolveMatrix class for more + information.) + */ + //@{ + + /// current number of columns + int ncols_; + /// current number of rows + int nrows_; + /// current number of coefficients + CoinBigIndex nelems_; + + /// Allocated number of columns + int ncols0_; + /// Allocated number of rows + int nrows0_ ; + /// Allocated number of coefficients + CoinBigIndex nelems0_ ; + /*! \brief Allocated size of bulk storage for row indices and coefficients + + This is the space allocated for hrow_ and colels_. This must be large + enough to allow columns to be copied into empty space when they need to + be expanded. For efficiency (to minimize the number of times the + representation must be compressed) it's recommended that this be at least + 2*nelems0_. + */ + CoinBigIndex bulk0_ ; + /// Ratio of bulk0_ to nelems0_; default is 2. + double bulkRatio_; + //@} + + /*! \name Problem representation + + The matrix is the common column-major format: A pair of vectors with + positional correspondence to hold coefficients and row indices, and a + second pair of vectors giving the starting position and length of each + column in the first pair. + */ + //@{ + /// Vector of column start positions in #hrow_, #colels_ + CoinBigIndex *mcstrt_; + /// Vector of column lengths + int *hincol_; + /// Row indices (positional correspondence with #colels_) + int *hrow_; + /// Coefficients (positional correspondence with #hrow_) + double *colels_; + + /// Objective coefficients + double *cost_; + /// Original objective offset + double originalOffset_; + + /// Column (primal variable) lower bounds + double *clo_; + /// Column (primal variable) upper bounds + double *cup_; + + /// Row (constraint) lower bounds + double *rlo_; + /// Row (constraint) upper bounds + double *rup_; + + /*! \brief Original column numbers + + Over the current range of column numbers in the presolved problem, + the entry for column j will contain the index of the corresponding + column in the original problem. + */ + int * originalColumn_; + /*! \brief Original row numbers + + Over the current range of row numbers in the presolved problem, the + entry for row i will contain the index of the corresponding row in + the original problem. + */ + int * originalRow_; + + /// Primal feasibility tolerance + double ztolzb_; + /// Dual feasibility tolerance + double ztoldj_; + + /*! \brief Maximization/minimization + + Yes, there's a variable here. No, you really don't want to set this to + maximise. See the main notes for CoinPresolveMatrix. + */ + double maxmin_; + //@} + + /*! \name Problem solution information + + The presolve phase will work without any solution information + (appropriate for initial optimisation) or with solution information + (appropriate for reoptimisation). When solution information is supplied, + presolve will maintain it to the best of its ability. #colstat_ is + checked to determine the presence/absence of status information. #sol_ is + checked for primal solution information, and #rowduals_ for dual solution + information. + + The postsolve phase requires the complete solution information from the + presolved problem (status, primal and dual solutions). It will be + transformed into a correct solution for the original problem. + */ + //@{ + /*! \brief Vector of primal variable values + + If #sol_ exists, it is assumed that primal solution information should be + updated and that #acts_ also exists. + */ + double *sol_; + /*! \brief Vector of dual variable values + + If #rowduals_ exists, it is assumed that dual solution information should + be updated and that #rcosts_ also exists. + */ + double *rowduals_; + /*! \brief Vector of constraint left-hand-side values (row activity) + + Produced by evaluating constraints according to #sol_. Updated iff + #sol_ exists. + */ + double *acts_; + /*! \brief Vector of reduced costs + + Produced by evaluating dual constraints according to #rowduals_. Updated + iff #rowduals_ exists. + */ + double *rcosts_; + + /*! \brief Status of primal variables + + Coded with CoinPrePostSolveMatrix::Status, one code per char. colstat_ and + #rowstat_ MUST be allocated as a single vector. This is to maintain + compatibility with ClpPresolve and OsiPresolve, which do it this way. + */ + unsigned char *colstat_; + + /*! \brief Status of constraints + + More accurately, the status of the logical variable associated with the + constraint. Coded with CoinPrePostSolveMatrix::Status, one code per char. + Note that this must be allocated as a single vector with #colstat_. + */ + unsigned char *rowstat_; + //@} + + /*! \name Message handling + + Uses the standard COIN approach: a default handler is installed, and the + CoinPrePostsolveMatrix object takes responsibility for it. If the client + replaces the handler with one of their own, it becomes their + responsibility. + */ + //@{ + /// Message handler + CoinMessageHandler *handler_; + /// Indicates if the current #handler_ is default (true) or not (false). + bool defaultHandler_; + /// Standard COIN messages + CoinMessage messages_; + //@} + +}; + +/*! \relates CoinPrePostsolveMatrix + \brief Generate a print string for a status code. +*/ +const char *statusName (CoinPrePostsolveMatrix::Status status) ; + + +/*! \class presolvehlink + \brief Links to aid in packed matrix modification + + Currently, the matrices held by the CoinPrePostsolveMatrix and + CoinPresolveMatrix objects are represented in the same way as a + CoinPackedMatrix. In the course of presolve and postsolve transforms, it + will happen that a major-dimension vector needs to increase in size. In + order to check whether there is enough room to add another coefficient in + place, it helps to know the next vector (in memory order) in the bulk + storage area. To do that, a linked list of major-dimension vectors is + maintained; the "pre" and "suc" fields give the previous and next vector, + in memory order (that is, the vector whose mcstrt_ or mrstrt_ entry is + next smaller or larger). + + Consider a column-major matrix with ncols columns. By definition, + presolvehlink[ncols].pre points to the column in the last occupied + position of the bulk storage arrays. There is no easy way to find the + column which occupies the first position (there is no presolvehlink[-1] to + consult). If the column that initially occupies the first position is + moved for expansion, there is no way to reclaim the space until the bulk + storage is compacted. The same holds for the last and first rows of a + row-major matrix, of course. +*/ + +class presolvehlink +{ public: + int pre, suc; +} ; + +#define NO_LINK -66666666 + +/*! \relates presolvehlink + \brief unlink vector i + + Remove vector i from the ordering. +*/ +inline void PRESOLVE_REMOVE_LINK(presolvehlink *link, int i) +{ + int ipre = link[i].pre; + int isuc = link[i].suc; + if (ipre >= 0) { + link[ipre].suc = isuc; + } + if (isuc >= 0) { + link[isuc].pre = ipre; + } + link[i].pre = NO_LINK, link[i].suc = NO_LINK; +} + +/*! \relates presolvehlink + \brief insert vector i after vector j + + Insert vector i between j and j.suc. +*/ +inline void PRESOLVE_INSERT_LINK(presolvehlink *link, int i, int j) +{ + int isuc = link[j].suc; + link[j].suc = i; + link[i].pre = j; + if (isuc >= 0) { + link[isuc].pre = i; + } + link[i].suc = isuc; +} + +/*! \relates presolvehlink + \brief relink vector j in place of vector i + + Replace vector i in the ordering with vector j. This is equivalent to +
+     int pre = link[i].pre;
+     PRESOLVE_REMOVE_LINK(link,i);
+     PRESOLVE_INSERT_LINK(link,j,pre);
+   
+ But, this routine will work even if i happens to be first in the order. +*/ +inline void PRESOLVE_MOVE_LINK(presolvehlink *link, int i, int j) +{ + int ipre = link[i].pre; + int isuc = link[i].suc; + if (ipre >= 0) { + link[ipre].suc = j; + } + if (isuc >= 0) { + link[isuc].pre = j; + } + link[i].pre = NO_LINK, link[i].suc = NO_LINK; +} + + +/*! \class CoinPresolveMatrix + \brief Augments CoinPrePostsolveMatrix with information about the problem + that is only needed during presolve. + + For problem manipulation, this class adds a row-major matrix + representation, linked lists that allow for easy manipulation of the matrix + when applying presolve transforms, and vectors to track row and column + processing status (changed, needs further processing, change prohibited) + + For problem representation, this class adds information about variable type + (integer or continuous), an objective offset, and a feasibility tolerance. + + NOTE that the #anyInteger_ and #anyProhibited_ flags are independent + of the vectors used to track this information for individual variables + (#integerType_ and #rowChanged_ and #colChanged_, respectively). + + NOTE also that at the end of presolve the column-major and row-major + matrix representations are loosely packed (i.e., there may be gaps + between columns in the bulk storage arrays). + + NOTE that while you might think that CoinPresolve is prepared to + handle minimisation or maximisation, it's unlikely that this still works. + This is a good thing: better to convert objective coefficients and duals + once, before starting presolve, rather than doing it over and over in + each transform that considers dual variables. + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ + +class CoinPresolveMatrix : public CoinPrePostsolveMatrix +{ + public: + + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. + On the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPresolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + /*! \brief Clp OSI constructor + + See Clp code for the definition. + */ + CoinPresolveMatrix(int ncols0, + double maxmin, + // end prepost members + + ClpSimplex * si, + + // rowrep + int nrows, + CoinBigIndex nelems, + bool doStatus, + double nonLinearVariable, + double bulkRatio); + + /*! \brief Update the model held by a Clp OSI */ + void update_model(ClpSimplex * si, + int nrows0, + int ncols0, + CoinBigIndex nelems0); + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPresolveMatrix(int ncols0, + double maxmin, + // end prepost members + OsiSolverInterface * si, + // rowrep + int nrows, + CoinBigIndex nelems, + bool doStatus, + double nonLinearVariable, + const char * prohibited, + const char * rowProhibited=NULL); + + /*! \brief Update the model held by a generic OSI */ + void update_model(OsiSolverInterface * si, + int nrows0, + int ncols0, + CoinBigIndex nelems0); + + /// Destructor + ~CoinPresolveMatrix(); + + /*! \brief Initialize a CoinPostsolveMatrix object, destroying the + CoinPresolveMatrix object. + + See CoinPostsolveMatrix::assignPresolveToPostsolve. + */ + friend void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ; + + /*! \name Functions to load the problem representation + */ + //@{ + /*! \brief Load the cofficient matrix. + + Load the coefficient matrix before loading the other vectors (bounds, + objective, variable type) required to define the problem. + */ + void setMatrix(const CoinPackedMatrix *mtx) ; + + /// Count number of empty rows + inline int countEmptyRows() + { int empty = 0 ; + for (int i = 0 ; i < nrows_ ; i++) if (hinrow_[i] == 0) empty++ ; + return (empty) ; } + + /*! \brief Set variable type information for a single variable + + Set \p variableType to 0 for continous, 1 for integer. + Does not manipulate the #anyInteger_ flag. + */ + inline void setVariableType(int i, int variableType) + { if (integerType_ == 0) integerType_ = new unsigned char [ncols0_] ; + integerType_[i] = static_cast(variableType) ; } + + /*! \brief Set variable type information for all variables + + Set \p variableType[i] to 0 for continuous, 1 for integer. + Does not manipulate the #anyInteger_ flag. + */ + void setVariableType(const unsigned char *variableType, int lenParam) ; + + /*! \brief Set the type of all variables + + allIntegers should be true to set the type to integer, false to set the + type to continuous. + */ + void setVariableType (bool allIntegers, int lenParam) ; + + /// Set a flag for presence (true) or absence (false) of integer variables + inline void setAnyInteger (bool anyInteger = true) + { anyInteger_ = anyInteger ; } + //@} + + /*! \name Functions to retrieve problem information + */ + //@{ + + /// Get row start vector for row-major packed matrix + inline const CoinBigIndex *getRowStarts() const + { return (mrstrt_) ; } + /// Get vector of column indices for row-major packed matrix + inline const int *getColIndicesByRow() const + { return (hcol_) ; } + /// Get vector of elements for row-major packed matrix + inline const double *getElementsByRow() const + { return (rowels_) ; } + + /*! \brief Check for integrality of the specified variable. + + Consults the #integerType_ vector if present; fallback is the + #anyInteger_ flag. + */ + inline bool isInteger (int i) const + { if (integerType_ == 0) + { return (anyInteger_) ; } + else + if (integerType_[i] == 1) + { return (true) ; } + else + { return (false) ; } } + + /*! \brief Check if there are any integer variables + + Consults the #anyInteger_ flag + */ + inline bool anyInteger () const + { return (anyInteger_) ; } + /// Picks up any special options + inline int presolveOptions() const + { return presolveOptions_;} + /// Sets any special options (see #presolveOptions_) + inline void setPresolveOptions(int value) + { presolveOptions_=value;} + //@} + + /*! \name Matrix storage management links + + Linked lists, modelled after the linked lists used in OSL + factorization. They are used for management of the bulk coefficient + and minor index storage areas. + */ + //@{ + /// Linked list for the column-major representation. + presolvehlink *clink_; + /// Linked list for the row-major representation. + presolvehlink *rlink_; + //@} + + /// Objective function offset introduced during presolve + double dobias_ ; + + /// Adjust objective function constant offset + inline void change_bias(double change_amount) + { + dobias_ += change_amount ; + # if PRESOLVE_DEBUG > 2 + assert(fabs(change_amount)<1.0e50) ; + if (change_amount) + PRESOLVE_STMT(printf("changing bias by %g to %g\n", + change_amount, dobias_)) ; + # endif + } + + /*! \name Row-major representation + + Common row-major format: A pair of vectors with positional + correspondence to hold coefficients and column indices, and a second pair + of vectors giving the starting position and length of each row in + the first pair. + */ + //@{ + /// Vector of row start positions in #hcol, #rowels_ + CoinBigIndex *mrstrt_; + /// Vector of row lengths + int *hinrow_; + /// Coefficients (positional correspondence with #hcol_) + double *rowels_; + /// Column indices (positional correspondence with #rowels_) + int *hcol_; + //@} + + /// Tracks integrality of columns (1 for integer, 0 for continuous) + unsigned char *integerType_; + /*! \brief Flag to say if any variables are integer + + Note that this flag is not manipulated by the various + \c setVariableType routines. + */ + bool anyInteger_ ; + /// Print statistics for tuning + bool tuning_; + /// Say we want statistics - also set time + void statistics(); + /// Start time of presolve + double startTime_; + + /// Bounds can be moved by this to retain feasibility + double feasibilityTolerance_; + /// Return feasibility tolerance + inline double feasibilityTolerance() + { return (feasibilityTolerance_) ; } + /// Set feasibility tolerance + inline void setFeasibilityTolerance (double val) + { feasibilityTolerance_ = val ; } + + /*! \brief Output status: 0 = feasible, 1 = infeasible, 2 = unbounded + + Actually implemented as single bit flags: 1^0 = infeasible, 1^1 = + unbounded. + */ + int status_; + /// Returns problem status (0 = feasible, 1 = infeasible, 2 = unbounded) + inline int status() + { return (status_) ; } + /// Set problem status + inline void setStatus(int status) + { status_ = (status&0x3) ; } + + /*! \brief Presolve pass number + + Should be incremented externally by the method controlling application of + presolve transforms. + Used to control the execution of testRedundant (evoked by the + implied_free transform). + */ + int pass_; + /// Set pass number + inline void setPass (int pass = 0) + { pass_ = pass ; } + + /*! \brief Maximum substitution level + + Used to control the execution of subst from implied_free + */ + int maxSubstLevel_; + /// Set Maximum substitution level (normally 3) + inline void setMaximumSubstitutionLevel (int level) + { maxSubstLevel_ = level ; } + + + /*! \name Row and column processing status + + Information used to determine if rows or columns can be changed and + if they require further processing due to changes. + + There are four major lists: the [row,col]ToDo list, and the + [row,col]NextToDo list. In general, a transform processes entries from + the ToDo list and adds entries to the NextToDo list. + + There are two vectors, [row,col]Changed, which track the status of + individual rows and columns. + */ + //@{ + /*! \brief Column change status information + + Coded using the following bits: +
    +
  • 0x01: Column has changed +
  • 0x02: preprocessing prohibited +
  • 0x04: Column has been used +
  • 0x08: Column originally had infinite ub +
+ */ + unsigned char * colChanged_; + /// Input list of columns to process + int * colsToDo_; + /// Length of #colsToDo_ + int numberColsToDo_; + /// Output list of columns to process next + int * nextColsToDo_; + /// Length of #nextColsToDo_ + int numberNextColsToDo_; + + /*! \brief Row change status information + + Coded using the following bits: +
    +
  • 0x01: Row has changed +
  • 0x02: preprocessing prohibited +
  • 0x04: Row has been used +
+ */ + unsigned char * rowChanged_; + /// Input list of rows to process + int * rowsToDo_; + /// Length of #rowsToDo_ + int numberRowsToDo_; + /// Output list of rows to process next + int * nextRowsToDo_; + /// Length of #nextRowsToDo_ + int numberNextRowsToDo_; + /*! \brief Fine control over presolve actions + + Set/clear the following bits to allow or suppress actions: + - 0x01 allow duplicate column tests for integer variables + - 0x02 not used + - 0x04 set to inhibit x+y+z=1 mods + - 0x08 not used + - 0x10 set to allow stuff which won't unroll easily (overlapping + duplicate rows; opportunistic fixing of variables from bound + propagation). + - 0x04000 allow presolve transforms to arbitrarily ignore infeasibility + and set arbitrary feasible bounds. + - 0x10000 instructs implied_free_action to be `more lightweight'; will + return without doing anything after 15 presolve passes. + - 0x(2,4,6)0000 instructs implied_free_action to remove small created elements + - 0x80000000 set by presolve to say dupcol_action compressed columns + */ + int presolveOptions_; + /*! Flag to say if any rows or columns are marked as prohibited + + Note that this flag is not manipulated by any of the + various \c set*Prohibited routines. + */ + bool anyProhibited_; + //@} + + /*! \name Scratch work arrays + + Preallocated work arrays are useful to avoid having to allocate and free + work arrays in individual presolve methods. + + All are allocated from #setMatrix by #initializeStuff, freed from + #~CoinPresolveMatrix. You can use #deleteStuff followed by + #initializeStuff to remove and recreate them. + */ + //@{ + /// Preallocated scratch work array, 3*nrows_ + int *usefulRowInt_ ; + /// Preallocated scratch work array, 2*nrows_ + double *usefulRowDouble_ ; + /// Preallocated scratch work array, 2*ncols_ + int *usefulColumnInt_ ; + /// Preallocated scratch work array, ncols_ + double *usefulColumnDouble_ ; + /// Array of random numbers (max row,column) + double *randomNumber_ ; + + /// Work array for count of infinite contributions to row lhs upper bound + int *infiniteUp_ ; + /// Work array for sum of finite contributions to row lhs upper bound + double *sumUp_ ; + /// Work array for count of infinite contributions to row lhs lower bound + int *infiniteDown_ ; + /// Work array for sum of finite contributions to row lhs lower bound + double *sumDown_ ; + //@} + + /*! \brief Recompute row lhs bounds + + Calculate finite contributions to row lhs upper and lower bounds + and count infinite contributions. Returns the number of rows found + to be infeasible. + + If \p whichRow < 0, bounds are recomputed for all rows. + + As of 110611, this seems to be a work in progress in the sense that it's + barely used by the existing presolve code. + */ + int recomputeSums(int whichRow) ; + + /// Allocate scratch arrays + void initializeStuff() ; + /// Free scratch arrays + void deleteStuff() ; + + /*! \name Functions to manipulate row and column processing status */ + //@{ + + /*! \brief Initialise the column ToDo lists + + Places all columns in the #colsToDo_ list except for columns marked + as prohibited (viz. #colChanged_). + */ + void initColsToDo () ; + + /*! \brief Step column ToDo lists + + Moves columns on the #nextColsToDo_ list to the #colsToDo_ list, emptying + #nextColsToDo_. Returns the number of columns transferred. + */ + int stepColsToDo () ; + + /// Return the number of columns on the #colsToDo_ list + inline int numberColsToDo() + { return (numberColsToDo_) ; } + + /// Has column been changed? + inline bool colChanged(int i) const { + return (colChanged_[i]&1)!=0; + } + /// Mark column as not changed + inline void unsetColChanged(int i) { + colChanged_[i] = static_cast(colChanged_[i] & (~1)) ; + } + /// Mark column as changed. + inline void setColChanged(int i) { + colChanged_[i] = static_cast(colChanged_[i] | (1)) ; + } + /// Mark column as changed and add to list of columns to process next + inline void addCol(int i) { + if ((colChanged_[i]&1)==0) { + colChanged_[i] = static_cast(colChanged_[i] | (1)) ; + nextColsToDo_[numberNextColsToDo_++] = i; + } + } + /// Test if column is eligible for preprocessing + inline bool colProhibited(int i) const { + return (colChanged_[i]&2)!=0; + } + /*! \brief Test if column is eligible for preprocessing + + The difference between this method and #colProhibited() is that this + method first tests #anyProhibited_ before examining the specific entry + for the specified column. + */ + inline bool colProhibited2(int i) const { + if (!anyProhibited_) + return false; + else + return (colChanged_[i]&2)!=0; + } + /// Mark column as ineligible for preprocessing + inline void setColProhibited(int i) { + colChanged_[i] = static_cast(colChanged_[i] | (2)) ; + } + /*! \brief Test if column is marked as used + + This is for doing faster lookups to see where two columns have entries + in common. + */ + inline bool colUsed(int i) const { + return (colChanged_[i]&4)!=0; + } + /// Mark column as used + inline void setColUsed(int i) { + colChanged_[i] = static_cast(colChanged_[i] | (4)) ; + } + /// Mark column as unused + inline void unsetColUsed(int i) { + colChanged_[i] = static_cast(colChanged_[i] & (~4)) ; + } + /// Has column infinite ub (originally) + inline bool colInfinite(int i) const { + return (colChanged_[i]&8)!=0; + } + /// Mark column as not infinite ub (originally) + inline void unsetColInfinite(int i) { + colChanged_[i] = static_cast(colChanged_[i] & (~8)) ; + } + /// Mark column as infinite ub (originally) + inline void setColInfinite(int i) { + colChanged_[i] = static_cast(colChanged_[i] | (8)) ; + } + + /*! \brief Initialise the row ToDo lists + + Places all rows in the #rowsToDo_ list except for rows marked + as prohibited (viz. #rowChanged_). + */ + void initRowsToDo () ; + + /*! \brief Step row ToDo lists + + Moves rows on the #nextRowsToDo_ list to the #rowsToDo_ list, emptying + #nextRowsToDo_. Returns the number of rows transferred. + */ + int stepRowsToDo () ; + + /// Return the number of rows on the #rowsToDo_ list + inline int numberRowsToDo() + { return (numberRowsToDo_) ; } + + /// Has row been changed? + inline bool rowChanged(int i) const { + return (rowChanged_[i]&1)!=0; + } + /// Mark row as not changed + inline void unsetRowChanged(int i) { + rowChanged_[i] = static_cast(rowChanged_[i] & (~1)) ; + } + /// Mark row as changed + inline void setRowChanged(int i) { + rowChanged_[i] = static_cast(rowChanged_[i] | (1)) ; + } + /// Mark row as changed and add to list of rows to process next + inline void addRow(int i) { + if ((rowChanged_[i]&1)==0) { + rowChanged_[i] = static_cast(rowChanged_[i] | (1)) ; + nextRowsToDo_[numberNextRowsToDo_++] = i; + } + } + /// Test if row is eligible for preprocessing + inline bool rowProhibited(int i) const { + return (rowChanged_[i]&2)!=0; + } + /*! \brief Test if row is eligible for preprocessing + + The difference between this method and #rowProhibited() is that this + method first tests #anyProhibited_ before examining the specific entry + for the specified row. + */ + inline bool rowProhibited2(int i) const { + if (!anyProhibited_) + return false; + else + return (rowChanged_[i]&2)!=0; + } + /// Mark row as ineligible for preprocessing + inline void setRowProhibited(int i) { + rowChanged_[i] = static_cast(rowChanged_[i] | (2)) ; + } + /*! \brief Test if row is marked as used + + This is for doing faster lookups to see where two rows have entries + in common. It can be used anywhere as long as it ends up zeroed out. + */ + inline bool rowUsed(int i) const { + return (rowChanged_[i]&4)!=0; + } + /// Mark row as used + inline void setRowUsed(int i) { + rowChanged_[i] = static_cast(rowChanged_[i] | (4)) ; + } + /// Mark row as unused + inline void unsetRowUsed(int i) { + rowChanged_[i] = static_cast(rowChanged_[i] & (~4)) ; + } + + + /// Check if there are any prohibited rows or columns + inline bool anyProhibited() const + { return anyProhibited_;} + /// Set a flag for presence of prohibited rows or columns + inline void setAnyProhibited(bool val = true) + { anyProhibited_ = val ; } + //@} + +}; + +/*! \class CoinPostsolveMatrix + \brief Augments CoinPrePostsolveMatrix with information about the problem + that is only needed during postsolve. + + The notable point is that the matrix representation is threaded. The + representation is column-major and starts with the standard two pairs of + arrays: one pair to hold the row indices and coefficients, the second pair + to hold the column starting positions and lengths. But the row indices and + coefficients for a column do not necessarily occupy a contiguous block in + their respective arrays. Instead, a link array gives the position of the + next (row index,coefficient) pair. If the row index and value of a + coefficient a occupy position kp in their arrays, then the position of + the next coefficient a is found as kq = link[kp]. + + This threaded representation allows for efficient expansion of columns as + rows are reintroduced during postsolve transformations. The basic packed + structures are allocated to the expected size of the postsolved matrix, + and as new coefficients are added, their location is simply added to the + thread for the column. + + There is no provision to convert the threaded representation to a packed + representation. In the context of postsolve, it's not required. (You did + keep a copy of the original matrix, eh?) + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ +class CoinPostsolveMatrix : public CoinPrePostsolveMatrix +{ + public: + + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. + On the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + + /*! \brief Clp OSI constructor + + See Clp code for the definition. + */ + CoinPostsolveMatrix(ClpSimplex * si, + + int ncols0, + int nrows0, + CoinBigIndex nelems0, + + double maxmin_, + // end prepost members + + double *sol, + double *acts, + + unsigned char *colstat, + unsigned char *rowstat); + + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPostsolveMatrix(OsiSolverInterface * si, + + int ncols0, + int nrows0, + CoinBigIndex nelems0, + + double maxmin_, + // end prepost members + + double *sol, + double *acts, + + unsigned char *colstat, + unsigned char *rowstat); + + /*! \brief Load an empty CoinPostsolveMatrix from a CoinPresolveMatrix + + This routine transfers the contents of the CoinPrePostsolveMatrix + object from the CoinPresolveMatrix object to the CoinPostsolveMatrix + object and completes initialisation of the CoinPostsolveMatrix object. + The empty shell of the CoinPresolveMatrix object is destroyed. + + The routine expects an empty CoinPostsolveMatrix object. If handed a loaded + object, a lot of memory will leak. + */ + void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ; + + /// Destructor + ~CoinPostsolveMatrix(); + + /*! \name Column thread structures + + As mentioned in the class documentation, the entries for a given column + do not necessarily occupy a contiguous block of space. The #link_ array + is used to maintain the threading. There is one thread for each column, + and a single thread for all free entries in #hrow_ and #colels_. + + The allocated size of #link_ must be at least as large as the allocated + size of #hrow_ and #colels_. + */ + //@{ + + /*! \brief First entry in free entries thread */ + CoinBigIndex free_list_; + /// Allocated size of #link_ + int maxlink_; + /*! \brief Thread array + + Within a thread, link_[k] points to the next entry in the thread. + */ + CoinBigIndex *link_; + + //@} + + /*! \name Debugging aids + + These arrays are allocated only when CoinPresolve is compiled with + PRESOLVE_DEBUG defined. They hold codes which track the reason that + a column or row is added to the problem during postsolve. + */ + //@{ + char *cdone_; + char *rdone_; + //@} + + /// debug + void check_nbasic(); + +}; + + +/*! \defgroup MtxManip Presolve Matrix Manipulation Functions + + Functions to work with the loosely packed and threaded packed matrix + structures used during presolve and postsolve. +*/ +//@{ + +/*! \relates CoinPrePostsolveMatrix + \brief Initialise linked list for major vector order in bulk storage +*/ + +void presolve_make_memlists(/*CoinBigIndex *starts,*/ int *lengths, + presolvehlink *link, int n); + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a major-dimension vector k has room for one more + coefficient. + + You can use this directly, or use the inline wrappers presolve_expand_col + and presolve_expand_row +*/ +bool presolve_expand_major(CoinBigIndex *majstrts, double *majels, + int *minndxs, int *majlens, + presolvehlink *majlinks, int nmaj, int k) ; + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a column (colx) in a column-major matrix has room for + one more coefficient +*/ + +inline bool presolve_expand_col(CoinBigIndex *mcstrt, double *colels, + int *hrow, int *hincol, + presolvehlink *clink, int ncols, int colx) +{ return presolve_expand_major(mcstrt,colels, + hrow,hincol,clink,ncols,colx) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a row (rowx) in a row-major matrix has room for one + more coefficient +*/ + +inline bool presolve_expand_row(CoinBigIndex *mrstrt, double *rowels, + int *hcol, int *hinrow, + presolvehlink *rlink, int nrows, int rowx) +{ return presolve_expand_major(mrstrt,rowels, + hcol,hinrow,rlink,nrows,rowx) ; } + + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a minor index in a major vector. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will abort if the entry does not exist. Can be + used directly or via the inline wrappers presolve_find_row and + presolve_find_col. +*/ +inline CoinBigIndex presolve_find_minor(int tgt, + CoinBigIndex ks, CoinBigIndex ke, + const int *minndxs) +{ CoinBigIndex k ; + for (k = ks ; k < ke ; k++) +#ifndef NDEBUG + { if (minndxs[k] == tgt) + return (k) ; } + DIE("FIND_MINOR") ; + + abort () ; return -1; +#else + { if (minndxs[k] == tgt) + break ; } + return (k) ; +#endif +} + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a row in a column in a column-major matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row(int row, CoinBigIndex kcs, + CoinBigIndex kce, const int *hrow) +{ return presolve_find_minor(row,kcs,kce,hrow) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a column in a row in a row-major matrix. + + The routine returns the position \c k in \p hcol for the specified \p col. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_col(int col, CoinBigIndex krs, + CoinBigIndex kre, const int *hcol) +{ return presolve_find_minor(col,krs,kre,hcol) ; } + + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a minor index in a major vector. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. A return value of \p ke means the entry does not + exist. Can be used directly or via the inline wrappers + presolve_find_row1 and presolve_find_col1. +*/ +CoinBigIndex presolve_find_minor1(int tgt, CoinBigIndex ks, CoinBigIndex ke, + const int *minndxs); + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a row in a column in a column-major matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + A return value of \p kce means the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row1(int row, CoinBigIndex kcs, + CoinBigIndex kce, const int *hrow) +{ return presolve_find_minor1(row,kcs,kce,hrow) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a column in a row in a row-major matrix. + + The routine returns the position \c k in \p hcol for the specified \p col. + A return value of \p kre means the entry does not exist. +*/ +inline CoinBigIndex presolve_find_col1(int col, CoinBigIndex krs, + CoinBigIndex kre, const int *hcol) +{ return presolve_find_minor1(col,krs,kre,hcol) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a minor index in a major vector in a threaded + matrix. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will abort if the entry does not exist. Can be + used directly or via the inline wrapper presolve_find_row2. +*/ +CoinBigIndex presolve_find_minor2(int tgt, CoinBigIndex ks, int majlen, + const int *minndxs, + const CoinBigIndex *majlinks) ; + +/*! \relates CoinPostsolveMatrix + \brief Find position of a row in a column in a column-major threaded + matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row2(int row, CoinBigIndex kcs, int collen, + const int *hrow, + const CoinBigIndex *clinks) +{ return presolve_find_minor2(row,kcs,collen,hrow,clinks) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a minor index in a major vector in a threaded + matrix. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will return -1 if the entry does not exist. + Can be used directly or via the inline wrappers presolve_find_row3. +*/ +CoinBigIndex presolve_find_minor3(int tgt, CoinBigIndex ks, int majlen, + const int *minndxs, + const CoinBigIndex *majlinks) ; + +/*! \relates CoinPostsolveMatrix + \brief Find position of a row in a column in a column-major threaded + matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will return -1 if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row3(int row, CoinBigIndex kcs, int collen, + const int *hrow, + const CoinBigIndex *clinks) +{ return presolve_find_minor3(row,kcs,collen,hrow,clinks) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for a minor index from a major vector. + + Deletes the entry for \p minndx from the major vector \p majndx. + Specifically, the relevant entries are removed from the minor index + (\p minndxs) and coefficient (\p els) arrays and the vector length (\p + majlens) is decremented. Loose packing is maintained by swapping the last + entry in the row into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_major(int majndx, int minndx, + const CoinBigIndex *majstrts, + int *majlens, int *minndxs, double *els) +{ + const CoinBigIndex ks = majstrts[majndx] ; + const CoinBigIndex ke = ks+majlens[majndx] ; + + const CoinBigIndex kmi = presolve_find_minor(minndx,ks,ke,minndxs) ; + + minndxs[kmi] = minndxs[ke-1] ; + els[kmi] = els[ke-1] ; + majlens[majndx]-- ; + + return ; +} + +/*! \relates CoinPrePostsolveMatrix + \brief Delete marked entries + + Removes the entries specified in \p marked, compressing the major vector + to maintain loose packing. \p marked is cleared in the process. +*/ +inline void presolve_delete_many_from_major(int majndx, char *marked, + const CoinBigIndex *majstrts, + int *majlens, int *minndxs, double *els) +{ + const CoinBigIndex ks = majstrts[majndx] ; + const CoinBigIndex ke = ks+majlens[majndx] ; + CoinBigIndex put = ks ; + for (CoinBigIndex k = ks ; k < ke ; k++) { + int iMinor = minndxs[k] ; + if (!marked[iMinor]) { + minndxs[put] = iMinor ; + els[put++] = els[k] ; + } else { + marked[iMinor] = 0 ; + } + } + majlens[majndx] = put-ks ; + return ; +} + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for row \p row from column \p col in a + column-major matrix + + Deletes the entry for \p row from the major vector for \p col. + Specifically, the relevant entries are removed from the row index (\p + hrow) and coefficient (\p colels) arrays and the vector length (\p + hincol) is decremented. Loose packing is maintained by swapping the last + entry in the row into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_col(int row, int col, + const CoinBigIndex *mcstrt, + int *hincol, int *hrow, double *colels) +{ presolve_delete_from_major(col,row,mcstrt,hincol,hrow,colels) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for column \p col from row \p row in a + row-major matrix + + Deletes the entry for \p col from the major vector for \p row. + Specifically, the relevant entries are removed from the column index (\p + hcol) and coefficient (\p rowels) arrays and the vector length (\p + hinrow) is decremented. Loose packing is maintained by swapping the last + entry in the column into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_row(int row, int col, + const CoinBigIndex *mrstrt, + int *hinrow, int *hcol, double *rowels) +{ presolve_delete_from_major(row,col,mrstrt,hinrow,hcol,rowels) ; } + +/*! \relates CoinPostsolveMatrix + \brief Delete the entry for a minor index from a major vector in a + threaded matrix. + + Deletes the entry for \p minndx from the major vector \p majndx. + Specifically, the relevant entries are removed from the minor index (\p + minndxs) and coefficient (\p els) arrays and the vector length (\p + majlens) is decremented. The thread for the major vector is relinked + around the deleted entry and the space is returned to the free list. +*/ +void presolve_delete_from_major2 (int majndx, int minndx, + CoinBigIndex *majstrts, int *majlens, + int *minndxs, int *majlinks, + CoinBigIndex *free_listp) ; + +/*! \relates CoinPostsolveMatrix + \brief Delete the entry for row \p row from column \p col in a + column-major threaded matrix + + Deletes the entry for \p row from the major vector for \p col. + Specifically, the relevant entries are removed from the row index (\p + hrow) and coefficient (\p colels) arrays and the vector length (\p + hincol) is decremented. The thread for the major vector is relinked + around the deleted entry and the space is returned to the free list. +*/ +inline void presolve_delete_from_col2(int row, int col, CoinBigIndex *mcstrt, + int *hincol, int *hrow, + int *clinks, CoinBigIndex *free_listp) +{ presolve_delete_from_major2(col,row,mcstrt,hincol,hrow,clinks,free_listp) ; } + +//@} + +/*! \defgroup PresolveUtilities Presolve Utility Functions + + Utilities used by multiple presolve transform objects. +*/ +//@{ + +/*! \brief Duplicate a major-dimension vector; optionally omit the entry + with minor index \p tgt. + + Designed to copy a major-dimension vector from the paired coefficient + (\p elems) and minor index (\p indices) arrays used in the standard + packed matrix representation. Copies \p length entries starting at + \p offset. + + If \p tgt is specified, the entry with minor index == \p tgt is + omitted from the copy. +*/ +double *presolve_dupmajor(const double *elems, const int *indices, + int length, CoinBigIndex offset, int tgt = -1); + +/// Initialize a vector with random numbers +void coin_init_random_vec(double *work, int n); + +//@} + + +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveMonitor.hpp b/thirdparty/linux/include/coin/CoinPresolveMonitor.hpp new file mode 100644 index 0000000..cef7a41 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveMonitor.hpp @@ -0,0 +1,105 @@ + +#ifndef CoinPresolveMonitor_H +#define CoinPresolveMonitor_H + +/*! + \brief Monitor a row or column for modification + + The purpose of this class is to monitor a row or column for modifications + during presolve and postsolve. Each object can monitor one row or + column. The initial copy of the row or column is loaded by the constructor. + Each subsequent call to checkAndTell() compares the current state of the row + or column with the stored state and reports any modifications. + + Internally the row or column is held as a CoinPackedVector so that it's + possible to follow a row or column through presolve (CoinPresolveMatrix) + and postsolve (CoinPostsolveMatrix). + + Do not underestimate the amount of work required here. Extracting a row from + the CoinPostsolve matrix requires a scan of every element in the matrix. + That's one scan by the constructor and one scan with every call to modify. + But that's precisely why it's virtually impossible to debug presolve without + aids. + + Parameter overloads for CoinPresolveMatrix and CoinPostsolveMatrix are a + little clumsy, but not a problem in use. The alternative is to add methods + to the CoinPresolveMatrix and CoinPostsolveMatrix classes that will only be + used for debugging. That's not too attractive either. +*/ +class CoinPresolveMonitor +{ + public: + + /*! \brief Default constructor + + Creates an empty monitor. + */ + CoinPresolveMonitor() ; + + /*! \brief Initialise from a CoinPresolveMatrix + + Load the initial row or column from a CoinPresolveMatrix. Set \p isRow + true for a row, false for a column. + */ + CoinPresolveMonitor(const CoinPresolveMatrix *mtx, bool isRow, int k) ; + + /*! \brief Initialise from a CoinPostsolveMatrix + + Load the initial row or column from a CoinPostsolveMatrix. Set \p isRow + true for a row, false for a column. + */ + CoinPresolveMonitor(const CoinPostsolveMatrix *mtx, bool isRow, int k) ; + + /*! \brief Compare the present row or column against the stored copy and + report differences. + + Load the current row or column from a CoinPresolveMatrix and compare. + Differences are printed to std::cout. + */ + void checkAndTell(const CoinPresolveMatrix *mtx) ; + + /*! \brief Compare the present row or column against the stored copy and + report differences. + + Load the current row or column from a CoinPostsolveMatrix and compare. + Differences are printed to std::cout. + */ + void checkAndTell(const CoinPostsolveMatrix *mtx) ; + + private: + + /// Extract a row from a CoinPresolveMatrix + CoinPackedVector *extractRow(int i, const CoinPresolveMatrix *mtx) const ; + + /// Extract a column from a CoinPresolveMatrix + CoinPackedVector *extractCol(int j, const CoinPresolveMatrix *mtx) const ; + + /// Extract a row from a CoinPostsolveMatrix + CoinPackedVector *extractRow(int i, const CoinPostsolveMatrix *mtx) const ; + + /// Extract a column from a CoinPostsolveMatrix + CoinPackedVector *extractCol(int j, const CoinPostsolveMatrix *mtx) const ; + + /// Worker method underlying the public checkAndTell methods. + void checkAndTell(CoinPackedVector *curVec, double lb, double ub) ; + + /// True to monitor a row, false to monitor a column + bool isRow_ ; + + /// Row or column index + int ndx_ ; + + /*! The original row or column + + Sorted in increasing order of indices. + */ + CoinPackedVector *origVec_ ; + + /// Original row or column lower bound + double lb_ ; + + /// Original row or column upper bound + double ub_ ; +} ; + +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolvePsdebug.hpp b/thirdparty/linux/include/coin/CoinPresolvePsdebug.hpp new file mode 100644 index 0000000..d72479a --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolvePsdebug.hpp @@ -0,0 +1,166 @@ +/* $Id: CoinPresolvePsdebug.hpp 1560 2012-11-24 00:29:01Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolvePsdebug_H +#define CoinPresolvePsdebug_H + +/* + The current idea of the relation between PRESOLVE_DEBUG and + PRESOLVE_CONSISTENCY is that PRESOLVE_CONSISTENCY triggers the consistency + checks and PRESOLVE_DEBUG triggers consistency checks and output. + This isn't always true in the code, but that's the goal. Really, + the whole compile-time scheme should be replaced with something more + user-friendly (control variables that can be changed during the run). + + Also floating about are PRESOLVE_SUMMARY and COIN_PRESOLVE_TUNING. + -- lh, 111208 -- +*/ +/*! \defgroup PresolveDebugFunctions Presolve Debug Functions + + These functions implement consistency checks on data structures involved + in presolve and postsolve and on the components of the lp solution. + + To use these functions, include CoinPresolvePsdebug.hpp in your file and + define the compile-time constants PRESOLVE_SUMMARY, PRESOLVE_DEBUG, and + PRESOLVE_CONSISTENCY. A value is needed (i.e., PRESOLVE_DEBUG=1). + In a few places, higher values will get you a bit more output. + + ******** + + Define the symbols PRESOLVE_DEBUG and PRESOLVE_CONSISTENCY on the configure + command line (use ADD_CXXFLAGS), in a Makefile, or similar and do a full + rebuild (including any presolve driver code). If the symbols are not + consistently nonzero across *all* presolve code, you'll get something + between garbage and a core dump! Debugging adds messages to CoinMessage + and allocates and maintains arrays that hold debug information. + + That said, given that you've configured and built with PRESOLVE_DEBUG and + PRESOLVE_CONSISTENCY nonzero everywhere, it's safe to adjust PRESOLVE_DEBUG + to values in the range 1..n in individual files to increase or decrease the + amount of output. + + The suggested approach for PRESOLVE_DEBUG is to define it to 1 in the build + and then increase it in individual presolve code files to get more detail. + + ******** +*/ +//@{ + +/*! \relates CoinPresolveMatrix + \brief Check column-major and/or row-major matrices for duplicate + entries in the major vectors. + + By default, scans both the column- and row-major matrices. Set doCol (doRow) + to false to suppress the column (row) scan. +*/ +void presolve_no_dups(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Check the links which track storage order for major vectors in + the bulk storage area. + + By default, scans both the column- and row-major matrix. Set doCol = false to + suppress the column-major scan. Set doRow = false to suppres the row-major + scan. +*/ +void presolve_links_ok(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Check for explicit zeros in the column- and/or row-major matrices. + + By default, scans both the column- and row-major matrices. Set doCol (doRow) + to false to suppress the column (row) scan. +*/ +void presolve_no_zeros(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Checks for equivalence of the column- and row-major matrices. + + Normally the routine will test for coefficient presence and value. Set + \p chkvals to false to suppress the check for equal value. +*/ +void presolve_consistent(const CoinPresolveMatrix *preObj, + bool chkvals = true) ; + +/*! \relates CoinPostsolveMatrix + \brief Checks that column threads agree with column lengths +*/ +void presolve_check_threads(const CoinPostsolveMatrix *obj) ; + +/*! \relates CoinPostsolveMatrix + \brief Checks the free list + + Scans the thread of free locations in the bulk store and checks that all + entries are reasonable (0 <= index < bulk0_). If chkElemCnt is true, it + also checks that the total number of entries in the matrix plus the + locations on the free list total to the size of the bulk store. Postsolve + routines do not maintain an accurate element count, but this is useful + for checking a newly constructed postsolve matrix. +*/ +void presolve_check_free_list(const CoinPostsolveMatrix *obj, + bool chkElemCnt = false) ; + +/*! \relates CoinPostsolveMatrix + \brief Check stored reduced costs for accuracy and consistency with + variable status. + + The routine will check the value of the reduced costs for architectural + variables (CoinPrePostsolveMatrix::rcosts_). It performs an accuracy check + by recalculating the reduced cost from scratch. It will also check the + value for consistency with the status information in + CoinPrePostsolveMatrix::colstat_. +*/ +void presolve_check_reduced_costs(const CoinPostsolveMatrix *obj) ; + +/*! \relates CoinPostsolveMatrix + \brief Check the dual variables for consistency with row activity. + + The routine checks that the value of the dual variable is consistent + with the state of the constraint (loose, tight at lower bound, or tight at + upper bound). +*/ +void presolve_check_duals(const CoinPostsolveMatrix *postObj) ; + +/*! \relates CoinPresolveMatrix + \brief Check primal solution and architectural variable status. + + The architectural variables can be checked for bogus values, feasibility, + and valid status. The row activity is checked for bogus values, accuracy, + and feasibility. By default, row activity is not checked (presolve is + sloppy about maintaining it). See the definitions in + CoinPresolvePsdebug.cpp for more information. +*/ +void presolve_check_sol(const CoinPresolveMatrix *preObj, + int chkColSol = 2, int chkRowAct = 1, + int chkStatus = 1) ; + +/*! \relates CoinPostsolveMatrix + \brief Check primal solution and architectural variable status. + + The architectural variables can be checked for bogus values, feasibility, + and valid status. The row activity is checked for bogus values, accuracy, + and feasibility. See the definitions in CoinPresolvePsdebug.cpp for more + information. +*/ +void presolve_check_sol(const CoinPostsolveMatrix *postObj, + int chkColSol = 2, int chkRowAct = 2, + int chkStatus = 1) ; + +/*! \relates CoinPresolveMatrix + \brief Check for the proper number of basic variables. +*/ +void presolve_check_nbasic(const CoinPresolveMatrix *preObj) ; + +/*! \relates CoinPostsolveMatrix + \brief Check for the proper number of basic variables. +*/ +void presolve_check_nbasic(const CoinPostsolveMatrix *postObj) ; + +//@} + +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveSingleton.hpp b/thirdparty/linux/include/coin/CoinPresolveSingleton.hpp new file mode 100644 index 0000000..10bc1cc --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveSingleton.hpp @@ -0,0 +1,112 @@ +/* $Id: CoinPresolveSingleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveSingleton_H +#define CoinPresolveSingleton_H +#define SLACK_DOUBLETON 2 +#define SLACK_SINGLETON 8 + +/*! + \file +*/ + +//const int MAX_SLACK_DOUBLETONS = 1000; + +/*! \class slack_doubleton_action + \brief Convert an explicit bound constraint to a column bound + + This transform looks for explicit bound constraints for a variable and + transfers the bound to the appropriate column bound array. + The constraint is removed from the constraint system. +*/ +class slack_doubleton_action : public CoinPresolveAction { + struct action { + double clo; + double cup; + + double rlo; + double rup; + + double coeff; + + int col; + int row; + }; + + const int nactions_; + const action *const actions_; + + slack_doubleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) +{} + + public: + const char *name() const { return ("slack_doubleton_action"); } + + /*! \brief Convert explicit bound constraints to column bounds. + + Not now There is a hard limit (#MAX_SLACK_DOUBLETONS) on the number of + constraints processed in a given call. \p notFinished is set to true + if candidates remain. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next, + bool ¬Finished); + + void postsolve(CoinPostsolveMatrix *prob) const; + + + virtual ~slack_doubleton_action() { deleteAction(actions_,action*); } +}; +/*! \class slack_singleton_action + \brief For variables with one entry + + If we have a variable with one entry and no cost then we can + transform the row from E to G etc. + If there is a row objective region then we may be able to do + this even with a cost. +*/ +class slack_singleton_action : public CoinPresolveAction { + struct action { + double clo; + double cup; + + double rlo; + double rup; + + double coeff; + + int col; + int row; + }; + + const int nactions_; + const action *const actions_; + + slack_singleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) +{} + + public: + const char *name() const { return ("slack_singleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next, + double * rowObjective); + + void postsolve(CoinPostsolveMatrix *prob) const; + + + virtual ~slack_singleton_action() { deleteAction(actions_,action*); } +}; +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveSubst.hpp b/thirdparty/linux/include/coin/CoinPresolveSubst.hpp new file mode 100644 index 0000000..93822a5 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveSubst.hpp @@ -0,0 +1,101 @@ +/* $Id: CoinPresolveSubst.hpp 1562 2012-11-24 00:36:15Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveSubst_H +#define CoinPresolveSubst_H + +/*! + \file +*/ + +#define SUBST_ROW 21 + +#include "CoinPresolveMatrix.hpp" + +/*! \class subst_constraint_action + \brief Detect and process implied free variables + + Consider a variable x. Suppose that we can find an equality such that the + bound on the equality, combined with + the bounds on the other variables involved in the equality, are such that + even the worst case values of the other variables still imply bounds for x + which are tighter than the variable's original bounds. Since x can never + reach its upper or lower bounds, it is an implied free variable. By solving + the equality for x and substituting for x in every other constraint + entangled with x, we can make x into a column singleton. Now x is an implied + free column singleton and both x and the equality can be removed. + + A similar transform for the case where the variable is a natural column + singleton is handled by #implied_free_action. In the current presolve + architecture, #implied_free_action is responsible for detecting implied free + variables that are natural column singletons or can be reduced to column + singletons. #implied_free_action calls subst_constraint_action to process + variables that must be reduced to column singletons. +*/ +class subst_constraint_action : public CoinPresolveAction { +private: + subst_constraint_action(); + subst_constraint_action(const subst_constraint_action& rhs); + subst_constraint_action& operator=(const subst_constraint_action& rhs); + + struct action { + double *rlos; + double *rups; + + double *coeffxs; + int *rows; + + int *ninrowxs; + int *rowcolsxs; + double *rowelsxs; + + const double *costsx; + int col; + int rowy; + + int nincol; + }; + + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + + subst_constraint_action(int nactions, + action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const int *implied_free, + const int * which, + int numberFree, + const CoinPresolveAction *next, + int fill_level); + static const CoinPresolveAction *presolveX(CoinPresolveMatrix * prob, + const CoinPresolveAction *next, + int fillLevel); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~subst_constraint_action(); +}; + + + + + +/*static*/ void implied_bounds(const double *els, + const double *clo, const double *cup, + const int *hcol, + CoinBigIndex krs, CoinBigIndex kre, + double *maxupp, double *maxdownp, + int jcol, + double rlo, double rup, + double *iclb, double *icub); +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveTighten.hpp b/thirdparty/linux/include/coin/CoinPresolveTighten.hpp new file mode 100644 index 0000000..3a5319b --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveTighten.hpp @@ -0,0 +1,55 @@ +/* $Id: CoinPresolveTighten.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveTighten_H +#define CoinPresolveTighten_H + +#include "CoinPresolveMatrix.hpp" + +// This action has no separate class; +// instead, it decides which columns can be made fixed +// and calls make_fixed_action::presolve. +const CoinPresolveAction *tighten_zero_cost(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + +#define DO_TIGHTEN 30 + +class do_tighten_action : public CoinPresolveAction { + do_tighten_action(); + do_tighten_action(const do_tighten_action& rhs); + do_tighten_action& operator=(const do_tighten_action& rhs); + + struct action { + int *rows; + double *lbound; + double *ubound; + int col; + int nrows; + int direction; // just for assertions + }; + + const int nactions_; + const action *const actions_; + + do_tighten_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~do_tighten_action(); + +}; +#endif + + diff --git a/thirdparty/linux/include/coin/CoinPresolveTripleton.hpp b/thirdparty/linux/include/coin/CoinPresolveTripleton.hpp new file mode 100644 index 0000000..eaa79c5 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveTripleton.hpp @@ -0,0 +1,66 @@ +/* $Id: CoinPresolveTripleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveTripleton_H +#define CoinPresolveTripleton_H +#define TRIPLETON 11 +/** We are only going to do this if it does not increase number of elements?. + It could be generalized to more than three but it seems unlikely it would + help. + + As it is adapted from doubleton icoly is one dropped. + */ +class tripleton_action : public CoinPresolveAction { + public: + struct action { + int icolx; + int icolz; + int row; + + int icoly; + double cloy; + double cupy; + double costy; + double clox; + double cupx; + double costx; + + double rlo; + double rup; + + double coeffx; + double coeffy; + double coeffz; + + double *colel; + + int ncolx; + int ncoly; + }; + + const int nactions_; + const action *const actions_; + + private: + tripleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("tripleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~tripleton_action(); +}; +#endif + + diff --git a/thirdparty/linux/include/coin/CoinPresolveUseless.hpp b/thirdparty/linux/include/coin/CoinPresolveUseless.hpp new file mode 100644 index 0000000..624a373 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveUseless.hpp @@ -0,0 +1,63 @@ +/* $Id: CoinPresolveUseless.hpp 1566 2012-11-29 19:33:56Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveUseless_H +#define CoinPresolveUseless_H +#define USELESS 20 + +class useless_constraint_action : public CoinPresolveAction { + struct action { + double rlo; + double rup; + const int *rowcols; + const double *rowels; + int row; + int ninrow; + }; + + const int nactions_; + const action *const actions_; + + useless_constraint_action(int nactions, + const action *actions, + const CoinPresolveAction *next); + + public: + const char *name() const; + + // These rows are asserted to be useless, + // that is, given a solution the row activity + // must be in range. + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const int *useless_rows, + int nuseless_rows, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~useless_constraint_action(); + +}; + +/*! \relates useless_constraint_action + \brief Scan constraints looking for useless constraints + + A front end to identify useless constraints and hand them to + useless_constraint_action::presolve() for processing. + + In a bit more detail, the routine implements a greedy algorithm that + identifies a set of necessary constraints. A constraint is necessary if it + implies a tighter bound on a variable than the original column bound. These + tighter column bounds are then used to calculate row activity and identify + constraints that are useless given the presence of the necessary + constraints. +*/ + +const CoinPresolveAction *testRedundant(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + + + +#endif diff --git a/thirdparty/linux/include/coin/CoinPresolveZeros.hpp b/thirdparty/linux/include/coin/CoinPresolveZeros.hpp new file mode 100644 index 0000000..219e613 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinPresolveZeros.hpp @@ -0,0 +1,60 @@ +/* $Id: CoinPresolveZeros.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveZeros_H +#define CoinPresolveZeros_H + +/*! \file + + Drop/reintroduce explicit zeros. +*/ + +#define DROP_ZERO 8 + +/*! \brief Tracking information for an explicit zero coefficient + + \todo Why isn't this a nested class in drop_zero_coefficients_action? + That would match the structure of other presolve classes. +*/ + +struct dropped_zero { + int row; + int col; +}; + +/*! \brief Removal of explicit zeros + + The presolve action for this class removes explicit zeros from the constraint + matrix. The postsolve action puts them back. +*/ +class drop_zero_coefficients_action : public CoinPresolveAction { + + const int nzeros_; + const dropped_zero *const zeros_; + + drop_zero_coefficients_action(int nzeros, + const dropped_zero *zeros, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nzeros_(nzeros), zeros_(zeros) +{} + + public: + const char *name() const { return ("drop_zero_coefficients_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + int *checkcols, + int ncheckcols, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_zero_coefficients_action() { deleteAction(zeros_,dropped_zero*); } +}; + +const CoinPresolveAction *drop_zero_coefficients(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + +#endif diff --git a/thirdparty/linux/include/coin/CoinRational.hpp b/thirdparty/linux/include/coin/CoinRational.hpp new file mode 100644 index 0000000..bfbfa5f --- /dev/null +++ b/thirdparty/linux/include/coin/CoinRational.hpp @@ -0,0 +1,44 @@ +// Authors: Matthew Saltzman and Ted Ralphs +// Copyright 2015, Matthew Saltzman and Ted Ralphs +// Licensed under the Eclipse Public License 1.0 + +#ifndef CoinRational_H +#define CoinRational_H + +#include + +//Small class for rational numbers +class CoinRational +{ + +public : + long getDenominator() { return denominator_; } + long getNumerator() { return numerator_; } + + CoinRational(): + numerator_(0), + denominator_(1) + {}; + + CoinRational(long n, long d): + numerator_(n), + denominator_(d) + {}; + + CoinRational(double val, double maxdelta, long maxdnom) + { + if (!nearestRational_(val, maxdelta, maxdnom)){ + numerator_ = 0; + denominator_ = 1; + } + }; + +private : + + long numerator_; + long denominator_; + + bool nearestRational_(double val, double maxdelta, long maxdnom); +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinSearchTree.hpp b/thirdparty/linux/include/coin/CoinSearchTree.hpp new file mode 100644 index 0000000..f7c101d --- /dev/null +++ b/thirdparty/linux/include/coin/CoinSearchTree.hpp @@ -0,0 +1,465 @@ +/* $Id: CoinSearchTree.hpp 1824 2015-04-04 16:27:28Z tkr $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSearchTree_H +#define CoinSearchTree_H + +#include +#include +#include +#include + +#include "CoinFinite.hpp" +#include "CoinHelperFunctions.hpp" + +// #define DEBUG_PRINT + +//############################################################################# + +class BitVector128 { + friend bool operator<(const BitVector128& b0, const BitVector128& b1); +private: + unsigned int bits_[4]; +public: + BitVector128(); + BitVector128(unsigned int bits[4]); + ~BitVector128() {} + void set(unsigned int bits[4]); + void setBit(int i); + void clearBit(int i); + std::string str() const; +}; + +bool operator<(const BitVector128& b0, const BitVector128& b1); + +//############################################################################# + +/** A class from which the real tree nodes should be derived from. Some of the + data that undoubtedly exist in the real tree node is replicated here for + fast access. This class is used in the various comparison functions. */ +class CoinTreeNode { +protected: + CoinTreeNode() : + depth_(-1), + fractionality_(-1), + quality_(-COIN_DBL_MAX), + true_lower_bound_(-COIN_DBL_MAX), + preferred_() {} + CoinTreeNode(int d, + int f = -1, + double q = -COIN_DBL_MAX, + double tlb = -COIN_DBL_MAX, + BitVector128 p = BitVector128()) : + depth_(d), + fractionality_(f), + quality_(q), + true_lower_bound_(tlb), + preferred_(p) {} + CoinTreeNode(const CoinTreeNode& x) : + depth_(x.depth_), + fractionality_(x.fractionality_), + quality_(x.quality_), + true_lower_bound_(x.true_lower_bound_), + preferred_(x.preferred_) {} + CoinTreeNode& operator=(const CoinTreeNode& x) { + if (this != &x) { + depth_ = x.depth_; + fractionality_ = x.fractionality_; + quality_ = x.quality_; + true_lower_bound_ = x.true_lower_bound_; + preferred_ = x.preferred_; + } + return *this; + } +private: + /// The depth of the node in the tree + int depth_; + /** A measure of fractionality, e.g., the number of unsatisfied + integrality requirements */ + int fractionality_; + /** Some quality for the node. For normal branch-and-cut problems the LP + relaxation value will do just fine. It is probably an OK approximation + even if column generation is done. */ + double quality_; + /** A true lower bound on the node. May be -infinity. For normal + branch-and-cut problems the LP relaxation value is OK. It is different + when column generation is done. */ + double true_lower_bound_; + /** */ + BitVector128 preferred_; +public: + virtual ~CoinTreeNode() {} + + inline int getDepth() const { return depth_; } + inline int getFractionality() const { return fractionality_; } + inline double getQuality() const { return quality_; } + inline double getTrueLB() const { return true_lower_bound_; } + inline BitVector128 getPreferred() const { return preferred_; } + + inline void setDepth(int d) { depth_ = d; } + inline void setFractionality(int f) { fractionality_ = f; } + inline void setQuality(double q) { quality_ = q; } + inline void setTrueLB(double tlb) { true_lower_bound_ = tlb; } + inline void setPreferred(BitVector128 p) { preferred_ = p; } +}; + +//============================================================================== + +class CoinTreeSiblings { +private: + CoinTreeSiblings(); + CoinTreeSiblings& operator=(const CoinTreeSiblings&); +private: + int current_; + int numSiblings_; + CoinTreeNode** siblings_; +public: + CoinTreeSiblings(const int n, CoinTreeNode** nodes) : + current_(0), numSiblings_(n), siblings_(new CoinTreeNode*[n]) + { + CoinDisjointCopyN(nodes, n, siblings_); + } + CoinTreeSiblings(const CoinTreeSiblings& s) : + current_(s.current_), + numSiblings_(s.numSiblings_), + siblings_(new CoinTreeNode*[s.numSiblings_]) + { + CoinDisjointCopyN(s.siblings_, s.numSiblings_, siblings_); + } + ~CoinTreeSiblings() { delete[] siblings_; } + inline CoinTreeNode* currentNode() const { return siblings_[current_]; } + /** returns false if cannot be advanced */ + inline bool advanceNode() { return ++current_ != numSiblings_; } + inline int toProcess() const { return numSiblings_ - current_; } + inline int size() const { return numSiblings_; } + inline void printPref() const { + for (int i = 0; i < numSiblings_; ++i) { + std::string pref = siblings_[i]->getPreferred().str(); + printf("prefs of sibligs: sibling[%i]: %s\n", i, pref.c_str()); + } + } +}; + +//############################################################################# + +/** Function objects to compare search tree nodes. The comparison function + must return true if the first argument is "better" than the second one, + i.e., it should be processed first. */ +/*@{*/ +/** Depth First Search. */ +struct CoinSearchTreeComparePreferred { + static inline const char* name() { return "CoinSearchTreeComparePreferred"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + register const CoinTreeNode* xNode = x->currentNode(); + register const CoinTreeNode* yNode = y->currentNode(); + const BitVector128 xPref = xNode->getPreferred(); + const BitVector128 yPref = yNode->getPreferred(); + bool retval = true; + if (xPref < yPref) { + retval = true; + } else if (yPref < xPref) { + retval = false; + } else { + retval = xNode->getQuality() < yNode->getQuality(); + } +#ifdef DEBUG_PRINT + printf("Comparing xpref (%s) and ypref (%s) : %s\n", + xpref.str().c_str(), ypref.str().c_str(), retval ? "T" : "F"); +#endif + return retval; + } +}; + +//----------------------------------------------------------------------------- +/** Depth First Search. */ +struct CoinSearchTreeCompareDepth { + static inline const char* name() { return "CoinSearchTreeCompareDepth"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { +#if 1 + return x->currentNode()->getDepth() >= y->currentNode()->getDepth(); +#else + if(x->currentNode()->getDepth() > y->currentNode()->getDepth()) + return 1; + if(x->currentNode()->getDepth() == y->currentNode()->getDepth() && + x->currentNode()->getQuality() <= y->currentNode()->getQuality()) + return 1; + return 0; +#endif + } +}; + +//----------------------------------------------------------------------------- +/* Breadth First Search */ +struct CoinSearchTreeCompareBreadth { + static inline const char* name() { return "CoinSearchTreeCompareBreadth"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + return x->currentNode()->getDepth() < y->currentNode()->getDepth(); + } +}; + +//----------------------------------------------------------------------------- +/** Best first search */ +struct CoinSearchTreeCompareBest { + static inline const char* name() { return "CoinSearchTreeCompareBest"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + return x->currentNode()->getQuality() < y->currentNode()->getQuality(); + } +}; + +//############################################################################# + +class CoinSearchTreeBase +{ +private: + CoinSearchTreeBase(const CoinSearchTreeBase&); + CoinSearchTreeBase& operator=(const CoinSearchTreeBase&); + +protected: + std::vector candidateList_; + int numInserted_; + int size_; + +protected: + CoinSearchTreeBase() : candidateList_(), numInserted_(0), size_(0) {} + + virtual void realpop() = 0; + virtual void realpush(CoinTreeSiblings* s) = 0; + virtual void fixTop() = 0; + +public: + virtual ~CoinSearchTreeBase() {} + virtual const char* compName() const = 0; + + inline const std::vector& getCandidates() const { + return candidateList_; + } + inline bool empty() const { return candidateList_.empty(); } + inline int size() const { return size_; } + inline int numInserted() const { return numInserted_; } + inline CoinTreeNode* top() const { + if (size_ == 0 || candidateList_.size() == 0) + return NULL; +#ifdef DEBUG_PRINT + char output[44]; + output[43] = 0; + candidateList_.front()->currentNode()->getPreferred().print(output); + printf("top's pref: %s\n", output); +#endif + return candidateList_.front()->currentNode(); + } + /** pop will advance the \c next pointer among the siblings on the top and + then moves the top to its correct position. #realpop is the method + that actually removes the element from the heap */ + inline void pop() { + CoinTreeSiblings* s = candidateList_.front(); + if (!s->advanceNode()) { + realpop(); + delete s; + } else { + fixTop(); + } + --size_; + } + inline void push(int numNodes, CoinTreeNode** nodes, + const bool incrInserted = true) { + CoinTreeSiblings* s = new CoinTreeSiblings(numNodes, nodes); + realpush(s); + if (incrInserted) { + numInserted_ += numNodes; + } + size_ += numNodes; + } + inline void push(const CoinTreeSiblings& sib, + const bool incrInserted = true) { + CoinTreeSiblings* s = new CoinTreeSiblings(sib); +#ifdef DEBUG_PRINT + s->printPref(); +#endif + realpush(s); + if (incrInserted) { + numInserted_ += sib.toProcess(); + } + size_ += sib.toProcess(); + } +}; + +//############################################################################# + +// #define CAN_TRUST_STL_HEAP +#ifdef CAN_TRUST_STL_HEAP + +template +class CoinSearchTree : public CoinSearchTreeBase +{ +private: + Comp comp_; +protected: + virtual void realpop() { + candidateList_.pop_back(); + } + virtual void fixTop() { + CoinTreeSiblings* s = top(); + realpop(); + push(s, false); + } + virtual void realpush(CoinTreeSiblings* s) { + nodes_.push_back(s); + std::push_heap(candidateList_.begin(), candidateList_.end(), comp_); + } +public: + CoinSearchTree() : CoinSearchTreeBase(), comp_() {} + CoinSearchTree(const CoinSearchTreeBase& t) : + CoinSearchTreeBase(), comp_() { + candidateList_ = t.getCandidates(); + std::make_heap(candidateList_.begin(), candidateList_.end(), comp_); + numInserted_ = t.numInserted_; + size_ = t.size_; + } + ~CoinSearchTree() {} + const char* compName() const { return Comp::name(); } +}; + +#else + +template +class CoinSearchTree : public CoinSearchTreeBase +{ +private: + Comp comp_; + +protected: + virtual void realpop() { + candidateList_[0] = candidateList_.back(); + candidateList_.pop_back(); + fixTop(); + } + /** After changing data in the top node, fix the heap */ + virtual void fixTop() { + const size_t size = candidateList_.size(); + if (size > 1) { + CoinTreeSiblings** candidates = &candidateList_[0]; + CoinTreeSiblings* s = candidates[0]; + --candidates; + size_t pos = 1; + size_t ch; + for (ch = 2; ch < size; pos = ch, ch *= 2) { + if (comp_(candidates[ch+1], candidates[ch])) + ++ch; + if (comp_(s, candidates[ch])) + break; + candidates[pos] = candidates[ch]; + } + if (ch == size) { + if (comp_(candidates[ch], s)) { + candidates[pos] = candidates[ch]; + pos = ch; + } + } + candidates[pos] = s; + } + } + virtual void realpush(CoinTreeSiblings* s) { + candidateList_.push_back(s); + CoinTreeSiblings** candidates = &candidateList_[0]; + --candidates; + size_t pos = candidateList_.size(); + size_t ch; + for (ch = pos/2; ch != 0; pos = ch, ch /= 2) { + if (comp_(candidates[ch], s)) + break; + candidates[pos] = candidates[ch]; + } + candidates[pos] = s; + } + +public: + CoinSearchTree() : CoinSearchTreeBase(), comp_() {} + CoinSearchTree(const CoinSearchTreeBase& t) : + CoinSearchTreeBase(), comp_() { + candidateList_ = t.getCandidates(); + std::sort(candidateList_.begin(), candidateList_.end(), comp_); + numInserted_ = t.numInserted(); + size_ = t.size(); + } + virtual ~CoinSearchTree() {} + const char* compName() const { return Comp::name(); } +}; + +#endif + +//############################################################################# + +enum CoinNodeAction { + CoinAddNodeToCandidates, + CoinTestNodeForDiving, + CoinDiveIntoNode +}; + +class CoinSearchTreeManager +{ +private: + CoinSearchTreeManager(const CoinSearchTreeManager&); + CoinSearchTreeManager& operator=(const CoinSearchTreeManager&); +private: + CoinSearchTreeBase* candidates_; + int numSolution; + /** Whether there is an upper bound or not. The upper bound may have come + as input, not necessarily from a solution */ + bool hasUB_; + + /** variable used to test whether we need to reevaluate search strategy */ + bool recentlyReevaluatedSearchStrategy_; + +public: + CoinSearchTreeManager() : + candidates_(NULL), + numSolution(0), + recentlyReevaluatedSearchStrategy_(true) + {} + virtual ~CoinSearchTreeManager() { + delete candidates_; + } + + inline void setTree(CoinSearchTreeBase* t) { + delete candidates_; + candidates_ = t; + } + inline CoinSearchTreeBase* getTree() const { + return candidates_; + } + + inline bool empty() const { return candidates_->empty(); } + inline size_t size() const { return candidates_->size(); } + inline size_t numInserted() const { return candidates_->numInserted(); } + inline CoinTreeNode* top() const { return candidates_->top(); } + inline void pop() { candidates_->pop(); } + inline void push(CoinTreeNode* node, const bool incrInserted = true) { + candidates_->push(1, &node, incrInserted); + } + inline void push(const CoinTreeSiblings& s, const bool incrInserted=true) { + candidates_->push(s, incrInserted); + } + inline void push(const int n, CoinTreeNode** nodes, + const bool incrInserted = true) { + candidates_->push(n, nodes, incrInserted); + } + + inline CoinTreeNode* bestQualityCandidate() const { + return candidates_->top(); + } + inline double bestQuality() const { + return candidates_->top()->getQuality(); + } + void newSolution(double solValue); + void reevaluateSearchStrategy(); +}; + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin/CoinShallowPackedVector.hpp b/thirdparty/linux/include/coin/CoinShallowPackedVector.hpp new file mode 100644 index 0000000..07c1870 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinShallowPackedVector.hpp @@ -0,0 +1,148 @@ +/* $Id: CoinShallowPackedVector.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinShallowPackedVector_H +#define CoinShallowPackedVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include "CoinError.hpp" +#include "CoinPackedVectorBase.hpp" + +/** Shallow Sparse Vector + +This class is for sparse vectors where the indices and +elements are stored elsewhere. This class only maintains +pointers to the indices and elements. Since this class +does not own the index and element data it provides +read only access to to the data. An CoinSparsePackedVector +must be used when the sparse vector's data will be altered. + +This class stores pointers to the vectors. +It does not actually contain the vectors. + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 }; + double el[ne] = { 10., 40., 1., 50. }; + + // Create vector and set its value + CoinShallowPackedVector r(ne,inx,el); + + // access each index and element + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Tests for equality and equivalence + CoinShallowPackedVector r1; + r1=r; + assert( r==r1 ); + r.sort(CoinIncrElementOrdered()); + assert( r!=r1 ); + + // Add packed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinPackedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinShallowPackedVector : public CoinPackedVectorBase { + friend void CoinShallowPackedVectorUnitTest(); + +public: + + /**@name Get methods */ + //@{ + /// Get length of indices and elements vectors + virtual int getNumElements() const { return nElements_; } + /// Get indices of elements + virtual const int * getIndices() const { return indices_; } + /// Get element values + virtual const double * getElements() const { return elements_; } + //@} + + /**@name Set methods */ + //@{ + /// Reset the vector (as if were just created an empty vector) + void clear(); + /** Assignment operator. */ + CoinShallowPackedVector& operator=(const CoinShallowPackedVector & x); + /** Assignment operator from a CoinPackedVectorBase. */ + CoinShallowPackedVector& operator=(const CoinPackedVectorBase & x); + /** just like the explicit constructor */ + void setVector(int size, const int * indices, const double * elements, + bool testForDuplicateIndex = true); + //@} + + /**@name Methods to create, set and destroy */ + //@{ + /** Default constructor. */ + CoinShallowPackedVector(bool testForDuplicateIndex = true); + /** Explicit Constructor. + Set vector size, indices, and elements. Size is the length of both the + indices and elements vectors. The indices and elements vectors are not + copied into this class instance. The ShallowPackedVector only maintains + the pointers to the indices and elements vectors.
+ The last argument specifies whether the creator of the object knows in + advance that there are no duplicate indices. + */ + CoinShallowPackedVector(int size, + const int * indices, const double * elements, + bool testForDuplicateIndex = true); + /** Copy constructor from the base class. */ + CoinShallowPackedVector(const CoinPackedVectorBase &); + /** Copy constructor. */ + CoinShallowPackedVector(const CoinShallowPackedVector &); + /** Destructor. */ + virtual ~CoinShallowPackedVector() {} + /// Print vector information. + void print(); + //@} + +private: + /**@name Private member data */ + //@{ + /// Vector indices + const int * indices_; + ///Vector elements + const double * elements_; + /// Size of indices and elements vectors + int nElements_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CoinShallowPackedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinShallowPackedVectorUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin/CoinSignal.hpp b/thirdparty/linux/include/coin/CoinSignal.hpp new file mode 100644 index 0000000..2bbf0d0 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinSignal.hpp @@ -0,0 +1,117 @@ +/* $Id: CoinSignal.hpp 1810 2015-03-13 20:16:34Z tkr $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinSignal_hpp +#define _CoinSignal_hpp + +// This file is fully docified. +// There's nothing to docify... + +//############################################################################# + +#include + +//############################################################################# + +#if defined(_MSC_VER) + typedef void (__cdecl *CoinSighandler_t) (int); +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if (defined(__GNUC__) && defined(__linux__)) + typedef sighandler_t CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__CYGWIN__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__MINGW32__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__FreeBSD__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__NetBSD__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(_AIX) +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined (__hpux) +# define CoinSighandler_t_defined +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# else + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined(__sun) +# if defined(__SUNPRO_CC) +# include + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +# define CoinSighandler_t_defined +# endif +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined(__MACH__) && defined(__GNUC__) +typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//############################################################################# + +#ifndef CoinSighandler_t_defined +# warning("OS and/or compiler is not recognized. Defaulting to:"); +# warning("extern 'C' {") +# warning(" typedef void (*CoinSighandler_t) (int);") +# warning("}") + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +#endif + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin/CoinSimpFactorization.hpp b/thirdparty/linux/include/coin/CoinSimpFactorization.hpp new file mode 100644 index 0000000..242b6cd --- /dev/null +++ b/thirdparty/linux/include/coin/CoinSimpFactorization.hpp @@ -0,0 +1,431 @@ +/* $Id: CoinSimpFactorization.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* + This is a simple factorization of the LP Basis + */ +#ifndef CoinSimpFactorization_H +#define CoinSimpFactorization_H + +#include +#include +#include +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinDenseFactorization.hpp" +class CoinPackedMatrix; + + +/// pointers used during factorization +class FactorPointers{ +public: + double *rowMax; + int *firstRowKnonzeros; + int *prevRow; + int *nextRow; + int *firstColKnonzeros; + int *prevColumn; + int *nextColumn; + int *newCols; + //constructor + FactorPointers( int numRows, int numCols, int *UrowLengths_, int *UcolLengths_ ); + // destructor + ~ FactorPointers(); +}; + +class CoinSimpFactorization : public CoinOtherFactorization { + friend void CoinSimpFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinSimpFactorization ( ); + /// Copy constructor + CoinSimpFactorization ( const CoinSimpFactorization &other); + + /// Destructor + virtual ~CoinSimpFactorization ( ); + /// = copy + CoinSimpFactorization & operator = ( const CoinSimpFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + //@} + + /**@name general stuff such as status */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false); + + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /// does updatecolumn if save==true keeps column for replace column + int upColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false, bool save=false) const; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + /// does updateColumnTranspose, the other is a wrapper + int upColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + /// Returns array to put basis indices in + inline int * indices() const + { return reinterpret_cast (elements_+numberRows_*numberRows_);} + /// Returns permute in + virtual inline int * permute() const + { return pivotRow_;} + //@} + + /// The real work of destructor + void gutsOfDestructor(); + /// The real work of constructor + void gutsOfInitialize(); + /// The real work of copy + void gutsOfCopy(const CoinSimpFactorization &other); + + + /// calls factorization + void factorize(int numberOfRows, + int numberOfColumns, + const int colStarts[], + const int indicesRow[], + const double elements[]); + /// main loop of factorization + int mainLoopFactor (FactorPointers &pointers ); + /// copies L by rows + void copyLbyRows(); + /// copies U by columns + void copyUbyColumns(); + /// finds a pivot element using Markowitz count + int findPivot(FactorPointers &pointers, int &r, int &s, bool &ifSlack); + /// finds a pivot in a shortest column + int findPivotShCol(FactorPointers &pointers, int &r, int &s); + /// finds a pivot in the first column available + int findPivotSimp(FactorPointers &pointers, int &r, int &s); + /// does Gauss elimination + void GaussEliminate(FactorPointers &pointers, int &r, int &s); + /// finds short row that intersects a given column + int findShortRow(const int column, const int length, int &minRow, + int &minRowLength, FactorPointers &pointers); + /// finds short column that intersects a given row + int findShortColumn(const int row, const int length, int &minCol, + int &minColLength, FactorPointers &pointers); + /// finds maximum absolute value in a row + double findMaxInRrow(const int row, FactorPointers &pointers); + /// does pivoting + void pivoting(const int pivotRow, const int pivotColumn, + const double invPivot, FactorPointers &pointers); + /// part of pivoting + void updateCurrentRow(const int pivotRow, const int row, + const double multiplier, FactorPointers &pointers, + int &newNonZeros); + /// allocates more space for L + void increaseLsize(); + /// allocates more space for a row of U + void increaseRowSize(const int row, const int newSize); + /// allocates more space for a column of U + void increaseColSize(const int column, const int newSize, const bool b); + /// allocates more space for rows of U + void enlargeUrow(const int numNewElements); + /// allocates more space for columns of U + void enlargeUcol(const int numNewElements, const bool b); + /// finds a given row in a column + int findInRow(const int row, const int column); + /// finds a given column in a row + int findInColumn(const int column, const int row); + /// declares a row inactive + void removeRowFromActSet(const int row, FactorPointers &pointers); + /// declares a column inactive + void removeColumnFromActSet(const int column, FactorPointers &pointers); + /// allocates space for U + void allocateSpaceForU(); + /// allocates several working arrays + void allocateSomeArrays(); + /// initializes some numbers + void initialSomeNumbers(); + /// solves L x = b + void Lxeqb(double *b) const; + /// same as above but with two rhs + void Lxeqb2(double *b1, double *b2) const; + /// solves U x = b + void Uxeqb(double *b, double *sol) const; + /// same as above but with two rhs + void Uxeqb2(double *b1, double *sol1, double *sol2, double *b2) const; + /// solves x L = b + void xLeqb(double *b) const; + /// solves x U = b + void xUeqb(double *b, double *sol) const; + /// updates factorization after a Simplex iteration + int LUupdate(int newBasicCol); + /// creates a new eta vector + void newEta(int row, int numNewElements); + /// makes a copy of row permutations + void copyRowPermutations(); + /// solves H x = b, where H is a product of eta matrices + void Hxeqb(double *b) const; + /// same as above but with two rhs + void Hxeqb2(double *b1, double *b2) const; + /// solves x H = b + void xHeqb(double *b) const; + /// does FTRAN + void ftran(double *b, double *sol, bool save) const; + /// same as above but with two columns + void ftran2(double *b1, double *sol1, double *b2, double *sol2) const; + /// does BTRAN + void btran(double *b, double *sol) const; + ///--------------------------------------- + + + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// work array (should be initialized to zero) + double *denseVector_; + /// work array + double *workArea2_; + /// work array + double *workArea3_; + /// array of labels (should be initialized to zero) + int *vecLabels_; + /// array of indices + int *indVector_; + + /// auxiliary vector + double *auxVector_; + /// auxiliary vector + int *auxInd_; + + /// vector to keep for LUupdate + double *vecKeep_; + /// indices of this vector + int *indKeep_; + /// number of nonzeros + mutable int keepSize_; + + + + /// Starts of the rows of L + int *LrowStarts_; + /// Lengths of the rows of L + int *LrowLengths_; + /// L by rows + double *Lrows_; + /// indices in the rows of L + int *LrowInd_; + /// Size of Lrows_; + int LrowSize_; + /// Capacity of Lrows_ + int LrowCap_; + + /// Starts of the columns of L + int *LcolStarts_; + /// Lengths of the columns of L + int *LcolLengths_; + /// L by columns + double *Lcolumns_; + /// indices in the columns of L + int *LcolInd_; + /// numbers of elements in L + int LcolSize_; + /// maximum capacity of L + int LcolCap_; + + + /// Starts of the rows of U + int *UrowStarts_; + /// Lengths of the rows of U + int *UrowLengths_; +#ifdef COIN_SIMP_CAPACITY + /// Capacities of the rows of U + int *UrowCapacities_; +#endif + /// U by rows + double *Urows_; + /// Indices in the rows of U + int *UrowInd_; + /// maximum capacity of Urows + int UrowMaxCap_; + /// number of used places in Urows + int UrowEnd_; + /// first row in U + int firstRowInU_; + /// last row in U + int lastRowInU_; + /// previous row in U + int *prevRowInU_; + /// next row in U + int *nextRowInU_; + + /// Starts of the columns of U + int *UcolStarts_; + /// Lengths of the columns of U + int *UcolLengths_; +#ifdef COIN_SIMP_CAPACITY + /// Capacities of the columns of U + int *UcolCapacities_; +#endif + /// U by columns + double *Ucolumns_; + /// Indices in the columns of U + int *UcolInd_; + /// previous column in U + int *prevColInU_; + /// next column in U + int *nextColInU_; + /// first column in U + int firstColInU_; + /// last column in U + int lastColInU_; + /// maximum capacity of Ucolumns_ + int UcolMaxCap_; + /// last used position in Ucolumns_ + int UcolEnd_; + /// indicator of slack variables + int *colSlack_; + + /// inverse values of the elements of diagonal of U + double *invOfPivots_; + + /// permutation of columns + int *colOfU_; + /// position of column after permutation + int *colPosition_; + /// permutations of rows + int *rowOfU_; + /// position of row after permutation + int *rowPosition_; + /// permutations of rows during LUupdate + int *secRowOfU_; + /// position of row after permutation during LUupdate + int *secRowPosition_; + + /// position of Eta vector + int *EtaPosition_; + /// Starts of eta vectors + int *EtaStarts_; + /// Lengths of eta vectors + int *EtaLengths_; + /// columns of eta vectors + int *EtaInd_; + /// elements of eta vectors + double *Eta_; + /// number of elements in Eta_ + int EtaSize_; + /// last eta row + int lastEtaRow_; + /// maximum number of eta vectors + int maxEtaRows_; + /// Capacity of Eta_ + int EtaMaxCap_; + + /// minimum storage increase + int minIncrease_; + /// maximum size for the diagonal of U after update + double updateTol_; + /// do Shul heuristic + bool doSuhlHeuristic_; + /// maximum of U + double maxU_; + /// bound on the growth rate + double maxGrowth_; + /// maximum of A + double maxA_; + /// maximum number of candidates for pivot + int pivotCandLimit_; + /// number of slacks in basis + int numberSlacks_; + /// number of slacks in irst basis + int firstNumberSlacks_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/CoinSmartPtr.hpp b/thirdparty/linux/include/coin/CoinSmartPtr.hpp new file mode 100644 index 0000000..93366a2 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinSmartPtr.hpp @@ -0,0 +1,528 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: CoinSmartPtr.hpp 1520 2012-01-29 00:43:31Z tkr $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +// Removed lots of debugging stuff and reformatted: Laszlo Ladanyi, IBM +#ifndef CoinSmartPtr_hpp +#define CoinSmartPtr_hpp + +#include +#include +#include +#include + +namespace Coin { + + //######################################################################### + + /** ReferencedObject class. + * This is part of the implementation of an intrusive smart pointer + * design. This class stores the reference count of all the smart + * pointers that currently reference it. See the documentation for + * the SmartPtr class for more details. + * + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "CoinSmartPtr.hpp" + + * + * class MyClass : public Coin::ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * + * In my_usage.cpp... + * + * #include "CoinSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * Coin::SmartPtr ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point + * to A and B, but A and B also point to each other (i.e. A has a + * SmartPtr to B and B has a SmartPtr to A). In this scenario, when the + * higher level object is finished with A and B, their reference counts + * will never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + class ReferencedObject { + public: + ReferencedObject() : reference_count_(0) {} + virtual ~ReferencedObject() { assert(reference_count_ == 0); } + inline int ReferenceCount() const { return reference_count_; } + inline void AddRef() const { ++reference_count_; } + inline void ReleaseRef() const { --reference_count_; } + + private: + mutable int reference_count_; + }; + + //######################################################################### + + +//#define IP_DEBUG_SMARTPTR +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_SMARTPTR +#endif +#ifdef IP_DEBUG_SMARTPTR +# include "IpDebug.hpp" +#endif + + /** Template class for Smart Pointers. + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "CoinSmartPtr.hpp" + * + * class MyClass : public Coin::ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * + * In my_usage.cpp... + * + * #include "CoinSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * It is not necessary to use SmartPtr's in all cases where an + * object is used that has been allocated "into" a SmartPtr. It is + * possible to just pass objects by reference or regular pointers, + * even if lower down in the stack a SmartPtr is to be held on to. + * Everything should work fine as long as a pointer created by "new" + * is immediately passed into a SmartPtr, and if SmartPtr's are used + * to hold on to objects. + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + template + class SmartPtr { + public: + /** Returns the raw pointer contained. Use to get the value of the + * raw ptr (i.e. to pass to other methods/functions, etc.) Note: This + * method does NOT copy, therefore, modifications using this value + * modify the underlying object contained by the SmartPtr, NEVER + * delete this returned value. + */ + T* GetRawPtr() const { return ptr_; } + + /** Returns true if the SmartPtr is NOT NULL. + * Use this to check if the SmartPtr is not null + * This is preferred to if(GetRawPtr(sp) != NULL) + */ + bool IsValid() const { return ptr_ != NULL; } + + /** Returns true if the SmartPtr is NULL. + * Use this to check if the SmartPtr IsNull. + * This is preferred to if(GetRawPtr(sp) == NULL) + */ + bool IsNull() const { return ptr_ == NULL; } + + private: + /**@name Private Data/Methods */ + //@{ + /** Actual raw pointer to the object. */ + T* ptr_; + + /** Release the currently referenced object. */ + void ReleasePointer_() { + if (ptr_) { + ptr_->ReleaseRef(); + if (ptr_->ReferenceCount() == 0) { + delete ptr_; + } + ptr_ = NULL; + } + } + + /** Set the value of the internal raw pointer from another raw + * pointer, releasing the previously referenced object if necessary. */ + SmartPtr& SetFromRawPtr_(T* rhs){ + ReleasePointer_(); // Release any old pointer + if (rhs != NULL) { + rhs->AddRef(); + ptr_ = rhs; + } + return *this; + } + + /** Set the value of the internal raw pointer from a SmartPtr, + * releasing the previously referenced object if necessary. */ + inline SmartPtr& SetFromSmartPtr_(const SmartPtr& rhs) { + SetFromRawPtr_(rhs.GetRawPtr()); + return (*this); + } + + //@} + + public: +#define dbg_smartptr_verbosity 0 + + /**@name Constructors/Destructors */ + //@{ + /** Default constructor, initialized to NULL */ + SmartPtr() : ptr_(NULL) {} + + /** Copy constructor, initialized from copy */ + SmartPtr(const SmartPtr& copy) : ptr_(NULL) { + (void) SetFromSmartPtr_(copy); + } + + /** Constructor, initialized from T* ptr */ + SmartPtr(T* ptr) : ptr_(NULL) { + (void) SetFromRawPtr_(ptr); + } + + /** Destructor, automatically decrements the reference count, deletes + * the object if necessary.*/ + ~SmartPtr() { + ReleasePointer_(); + } + //@} + + /**@name Overloaded operators. */ + //@{ + /** Overloaded arrow operator, allows the user to call + * methods using the contained pointer. */ + T* operator->() const { +#if COIN_COINUTILS_CHECKLEVEL > 0 + assert(ptr_); +#endif + return ptr_; + } + + /** Overloaded dereference operator, allows the user + * to dereference the contained pointer. */ + T& operator*() const { +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + return *ptr_; + } + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from a raw pointer */ + SmartPtr& operator=(T* rhs) { + return SetFromRawPtr_(rhs); + } + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr */ + SmartPtr& operator=(const SmartPtr& rhs) { + return SetFromSmartPtr_(rhs); + } + + /** Overloaded equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template + friend + bool operator==(const SmartPtr& lhs, const SmartPtr& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template + friend + bool operator==(const SmartPtr& lhs, U2* raw_rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a raw pointer with a SmartPtr. */ + template + friend + bool operator==(U1* lhs, const SmartPtr& raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template + friend + bool operator!=(const SmartPtr& lhs, const SmartPtr& rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template + friend + bool operator!=(const SmartPtr& lhs, U2* raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template + friend + bool operator!=(U1* lhs, const SmartPtr& raw_rhs); + //@} + + }; + + template + bool ComparePointers(const U1* lhs, const U2* rhs) { + if (lhs == rhs) { + return true; + } + // If lhs and rhs point to the same object with different interfaces + // U1 and U2, we cannot guarantee that the value of the pointers will + // be equivalent. We can guarantee this if we convert to void*. + return static_cast(lhs) == static_cast(rhs); + } + +} // namespace Coin + +//############################################################################# + +/**@name SmartPtr friends that are overloaded operators, so they are not in + the Coin namespace. */ +//@{ +template +bool operator==(const Coin::SmartPtr& lhs, const Coin::SmartPtr& rhs) { + return Coin::ComparePointers(lhs.GetRawPtr(), rhs.GetRawPtr()); +} + +template +bool operator==(const Coin::SmartPtr& lhs, U2* raw_rhs) { + return Coin::ComparePointers(lhs.GetRawPtr(), raw_rhs); +} + +template +bool operator==(U1* raw_lhs, const Coin::SmartPtr& rhs) { + return Coin::ComparePointers(raw_lhs, rhs.GetRawPtr()); +} + +template +bool operator!=(const Coin::SmartPtr& lhs, const Coin::SmartPtr& rhs) { + return ! operator==(lhs, rhs); +} + +template +bool operator!=(const Coin::SmartPtr& lhs, U2* raw_rhs) { + return ! operator==(lhs, raw_rhs); +} + +template +bool operator!=(U1* raw_lhs, const Coin::SmartPtr& rhs) { + return ! operator==(raw_lhs, rhs); +} +//@} + +#define CoinReferencedObject Coin::ReferencedObject +#define CoinSmartPtr Coin::SmartPtr +#define CoinComparePointers Coin::ComparePointers + +#endif diff --git a/thirdparty/linux/include/coin/CoinSnapshot.hpp b/thirdparty/linux/include/coin/CoinSnapshot.hpp new file mode 100644 index 0000000..e928026 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinSnapshot.hpp @@ -0,0 +1,476 @@ +/* $Id: CoinSnapshot.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSnapshot_H +#define CoinSnapshot_H + +class CoinPackedMatrix; +#include "CoinTypes.hpp" + +//############################################################################# + +/** NON Abstract Base Class for interfacing with cut generators or branching code or .. + It is designed to be snapshot of a problem at a node in tree + + The class may or may not own the arrays - see owned_ + + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return arrays. +*/ + +class CoinSnapshot { + +public: + + //--------------------------------------------------------------------------- + /**@name Problem query methods + + The Matrix pointers may be NULL + */ + //@{ + /// Get number of columns + inline int getNumCols() const + { return numCols_;} + + /// Get number of rows + inline int getNumRows() const + { return numRows_;} + + /// Get number of nonzero elements + inline int getNumElements() const + { return numElements_;} + + /// Get number of integer variables + inline int getNumIntegers() const + { return numIntegers_;} + + /// Get pointer to array[getNumCols()] of column lower bounds + inline const double * getColLower() const + { return colLower_;} + + /// Get pointer to array[getNumCols()] of column upper bounds + inline const double * getColUpper() const + { return colUpper_;} + + /// Get pointer to array[getNumRows()] of row lower bounds + inline const double * getRowLower() const + { return rowLower_;} + + /// Get pointer to array[getNumRows()] of row upper bounds + inline const double * getRowUpper() const + { return rowUpper_;} + + /** Get pointer to array[getNumRows()] of row right-hand sides + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + inline const double * getRightHandSide() const + { return rightHandSide_;} + + /// Get pointer to array[getNumCols()] of objective function coefficients + inline const double * getObjCoefficients() const + { return objCoefficients_;} + + /// Get objective function sense (1 for min (default), -1 for max) + inline double getObjSense() const + { return objSense_;} + + /// Return true if variable is continuous + inline bool isContinuous(int colIndex) const + { return colType_[colIndex]=='C';} + + /// Return true if variable is binary + inline bool isBinary(int colIndex) const + { return colType_[colIndex]=='B';} + + /// Return true if column is integer. + inline bool isInteger(int colIndex) const + { return colType_[colIndex]=='B'||colType_[colIndex]=='I';} + + /// Return true if variable is general integer + inline bool isIntegerNonBinary(int colIndex) const + { return colType_[colIndex]=='I';} + + /// Return true if variable is binary and not fixed at either bound + inline bool isFreeBinary(int colIndex) const + { return colType_[colIndex]=='B'&&colUpper_[colIndex]>colLower_[colIndex];} + + /// Get colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + inline const char * getColType() const + { return colType_;} + + /// Get pointer to row-wise copy of current matrix + inline const CoinPackedMatrix * getMatrixByRow() const + { return matrixByRow_;} + + /// Get pointer to column-wise copy of current matrix + inline const CoinPackedMatrix * getMatrixByCol() const + { return matrixByCol_;} + + /// Get pointer to row-wise copy of "original" matrix + inline const CoinPackedMatrix * getOriginalMatrixByRow() const + { return originalMatrixByRow_;} + + /// Get pointer to column-wise copy of "original" matrix + inline const CoinPackedMatrix * getOriginalMatrixByCol() const + { return originalMatrixByCol_;} + //@} + + /**@name Solution query methods */ + //@{ + /// Get pointer to array[getNumCols()] of primal variable values + inline const double * getColSolution() const + { return colSolution_;} + + /// Get pointer to array[getNumRows()] of dual variable values + inline const double * getRowPrice() const + { return rowPrice_;} + + /// Get a pointer to array[getNumCols()] of reduced costs + inline const double * getReducedCost() const + { return reducedCost_;} + + /// Get pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + inline const double * getRowActivity() const + { return rowActivity_;} + + /// Get pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + inline const double * getDoNotSeparateThis() const + { return doNotSeparateThis_;} + //@} + + /**@name Other scalar get methods */ + //@{ + /// Get solver's value for infinity + inline double getInfinity() const + { return infinity_;} + + /** Get objective function value - includinbg any offset i.e. + sum c sub j * x subj - objValue = objOffset */ + inline double getObjValue() const + { return objValue_;} + + /// Get objective offset i.e. sum c sub j * x subj -objValue = objOffset + inline double getObjOffset() const + { return objOffset_;} + + /// Get dual tolerance + inline double getDualTolerance() const + { return dualTolerance_;} + + /// Get primal tolerance + inline double getPrimalTolerance() const + { return primalTolerance_;} + + /// Get integer tolerance + inline double getIntegerTolerance() const + { return integerTolerance_;} + + /// Get integer upper bound i.e. best solution * getObjSense + inline double getIntegerUpperBound() const + { return integerUpperBound_;} + + /// Get integer lower bound i.e. best possible solution * getObjSense + inline double getIntegerLowerBound() const + { return integerLowerBound_;} + //@} + + //--------------------------------------------------------------------------- + + /**@name Method to input a problem */ + //@{ + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • rowub: all rows have upper bound infinity +
  • rowlb: all rows have lower bound -infinity +
  • obj: all variables have 0 objective coefficient +
+ All solution type arrays will be deleted + */ + void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + bool makeRowCopy=false); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Methods to set data */ + //@{ + /// Set number of columns + inline void setNumCols(int value) + { numCols_ = value;} + + /// Set number of rows + inline void setNumRows(int value) + { numRows_ = value;} + + /// Set number of nonzero elements + inline void setNumElements(int value) + { numElements_ = value;} + + /// Set number of integer variables + inline void setNumIntegers(int value) + { numIntegers_ = value;} + + /// Set pointer to array[getNumCols()] of column lower bounds + void setColLower(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of column upper bounds + void setColUpper(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row lower bounds + void setRowLower(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row upper bounds + void setRowUpper(const double * array, bool copyIn=true); + + /** Set pointer to array[getNumRows()] of row right-hand sides + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + void setRightHandSide(const double * array, bool copyIn=true); + + /** Create array[getNumRows()] of row right-hand sides + using existing information + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + void createRightHandSide(); + + /// Set pointer to array[getNumCols()] of objective function coefficients + void setObjCoefficients(const double * array, bool copyIn=true); + + /// Set objective function sense (1 for min (default), -1 for max) + inline void setObjSense(double value) + { objSense_ = value;} + + /// Set colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + void setColType(const char *array, bool copyIn=true); + + /// Set pointer to row-wise copy of current matrix + void setMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Create row-wise copy from MatrixByCol + void createMatrixByRow(); + + /// Set pointer to column-wise copy of current matrix + void setMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to row-wise copy of "original" matrix + void setOriginalMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to column-wise copy of "original" matrix + void setOriginalMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of primal variable values + void setColSolution(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of dual variable values + void setRowPrice(const double * array, bool copyIn=true); + + /// Set a pointer to array[getNumCols()] of reduced costs + void setReducedCost(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + void setRowActivity(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + void setDoNotSeparateThis(const double * array, bool copyIn=true); + + /// Set solver's value for infinity + inline void setInfinity(double value) + { infinity_ = value;} + + /// Set objective function value (including any rhs offset) + inline void setObjValue(double value) + { objValue_ = value;} + + /// Set objective offset i.e. sum c sub j * x subj -objValue = objOffset + inline void setObjOffset(double value) + { objOffset_ = value;} + + /// Set dual tolerance + inline void setDualTolerance(double value) + { dualTolerance_ = value;} + + /// Set primal tolerance + inline void setPrimalTolerance(double value) + { primalTolerance_ = value;} + + /// Set integer tolerance + inline void setIntegerTolerance(double value) + { integerTolerance_ = value;} + + /// Set integer upper bound i.e. best solution * getObjSense + inline void setIntegerUpperBound(double value) + { integerUpperBound_ = value;} + + /// Set integer lower bound i.e. best possible solution * getObjSense + inline void setIntegerLowerBound(double value) + { integerLowerBound_ = value;} + //@} + + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors + //@{ + /// Default Constructor + CoinSnapshot(); + + /// Copy constructor + CoinSnapshot(const CoinSnapshot &); + + /// Assignment operator + CoinSnapshot & operator=(const CoinSnapshot& rhs); + + /// Destructor + virtual ~CoinSnapshot (); + + //@} + +private: + ///@name private functions + //@{ + /** Does main work of destructor - type (or'ed) + 1 - NULLify pointers + 2 - delete pointers + 4 - initialize scalars (tolerances etc) + 8 - initialize scalars (objValue etc0 + */ + void gutsOfDestructor(int type); + /// Does main work of copy + void gutsOfCopy(const CoinSnapshot & rhs); + //@} + + ///@name Private member data + + /// objective function sense (1 for min (default), -1 for max) + double objSense_; + + /// solver's value for infinity + double infinity_; + + /// objective function value (including any rhs offset) + double objValue_; + + /// objective offset i.e. sum c sub j * x subj -objValue = objOffset + double objOffset_; + + /// dual tolerance + double dualTolerance_; + + /// primal tolerance + double primalTolerance_; + + /// integer tolerance + double integerTolerance_; + + /// integer upper bound i.e. best solution * getObjSense + double integerUpperBound_; + + /// integer lower bound i.e. best possible solution * getObjSense + double integerLowerBound_; + + /// pointer to array[getNumCols()] of column lower bounds + const double * colLower_; + + /// pointer to array[getNumCols()] of column upper bounds + const double * colUpper_; + + /// pointer to array[getNumRows()] of row lower bounds + const double * rowLower_; + + /// pointer to array[getNumRows()] of row upper bounds + const double * rowUpper_; + + /// pointer to array[getNumRows()] of rhs side values + const double * rightHandSide_; + + /// pointer to array[getNumCols()] of objective function coefficients + const double * objCoefficients_; + + /// colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + const char * colType_; + + /// pointer to row-wise copy of current matrix + const CoinPackedMatrix * matrixByRow_; + + /// pointer to column-wise copy of current matrix + const CoinPackedMatrix * matrixByCol_; + + /// pointer to row-wise copy of "original" matrix + const CoinPackedMatrix * originalMatrixByRow_; + + /// pointer to column-wise copy of "original" matrix + const CoinPackedMatrix * originalMatrixByCol_; + + /// pointer to array[getNumCols()] of primal variable values + const double * colSolution_; + + /// pointer to array[getNumRows()] of dual variable values + const double * rowPrice_; + + /// a pointer to array[getNumCols()] of reduced costs + const double * reducedCost_; + + /// pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + const double * rowActivity_; + + /// pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + const double * doNotSeparateThis_; + + /// number of columns + int numCols_; + + /// number of rows + int numRows_; + + /// number of nonzero elements + int numElements_; + + /// number of integer variables + int numIntegers_; + + /// To say whether arrays etc are owned by CoinSnapshot + typedef struct { + unsigned int colLower:1; + unsigned int colUpper:1; + unsigned int rowLower:1; + unsigned int rowUpper:1; + unsigned int rightHandSide:1; + unsigned int objCoefficients:1; + unsigned int colType:1; + unsigned int matrixByRow:1; + unsigned int matrixByCol:1; + unsigned int originalMatrixByRow:1; + unsigned int originalMatrixByCol:1; + unsigned int colSolution:1; + unsigned int rowPrice:1; + unsigned int reducedCost:1; + unsigned int rowActivity:1; + unsigned int doNotSeparateThis:1; + } coinOwned; + coinOwned owned_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/CoinSort.hpp b/thirdparty/linux/include/coin/CoinSort.hpp new file mode 100644 index 0000000..259fb35 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinSort.hpp @@ -0,0 +1,678 @@ +/* $Id: CoinSort.hpp 1594 2013-04-19 14:33:00Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSort_H +#define CoinSort_H + +#include +#include +#include +#include "CoinDistance.hpp" + +// Uncomment the next three lines to get thorough initialisation of memory. +// #ifndef ZEROFAULT +// #define ZEROFAULT +// #endif + +#ifdef COIN_FAST_CODE +#ifndef COIN_USE_EKK_SORT +#define COIN_USE_EKK_SORT +#endif +#endif + +//############################################################################# + +/** An ordered pair. It's the same as std::pair, just this way it'll have the + same look as the triple sorting. */ +template +struct CoinPair { +public: + /// First member of pair + S first; + /// Second member of pair + T second; +public: + /// Construct from ordered pair + CoinPair(const S& s, const T& t) : first(s), second(t) {} +}; + +//############################################################################# + +/**@name Comparisons on first element of two ordered pairs */ +//@{ +/** Function operator. + Returns true if t1.first < t2.first (i.e., increasing). */ +template < class S, class T> +class CoinFirstLess_2 { +public: + /// Compare function + inline bool operator()(const CoinPair& t1, + const CoinPair& t2) const + { return t1.first < t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if t1.first > t2.first (i.e, decreasing). */ +template < class S, class T> +class CoinFirstGreater_2 { +public: + /// Compare function + inline bool operator()(const CoinPair& t1, + const CoinPair& t2) const + { return t1.first > t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) < abs(t2.first) (i.e., increasing). */ +template < class S, class T> +class CoinFirstAbsLess_2 { +public: + /// Compare function + inline bool operator()(const CoinPair& t1, + const CoinPair& t2) const + { + const T t1Abs = t1.first < static_cast(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast(0) ? -t2.first : t2.first; + return t1Abs < t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) > abs(t2.first) (i.e., decreasing). */ +template < class S, class T> +class CoinFirstAbsGreater_2 { +public: + /// Compare function + inline bool operator()(CoinPair t1, CoinPair t2) const + { + const T t1Abs = t1.first < static_cast(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast(0) ? -t2.first : t2.first; + return t1Abs > t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first < vec[t2.first] (i.e., increasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class V> +class CoinExternalVectorFirstLess_2 { +private: + CoinExternalVectorFirstLess_2(); +private: + const V* vec_; +public: + inline bool operator()(const CoinPair& t1, + const CoinPair& t2) const + { return vec_[t1.first] < vec_[t2.first]; } + CoinExternalVectorFirstLess_2(const V* v) : vec_(v) {} +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first > vec[t2.first] (i.e., decreasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class V> +class CoinExternalVectorFirstGreater_2 { +private: + CoinExternalVectorFirstGreater_2(); +private: + const V* vec_; +public: + inline bool operator()(const CoinPair& t1, + const CoinPair& t2) const + { return vec_[t1.first] > vec_[t2.first]; } + CoinExternalVectorFirstGreater_2(const V* v) : vec_(v) {} +}; +//@} + +//############################################################################# + +/** Sort a pair of containers.
+ + Iter_S - iterator for first container
+ Iter_T - iterator for 2nd container
+ CoinCompare2 - class comparing CoinPairs
+*/ + +#ifdef COIN_SORT_ARBITRARY_CONTAINERS +template void +CoinSort_2(Iter_S sfirst, Iter_S slast, Iter_T tfirst, const CoinCompare2& pc) +{ + typedef typename std::iterator_traits::value_type S; + typedef typename std::iterator_traits::value_type T; + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinPair ST_pair; + ST_pair* x = static_cast(::operator new(len * sizeof(ST_pair))); +# ifdef ZEROFAULT + memset(x,0,(len*sizeof(ST_pair))) ; +# endif + + int i = 0; + Iter_S scurrent = sfirst; + Iter_T tcurrent = tfirst; + while (scurrent != slast) { + new (x+i++) ST_pair(*scurrent++, *tcurrent++); + } + + std::sort(x.begin(), x.end(), pc); + + scurrent = sfirst; + tcurrent = tfirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template void +CoinSort_2(Iter_S sfirst, Iter_S slast, Iter_T tfirst) +{ + typedef typename std::iterator_traits::value_type S; + typedef typename std::iterator_traits::value_type T; + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2()); +} + +#else //======================================================================= + +template void +CoinSort_2(S* sfirst, S* slast, T* tfirst, const CoinCompare2& pc) +{ + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinPair ST_pair; + ST_pair* x = static_cast(::operator new(len * sizeof(ST_pair))); +# ifdef ZEROFAULT + // Can show RUI errors on some systems due to copy of ST_pair with gaps. + // E.g., has 4 byte alignment gap on Solaris/SUNWspro. + memset(x,0,(len*sizeof(ST_pair))) ; +# endif + + size_t i = 0; + S* scurrent = sfirst; + T* tcurrent = tfirst; + while (scurrent != slast) { + new (x+i++) ST_pair(*scurrent++, *tcurrent++); + } + + std::sort(x, x + len, pc); + + scurrent = sfirst; + tcurrent = tfirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + } + + ::operator delete(x); +} +template void +// This Always uses std::sort +CoinSort_2Std(S* sfirst, S* slast, T* tfirst) +{ + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2()); +} +#ifndef COIN_USE_EKK_SORT +//----------------------------------------------------------------------------- +template void +CoinSort_2(S* sfirst, S* slast, T* tfirst) +{ + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2()); +} +#else +//----------------------------------------------------------------------------- +extern int boundary_sort; +extern int boundary_sort2; +extern int boundary_sort3; +/// Sort without new and delete +template void +CoinSort_2(S* key, S* lastKey, T* array2) +{ + const size_t number = coinDistance(key, lastKey); + if (number <= 1) { + return; + } else if (number>10000) { + CoinSort_2Std(key, lastKey, array2); + return; + } +#if 0 + if (number==boundary_sort3) { + printf("before sort %d entries\n",number); + for (int j=0;j(number); + int sp; + S *v = key; + S *m, t; + S * ls[32] , * rs[32]; + S *l , *r , c; + T it; + int j; + /*check already sorted */ + S last=key[0]; + for (j=1;j=last) { + last=key[j]; + } else { + break; + } /* endif */ + } /* endfor */ + if (j==n) { + return; + } /* endif */ + sp = 0 ; ls[sp] = v ; rs[sp] = v + (n-1) ; + while( sp >= 0 ) + { + if ( rs[sp] - ls[sp] > minsize ) + { + l = ls[sp] ; r = rs[sp] ; m = l + (r-l)/2 ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + if ( *m > *r ) + { + t = *m ; *m = *r ; *r = t ; + it = array2[m-v] ; array2[m-v] = array2[r-v] ; array2[r-v] = it ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + } + c = *m ; + while ( r - l > 1 ) + { + while ( *(++l) < c ) ; + while ( *(--r) > c ) ; + t = *l ; *l = *r ; *r = t ; + it = array2[l-v] ; array2[l-v] = array2[r-v] ; array2[r-v] = it ; + } + l = r - 1 ; + if ( l < m ) + { ls[sp+1] = ls[sp] ; + rs[sp+1] = l ; + ls[sp ] = r ; + } + else + { ls[sp+1] = r ; + rs[sp+1] = rs[sp] ; + rs[sp ] = l ; + } + sp++ ; + } + else sp-- ; + } + for ( l = v , m = v + (n-1) ; l < m ; l++ ) + { if ( *l > *(l+1) ) + { + c = *(l+1) ; + it = array2[(l-v)+1] ; + for ( r = l ; r >= v && *r > c ; r-- ) + { + *(r+1) = *r ; + array2[(r-v)+1] = array2[(r-v)] ; + } + *(r+1) = c ; + array2[(r-v)+1] = it ; + } + } +#if 0 + if (number==boundary_sort3) { + printf("after sort %d entries\n",number); + for (int j=0;j void +CoinShortSort_2(S* key, S* lastKey, T* array2) +{ + const size_t number = coinDistance(key, lastKey); + if (number <= 2) { + if (number == 2 && key[0] > key[1]) { + S tempS = key[0]; + T tempT = array2[0]; + key[0] = key[1]; + array2[0] = array2[1]; + key[1] = tempS; + array2[1] = tempT; + } + return; + } else if (number>10000) { + CoinSort_2Std(key, lastKey, array2); + return; + } + int minsize=10; + size_t n = number; + int sp; + S *v = key; + S *m, t; + S * ls[32] , * rs[32]; + S *l , *r , c; + T it; + size_t j; + /*check already sorted */ + S last=key[0]; + for (j=1;j=last) { + last=key[j]; + } else { + break; + } /* endif */ + } /* endfor */ + if (j==n) { + return; + } /* endif */ + sp = 0 ; ls[sp] = v ; rs[sp] = v + (n-1) ; + while( sp >= 0 ) + { + if ( rs[sp] - ls[sp] > minsize ) + { + l = ls[sp] ; r = rs[sp] ; m = l + (r-l)/2 ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + if ( *m > *r ) + { + t = *m ; *m = *r ; *r = t ; + it = array2[m-v] ; array2[m-v] = array2[r-v] ; array2[r-v] = it ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + } + c = *m ; + while ( r - l > 1 ) + { + while ( *(++l) < c ) ; + while ( *(--r) > c ) ; + t = *l ; *l = *r ; *r = t ; + it = array2[l-v] ; array2[l-v] = array2[r-v] ; array2[r-v] = it ; + } + l = r - 1 ; + if ( l < m ) + { ls[sp+1] = ls[sp] ; + rs[sp+1] = l ; + ls[sp ] = r ; + } + else + { ls[sp+1] = r ; + rs[sp+1] = rs[sp] ; + rs[sp ] = l ; + } + sp++ ; + } + else sp-- ; + } + for ( l = v , m = v + (n-1) ; l < m ; l++ ) + { if ( *l > *(l+1) ) + { + c = *(l+1) ; + it = array2[(l-v)+1] ; + for ( r = l ; r >= v && *r > c ; r-- ) + { + *(r+1) = *r ; + array2[(r-v)+1] = array2[(r-v)] ; + } + *(r+1) = c ; + array2[(r-v)+1] = it ; + } + } +} +//############################################################################# +//############################################################################# + +/**@name Ordered Triple Struct */ +template +class CoinTriple { +public: + /// First member of triple + S first; + /// Second member of triple + T second; + /// Third member of triple + U third; +public: + /// Construct from ordered triple + CoinTriple(const S& s, const T& t, const U& u):first(s),second(t),third(u) {} +}; + +//############################################################################# +/**@name Comparisons on first element of two ordered triples */ +//@{ +/** Function operator. + Returns true if t1.first < t2.first (i.e., increasing). */ +template < class S, class T, class U > +class CoinFirstLess_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple& t1, + const CoinTriple& t2) const + { return t1.first < t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if t1.first > t2.first (i.e, decreasing). */ +template < class S, class T, class U > +class CoinFirstGreater_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple& t1, + const CoinTriple& t2) const + { return t1.first>t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) < abs(t2.first) (i.e., increasing). */ +template < class S, class T, class U > +class CoinFirstAbsLess_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple& t1, + const CoinTriple& t2) const + { + const T t1Abs = t1.first < static_cast(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast(0) ? -t2.first : t2.first; + return t1Abs < t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) > abs(t2.first) (i.e., decreasing). */ +template < class S, class T, class U > +class CoinFirstAbsGreater_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple& t1, + const CoinTriple& t2) const + { + const T t1Abs = t1.first < static_cast(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast(0) ? -t2.first : t2.first; + return t1Abs > t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first < vec[t2.first] (i.e., increasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class U, class V> +class CoinExternalVectorFirstLess_3 { +private: + CoinExternalVectorFirstLess_3(); +private: + const V* vec_; +public: + inline bool operator()(const CoinTriple& t1, + const CoinTriple& t2) const + { return vec_[t1.first] < vec_[t2.first]; } + CoinExternalVectorFirstLess_3(const V* v) : vec_(v) {} +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first > vec[t2.first] (i.e., decreasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class U, class V> +class CoinExternalVectorFirstGreater_3 { +private: + CoinExternalVectorFirstGreater_3(); +private: + const V* vec_; +public: + inline bool operator()(const CoinTriple& t1, + const CoinTriple& t2) const + { return vec_[t1.first] > vec_[t2.first]; } + CoinExternalVectorFirstGreater_3(const V* v) : vec_(v) {} +}; +//@} + +//############################################################################# + +/**@name Typedefs for sorting the entries of a packed vector based on an + external vector. */ +//@{ +/// Sort packed vector in increasing order of the external vector +typedef CoinExternalVectorFirstLess_3 +CoinIncrSolutionOrdered; +/// Sort packed vector in decreasing order of the external vector +typedef CoinExternalVectorFirstGreater_3 +CoinDecrSolutionOrdered; +//@} + +//############################################################################# + +/** Sort a triple of containers.
+ + Iter_S - iterator for first container
+ Iter_T - iterator for 2nd container
+ Iter_U - iterator for 3rd container
+ CoinCompare3 - class comparing CoinTriples
+*/ +#ifdef COIN_SORT_ARBITRARY_CONTAINERS +template void +CoinSort_3(Iter_S sfirst, Iter_S slast, Iter_T tfirst, Iter_U, ufirst, + const CoinCompare3& tc) +{ + typedef typename std::iterator_traits::value_type S; + typedef typename std::iterator_traits::value_type T; + typedef typename std::iterator_traits::value_type U; + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinTriple STU_triple; + STU_triple* x = + static_cast(::operator new(len * sizeof(STU_triple))); + + int i = 0; + Iter_S scurrent = sfirst; + Iter_T tcurrent = tfirst; + Iter_U ucurrent = ufirst; + while (scurrent != slast) { + new (x+i++) STU_triple(*scurrent++, *tcurrent++, *ucurrent++); + } + + std::sort(x, x+len, tc); + + scurrent = sfirst; + tcurrent = tfirst; + ucurrent = ufirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + *ucurrent++ = x[i].third; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template void +CoinSort_3(Iter_S sfirst, Iter_S slast, Iter_T tfirst, Iter_U, ufirst) +{ + typedef typename std::iterator_traits::value_type S; + typedef typename std::iterator_traits::value_type T; + typedef typename std::iterator_traits::value_type U; + CoinSort_3(sfirts, slast, tfirst, ufirst, CoinFirstLess_3()); +} + +#else //======================================================================= + +template void +CoinSort_3(S* sfirst, S* slast, T* tfirst, U* ufirst, const CoinCompare3& tc) +{ + const size_t len = coinDistance(sfirst,slast); + if (len <= 1) + return; + + typedef CoinTriple STU_triple; + STU_triple* x = + static_cast(::operator new(len * sizeof(STU_triple))); + + size_t i = 0; + S* scurrent = sfirst; + T* tcurrent = tfirst; + U* ucurrent = ufirst; + while (scurrent != slast) { + new (x+i++) STU_triple(*scurrent++, *tcurrent++, *ucurrent++); + } + + std::sort(x, x+len, tc); + + scurrent = sfirst; + tcurrent = tfirst; + ucurrent = ufirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + *ucurrent++ = x[i].third; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template void +CoinSort_3(S* sfirst, S* slast, T* tfirst, U* ufirst) +{ + CoinSort_3(sfirst, slast, tfirst, ufirst, CoinFirstLess_3()); +} + +#endif + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin/CoinStructuredModel.hpp b/thirdparty/linux/include/coin/CoinStructuredModel.hpp new file mode 100644 index 0000000..19659b8 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinStructuredModel.hpp @@ -0,0 +1,247 @@ +/* $Id: CoinStructuredModel.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinStructuredModel_H +#define CoinStructuredModel_H + +#include "CoinModel.hpp" +#include + +/** + This is a model which is made up of Coin(Structured)Model blocks. +*/ + typedef struct CoinModelInfo2 { + int rowBlock; // Which row block + int columnBlock; // Which column block + char matrix; // nonzero if matrix exists + char rhs; // nonzero if non default rhs exists + char rowName; // nonzero if row names exists + char integer; // nonzero if integer information exists + char bounds; // nonzero if non default bounds/objective exists + char columnName; // nonzero if column names exists + CoinModelInfo2() : + rowBlock(0), + columnBlock(0), + matrix(0), + rhs(0), + rowName(0), + integer(0), + bounds(0), + columnName(0) + {} +} CoinModelBlockInfo; + +class CoinStructuredModel : public CoinBaseModel { + +public: + /**@name Useful methods for building model */ + //@{ + /** add a block from a CoinModel using names given as parameters + returns number of errors (e.g. both have objectives but not same) + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + const CoinBaseModel & block); + /** add a block from a CoinModel with names in model + returns number of errors (e.g. both have objectives but not same) + */ + int addBlock(const CoinBaseModel & block); + /** add a block from a CoinModel using names given as parameters + returns number of errors (e.g. both have objectives but not same) + This passes in block - structured model takes ownership + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + CoinBaseModel * block); + /** add a block using names + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + const CoinPackedMatrix & matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written +
    +
  • 0: plain text (default) +
  • 1: gzip compressed (.gz is appended to \c filename) +
  • 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) +
+ If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file +
    +
  • 0: normal precision (default) +
  • 1: extra accuracy +
  • 2: IEEE hex +
+ + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + not const as may change model e.g. fill in default bounds + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; + /// Read SMPS model + int readSmps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + + /** Decompose a CoinModel + 1 - try D-W + 2 - try Benders + 3 - try Staircase + Returns number of blocks or zero if no structure + */ + int decompose(const CoinModel &model,int type, + int maxBlocks=50, const char ** starts=NULL); + /** Decompose a model specified as arrays + CoinPackedMatrix + 1 - try D-W + 2 - try Benders + 3 - try Staircase + Returns number of blocks or zero if no structure + */ + int decompose(const CoinPackedMatrix & matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective, int type,int maxBlocks=50, + int * starts=NULL, + double objectiveOffset=0.0); + + //@} + + + /**@name For getting information */ + //@{ + /// Return number of row blocks + inline int numberRowBlocks() const + { return numberRowBlocks_;} + /// Return number of column blocks + inline int numberColumnBlocks() const + { return numberColumnBlocks_;} + /// Return number of elementBlocks + inline CoinBigIndex numberElementBlocks() const + { return numberElementBlocks_;} + /// Return number of elements + CoinBigIndex numberElements() const; + /// Return the i'th row block name + inline const std::string & getRowBlock(int i) const + { return rowBlockNames_[i];} + /// Set i'th row block name + inline void setRowBlock(int i,const std::string &name) + { rowBlockNames_[i] = name;} + /// Add or check a row block name and number of rows + int addRowBlock(int numberRows,const std::string &name) ; + /// Return a row block index given a row block name + int rowBlock(const std::string &name) const; + /// Return i'th the column block name + inline const std::string & getColumnBlock(int i) const + { return columnBlockNames_[i];} + /// Set i'th column block name + inline void setColumnBlock(int i,const std::string &name) + { columnBlockNames_[i] = name;} + /// Add or check a column block name and number of columns + int addColumnBlock(int numberColumns,const std::string &name) ; + /// Return a column block index given a column block name + int columnBlock(const std::string &name) const; + /// Return i'th block type + inline const CoinModelBlockInfo & blockType(int i) const + { return blockType_[i];} + /// Return i'th block + inline CoinBaseModel * block(int i) const + { return blocks_[i];} + /// Return block corresponding to row and column + const CoinBaseModel * block(int row,int column) const; + /// Return i'th block as CoinModel (or NULL) + CoinModel * coinBlock(int i) const; + /// Return block corresponding to row and column as CoinModel + const CoinBaseModel * coinBlock(int row,int column) const; + /// Return block number corresponding to row and column + int blockIndex(int row,int column) const; + /** Return model as a CoinModel block + and fill in info structure and update counts + */ + CoinModel * coinModelBlock(CoinModelBlockInfo & info) ; + /// Sets given block into coinModelBlocks_ + void setCoinModel(CoinModel * block, int iBlock); + /// Refresh info in blockType_ + void refresh(int iBlock); + /** Fill pointers corresponding to row and column */ + + CoinModelBlockInfo block(int row,int column, + const double * & rowLower, const double * & rowUpper, + const double * & columnLower, const double * & columnUpper, + const double * & objective) const; + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinStructuredModel(); + /** Read a problem in MPS format from the given filename. + May try and decompose + */ + CoinStructuredModel(const char *fileName,int decompose=0, + int maxBlocks=50); + /** Destructor */ + virtual ~CoinStructuredModel(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinStructuredModel(const CoinStructuredModel&); + /// = + CoinStructuredModel& operator=(const CoinStructuredModel&); + /// Clone + virtual CoinBaseModel * clone() const; + //@} + +private: + + /** Fill in info structure and update counts + Returns number of inconsistencies on border + */ + int fillInfo(CoinModelBlockInfo & info,const CoinModel * block); + /** Fill in info structure and update counts + */ + void fillInfo(CoinModelBlockInfo & info,const CoinStructuredModel * block); + /**@name Data members */ + //@{ + /// Current number of row blocks + int numberRowBlocks_; + /// Current number of column blocks + int numberColumnBlocks_; + /// Current number of element blocks + int numberElementBlocks_; + /// Maximum number of element blocks + int maximumElementBlocks_; + /// Rowblock name + std::vector rowBlockNames_; + /// Columnblock name + std::vector columnBlockNames_; + /// Blocks + CoinBaseModel ** blocks_; + /// CoinModel copies of blocks or NULL if original CoinModel + CoinModel ** coinModelBlocks_; + /// Which parts of model are set in block + CoinModelBlockInfo * blockType_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/CoinTime.hpp b/thirdparty/linux/include/coin/CoinTime.hpp new file mode 100644 index 0000000..49e8507 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinTime.hpp @@ -0,0 +1,310 @@ +/* $Id: CoinTime.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinTime_hpp +#define _CoinTime_hpp + +// Uncomment the next three lines for thorough memory initialisation. +// #ifndef ZEROFAULT +// # define ZEROFAULT +// #endif + +//############################################################################# + +#include +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#else +// MacOS-X and FreeBSD needs sys/time.h +#if defined(__MACH__) || defined (__FreeBSD__) +#include +#endif +#if !defined(__MSVCRT__) +#include +#endif +#endif + +//############################################################################# + +#if defined(_MSC_VER) + +#if 0 // change this to 1 if want to use the win32 API +#include +#ifdef small +/* for some unfathomable reason (to me) rpcndr.h (pulled in by windows.h) does a + '#define small char' */ +#undef small +#endif +#define TWO_TO_THE_THIRTYTWO 4294967296.0 +#define DELTA_EPOCH_IN_SECS 11644473600.0 +inline double CoinGetTimeOfDay() +{ + FILETIME ft; + + GetSystemTimeAsFileTime(&ft); + double t = ft.dwHighDateTime * TWO_TO_THE_THIRTYTWO + ft.dwLowDateTime; + t = t/10000000.0 - DELTA_EPOCH_IN_SECS; + return t; +} +#else +#include +#include +inline double CoinGetTimeOfDay() +{ + struct _timeb timebuffer; +#pragma warning(disable:4996) + _ftime( &timebuffer ); // C4996 +#pragma warning(default:4996) + return timebuffer.time + timebuffer.millitm/1000.0; +} +#endif + +#else + +#include + +inline double CoinGetTimeOfDay() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return static_cast(tv.tv_sec) + static_cast(tv.tv_usec)/1000000.0; +} + +#endif // _MSC_VER + +/** + Query the elapsed wallclock time since the first call to this function. If + a positive argument is passed to the function then the time of the first + call is set to that value (this kind of argument is allowed only at the + first call!). If a negative argument is passed to the function then it + returns the time when it was set. +*/ + +inline double CoinWallclockTime(double callType = 0) +{ + double callTime = CoinGetTimeOfDay(); + static const double firstCall = callType > 0 ? callType : callTime; + return callType < 0 ? firstCall : callTime - firstCall; +} + +//############################################################################# + +//#define HAVE_SDK // if SDK under Win32 is installed, for CPU instead of elapsed time under Win +#ifdef HAVE_SDK +#include +#ifdef small +/* for some unfathomable reason (to me) rpcndr.h (pulled in by windows.h) does a + '#define small char' */ +#undef small +#endif +#define TWO_TO_THE_THIRTYTWO 4294967296.0 +#endif + +static inline double CoinCpuTime() +{ + double cpu_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) +#ifdef HAVE_SDK + FILETIME creation; + FILETIME exit; + FILETIME kernel; + FILETIME user; + GetProcessTimes(GetCurrentProcess(), &creation, &exit, &kernel, &user); + double t = user.dwHighDateTime * TWO_TO_THE_THIRTYTWO + user.dwLowDateTime; + return t/10000000.0; +#else + unsigned int ticksnow; /* clock_t is same as int */ + ticksnow = (unsigned int)clock(); + cpu_temp = (double)((double)ticksnow/CLOCKS_PER_SEC); +#endif + +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_SELF,&usage); + cpu_temp = static_cast(usage.ru_utime.tv_sec); + cpu_temp += 1.0e-6*(static_cast (usage.ru_utime.tv_usec)); +#endif + return cpu_temp; +} + +//############################################################################# + + + +static inline double CoinSysTime() +{ + double sys_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) + sys_temp = 0.0; +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_SELF,&usage); + sys_temp = static_cast(usage.ru_stime.tv_sec); + sys_temp += 1.0e-6*(static_cast (usage.ru_stime.tv_usec)); +#endif + return sys_temp; +} + +//############################################################################# +// On most systems SELF seems to include children threads, This is for when it doesn't +static inline double CoinCpuTimeJustChildren() +{ + double cpu_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) + cpu_temp = 0.0; +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_CHILDREN,&usage); + cpu_temp = static_cast(usage.ru_utime.tv_sec); + cpu_temp += 1.0e-6*(static_cast (usage.ru_utime.tv_usec)); +#endif + return cpu_temp; +} +//############################################################################# + +#include + +/** + This class implements a timer that also implements a tracing functionality. + + The timer stores the start time of the timer, for how much time it was set to + and when does it expire (start + limit = end). Queries can be made that tell + whether the timer is expired, is past an absolute time, is past a percentage + of the length of the timer. All times are given in seconds, but as double + numbers, so there can be fractional values. + + The timer can also be initialized with a stream and a specification whether + to write to or read from the stream. In the former case the result of every + query is written into the stream, in the latter case timing is not tested at + all, rather the supposed result is read out from the stream. This makes it + possible to exactly retrace time sensitive program execution. +*/ +class CoinTimer +{ +private: + /// When the timer was initialized/reset/restarted + double start; + /// + double limit; + double end; +#ifdef COIN_COMPILE_WITH_TRACING + std::fstream* stream; + bool write_stream; +#endif + +private: +#ifdef COIN_COMPILE_WITH_TRACING + inline bool evaluate(bool b_tmp) const { + int i_tmp = b_tmp; + if (stream) { + if (write_stream) + (*stream) << i_tmp << "\n"; + else + (*stream) >> i_tmp; + } + return i_tmp; + } + inline double evaluate(double d_tmp) const { + if (stream) { + if (write_stream) + (*stream) << d_tmp << "\n"; + else + (*stream) >> d_tmp; + } + return d_tmp; + } +#else + inline bool evaluate(const bool b_tmp) const { + return b_tmp; + } + inline double evaluate(const double d_tmp) const { + return d_tmp; + } +#endif + +public: + /// Default constructor creates a timer with no time limit and no tracing + CoinTimer() : + start(0), limit(1e100), end(1e100) +#ifdef COIN_COMPILE_WITH_TRACING + , stream(0), write_stream(true) +#endif + {} + + /// Create a timer with the given time limit and with no tracing + CoinTimer(double lim) : + start(CoinCpuTime()), limit(lim), end(start+lim) +#ifdef COIN_COMPILE_WITH_TRACING + , stream(0), write_stream(true) +#endif + {} + +#ifdef COIN_COMPILE_WITH_TRACING + /** Create a timer with no time limit and with writing/reading the trace + to/from the given stream, depending on the argument \c write. */ + CoinTimer(std::fstream* s, bool write) : + start(0), limit(1e100), end(1e100), + stream(s), write_stream(write) {} + + /** Create a timer with the given time limit and with writing/reading the + trace to/from the given stream, depending on the argument \c write. */ + CoinTimer(double lim, std::fstream* s, bool w) : + start(CoinCpuTime()), limit(lim), end(start+lim), + stream(s), write_stream(w) {} +#endif + + /// Restart the timer (keeping the same time limit) + inline void restart() { start=CoinCpuTime(); end=start+limit; } + /// An alternate name for \c restart() + inline void reset() { restart(); } + /// Reset (and restart) the timer and change its time limit + inline void reset(double lim) { limit=lim; restart(); } + + /** Return whether the given percentage of the time limit has elapsed since + the timer was started */ + inline bool isPastPercent(double pct) const { + return evaluate(start + limit * pct < CoinCpuTime()); + } + /** Return whether the given amount of time has elapsed since the timer was + started */ + inline bool isPast(double lim) const { + return evaluate(start + lim < CoinCpuTime()); + } + /** Return whether the originally specified time limit has passed since the + timer was started */ + inline bool isExpired() const { + return evaluate(end < CoinCpuTime()); + } + + /** Return how much time is left on the timer */ + inline double timeLeft() const { + return evaluate(end - CoinCpuTime()); + } + + /** Return how much time has elapsed */ + inline double timeElapsed() const { + return evaluate(CoinCpuTime() - start); + } + + inline void setLimit(double l) { + limit = l; + return; + } +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinTypes.hpp b/thirdparty/linux/include/coin/CoinTypes.hpp new file mode 100644 index 0000000..3adee2e --- /dev/null +++ b/thirdparty/linux/include/coin/CoinTypes.hpp @@ -0,0 +1,64 @@ +/* $Id: CoinTypes.hpp 1762 2014-12-29 20:37:12Z tkr $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinTypes_hpp +#define _CoinTypes_hpp + +#include "CoinUtilsConfig.h" +/* On some systems, we require stdint.h to have the 64bit integer type defined. */ +#ifdef COINUTILS_HAS_STDINT_H +#include +#endif +#ifdef COINUTILS_HAS_CSTDINT +#include +#endif + +#define CoinInt64 COIN_INT64_T +#define CoinUInt64 COIN_UINT64_T +#define CoinIntPtr COIN_INTPTR_T + +//============================================================================= +#ifndef COIN_BIG_INDEX +#define COIN_BIG_INDEX 0 +#endif + +#if COIN_BIG_INDEX==0 +typedef int CoinBigIndex; +#elif COIN_BIG_INDEX==1 +typedef long CoinBigIndex; +#else +typedef long long CoinBigIndex; +#endif + +//============================================================================= +#ifndef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 0 +#endif + +// See if we want the ability to have long double work arrays +#if COIN_BIG_DOUBLE==2 +#undef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 0 +#define COIN_LONG_WORK 1 +typedef long double CoinWorkDouble; +#elif COIN_BIG_DOUBLE==3 +#undef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 1 +#define COIN_LONG_WORK 1 +typedef long double CoinWorkDouble; +#else +#define COIN_LONG_WORK 0 +typedef double CoinWorkDouble; +#endif + +#if COIN_BIG_DOUBLE==0 +typedef double CoinFactorizationDouble; +#elif COIN_BIG_DOUBLE==1 +typedef long double CoinFactorizationDouble; +#else +typedef double CoinFactorizationDouble; +#endif + +#endif diff --git a/thirdparty/linux/include/coin/CoinUtility.hpp b/thirdparty/linux/include/coin/CoinUtility.hpp new file mode 100644 index 0000000..49a30e2 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinUtility.hpp @@ -0,0 +1,19 @@ +/* $Id: CoinUtility.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinUtility_h_ +#define CoinUtility_h_ + +#include "CoinSort.hpp" + +template +CoinPair CoinMakePair(const S& s, const T& t) +{ return CoinPair(s, t); } + +template +CoinTriple CoinMakeTriple(const S& s, const T& t, const U& u) +{ return CoinTriple(s, t, u); } + +#endif diff --git a/thirdparty/linux/include/coin/CoinUtilsConfig.h b/thirdparty/linux/include/coin/CoinUtilsConfig.h new file mode 100644 index 0000000..03c4d55 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinUtilsConfig.h @@ -0,0 +1,34 @@ +/* src/config_coinutils.h. Generated by configure. */ +/* inc/config_coinutils.h.in. */ + +#ifndef __CONFIG_COINUTILS_H__ +#define __CONFIG_COINUTILS_H__ + +/* Define to 1 if stdint.h is available for CoinUtils */ +#define COINUTILS_HAS_STDINT_H 1 + +/* Define to 1 if stdint.h is available for CoinUtils */ +/* #undef COINUTILS_HAS_CSTDINT */ + +/* Version number of project */ +#define COINUTILS_VERSION "2.10.11" + +/* Major Version number of project */ +#define COINUTILS_VERSION_MAJOR 2 + +/* Minor Version number of project */ +#define COINUTILS_VERSION_MINOR 10 + +/* Release Version number of project */ +#define COINUTILS_VERSION_RELEASE 11 + +/* Define to 64bit integer type */ +#define COIN_INT64_T int64_t + +/* Define to integer type capturing pointer */ +#define COIN_INTPTR_T intptr_t + +/* Define to 64bit unsigned integer type */ +#define COIN_UINT64_T int64_t + +#endif diff --git a/thirdparty/linux/include/coin/CoinWarmStart.hpp b/thirdparty/linux/include/coin/CoinWarmStart.hpp new file mode 100644 index 0000000..a7e28c8 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinWarmStart.hpp @@ -0,0 +1,58 @@ +/* $Id: CoinWarmStart.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStart_H +#define CoinWarmStart_H + +//############################################################################# + +class CoinWarmStartDiff; + +/** Abstract base class for warm start information. + + Really nothing can be generalized for warm start information --- all we + know is that it exists. Hence the abstract base class contains only a + virtual destructor and a virtual clone function (a virtual constructor), + so that derived classes can provide these functions. +*/ + +class CoinWarmStart { +public: + + /// Abstract destructor + virtual ~CoinWarmStart() {} + + /// `Virtual constructor' + virtual CoinWarmStart *clone() const = 0 ; + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const ) const { return 0; } + + + virtual void + applyDiff (const CoinWarmStartDiff *const ) {} + +}; + + +/*! \class CoinWarmStartDiff + \brief Abstract base class for warm start `diff' objects + + For those types of warm start objects where the notion of a `diff' makes + sense, this virtual base class is provided. As with CoinWarmStart, its sole + reason for existence is to make it possible to write solver-independent code. +*/ + +class CoinWarmStartDiff { +public: + + /// Abstract destructor + virtual ~CoinWarmStartDiff() {} + + /// `Virtual constructor' + virtual CoinWarmStartDiff *clone() const = 0 ; +}; + +#endif diff --git a/thirdparty/linux/include/coin/CoinWarmStartBasis.hpp b/thirdparty/linux/include/coin/CoinWarmStartBasis.hpp new file mode 100644 index 0000000..272d393 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinWarmStartBasis.hpp @@ -0,0 +1,456 @@ +/* $Id: CoinWarmStartBasis.hpp 1515 2011-12-10 23:38:04Z lou $ */ +/*! \legal + Copyright (C) 2000 -- 2003, International Business Machines Corporation + and others. All Rights Reserved. + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ + +/*! \file CoinWarmStart.hpp + \brief Declaration of the generic simplex (basis-oriented) warm start + class. Also contains a basis diff class. +*/ + +#ifndef CoinWarmStartBasis_H +#define CoinWarmStartBasis_H + +#include + +#include "CoinSort.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" + +//############################################################################# + +/*! \class CoinWarmStartBasis + \brief The default COIN simplex (basis-oriented) warm start class + + CoinWarmStartBasis provides for a warm start object which contains the + status of each variable (structural and artificial). + + \todo Modify this class so that the number of status entries per byte + and bytes per status vector allocation unit are not hardcoded. + At the least, collect this into a couple of macros. + + \todo Consider separate fields for allocated capacity and actual basis + size. We could avoid some reallocation, at the price of retaining + more space than we need. Perhaps more important, we could do much + better sanity checks. +*/ + +class CoinWarmStartBasis : public virtual CoinWarmStart { +public: + + /*! \brief Enum for status of variables + + Matches CoinPrePostsolveMatrix::Status, without superBasic. Most code that + converts between CoinPrePostsolveMatrix::Status and + CoinWarmStartBasis::Status will break if this correspondence is broken. + + The status vectors are currently packed using two bits per status code, + four codes per byte. The location of the status information for + variable \c i is in byte i>>2 and occupies bits 0:1 + if i\%4 == 0, bits 2:3 if i\%4 == 1, etc. + The non-member functions getStatus(const char*,int) and + setStatus(char*,int,CoinWarmStartBasis::Status) are provided to hide + details of the packing. + */ + enum Status { + isFree = 0x00, ///< Nonbasic free variable + basic = 0x01, ///< Basic variable + atUpperBound = 0x02, ///< Nonbasic at upper bound + atLowerBound = 0x03 ///< Nonbasic at lower bound + }; + + /** \brief Transfer vector entry for + mergeBasis(const CoinWarmStartBasis*,const XferVec*,const XferVec*) + */ + typedef CoinTriple XferEntry ; + + /** \brief Transfer vector for + mergeBasis(const CoinWarmStartBasis*,const XferVec*,const XferVec*) + */ + typedef std::vector XferVec ; + +public: + +/*! \name Methods to get and set basis information. + + The status of variables is kept in a pair of arrays, one for structural + variables, and one for artificials (aka logicals and slacks). The status + is coded using the values of the Status enum. + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. +*/ +//@{ + /// Return the number of structural variables + inline int getNumStructural() const { return numStructural_; } + + /// Return the number of artificial variables + inline int getNumArtificial() const { return numArtificial_; } + + /** Return the number of basic structurals + + A fast test for an all-slack basis. + */ + int numberBasicStructurals() const ; + + /// Return the status of the specified structural variable. + inline Status getStructStatus(int i) const { + const int st = (structuralStatus_[i>>2] >> ((i&3)<<1)) & 3; + return static_cast(st); + } + + /// Set the status of the specified structural variable. + inline void setStructStatus(int i, Status st) { + char& st_byte = structuralStatus_[i>>2]; + st_byte = static_cast(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast(st_byte | (st << ((i&3)<<1))) ; + } + + /** Return the status array for the structural variables + + The status information is stored using the codes defined in the + Status enum, 2 bits per variable, packed 4 variables per byte. + */ + inline char * getStructuralStatus() { return structuralStatus_; } + + /** \c const overload for + \link CoinWarmStartBasis::getStructuralStatus() + getStructuralStatus() + \endlink + */ + inline const char * getStructuralStatus() const { return structuralStatus_; } + + /** As for \link getStructuralStatus() getStructuralStatus \endlink, + but returns the status array for the artificial variables. + */ + inline char * getArtificialStatus() { return artificialStatus_; } + + /// Return the status of the specified artificial variable. + inline Status getArtifStatus(int i) const { + const int st = (artificialStatus_[i>>2] >> ((i&3)<<1)) & 3; + return static_cast(st); + } + + /// Set the status of the specified artificial variable. + inline void setArtifStatus(int i, Status st) { + char& st_byte = artificialStatus_[i>>2]; + st_byte = static_cast(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast(st_byte | (st << ((i&3)<<1))) ; + } + + /** \c const overload for + \link CoinWarmStartBasis::getArtificialStatus() + getArtificialStatus() + \endlink + */ + inline const char * getArtificialStatus() const { return artificialStatus_; } + +//@} + +/*! \name Basis `diff' methods */ +//@{ + + /*! \brief Generate a `diff' that can convert the warm start basis passed as + a parameter to the warm start basis specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this basis + + Update this basis by applying \p diff. It's assumed that the allocated + capacity of the basis is sufficiently large. + */ + + virtual void + applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + +//@} + + +/*! \name Methods to modify the warm start object */ +//@{ + + /*! \brief Set basis capacity; existing basis is discarded. + + After execution of this routine, the warm start object does not describe + a valid basis: all structural and artificial variables have status isFree. + */ + virtual void setSize(int ns, int na) ; + + /*! \brief Set basis capacity; existing basis is maintained. + + After execution of this routine, the warm start object describes a valid + basis: the status of new structural variables (added columns) is set to + nonbasic at lower bound, and the status of new artificial variables + (added rows) is set to basic. (The basis can be invalid if new structural + variables do not have a finite lower bound.) + */ + virtual void resize (int newNumberRows, int newNumberColumns); + + /** \brief Delete a set of rows from the basis + + \warning + This routine assumes that the set of indices to be deleted is sorted in + ascending order and contains no duplicates. Use deleteRows() if this is + not the case. + + \warning + The resulting basis is guaranteed valid only if all deleted + constraints are slack (hence the associated logicals are basic). + + Removal of a tight constraint with a nonbasic logical implies that + some basic variable must be made nonbasic. This correction is left to + the client. + */ + + virtual void compressRows (int tgtCnt, const int *tgts) ; + + /** \brief Delete a set of rows from the basis + + \warning + The resulting basis is guaranteed valid only if all deleted + constraints are slack (hence the associated logicals are basic). + + Removal of a tight constraint with a nonbasic logical implies that + some basic variable must be made nonbasic. This correction is left to + the client. + */ + + virtual void deleteRows(int rawTgtCnt, const int *rawTgts) ; + + /** \brief Delete a set of columns from the basis + + \warning + The resulting basis is guaranteed valid only if all deleted variables + are nonbasic. + + Removal of a basic variable implies that some nonbasic variable must be + made basic. This correction is left to the client. + */ + + virtual void deleteColumns(int number, const int * which); + + /** \brief Merge entries from a source basis into this basis. + + \warning + It's the client's responsibility to ensure validity of the merged basis, + if that's important to the application. + + The vector xferCols (xferRows) specifies runs of entries to be taken from + the source basis and placed in this basis. Each entry is a CoinTriple, + with first specifying the starting source index of a run, second + specifying the starting destination index, and third specifying the run + length. + */ + virtual void mergeBasis(const CoinWarmStartBasis *src, + const XferVec *xferRows, + const XferVec *xferCols) ; + +//@} + +/*! \name Constructors, destructors, and related functions */ + +//@{ + + /** Default constructor + + Creates a warm start object representing an empty basis + (0 rows, 0 columns). + */ + CoinWarmStartBasis(); + + /** Constructs a warm start object with the specified status vectors. + + The parameters are copied. + Consider assignBasisStatus(int,int,char*&,char*&) if the object should + assume ownership. + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. + */ + CoinWarmStartBasis(int ns, int na, const char* sStat, const char* aStat) ; + + /** Copy constructor */ + CoinWarmStartBasis(const CoinWarmStartBasis& ws) ; + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const + { + return new CoinWarmStartBasis(*this); + } + + /** Destructor */ + virtual ~CoinWarmStartBasis(); + + /** Assignment */ + + virtual CoinWarmStartBasis& operator=(const CoinWarmStartBasis& rhs) ; + + /** Assign the status vectors to be the warm start information. + + In this method the CoinWarmStartBasis object assumes ownership of the + pointers and upon return the argument pointers will be NULL. + If copying is desirable, use the + \link CoinWarmStartBasis(int,int,const char*,const char*) + array constructor \endlink + or the + \link operator=(const CoinWarmStartBasis&) + assignment operator \endlink. + + \note + The pointers passed to this method will be + freed using delete[], so they must be created using new[]. + */ + virtual void assignBasisStatus(int ns, int na, char*& sStat, char*& aStat) ; +//@} + +/*! \name Miscellaneous methods */ +//@{ + + /// Prints in readable format (for debug) + virtual void print() const; + /// Returns true if full basis (for debug) + bool fullBasis() const; + /// Returns true if full basis and fixes up (for debug) + bool fixFullBasis(); + +//@} + +protected: + /** \name Protected data members + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. + */ + //@{ + /// The number of structural variables + int numStructural_; + /// The number of artificial variables + int numArtificial_; + /// The maximum sise (in ints - actually 4*char) (so resize does not need to do new) + int maxSize_; + /** The status of the structural variables. */ + char * structuralStatus_; + /** The status of the artificial variables. */ + char * artificialStatus_; + //@} +}; + + +/*! \relates CoinWarmStartBasis + \brief Get the status of the specified variable in the given status array. +*/ + +inline CoinWarmStartBasis::Status getStatus(const char *array, int i) { + const int st = (array[i>>2] >> ((i&3)<<1)) & 3; + return static_cast(st); +} + +/*! \relates CoinWarmStartBasis + \brief Set the status of the specified variable in the given status array. +*/ + +inline void setStatus(char * array, int i, CoinWarmStartBasis::Status st) { + char& st_byte = array[i>>2]; + st_byte = static_cast(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast(st_byte | (st << ((i&3)<<1))) ; +} + +/*! \relates CoinWarmStartBasis + \brief Generate a print string for a status code +*/ +const char *statusName(CoinWarmStartBasis::Status status) ; + + +/*! \class CoinWarmStartBasisDiff + \brief A `diff' between two CoinWarmStartBasis objects + + This class exists in order to hide from the world the details of + calculating and representing a `diff' between two CoinWarmStartBasis + objects. For convenience, assignment, cloning, and deletion are visible to + the world, and default and copy constructors are made available to derived + classes. Knowledge of the rest of this structure, and of generating and + applying diffs, is restricted to the friend functions + CoinWarmStartBasis::generateDiff() and CoinWarmStartBasis::applyDiff(). + + The actual data structure is an unsigned int vector, #difference_ which + starts with indices of changed and then has values starting after #sze_ + + \todo This is a pretty generic structure, and vector diff is a pretty generic + activity. We should be able to convert this to a template. + + \todo Using unsigned int as the data type for the diff vectors might help + to contain the damage when this code is inevitably compiled for 64 bit + architectures. But the notion of int as 4 bytes is hardwired into + CoinWarmStartBasis, so changes are definitely required. +*/ + +class CoinWarmStartBasisDiff : public virtual CoinWarmStartDiff +{ public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff *clone() const + { CoinWarmStartBasisDiff *cwsbd = new CoinWarmStartBasisDiff(*this) ; + return (dynamic_cast(cwsbd)) ; } + + /*! \brief Assignment */ + virtual + CoinWarmStartBasisDiff &operator= (const CoinWarmStartBasisDiff &rhs) ; + + /*! \brief Destructor */ + virtual ~CoinWarmStartBasisDiff(); + + protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make their default constructor protected or + private. + */ + CoinWarmStartBasisDiff () : sze_(0), difference_(0) { } + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartBasisDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + + This is protected (rather than private) so that derived classes can + see it when they make their copy constructor protected or + private. + */ + CoinWarmStartBasisDiff (const CoinWarmStartBasisDiff &cwsbd) ; + + /*! \brief Standard constructor */ + CoinWarmStartBasisDiff (int sze, const unsigned int *const diffNdxs, + const unsigned int *const diffVals) ; + + /*! \brief Constructor when full is smaller than diff!*/ + CoinWarmStartBasisDiff (const CoinWarmStartBasis * rhs); + + private: + + friend CoinWarmStartDiff* + CoinWarmStartBasis::generateDiff(const CoinWarmStart *const oldCWS) const ; + friend void + CoinWarmStartBasis::applyDiff(const CoinWarmStartDiff *const diff) ; + + /*! \brief Number of entries (and allocated capacity), in units of \c int. */ + int sze_ ; + + /*! \brief Array of diff indices and diff values */ + + unsigned int *difference_ ; + +} ; + + +#endif diff --git a/thirdparty/linux/include/coin/CoinWarmStartDual.hpp b/thirdparty/linux/include/coin/CoinWarmStartDual.hpp new file mode 100644 index 0000000..3e60d11 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinWarmStartDual.hpp @@ -0,0 +1,166 @@ +/* $Id: CoinWarmStartDual.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartDual_H +#define CoinWarmStartDual_H + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" +#include "CoinWarmStartVector.hpp" + + +//############################################################################# + +/** WarmStart information that is only a dual vector */ + +class CoinWarmStartDual : public virtual CoinWarmStart { +public: + /// return the size of the dual vector + inline int size() const { return dual_.size(); } + /// return a pointer to the array of duals + inline const double * dual() const { return dual_.values(); } + + /** Assign the dual vector to be the warmstart information. In this method + the object assumes ownership of the pointer and upon return "dual" will + be a NULL pointer. If copying is desirable use the constructor. */ + inline void assignDual(int size, double *& dual) + { dual_.assignVector(size, dual); } + + CoinWarmStartDual() {} + + CoinWarmStartDual(int size, const double * dual) : dual_(size, dual) {} + + CoinWarmStartDual(const CoinWarmStartDual& rhs) : dual_(rhs.dual_) {} + + CoinWarmStartDual& operator=(const CoinWarmStartDual& rhs) { + if (this != &rhs) { + dual_ = rhs.dual_; + } + return *this; + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartDual(*this); + } + + virtual ~CoinWarmStartDual() {} + +/*! \name Dual warm start `diff' methods */ +//@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + +#if 0 +protected: + inline const CoinWarmStartVector& warmStartVector() const { return dual_; } +#endif + +//@} + +private: + ///@name Private data members + CoinWarmStartVector dual_; +}; + +//############################################################################# + +/*! \class CoinWarmStartDualDiff + \brief A `diff' between two CoinWarmStartDual objects + + This class exists in order to hide from the world the details of + calculating and representing a `diff' between two CoinWarmStartDual + objects. For convenience, assignment, cloning, and deletion are visible to + the world, and default and copy constructors are made available to derived + classes. Knowledge of the rest of this structure, and of generating and + applying diffs, is restricted to the friend functions + CoinWarmStartDual::generateDiff() and CoinWarmStartDual::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +class CoinWarmStartDualDiff : public virtual CoinWarmStartDiff +{ public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff *clone() const + { + return new CoinWarmStartDualDiff(*this) ; + } + + /*! \brief Assignment */ + virtual CoinWarmStartDualDiff &operator= (const CoinWarmStartDualDiff &rhs) + { + if (this != &rhs) { + diff_ = rhs.diff_; + } + return *this; + } + + /*! \brief Destructor */ + virtual ~CoinWarmStartDualDiff() {} + + protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make their default constructor protected or + private. + */ + CoinWarmStartDualDiff () : diff_() {} + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartDualDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + + This is protected (rather than private) so that derived classes can + see it when the make their copy constructor protected or + private. + */ + CoinWarmStartDualDiff (const CoinWarmStartDualDiff &rhs) : + diff_(rhs.diff_) {} + + private: + + friend CoinWarmStartDiff* + CoinWarmStartDual::generateDiff(const CoinWarmStart *const oldCWS) const ; + friend void + CoinWarmStartDual::applyDiff(const CoinWarmStartDiff *const diff) ; + + /*! \brief Standard constructor */ + CoinWarmStartDualDiff (int sze, const unsigned int *const diffNdxs, + const double *const diffVals) : + diff_(sze, diffNdxs, diffVals) {} + + /*! + \brief The difference in the dual vector is simply the difference in a + vector. + */ + CoinWarmStartVectorDiff diff_; +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/CoinWarmStartPrimalDual.hpp b/thirdparty/linux/include/coin/CoinWarmStartPrimalDual.hpp new file mode 100644 index 0000000..c98d423 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinWarmStartPrimalDual.hpp @@ -0,0 +1,211 @@ +/* $Id: CoinWarmStartPrimalDual.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartPrimalDual_H +#define CoinWarmStartPrimalDual_H + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" +#include "CoinWarmStartVector.hpp" + + +//############################################################################# + +/** WarmStart information that is only a dual vector */ + +class CoinWarmStartPrimalDual : public virtual CoinWarmStart { +public: + /// return the size of the dual vector + inline int dualSize() const { return dual_.size(); } + /// return a pointer to the array of duals + inline const double * dual() const { return dual_.values(); } + + /// return the size of the primal vector + inline int primalSize() const { return primal_.size(); } + /// return a pointer to the array of primals + inline const double * primal() const { return primal_.values(); } + + /** Assign the primal/dual vectors to be the warmstart information. In this + method the object assumes ownership of the pointers and upon return \c + primal and \c dual will be a NULL pointers. If copying is desirable use + the constructor. + + NOTE: \c primal and \c dual must have been allocated by new double[], + because they will be freed by delete[] upon the desructtion of this + object... + */ + void assign(int primalSize, int dualSize, double*& primal, double *& dual) { + primal_.assignVector(primalSize, primal); + dual_.assignVector(dualSize, dual); + } + + CoinWarmStartPrimalDual() : primal_(), dual_() {} + + CoinWarmStartPrimalDual(int primalSize, int dualSize, + const double* primal, const double * dual) : + primal_(primalSize, primal), dual_(dualSize, dual) {} + + CoinWarmStartPrimalDual(const CoinWarmStartPrimalDual& rhs) : + primal_(rhs.primal_), dual_(rhs.dual_) {} + + CoinWarmStartPrimalDual& operator=(const CoinWarmStartPrimalDual& rhs) { + if (this != &rhs) { + primal_ = rhs.primal_; + dual_ = rhs.dual_; + } + return *this; + } + + /*! \brief Clear the data + + Make it appear as if the warmstart was just created using the default + constructor. + */ + inline void clear() { + primal_.clear(); + dual_.clear(); + } + + inline void swap(CoinWarmStartPrimalDual& rhs) { + if (this != &rhs) { + primal_.swap(rhs.primal_); + dual_.swap(rhs.dual_); + } + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartPrimalDual(*this); + } + + virtual ~CoinWarmStartPrimalDual() {} + + /*! \name PrimalDual warm start `diff' methods */ + //@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + + //@} + +#if 0 +protected: + inline const CoinWarmStartVector& primalWarmStartVector() const + { return primal_; } + inline const CoinWarmStartVector& dualWarmStartVector() const + { return dual_; } +#endif + +private: + ///@name Private data members + //@{ + CoinWarmStartVector primal_; + CoinWarmStartVector dual_; + //@} +}; + +//############################################################################# + +/*! \class CoinWarmStartPrimalDualDiff + \brief A `diff' between two CoinWarmStartPrimalDual objects + + This class exists in order to hide from the world the details of calculating + and representing a `diff' between two CoinWarmStartPrimalDual objects. For + convenience, assignment, cloning, and deletion are visible to the world, and + default and copy constructors are made available to derived classes. + Knowledge of the rest of this structure, and of generating and applying + diffs, is restricted to the friend functions + CoinWarmStartPrimalDual::generateDiff() and + CoinWarmStartPrimalDual::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +class CoinWarmStartPrimalDualDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartPrimalDual::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartPrimalDual::applyDiff(const CoinWarmStartDiff *const diff) ; + +public: + + /*! \brief `Virtual constructor'. To be used when retaining polymorphism is + important */ + virtual CoinWarmStartDiff *clone() const + { + return new CoinWarmStartPrimalDualDiff(*this); + } + + /*! \brief Destructor */ + virtual ~CoinWarmStartPrimalDualDiff() {} + +protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make their default constructor protected or + private. + */ + CoinWarmStartPrimalDualDiff () : primalDiff_(), dualDiff_() {} + + /*! \brief Copy constructor + + For convenience when copying objects containing + CoinWarmStartPrimalDualDiff objects. But consider whether you should be + using #clone() to retain polymorphism. + + This is protected (rather than private) so that derived classes can + see it when the make their copy constructor protected or + private. + */ + CoinWarmStartPrimalDualDiff (const CoinWarmStartPrimalDualDiff &rhs) : + primalDiff_(rhs.primalDiff_), dualDiff_(rhs.dualDiff_) {} + + /*! \brief Clear the data + + Make it appear as if the diff was just created using the default + constructor. + */ + inline void clear() { + primalDiff_.clear(); + dualDiff_.clear(); + } + + inline void swap(CoinWarmStartPrimalDualDiff& rhs) { + if (this != &rhs) { + primalDiff_.swap(rhs.primalDiff_); + dualDiff_.swap(rhs.dualDiff_); + } + } + +private: + + /*! + \brief These two differences describe the differences in the primal and + in the dual vector. + */ + CoinWarmStartVectorDiff primalDiff_; + CoinWarmStartVectorDiff dualDiff_; +} ; + +#endif diff --git a/thirdparty/linux/include/coin/CoinWarmStartVector.hpp b/thirdparty/linux/include/coin/CoinWarmStartVector.hpp new file mode 100644 index 0000000..e43ea10 --- /dev/null +++ b/thirdparty/linux/include/coin/CoinWarmStartVector.hpp @@ -0,0 +1,488 @@ +/* $Id: CoinWarmStartVector.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartVector_H +#define CoinWarmStartVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include +#include + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" + + +//############################################################################# + +/** WarmStart information that is only a vector */ + +template +class CoinWarmStartVector : public virtual CoinWarmStart +{ +protected: + inline void gutsOfDestructor() { + delete[] values_; + } + inline void gutsOfCopy(const CoinWarmStartVector& rhs) { + size_ = rhs.size_; + values_ = new T[size_]; + CoinDisjointCopyN(rhs.values_, size_, values_); + } + +public: + /// return the size of the vector + int size() const { return size_; } + /// return a pointer to the array of vectors + const T* values() const { return values_; } + + /** Assign the vector to be the warmstart information. In this method + the object assumes ownership of the pointer and upon return #vector will + be a NULL pointer. If copying is desirable use the constructor. */ + void assignVector(int size, T*& vec) { + size_ = size; + delete[] values_; + values_ = vec; + vec = NULL; + } + + CoinWarmStartVector() : size_(0), values_(NULL) {} + + CoinWarmStartVector(int size, const T* vec) : + size_(size), values_(new T[size]) { + CoinDisjointCopyN(vec, size, values_); + } + + CoinWarmStartVector(const CoinWarmStartVector& rhs) { + gutsOfCopy(rhs); + } + + CoinWarmStartVector& operator=(const CoinWarmStartVector& rhs) { + if (this != &rhs) { + gutsOfDestructor(); + gutsOfCopy(rhs); + } + return *this; + } + + inline void swap(CoinWarmStartVector& rhs) { + if (this != &rhs) { + std::swap(size_, rhs.size_); + std::swap(values_, rhs.values_); + } + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartVector(*this); + } + + virtual ~CoinWarmStartVector() { + gutsOfDestructor(); + } + + /*! \brief Clear the data + + Make it appear as if the warmstart was just created using the default + constructor. + */ + inline void clear() { + size_ = 0; + delete[] values_; + values_ = NULL; + } + + /*! \name Vector warm start `diff' methods */ + //@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + + //@} + +private: + ///@name Private data members + //@{ + /// the size of the vector + int size_; + /// the vector itself + T* values_; + //@} +}; + +//============================================================================= + +/*! \class CoinWarmStartVectorDiff + \brief A `diff' between two CoinWarmStartVector objects + + This class exists in order to hide from the world the details of calculating + and representing a `diff' between two CoinWarmStartVector objects. For + convenience, assignment, cloning, and deletion are visible to the world, and + default and copy constructors are made available to derived classes. + Knowledge of the rest of this structure, and of generating and applying + diffs, is restricted to the friend functions + CoinWarmStartVector::generateDiff() and CoinWarmStartVector::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +template +class CoinWarmStartVectorDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartVector::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartVector::applyDiff(const CoinWarmStartDiff *const diff) ; + +public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff * clone() const { + return new CoinWarmStartVectorDiff(*this) ; + } + + /*! \brief Assignment */ + virtual CoinWarmStartVectorDiff & + operator= (const CoinWarmStartVectorDiff& rhs) ; + + /*! \brief Destructor */ + virtual ~CoinWarmStartVectorDiff() { + delete[] diffNdxs_ ; + delete[] diffVals_ ; + } + + inline void swap(CoinWarmStartVectorDiff& rhs) { + if (this != &rhs) { + std::swap(sze_, rhs.sze_); + std::swap(diffNdxs_, rhs.diffNdxs_); + std::swap(diffVals_, rhs.diffVals_); + } + } + + /*! \brief Default constructor + */ + CoinWarmStartVectorDiff () : sze_(0), diffNdxs_(0), diffVals_(NULL) {} + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartVectorDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + */ + CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff& rhs) ; + + /*! \brief Standard constructor */ + CoinWarmStartVectorDiff(int sze, const unsigned int* const diffNdxs, + const T* const diffVals) ; + + /*! \brief Clear the data + + Make it appear as if the diff was just created using the default + constructor. + */ + inline void clear() { + sze_ = 0; + delete[] diffNdxs_; diffNdxs_ = NULL; + delete[] diffVals_; diffVals_ = NULL; + } + +private: + + /*! + \brief Number of entries (and allocated capacity), in units of \c T. + */ + int sze_ ; + + /*! \brief Array of diff indices */ + + unsigned int* diffNdxs_ ; + + /*! \brief Array of diff values */ + + T* diffVals_ ; +}; + +//############################################################################## + +template +class CoinWarmStartVectorPair : public virtual CoinWarmStart +{ +private: + CoinWarmStartVector t_; + CoinWarmStartVector u_; + +public: + inline int size0() const { return t_.size(); } + inline int size1() const { return u_.size(); } + inline const T* values0() const { return t_.values(); } + inline const U* values1() const { return u_.values(); } + + inline void assignVector0(int size, T*& vec) { t_.assignVector(size, vec); } + inline void assignVector1(int size, U*& vec) { u_.assignVector(size, vec); } + + CoinWarmStartVectorPair() {} + CoinWarmStartVectorPair(int s0, const T* v0, int s1, const U* v1) : + t_(s0, v0), u_(s1, v1) {} + + CoinWarmStartVectorPair(const CoinWarmStartVectorPair& rhs) : + t_(rhs.t_), u_(rhs.u_) {} + CoinWarmStartVectorPair& operator=(const CoinWarmStartVectorPair& rhs) { + if (this != &rhs) { + t_ = rhs.t_; + u_ = rhs.u_; + } + return *this; + } + + inline void swap(CoinWarmStartVectorPair& rhs) { + t_.swap(rhs.t_); + u_.swap(rhs.u_); + } + + virtual CoinWarmStart *clone() const { + return new CoinWarmStartVectorPair(*this); + } + + virtual ~CoinWarmStartVectorPair() {} + + inline void clear() { + t_.clear(); + u_.clear(); + } + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; +}; + +//============================================================================= + +template +class CoinWarmStartVectorPairDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartVectorPair::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartVectorPair::applyDiff(const CoinWarmStartDiff *const diff) ; + +private: + CoinWarmStartVectorDiff tdiff_; + CoinWarmStartVectorDiff udiff_; + +public: + CoinWarmStartVectorPairDiff() {} + CoinWarmStartVectorPairDiff(const CoinWarmStartVectorPairDiff& rhs) : + tdiff_(rhs.tdiff_), udiff_(rhs.udiff_) {} + virtual ~CoinWarmStartVectorPairDiff() {} + + virtual CoinWarmStartVectorPairDiff& + operator=(const CoinWarmStartVectorPairDiff& rhs) { + if (this != &rhs) { + tdiff_ = rhs.tdiff_; + udiff_ = rhs.udiff_; + } + return *this; + } + + virtual CoinWarmStartDiff * clone() const { + return new CoinWarmStartVectorPairDiff(*this) ; + } + + inline void swap(CoinWarmStartVectorPairDiff& rhs) { + tdiff_.swap(rhs.tdiff_); + udiff_.swap(rhs.udiff_); + } + + inline void clear() { + tdiff_.clear(); + udiff_.clear(); + } +}; + +//############################################################################## +//############################################################################# + +/* + Generate a `diff' that can convert the warm start passed as a parameter to + the warm start specified by this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by this. +*/ + +template CoinWarmStartDiff* +CoinWarmStartVector::generateDiff(const CoinWarmStart *const oldCWS) const +{ +/* + Make sure the parameter is CoinWarmStartVector or derived class. +*/ + const CoinWarmStartVector* oldVector = + dynamic_cast*>(oldCWS); + if (!oldVector) + { throw CoinError("Old warm start not derived from CoinWarmStartVector.", + "generateDiff","CoinWarmStartVector") ; } + const CoinWarmStartVector* newVector = this ; + /* + Make sure newVector is equal or bigger than oldVector. Calculate the worst + case number of diffs and allocate vectors to hold them. + */ + const int oldCnt = oldVector->size() ; + const int newCnt = newVector->size() ; + + assert(newCnt >= oldCnt) ; + + unsigned int *diffNdx = new unsigned int [newCnt]; + T* diffVal = new T[newCnt]; + /* + Scan the vector vectors. For the portion of the vectors which overlap, + create diffs. Then add any additional entries from newVector. + */ + const T*oldVal = oldVector->values() ; + const T*newVal = newVector->values() ; + int numberChanged = 0 ; + int i ; + for (i = 0 ; i < oldCnt ; i++) { + if (oldVal[i] != newVal[i]) { + diffNdx[numberChanged] = i ; + diffVal[numberChanged++] = newVal[i] ; + } + } + for ( ; i < newCnt ; i++) { + diffNdx[numberChanged] = i ; + diffVal[numberChanged++] = newVal[i] ; + } + /* + Create the object of our desire. + */ + CoinWarmStartVectorDiff *diff = + new CoinWarmStartVectorDiff(numberChanged,diffNdx,diffVal) ; + /* + Clean up and return. + */ + delete[] diffNdx ; + delete[] diffVal ; + + return diff; + // return (dynamic_cast*>(diff)) ; +} + + +/* + Apply diff to this warm start. + + Update this warm start by applying diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. +*/ + +template void +CoinWarmStartVector::applyDiff (const CoinWarmStartDiff *const cwsdDiff) +{ + /* + Make sure we have a CoinWarmStartVectorDiff + */ + const CoinWarmStartVectorDiff* diff = + dynamic_cast*>(cwsdDiff) ; + if (!diff) { + throw CoinError("Diff not derived from CoinWarmStartVectorDiff.", + "applyDiff","CoinWarmStartVector") ; + } + /* + Application is by straighforward replacement of words in the vector vector. + */ + const int numberChanges = diff->sze_ ; + const unsigned int *diffNdxs = diff->diffNdxs_ ; + const T* diffVals = diff->diffVals_ ; + T* vals = this->values_ ; + + for (int i = 0 ; i < numberChanges ; i++) { + unsigned int diffNdx = diffNdxs[i] ; + T diffVal = diffVals[i] ; + vals[diffNdx] = diffVal ; + } +} + +//############################################################################# + + +// Assignment + +template CoinWarmStartVectorDiff& +CoinWarmStartVectorDiff::operator=(const CoinWarmStartVectorDiff &rhs) +{ + if (this != &rhs) { + if (sze_ > 0) { + delete[] diffNdxs_ ; + delete[] diffVals_ ; + } + sze_ = rhs.sze_ ; + if (sze_ > 0) { + diffNdxs_ = new unsigned int[sze_] ; + memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ; + diffVals_ = new T[sze_] ; + memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ; + } else { + diffNdxs_ = 0 ; + diffVals_ = 0 ; + } + } + + return (*this) ; +} + + +// Copy constructor + +template +CoinWarmStartVectorDiff::CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff &rhs) + : sze_(rhs.sze_), + diffNdxs_(0), + diffVals_(0) +{ + if (sze_ > 0) { + diffNdxs_ = new unsigned int[sze_] ; + memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ; + diffVals_ = new T[sze_] ; + memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ; + } +} + +/// Standard constructor + +template +CoinWarmStartVectorDiff::CoinWarmStartVectorDiff +(int sze, const unsigned int *const diffNdxs, const T *const diffVals) + : sze_(sze), + diffNdxs_(0), + diffVals_(0) +{ + if (sze > 0) { + diffNdxs_ = new unsigned int[sze] ; + memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ; + diffVals_ = new T[sze] ; + memcpy(diffVals_,diffVals,sze*sizeof(T)) ; + } +} + +#endif diff --git a/thirdparty/linux/include/coin/Coin_C_defines.h b/thirdparty/linux/include/coin/Coin_C_defines.h new file mode 100644 index 0000000..5c43aaa --- /dev/null +++ b/thirdparty/linux/include/coin/Coin_C_defines.h @@ -0,0 +1,115 @@ +/* $Id: Coin_C_defines.h 1690 2014-03-13 17:45:21Z mlubin $ */ +/* + Copyright (C) 2002, 2003 International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef CoinCDefine_H +#define CoinCDefine_H + +/** This has #defines etc for the "C" interface to Coin. + If COIN_EXTERN_C defined then an extra extern C +*/ + +#if defined (CLP_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_SBB +#define COIN_NO_CBC +#endif +#if defined (SBB_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_CLP +#endif +#if defined (CBC_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_CLP +#endif +/* We need to allow for Microsoft */ +#ifndef COINLIBAPI + +#if defined(CBCCINTERFACEDLL_EXPORTS) || defined(CLPMSDLL) +#if defined (COIN_EXTERN_C) +# define COINLIBAPI __declspec(dllexport) +#else +# define COINLIBAPI __declspec(dllexport) +#endif +# define COINLINKAGE __stdcall +# define COINLINKAGE_CB __cdecl +#else +#if defined (COIN_EXTERN_C) +# define COINLIBAPI extern "C" +#else +# define COINLIBAPI +#endif +# define COINLINKAGE +# define COINLINKAGE_CB +#endif + +#endif +/** User does not need to see structure of model but C++ code does */ +#if defined (CLP_EXTERN_C) +/* Real typedef for structure */ +class CMessageHandler; +typedef struct { + ClpSimplex * model_; + CMessageHandler * handler_; +} Clp_Simplex; +#else +typedef void Clp_Simplex; +#endif + +#ifndef COIN_NO_CLP +/** typedef for user call back. + The cvec are constructed so don't need to be const*/ +typedef void (COINLINKAGE_CB *clp_callback) (Clp_Simplex * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +#endif +/** User does not need to see structure of model but C++ code does */ +#if defined (SBB_EXTERN_C) +/* Real typedef for structure */ +class Sbb_MessageHandler; +typedef struct { + OsiClpSolverInterface * solver_; + SbbModel * model_; + Sbb_MessageHandler * handler_; + char * information_; +} Sbb_Model; +#else +typedef void Sbb_Model; +#endif +#if defined (CBC_EXTERN_C) +/* Real typedef for structure */ +class Cbc_MessageHandler; +typedef struct { + OsiClpSolverInterface * solver_; + CbcModel * model_; + Cbc_MessageHandler * handler_; + std::vector cmdargs_; +} Cbc_Model; +#else +typedef void Cbc_Model; +#endif +#ifndef COIN_NO_SBB +/** typedef for user call back. + The cvec are constructed so don't need to be const*/ +typedef void (COINLINKAGE_CB *sbb_callback) (Sbb_Model * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +typedef void (COINLINKAGE_CB *cbc_callback) (Cbc_Model * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +#endif +#if COIN_BIG_INDEX==0 +typedef int CoinBigIndex; +#elif COIN_BIG_INDEX==1 +typedef long CoinBigIndex; +#else +typedef long long CoinBigIndex; +#endif +/* just in case used somewhere */ +#undef COIN_NO_CLP +#undef COIN_NO_SBB +#undef COIN_NO_CBC +#endif diff --git a/thirdparty/linux/include/coin/HSLLoader.h b/thirdparty/linux/include/coin/HSLLoader.h new file mode 100644 index 0000000..c38915c --- /dev/null +++ b/thirdparty/linux/include/coin/HSLLoader.h @@ -0,0 +1,378 @@ +/* Copyright (C) 2008, 2011 GAMS Development and others + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: HSLLoader.h 2317 2013-06-01 13:16:07Z stefan $ + + Author: Stefan Vigerske +*/ + +#ifndef HSLLOADER_H_ +#define HSLLOADER_H_ + +#include "IpoptConfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ma77_default_control +#define ma77_control ma77_control_d +#define ma77_info ma77_info_d +#define ma77_default_control ma77_default_control_d +#define ma77_open_nelt ma77_open_nelt_d +#define ma77_open ma77_open_d +#define ma77_input_vars ma77_input_vars_d +#define ma77_input_reals ma77_input_reals_d +#define ma77_analyse ma77_analyse_d +#define ma77_factor ma77_factor_d +#define ma77_factor_solve ma77_factor_solve_d +#define ma77_solve ma77_solve_d +#define ma77_resid ma77_resid_d +#define ma77_scale ma77_scale_d +#define ma77_enquire_posdef ma77_enquire_posdef_d +#define ma77_enquire_indef ma77_enquire_indef_d +#define ma77_alter ma77_alter_d +#define ma77_restart ma77_restart_d +#define ma77_finalise ma77_finalise_d +#endif + +struct ma77_control; +struct ma77_info; +typedef double ma77pkgtype_d_; + + +#ifndef ma86_default_control +#define ma86_control ma86_control_d +#define ma86_info ma86_info_d +#define ma86_default_control ma86_default_control_d +#define ma86_analyse ma86_analyse_d +#define ma86_factor ma86_factor_d +#define ma86_factor_solve ma86_factor_solve_d +#define ma86_solve ma86_solve_d +#define ma86_finalise ma86_finalise_d +#endif + +struct ma86_control; +struct ma86_info; +typedef double ma86pkgtype_d_; +typedef double ma86realtype_d_; + +#ifndef ma97_default_control +#define ma97_control ma97_control_d +#define ma97_info ma97_info_d +#define ma97_default_control ma97_default_control_d +#define ma97_analyse ma97_analyse_d +#define ma97_factor ma97_factor_d +#define ma97_factor_solve ma97_factor_solve_d +#define ma97_solve ma97_solve_d +#define ma97_finalise ma97_finalise_d +#define ma97_free_akeep ma97_free_akeep_d +#endif + +struct ma97_control; +struct ma97_info; +typedef double ma97pkgtype_d_; +typedef double ma97realtype_d_; + +struct mc68_control_i; +struct mc68_info_i; + +#ifndef __IPTYPES_HPP__ +/* Type of Fortran integer translated into C */ +typedef FORTRAN_INTEGER_TYPE ipfint; +#endif + +typedef void (*ma27ad_t)(ipfint *N, ipfint *NZ, const ipfint *IRN, const ipfint* ICN, + ipfint *IW, ipfint* LIW, ipfint* IKEEP, ipfint *IW1, + ipfint* NSTEPS, ipfint* IFLAG, ipfint* ICNTL, + double* CNTL, ipfint *INFO, double* OPS); +typedef void (*ma27bd_t)(ipfint *N, ipfint *NZ, const ipfint *IRN, const ipfint* ICN, + double* A, ipfint* LA, ipfint* IW, ipfint* LIW, + ipfint* IKEEP, ipfint* NSTEPS, ipfint* MAXFRT, + ipfint* IW1, ipfint* ICNTL, double* CNTL, + ipfint* INFO); +typedef void (*ma27cd_t)(ipfint *N, double* A, ipfint* LA, ipfint* IW, + ipfint* LIW, double* W, ipfint* MAXFRT, + double* RHS, ipfint* IW1, ipfint* NSTEPS, + ipfint* ICNTL, double* CNTL); +typedef void (*ma27id_t)(ipfint* ICNTL, double* CNTL); + +typedef void (*ma28ad_t)(void* nsize, void* nz, void* rw, void* licn, void* iw, + void* lirn, void* iw2, void* pivtol, void* iw3, void* iw4, void* rw2, void* iflag); + +typedef void (*ma57ad_t) ( + ipfint *n, /* Order of matrix. */ + ipfint *ne, /* Number of entries. */ + const ipfint *irn, /* Matrix nonzero row structure */ + const ipfint *jcn, /* Matrix nonzero column structure */ + ipfint *lkeep, /* Workspace for the pivot order of lenght 3*n */ + ipfint *keep, /* Workspace for the pivot order of lenght 3*n */ + /* Automatically iflag = 0; ikeep pivot order iflag = 1 */ + ipfint *iwork, /* Integer work space. */ + ipfint *icntl, /* Integer Control parameter of length 30*/ + ipfint *info, /* Statistical Information; Integer array of length 20 */ + double *rinfo); /* Double Control parameter of length 5 */ + +typedef void (*ma57bd_t) ( + ipfint *n, /* Order of matrix. */ + ipfint *ne, /* Number of entries. */ + double *a, /* Numerical values. */ + double *fact, /* Entries of factors. */ + ipfint *lfact, /* Length of array `fact'. */ + ipfint *ifact, /* Indexing info for factors. */ + ipfint *lifact, /* Length of array `ifact'. */ + ipfint *lkeep, /* Length of array `keep'. */ + ipfint *keep, /* Integer array. */ + ipfint *iwork, /* Workspace of length `n'. */ + ipfint *icntl, /* Integer Control parameter of length 20. */ + double *cntl, /* Double Control parameter of length 5. */ + ipfint *info, /* Statistical Information; Integer array of length 40. */ + double *rinfo); /* Statistical Information; Real array of length 20. */ + +typedef void (*ma57cd_t) ( + ipfint *job, /* Solution job. Solve for... */ + ipfint *n, /* Order of matrix. */ + double *fact, /* Entries of factors. */ + ipfint *lfact, /* Length of array `fact'. */ + ipfint *ifact, /* Indexing info for factors. */ + ipfint *lifact, /* Length of array `ifact'. */ + ipfint *nrhs, /* Number of right hand sides. */ + double *rhs, /* Numerical Values. */ + ipfint *lrhs, /* Leading dimensions of `rhs'. */ + double *work, /* Real workspace. */ + ipfint *lwork, /* Length of `work', >= N*NRHS. */ + ipfint *iwork, /* Integer array of length `n'. */ + ipfint *icntl, /* Integer Control parameter array of length 20. */ + ipfint *info); /* Statistical Information; Integer array of length 40. */ + +typedef void (*ma57ed_t) ( + ipfint *n, + ipfint *ic, /* 0: copy real array. >=1: copy integer array. */ + ipfint *keep, + double *fact, + ipfint *lfact, + double *newfac, + ipfint *lnew, + ipfint *ifact, + ipfint *lifact, + ipfint *newifc, + ipfint *linew, + ipfint *info); + +typedef void (*ma57id_t) (double *cntl, ipfint *icntl); + +typedef void (*ma77_default_control_t)(struct ma77_control_d *control); +typedef void (*ma77_open_nelt_t)(const int n, const char* fname1, const char* fname2, + const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const int nelt); +typedef void (*ma77_open_t)(const int n, const char* fname1, const char* fname2, + const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_input_vars_t)(const int idx, const int nvar, const int list[], + void **keep, const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_input_reals_t)(const int idx, const int length, + const double reals[], void **keep, const struct ma77_control_d *control, + struct ma77_info_d *info); +typedef void (*ma77_analyse_t)(const int order[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_factor_t)(const int posdef, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale); +typedef void (*ma77_factor_solve_t)(const int posdef, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale, const int nrhs, const int lx, + double rhs[]); +typedef void (*ma77_solve_t)(const int job, const int nrhs, const int lx, double x[], + void **keep, const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale); +typedef void (*ma77_resid_t)(const int nrhs, const int lx, const double x[], + const int lresid, double resid[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + double *anorm_bnd); +typedef void (*ma77_scale_t)(double scale[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + double *anorm); +typedef void (*ma77_enquire_posdef_t)(double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_enquire_indef_t)(int piv_order[], double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_alter_t)(const double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_restart_t)(const char *restart_file, const char *fname1, + const char *fname2, const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_finalise_t)(void **keep, const struct ma77_control_d *control, + struct ma77_info_d *info); + +typedef void (*ma86_default_control_t)(struct ma86_control *control); +typedef void (*ma86_analyse_t)(const int n, const int ptr[], const int row[], + int order[], void **keep, const struct ma86_control *control, + struct ma86_info *info); +typedef void (*ma86_factor_t)(const int n, const int ptr[], const int row[], + const ma86pkgtype_d_ val[], const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, + const ma86pkgtype_d_ scale[]); +typedef void (*ma86_factor_solve_t)(const int n, const int ptr[], + const int row[], const ma86pkgtype_d_ val[], const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, const int nrhs, + const int ldx, ma86pkgtype_d_ x[], const ma86pkgtype_d_ scale[]); +typedef void (*ma86_solve_t)(const int job, const int nrhs, const int ldx, + ma86pkgtype_d_ *x, const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, + const ma86pkgtype_d_ scale[]); +typedef void (*ma86_finalise_t)(void **keep, + const struct ma86_control *control); + +typedef void (*ma97_default_control_t)(struct ma97_control *control); +typedef void (*ma97_analyse_t)(const int check, const int n, const int ptr[], + const int row[], ma97pkgtype_d_ val[], void **akeep, + const struct ma97_control *control, struct ma97_info *info, int order[]); +typedef void (*ma97_factor_t)(const int matrix_type, const int ptr[], + const int row[], const ma97pkgtype_d_ val[], void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info, + const ma97pkgtype_d_ scale[]); +typedef void (*ma97_factor_solve_t)(const int matrix_type, const int ptr[], + const int row[], const ma97pkgtype_d_ val[], const int nrhs, + ma97pkgtype_d_ x[], const int ldx, void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info, + const ma97pkgtype_d_ scale[]); +typedef void (*ma97_solve_t)(const int job, const int nrhs, ma97pkgtype_d_ *x, + const int ldx, void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info); +typedef void (*ma97_finalise_t)(void **akeep, void **fkeep); +typedef void (*ma97_free_akeep_t)(void **akeep); + +typedef void (*mc19ad_t)(ipfint *N, ipfint *NZ, double* A, ipfint *IRN, ipfint* ICN, float* R, float* C, float* W); + +typedef void (*mc68_default_control_t)(struct mc68_control_i *control); +typedef void (*mc68_order_t)(int ord, int n, const int ptr[], + const int row[], int perm[], const struct mc68_control_i *control, + struct mc68_info_i *info); + + /** Tries to load a dynamically linked library with HSL routines. + * Also tries to load symbols for those HSL routines that are not linked into Ipopt, i.e., HAVE_... is not defined. + * Return a failure if the library cannot be loaded, but not if a symbol is not found. + * @see LSL_isMA27available + * @see LSL_isMA28available + * @see LSL_isMA57available + * @see LSL_isMA77available + * @see LSL_isMA86available + * @see LSL_isMA97available + * @see LSL_isMC19available + * @param libname The name under which the HSL lib can be found, or NULL to use a default name (libhsl.SHAREDLIBEXT). + * @param msgbuf A buffer where we can store a failure message. Assumed to be NOT NULL! + * @param msglen Length of the message buffer. + * @return Zero on success, nonzero on failure. + */ + int LSL_loadHSL(const char* libname, char* msgbuf, int msglen); + + /** Unloads a loaded HSL library. + * @return Zero on success, nonzero on failure. + */ + int LSL_unloadHSL(); + + /** Indicates whether a HSL library has been loaded. + * @return Zero if not loaded, nonzero if handle is loaded + */ + int LSL_isHSLLoaded(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA27 have been found. + * @return Zero if not available, nonzero if MA27 is available in the loaded library. + */ + int LSL_isMA27available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA28 have been found. + * @return Zero if not available, nonzero if MA28 is available in the loaded library. + */ + int LSL_isMA28available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA57 have been found. + * @return Zero if not available, nonzero if MA57 is available in the loaded library. + */ + int LSL_isMA57available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA77 have been found. + * @return Zero if not available, nonzero if HSL_MA77 is available in the loaded library. + */ + int LSL_isMA77available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MA86 have been found. + * @return Zero if not available, nonzero if HSL_MA86 is available in the loaded library. + */ + int LSL_isMA86available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MA97 have been found. + * @return Zero if not available, nonzero if HSL_MA97 is available in the loaded library. + */ + int LSL_isMA97available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA57 have been found. + * @return Zero if not available, nonzero if MC19 is available in the loaded library. + */ + int LSL_isMC19available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MC68 have been found. + * @return Zero if not available, nonzero if MC68 is available in the loaded library. + */ + int LSL_isMC68available(); + + /** Returns name of the shared library that should contain HSL */ + char* LSL_HSLLibraryName(); + + /** sets pointers to MA27 functions */ + void LSL_setMA27(ma27ad_t ma27ad, ma27bd_t ma27bd, ma27cd_t ma27cd, ma27id_t ma27id); + + /** sets pointers to MA28 functions */ + void LSL_setMA28(ma28ad_t ma28ad); + + /** sets pointers to MA57 functions */ + void LSL_setMA57(ma57ad_t ma57ad, ma57bd_t ma57bd, ma57cd_t ma57cd, ma57ed_t ma57ed, ma57id_t ma57id); + + /** sets pointers to MA77 functions */ + void LSL_setMA77(ma77_default_control_t ma77_default_control, + ma77_open_nelt_t ma77_open_nelt, + ma77_open_t ma77_open, + ma77_input_vars_t ma77_input_vars, + ma77_input_reals_t ma77_input_reals, + ma77_analyse_t ma77_analyse, + ma77_factor_t ma77_factor, + ma77_factor_solve_t ma77_factor_solve, + ma77_solve_t ma77_solve, + ma77_resid_t ma77_resid, + ma77_scale_t ma77_scale, + ma77_enquire_posdef_t ma77_enquire_posdef, + ma77_enquire_indef_t ma77_enquire_indef, + ma77_alter_t ma77_alter, + ma77_restart_t ma77_restart, + ma77_finalise_t ma77_finalise); + + /** sets pointers to MA86 functions */ + void LSL_setMA86(ma86_default_control_t ma86_default_control, + ma86_analyse_t ma86_analyse, + ma86_factor_t ma86_factor, + ma86_factor_solve_t ma86_factor_solve, + ma86_solve_t ma86_solve, + ma86_finalise_t ma86_finalise); + + /** sets pointers to MA97 functions */ + void LSL_setMA97(ma97_default_control_t ma97_default_control, + ma97_analyse_t ma97_analyse, + ma97_factor_t ma97_factor, + ma97_factor_solve_t ma97_factor_solve, + ma97_solve_t ma97_solve, + ma97_finalise_t ma97_finalise, + ma97_free_akeep_t ma97_free_akeep); + + /** sets pointer to MC19 function */ + void LSL_setMC19(mc19ad_t mc19ad); + + /** sets pointers to MC68 functions */ + void LSL_setMC68(mc68_default_control_t mc68_default_control, mc68_order_t mc68_order); + +#ifdef __cplusplus +} +#endif + +#endif /*HSLLOADER_H_*/ diff --git a/thirdparty/linux/include/coin/Idiot.hpp b/thirdparty/linux/include/coin/Idiot.hpp new file mode 100644 index 0000000..b675c4f --- /dev/null +++ b/thirdparty/linux/include/coin/Idiot.hpp @@ -0,0 +1,298 @@ +/* $Id: Idiot.hpp 2143 2015-05-20 15:49:17Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// "Idiot" as the name of this algorithm is copylefted. If you want to change +// the name then it should be something equally stupid (but not "Stupid") or +// even better something witty. + +#ifndef Idiot_H +#define Idiot_H +#ifndef OSI_IDIOT +#include "ClpSimplex.hpp" +#define OsiSolverInterface ClpSimplex +#else +#include "OsiSolverInterface.hpp" +typedef int CoinBigIndex; +#endif +class CoinMessageHandler; +class CoinMessages; +/// for use internally +typedef struct { + double infeas; + double objval; + double dropThis; + double weighted; + double sumSquared; + double djAtBeginning; + double djAtEnd; + int iteration; +} IdiotResult; +/** This class implements a very silly algorithm. It has no merit + apart from the fact that it gets an approximate solution to + some classes of problems. Better if vaguely homogeneous. + It works on problems where volume algorithm works and often + gets a better primal solution but it has no dual solution. + + It can also be used as a "crash" to get a problem started. This + is probably its most useful function. + + It is based on the idea that algorithms with terrible convergence + properties may be okay at first. Throw in some random dubious tricks + and the resulting code may be worth keeping as long as you don't + look at it. + +*/ + +class Idiot { + +public: + + /**@name Constructors and destructor + Just a pointer to model is kept + */ + //@{ + /// Default constructor + Idiot ( ); + /// Constructor with model + Idiot ( OsiSolverInterface & model ); + + /// Copy constructor. + Idiot(const Idiot &); + /// Assignment operator. This copies the data + Idiot & operator=(const Idiot & rhs); + /// Destructor + ~Idiot ( ); + //@} + + + /**@name Algorithmic calls + */ + //@{ + /// Get an approximate solution with the idiot code + void solve(); + /// Lightweight "crash" + void crash(int numberPass, CoinMessageHandler * handler, + const CoinMessages * messages, bool doCrossover = true); + /** Use simplex to get an optimal solution + mode is how many steps the simplex crossover should take to + arrive to an extreme point: + 0 - chosen,all ever used, all + 1 - chosen, all + 2 - all + 3 - do not do anything - maybe basis + + 16 do presolves + */ + void crossOver(int mode); + //@} + + + /**@name Gets and sets of most useful data + */ + //@{ + /** Starting weight - small emphasizes feasibility, + default 1.0e-4 */ + inline double getStartingWeight() const { + return mu_; + } + inline void setStartingWeight(double value) { + mu_ = value; + } + /** Weight factor - weight multiplied by this when changes, + default 0.333 */ + inline double getWeightFactor() const { + return muFactor_; + } + inline void setWeightFactor(double value) { + muFactor_ = value; + } + /** Feasibility tolerance - problem essentially feasible if + individual infeasibilities less than this. + default 0.1 */ + inline double getFeasibilityTolerance() const { + return smallInfeas_; + } + inline void setFeasibilityTolerance(double value) { + smallInfeas_ = value; + } + /** Reasonably feasible. Dubious method concentrates more on + objective when sum of infeasibilities less than this. + Very dubious default value of (Number of rows)/20 */ + inline double getReasonablyFeasible() const { + return reasonableInfeas_; + } + inline void setReasonablyFeasible(double value) { + reasonableInfeas_ = value; + } + /** Exit infeasibility - exit if sum of infeasibilities less than this. + Default -1.0 (i.e. switched off) */ + inline double getExitInfeasibility() const { + return exitFeasibility_; + } + inline void setExitInfeasibility(double value) { + exitFeasibility_ = value; + } + /** Major iterations. stop after this number. + Default 30. Use 2-5 for "crash" 50-100 for serious crunching */ + inline int getMajorIterations() const { + return majorIterations_; + } + inline void setMajorIterations(int value) { + majorIterations_ = value; + } + /** Minor iterations. Do this number of tiny steps before + deciding whether to change weights etc. + Default - dubious sqrt(Number of Rows). + Good numbers 105 to 405 say (5 is dubious method of making sure + idiot is not trying to be clever which it may do every 10 minor + iterations) */ + inline int getMinorIterations() const { + return maxIts2_; + } + inline void setMinorIterations(int value) { + maxIts2_ = value; + } + // minor iterations for first time + inline int getMinorIterations0() const { + return maxIts_; + } + inline void setMinorIterations0(int value) { + maxIts_ = value; + } + /** Reduce weight after this many major iterations. It may + get reduced before this but this is a maximum. + Default 3. 3-10 plausible. */ + inline int getReduceIterations() const { + return maxBigIts_; + } + inline void setReduceIterations(int value) { + maxBigIts_ = value; + } + /// Amount of information - default of 1 should be okay + inline int getLogLevel() const { + return logLevel_; + } + inline void setLogLevel(int value) { + logLevel_ = value; + } + /// How lightweight - 0 not, 1 yes, 2 very lightweight + inline int getLightweight() const { + return lightWeight_; + } + inline void setLightweight(int value) { + lightWeight_ = value; + } + /// strategy + inline int getStrategy() const { + return strategy_; + } + inline void setStrategy(int value) { + strategy_ = value; + } + /// Fine tuning - okay if feasibility drop this factor + inline double getDropEnoughFeasibility() const { + return dropEnoughFeasibility_; + } + inline void setDropEnoughFeasibility(double value) { + dropEnoughFeasibility_ = value; + } + /// Fine tuning - okay if weighted obj drop this factor + inline double getDropEnoughWeighted() const { + return dropEnoughWeighted_; + } + inline void setDropEnoughWeighted(double value) { + dropEnoughWeighted_ = value; + } + /// Set model + inline void setModel(OsiSolverInterface * model) { + model_ = model; + }; + //@} + + +/// Stuff for internal use +private: + + /// Does actual work + // allow public! +public: + void solve2(CoinMessageHandler * handler, const CoinMessages *messages); +private: + IdiotResult IdiSolve( + int nrows, int ncols, double * rowsol , double * colsol, + double * pi, double * djs, const double * origcost , + double * rowlower, + double * rowupper, const double * lower, + const double * upper, const double * element, + const int * row, const CoinBigIndex * colcc, + const int * length, double * lambda, + int maxIts, double mu, double drop, + double maxmin, double offset, + int strategy, double djTol, double djExit, double djFlag, + CoinThreadRandom * randomNumberGenerator); + int dropping(IdiotResult result, + double tolerance, + double small, + int *nbad); + IdiotResult objval(int nrows, int ncols, double * rowsol , double * colsol, + double * pi, double * djs, const double * cost , + const double * rowlower, + const double * rowupper, const double * lower, + const double * upper, const double * elemnt, + const int * row, const CoinBigIndex * columnStart, + const int * length, int extraBlock, int * rowExtra, + double * solExtra, double * elemExtra, double * upperExtra, + double * costExtra, double weight); + // Deals with whenUsed and slacks + int cleanIteration(int iteration, int ordinaryStart, int ordinaryEnd, + double * colsol, const double * lower, const double * upper, + const double * rowLower, const double * rowUpper, + const double * cost, const double * element, double fixTolerance, double & objChange, + double & infChange, double & maxInfeasibility); +private: + /// Underlying model + OsiSolverInterface * model_; + + double djTolerance_; + double mu_; /* starting mu */ + double drop_; /* exit if drop over 5 checks less than this */ + double muFactor_; /* reduce mu by this */ + double stopMu_; /* exit if mu gets smaller than this */ + double smallInfeas_; /* feasibility tolerance */ + double reasonableInfeas_; /* use lambdas if feasibility less than this */ + double exitDrop_; /* candidate for stopping after a major iteration */ + double muAtExit_; /* mu on exit */ + double exitFeasibility_; /* exit if infeasibility less than this */ + double dropEnoughFeasibility_; /* okay if feasibility drop this factor */ + double dropEnoughWeighted_; /* okay if weighted obj drop this factor */ + int * whenUsed_; /* array to say what was used */ + int maxBigIts_; /* always reduce mu after this */ + int maxIts_; /* do this many iterations on first go */ + int majorIterations_; + int logLevel_; + int logFreq_; + int checkFrequency_; /* can exit after 5 * this iterations (on drop) */ + int lambdaIterations_; /* do at least this many lambda iterations */ + int maxIts2_; /* do this many iterations on subsequent goes */ + int strategy_; /* 0 - default strategy + 1 - do accelerator step but be cautious + 2 - do not do accelerator step + 4 - drop, exitDrop and djTolerance all relative + 8 - keep accelerator step to theta=10.0 + + 32 - Scale + 512 - crossover + 2048 - keep lambda across mu change + 4096 - return best solution (not last found) + 8192 - always do a presolve in crossover + 16384 - costed slacks found - so whenUsed_ longer + 32768 - experimental 1 + 65536 - experimental 2 + 131072 - experimental 3 + 262144 - just values pass etc + 524288 - don't treat structural slacks as slacks */ + + int lightWeight_; // 0 - normal, 1 lightweight +}; +#endif diff --git a/thirdparty/linux/include/coin/IpAlgBuilder.hpp b/thirdparty/linux/include/coin/IpAlgBuilder.hpp new file mode 100644 index 0000000..05692bb --- /dev/null +++ b/thirdparty/linux/include/coin/IpAlgBuilder.hpp @@ -0,0 +1,360 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgBuilder.hpp 2666 2016-07-20 16:02:55Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-29 + +#ifndef __IPALGBUILDER_HPP__ +#define __IPALGBUILDER_HPP__ + +#include "IpIpoptAlg.hpp" +#include "IpReferenced.hpp" +#include "IpAugSystemSolver.hpp" +#include "IpPDSystemSolver.hpp" + +namespace Ipopt +{ + + // forward declarations + class IterationOutput; + class HessianUpdater; + class ConvergenceCheck; + class SearchDirectionCalculator; + class EqMultiplierCalculator; + class IterateInitializer; + class LineSearch; + class MuUpdate; + + /** Builder for creating a complete IpoptAlg object. This object + * contains all subelements (such as line search objects etc). How + * the resulting IpoptAlg object is built can be influenced by the + * options. + * + * More advanced customization can be achieved by subclassing this + * class and overloading the virtual methods that build the + * individual parts. The advantage of doing this is that it allows + * one to reuse the extensive amount of options processing that + * takes place, for instance, when generating the symmetric linear + * system solver. Another method for customizing the algorithm is + * using the optional custom_solver argument, which allows the + * expert user to provide a specialized linear solver for the + * augmented system (e.g., type GenAugSystemSolver), possibly for + * user-defined matrix objects. The optional custom_solver constructor + * argument is likely obsolete, however, as more control over this + * this process can be achieved by implementing a subclass of this + * AlgBuilder (e.g., by overloading the AugSystemSolverFactory method). + */ + class AlgorithmBuilder : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + AlgorithmBuilder(SmartPtr custom_solver=NULL); + + /** Destructor */ + virtual ~AlgorithmBuilder() + {} + + //@} + + /** Methods for IpoptTypeInfo */ + //@{ + /** register the options used by the algorithm builder */ + static void RegisterOptions(SmartPtr roptions); + //@} + + /** @name Convenience methods for building solvers without having + * to duplicate the significant amount of preprocessor flag and + * option checking that takes place. These solvers are used to + * create a number of core algorithm components across the + * different Build* methods, but depending on what options are + * chosen, the first method requiring the solver to be used can + * vary. Therefore, each of the Factory methods below is paired + * with a Getter method, which is called by all parts of this + * algorithm builder to ensure the Factory is only called once. */ + //@{ + + /** Create a solver that can be used to solve a symmetric linear + * system. + * Dependencies: None + */ + virtual SmartPtr + SymLinearSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the symmetric linear system solver for this + * algorithm. This method will call the SymLinearSolverFactory + * exactly once (the first time it is used), and store its + * instance on SymSolver_ for use in subsequent calls. + */ + SmartPtr GetSymLinearSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Create a solver that can be used to solve an + * augmented system. + * Dependencies: + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr + AugSystemSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the augmented system solver for this algorithm. This + * method will call the AugSystemSolverFactory exactly once (the + * first time it is used), and store its instance on AugSolver_ + * for use in subsequent calls. + */ + SmartPtr GetAugSystemSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Create a solver that can be used to solve a + * primal-dual system. + * Dependencies: + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr + PDSystemSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the primal-dual system solver for this algorithm. This + * method will call the PDSystemSolverFactory exactly once (the + * first time it is used), and store its instance on PDSolver_ + * for use in subsequent calls. + */ + SmartPtr GetPDSystemSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + //@} + + /** @name Methods to build parts of the algorithm */ + //@{ + /** Allocates memory for the IpoptNLP, IpoptData, and + * IpoptCalculatedQuanties arguments. + * Dependencies: None + */ + virtual void BuildIpoptObjects(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix, + const SmartPtr& nlp, + SmartPtr& ip_nlp, + SmartPtr& ip_data, + SmartPtr& ip_cq); + + /** Creates an instance of the IpoptAlgorithm class by building + * each of its required constructor arguments piece-by-piece. The + * default algorithm can be customized by overloading this method + * or by overloading one or more of the Build* methods called in + * this method's default implementation. Additional control can + * be achieved by overloading any of the *SolverFactory methods. + * This method will call (in this order): + * -> BuildIterationOutput() + * -> BuildHessianUpdater() + * -> BuildConvergenceCheck() + * -> BuildSearchDirectionCalculator() + * -> BuildEqMultiplierCalculator() + * -> BuildIterateInitializer() + * -> BuildLineSearch() + * -> BuildMuUpdate() + */ + virtual SmartPtr BuildBasicAlgorithm(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the IterationOutput class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr + BuildIterationOutput(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the HessianUpdater class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr + BuildHessianUpdater(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the ConvergenceCheck class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr + BuildConvergenceCheck(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the SearchDirectionCalculator + * class. This method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr + BuildSearchDirectionCalculator(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the EqMultiplierCalculator class. This + * method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr + BuildEqMultiplierCalculator(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the IterateInitializer class. This + * method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> EqMultCalculator_ + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr + BuildIterateInitializer(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the LineSearch class. This method is + * called in the default implementation of BuildBasicAlgorithm. + * It can be overloaded to customize that portion the default + * algorithm. + * Dependencies: + * -> EqMultCalculator_ + * -> ConvCheck_ + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr BuildLineSearch(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the MuUpdate class. This method is + * called in the default implementation of BuildBasicAlgorithm. + * It can be overloaded to customize that portion the default + * algorithm. + * Dependencies: + * -> LineSearch_ + * -> EqMultCalculator_ + * -> ConvCheck_ + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr BuildMuUpdate(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //AlgorithmBuilder(); + + /** Copy Constructor */ + AlgorithmBuilder(const AlgorithmBuilder&); + + /** Overloaded Equals Operator */ + void operator=(const AlgorithmBuilder&); + //@} + + /** @name IpoptAlgorithm constructor arguments. + * These components are built in separate Build + * methods in the order defined by BuildBasicAlgorithm. + * A single core component may require one or more + * other core components in its constructor, so the + * this class holds pointers to each component for use + * between the separate Build methods. */ + //@{ + SmartPtr IterOutput_; + SmartPtr HessUpdater_; + SmartPtr ConvCheck_; + SmartPtr SearchDirCalc_; + SmartPtr EqMultCalculator_; + SmartPtr IterInitializer_; + SmartPtr LineSearch_; + SmartPtr MuUpdate_; + //@} + + /** @name Commonly used solver components + * for building core algorithm components. Each + * of these members is paired with a Factory/Getter + * method. */ + //@{ + SmartPtr SymSolver_; + SmartPtr AugSolver_; + SmartPtr PDSolver_; + //@} + + /** Optional pointer to AugSystemSolver. If this is set in the + * contructor, we will use this to solve the linear systems. */ + SmartPtr custom_solver_; + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpAlgStrategy.hpp b/thirdparty/linux/include/coin/IpAlgStrategy.hpp new file mode 100644 index 0000000..746a968 --- /dev/null +++ b/thirdparty/linux/include/coin/IpAlgStrategy.hpp @@ -0,0 +1,185 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgStrategy.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPALGSTRATEGY_HPP__ +#define __IPALGSTRATEGY_HPP__ + +#include "IpOptionsList.hpp" +#include "IpJournalist.hpp" +#include "IpIpoptCalculatedQuantities.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" + +namespace Ipopt +{ + + /** This is the base class for all algorithm strategy objects. The + * AlgorithmStrategyObject base class implements a common interface + * for all algorithm strategy objects. A strategy object is a + * component of the algorithm for which different alternatives or + * implementations exists. It allows to compose the algorithm + * before execution for a particular configuration, without the + * need to call alternatives based on enums. For example, the + * LineSearch object is a strategy object, since different line + * search options might be used for different runs. + * + * This interface is used for + * things that are done to all strategy objects, like + * initialization and setting options. + */ + class AlgorithmStrategyObject : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + AlgorithmStrategyObject() + : + initialize_called_(false) + {} + + /** Default Destructor */ + virtual ~AlgorithmStrategyObject() + {} + //@} + + /** This method is called every time the algorithm starts again - + * it is used to reset any internal state. The pointers to the + * Journalist, as well as to the IpoptNLP, IpoptData, and + * IpoptCalculatedQuantities objects should be stored in the + * instanciation of this base class. This method is also used to + * get all required user options from the OptionsList. Here, if + * prefix is given, each tag (identifying the options) is first + * looked for with the prefix in front, and if not found, without + * the prefix. Note: you should not cue off of the iteration + * count to indicate the "start" of an algorithm! + * + * Do not overload this method, since it does some general + * initialization that is common for all strategy objects. + * Overload the protected InitializeImpl method instead. + */ + bool Initialize(const Journalist& jnlst, + IpoptNLP& ip_nlp, + IpoptData& ip_data, + IpoptCalculatedQuantities& ip_cq, + const OptionsList& options, + const std::string& prefix) + { + initialize_called_ = true; + // Copy the pointers for the problem defining objects + jnlst_ = &jnlst; + ip_nlp_ = &ip_nlp; + ip_data_ = &ip_data; + ip_cq_ = &ip_cq; + + bool retval = InitializeImpl(options, prefix); + if (!retval) { + initialize_called_ = false; + } + + return retval; + } + + /** Reduced version of the Initialize method, which does not + * require special Ipopt information. This is useful for + * algorithm objects that could be used outside Ipopt, such as + * linear solvers. */ + bool ReducedInitialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + initialize_called_ = true; + // Copy the pointers for the problem defining objects + jnlst_ = &jnlst; + ip_nlp_ = NULL; + ip_data_ = NULL; + ip_cq_ = NULL; + + bool retval = InitializeImpl(options, prefix); + if (!retval) { + initialize_called_ = false; + } + + return retval; + } + + protected: + /** Implementation of the initialization method that has to be + * overloaded by for each derived class. */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix)=0; + + /** @name Accessor methods for the problem defining objects. + * Those should be used by the derived classes. */ + //@{ + const Journalist& Jnlst() const + { + DBG_ASSERT(initialize_called_); + return *jnlst_; + } + IpoptNLP& IpNLP() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_nlp_)); + return *ip_nlp_; + } + IpoptData& IpData() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_data_)); + return *ip_data_; + } + IpoptCalculatedQuantities& IpCq() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_cq_)); + return *ip_cq_; + } + bool HaveIpData() const + { + return IsValid(ip_data_); + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //AlgorithmStrategyObject(); + + + /** Copy Constructor */ + AlgorithmStrategyObject(const AlgorithmStrategyObject&); + + /** Overloaded Equals Operator */ + void operator=(const AlgorithmStrategyObject&); + //@} + + /** @name Pointers to objects defining a particular optimization + * problem */ + //@{ + SmartPtr jnlst_; + SmartPtr ip_nlp_; + SmartPtr ip_data_; + SmartPtr ip_cq_; + //@} + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpAlgTypes.hpp b/thirdparty/linux/include/coin/IpAlgTypes.hpp new file mode 100644 index 0000000..53e8ea5 --- /dev/null +++ b/thirdparty/linux/include/coin/IpAlgTypes.hpp @@ -0,0 +1,66 @@ +// Copyright (C) 2005, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgTypes.hpp 2551 2015-02-13 02:51:47Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-07-19 + +#ifndef __IPALGTYPES_HPP__ +#define __IPALGTYPES_HPP__ + +#include "IpTypes.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + + /**@name Enumerations */ + //@{ + /** enum for the return from the optimize algorithm + * (obviously we need to add more) */ + enum SolverReturn { + SUCCESS, + MAXITER_EXCEEDED, + CPUTIME_EXCEEDED, + STOP_AT_TINY_STEP, + STOP_AT_ACCEPTABLE_POINT, + LOCAL_INFEASIBILITY, + USER_REQUESTED_STOP, + FEASIBLE_POINT_FOUND, + DIVERGING_ITERATES, + RESTORATION_FAILURE, + ERROR_IN_STEP_COMPUTATION, + INVALID_NUMBER_DETECTED, + TOO_FEW_DEGREES_OF_FREEDOM, + INVALID_OPTION, + OUT_OF_MEMORY, + INTERNAL_ERROR, + UNASSIGNED + }; + //@} + + /** @name Some exceptions used in multiple places */ + //@{ + DECLARE_STD_EXCEPTION(LOCALLY_INFEASIBLE); + DECLARE_STD_EXCEPTION(TOO_FEW_DOF); + DECLARE_STD_EXCEPTION(TINY_STEP_DETECTED); + DECLARE_STD_EXCEPTION(ACCEPTABLE_POINT_REACHED); + DECLARE_STD_EXCEPTION(FEASIBILITY_PROBLEM_SOLVED); + DECLARE_STD_EXCEPTION(INVALID_WARMSTART); + DECLARE_STD_EXCEPTION(INTERNAL_ABORT); + DECLARE_STD_EXCEPTION(NO_FREE_VARIABLES_BUT_FEASIBLE); + DECLARE_STD_EXCEPTION(NO_FREE_VARIABLES_AND_INFEASIBLE); + DECLARE_STD_EXCEPTION(INCONSISTENT_BOUNDS); + /** Exception FAILED_INITIALIZATION for problem during + * initialization of a strategy object (or other problems). This + * is thrown by a strategy object, if a problem arises during + * initialization, such as a value out of a feasible range. + */ + DECLARE_STD_EXCEPTION(FAILED_INITIALIZATION); + //@} + + +} + +#endif diff --git a/thirdparty/linux/include/coin/IpAugSystemSolver.hpp b/thirdparty/linux/include/coin/IpAugSystemSolver.hpp new file mode 100644 index 0000000..1396ce4 --- /dev/null +++ b/thirdparty/linux/include/coin/IpAugSystemSolver.hpp @@ -0,0 +1,200 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAugSystemSolver.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IP_AUGSYSTEMSOLVER_HPP__ +#define __IP_AUGSYSTEMSOLVER_HPP__ + +#include "IpSymMatrix.hpp" +#include "IpSymLinearSolver.hpp" +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(FATAL_ERROR_IN_LINEAR_SOLVER); + + /** Base class for Solver for the augmented system. This is the + * base class for linear solvers that solve the augmented system, + * which is defined as + * + * \f$\left[\begin{array}{cccc} + * W + D_x + \delta_xI & 0 & J_c^T & J_d^T\\ + * 0 & D_s + \delta_sI & 0 & -I \\ + * J_c & 0 & D_c - \delta_cI & 0\\ + * J_d & -I & 0 & D_d - \delta_dI + * \end{array}\right] + * \left(\begin{array}{c}sol_x\\sol_s\\sol_c\\sol_d\end{array}\right)= + * \left(\begin{array}{c}rhs_x\\rhs_s\\rhs_c\\rhs_d\end{array}\right)\f$ + * + * Since this system might be solved repeatedly for different right + * hand sides, it is desirable to step the factorization of a + * direct linear solver if possible. + */ + class AugSystemSolver: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + AugSystemSolver() + {} + /** Default destructor */ + virtual ~AugSystemSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Set up the augmented system and solve it for a given right hand + * side. If desired (i.e. if check_NegEVals is true), then the + * solution is only computed if the number of negative eigenvalues + * matches numberOfNegEVals. + * + * The return value is the return value of the linear solver object. + */ + virtual ESymSolverStatus Solve( + const SymMatrix* W, + double W_factor, + const Vector* D_x, + double delta_x, + const Vector* D_s, + double delta_s, + const Matrix* J_c, + const Vector* D_c, + double delta_c, + const Matrix* J_d, + const Vector* D_d, + double delta_d, + const Vector& rhs_x, + const Vector& rhs_s, + const Vector& rhs_c, + const Vector& rhs_d, + Vector& sol_x, + Vector& sol_s, + Vector& sol_c, + Vector& sol_d, + bool check_NegEVals, + Index numberOfNegEVals) + { + std::vector > rhs_xV(1); + rhs_xV[0] = &rhs_x; + std::vector > rhs_sV(1); + rhs_sV[0] = &rhs_s; + std::vector > rhs_cV(1); + rhs_cV[0] = &rhs_c; + std::vector > rhs_dV(1); + rhs_dV[0] = &rhs_d; + std::vector > sol_xV(1); + sol_xV[0] = &sol_x; + std::vector > sol_sV(1); + sol_sV[0] = &sol_s; + std::vector > sol_cV(1); + sol_cV[0] = &sol_c; + std::vector > sol_dV(1); + sol_dV[0] = &sol_d; + return MultiSolve(W, W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, + J_d, D_d, delta_d, rhs_xV, rhs_sV, rhs_cV, rhs_dV, + sol_xV, sol_sV, sol_cV, sol_dV, check_NegEVals, + numberOfNegEVals); + } + + /** Like Solve, but for multiple right hand sides. The inheriting + * class has to be overload at least one of Solve and + * MultiSolve. */ + virtual ESymSolverStatus MultiSolve( + const SymMatrix* W, + double W_factor, + const Vector* D_x, + double delta_x, + const Vector* D_s, + double delta_s, + const Matrix* J_c, + const Vector* D_c, + double delta_c, + const Matrix* J_d, + const Vector* D_d, + double delta_d, + std::vector >& rhs_xV, + std::vector >& rhs_sV, + std::vector >& rhs_cV, + std::vector >& rhs_dV, + std::vector >& sol_xV, + std::vector >& sol_sV, + std::vector >& sol_cV, + std::vector >& sol_dV, + bool check_NegEVals, + Index numberOfNegEVals) + { + // Solve for one right hand side after the other + Index nrhs = (Index)rhs_xV.size(); + DBG_ASSERT(nrhs>0); + DBG_ASSERT(nrhs==(Index)rhs_sV.size()); + DBG_ASSERT(nrhs==(Index)rhs_cV.size()); + DBG_ASSERT(nrhs==(Index)rhs_dV.size()); + DBG_ASSERT(nrhs==(Index)sol_xV.size()); + DBG_ASSERT(nrhs==(Index)sol_sV.size()); + DBG_ASSERT(nrhs==(Index)sol_cV.size()); + DBG_ASSERT(nrhs==(Index)sol_dV.size()); + + ESymSolverStatus retval=SYMSOLVER_SUCCESS; + for (Index i=0; i +#include +#include + +namespace Ipopt +{ + +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_CACHE +#endif +#ifdef IP_DEBUG_CACHE +# include "IpDebug.hpp" +#endif + + // Forward Declarations + + template + class DependentResult; + + // AW: I'm taking this out, since this is by far the most used + // class. We should keep it as simple as possible. + // /** Cache Priority Enum */ + // enum CachePriority + // { + // CP_Lowest, + // CP_Standard, + // CP_Trial, + // CP_Iterate + // }; + + /** Templated class for Cached Results. This class stores up to a + * given number of "results", entities that are stored here + * together with identifiers, that can be used to later retrieve the + * information again. + * + * Typically, T is a SmartPtr for some calculated quantity that + * should be stored (such as a Vector). The identifiers (or + * dependencies) are a (possibly varying) number of Tags from + * TaggedObjects, and a number of Numbers. Results are added to + * the cache using the AddCachedResults methods, and the can be + * retrieved with the GetCachedResults methods. The second set of + * methods checks whether a result has been cached for the given + * identifiers. If a corresponding result is found, a copy of it + * is returned and the method evaluates to true, otherwise it + * evaluates to false. + * + * Note that cached results can become "stale", namely when a + * TaggedObject that is used to identify this CachedResult is + * changed. When this happens, the cached result can never be + * asked for again, so that there is no point in storing it any + * longer. For this purpose, a cached result, which is stored as a + * DependentResult, inherits off an Observer. This Observer + * retrieves notification whenever a TaggedObject dependency has + * changed. Stale results are later removed from the cache. + */ + template + class CachedResults + { + public: +#ifdef IP_DEBUG_CACHE + /** (Only if compiled in DEBUG mode): debug verbosity level */ + static const Index dbg_verbosity; +#endif + + /** @name Constructors and Destructors. */ + //@{ + /** Constructor, where max_cache_size is the maximal number of + * results that should be cached. If max_cache_size is negative, + * we allow an infinite amount of cache. + */ + CachedResults(Int max_cache_size); + + /** Destructor */ + virtual ~CachedResults(); + //@} + + /** @name Generic methods for adding and retrieving cached results. */ + //@{ + /** Generic method for adding a result to the cache, given a + * std::vector of TaggesObjects and a std::vector of Numbers. + */ + void AddCachedResult(const T& result, + const std::vector& dependents, + const std::vector& scalar_dependents); + + /** Generic method for retrieving a cached results, given the + * dependencies as a std::vector of TaggesObjects and a + * std::vector of Numbers. + */ + bool GetCachedResult(T& retResult, + const std::vector& dependents, + const std::vector& scalar_dependents) const; + + /** Method for adding a result, providing only a std::vector of + * TaggedObjects. + */ + void AddCachedResult(const T& result, + const std::vector& dependents); + + /** Method for retrieving a cached result, providing only a + * std::vector of TaggedObjects. + */ + bool GetCachedResult(T& retResult, + const std::vector& dependents) const; + //@} + + /** @name Pointer-based methods for adding and retrieving cached + * results, providing dependencies explicitly. + */ + //@{ + /** Method for adding a result to the cache, proving one + * dependency as a TaggedObject explicitly. + */ + void AddCachedResult1Dep(const T& result, + const TaggedObject* dependent1); + + /** Method for retrieving a cached result, proving one dependency + * as a TaggedObject explicitly. + */ + bool GetCachedResult1Dep(T& retResult, const TaggedObject* dependent1); + + /** Method for adding a result to the cache, proving two + * dependencies as a TaggedObject explicitly. + */ + void AddCachedResult2Dep(const T& result, + const TaggedObject* dependent1, + const TaggedObject* dependent2); + + /** Method for retrieving a cached result, proving two + * dependencies as a TaggedObject explicitly. + */ + bool GetCachedResult2Dep(T& retResult, + const TaggedObject* dependent1, + const TaggedObject* dependent2); + + /** Method for adding a result to the cache, proving three + * dependencies as a TaggedObject explicitly. + */ + void AddCachedResult3Dep(const T& result, + const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3); + + /** Method for retrieving a cached result, proving three + * dependencies as a TaggedObject explicitly. + */ + bool GetCachedResult3Dep(T& retResult, + const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3); + + /** @name Pointer-free version of the Add and Get methods */ + //@{ + bool GetCachedResult1Dep(T& retResult, const TaggedObject& dependent1) + { + return GetCachedResult1Dep(retResult, &dependent1); + } + bool GetCachedResult2Dep(T& retResult, + const TaggedObject& dependent1, + const TaggedObject& dependent2) + { + return GetCachedResult2Dep(retResult, &dependent1, &dependent2); + } + bool GetCachedResult3Dep(T& retResult, + const TaggedObject& dependent1, + const TaggedObject& dependent2, + const TaggedObject& dependent3) + { + return GetCachedResult3Dep(retResult, &dependent1, &dependent2, &dependent3); + } + void AddCachedResult1Dep(const T& result, + const TaggedObject& dependent1) + { + AddCachedResult1Dep(result, &dependent1); + } + void AddCachedResult2Dep(const T& result, + const TaggedObject& dependent1, + const TaggedObject& dependent2) + { + AddCachedResult2Dep(result, &dependent1, &dependent2); + } + void AddCachedResult3Dep(const T& result, + const TaggedObject& dependent1, + const TaggedObject& dependent2, + const TaggedObject& dependent3) + { + AddCachedResult3Dep(result, &dependent1, &dependent2, &dependent3); + } + //@} + + /** Invalidates the result for given dependencies. Sets the stale + * flag for the corresponding cached result to true if it is + * found. Returns true, if the result was found. */ + bool InvalidateResult(const std::vector& dependents, + const std::vector& scalar_dependents); + + /** Invalidates all cached results */ + void Clear(); + + /** Invalidate all cached results and changes max_cache_size */ + void Clear(Int max_cache_size); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CachedResults(); + + /** Copy Constructor */ + CachedResults(const CachedResults&); + + /** Overloaded Equals Operator */ + void operator=(const CachedResults&); + //@} + + /** maximum number of cached results */ + Int max_cache_size_; + + /** list of currently cached results. */ + mutable std::list*>* cached_results_; + + /** internal method for removing stale DependentResults from the + * list. It is called at the beginning of every + * GetDependentResult method. + */ + void CleanupInvalidatedResults() const; + + /** Print list of currently cached results */ + void DebugPrintCachedResults() const; + }; + + /** Templated class which stores one entry for the CachedResult + * class. It stores the result (of type T), together with its + * dependencies (vector of TaggedObjects and vector of Numbers). + * It also stores a priority. + */ + template + class DependentResult : public Observer + { + public: + +#ifdef IP_DEBUG_CACHE + static const Index dbg_verbosity; +#endif + + /** @name Constructor, Destructors */ + //@{ + /** Constructor, given all information about the result. */ + DependentResult(const T& result, const std::vector& dependents, + const std::vector& scalar_dependents); + + /** Destructor. */ + ~DependentResult(); + //@} + + /** @name Accessor method. */ + //@{ + /** This returns true, if the DependentResult is no longer valid. */ + bool IsStale() const; + + /** Invalidates the cached result. */ + void Invalidate(); + + /** Returns the cached result. */ + const T& GetResult() const; + //@} + + /** This method returns true if the dependencies provided to this + * function are identical to the ones stored with the + * DependentResult. + */ + bool DependentsIdentical(const std::vector& dependents, + const std::vector& scalar_dependents) const; + + /** Print information about this DependentResults. */ + void DebugPrint() const; + + protected: + /** This method is overloading the pure virtual method from the + * Observer base class. This method is called when a Subject + * registered for this Observer sends a notification. In this + * particular case, if this method is called with + * notify_type==NT_Changed or NT_BeingDeleted, then this results + * is marked as stale. + */ + virtual void RecieveNotification(NotifyType notify_type, const Subject* subject); + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DependentResult(); + + /** Copy Constructor */ + DependentResult(const DependentResult&); + + /** Overloaded Equals Operator */ + void operator=(const DependentResult&); + //@} + + /** Flag indicating, if the cached result is still valid. A + result becomes invalid, if the RecieveNotification method is + called with NT_Changed */ + bool stale_; + /** The value of the dependent results */ + const T result_; + /** Dependencies in form of TaggedObjects */ + std::vector dependent_tags_; + /** Dependencies in form a Numbers */ + std::vector scalar_dependents_; + }; + +#ifdef IP_DEBUG_CACHE + template + const Index CachedResults::dbg_verbosity = 0; + + template + const Index DependentResult::dbg_verbosity = 0; +#endif + + template + DependentResult::DependentResult( + const T& result, + const std::vector& dependents, + const std::vector& scalar_dependents) + : + stale_(false), + result_(result), + dependent_tags_(dependents.size()), + scalar_dependents_(scalar_dependents) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult::DependentResult()", dbg_verbosity); +#endif + + for (Index i=0; i<(Index)dependents.size(); i++) { + if (dependents[i]) { + // Call the RequestAttach method of the Observer base class. + // This will add this dependent result in the Observer list + // for the Subject dependents[i]. As a consequence, the + // RecieveNotification method of this DependentResult will be + // called with notify_type=NT_Changed, whenever the + // TaggedResult dependents[i] is changed (i.e. its HasChanged + // method is called). + RequestAttach(NT_Changed, dependents[i]); + dependent_tags_[i] = dependents[i]->GetTag(); + } + else { + dependent_tags_[i] = 0; + } + } + } + + template + DependentResult::~DependentResult() + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult::~DependentResult()", dbg_verbosity); + //DBG_ASSERT(stale_ == true); +#endif + // Nothing to be done here, destructor + // of T should sufficiently remove + // any memory, etc. + } + + template + bool DependentResult::IsStale() const + { + return stale_; + } + + template + void DependentResult::Invalidate() + { + stale_ = true; + } + + template + void DependentResult::RecieveNotification(NotifyType notify_type, const Subject* /* subject */) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult::RecieveNotification", dbg_verbosity); +#endif + + if (notify_type == NT_Changed || notify_type==NT_BeingDestroyed) { + stale_ = true; + // technically, I could unregister the notifications here, but they + // aren't really hurting anything + } + } + + template + bool DependentResult::DependentsIdentical(const std::vector& dependents, + const std::vector& scalar_dependents) const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult::DependentsIdentical", dbg_verbosity); + DBG_ASSERT(stale_ == false); + DBG_ASSERT(dependents.size() == dependent_tags_.size()); +#endif + + bool retVal = true; + + if (dependents.size() != dependent_tags_.size() + || scalar_dependents.size() != scalar_dependents_.size()) { + retVal = false; + } + else { + for (Index i=0; i<(Index)dependents.size(); i++) { + if ( (dependents[i] && dependents[i]->GetTag() != dependent_tags_[i]) + || (!dependents[i] && dependent_tags_[i] != 0) ) { + retVal = false; + break; + } + } + if (retVal) { + for (Index i=0; i<(Index)scalar_dependents.size(); i++) { + if (scalar_dependents[i] != scalar_dependents_[i]) { + retVal = false; + break; + } + } + } + } + + return retVal; + } + + template + const T& DependentResult::GetResult() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult::GetResult()", dbg_verbosity); + DBG_ASSERT(stale_ == false); +#endif + + return result_; + } + + template + void DependentResult::DebugPrint() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult::DebugPrint", dbg_verbosity); +#endif + + } + + template + CachedResults::CachedResults(Int max_cache_size) + : + max_cache_size_(max_cache_size), + cached_results_(NULL) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::CachedResults", dbg_verbosity); +#endif + + } + + template + CachedResults::~CachedResults() + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::!CachedResults()", dbg_verbosity); +#endif + + if (cached_results_) { + for (typename std::list< DependentResult* >::iterator iter = cached_results_-> + begin(); + iter != cached_results_->end(); + iter++) { + delete *iter; + } + delete cached_results_; + } + /* + while (!cached_results_.empty()) { + DependentResult* result = cached_results_.back(); + cached_results_.pop_back(); + delete result; + } + */ + } + + template + void CachedResults::AddCachedResult(const T& result, + const std::vector& dependents, + const std::vector& scalar_dependents) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::AddCachedResult", dbg_verbosity); +#endif + + CleanupInvalidatedResults(); + + // insert the new one here + DependentResult* newResult = new DependentResult(result, dependents, scalar_dependents); + if (!cached_results_) { + cached_results_ = new std::list*>; + } + cached_results_->push_front(newResult); + + // keep the list small enough + if (max_cache_size_ >= 0) { // if negative, allow infinite cache + // non-negative - limit size of list to max_cache_size + DBG_ASSERT((Int)cached_results_->size()<=max_cache_size_+1); + if ((Int)cached_results_->size() > max_cache_size_) { + delete cached_results_->back(); + cached_results_->pop_back(); + } + } + +#ifdef IP_DEBUG_CACHE + DBG_EXEC(2, DebugPrintCachedResults()); +#endif + + } + + template + void CachedResults::AddCachedResult(const T& result, + const std::vector& dependents) + { + std::vector scalar_dependents; + AddCachedResult(result, dependents, scalar_dependents); + } + + template + bool CachedResults::GetCachedResult(T& retResult, const std::vector& dependents, + const std::vector& scalar_dependents) const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::GetCachedResult", dbg_verbosity); +#endif + + if (!cached_results_) + return false; + + CleanupInvalidatedResults(); + + bool retValue = false; + typename std::list< DependentResult* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); iter++) { + if ((*iter)->DependentsIdentical(dependents, scalar_dependents)) { + retResult = (*iter)->GetResult(); + retValue = true; + break; + } + } + +#ifdef IP_DEBUG_CACHE + DBG_EXEC(2, DebugPrintCachedResults()); +#endif + + return retValue; + } + + template + bool CachedResults::GetCachedResult( + T& retResult, const std::vector& dependents) const + { + std::vector scalar_dependents; + return GetCachedResult(retResult, dependents, scalar_dependents); + } + + template + void CachedResults::AddCachedResult1Dep(const T& result, + const TaggedObject* dependent1) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::AddCachedResult1Dep", dbg_verbosity); +#endif + + std::vector dependents(1); + dependents[0] = dependent1; + + AddCachedResult(result, dependents); + } + + template + bool CachedResults::GetCachedResult1Dep(T& retResult, const TaggedObject* dependent1) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::GetCachedResult1Dep", dbg_verbosity); +#endif + + std::vector dependents(1); + dependents[0] = dependent1; + + return GetCachedResult(retResult, dependents); + } + + template + void CachedResults::AddCachedResult2Dep(const T& result, const TaggedObject* dependent1, + const TaggedObject* dependent2) + + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::AddCachedResult2dDep", dbg_verbosity); +#endif + + std::vector dependents(2); + dependents[0] = dependent1; + dependents[1] = dependent2; + + AddCachedResult(result, dependents); + } + + template + bool CachedResults::GetCachedResult2Dep(T& retResult, const TaggedObject* dependent1, const TaggedObject* dependent2) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::GetCachedResult2Dep", dbg_verbosity); +#endif + + std::vector dependents(2); + dependents[0] = dependent1; + dependents[1] = dependent2; + + return GetCachedResult(retResult, dependents); + } + + template + void CachedResults::AddCachedResult3Dep(const T& result, const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3) + + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::AddCachedResult2dDep", dbg_verbosity); +#endif + + std::vector dependents(3); + dependents[0] = dependent1; + dependents[1] = dependent2; + dependents[2] = dependent3; + + AddCachedResult(result, dependents); + } + + template + bool CachedResults::GetCachedResult3Dep(T& retResult, const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::GetCachedResult2Dep", dbg_verbosity); +#endif + + std::vector dependents(3); + dependents[0] = dependent1; + dependents[1] = dependent2; + dependents[2] = dependent3; + + return GetCachedResult(retResult, dependents); + } + + template + bool CachedResults::InvalidateResult(const std::vector& dependents, + const std::vector& scalar_dependents) + { + if (!cached_results_) + return false; + + CleanupInvalidatedResults(); + + bool retValue = false; + typename std::list< DependentResult* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); + iter++) { + if ((*iter)->DependentsIdentical(dependents, scalar_dependents)) { + (*iter)->Invalidate(); + retValue = true; + break; + } + } + + return retValue; + } + + template + void CachedResults::Clear() + { + if (!cached_results_) + return; + + typename std::list< DependentResult* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); + iter++) { + (*iter)->Invalidate(); + } + + CleanupInvalidatedResults(); + } + + template + void CachedResults::Clear(Int max_cache_size) + { + Clear(); + max_cache_size_ = max_cache_size; + } + + template + void CachedResults::CleanupInvalidatedResults() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::CleanupInvalidatedResults", dbg_verbosity); +#endif + + if (!cached_results_) + return; + + typename std::list< DependentResult* >::iterator iter; + iter = cached_results_->begin(); + while (iter != cached_results_->end()) { + if ((*iter)->IsStale()) { + typename std::list< DependentResult* >::iterator + iter_to_remove = iter; + iter++; + DependentResult* result_to_delete = (*iter_to_remove); + cached_results_->erase(iter_to_remove); + delete result_to_delete; + } + else { + iter++; + } + } + } + + template + void CachedResults::DebugPrintCachedResults() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults::DebugPrintCachedResults", dbg_verbosity); + if (DBG_VERBOSITY()>=2 ) { + if (!cached_results_) { + DBG_PRINT((2,"Currentlt no cached results:\n")); + } + else { + typename std::list< DependentResult* >::const_iterator iter; + DBG_PRINT((2,"Current set of cached results:\n")); + for (iter = cached_results_->begin(); iter != cached_results_->end(); iter++) { + DBG_PRINT((2," DependentResult:0x%x\n", (*iter))); + } + } + } +#endif + + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpCompoundMatrix.hpp b/thirdparty/linux/include/coin/IpCompoundMatrix.hpp new file mode 100644 index 0000000..03e2e2a --- /dev/null +++ b/thirdparty/linux/include/coin/IpCompoundMatrix.hpp @@ -0,0 +1,340 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDMATRIX_HPP__ +#define __IPCOMPOUNDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundMatrixSpace; + + /** Class for Matrices consisting of other matrices. This matrix is + * a matrix that consists of zero, one or more Matrices's which are + * arranged like this: \f$ M_{\rm compound} = + * \left(\begin{array}{cccc}M_{00} & M_{01} & \ldots & M_{0,{\rm + * ncomp\_cols}-1} \\ \dots &&&\dots \\ M_{{\rm ncomp\_rows}-1,0} & + * M_{{\rm ncomp\_rows}-1,1} & \dots & M_{{\rm ncomp\_rows}-1,{\rm + * ncomp\_cols}-1}\end{array}\right)\f$. The individual components + * can be associated to different MatrixSpaces. The individual + * components can also be const and non-const Matrices. If a + * component is not set (i.e., it's pointer is NULL), then this + * components is treated like a zero-matrix of appropriate + * dimensions. + */ + class CompoundMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. The owner_space has to + * be defined, so that at each block row and column contain at + * least one non-NULL component. The individual components can + * be set afterwards with the SeteComp and SetCompNonConst + * methods. + */ + CompoundMatrix(const CompoundMatrixSpace* owner_space); + + /** Destructor */ + virtual ~CompoundMatrix(); + //@} + + /** Method for setting an individual component at position (irow, + * icol) in the compound matrix. The counting of indices starts + * at 0. */ + void SetComp(Index irow, Index jcol, const Matrix& matrix); + + /** Method to set a non-const Matrix entry */ + void SetCompNonConst(Index irow, Index jcol, Matrix& matrix); + + /** Method to create a new matrix from the space for this block */ + void CreateBlockFromSpace(Index irow, Index jcol); + + /** Method for retrieving one block from the compound matrix as a + * const Matrix. + */ + SmartPtr GetComp(Index irow, Index jcol) const + { + return ConstComp(irow, jcol); + } + + /** Method for retrieving one block from the compound matrix as a + * non-const Matrix. Note that calling this method with mark the + * CompoundMatrix as changed. Therefore, only use this method if + * you are intending to change the Matrix that you receive. */ + SmartPtr GetCompNonConst(Index irow, Index jcol) + { + ObjectChanged(); + return Comp(irow, jcol); + } + + /** Number of block rows of this compound matrix. */ + inline Index NComps_Rows() const; + /** Number of block colmuns of this compound matrix. */ + inline Index NComps_Cols() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized implementation. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CompoundMatrix(); + + /** Copy Constructor */ + CompoundMatrix(const CompoundMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundMatrix&); + //@} + + /** Matrix of matrix's containing the components */ + std::vector > > comps_; + + /** Matrix of const matrix's containing the components */ + std::vector > > const_comps_; + + /** Copy of the owner_space ptr as a CompoundMatrixSpace instead + * of MatrixSpace */ + const CompoundMatrixSpace* owner_space_; + + /** boolean indicating if the compound matrix is in a "valid" state */ + mutable bool matrices_valid_; + + /** Method to check whether or not the matrices are valid */ + bool MatricesValid() const; + + inline const Matrix* ConstComp(Index irow, Index jcol) const; + + inline Matrix* Comp(Index irow, Index jcol); + }; + + /** This is the matrix space for CompoundMatrix. Before a CompoundMatrix + * can be created, at least one MatrixSpace has to be set per block + * row and column. Individual component MatrixSpace's can be set + * with the SetComp method. + */ + class CompoundMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + CompoundMatrixSpace(Index ncomps_rows, + Index ncomps_cols, + Index total_nRows, + Index total_nCols); + + /** Destructor */ + ~CompoundMatrixSpace() + {} + //@} + + /** @name Methods for setting information about the components. */ + //@{ + /** Set the number nrows of rows in row-block number irow. */ + void SetBlockRows(Index irow, Index nrows); + + /** Set the number ncols of columns in column-block number jcol. */ + void SetBlockCols(Index jcol, Index ncols); + + /** Get the number nrows of rows in row-block number irow. */ + Index GetBlockRows(Index irow) const; + + /** Set the number ncols of columns in column-block number jcol. */ + Index GetBlockCols(Index jcol) const; + + /** Set the component MatrixSpace. If auto_allocate is true, then + * a new CompoundMatrix created later with MakeNew will have this + * component automatically created with the Matrix's MakeNew. + * Otherwise, the corresponding component will be NULL and has to + * be set with the SetComp methods of the CompoundMatrix. + */ + void SetCompSpace(Index irow, Index jcol, + const MatrixSpace& mat_space, + bool auto_allocate = false); + //@} + + /** Obtain the component MatrixSpace in block row irow and block + * column jcol. + */ + SmartPtr GetCompSpace(Index irow, Index jcol) const + { + DBG_ASSERT(irow > > comp_spaces_; + + /** 2-dim std::vector of booleans deciding whether to + * allocate a new matrix for the blocks automagically */ + std::vector > allocate_block_; + + /** Vector of the number of rows in each comp column */ + std::vector block_rows_; + + /** Vector of the number of cols in each comp row */ + std::vector block_cols_; + + /** true if the CompoundMatrixSpace only has Matrix spaces along the diagonal. + * this means that the CompoundMatrix will only have matrices along the + * diagonal and it could make some operations more efficient + */ + bool diagonal_; + + /** Auxilliary function for debugging to set if all block + * dimensions have been set. */ + bool DimensionsSet() const; + }; + + /* inline methods */ + inline + Index CompoundMatrix::NComps_Rows() const + { + return owner_space_->NComps_Rows(); + } + + inline + Index CompoundMatrix::NComps_Cols() const + { + return owner_space_->NComps_Cols(); + } + + inline + const Matrix* CompoundMatrix::ConstComp(Index irow, Index jcol) const + { + DBG_ASSERT(irow < NComps_Rows()); + DBG_ASSERT(jcol < NComps_Cols()); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + else if (IsValid(const_comps_[irow][jcol])) { + return GetRawPtr(const_comps_[irow][jcol]); + } + + return NULL; + } + + inline + Matrix* CompoundMatrix::Comp(Index irow, Index jcol) + { + DBG_ASSERT(irow < NComps_Rows()); + DBG_ASSERT(jcol < NComps_Cols()); + return GetRawPtr(comps_[irow][jcol]); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpCompoundSymMatrix.hpp b/thirdparty/linux/include/coin/IpCompoundSymMatrix.hpp new file mode 100644 index 0000000..4ca18fe --- /dev/null +++ b/thirdparty/linux/include/coin/IpCompoundSymMatrix.hpp @@ -0,0 +1,283 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDSYMMATRIX_HPP__ +#define __IPCOMPOUNDSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundSymMatrixSpace; + + /** Class for symmetric matrices consisting of other matrices. + * Here, the lower left block of the matrix is stored. + */ + class CompoundSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking only the number for block components into the + * row and column direction. The owner_space has to be defined, so + * that at each block row and column contain at least one non-NULL + * component. + */ + CompoundSymMatrix(const CompoundSymMatrixSpace* owner_space); + + /** Destructor */ + ~CompoundSymMatrix(); + //@} + + /** Method for setting an individual component at position (irow, + * icol) in the compound matrix. The counting of indices starts + * at 0. Since this only the lower left components are stored, we need + * to have jcol<=irow, and if irow==jcol, the matrix must be a SymMatrix */ + void SetComp(Index irow, Index jcol, const Matrix& matrix); + + /** Non const version of the same method */ + void SetCompNonConst(Index irow, Index jcol, Matrix& matrix); + + /** Method for retrieving one block from the compound matrix. + * Since this only the lower left components are stored, we need + * to have jcol<=irow */ + SmartPtr GetComp(Index irow, Index jcol) const + { + return ConstComp(irow,jcol); + } + + /** Non const version of GetComp. You should only use this method + * if you are intending to change the matrix you receive, since + * this CompoundSymMatrix will be marked as changed. */ + SmartPtr GetCompNonConst(Index irow, Index jcol) + { + ObjectChanged(); + return Comp(irow,jcol); + } + + /** Method for creating a new matrix of this specific type. */ + SmartPtr MakeNewCompoundSymMatrix() const; + + // The following don't seem to be necessary + /* Number of block rows of this compound matrix. */ + // Index NComps_NRows() const { return NComps_Dim(); } + + /* Number of block colmuns of this compound matrix. */ + // Index NComps_NCols() const { return NComps_Dim(); } + + /** Number of block rows and columns */ + Index NComps_Dim() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CompoundSymMatrix(); + + /** Copy Constructor */ + CompoundSymMatrix(const CompoundSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundSymMatrix&); + //@} + + /** Vector of vectors containing the components */ + std::vector > > comps_; + + /** Vector of vectors containing the const components */ + std::vector > > const_comps_; + + /** Copy of the owner_space ptr as a CompoundSymMatrixSpace */ + const CompoundSymMatrixSpace* owner_space_; + + /** boolean indicating if the compound matrix is in a "valid" state */ + mutable bool matrices_valid_; + + /** method to check wether or not the matrices are valid */ + bool MatricesValid() const; + + /** Internal method to return a const pointer to one of the comps */ + const Matrix* ConstComp(Index irow, Index jcol) const + { + DBG_ASSERT(irow < NComps_Dim()); + DBG_ASSERT(jcol <= irow); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + else if (IsValid(const_comps_[irow][jcol])) { + return GetRawPtr(const_comps_[irow][jcol]); + } + + return NULL; + } + + /** Internal method to return a non-const pointer to one of the comps */ + Matrix* Comp(Index irow, Index jcol) + { + DBG_ASSERT(irow < NComps_Dim()); + DBG_ASSERT(jcol <= irow); + // We shouldn't be asking for a non-const if this entry holds a + // const one... + DBG_ASSERT(IsNull(const_comps_[irow][jcol])); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + + return NULL; + } + }; + + /** This is the matrix space for CompoundSymMatrix. Before a + * CompoundSymMatrix can be created, at least one SymMatrixSpace has + * to be set per block row and column. Individual component + * SymMatrixSpace's can be set with the SetComp method. + */ + class CompoundSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of blocks (same for rows and + * columns), as well as the total dimension of the matrix. + */ + CompoundSymMatrixSpace(Index ncomp_spaces, Index total_dim); + + /** Destructor */ + ~CompoundSymMatrixSpace() + {} + //@} + + /** @name Methods for setting information about the components. */ + //@{ + /** Set the dimension dim for block row (or column) irow_jcol */ + void SetBlockDim(Index irow_jcol, Index dim); + + /** Get the dimension dim for block row (or column) irow_jcol */ + Index GetBlockDim(Index irow_jcol) const; + + /** Set the component SymMatrixSpace. If auto_allocate is true, then + * a new CompoundSymMatrix created later with MakeNew will have this + * component automatically created with the SymMatrix's MakeNew. + * Otherwise, the corresponding component will be NULL and has to + * be set with the SetComp methods of the CompoundSymMatrix. + */ + void SetCompSpace(Index irow, Index jcol, + const MatrixSpace& mat_space, + bool auto_allocate = false); + //@} + + /** Obtain the component MatrixSpace in block row irow and block + * column jcol. + */ + SmartPtr GetCompSpace(Index irow, Index jcol) const + { + DBG_ASSERT(irow block_dim_; + + /** 2-dim std::vector of matrix spaces for the components. Only + * the lower right part is stored. */ + std::vector > > comp_spaces_; + + /** 2-dim std::vector of booleans deciding whether to + * allocate a new matrix for the blocks automagically */ + std::vector > allocate_block_; + + /** boolean indicating if the compound matrix space is in a "valid" state */ + mutable bool dimensions_set_; + + /** Method to check whether or not the spaces are valid */ + bool DimensionsSet() const; + }; + + inline + SmartPtr CompoundSymMatrix::MakeNewCompoundSymMatrix() const + { + return owner_space_->MakeNewCompoundSymMatrix(); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpCompoundVector.hpp b/thirdparty/linux/include/coin/IpCompoundVector.hpp new file mode 100644 index 0000000..a4c52ab --- /dev/null +++ b/thirdparty/linux/include/coin/IpCompoundVector.hpp @@ -0,0 +1,339 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundVector.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDVECTOR_HPP__ +#define __IPCOMPOUNDVECTOR_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundVectorSpace; + + /** Class of Vectors consisting of other vectors. This vector is a + * vector that consists of zero, one or more Vector's which are + * stacked on each others: \f$ x_{\rm compound} = + * \left(\begin{array}{c}x_0\\\dots\\x_{{\rm + * ncomps} - 1}\end{array}\right)\f$. The individual components can be + * associated to different VectorSpaces. The individual components + * can also be const and non-const Vectors. + */ + class CompoundVector : public Vector + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor, given the corresponding CompoundVectorSpace. + * Before this constructor can be called, all components of the + * CompoundVectorSpace have to be set, so that the constructors + * for the individual components can be called. If the flag + * create_new is true, then the individual components of the new + * CompoundVector are initialized with the MakeNew methods of + * each VectorSpace (and are non-const). Otherwise, the + * individual components can later be set using the SetComp and + * SetCompNonConst method. + */ + CompoundVector(const CompoundVectorSpace* owner_space, bool create_new); + + /** Default destructor */ + virtual ~CompoundVector(); + //@} + + /** Method for setting the pointer for a component that is a const + * Vector + */ + void SetComp(Index icomp, const Vector& vec); + + /** Method for setting the pointer for a component that is a + * non-const Vector + */ + void SetCompNonConst(Index icomp, Vector& vec); + + /** Number of components of this compound vector */ + inline Index NComps() const; + + /** Check if a particular component is const or not */ + bool IsCompConst(Index i) const + { + DBG_ASSERT(i > 0 && i < NComps()); + DBG_ASSERT(IsValid(comps_[i]) || IsValid(const_comps_[i])); + if (IsValid(const_comps_[i])) { + return true; + } + return false; + } + + /** Check if a particular component is null or not */ + bool IsCompNull(Index i) const + { + DBG_ASSERT(i >= 0 && i < NComps()); + if (IsValid(comps_[i]) || IsValid(const_comps_[i])) { + return false; + } + return true; + } + + /** Return a particular component (const version) */ + SmartPtr GetComp(Index i) const + { + return ConstComp(i); + } + + /** Return a particular component (non-const version). Note that + * calling this method with mark the CompoundVector as changed. + * Therefore, only use this method if you are intending to change + * the Vector that you receive. + */ + SmartPtr GetCompNonConst(Index i) + { + ObjectChanged(); + return Comp(i); + } + + protected: + /** @name Overloaded methods from Vector base class */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number value); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$.*/ + virtual void ElementWiseDivideImpl(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$.*/ + virtual void ElementWiseMultiplyImpl(const Vector& x); + + /** Element-wise max against entries in x */ + virtual void ElementWiseMaxImpl(const Vector& x); + + /** Element-wise min against entries in x */ + virtual void ElementWiseMinImpl(const Vector& x); + + /** Element-wise reciprocal */ + virtual void ElementWiseReciprocalImpl(); + + /** Element-wise absolute values */ + virtual void ElementWiseAbsImpl(); + + /** Element-wise square-root */ + virtual void ElementWiseSqrtImpl(); + + /** Replaces entries with sgn of the entry */ + virtual void ElementWiseSgnImpl(); + + /** Add scalar to every component of the vector.*/ + virtual void AddScalarImpl(Number scalar); + + /** Max value in the vector */ + virtual Number MaxImpl() const; + + /** Min value in the vector */ + virtual Number MinImpl() const; + + /** Computes the sum of the lements of vector */ + virtual Number SumImpl() const; + + /** Computes the sum of the logs of the elements of vector */ + virtual Number SumLogsImpl() const; + + /** @name Implemented specialized functions */ + //@{ + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. */ + Number FracToBoundImpl(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + void AddVectorQuotientImpl(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + /** @name Output methods */ + //@{ + /* Print the entire vector with padding */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. + */ + //@{ + /** Default Constructor */ + CompoundVector(); + + /** Copy Constructor */ + CompoundVector(const CompoundVector&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundVector&); + //@} + + /** Components of the compound vector. The components + * are stored by SmartPtrs in a std::vector + */ + std::vector< SmartPtr > comps_; + std::vector< SmartPtr > const_comps_; + + const CompoundVectorSpace* owner_space_; + + bool vectors_valid_; + + bool VectorsValid(); + + inline const Vector* ConstComp(Index i) const; + + inline Vector* Comp(Index i); + }; + + /** This vectors space is the vector space for CompoundVector. + * Before a CompoundVector can be created, all components of this + * CompoundVectorSpace have to be set. When calling the constructor, + * the number of component has to be specified. The individual + * VectorSpaces can be set with the SetComp method. + */ + class CompoundVectorSpace : public VectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor, has to be given the number of components and the + * total dimension of all components combined. */ + CompoundVectorSpace(Index ncomp_spaces, Index total_dim); + + /** Destructor */ + ~CompoundVectorSpace() + {} + //@} + + /** Method for setting the individual component VectorSpaces */ + virtual void SetCompSpace(Index icomp /** Number of the component to be set */ , + const VectorSpace& vec_space /** VectorSpace for component icomp */ + ); + + /** Method for obtaining an individual component VectorSpace */ + SmartPtr GetCompSpace(Index icomp) const; + + /** Accessor method to obtain the number of components */ + Index NCompSpaces() const + { + return ncomp_spaces_; + } + + /** Method for creating a new vector of this specific type. */ + virtual CompoundVector* MakeNewCompoundVector(bool create_new = true) const + { + return new CompoundVector(this, create_new); + } + + /** Overloaded MakeNew method for the VectorSpace base class. + */ + virtual Vector* MakeNew() const + { + return MakeNewCompoundVector(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + CompoundVectorSpace(); + + /** Copy Constructor */ + CompoundVectorSpace(const CompoundVectorSpace&); + + /** Overloaded Equals Operator */ + CompoundVectorSpace& operator=(const CompoundVectorSpace&); + //@} + + /** Number of components */ + const Index ncomp_spaces_; + + /** std::vector of vector spaces for the components */ + std::vector< SmartPtr > comp_spaces_; + }; + + /* inline methods */ + inline + Index CompoundVector::NComps() const + { + return owner_space_->NCompSpaces(); + } + + inline + const Vector* CompoundVector::ConstComp(Index i) const + { + DBG_ASSERT(i < NComps()); + DBG_ASSERT(IsValid(comps_[i]) || IsValid(const_comps_[i])); + if (IsValid(comps_[i])) { + return GetRawPtr(comps_[i]); + } + else if (IsValid(const_comps_[i])) { + return GetRawPtr(const_comps_[i]); + } + + DBG_ASSERT(false && "shouldn't be here"); + return NULL; + } + + inline + Vector* CompoundVector::Comp(Index i) + { + DBG_ASSERT(i < NComps()); + DBG_ASSERT(IsValid(comps_[i])); + return GetRawPtr(comps_[i]); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpConvCheck.hpp b/thirdparty/linux/include/coin/IpConvCheck.hpp new file mode 100644 index 0000000..033fce4 --- /dev/null +++ b/thirdparty/linux/include/coin/IpConvCheck.hpp @@ -0,0 +1,87 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpConvCheck.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCONVCHECK_HPP__ +#define __IPCONVCHECK_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Base class for checking the algorithm + * termination criteria. + */ + class ConvergenceCheck : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + ConvergenceCheck() + {} + + /** Default destructor */ + virtual ~ConvergenceCheck() + {} + //@} + + /** Convergence return enum */ + enum ConvergenceStatus { + CONTINUE, + CONVERGED, + CONVERGED_TO_ACCEPTABLE_POINT, + MAXITER_EXCEEDED, + CPUTIME_EXCEEDED, + DIVERGING, + USER_STOP, + FAILED + }; + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Pure virtual method for performing the convergence test. If + * call_intermediate_callback is true, the user callback method + * in the NLP should be called in order to see if the user + * requests an early termination. */ + virtual ConvergenceStatus + CheckConvergence(bool call_intermediate_callback = true) = 0; + + /** Method for testing if the current iterate is considered to + * satisfy the "accptable level" of accuracy. The idea is that + * if the desired convergence tolerance cannot be achieved, the + * algorithm might stop after a number of acceptable points have + * been encountered. */ + virtual bool CurrentIsAcceptable()=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // ConvergenceCheck(); + + /** Copy Constructor */ + ConvergenceCheck(const ConvergenceCheck&); + + /** Overloaded Equals Operator */ + void operator=(const ConvergenceCheck&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpDebug.hpp b/thirdparty/linux/include/coin/IpDebug.hpp new file mode 100644 index 0000000..b8aae13 --- /dev/null +++ b/thirdparty/linux/include/coin/IpDebug.hpp @@ -0,0 +1,150 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDebug.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDEBUG_HPP__ +#define __IPDEBUG_HPP__ + +#include "IpoptConfig.h" +#include "IpTypes.hpp" + +#ifdef COIN_IPOPT_CHECKLEVEL +#ifdef HAVE_CASSERT +# include +#else +# ifdef HAVE_ASSERT_H +# include +# else +# error "don't have header file for assert" +# endif +#endif +#else +#define COIN_IPOPT_CHECKLEVEL 0 +#endif + +#if COIN_IPOPT_CHECKLEVEL > 0 +# ifdef NDEBUG +# undef NDEBUG +# endif +# define DBG_ASSERT(test) assert(test) +# define DBG_ASSERT_EXCEPTION(__condition, __except_type, __msg) \ + ASSERT_EXCEPTION( (__condition), __except_type, __msg); +# define DBG_DO(__cmd) __cmd +#else +# define DBG_ASSERT(test) +# define DBG_ASSERT_EXCEPTION(__condition, __except_type, __msg) +# define DBG_DO(__cmd) +#endif + +#ifndef COIN_IPOPT_VERBOSITY +#define COIN_IPOPT_VERBOSITY 0 +#endif + +#if COIN_IPOPT_VERBOSITY < 1 +# define DBG_START_FUN(__func_name, __verbose_level) +# define DBG_START_METH(__func_name, __verbose_level) +# define DBG_PRINT(__printf_args) +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) +# define DBG_EXEC(__verbosity, __cmd) +# define DBG_VERBOSITY() 0 +#else +#include + +namespace Ipopt +{ + // forward definition + class Journalist; + + /** Class that lives throughout the execution of a method or + * function for which debug output is to be generated. The output + * is sent to the unique debug journalist that is set with + * SetJournalist at the beginning of program execution. */ + class DebugJournalistWrapper + { + public: + /** @name Constructors/Destructors. */ + //@{ + DebugJournalistWrapper(std::string func_name, Index verbose_level); + DebugJournalistWrapper(std::string func_name, Index verbose_level, + const void* const method_owner); + ~DebugJournalistWrapper(); + //@} + + /** @name accessor methods */ + //@{ + Index Verbosity() + { + return verbose_level_; + } + const Journalist* Jnlst() + { + return jrnl_; + } + Index IndentationLevel() + { + return indentation_level_; + } + //@} + + /** Printing */ + void DebugPrintf(Index verbosity, const char* pformat, ...); + + /* Method for initialization of the static GLOBAL journalist, + * through with all debug printout is to be written. This needs + * to be set before any debug printout can be done. */ + static void SetJournalist(Journalist* jrnl); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + DebugJournalistWrapper(); + + /** copy contructor */ + DebugJournalistWrapper(const DebugJournalistWrapper&); + + /** Overloaded Equals Operator */ + DebugJournalistWrapper& operator=(const DebugJournalistWrapper&); + //@} + + static Index indentation_level_; + std::string func_name_; + Index verbose_level_; + const void* method_owner_; + + static Journalist* jrnl_; + }; +} + +# define DBG_START_FUN(__func_name, __verbose_level) \ + DebugJournalistWrapper dbg_jrnl((__func_name), (__verbose_level)); \ + +# define DBG_START_METH(__func_name, __verbose_level) \ + DebugJournalistWrapper dbg_jrnl((__func_name), (__verbose_level), this); + +# define DBG_PRINT(__args) \ + dbg_jrnl.DebugPrintf __args; + +# define DBG_EXEC(__verbose_level, __cmd) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + (__cmd); \ + } + +# define DBG_VERBOSITY() \ + dbg_jrnl.Verbosity() + +#endif + + +#endif diff --git a/thirdparty/linux/include/coin/IpDenseVector.hpp b/thirdparty/linux/include/coin/IpDenseVector.hpp new file mode 100644 index 0000000..380a06c --- /dev/null +++ b/thirdparty/linux/include/coin/IpDenseVector.hpp @@ -0,0 +1,550 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDenseVector.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDENSEVECTOR_HPP__ +#define __IPDENSEVECTOR_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include + +namespace Ipopt +{ + + /* forward declarations */ + class DenseVectorSpace; + + /** @name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(METADATA_ERROR); + //@} + + /** Dense Vector Implementation. This is the default Vector class + * in Ipopt. It stores vectors in contiguous Number arrays, unless + * the vector has the same value in all entires. In the latter + * case, we call the vector "homogeneous", and we store only the + * values that is repeated in all elements. If you want to obtain + * the values of vector, use the IsHomogeneous() method to find out + * what status the vector is in, and then use either Values() const + * or Scalar() const methods to get the values. To set the values + * of a homogeneous method, use the Set method. To set the values + * of a non-homogeneous vector, use the SetValues method, or use + * the non-const Values method to get an array that you can + * overwrite. In the latter case, storage is ensured. + */ + class DenseVector : public Vector + { + public: + + /**@name Constructors / Destructors */ + //@{ + /** Default Constructor + */ + DenseVector(const DenseVectorSpace* owner_space); + + /** Destructor + */ + virtual ~DenseVector(); + //@} + + /** @name Additional public methods not in Vector base class. */ + //@{ + /** Create a new DenseVector from same VectorSpace */ + SmartPtr MakeNewDenseVector() const; + + /** Set elements in the vector to the Number array x. */ + void SetValues(const Number *x); + + /** Obtain pointer to the internal Number array with vector + * elements with the indention to change the vector data (USE + * WITH CARE!). This does not produce a copy, and lifetime is not + * guaranteed!. + */ + inline Number* Values(); + + /** Obtain pointer to the internal Number array with vector + * elements without the intention to change the vector data (USE + * WITH CARE!). This does not produce a copy, and lifetime is not + * guaranteed! IMPORTANT: If this method is currently + * homogeneous (i.e. IsHomogeneous returns true), then you cannot + * call this method. Instead, you need to use the Scalar() + * method. + */ + inline const Number* Values() const; + + /** The same as the const version of Values, but we ensure that we + * always return a valid array, even if IsHomogeneous returns + * true. */ + const Number* ExpandedValues() const; + + /** This is the same as Values, but we add it here so that + * ExpandedValues can also be used for the non-const case. */ + inline Number* ExpandedValues() + { + return Values(); + } + + /** Indicates if the vector is homogeneous (i.e., all entries have + * the value Scalar() */ + bool IsHomogeneous() const + { + return homogeneous_; + } + + /** Scalar value of all entries in a homogeneous vector */ + Number Scalar() const + { + DBG_ASSERT(homogeneous_); + return scalar_; + } + //@} + + /** @name Modifying subranges of the vector. */ + //@{ + /** Copy the data in x into the subrange of this vector starting + * at position Pos in this vector. Position count starts at 0. + */ + void CopyToPos(Index Pos, const Vector& x); + /** Copy a subrange of x, starting at Pos, into the full data of + * this vector. Position count starts at 0. + */ + void CopyFromPos(Index Pos, const Vector& x); + //@} + + protected: + /** @name Overloaded methods from Vector base class */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number value); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$.*/ + virtual void ElementWiseDivideImpl(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$.*/ + virtual void ElementWiseMultiplyImpl(const Vector& x); + + /** Set entry to max of itself and the corresponding element in x */ + virtual void ElementWiseMaxImpl(const Vector& x); + + /** Set entry to min of itself and the corresponding element in x */ + virtual void ElementWiseMinImpl(const Vector& x); + + /** reciprocates the elements of the vector */ + virtual void ElementWiseReciprocalImpl(); + + /** take abs of the elements of the vector */ + virtual void ElementWiseAbsImpl(); + + /** take square-root of the elements of the vector */ + virtual void ElementWiseSqrtImpl(); + + /** Changes each entry in the vector to its sgn value */ + virtual void ElementWiseSgnImpl(); + + /** Add scalar to every component of the vector.*/ + virtual void AddScalarImpl(Number scalar); + + /** Max value in the vector */ + virtual Number MaxImpl() const; + + /** Min value in the vector */ + virtual Number MinImpl() const; + + /** Computes the sum of the lements of vector */ + virtual Number SumImpl() const; + + /** Computes the sum of the logs of the elements of vector */ + virtual Number SumLogsImpl() const; + + /** @name Implemented specialized functions */ + //@{ + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. */ + Number FracToBoundImpl(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + void AddVectorQuotientImpl(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** @name Output methods */ + //@{ + /* Print the entire vector with padding */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 1); + } + /* Print the entire vector with padding, and start counting with + an offset. */ + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index offset) const; + //@} + friend class ParVector; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DenseVector(); + + /** Copy Constructor */ + DenseVector(const DenseVector&); + + /** Overloaded Equals Operator */ + void operator=(const DenseVector&); + //@} + + /** Copy of the owner_space ptr as a DenseVectorSpace instead + * of a VectorSpace + */ + const DenseVectorSpace* owner_space_; + + /** Dense Number array of vector values. */ + Number* values_; + + /** Dense Number array pointer that is used for ExpandedValues */ + mutable Number* expanded_values_; + + /** Method of getting the internal values array, making sure that + * memory has been allocated */ + inline + Number* values_allocated(); + + /** Flag for Initialization. This flag is false, if the data has + not yet been initialized. */ + bool initialized_; + + /** Flag indicating whether the vector is currently homogeneous + * (that is, all elements have the same value). This flag is used + * to determine whether the elements of the vector are stored in + * values_ or in scalar_ */ + bool homogeneous_; + + /** Homogeneous value of all elements if the vector is currently + * homogenous */ + Number scalar_; + + /** Auxilliary method for setting explicitly all elements in + * values_ to the current scalar value. */ + void set_values_from_scalar(); + }; + + /** typedefs for the map variables that define meta data for the + * DenseVectorSpace + */ + typedef std::map > StringMetaDataMapType; + typedef std::map > IntegerMetaDataMapType; + typedef std::map > NumericMetaDataMapType; + + /** This vectors space is the vector space for DenseVector. + */ + class DenseVectorSpace : public VectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor, requires dimension of all vector for this + * VectorSpace + */ + DenseVectorSpace(Index dim) + : + VectorSpace(dim) + {} + + /** Destructor */ + ~DenseVectorSpace() + {} + //@} + + /** Method for creating a new vector of this specific type. */ + inline + DenseVector* MakeNewDenseVector() const + { + return new DenseVector(this); + } + + /** Instantiation of the generate MakeNew method for the + * VectorSpace base class. + */ + virtual Vector* MakeNew() const + { + return MakeNewDenseVector(); + } + + /**@name Methods called by DenseVector for memory management. + * This could allow to have sophisticated memory management in the + * VectorSpace. + */ + //@{ + /** Allocate internal storage for the DenseVector */ + inline + Number* AllocateInternalStorage() const; + + /** Deallocate internal storage for the DenseVector */ + inline + void FreeInternalStorage(Number* values) const; + //@} + + /**@name Methods for dealing with meta data on the vector + */ + //@{ + /** Check if string meta exists for tag */ + inline + bool HasStringMetaData(const std::string tag) const; + + /** Check if Integer meta exists for tag */ + inline + bool HasIntegerMetaData(const std::string tag) const; + + /** Check if Numeric meta exists for tag */ + inline + bool HasNumericMetaData(const std::string tag) const; + + /** Get meta data of type std::string by tag */ + inline + const std::vector& GetStringMetaData(const std::string& tag) const; + + /** Get meta data of type Index by tag */ + inline + const std::vector& GetIntegerMetaData(const std::string& tag) const; + + /** Get meta data of type Number by tag */ + inline + const std::vector& GetNumericMetaData(const std::string& tag) const; + + /** Set meta data of type std::string by tag */ + inline + void SetStringMetaData(std::string tag, std::vector meta_data); + + /** Set meta data of type Index by tag */ + inline + void SetIntegerMetaData(std::string tag, std::vector meta_data); + + /** Set meta data of type Number by tag */ + inline + void SetNumericMetaData(std::string tag, std::vector meta_data); + + /** Get map of meta data of type Number */ + inline + const StringMetaDataMapType& GetStringMetaData() const; + + /** Get map of meta data of type Number */ + inline + const IntegerMetaDataMapType& GetIntegerMetaData() const; + + /** Get map of meta data of type Number */ + inline + const NumericMetaDataMapType& GetNumericMetaData() const; + //@} + + private: + // variables to store vector meta data + StringMetaDataMapType string_meta_data_; + IntegerMetaDataMapType integer_meta_data_; + NumericMetaDataMapType numeric_meta_data_; + + }; + + // inline functions + inline Number* DenseVector::Values() + { + // Here we assume that every time someone requests this direct raw + // pointer, the data is going to change and the Tag for this + // vector has to be updated. + + if (initialized_ && homogeneous_) { + // If currently the vector is a homogeneous vector, set all elements + // explicitly to this value + set_values_from_scalar(); + } + ObjectChanged(); + initialized_= true; + homogeneous_ = false; + return values_allocated(); + } + + inline const Number* DenseVector::Values() const + { + DBG_ASSERT(initialized_ && (Dim()==0 || values_)); + return values_; + } + + inline Number* DenseVector::values_allocated() + { + if (values_==NULL) { + values_ = owner_space_->AllocateInternalStorage(); + } + return values_; + } + + inline + Number* DenseVectorSpace::AllocateInternalStorage() const + { + if (Dim()>0) { + return new Number[Dim()]; + } + else { + return NULL; + } + } + + inline + void DenseVectorSpace::FreeInternalStorage(Number* values) const + { + delete [] values; + } + + inline + SmartPtr DenseVector::MakeNewDenseVector() const + { + return owner_space_->MakeNewDenseVector(); + } + + inline + bool DenseVectorSpace::HasStringMetaData(const std::string tag) const + { + StringMetaDataMapType::const_iterator iter; + iter = string_meta_data_.find(tag); + + if (iter != string_meta_data_.end()) { + return true; + } + + return false; + } + + inline + bool DenseVectorSpace::HasIntegerMetaData(const std::string tag) const + { + IntegerMetaDataMapType::const_iterator iter; + iter = integer_meta_data_.find(tag); + + if (iter != integer_meta_data_.end()) { + return true; + } + + return false; + } + + inline + bool DenseVectorSpace::HasNumericMetaData(const std::string tag) const + { + NumericMetaDataMapType::const_iterator iter; + iter = numeric_meta_data_.find(tag); + + if (iter != numeric_meta_data_.end()) { + return true; + } + + return false; + } + + inline + const std::vector& DenseVectorSpace::GetStringMetaData(const std::string& tag) const + { + DBG_ASSERT(HasStringMetaData(tag)); + StringMetaDataMapType::const_iterator iter; + iter = string_meta_data_.find(tag); + return iter->second; + } + + inline + const std::vector& DenseVectorSpace::GetIntegerMetaData(const std::string& tag) const + { + DBG_ASSERT(HasIntegerMetaData(tag)); + IntegerMetaDataMapType::const_iterator iter; + iter = integer_meta_data_.find(tag); + return iter->second; + } + + inline + const std::vector& DenseVectorSpace::GetNumericMetaData(const std::string& tag) const + { + DBG_ASSERT(HasNumericMetaData(tag)); + NumericMetaDataMapType::const_iterator iter; + iter = numeric_meta_data_.find(tag); + return iter->second; + } + + inline + void DenseVectorSpace::SetStringMetaData(std::string tag, std::vector meta_data) + { + string_meta_data_[tag] = meta_data; + } + + inline + void DenseVectorSpace::SetIntegerMetaData(std::string tag, std::vector meta_data) + { + integer_meta_data_[tag] = meta_data; + } + + inline + void DenseVectorSpace::SetNumericMetaData(std::string tag, std::vector meta_data) + { + numeric_meta_data_[tag] = meta_data; + } + + inline + const StringMetaDataMapType& DenseVectorSpace::GetStringMetaData() const + { + return string_meta_data_; + } + + inline + const IntegerMetaDataMapType& DenseVectorSpace::GetIntegerMetaData() const + { + return integer_meta_data_; + } + + inline + const NumericMetaDataMapType& DenseVectorSpace::GetNumericMetaData() const + { + return numeric_meta_data_; + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpDiagMatrix.hpp b/thirdparty/linux/include/coin/IpDiagMatrix.hpp new file mode 100644 index 0000000..d912e77 --- /dev/null +++ b/thirdparty/linux/include/coin/IpDiagMatrix.hpp @@ -0,0 +1,141 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDiagMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDIAGMATRIX_HPP__ +#define __IPDIAGMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for diagonal matrices. The diagonal is stored as a + * Vector. */ + class DiagMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, given the corresponding matrix space. */ + DiagMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~DiagMatrix(); + //@} + + /** Method for setting the diagonal elements (as a Vector). */ + void SetDiag(const Vector& diag) + { + diag_ = &diag; + } + + /** Method for setting the diagonal elements. */ + SmartPtr GetDiag() const + { + return diag_; + } + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DiagMatrix(); + + /** Copy Constructor */ + DiagMatrix(const DiagMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const DiagMatrix&); + //@} + + /** Vector storing the diagonal elements */ + SmartPtr diag_; + }; + + /** This is the matrix space for DiagMatrix. */ + class DiagMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix. */ + DiagMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~DiagMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewDiagMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + DiagMatrix* MakeNewDiagMatrix() const + { + return new DiagMatrix(this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DiagMatrixSpace(); + + /** Copy Constructor */ + DiagMatrixSpace(const DiagMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const DiagMatrixSpace&); + //@} + + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpEqMultCalculator.hpp b/thirdparty/linux/include/coin/IpEqMultCalculator.hpp new file mode 100644 index 0000000..7c3cb20 --- /dev/null +++ b/thirdparty/linux/include/coin/IpEqMultCalculator.hpp @@ -0,0 +1,64 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpEqMultCalculator.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-23 + +#ifndef __IPEQMULTCALCULATOR_HPP__ +#define __IPEQMULTCALCULATOR_HPP__ + +#include "IpUtils.hpp" +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + /** Base Class for objects that compute estimates for the equality + * constraint multipliers y_c and y_d. For example, this is the + * base class for objects for computing least square multipliers or + * coordinate multipliers. */ + class EqMultiplierCalculator: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor. */ + EqMultiplierCalculator() + {} + /** Default destructor */ + virtual ~EqMultiplierCalculator() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** This method computes the estimates for y_c and y_d at the + * current point. If the estimates cannot be computed (e.g. some + * linear system is singular), the return value of this method is + * false. */ + virtual bool CalculateMultipliers(Vector& y_c, + Vector& y_d) = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + EqMultiplierCalculator(const EqMultiplierCalculator&); + + /** Overloaded Equals Operator */ + void operator=(const EqMultiplierCalculator&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpException.hpp b/thirdparty/linux/include/coin/IpException.hpp new file mode 100644 index 0000000..e64226f --- /dev/null +++ b/thirdparty/linux/include/coin/IpException.hpp @@ -0,0 +1,147 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpException.hpp 2023 2011-06-18 18:49:49Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPEXCEPTION_HPP__ +#define __IPEXCEPTION_HPP__ + +#include "IpUtils.hpp" +#include "IpJournalist.hpp" + +/* This file contains a base class for all exceptions + * and a set of macros to help with exceptions + */ + +namespace Ipopt +{ + + /** This is the base class for all exceptions. The easiest way to + * use this class is by means of the following macros: + * + * \verbatim + + DECLARE_STD_EXCEPTION(ExceptionType); + \endverbatim + * + * This macro defines a new class with the name ExceptionType, + * inherited from the base class IpoptException. After this, + * exceptions of this type can be thrown using + * + * \verbatim + + THROW_EXCEPTION(ExceptionType, Message); + \endverbatim + * + * where Message is a std::string with a message that gives an + * indication of what caused the exception. Exceptions can also be + * thrown using the macro + * + * \verbatim + + ASSERT_EXCEPTION(Condition, ExceptionType, Message); + \endverbatim + * + * where Conditions is an expression. If Condition evaluates to + * false, then the exception of the type ExceptionType is thrown + * with Message. + * + * When an exception is caught, the method ReportException can be + * used to write the information about the exception to the + * Journalist, using the level J_ERROR and the category J_MAIN. + * + */ + class IpoptException + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptException(std::string msg, std::string file_name, Index line_number, std::string type="IpoptException") + : + msg_(msg), + file_name_(file_name), + line_number_(line_number), + type_(type) + {} + + /** Copy Constructor */ + IpoptException(const IpoptException& copy) + : + msg_(copy.msg_), + file_name_(copy.file_name_), + line_number_(copy.line_number_), + type_(copy.type_) + {} + + /** Default destructor */ + virtual ~IpoptException() + {} + //@} + + /** Method to report the exception to a journalist */ + void ReportException(const Journalist& jnlst, + EJournalLevel level = J_ERROR) const + { + jnlst.Printf(level, J_MAIN, + "Exception of type: %s in file \"%s\" at line %d:\n Exception message: %s\n", + type_.c_str(), file_name_.c_str(), line_number_, msg_.c_str()); + } + + const std::string& Message() const + { + return msg_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptException(); + + /** Overloaded Equals Operator */ + void operator=(const IpoptException&); + //@} + + std::string msg_; + std::string file_name_; + Index line_number_; + std::string type_; + }; + +} // namespace Ipopt + +#define THROW_EXCEPTION(__except_type, __msg) \ + throw __except_type( (__msg), (__FILE__), (__LINE__) ); + +#define ASSERT_EXCEPTION(__condition, __except_type, __msg) \ + if (! (__condition) ) { \ + std::string newmsg = #__condition; \ + newmsg += " evaluated false: "; \ + newmsg += __msg; \ + throw __except_type( (newmsg), (__FILE__), (__LINE__) ); \ + } + +#define DECLARE_STD_EXCEPTION(__except_type) \ + class __except_type : public Ipopt::IpoptException \ + { \ + public: \ + __except_type(std::string msg, std::string fname, Ipopt::Index line) \ + : Ipopt::IpoptException(msg,fname,line, #__except_type) {} \ + __except_type(const __except_type& copy) \ + : Ipopt::IpoptException(copy) {} \ + private: \ + __except_type(); \ + void operator=(const __except_type&); \ + } + +#endif diff --git a/thirdparty/linux/include/coin/IpExpansionMatrix.hpp b/thirdparty/linux/include/coin/IpExpansionMatrix.hpp new file mode 100644 index 0000000..cbb9a99 --- /dev/null +++ b/thirdparty/linux/include/coin/IpExpansionMatrix.hpp @@ -0,0 +1,212 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpExpansionMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPEXPANSIONMATRIX_HPP__ +#define __IPEXPANSIONMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /** forward declarations */ + class ExpansionMatrixSpace; + + /** Class for expansion/projection matrices. These matrices allow + * to lift a vector to a vector with larger dimension, keeping + * some elements of the larger vector zero. This operation is achieved + * by the MultVector operation. The transpose operation then + * filters some elements from a large vector into a smaller vector. + */ + class ExpansionMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + ExpansionMatrix(const ExpansionMatrixSpace* owner_space); + + /** Destructor */ + ~ExpansionMatrix(); + //@} + + /** Return the vector of indices marking the expanded position. + * The result is the Index array (of length NSmallVec=NCols()) + * that stores the mapping from the small vector to the large + * vector. For each element i=0,..,NSmallVec in the small + * vector, ExpandedPosIndices()[i] give the corresponding index + * in the large vector. + */ + const Index* ExpandedPosIndices() const; + + /** Return the vector of indices marking the compressed position. + * The result is the Index array (of length NLargeVec=NRows()) + * that stores the mapping from the large vector to the small + * vector. For each element i=0,..,NLargeVec in the large + * vector, CompressedPosIndices()[i] gives the corresponding + * index in the small vector, unless CompressedPosIndices()[i] is + * negative. + */ + const Index* CompressedPosIndices() const; + + protected: + /**@name Overloaded methods from Matrix base class*/ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector &x, Number beta, + Vector &y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized implementation. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 1, 1); + } + //@} + + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index row_offset, + Index col_offset) const; + + friend class ParExpansionMatrix; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ExpansionMatrix(); + + /** Copy Constructor */ + ExpansionMatrix(const ExpansionMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ExpansionMatrix&); + //@} + + const ExpansionMatrixSpace* owner_space_; + + }; + + /** This is the matrix space for ExpansionMatrix. + */ + class ExpansionMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the list of elements of the large vector + * (of size NLargeVec) to be filtered into the small vector (of + * size NSmallVec). For each i=0..NSmallVec-1 the i-th element + * of the small vector will be put into the ExpPos[i] position of + * the large vector. The position counting in the vector is + * assumed to start at 0 (C-like array notation). + */ + ExpansionMatrixSpace(Index NLargeVec, + Index NSmallVec, + const Index *ExpPos, + const int offset = 0); + + /** Destructor */ + ~ExpansionMatrixSpace() + { + delete [] compressed_pos_; + delete [] expanded_pos_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + ExpansionMatrix* MakeNewExpansionMatrix() const + { + return new ExpansionMatrix(this); + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewExpansionMatrix(); + } + + /** Accessor Method to obtain the Index array (of length + * NSmallVec=NCols()) that stores the mapping from the small + * vector to the large vector. For each element i=0,..,NSmallVec + * in the small vector, ExpandedPosIndices()[i] give the + * corresponding index in the large vector. + */ + const Index* ExpandedPosIndices() const + { + return expanded_pos_; + } + + /** Accessor Method to obtain the Index array (of length + * NLargeVec=NRows()) that stores the mapping from the large + * vector to the small vector. For each element i=0,..,NLargeVec + * in the large vector, CompressedPosIndices()[i] gives the + * corresponding index in the small vector, unless + * CompressedPosIndices()[i] is negative. + */ + const Index* CompressedPosIndices() const + { + return compressed_pos_; + } + + private: + Index *expanded_pos_; + Index *compressed_pos_; + }; + + /* inline methods */ + inline + const Index* ExpansionMatrix::ExpandedPosIndices() const + { + return owner_space_->ExpandedPosIndices(); + } + + inline + const Index* ExpansionMatrix::CompressedPosIndices() const + { + return owner_space_->CompressedPosIndices(); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpGenTMatrix.hpp b/thirdparty/linux/include/coin/IpGenTMatrix.hpp new file mode 100644 index 0000000..059bfea --- /dev/null +++ b/thirdparty/linux/include/coin/IpGenTMatrix.hpp @@ -0,0 +1,264 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpGenTMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPGENTMATRIX_HPP__ +#define __IPGENTMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class GenTMatrixSpace; + + /** Class for general matrices stored in triplet format. In the + * triplet format, the nonzeros elements of a general matrix is + * stored in three arrays, Irow, Jcol, and Values, all of length + * Nonzeros. The first two arrays indicate the location of a + * non-zero element (row and column indices), and the last array + * stores the value at that location. If nonzero elements are + * listed more than once, their values are added. + * + * The structure of the nonzeros (i.e. the arrays Irow and Jcol) + * cannot be changed after the matrix can been initialized. Only + * the values of the nonzero elements can be modified. + * + * Note that the first row and column of a matrix has index 1, not + * 0. + */ + class GenTMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + GenTMatrix(const GenTMatrixSpace* owner_space); + + /** Destructor */ + ~GenTMatrix(); + //@} + + /**@name Changing the Values.*/ + //@{ + /** Set values of nonzero elements. The values of the nonzero + * elements are copied from the incoming Number array. Important: + * It is assume that the order of the values in Values + * corresponds to the one of Irn and Jcn given to one of the + * constructors above. */ + void SetValues(const Number* Values); + //@} + + /** @name Accessor Methods */ + //@{ + /** Number of nonzero entries */ + Index Nonzeros() const; + + /** Array with Row indices (counting starts at 1) */ + const Index* Irows() const; + + /** Array with Column indices (counting starts at 1) */ + const Index* Jcols() const; + + /** Array with nonzero values (const version). */ + const Number* Values() const + { + return values_; + } + + /** Array with the nonzero values of this matrix (non-const + * version). Use this method only if you are intending to change + * the values, because the GenTMatrix will be marked as changed. + */ + Number* Values() + { + ObjectChanged(); + initialized_ = true; + return values_; + } + //@} + + protected: + /**@name Overloaded methods from Matrix base class*/ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector &x, Number beta, + Vector &y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 0); + } + //@} + + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index offset) const; + + friend class ParGenMatrix; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + GenTMatrix(); + + /** Copy Constructor */ + GenTMatrix(const GenTMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const GenTMatrix&); + //@} + + /** Copy of the owner space as a GenTMatrixSpace instead of + * a MatrixSpace + */ + const GenTMatrixSpace* owner_space_; + + /** Values of nonzeros */ + Number* values_; + + /** Flag for Initialization */ + bool initialized_; + + }; + + /** This is the matrix space for a GenTMatrix with fixed sparsity + * structure. The sparsity structure is stored here in the matrix + * space. + */ + class GenTMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of rows and columns, as well as + * the number of nonzeros and the position of the nonzero + * elements. Note that the counting of the nonzeros starts a 1, + * i.e., iRows[i]==1 and jCols[i]==1 refers to the first element + * in the first row. This is in accordance with the HSL data + * structure. + */ + GenTMatrixSpace(Index nRows, Index nCols, + Index nonZeros, + const Index* iRows, const Index* jCols); + + /** Destructor */ + ~GenTMatrixSpace() + { + delete [] iRows_; + delete [] jCols_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + GenTMatrix* MakeNewGenTMatrix() const + { + return new GenTMatrix(this); + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewGenTMatrix(); + } + + /**@name Methods describing Matrix structure */ + //@{ + /** Number of non-zeros in the sparse matrix */ + Index Nonzeros() const + { + return nonZeros_; + } + + /** Row index of each non-zero element (counting starts at 1) */ + const Index* Irows() const + { + return iRows_; + } + + /** Column index of each non-zero element (counting starts at 1) */ + const Index* Jcols() const + { + return jCols_; + } + //@} + + private: + /** @name Sparsity structure of matrices generated by this matrix + * space. + */ + //@{ + const Index nonZeros_; + Index* jCols_; + Index* iRows_; + //@} + + /** This method is only for the GenTMatrix to call in order + * to allocate internal storage */ + Number* AllocateInternalStorage() const; + + /** This method is only for the GenTMatrix to call in order + * to de-allocate internal storage */ + void FreeInternalStorage(Number* values) const; + + friend class GenTMatrix; + }; + + /* inline methods */ + inline + Index GenTMatrix::Nonzeros() const + { + return owner_space_->Nonzeros(); + } + + inline + const Index* GenTMatrix::Irows() const + { + return owner_space_->Irows(); + } + + inline + const Index* GenTMatrix::Jcols() const + { + return owner_space_->Jcols(); + } + + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpHessianUpdater.hpp b/thirdparty/linux/include/coin/IpHessianUpdater.hpp new file mode 100644 index 0000000..a3912d6 --- /dev/null +++ b/thirdparty/linux/include/coin/IpHessianUpdater.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2005, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpHessianUpdater.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-12-26 + +#ifndef __IPHESSIANUPDATER_HPP__ +#define __IPHESSIANUPDATER_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Abstract base class for objects responsible for updating the + * Hessian information. This can be done using exact second + * derivatives from the NLP, or by a quasi-Newton Option. The + * result is put into the W field in IpData. + */ + class HessianUpdater : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + HessianUpdater() + {} + + /** Default destructor */ + virtual ~HessianUpdater() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Update the Hessian based on the current information in IpData, + * and possibly on information from previous calls. + */ + virtual void UpdateHessian() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + HessianUpdater(const HessianUpdater&); + + /** Overloaded Equals Operator */ + void operator=(const HessianUpdater&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpIdentityMatrix.hpp b/thirdparty/linux/include/coin/IpIdentityMatrix.hpp new file mode 100644 index 0000000..8032306 --- /dev/null +++ b/thirdparty/linux/include/coin/IpIdentityMatrix.hpp @@ -0,0 +1,149 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIdentityMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIDENTITYMATRIX_HPP__ +#define __IPIDENTITYMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for Matrices which are multiples of the identity matrix. + * + */ + class IdentityMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, initializing with dimensions of the matrix + * (true identity matrix). + */ + IdentityMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~IdentityMatrix(); + //@} + + /** Method for setting the factor for the identity matrix. */ + void SetFactor(Number factor) + { + factor_ = factor; + } + + /** Method for getting the factor for the identity matrix. */ + Number GetFactor() const + { + return factor_; + } + + /** Method for obtaining the dimention of the matrix. */ + Index Dim() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void AddMSinvZImpl(Number alpha, const Vector& S, + const Vector& Z, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IdentityMatrix(); + + /** Copy Constructor */ + IdentityMatrix(const IdentityMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const IdentityMatrix&); + //@} + + /** Scaling factor for this identity matrix */ + Number factor_; + }; + + /** This is the matrix space for IdentityMatrix. */ + class IdentityMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix. */ + IdentityMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~IdentityMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewIdentityMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + IdentityMatrix* MakeNewIdentityMatrix() const + { + return new IdentityMatrix(this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IdentityMatrixSpace(); + + /** Copy Constructor */ + IdentityMatrixSpace(const IdentityMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const IdentityMatrixSpace&); + //@} + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpIpoptAlg.hpp b/thirdparty/linux/include/coin/IpIpoptAlg.hpp new file mode 100644 index 0000000..60e3147 --- /dev/null +++ b/thirdparty/linux/include/coin/IpIpoptAlg.hpp @@ -0,0 +1,224 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptAlg.hpp 2167 2013-03-08 11:15:38Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTALG_HPP__ +#define __IPIPOPTALG_HPP__ + +#include "IpIpoptNLP.hpp" +#include "IpAlgStrategy.hpp" +#include "IpSearchDirCalculator.hpp" +#include "IpLineSearch.hpp" +#include "IpMuUpdate.hpp" +#include "IpConvCheck.hpp" +#include "IpOptionsList.hpp" +#include "IpIterateInitializer.hpp" +#include "IpIterationOutput.hpp" +#include "IpAlgTypes.hpp" +#include "IpHessianUpdater.hpp" +#include "IpEqMultCalculator.hpp" + +namespace Ipopt +{ + + /** @name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(STEP_COMPUTATION_FAILED); + //@} + + /** The main ipopt algorithm class. + * Main Ipopt algorithm class, contains the main optimize method, + * handles the execution of the optimization. + * The constructor initializes the data structures through the nlp, + * and the Optimize method then assumes that everything is + * initialized and ready to go. + * After an optimization is complete, the user can access the + * solution through the passed in ip_data structure. + * Multiple calls to the Optimize method are allowed as long as the + * structure of the problem remains the same (i.e. starting point + * or nlp parameter changes only). + */ + class IpoptAlgorithm : public AlgorithmStrategyObject + { + public: + + /**@name Constructors/Destructors */ + //@{ + /** Constructor. (The IpoptAlgorithm uses smart pointers for these + * passed-in pieces to make sure that a user of IpoptAlgoroithm + * cannot pass in an object created on the stack!) + */ + IpoptAlgorithm(const SmartPtr& search_dir_calculator, + const SmartPtr& line_search, + const SmartPtr& mu_update, + const SmartPtr& conv_check, + const SmartPtr& iterate_initializer, + const SmartPtr& iter_output, + const SmartPtr& hessian_updater, + const SmartPtr& eq_multiplier_calculator = NULL); + + /** Default destructor */ + virtual ~IpoptAlgorithm(); + //@} + + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix); + + /** Main solve method. */ + SolverReturn Optimize(bool isResto = false); + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr roptions); + //@} + + /**@name Access to internal strategy objects */ + //@{ + SmartPtr SearchDirCalc() + { + return search_dir_calculator_; + } + //@} + + static void print_copyright_message(const Journalist& jnlst); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptAlgorithm(); + + /** Copy Constructor */ + IpoptAlgorithm(const IpoptAlgorithm&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAlgorithm&); + //@} + + /** @name Strategy objects */ + //@{ + SmartPtr search_dir_calculator_; + SmartPtr line_search_; + SmartPtr mu_update_; + SmartPtr conv_check_; + SmartPtr iterate_initializer_; + SmartPtr iter_output_; + SmartPtr hessian_updater_; + /** The multipler calculator (for y_c and y_d) has to be set only + * if option recalc_y is set to true */ + SmartPtr eq_multiplier_calculator_; + //@} + + /** @name Main steps of the algorthim */ + //@{ + /** Method for updating the current Hessian. This can either just + * evaluate the exact Hessian (based on the current iterate), or + * perform a quasi-Newton update. + */ + void UpdateHessian(); + + /** Method to update the barrier parameter. Returns false, if the + * algorithm can't continue with the regular procedure and needs + * to revert to a fallback mechanism in the line search (such as + * restoration phase) */ + bool UpdateBarrierParameter(); + + /** Method to setup the call to the PDSystemSolver. Returns + * false, if the algorithm can't continue with the regular + * procedure and needs to revert to a fallback mechanism in the + * line search (such as restoration phase) */ + bool ComputeSearchDirection(); + + /** Method computing the new iterate (usually vialine search). + * The acceptable point is the one in trial after return. + */ + void ComputeAcceptableTrialPoint(); + + /** Method for accepting the trial point as the new iteration, + * possibly after adjusting the variable bounds in the NLP. */ + void AcceptTrialPoint(); + + /** Do all the output for one iteration */ + void OutputIteration(); + + /** Sets up initial values for the iterates, + * Corrects the initial values for x and s (force in bounds) + */ + void InitializeIterates(); + + /** Print the problem size statistics */ + void PrintProblemStatistics(); + + /** Compute the Lagrangian multipliers for a feasibility problem*/ + void ComputeFeasibilityMultipliers(); + //@} + + /** @name internal flags */ + //@{ + /** Flag indicating if the statistic should not be printed */ + bool skip_print_problem_stats_; + //@} + + /** @name Algorithmic parameters */ + //@{ + /** safeguard factor for bound multipliers. If value >= 1, then + * the dual variables will never deviate from the primal estimate + * by more than the factors kappa_sigma and 1./kappa_sigma. + */ + Number kappa_sigma_; + /** Flag indicating whether the y multipliers should be + * recalculated with the eq_mutliplier_calculator object for each + * new point. */ + bool recalc_y_; + /** Feasibility threshold for recalc_y */ + Number recalc_y_feas_tol_; + /** Flag indicating if we want to do Mehrotras's algorithm. This + * means that a number of options are ignored, or have to be set + * (or are automatically set) to certain values. */ + bool mehrotra_algorithm_; + /** String specifying linear solver */ + std::string linear_solver_; + //@} + + /** @name auxiliary functions */ + //@{ + void calc_number_of_bounds( + const Vector& x, + const Vector& x_L, + const Vector& x_U, + const Matrix& Px_L, + const Matrix& Px_U, + Index& n_tot, + Index& n_only_lower, + Index& n_both, + Index& n_only_upper); + + /** Method for ensuring that the trial multipliers are not too far + * from the primal estime. If a correction is made, new_trial_z + * is a pointer to the corrected multiplier, and the return value + * of this method give the magnitutde of the largest correction + * that we done. If no correction was made, new_trial_z is just + * a pointer to trial_z, and the return value is zero. + */ + Number correct_bound_multiplier(const Vector& trial_z, + const Vector& trial_slack, + const Vector& trial_compl, + SmartPtr& new_trial_z); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpIpoptApplication.hpp b/thirdparty/linux/include/coin/IpIpoptApplication.hpp new file mode 100644 index 0000000..0febc94 --- /dev/null +++ b/thirdparty/linux/include/coin/IpIpoptApplication.hpp @@ -0,0 +1,296 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptApplication.hpp 2617 2015-11-26 16:00:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTAPPLICATION_HPP__ +#define __IPIPOPTAPPLICATION_HPP__ + +#ifndef IPOPT_EXPORT +#ifdef _MSC_VER +#ifdef IPOPT_DLL +#define IPOPT_EXPORT(type) __declspec(dllexport) type __cdecl +#else +#define IPOPT_EXPORT(type) type __cdecl +#endif +#else +#define IPOPT_EXPORT(type) type +#endif +#endif + +#include + +#include "IpJournalist.hpp" +#include "IpTNLP.hpp" +#include "IpNLP.hpp" +/* Return codes for the Optimize call for an application */ +#include "IpReturnCodes.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(IPOPT_APPLICATION_ERROR); + + /* forward declarations */ + class IpoptAlgorithm; + class IpoptNLP; + class IpoptData; + class IpoptCalculatedQuantities; + class AlgorithmBuilder; + class RegisteredOptions; + class OptionsList; + class SolveStatistics; + + /** This is the main application class for making calls to Ipopt. */ + class IpoptApplication : public ReferencedObject + { + public: + IpoptApplication(bool create_console_out = true, + bool create_empty = false); + + /** Another constructor that assumes that the code in the + * (default) constructor has already been executed */ + IpoptApplication(SmartPtr reg_options, + SmartPtr options, + SmartPtr jnlst); + + virtual ~IpoptApplication(); + + /** Method for creating a new IpoptApplication that uses the same + * journalist and registered options, and a copy of the options + list. */ + virtual SmartPtr clone(); + + /** Initialization method. This method reads options from the + * input stream and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the input stream. + */ + virtual ApplicationReturnStatus Initialize(std::istream& is, bool allow_clobber = false); + /** Initialization method. This method reads options from the + * params file and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Note: You can skip the processing of a params file by + * setting params_file to "". + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the params file. + */ + virtual ApplicationReturnStatus Initialize(std::string params_file, bool allow_clobber = false); + /** Initialization method. This method reads options from the + * params file and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Note: You can skip the processing of a params file by + * setting params_file to "". + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the params file. + */ + virtual ApplicationReturnStatus Initialize(const char* params_file, bool allow_clobber = false) + { + return Initialize(std::string(params_file), allow_clobber); + } + /** Initialize method. This method reads the options file specified + * by the option_file_name option and initializes the journalists. + * You should call this method at some point before the first optimize + * call. + * It returns something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the options file. + */ + virtual ApplicationReturnStatus Initialize(bool allow_clobber = false); + + /**@name Solve methods */ + //@{ + /** Solve a problem that inherits from TNLP */ + virtual ApplicationReturnStatus OptimizeTNLP(const SmartPtr& tnlp); + + /** Solve a problem that inherits from NLP */ + virtual ApplicationReturnStatus OptimizeNLP(const SmartPtr& nlp); + + /** Solve a problem that inherits from NLP */ + virtual ApplicationReturnStatus OptimizeNLP(const SmartPtr& nlp, SmartPtr& alg_builder); + + /** Solve a problem (that inherits from TNLP) for a repeated time. + * The OptimizeTNLP method must have been called before. The + * TNLP must be the same object, and the structure (number of + * variables and constraints and position of nonzeros in Jacobian + * and Hessian must be the same). */ + virtual ApplicationReturnStatus ReOptimizeTNLP(const SmartPtr& tnlp); + + /** Solve a problem (that inherits from NLP) for a repeated time. + * The OptimizeNLP method must have been called before. The + * NLP must be the same object, and the structure (number of + * variables and constraints and position of nonzeros in Jacobian + * and Hessian must be the same). */ + virtual ApplicationReturnStatus ReOptimizeNLP(const SmartPtr& nlp); + //@} + + /** Method for opening an output file with given print_level. + * Returns false if there was a problem. */ + virtual bool OpenOutputFile(std::string file_name, EJournalLevel print_level); + + /**@name Accessor methods */ + //@{ + /** Get the Journalist for printing output */ + virtual SmartPtr Jnlst() + { + return jnlst_; + } + + /** Get a pointer to RegisteredOptions object to + * add new options */ + virtual SmartPtr RegOptions() + { + return reg_options_; + } + + /** Get the options list for setting options */ + virtual SmartPtr Options() + { + return options_; + } + + /** Get the options list for setting options (const version) */ + virtual SmartPtr Options() const + { + return ConstPtr(options_); + } + + /** Get the object with the statistics about the most recent + * optimization run. */ + virtual SmartPtr Statistics(); + + /** Get the IpoptNLP Object */ + virtual SmartPtr IpoptNLPObject(); + + /** Get the IpoptData Object */ + SmartPtr IpoptDataObject(); + + /** Get the IpoptCQ Object */ + virtual SmartPtr IpoptCQObject(); + + /** Get the Algorithm Object */ + SmartPtr AlgorithmObject(); + //@} + + /** Method for printing Ipopt copyright message now instead of + * just before the optimization. If you want to have the copy + * right message printed earlier than by default, call this + * method at the convenient time. */ + void PrintCopyrightMessage(); + + /** Method to set whether non-ipopt non-bad_alloc exceptions + * are rethrown by Ipopt. + * By default, non-Ipopt and non-std::bad_alloc exceptions are + * caught by Ipopts initialization and optimization methods + * and the status NonIpopt_Exception_Thrown is returned. + * This function allows to enable rethrowing of such exceptions. + */ + void RethrowNonIpoptException(bool dorethrow) + { + rethrow_nonipoptexception_ = dorethrow; + } + + /** @name Methods for IpoptTypeInfo */ + //@{ + static void RegisterOptions(SmartPtr roptions); + //@} + + /** Method to registering all Ipopt options. */ + static void + RegisterAllIpoptOptions(const SmartPtr& roptions); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // IpoptApplication(); + + /** Copy Constructor */ + IpoptApplication(const IpoptApplication&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptApplication&); + //@} + + /** Method for the actual optimize call of the Ipopt algorithm. + * This is used both for Optimize and ReOptimize */ + ApplicationReturnStatus call_optimize(); + + /**@name Variables that customize the application behavior */ + //@{ + /** Decide whether or not the ipopt.opt file should be read */ + bool read_params_dat_; + + /** Decide whether non-ipopt non-bad_alloc exceptions should be rethrown */ + bool rethrow_nonipoptexception_; + //@} + + /** Journalist for reporting output */ + SmartPtr jnlst_; + + /** RegisteredOptions */ + SmartPtr reg_options_; + + /** OptionsList used for the application */ + SmartPtr options_; + + /** Object for storing statistics about the most recent + * optimization run. */ + SmartPtr statistics_; + + /** Object with the algorithm sceleton. + */ + SmartPtr alg_; + + /** IpoptNLP Object for the NLP. We keep this around for a + * ReOptimize warm start. */ + SmartPtr ip_nlp_; + + /** IpoptData Object for the NLP. We keep this around for a + * ReOptimize warm start. + */ + SmartPtr ip_data_; + + /** IpoptCalculatedQuantities Object for the NLP. We keep this + * around for a ReOptimize warm start. + */ + SmartPtr ip_cq_; + + /** Pointer to the TNLPAdapter used to convert the TNLP to an NLP. + * We keep this around for the ReOptimizerTNLP call. */ + SmartPtr nlp_adapter_; + + /** @name Algorithmic parameters */ + //@{ + /** Flag indicating if we are to use the inexact linear solver option */ + bool inexact_algorithm_; + /** Flag indicating if all bounds should be replaced by inequality + * constraints. This is necessary for the inexact algorithm. */ + bool replace_bounds_; + //@} + }; + +} // namespace Ipopt + +extern "C" IPOPT_EXPORT(class Ipopt::IpoptApplication *) IpoptApplicationFactory(); + +#endif diff --git a/thirdparty/linux/include/coin/IpIpoptCalculatedQuantities.hpp b/thirdparty/linux/include/coin/IpIpoptCalculatedQuantities.hpp new file mode 100644 index 0000000..3b60b16 --- /dev/null +++ b/thirdparty/linux/include/coin/IpIpoptCalculatedQuantities.hpp @@ -0,0 +1,751 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptCalculatedQuantities.hpp 2020 2011-06-16 20:46:16Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTCALCULATEDQUANTITIES_HPP__ +#define __IPIPOPTCALCULATEDQUANTITIES_HPP__ + +#include "IpSmartPtr.hpp" +#include "IpCachedResults.hpp" + +#include + +namespace Ipopt +{ + class IpoptNLP; + class IpoptData; + class Vector; + class Matrix; + class SymMatrix; + class Journalist; + class OptionsList; + class RegisteredOptions; + + /** Norm types */ + enum ENormType { + NORM_1=0, + NORM_2, + NORM_MAX + }; + + /** Base class for additional calculated quantities that is special + * to a particular type of algorithm, such as the CG penalty + * function, or using iterative linear solvers. The regular + * IpoptCalculatedQuantities object should be given a derivation of + * this base class when it is created. */ + class IpoptAdditionalCq : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IpoptAdditionalCq() + {} + + /** Default destructor */ + virtual ~IpoptAdditionalCq() + {} + //@} + + /** This method is called to initialize the global algorithmic + * parameters. The parameters are taken from the OptionsList + * object. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptAdditionalCq(const IpoptAdditionalCq&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAdditionalCq&); + //@} + }; + + /** Class for all IPOPT specific calculated quantities. + * + */ + class IpoptCalculatedQuantities : public ReferencedObject + { + public: + + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptCalculatedQuantities(const SmartPtr& ip_nlp, + const SmartPtr& ip_data); + /** Default destructor */ + virtual ~IpoptCalculatedQuantities(); + //@} + + /** Method for setting pointer for additional calculated + * quantities. This needs to be called before Initialized. */ + void SetAddCq(SmartPtr add_cq) + { + DBG_ASSERT(!HaveAddCq()); + add_cq_ = add_cq; + } + + /** Method detecting if additional object for calculated + * quantities has already been set */ + bool HaveAddCq() + { + return IsValid(add_cq_); + } + + /** This method must be called to initialize the global + * algorithmic parameters. The parameters are taken from the + * OptionsList object. */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** @name Slacks */ + //@{ + /** Slacks for x_L (at current iterate) */ + SmartPtr curr_slack_x_L(); + /** Slacks for x_U (at current iterate) */ + SmartPtr curr_slack_x_U(); + /** Slacks for s_L (at current iterate) */ + SmartPtr curr_slack_s_L(); + /** Slacks for s_U (at current iterate) */ + SmartPtr curr_slack_s_U(); + /** Slacks for x_L (at trial point) */ + SmartPtr trial_slack_x_L(); + /** Slacks for x_U (at trial point) */ + SmartPtr trial_slack_x_U(); + /** Slacks for s_L (at trial point) */ + SmartPtr trial_slack_s_L(); + /** Slacks for s_U (at trial point) */ + SmartPtr trial_slack_s_U(); + /** Indicating whether or not we "fudged" the slacks */ + Index AdjustedTrialSlacks(); + /** Reset the flags for "fudged" slacks */ + void ResetAdjustedTrialSlacks(); + //@} + + /** @name Objective function */ + //@{ + /** Value of objective function (at current point) */ + virtual Number curr_f(); + /** Unscaled value of the objective function (at the current point) */ + virtual Number unscaled_curr_f(); + /** Value of objective function (at trial point) */ + virtual Number trial_f(); + /** Unscaled value of the objective function (at the trial point) */ + virtual Number unscaled_trial_f(); + /** Gradient of objective function (at current point) */ + SmartPtr curr_grad_f(); + /** Gradient of objective function (at trial point) */ + SmartPtr trial_grad_f(); + //@} + + /** @name Barrier Objective Function */ + //@{ + /** Barrier Objective Function Value + * (at current iterate with current mu) + */ + virtual Number curr_barrier_obj(); + /** Barrier Objective Function Value + * (at trial point with current mu) + */ + virtual Number trial_barrier_obj(); + + /** Gradient of barrier objective function with respect to x + * (at current point with current mu) */ + SmartPtr curr_grad_barrier_obj_x(); + /** Gradient of barrier objective function with respect to s + * (at current point with current mu) */ + SmartPtr curr_grad_barrier_obj_s(); + + /** Gradient of the damping term with respect to x (times + * kappa_d) */ + SmartPtr grad_kappa_times_damping_x(); + /** Gradient of the damping term with respect to s (times + * kappa_d) */ + SmartPtr grad_kappa_times_damping_s(); + //@} + + /** @name Constraints */ + //@{ + /** c(x) (at current point) */ + SmartPtr curr_c(); + /** unscaled c(x) (at current point) */ + SmartPtr unscaled_curr_c(); + /** c(x) (at trial point) */ + SmartPtr trial_c(); + /** unscaled c(x) (at trial point) */ + SmartPtr unscaled_trial_c(); + /** d(x) (at current point) */ + SmartPtr curr_d(); + /** unscaled d(x) (at current point) */ + SmartPtr unscaled_curr_d(); + /** d(x) (at trial point) */ + SmartPtr trial_d(); + /** d(x) - s (at current point) */ + SmartPtr curr_d_minus_s(); + /** d(x) - s (at trial point) */ + SmartPtr trial_d_minus_s(); + /** Jacobian of c (at current point) */ + SmartPtr curr_jac_c(); + /** Jacobian of c (at trial point) */ + SmartPtr trial_jac_c(); + /** Jacobian of d (at current point) */ + SmartPtr curr_jac_d(); + /** Jacobian of d (at trial point) */ + SmartPtr trial_jac_d(); + /** Product of Jacobian (evaluated at current point) of C + * transpose with general vector */ + SmartPtr curr_jac_cT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at trial point) of C + * transpose with general vector */ + SmartPtr trial_jac_cT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of D + * transpose with general vector */ + SmartPtr curr_jac_dT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at trial point) of D + * transpose with general vector */ + SmartPtr trial_jac_dT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of C + * transpose with current y_c */ + SmartPtr curr_jac_cT_times_curr_y_c(); + /** Product of Jacobian (evaluated at trial point) of C + * transpose with trial y_c */ + SmartPtr trial_jac_cT_times_trial_y_c(); + /** Product of Jacobian (evaluated at current point) of D + * transpose with current y_d */ + SmartPtr curr_jac_dT_times_curr_y_d(); + /** Product of Jacobian (evaluated at trial point) of D + * transpose with trial y_d */ + SmartPtr trial_jac_dT_times_trial_y_d(); + /** Product of Jacobian (evaluated at current point) of C + * with general vector */ + SmartPtr curr_jac_c_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of D + * with general vector */ + SmartPtr curr_jac_d_times_vec(const Vector& vec); + /** Constraint Violation (at current iterate). This value should + * be used in the line search, and not curr_primal_infeasibility(). + * What type of norm is used depends on constr_viol_normtype */ + virtual Number curr_constraint_violation(); + /** Constraint Violation (at trial point). This value should + * be used in the line search, and not curr_primal_infeasibility(). + * What type of norm is used depends on constr_viol_normtype */ + virtual Number trial_constraint_violation(); + /** Real constraint violation in a given norm (at current + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number curr_nlp_constraint_violation(ENormType NormType); + /** Unscaled real constraint violation in a given norm (at current + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number unscaled_curr_nlp_constraint_violation(ENormType NormType); + /** Unscaled real constraint violation in a given norm (at trial + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number unscaled_trial_nlp_constraint_violation(ENormType NormType); + //@} + + /** @name Hessian matrices */ + //@{ + /** exact Hessian at current iterate (uncached) */ + SmartPtr curr_exact_hessian(); + //@} + + /** @name primal-dual error and its components */ + //@{ + /** x-part of gradient of Lagrangian function (at current point) */ + SmartPtr curr_grad_lag_x(); + /** x-part of gradient of Lagrangian function (at trial point) */ + SmartPtr trial_grad_lag_x(); + /** s-part of gradient of Lagrangian function (at current point) */ + SmartPtr curr_grad_lag_s(); + /** s-part of gradient of Lagrangian function (at trial point) */ + SmartPtr trial_grad_lag_s(); + /** x-part of gradient of Lagrangian function (at current point) + including linear damping term */ + SmartPtr curr_grad_lag_with_damping_x(); + /** s-part of gradient of Lagrangian function (at current point) + including linear damping term */ + SmartPtr curr_grad_lag_with_damping_s(); + /** Complementarity for x_L (for current iterate) */ + SmartPtr curr_compl_x_L(); + /** Complementarity for x_U (for current iterate) */ + SmartPtr curr_compl_x_U(); + /** Complementarity for s_L (for current iterate) */ + SmartPtr curr_compl_s_L(); + /** Complementarity for s_U (for current iterate) */ + SmartPtr curr_compl_s_U(); + /** Complementarity for x_L (for trial iterate) */ + SmartPtr trial_compl_x_L(); + /** Complementarity for x_U (for trial iterate) */ + SmartPtr trial_compl_x_U(); + /** Complementarity for s_L (for trial iterate) */ + SmartPtr trial_compl_s_L(); + /** Complementarity for s_U (for trial iterate) */ + SmartPtr trial_compl_s_U(); + /** Relaxed complementarity for x_L (for current iterate and current mu) */ + SmartPtr curr_relaxed_compl_x_L(); + /** Relaxed complementarity for x_U (for current iterate and current mu) */ + SmartPtr curr_relaxed_compl_x_U(); + /** Relaxed complementarity for s_L (for current iterate and current mu) */ + SmartPtr curr_relaxed_compl_s_L(); + /** Relaxed complementarity for s_U (for current iterate and current mu) */ + SmartPtr curr_relaxed_compl_s_U(); + + /** Primal infeasibility in a given norm (at current iterate). */ + virtual Number curr_primal_infeasibility(ENormType NormType); + /** Primal infeasibility in a given norm (at trial point) */ + virtual Number trial_primal_infeasibility(ENormType NormType); + + /** Dual infeasibility in a given norm (at current iterate) */ + virtual Number curr_dual_infeasibility(ENormType NormType); + /** Dual infeasibility in a given norm (at trial iterate) */ + virtual Number trial_dual_infeasibility(ENormType NormType); + /** Unscaled dual infeasibility in a given norm (at current iterate) */ + virtual Number unscaled_curr_dual_infeasibility(ENormType NormType); + + /** Complementarity (for all complementarity conditions together) + * in a given norm (at current iterate) */ + virtual Number curr_complementarity(Number mu, ENormType NormType); + /** Complementarity (for all complementarity conditions together) + * in a given norm (at trial iterate) */ + virtual Number trial_complementarity(Number mu, ENormType NormType); + /** Complementarity (for all complementarity conditions together) + * in a given norm (at current iterate) without NLP scaling. */ + virtual Number unscaled_curr_complementarity(Number mu, ENormType NormType); + + /** Centrality measure (in spirit of the -infinity-neighborhood. */ + Number CalcCentralityMeasure(const Vector& compl_x_L, + const Vector& compl_x_U, + const Vector& compl_s_L, + const Vector& compl_s_U); + /** Centrality measure at current point */ + virtual Number curr_centrality_measure(); + + /** Total optimality error for the original NLP at the current + * iterate, using scaling factors based on multipliers. Note + * that here the constraint violation is measured without slacks + * (nlp_constraint_violation) */ + virtual Number curr_nlp_error(); + /** Total optimality error for the original NLP at the current + * iterate, but using no scaling based on multipliers, and no + * scaling for the NLP. Note that here the constraint violation + * is measured without slacks (nlp_constraint_violation) */ + virtual Number unscaled_curr_nlp_error(); + + /** Total optimality error for the barrier problem at the + * current iterate, using scaling factors based on multipliers. */ + virtual Number curr_barrier_error(); + + /** Norm of the primal-dual system for a given mu (at current + * iterate). The norm is defined as the sum of the 1-norms of + * dual infeasibiliy, primal infeasibility, and complementarity, + * all divided by the number of elements of the vectors of which + * the norm is taken. + */ + virtual Number curr_primal_dual_system_error(Number mu); + /** Norm of the primal-dual system for a given mu (at trial + * iterate). The norm is defined as the sum of the 1-norms of + * dual infeasibiliy, primal infeasibility, and complementarity, + * all divided by the number of elements of the vectors of which + * the norm is taken. + */ + virtual Number trial_primal_dual_system_error(Number mu); + //@} + + /** @name Computing fraction-to-the-boundary step sizes */ + //@{ + /** Fraction to the boundary from (current) primal variables x and s + * for a given step */ + Number primal_frac_to_the_bound(Number tau, + const Vector& delta_x, + const Vector& delta_s); + /** Fraction to the boundary from (current) primal variables x and s + * for internal (current) step */ + Number curr_primal_frac_to_the_bound(Number tau); + /** Fraction to the boundary from (current) dual variables z and v + * for a given step */ + Number dual_frac_to_the_bound(Number tau, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + /** Fraction to the boundary from (current) dual variables z and v + * for a given step, without caching */ + Number uncached_dual_frac_to_the_bound(Number tau, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + /** Fraction to the boundary from (current) dual variables z and v + * for internal (current) step */ + Number curr_dual_frac_to_the_bound(Number tau); + /** Fraction to the boundary from (current) slacks for a given + * step in the slacks. Usually, one will use the + * primal_frac_to_the_bound method to compute the primal fraction + * to the boundary step size, but if it is cheaper to provide the + * steps in the slacks directly (e.g. when the primal step sizes + * are only temporary), the this method is more efficient. This + * method does not cache computations. */ + Number uncached_slack_frac_to_the_bound(Number tau, + const Vector& delta_x_L, + const Vector& delta_x_U, + const Vector& delta_s_L, + const Vector& delta_s_U); + //@} + + /** @name Sigma matrices */ + //@{ + SmartPtr curr_sigma_x(); + SmartPtr curr_sigma_s(); + //@} + + /** average of current values of the complementarities */ + Number curr_avrg_compl(); + /** average of trial values of the complementarities */ + Number trial_avrg_compl(); + + /** inner_product of current barrier obj. fn. gradient with + * current search direction */ + Number curr_gradBarrTDelta(); + + /** Compute the norm of a specific type of a set of vectors (uncached) */ + Number + CalcNormOfType(ENormType NormType, + std::vector > vecs); + + /** Compute the norm of a specific type of two vectors (uncached) */ + Number + CalcNormOfType(ENormType NormType, + const Vector& vec1, const Vector& vec2); + + /** Norm type used for calculating constraint violation */ + ENormType constr_viol_normtype() const + { + return constr_viol_normtype_; + } + + /** Method returning true if this is a square problem */ + bool IsSquareProblem() const; + + /** Method returning the IpoptNLP object. This should only be + * used with care! */ + SmartPtr& GetIpoptNLP() + { + return ip_nlp_; + } + + IpoptAdditionalCq& AdditionalCq() + { + DBG_ASSERT(IsValid(add_cq_)); + return *add_cq_; + } + + /** Methods for IpoptType */ + //@{ + /** Called by IpoptType to register the options */ + static void RegisterOptions(SmartPtr roptions); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptCalculatedQuantities(); + + /** Copy Constructor */ + IpoptCalculatedQuantities(const IpoptCalculatedQuantities&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptCalculatedQuantities&); + //@} + + /** @name Pointers for easy access to data and NLP information */ + //@{ + /** Ipopt NLP object */ + SmartPtr ip_nlp_; + /** Ipopt Data object */ + SmartPtr ip_data_; + /** Chen-Goldfarb specific calculated quantities */ + SmartPtr add_cq_; + //@} + + /** @name Algorithmic Parameters that can be set throught the + * options list. Those parameters are initialize by calling the + * Initialize method.*/ + //@{ + /** Parameter in formula for computing overall primal-dual + * optimality error */ + Number s_max_; + /** Weighting factor for the linear damping term added to the + * barrier objective funciton. */ + Number kappa_d_; + /** fractional movement allowed in bounds */ + Number slack_move_; + /** Norm type to be used when calculating the constraint violation */ + ENormType constr_viol_normtype_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Desired value of the barrier parameter */ + Number mu_target_; + //@} + + /** @name Caches for slacks */ + //@{ + CachedResults< SmartPtr > curr_slack_x_L_cache_; + CachedResults< SmartPtr > curr_slack_x_U_cache_; + CachedResults< SmartPtr > curr_slack_s_L_cache_; + CachedResults< SmartPtr > curr_slack_s_U_cache_; + CachedResults< SmartPtr > trial_slack_x_L_cache_; + CachedResults< SmartPtr > trial_slack_x_U_cache_; + CachedResults< SmartPtr > trial_slack_s_L_cache_; + CachedResults< SmartPtr > trial_slack_s_U_cache_; + Index num_adjusted_slack_x_L_; + Index num_adjusted_slack_x_U_; + Index num_adjusted_slack_s_L_; + Index num_adjusted_slack_s_U_; + //@} + + /** @name Cached for objective function stuff */ + //@{ + CachedResults curr_f_cache_; + CachedResults trial_f_cache_; + CachedResults< SmartPtr > curr_grad_f_cache_; + CachedResults< SmartPtr > trial_grad_f_cache_; + //@} + + /** @name Caches for barrier function stuff */ + //@{ + CachedResults curr_barrier_obj_cache_; + CachedResults trial_barrier_obj_cache_; + CachedResults< SmartPtr > curr_grad_barrier_obj_x_cache_; + CachedResults< SmartPtr > curr_grad_barrier_obj_s_cache_; + CachedResults< SmartPtr > grad_kappa_times_damping_x_cache_; + CachedResults< SmartPtr > grad_kappa_times_damping_s_cache_; + //@} + + /** @name Caches for constraint stuff */ + //@{ + CachedResults< SmartPtr > curr_c_cache_; + CachedResults< SmartPtr > trial_c_cache_; + CachedResults< SmartPtr > curr_d_cache_; + CachedResults< SmartPtr > trial_d_cache_; + CachedResults< SmartPtr > curr_d_minus_s_cache_; + CachedResults< SmartPtr > trial_d_minus_s_cache_; + CachedResults< SmartPtr > curr_jac_c_cache_; + CachedResults< SmartPtr > trial_jac_c_cache_; + CachedResults< SmartPtr > curr_jac_d_cache_; + CachedResults< SmartPtr > trial_jac_d_cache_; + CachedResults< SmartPtr > curr_jac_cT_times_vec_cache_; + CachedResults< SmartPtr > trial_jac_cT_times_vec_cache_; + CachedResults< SmartPtr > curr_jac_dT_times_vec_cache_; + CachedResults< SmartPtr > trial_jac_dT_times_vec_cache_; + CachedResults< SmartPtr > curr_jac_c_times_vec_cache_; + CachedResults< SmartPtr > curr_jac_d_times_vec_cache_; + CachedResults curr_constraint_violation_cache_; + CachedResults trial_constraint_violation_cache_; + CachedResults curr_nlp_constraint_violation_cache_; + CachedResults unscaled_curr_nlp_constraint_violation_cache_; + CachedResults unscaled_trial_nlp_constraint_violation_cache_; + //@} + + /** Cache for the exact Hessian */ + CachedResults< SmartPtr > curr_exact_hessian_cache_; + + /** @name Components of primal-dual error */ + //@{ + CachedResults< SmartPtr > curr_grad_lag_x_cache_; + CachedResults< SmartPtr > trial_grad_lag_x_cache_; + CachedResults< SmartPtr > curr_grad_lag_s_cache_; + CachedResults< SmartPtr > trial_grad_lag_s_cache_; + CachedResults< SmartPtr > curr_grad_lag_with_damping_x_cache_; + CachedResults< SmartPtr > curr_grad_lag_with_damping_s_cache_; + CachedResults< SmartPtr > curr_compl_x_L_cache_; + CachedResults< SmartPtr > curr_compl_x_U_cache_; + CachedResults< SmartPtr > curr_compl_s_L_cache_; + CachedResults< SmartPtr > curr_compl_s_U_cache_; + CachedResults< SmartPtr > trial_compl_x_L_cache_; + CachedResults< SmartPtr > trial_compl_x_U_cache_; + CachedResults< SmartPtr > trial_compl_s_L_cache_; + CachedResults< SmartPtr > trial_compl_s_U_cache_; + CachedResults< SmartPtr > curr_relaxed_compl_x_L_cache_; + CachedResults< SmartPtr > curr_relaxed_compl_x_U_cache_; + CachedResults< SmartPtr > curr_relaxed_compl_s_L_cache_; + CachedResults< SmartPtr > curr_relaxed_compl_s_U_cache_; + CachedResults curr_primal_infeasibility_cache_; + CachedResults trial_primal_infeasibility_cache_; + CachedResults curr_dual_infeasibility_cache_; + CachedResults trial_dual_infeasibility_cache_; + CachedResults unscaled_curr_dual_infeasibility_cache_; + CachedResults curr_complementarity_cache_; + CachedResults trial_complementarity_cache_; + CachedResults curr_centrality_measure_cache_; + CachedResults curr_nlp_error_cache_; + CachedResults unscaled_curr_nlp_error_cache_; + CachedResults curr_barrier_error_cache_; + CachedResults curr_primal_dual_system_error_cache_; + CachedResults trial_primal_dual_system_error_cache_; + //@} + + /** @name Caches for fraction to the boundary step sizes */ + //@{ + CachedResults primal_frac_to_the_bound_cache_; + CachedResults dual_frac_to_the_bound_cache_; + //@} + + /** @name Caches for sigma matrices */ + //@{ + CachedResults< SmartPtr > curr_sigma_x_cache_; + CachedResults< SmartPtr > curr_sigma_s_cache_; + //@} + + /** Cache for average of current complementarity */ + CachedResults curr_avrg_compl_cache_; + /** Cache for average of trial complementarity */ + CachedResults trial_avrg_compl_cache_; + + /** Cache for grad barrier obj. fn inner product with step */ + CachedResults curr_gradBarrTDelta_cache_; + + /** @name Indicator vectors required for the linear damping terms + * to handle unbounded solution sets. */ + //@{ + /** Indicator vector for selecting the elements in x that have + * only lower bounds. */ + SmartPtr dampind_x_L_; + /** Indicator vector for selecting the elements in x that have + * only upper bounds. */ + SmartPtr dampind_x_U_; + /** Indicator vector for selecting the elements in s that have + * only lower bounds. */ + SmartPtr dampind_s_L_; + /** Indicator vector for selecting the elements in s that have + * only upper bounds. */ + SmartPtr dampind_s_U_; + //@} + + /** @name Temporary vectors for intermediate calcuations. We keep + * these around to avoid unnecessarily many new allocations of + * Vectors. */ + //@{ + SmartPtr tmp_x_; + SmartPtr tmp_s_; + SmartPtr tmp_c_; + SmartPtr tmp_d_; + SmartPtr tmp_x_L_; + SmartPtr tmp_x_U_; + SmartPtr tmp_s_L_; + SmartPtr tmp_s_U_; + + /** Accessor methods for the temporary vectors */ + Vector& Tmp_x(); + Vector& Tmp_s(); + Vector& Tmp_c(); + Vector& Tmp_d(); + Vector& Tmp_x_L(); + Vector& Tmp_x_U(); + Vector& Tmp_s_L(); + Vector& Tmp_s_U(); + //@} + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + + /** @name Auxiliary functions */ + //@{ + /** Compute new vector containing the slack to a lower bound + * (uncached) + */ + SmartPtr CalcSlack_L(const Matrix& P, + const Vector& x, + const Vector& x_bound); + /** Compute new vector containing the slack to a upper bound + * (uncached) + */ + SmartPtr CalcSlack_U(const Matrix& P, + const Vector& x, + const Vector& x_bound); + /** Compute barrier term at given point + * (uncached) + */ + Number CalcBarrierTerm(Number mu, + const Vector& slack_x_L, + const Vector& slack_x_U, + const Vector& slack_s_L, + const Vector& slack_s_U); + + /** Compute complementarity for slack / multiplier pair */ + SmartPtr CalcCompl(const Vector& slack, + const Vector& mult); + + /** Compute fraction to the boundary parameter for lower and upper bounds */ + Number CalcFracToBound(const Vector& slack_L, + Vector& tmp_L, + const Matrix& P_L, + const Vector& slack_U, + Vector& tmp_U, + const Matrix& P_U, + const Vector& delta, + Number tau); + + /** Compute the scaling factors for the optimality error. */ + void ComputeOptimalityErrorScaling(const Vector& y_c, const Vector& y_d, + const Vector& z_L, const Vector& z_U, + const Vector& v_L, const Vector& v_U, + Number s_max, + Number& s_d, Number& s_c); + + /** Check if slacks are becoming too small. If slacks are + * becoming too small, they are change. The return value is the + * number of corrected slacks. */ + Index CalculateSafeSlack(SmartPtr& slack, + const SmartPtr& bound, + const SmartPtr& curr_point, + const SmartPtr& multiplier); + + /** Computes the indicator vectors that can be used to filter out + * those entries in the slack_... variables, that correspond to + * variables with only lower and upper bounds. This is required + * for the linear damping term in the barrier objective function + * to handle unbounded solution sets. */ + void ComputeDampingIndicators(SmartPtr& dampind_x_L, + SmartPtr& dampind_x_U, + SmartPtr& dampind_s_L, + SmartPtr& dampind_s_U); + + /** Check if we are in the restoration phase. Returns true, if the + * ip_nlp is of the type RestoIpoptNLP. ToDo: We probably want to + * handle this more elegant and don't have an explicit dependency + * here. Now I added this because otherwise the caching doesn't + * work properly since the restoration phase objective function + * depends on the current barrier parameter. */ + bool in_restoration_phase(); + + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpIpoptData.hpp b/thirdparty/linux/include/coin/IpIpoptData.hpp new file mode 100644 index 0000000..6973bab --- /dev/null +++ b/thirdparty/linux/include/coin/IpIpoptData.hpp @@ -0,0 +1,819 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptData.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTDATA_HPP__ +#define __IPIPOPTDATA_HPP__ + +#include "IpSymMatrix.hpp" +#include "IpOptionsList.hpp" +#include "IpIteratesVector.hpp" +#include "IpRegOptions.hpp" +#include "IpTimingStatistics.hpp" + +namespace Ipopt +{ + + /* Forward declaration */ + class IpoptNLP; + + /** Base class for additional data that is special to a particular + * type of algorithm, such as the CG penalty function, or using + * iterative linear solvers. The regular IpoptData object should + * be given a derivation of this base class when it is created. */ + class IpoptAdditionalData : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IpoptAdditionalData() + {} + + /** Default destructor */ + virtual ~IpoptAdditionalData() + {} + //@} + + /** This method is called to initialize the global algorithmic + * parameters. The parameters are taken from the OptionsList + * object. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) = 0; + + /** Initialize Data Structures at the beginning. */ + virtual bool InitializeDataStructures() = 0; + + /** Do whatever is necessary to accept a trial point as current + * iterate. This is also used to finish an iteration, i.e., to + * release memory, and to reset any flags for a new iteration. */ + virtual void AcceptTrialPoint() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptAdditionalData(const IpoptAdditionalData&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAdditionalData&); + //@} + }; + + /** Class to organize all the data required by the algorithm. + * Internally, once this Data object has been initialized, all + * internal curr_ vectors must always be set (so that prototyes are + * available). The current values can only be set from the trial + * values. The trial values can be set by copying from a vector or + * by adding some fraction of a step to the current values. This + * object also stores steps, which allows to easily communicate the + * step from the step computation object to the line search object. + */ + class IpoptData : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptData(SmartPtr add_data = NULL, + Number cpu_time_start = -1.); + + /** Default destructor */ + virtual ~IpoptData(); + //@} + + /** Initialize Data Structures */ + bool InitializeDataStructures(IpoptNLP& ip_nlp, + bool want_x, + bool want_y_c, + bool want_y_d, + bool want_z_L, + bool want_z_U); + + /** This method must be called to initialize the global + * algorithmic parameters. The parameters are taken from the + * OptionsList object. */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** @name Get Methods for Iterates */ + //@{ + /** Current point */ + inline + SmartPtr curr() const; + + /** Get the current point in a copied container that is non-const. + The entries in the container cannot be modified, but + the container can be modified to point to new entries. + */ + // SmartPtr curr_container() const; + + /** Get Trial point */ + inline + SmartPtr trial() const; + + /** Get Trial point in a copied container that is non-const. + * The entries in the container can not be modified, but + * the container can be modified to point to new entries. + */ + //SmartPtr trial_container() const; + + /** Set the trial point - this method copies the pointer for + * efficiency (no copy and to keep cache tags the same) so + * after you call set you cannot modify the data again + */ + inline + void set_trial(SmartPtr& trial); + + /** Set the values of the primal trial variables (x and s) from + * provided Step with step length alpha. + */ + void SetTrialPrimalVariablesFromStep(Number alpha, + const Vector& delta_x, + const Vector& delta_s); + /** Set the values of the trial values for the equality constraint + * multipliers (y_c and y_d) from provided step with step length + * alpha. + */ + void SetTrialEqMultipliersFromStep(Number alpha, + const Vector& delta_y_c, + const Vector& delta_y_d); + /** Set the value of the trial values for the bound multipliers + * (z_L, z_U, v_L, v_U) from provided step with step length + * alpha. + */ + void SetTrialBoundMultipliersFromStep(Number alpha, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + + /** ToDo: I may need to add versions of set_trial like the + * following, but I am not sure + */ + // void set_trial(const SmartPtr& trial_iterates); + // void set_trial(SmartPtr& trial_iterates); + + /** get the current delta */ + inline + SmartPtr delta() const; + + /** Set the current delta - like the trial point, this method copies + * the pointer for efficiency (no copy and to keep cache tags the + * same) so after you call set, you cannot modify the data + */ + inline + void set_delta(SmartPtr& delta); + + /** Set the current delta - like the trial point, this method + * copies the pointer for efficiency (no copy and to keep cache + * tags the same) so after you call set, you cannot modify the + * data. This is the version that is happy with a pointer to + * const IteratesVector. + */ + inline + void set_delta(SmartPtr& delta); + + /** Affine Delta */ + inline + SmartPtr delta_aff() const; + + /** Set the affine delta - like the trial point, this method copies + * the pointer for efficiency (no copy and to keep cache tags the + * same) so after you call set, you cannot modify the data + */ + inline + void set_delta_aff(SmartPtr& delta_aff); + + /** Hessian or Hessian approximation (do not hold on to it, it might be changed) */ + SmartPtr W() + { + DBG_ASSERT(IsValid(W_)); + return W_; + } + + /** Set Hessian approximation */ + void Set_W(SmartPtr W) + { + W_ = W; + } + + /** @name ("Main") Primal-dual search direction. Those fields are + * used to store the search directions computed from solving the + * primal-dual system, and can be used in the line search. They + * are overwritten in every iteration, so do not hold on to the + * pointers (make copies instead) */ + //@{ + + /** Returns true, if the primal-dual step have been already + * computed for the current iteration. This flag is reset after + * every call of AcceptTrialPoint(). If the search direction is + * computed during the computation of the barrier parameter, the + * method computing the barrier parameter should call + * SetHaveDeltas(true) to tell the IpoptAlgorithm object that it + * doesn't need to recompute the primal-dual step. */ + bool HaveDeltas() const + { + return have_deltas_; + } + + /** Method for setting the HaveDeltas flag. This method should be + * called if some method computes the primal-dual step (and + * stores it in the delta_ fields of IpoptData) at an early part + * of the iteration. If that flag is set to true, the + * IpoptAlgorithm object will not recompute the step. */ + void SetHaveDeltas(bool have_deltas) + { + have_deltas_ = have_deltas; + } + //@} + + /** @name Affine-scaling step. Those fields can be used to store + * the affine scaling step. For example, if the method for + * computing the current barrier parameter computes the affine + * scaling steps, then the corrector step in the line search does + * not have to recompute those solutions of the linear system. */ + //@{ + + /** Returns true, if the affine-scaling step have been already + * computed for the current iteration. This flag is reset after + * every call of AcceptTrialPoint(). If the search direction is + * computed during the computation of the barrier parameter, the + * method computing the barrier parameter should call + * SetHaveDeltas(true) to tell the line search does not have to + * recompute them in case it wants to do a corrector step. */ + bool HaveAffineDeltas() const + { + return have_affine_deltas_; + } + + /** Method for setting the HaveDeltas flag. This method should be + * called if some method computes the primal-dual step (and + * stores it in the delta_ fields of IpoptData) at an early part + * of the iteration. If that flag is set to true, the + * IpoptAlgorithm object will not recompute the step. */ + void SetHaveAffineDeltas(bool have_affine_deltas) + { + have_affine_deltas_ = have_affine_deltas; + } + //@} + + /** @name Public Methods for updating iterates */ + //@{ + /** Copy the trial values to the current values */ + inline + void CopyTrialToCurrent(); + + /** Set the current iterate values from the + * trial values. */ + void AcceptTrialPoint(); + //@} + + /** @name General algorithmic data */ + //@{ + Index iter_count() const + { + return iter_count_; + } + void Set_iter_count(Index iter_count) + { + iter_count_ = iter_count; + } + + Number curr_mu() const + { + DBG_ASSERT(mu_initialized_); + return curr_mu_; + } + void Set_mu(Number mu) + { + curr_mu_ = mu; + mu_initialized_ = true; + } + bool MuInitialized() const + { + return mu_initialized_; + } + + Number curr_tau() const + { + DBG_ASSERT(tau_initialized_); + return curr_tau_; + } + void Set_tau(Number tau) + { + curr_tau_ = tau; + tau_initialized_ = true; + } + bool TauInitialized() const + { + return tau_initialized_; + } + + void SetFreeMuMode(bool free_mu_mode) + { + free_mu_mode_ = free_mu_mode; + } + bool FreeMuMode() const + { + return free_mu_mode_; + } + + /** Setting the flag that indicates if a tiny step (below machine + * precision) has been detected */ + void Set_tiny_step_flag(bool flag) + { + tiny_step_flag_ = flag; + } + bool tiny_step_flag() + { + return tiny_step_flag_; + } + //@} + + /** Overall convergence tolerance. It is used in the convergence + * test, but also in some other parts of the algorithm that + * depend on the specified tolerance, such as the minimum value + * for the barrier parameter. */ + //@{ + /** Obtain the tolerance. */ + Number tol() const + { + DBG_ASSERT(initialize_called_); + return tol_; + } + /** Set a new value for the tolerance. One should be very careful + * when using this, since changing the predefined tolerance might + * have unexpected consequences. This method is for example used + * in the restoration convergence checker to tighten the + * restoration phase convergence tolerance, if the restoration + * phase converged to a point that has not a large value for the + * constraint violation. */ + void Set_tol(Number tol) + { + tol_ = tol; + } + //@} + + /** Cpu time counter at the beginning of the optimization. This + * is useful to see how much CPU time has been spent in this + * optimization run. */ + Number cpu_time_start() const + { + return cpu_time_start_; + } + + /** @name Information gathered for iteration output */ + //@{ + Number info_regu_x() const + { + return info_regu_x_; + } + void Set_info_regu_x(Number regu_x) + { + info_regu_x_ = regu_x; + } + Number info_alpha_primal() const + { + return info_alpha_primal_; + } + void Set_info_alpha_primal(Number alpha_primal) + { + info_alpha_primal_ = alpha_primal; + } + char info_alpha_primal_char() const + { + return info_alpha_primal_char_; + } + void Set_info_alpha_primal_char(char info_alpha_primal_char) + { + info_alpha_primal_char_ = info_alpha_primal_char; + } + Number info_alpha_dual() const + { + return info_alpha_dual_; + } + void Set_info_alpha_dual(Number alpha_dual) + { + info_alpha_dual_ = alpha_dual; + } + Index info_ls_count() const + { + return info_ls_count_; + } + void Set_info_ls_count(Index ls_count) + { + info_ls_count_ = ls_count; + } + bool info_skip_output() const + { + return info_skip_output_; + } + void Append_info_string(const std::string& add_str) + { + info_string_ += add_str; + } + const std::string& info_string() const + { + return info_string_; + } + /** Set this to true, if the next time when output is written, the + * summary line should not be printed. */ + void Set_info_skip_output(bool info_skip_output) + { + info_skip_output_ = info_skip_output; + } + + /** gives time when the last summary output line was printed */ + Number info_last_output() + { + return info_last_output_; + } + /** sets time when the last summary output line was printed */ + void Set_info_last_output(Number info_last_output) + { + info_last_output_ = info_last_output; + } + + /** gives number of iteration summaries actually printed + * since last summary header was printed */ + int info_iters_since_header() + { + return info_iters_since_header_; + } + /** increases number of iteration summaries actually printed + * since last summary header was printed */ + void Inc_info_iters_since_header() + { + info_iters_since_header_++; + } + /** sets number of iteration summaries actually printed + * since last summary header was printed */ + void Set_info_iters_since_header(int info_iters_since_header) + { + info_iters_since_header_ = info_iters_since_header; + } + + /** Reset all info fields */ + void ResetInfo() + { + info_regu_x_ = 0; + info_alpha_primal_ = 0; + info_alpha_dual_ = 0.; + info_alpha_primal_char_ = ' '; + info_skip_output_ = false; + info_string_.erase(); + } + //@} + + /** Return Timing Statistics Object */ + TimingStatistics& TimingStats() + { + return timing_statistics_; + } + + /** Check if additional data has been set */ + bool HaveAddData() + { + return IsValid(add_data_); + } + + /** Get access to additional data object */ + IpoptAdditionalData& AdditionalData() + { + return *add_data_; + } + + /** Set a new pointer for additional Ipopt data */ + void SetAddData(SmartPtr add_data) + { + DBG_ASSERT(!HaveAddData()); + add_data_ = add_data; + } + + /** Set the perturbation of the primal-dual system */ + void setPDPert(Number pd_pert_x, Number pd_pert_s, + Number pd_pert_c, Number pd_pert_d) + { + pd_pert_x_ = pd_pert_x; + pd_pert_s_ = pd_pert_s; + pd_pert_c_ = pd_pert_c; + pd_pert_d_ = pd_pert_d; + } + + /** Get the current perturbation of the primal-dual system */ + void getPDPert(Number& pd_pert_x, Number& pd_pert_s, + Number& pd_pert_c, Number& pd_pert_d) + { + pd_pert_x = pd_pert_x_; + pd_pert_s = pd_pert_s_; + pd_pert_c = pd_pert_c_; + pd_pert_d = pd_pert_d_; + } + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(const SmartPtr& roptions); + //@} + + private: + /** @name Iterates */ + //@{ + /** Main iteration variables + * (current iteration) */ + SmartPtr curr_; + + /** Main iteration variables + * (trial calculations) */ + SmartPtr trial_; + + /** Hessian (approximation) - might be changed elsewhere! */ + SmartPtr W_; + + /** @name Primal-dual Step */ + //@{ + SmartPtr delta_; + /** The following flag is set to true, if some other part of the + * algorithm (like the method for computing the barrier + * parameter) has already computed the primal-dual search + * direction. This flag is reset when the AcceptTrialPoint + * method is called. + * ToDo: we could cue off of a null delta_; + */ + bool have_deltas_; + //@} + + /** @name Affine-scaling step. This used to transfer the + * information about the affine-scaling step from the computation + * of the barrier parameter to the corrector (in the line + * search). */ + //@{ + SmartPtr delta_aff_; + /** The following flag is set to true, if some other part of the + * algorithm (like the method for computing the barrier + * parameter) has already computed the affine-scaling step. This + * flag is reset when the AcceptTrialPoint method is called. + * ToDo: we could cue off of a null delta_aff_; + */ + bool have_affine_deltas_; + //@} + + /** iteration count */ + Index iter_count_; + + /** current barrier parameter */ + Number curr_mu_; + bool mu_initialized_; + + /** current fraction to the boundary parameter */ + Number curr_tau_; + bool tau_initialized_; + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + + /** flag for debugging whether we have already curr_ values + * available (from which new Vectors can be generated */ + bool have_prototypes_; + + /** @name Global algorithm parameters. Those are options that can + * be modified by the user and appear at different places in the + * algorithm. They are set using an OptionsList object in the + * Initialize method. */ + //@{ + /** Overall convergence tolerance */ + Number tol_; + //@} + + /** @name Status data **/ + //@{ + /** flag indicating whether the algorithm is in the free mu mode */ + bool free_mu_mode_; + /** flag indicating if a tiny step has been detected */ + bool tiny_step_flag_; + //@} + + /** @name Gathered information for iteration output */ + //@{ + /** Size of regularization for the Hessian */ + Number info_regu_x_; + /** Primal step size */ + Number info_alpha_primal_; + /** Info character for primal step size */ + char info_alpha_primal_char_; + /** Dual step size */ + Number info_alpha_dual_; + /** Number of backtracking trial steps */ + Index info_ls_count_; + /** true, if next summary output line should not be printed (eg + * after restoration phase. */ + bool info_skip_output_; + /** any string of characters for the end of the output line */ + std::string info_string_; + /** time when the last summary output line was printed */ + Number info_last_output_; + /** number of iteration summaries actually printed since last + * summary header was printed */ + int info_iters_since_header_; + //@} + + /** VectorSpace for all the iterates */ + SmartPtr iterates_space_; + + /** TimingStatistics object collecting all Ipopt timing + * statistics */ + TimingStatistics timing_statistics_; + + /** CPU time counter at initialization. */ + Number cpu_time_start_; + + /** Object for the data specific for the Chen-Goldfarb penalty + * method algorithm */ + SmartPtr add_data_; + + /** @name Information about the perturbation of the primal-dual + * system */ + //@{ + Number pd_pert_x_; + Number pd_pert_s_; + Number pd_pert_c_; + Number pd_pert_d_; + //@} + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptData(const IpoptData&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptData&); + //@} + +#if COIN_IPOPT_CHECKLEVEL > 0 + /** Some debug flags to make sure vectors are not changed + * behind the IpoptData's back + */ + //@{ + TaggedObject::Tag debug_curr_tag_; + TaggedObject::Tag debug_trial_tag_; + TaggedObject::Tag debug_delta_tag_; + TaggedObject::Tag debug_delta_aff_tag_; + TaggedObject::Tag debug_curr_tag_sum_; + TaggedObject::Tag debug_trial_tag_sum_; + TaggedObject::Tag debug_delta_tag_sum_; + TaggedObject::Tag debug_delta_aff_tag_sum_; + //@} +#endif + + }; + + inline + SmartPtr IpoptData::curr() const + { + DBG_ASSERT(IsNull(curr_) || (curr_->GetTag() == debug_curr_tag_ && curr_->GetTagSum() == debug_curr_tag_sum_) ); + + return curr_; + } + + inline + SmartPtr IpoptData::trial() const + { + DBG_ASSERT(IsNull(trial_) || (trial_->GetTag() == debug_trial_tag_ && trial_->GetTagSum() == debug_trial_tag_sum_) ); + + return trial_; + } + + inline + SmartPtr IpoptData::delta() const + { + DBG_ASSERT(IsNull(delta_) || (delta_->GetTag() == debug_delta_tag_ && delta_->GetTagSum() == debug_delta_tag_sum_) ); + + return delta_; + } + + inline + SmartPtr IpoptData::delta_aff() const + { + DBG_ASSERT(IsNull(delta_aff_) || (delta_aff_->GetTag() == debug_delta_aff_tag_ && delta_aff_->GetTagSum() == debug_delta_aff_tag_sum_) ); + + return delta_aff_; + } + + inline + void IpoptData::CopyTrialToCurrent() + { + curr_ = trial_; +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(curr_)) { + debug_curr_tag_ = curr_->GetTag(); + debug_curr_tag_sum_ = curr_->GetTagSum(); + } + else { + debug_curr_tag_ = 0; + debug_curr_tag_sum_ = 0; + } +#endif + + } + + inline + void IpoptData::set_trial(SmartPtr& trial) + { + trial_ = ConstPtr(trial); + +#if COIN_IPOPT_CHECKLEVEL > 0 + // verify the correct space + DBG_ASSERT(trial_->OwnerSpace() == (VectorSpace*)GetRawPtr(iterates_space_)); + if (IsValid(trial)) { + debug_trial_tag_ = trial->GetTag(); + debug_trial_tag_sum_ = trial->GetTagSum(); + } + else { + debug_trial_tag_ = 0; + debug_trial_tag_sum_ = 0; + } +#endif + + trial = NULL; + } + + inline + void IpoptData::set_delta(SmartPtr& delta) + { + delta_ = ConstPtr(delta); +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta)) { + debug_delta_tag_ = delta->GetTag(); + debug_delta_tag_sum_ = delta->GetTagSum(); + } + else { + debug_delta_tag_ = 0; + debug_delta_tag_sum_ = 0; + } +#endif + + delta = NULL; + } + + inline + void IpoptData::set_delta(SmartPtr& delta) + { + delta_ = delta; +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta)) { + debug_delta_tag_ = delta->GetTag(); + debug_delta_tag_sum_ = delta->GetTagSum(); + } + else { + debug_delta_tag_ = 0; + debug_delta_tag_sum_ = 0; + } +#endif + + delta = NULL; + } + + inline + void IpoptData::set_delta_aff(SmartPtr& delta_aff) + { + delta_aff_ = ConstPtr(delta_aff); +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta_aff)) { + debug_delta_aff_tag_ = delta_aff->GetTag(); + debug_delta_aff_tag_sum_ = delta_aff->GetTagSum(); + } + else { + debug_delta_aff_tag_ = 0; + debug_delta_aff_tag_sum_ = delta_aff->GetTagSum(); + } +#endif + + delta_aff = NULL; + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpIpoptNLP.hpp b/thirdparty/linux/include/coin/IpIpoptNLP.hpp new file mode 100644 index 0000000..21951c3 --- /dev/null +++ b/thirdparty/linux/include/coin/IpIpoptNLP.hpp @@ -0,0 +1,261 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptNLP.hpp 2594 2015-08-09 14:31:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTNLP_HPP__ +#define __IPIPOPTNLP_HPP__ + +#include "IpNLP.hpp" +#include "IpJournalist.hpp" +#include "IpNLPScaling.hpp" + +namespace Ipopt +{ + // forward declarations + class IteratesVector; + + /** This is the abstract base class for classes that map + * the traditional NLP into + * something that is more useful by Ipopt. + * This class takes care of storing the + * calculated model results, handles cacheing, + * and (some day) takes care of addition of slacks. + */ + class IpoptNLP : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + IpoptNLP(const SmartPtr nlp_scaling) + : + nlp_scaling_(nlp_scaling) + {} + + /** Default destructor */ + virtual ~IpoptNLP() + {} + //@} + + /** Initialization method. Set the internal options and + * initialize internal data structures. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + bool ret = true; + if (IsValid(nlp_scaling_)) { + ret = nlp_scaling_->Initialize(jnlst, options, prefix); + } + return ret; + } + + /**@name Possible Exceptions */ + //@{ + /** thrown if there is any error evaluating values from the nlp */ + DECLARE_STD_EXCEPTION(Eval_Error); + //@} + /** Initialize (create) structures for + * the iteration data */ + virtual bool InitializeStructures(SmartPtr& x, + bool init_x, + SmartPtr& y_c, + bool init_y_c, + SmartPtr& y_d, + bool init_y_d, + SmartPtr& z_L, + bool init_z_L, + SmartPtr& z_U, + bool init_z_U, + SmartPtr& v_L, + SmartPtr& v_U + ) = 0; + + /** Method accessing the GetWarmStartIterate of the NLP */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate)=0; + + /** Accessor methods for model data */ + //@{ + /** Objective value */ + virtual Number f(const Vector& x) = 0; + + /** Gradient of the objective */ + virtual SmartPtr grad_f(const Vector& x) = 0; + + /** Equality constraint residual */ + virtual SmartPtr c(const Vector& x) = 0; + + /** Jacobian Matrix for equality constraints */ + virtual SmartPtr jac_c(const Vector& x) = 0; + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + virtual SmartPtr d(const Vector& x) = 0; + + /** Jacobian Matrix for inequality constraints */ + virtual SmartPtr jac_d(const Vector& x) = 0; + + /** Hessian of the Lagrangian */ + virtual SmartPtr h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd + ) = 0; + + /** Lower bounds on x */ + virtual SmartPtr x_L() const = 0; + + /** Permutation matrix (x_L_ -> x) */ + virtual SmartPtr Px_L() const = 0; + + /** Upper bounds on x */ + virtual SmartPtr x_U() const = 0; + + /** Permutation matrix (x_U_ -> x */ + virtual SmartPtr Px_U() const = 0; + + /** Lower bounds on d */ + virtual SmartPtr d_L() const = 0; + + /** Permutation matrix (d_L_ -> d) */ + virtual SmartPtr Pd_L() const = 0; + + /** Upper bounds on d */ + virtual SmartPtr d_U() const = 0; + + /** Permutation matrix (d_U_ -> d */ + virtual SmartPtr Pd_U() const = 0; + + /** x_space */ + virtual SmartPtr x_space() const = 0; + + /** Accessor method to obtain the MatrixSpace for the Hessian + * matrix (or it's approximation) */ + virtual SmartPtr HessianMatrixSpace() const = 0; + //@} + + /** Accessor method for vector/matrix spaces pointers. */ + virtual void GetSpaces(SmartPtr& x_space, + SmartPtr& c_space, + SmartPtr& d_space, + SmartPtr& x_l_space, + SmartPtr& px_l_space, + SmartPtr& x_u_space, + SmartPtr& px_u_space, + SmartPtr& d_l_space, + SmartPtr& pd_l_space, + SmartPtr& d_u_space, + SmartPtr& pd_u_space, + SmartPtr& Jac_c_space, + SmartPtr& Jac_d_space, + SmartPtr& Hess_lagrangian_space) = 0; + + /** Method for adapting the variable bounds. This is called if + * slacks are becoming too small */ + virtual void AdjustVariableBounds(const Vector& new_x_L, + const Vector& new_x_U, + const Vector& new_d_L, + const Vector& new_d_U)=0; + + /** @name Counters for the number of function evaluations. */ + //@{ + virtual Index f_evals() const = 0; + virtual Index grad_f_evals() const = 0; + virtual Index c_evals() const = 0; + virtual Index jac_c_evals() const = 0; + virtual Index d_evals() const = 0; + virtual Index jac_d_evals() const = 0; + virtual Index h_evals() const = 0; + //@} + + /** @name Special method for dealing with the fact that the + * restoration phase objective function depends on the barrier + * parameter */ + //@{ + /** Method for telling the IpoptCalculatedQuantities class whether + * the objective function depends on the barrier function. This + * is only used for the restoration phase NLP + * formulation. Probably only RestoIpoptNLP should overwrite + * this. */ + virtual bool objective_depends_on_mu() const + { + return false; + } + + /** Replacement for the default objective function method which + * knows about the barrier parameter */ + virtual Number f(const Vector& x, Number mu) = 0; + + /** Replacement for the default objective gradient method which + * knows about the barrier parameter */ + virtual SmartPtr grad_f(const Vector& x, Number mu) = 0; + + /** Replacement for the default Lagrangian Hessian method which + * knows about the barrier parameter */ + virtual SmartPtr h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + Number mu) = 0; + + /** Provides a Hessian matrix from the correct matrix space with + * uninitialized values. This can be used in LeastSquareMults to + * obtain a "zero Hessian". */ + virtual SmartPtr uninitialized_h() = 0; + //@} + + /**@name solution routines */ + //@{ + virtual void FinalizeSolution(SolverReturn status, + const Vector& x, const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq)=0; + + virtual bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + SmartPtr ip_data, + SmartPtr ip_cq)=0; + //@} + + /** Returns the scaling strategy object */ + SmartPtr NLP_scaling() const + { + DBG_ASSERT(IsValid(nlp_scaling_)); + return nlp_scaling_; + } + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + IpoptNLP(const IpoptNLP&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptNLP&); + //@} + + SmartPtr nlp_scaling_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpIterateInitializer.hpp b/thirdparty/linux/include/coin/IpIterateInitializer.hpp new file mode 100644 index 0000000..d179651 --- /dev/null +++ b/thirdparty/linux/include/coin/IpIterateInitializer.hpp @@ -0,0 +1,64 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIterateInitializer.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-24 + +#ifndef __IPITERATEINITIALIZER_HPP__ +#define __IPITERATEINITIALIZER_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for all methods for initializing the iterates. + */ + class IterateInitializer: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IterateInitializer() + {} + + /** Default destructor */ + virtual ~IterateInitializer() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Compute the initial iterates and set the into the curr field + * of the ip_data object. */ + virtual bool SetInitialIterates() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IterateInitializer(const IterateInitializer&); + + /** Overloaded Equals Operator */ + void operator=(const IterateInitializer&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpIteratesVector.hpp b/thirdparty/linux/include/coin/IpIteratesVector.hpp new file mode 100644 index 0000000..2ed7580 --- /dev/null +++ b/thirdparty/linux/include/coin/IpIteratesVector.hpp @@ -0,0 +1,689 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIteratesVector.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-06-06 + +#ifndef __IPITERATESVECTOR_HPP__ +#define __IPITERATESVECTOR_HPP__ + +#include "IpCompoundVector.hpp" + +namespace Ipopt +{ + /* forward declarations */ + class IteratesVectorSpace; + + /** Specialized CompoundVector class specifically for the algorithm + * iterates. This class inherits from CompoundVector and is a + * specialized class for handling the iterates of the Ipopt + * Algorithm, that is, x, s, y_c, y_d, z_L, z_U, v_L, and v_U. It + * inherits from CompoundVector so it can behave like a CV in most + * calculations, but it has fixed dimensions and cannot be + * customized + */ + class IteratesVector : public CompoundVector + { + public: + /** Constructors / Destructors */ + //@{ + IteratesVector(const IteratesVectorSpace* owner_space, bool create_new); + + virtual ~IteratesVector(); + //@} + + /** Make New methods */ + //@{ + /** Use this method to create a new iterates vector. The MakeNew + * method on the Vector class also works, but it does not give + * the create_new option. + */ + SmartPtr MakeNewIteratesVector(bool create_new = true) const; + + /** Use this method to create a new iterates vector with a copy of + * all the data. + */ + SmartPtr MakeNewIteratesVectorCopy() const + { + SmartPtr ret = MakeNewIteratesVector(true); + ret->Copy(*this); + return ret; + } + + /** Use this method to create a new iterates vector + * container. This creates a new NonConst container, but the + * elements inside the iterates vector may be const. Therefore, + * the container can be modified to point to new entries, but the + * existing entries may or may not be modifiable. + */ + SmartPtr MakeNewContainer() const; + //@} + + /** Iterates Set/Get Methods */ + //@{ + /** Get the x iterate (const) */ + SmartPtr x() const + { + return GetIterateFromComp(0); + } + + /** Get the x iterate (non-const) - this can only be called if the + * vector was created intenally, or the Set_x_NonConst method was + * used. */ + SmartPtr x_NonConst() + { + return GetNonConstIterateFromComp(0); + } + + /** Create a new vector in the x entry */ + inline + SmartPtr create_new_x(); + + /** Create a new vector in the x entry and copy the current values + * into it. */ + SmartPtr create_new_x_copy() + { + SmartPtr curr_x = GetComp(0); + Set_x_NonConst(*curr_x->MakeNew()); + x_NonConst()->Copy(*curr_x); + return x_NonConst(); + } + + /** Set the x iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_x(const Vector& vec) + { + SetComp(0, vec); + } + + /** Set the x iterate (non-const). Sets the pointer, does NOT copy + * data. */ + void Set_x_NonConst(Vector& vec) + { + SetCompNonConst(0, vec); + } + + /** Get the s iterate (const) */ + SmartPtr s() const + { + return GetIterateFromComp(1); + } + + /** Get the s iterate (non-const) - this can only be called if the + * vector was created intenally, or the Set_s_NonConst method was + * used. */ + SmartPtr s_NonConst() + { + return GetNonConstIterateFromComp(1); + } + + /** Create a new vector in the s entry */ + inline + SmartPtr create_new_s(); + + /** Create a new vector in the s entry and copy the current values + * into it. */ + SmartPtr create_new_s_copy() + { + SmartPtr curr_s = GetComp(1); + Set_s_NonConst(*curr_s->MakeNew()); + s_NonConst()->Copy(*curr_s); + return s_NonConst(); + } + + /** Set the s iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_s(const Vector& vec) + { + SetComp(1, vec); + } + + /** Set the s iterate (non-const). Sets the pointer, does NOT copy + * data. */ + void Set_s_NonConst(Vector& vec) + { + SetCompNonConst(1, vec); + } + + /** Get the y_c iterate (const) */ + SmartPtr y_c() const + { + return GetIterateFromComp(2); + } + + /** Get the y_c iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_y_c_NonConst + * method was used. */ + SmartPtr y_c_NonConst() + { + return GetNonConstIterateFromComp(2); + } + + /** Create a new vector in the y_c entry */ + inline + SmartPtr create_new_y_c(); + + /** Create a new vector in the y_c entry and copy the current + * values into it. */ + SmartPtr create_new_y_c_copy() + { + SmartPtr curr_y_c = GetComp(2); + Set_y_c_NonConst(*curr_y_c->MakeNew()); + y_c_NonConst()->Copy(*curr_y_c); + return y_c_NonConst(); + } + + /** Set the y_c iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_y_c(const Vector& vec) + { + SetComp(2, vec); + } + + /** Set the y_c iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_y_c_NonConst(Vector& vec) + { + SetCompNonConst(2, vec); + } + + /** Get the y_d iterate (const) */ + SmartPtr y_d() const + { + return GetIterateFromComp(3); + } + + /** Get the y_d iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_y_d_NonConst + * method was used. */ + SmartPtr y_d_NonConst() + { + return GetNonConstIterateFromComp(3); + } + + /** Create a new vector in the y_d entry */ + inline + SmartPtr create_new_y_d(); + + /** Create a new vector in the y_d entry and copy the current + * values into it. */ + SmartPtr create_new_y_d_copy() + { + SmartPtr curr_y_d = GetComp(3); + Set_y_d_NonConst(*curr_y_d->MakeNew()); + y_d_NonConst()->Copy(*curr_y_d); + return y_d_NonConst(); + } + + /** Set the y_d iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_y_d(const Vector& vec) + { + SetComp(3, vec); + } + + /** Set the y_d iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_y_d_NonConst(Vector& vec) + { + SetCompNonConst(3, vec); + } + + /** Get the z_L iterate (const) */ + SmartPtr z_L() const + { + return GetIterateFromComp(4); + } + + /** Get the z_L iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_z_L_NonConst + * method was used. */ + SmartPtr z_L_NonConst() + { + return GetNonConstIterateFromComp(4); + } + + /** Create a new vector in the z_L entry */ + inline + SmartPtr create_new_z_L(); + + /** Create a new vector in the z_L entry and copy the current + * values into it. */ + SmartPtr create_new_z_L_copy() + { + SmartPtr curr_z_L = GetComp(4); + Set_z_L_NonConst(*curr_z_L->MakeNew()); + z_L_NonConst()->Copy(*curr_z_L); + return z_L_NonConst(); + } + + /** Set the z_L iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_z_L(const Vector& vec) + { + SetComp(4, vec); + } + + /** Set the z_L iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_z_L_NonConst(Vector& vec) + { + SetCompNonConst(4, vec); + } + + /** Get the z_U iterate (const) */ + SmartPtr z_U() const + { + return GetIterateFromComp(5); + } + + /** Get the z_U iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_z_U_NonConst + * method was used. */ + SmartPtr z_U_NonConst() + { + return GetNonConstIterateFromComp(5); + } + + /** Create a new vector in the z_U entry */ + inline + SmartPtr create_new_z_U(); + + /** Create a new vector in the z_U entry and copy the current + * values into it. */ + SmartPtr create_new_z_U_copy() + { + SmartPtr curr_z_U = GetComp(5); + Set_z_U_NonConst(*curr_z_U->MakeNew()); + z_U_NonConst()->Copy(*curr_z_U); + return z_U_NonConst(); + } + + /** Set the z_U iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_z_U(const Vector& vec) + { + SetComp(5, vec); + } + + /** Set the z_U iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_z_U_NonConst(Vector& vec) + { + SetCompNonConst(5, vec); + } + + /** Get the v_L iterate (const) */ + SmartPtr v_L() const + { + return GetIterateFromComp(6); + } + + /** Get the v_L iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_v_L_NonConst + * method was used. */ + SmartPtr v_L_NonConst() + { + return GetNonConstIterateFromComp(6); + } + + /** Create a new vector in the v_L entry */ + inline + SmartPtr create_new_v_L(); + + /** Create a new vector in the v_L entry and copy the current + * values into it. */ + SmartPtr create_new_v_L_copy() + { + SmartPtr curr_v_L = GetComp(6); + Set_v_L_NonConst(*curr_v_L->MakeNew()); + v_L_NonConst()->Copy(*curr_v_L); + return v_L_NonConst(); + } + + /** Set the v_L iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_v_L(const Vector& vec) + { + SetComp(6, vec); + } + + /** Set the v_L iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_v_L_NonConst(Vector& vec) + { + SetCompNonConst(6, vec); + } + + /** Get the v_U iterate (const) */ + SmartPtr v_U() const + { + return GetIterateFromComp(7); + } + + /** Get the v_U iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_v_U_NonConst + * method was used. */ + SmartPtr v_U_NonConst() + { + return GetNonConstIterateFromComp(7); + } + + /** Create a new vector in the v_U entry */ + inline + SmartPtr create_new_v_U(); + + /** Create a new vector in the v_U entry and copy the current + * values into it. */ + SmartPtr create_new_v_U_copy() + { + SmartPtr curr_v_U = GetComp(7); + Set_v_U_NonConst(*curr_v_U->MakeNew()); + v_U_NonConst()->Copy(*curr_v_U); + return v_U_NonConst(); + } + + /** Set the v_U iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_v_U(const Vector& vec) + { + SetComp(7, vec); + } + + /** Set the v_U iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_v_U_NonConst(Vector& vec) + { + SetCompNonConst(7, vec); + } + + /** Set the primal variables all in one shot. Sets the pointers, + * does NOT copy data */ + void Set_primal(const Vector& x, const Vector& s) + { + SetComp(0, x); + SetComp(1, s); + } + void Set_primal_NonConst(Vector& x, Vector& s) + { + SetCompNonConst(0, x); + SetCompNonConst(1, s); + } + + /** Set the eq multipliers all in one shot. Sets the pointers, + * does not copy data. */ + void Set_eq_mult(const Vector& y_c, const Vector& y_d) + { + SetComp(2, y_c); + SetComp(3, y_d); + } + void Set_eq_mult_NonConst(Vector& y_c, Vector& y_d) + { + SetCompNonConst(2, y_c); + SetCompNonConst(3, y_d); + } + + /** Set the bound multipliers all in one shot. Sets the pointers, + * does not copy data. */ + void Set_bound_mult(const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U) + { + SetComp(4, z_L); + SetComp(5, z_U); + SetComp(6, v_L); + SetComp(7, v_U); + } + void Set_bound_mult_NonConst(Vector& z_L, Vector& z_U, Vector& v_L, Vector& v_U) + { + SetCompNonConst(4, z_L); + SetCompNonConst(5, z_U); + SetCompNonConst(6, v_L); + SetCompNonConst(7, v_U); + } + + /** Get a sum of the tags of the contained items. There is no + * guarantee that this is unique, but there is a high chance it + * is unique and it can be used for debug checks relatively + * reliably. + */ + TaggedObject::Tag GetTagSum() const + { + TaggedObject::Tag tag = 0; + + if (IsValid(x())) { + tag += x()->GetTag(); + } + if (IsValid(s())) { + tag += s()->GetTag(); + } + if (IsValid(y_c())) { + tag += y_c()->GetTag(); + } + if (IsValid(y_d())) { + tag += y_d()->GetTag(); + } + if (IsValid(z_L())) { + tag += z_L()->GetTag(); + } + if (IsValid(z_U())) { + tag += z_U()->GetTag(); + } + if (IsValid(v_L())) { + tag += v_L()->GetTag(); + } + if (IsValid(v_U())) { + tag += v_U()->GetTag(); + } + + return tag; + } + //@} + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. + */ + //@{ + /** Default Constructor */ + IteratesVector(); + + /** Copy Constructor */ + IteratesVector(const IteratesVector&); + + /** Overloaded Equals Operator */ + void operator=(const IteratesVector&); + //@} + + const IteratesVectorSpace* owner_space_; + + /** private method to return the const element from the compound + * vector. This method will return NULL if none is currently + * set. + */ + SmartPtr GetIterateFromComp(Index i) const + { + if (IsCompNull(i)) { + return NULL; + } + return GetComp(i); + } + + /** private method to return the non-const element from the + * compound vector. This method will return NULL if none is + * currently set. + */ + SmartPtr GetNonConstIterateFromComp(Index i) + { + if (IsCompNull(i)) { + return NULL; + } + return GetCompNonConst(i); + } + + }; + + /** Vector Space for the IteratesVector class. This is a + * specialized vector space for the IteratesVector class. + */ + class IteratesVectorSpace : public CompoundVectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor that takes the spaces for each of the iterates. + * Warning! None of these can be NULL ! + */ + IteratesVectorSpace(const VectorSpace& x_space, const VectorSpace& s_space, + const VectorSpace& y_c_space, const VectorSpace& y_d_space, + const VectorSpace& z_L_space, const VectorSpace& z_U_space, + const VectorSpace& v_L_space, const VectorSpace& v_U_space + ); + + virtual ~IteratesVectorSpace(); + //@} + + /** Method for creating vectors . */ + //@{ + /** Use this to create a new IteratesVector. You can pass-in + * create_new = false if you only want a container and do not + * want vectors allocated. + */ + virtual IteratesVector* MakeNewIteratesVector(bool create_new = true) const + { + return new IteratesVector(this, create_new); + } + + /** Use this method to create a new const IteratesVector. You must pass in + * valid pointers for all of the entries. + */ + const SmartPtr MakeNewIteratesVector(const Vector& x, const Vector& s, + const Vector& y_c, const Vector& y_d, + const Vector& z_L, const Vector& z_U, + const Vector& v_L, const Vector& v_U) + { + SmartPtr newvec = MakeNewIteratesVector(false); + newvec->Set_x(x); + newvec->Set_s(s); + newvec->Set_y_c(y_c); + newvec->Set_y_d(y_d); + newvec->Set_z_L(z_L); + newvec->Set_z_U(z_U); + newvec->Set_v_L(v_L); + newvec->Set_v_U(v_U); + return ConstPtr(newvec); + } + + + /** This method overloads + * ComooundVectorSpace::MakeNewCompoundVector to make sure that + * we get a vector of the correct type + */ + virtual CompoundVector* MakeNewCompoundVector(bool create_new = true) const + { + return MakeNewIteratesVector(create_new); + } + + /** This method creates a new vector (and allocates space in all + * the contained vectors. This is really only used for code that + * does not know what type of vector it is dealing with - for + * example, this method is called from Vector::MakeNew() + */ + virtual Vector* MakeNew() const + { + return MakeNewIteratesVector(); + } + //@} + + /** This method hides the CompoundVectorSpace::SetCompSpace method + * since the components of the Iterates are fixed at + * construction. + */ + virtual void SetCompSpace(Index icomp, const VectorSpace& vec_space) + { + DBG_ASSERT(false && "This is an IteratesVectorSpace - a special compound vector for Ipopt iterates. The contained spaces should not be modified."); + } + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + IteratesVectorSpace(); + + /** Copy Constructor */ + IteratesVectorSpace(const IteratesVectorSpace&); + + /** Overloaded Equals Operator */ + IteratesVectorSpace& operator=(const IteratesVectorSpace&); + //@} + + /** Contained Spaces */ + SmartPtr x_space_; + SmartPtr s_space_; + SmartPtr y_c_space_; + SmartPtr y_d_space_; + SmartPtr z_L_space_; + SmartPtr z_U_space_; + SmartPtr v_L_space_; + SmartPtr v_U_space_; + }; + + + inline + SmartPtr IteratesVector::create_new_x() + { + Set_x_NonConst(*owner_space_->GetCompSpace(0)->MakeNew()); + return x_NonConst(); + } + inline + SmartPtr IteratesVector::create_new_s() + { + Set_s_NonConst(*owner_space_->GetCompSpace(1)->MakeNew()); + return s_NonConst(); + } + inline + SmartPtr IteratesVector::create_new_y_c() + { + Set_y_c_NonConst(*owner_space_->GetCompSpace(2)->MakeNew()); + return y_c_NonConst(); + } + inline + SmartPtr IteratesVector::create_new_y_d() + { + Set_y_d_NonConst(*owner_space_->GetCompSpace(3)->MakeNew()); + return y_d_NonConst(); + } + inline + SmartPtr IteratesVector::create_new_z_L() + { + Set_z_L_NonConst(*owner_space_->GetCompSpace(4)->MakeNew()); + return z_L_NonConst(); + } + inline + SmartPtr IteratesVector::create_new_z_U() + { + Set_z_U_NonConst(*owner_space_->GetCompSpace(5)->MakeNew()); + return z_U_NonConst(); + } + inline + SmartPtr IteratesVector::create_new_v_L() + { + Set_v_L_NonConst(*owner_space_->GetCompSpace(6)->MakeNew()); + return v_L_NonConst(); + } + inline + SmartPtr IteratesVector::create_new_v_U() + { + Set_v_U_NonConst(*owner_space_->GetCompSpace(7)->MakeNew()); + return v_U_NonConst(); + } +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpIterationOutput.hpp b/thirdparty/linux/include/coin/IpIterationOutput.hpp new file mode 100644 index 0000000..95fd650 --- /dev/null +++ b/thirdparty/linux/include/coin/IpIterationOutput.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIterationOutput.hpp 2020 2011-06-16 20:46:16Z andreasw $ +// +// Authors: Andreas Waechter, Carl Laird IBM 2004-09-27 + +#ifndef __IPITERATIONOUTPUT_HPP__ +#define __IPITERATIONOUTPUT_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for objects that do the output summary per iteration. + */ + class IterationOutput: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IterationOutput() + {} + + /** Default destructor */ + virtual ~IterationOutput() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Method to do all the summary output per iteration. This + * include the one-line summary output as well as writing the + * details about the iterates if desired */ + virtual void WriteOutput() = 0; + + protected: + /** enumeration for different inf_pr output options */ + enum InfPrOutput + { + INTERNAL=0, + ORIGINAL + }; + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IterationOutput(const IterationOutput&); + + /** Overloaded Equals Operator */ + void operator=(const IterationOutput&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpJournalist.hpp b/thirdparty/linux/include/coin/IpJournalist.hpp new file mode 100644 index 0000000..266130a --- /dev/null +++ b/thirdparty/linux/include/coin/IpJournalist.hpp @@ -0,0 +1,497 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpJournalist.hpp 2204 2013-04-13 13:49:26Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPJOURNALIST_HPP__ +#define __IPJOURNALIST_HPP__ + +#include "IpoptConfig.h" +#include "IpTypes.hpp" +#include "IpReferenced.hpp" +#include "IpSmartPtr.hpp" + +#ifdef HAVE_CSTDARG +# include +#else +# ifdef HAVE_STDARG_H +# include +# else +# include // if this header is included by someone who does not define HAVE_CSTDARG or HAVE_STDARG, let's hope that cstdarg is available +# endif +#endif + +#ifdef HAVE_CSTDIO +# include +#else +# ifdef HAVE_STDIO_H +# include +# else +# include // if this header is included by someone who does not define HAVE_CSTDIO or HAVE_STDIO, let's hope that cstdio is available +# endif +#endif + +#include +#include +#include + +namespace Ipopt +{ + + // forward declarations + class Journal; + class FileJournal; + + /**@name Journalist Enumerations. */ + //@{ + /** Print Level Enum. */ + enum EJournalLevel { + J_INSUPPRESSIBLE=-1, + J_NONE=0, + J_ERROR, + J_STRONGWARNING, + J_SUMMARY, + J_WARNING, + J_ITERSUMMARY, + J_DETAILED, + J_MOREDETAILED, + J_VECTOR, + J_MOREVECTOR, + J_MATRIX, + J_MOREMATRIX, + J_ALL, + J_LAST_LEVEL + }; + + /** Category Selection Enum. */ + enum EJournalCategory { + J_DBG=0, + J_STATISTICS, + J_MAIN, + J_INITIALIZATION, + J_BARRIER_UPDATE, + J_SOLVE_PD_SYSTEM, + J_FRAC_TO_BOUND, + J_LINEAR_ALGEBRA, + J_LINE_SEARCH, + J_HESSIAN_APPROXIMATION, + J_SOLUTION, + J_DOCUMENTATION, + J_NLP, + J_TIMING_STATISTICS, + J_USER_APPLICATION /** This can be used by the user's application*/ , + J_USER1 /** This can be used by the user's application*/ , + J_USER2 /** This can be used by the user's application*/ , + J_USER3 /** This can be used by the user's application*/ , + J_USER4 /** This can be used by the user's application*/ , + J_USER5 /** This can be used by the user's application*/ , + J_USER6 /** This can be used by the user's application*/ , + J_USER7 /** This can be used by the user's application*/ , + J_USER8 /** This can be used by the user's application*/ , + J_USER9 /** This can be used by the user's application*/ , + J_USER10 /** This can be used by the user's application*/ , + J_USER11 /** This can be used by the user's application*/ , + J_USER12 /** This can be used by the user's application*/ , + J_USER13 /** This can be used by the user's application*/ , + J_USER14 /** This can be used by the user's application*/ , + J_USER15 /** This can be used by the user's application*/ , + J_USER16 /** This can be used by the user's application*/ , + J_USER17 /** This can be used by the user's application*/ , + J_LAST_CATEGORY + }; + //@} + + /** Class responsible for all message output. + * This class is responsible for all messaging and output. + * The "printing" code or "author" should send ALL messages to the + * Journalist, indicating an appropriate category and print level. + * The journalist then decides, based on reader specified + * acceptance criteria, which message is actually printed in which + * journals. + * This allows the printing code to send everything, while the + * "reader" can decide what they really want to see. + * + * Authors: + * Authors use the + * Journals: You can add as many Journals as you like to the + * Journalist with the AddJournal or the AddFileJournal methods. + * Each one represents a different printing location (or file). + * Then, you can call the "print" methods of the Journalist to output + * information to each of the journals. + * + * Acceptance Criteria: Each print message should be flagged + * appropriately with an EJournalCategory and EJournalLevel. + * + * The AddFileJournal + * method returns a pointer to the newly created Journal object + * (if successful) so you can set Acceptance criteria for that + * particular location. + * + */ + class Journalist : public ReferencedObject + { + public: + /**@name Constructor / Desructor. */ + //@{ + /** Constructor. */ + Journalist(); + + /** Destructor... */ + virtual ~Journalist(); + //@} + + /**@name Author Methods. + * These methods are used by authoring code, or code that wants + * to report some information. + */ + //@{ + /** Method to print a formatted string */ + virtual void Printf(EJournalLevel level, EJournalCategory category, + const char* format, ...) const; + + /** Method to print a long string including indentation. The + * string is printed starting at the current position. If the + * position (counting started at the current position) exceeds + * max_length, a new line is inserted, and indent_spaces many + * spaces are printed before the string is continued. This is + * for example used during the printing of the option + * documentation. */ + virtual void PrintStringOverLines(EJournalLevel level, EJournalCategory category, + Index indent_spaces, Index max_length, + const std::string& line) const; + + /** Method to print a formatted string with indentation */ + virtual void PrintfIndented(EJournalLevel level, + EJournalCategory category, + Index indent_level, + const char* format, ...) const; + + /** Method to print a formatted string + * using the va_list argument. */ + virtual void VPrintf(EJournalLevel level, + EJournalCategory category, + const char* pformat, + va_list ap) const; + + /** Method to print a formatted string with indentation, + * using the va_list argument. */ + virtual void VPrintfIndented(EJournalLevel level, + EJournalCategory category, + Index indent_level, + const char* pformat, + va_list ap) const; + + /** Method that returns true if there is a Journal that would + * write output for the given JournalLevel and JournalCategory. + * This is useful if expensive computation would be required for + * a particular output. The author code can check with this + * method if the computations are indeed required. + */ + virtual bool ProduceOutput(EJournalLevel level, + EJournalCategory category) const; + + + /** Method that flushes the current buffer for all Journalists. + Calling this method after one optimization run helps to avoid + cluttering output with that produced by other parts of the + program (e.g. written in Fortran) */ + virtual void FlushBuffer() const; + //@} + + /**@name Reader Methods. + * These methods are used by the reader. The reader will setup the + * journalist with each output file and the acceptance + * criteria for that file. + * + * Use these methods to setup the journals (files or other output). + * These are the internal objects that keep track of the print levels + * for each category. Then use the internal Journal objects to + * set specific print levels for each category (or keep defaults). + * + */ + //@{ + /** Add a new journal. The location_name is a string identifier, + * which can be used to obtain the pointer to the new Journal at + * a later point using the GetJournal method. + * The default_level is + * used to initialize the * printing level for all categories. + */ + virtual bool AddJournal(const SmartPtr jrnl); + + /** Add a new FileJournal. fname is the name + * of the * file to which this Journal corresponds. Use + * fname="stdout" * for stdout, and use fname="stderr" for + * stderr. This method * returns the Journal pointer so you can + * set specific acceptance criteria. It returns NULL if there + * was a problem creating a new Journal. + */ + virtual SmartPtr AddFileJournal( + const std::string& location_name, /**< journal identifier */ + const std::string& fname, /**< file name */ + EJournalLevel default_level = J_WARNING /**< default journal level */ + ); + + /** Get an existing journal. You can use this method to change + * the acceptance criteria at runtime. + */ + virtual SmartPtr GetJournal(const std::string& location_name); + + /** Delete all journals curently known by the journalist. */ + virtual void DeleteAllJournals(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Journalist(const Journalist&); + + /** Overloaded Equals Operator */ + void operator=(const Journalist&); + //@} + + //** Private Data Members. */ + //@{ + std::vector< SmartPtr > journals_; + //@} + }; + + /** Journal class (part of the Journalist implementation.). This + * class is the base class for all Journals. It controls the + * acceptance criteria for print statements etc. Derived classes + * like the FileJournal - output those messages to specific locations + */ + class Journal : public ReferencedObject + { + public: + /** Constructor. */ + Journal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~Journal(); + + /** Get the name of the Journal */ + virtual std::string Name(); + + /** Set the print level for a particular category. */ + virtual void SetPrintLevel( + EJournalCategory category, EJournalLevel level + ); + + /** Set the print level for all category. */ + virtual void SetAllPrintLevels( + EJournalLevel level + ); + + /**@name Journal Output Methods. These methods are called by the + * Journalist who first checks if the output print level and category + * are acceptable. + * Calling the Print methods explicitly (instead of through the + * Journalist will output the message regardless of print level + * and category. You should use the Journalist to print & flush instead + */ + //@{ + /** Ask if a particular print level/category is accepted by the + * journal. + */ + virtual bool IsAccepted( + EJournalCategory category, EJournalLevel level + ) const; + + /** Print to the designated output location */ + virtual void Print(EJournalCategory category, EJournalLevel level, + const char* str) + { + PrintImpl(category, level, str); + } + + /** Printf to the designated output location */ + virtual void Printf(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap) + { + PrintfImpl(category, level, pformat, ap); + } + + /** Flush output buffer.*/ + virtual void FlushBuffer() + { + FlushBufferImpl(); + } + //@} + + protected: + /**@name Implementation version of Print methods. Derived classes + * should overload the Impl methods. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str)=0; + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap)=0; + + /** Flush output buffer.*/ + virtual void FlushBufferImpl()=0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + Journal(); + + /** Copy Constructor */ + Journal(const Journal&); + + /** Overloaded Equals Operator */ + void operator=(const Journal&); + //@} + + /** Name of the output location */ + std::string name_; + + /** vector of integers indicating the level for each category */ + Index print_levels_[J_LAST_CATEGORY]; + }; + + + /** FileJournal class. This is a particular Journal implementation that + * writes to a file for output. It can write to (stdout, stderr, or disk) + * by using "stdout" and "stderr" as filenames. + */ + class FileJournal : public Journal + { + public: + /** Constructor. */ + FileJournal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~FileJournal(); + + /** Open a new file for the output location. + * Special Names: stdout means stdout, + * : stderr means stderr. + * + * Return code is false only if the file with the given name + * could not be opened. + */ + virtual bool Open(const char* fname); + + protected: + /**@name Implementation version of Print methods - Overloaded from + * Journal base class. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str); + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap); + + /** Flush output buffer.*/ + virtual void FlushBufferImpl(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + FileJournal(); + + /** Copy Constructor */ + FileJournal(const FileJournal&); + + /** Overloaded Equals Operator */ + void operator=(const FileJournal&); + //@} + + /** FILE pointer for the output destination */ + FILE* file_; + }; + + /** StreamJournal class. This is a particular Journal implementation that + * writes to a stream for output. + */ + class StreamJournal : public Journal + { + public: + /** Constructor. */ + StreamJournal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~StreamJournal() + {} + + /** Setting the output stream pointer */ + void SetOutputStream(std::ostream* os); + + protected: + /**@name Implementation version of Print methods - Overloaded from + * Journal base class. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str); + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap); + + /** Flush output buffer.*/ + virtual void FlushBufferImpl(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + StreamJournal(); + + /** Copy Constructor */ + StreamJournal(const StreamJournal&); + + /** Overloaded Equals Operator */ + void operator=(const StreamJournal&); + //@} + + /** pointer to output stream for the output destination */ + std::ostream* os_; + + /** buffer for sprintf. Being generous in size here... */ + char buffer_[32768]; + }; +} + +#endif diff --git a/thirdparty/linux/include/coin/IpLapack.hpp b/thirdparty/linux/include/coin/IpLapack.hpp new file mode 100644 index 0000000..ef8883c --- /dev/null +++ b/thirdparty/linux/include/coin/IpLapack.hpp @@ -0,0 +1,55 @@ +// Copyright (C) 2005, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpLapack.hpp 2449 2013-12-16 00:25:42Z ghackebeil $ +// +// Authors: Andreas Waechter IBM 2005-12-25 + +#ifndef __IPLAPACK_HPP__ +#define __IPLAPACK_HPP__ + +#include "IpUtils.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(LAPACK_NOT_INCLUDED); + + /** Wrapper for LAPACK subroutine DPOTRS. Solving a linear system + * given a Cholesky factorization. We assume that the Cholesky + * factor is lower traiangular. */ + void IpLapackDpotrs(Index ndim, Index nrhs, const Number *a, Index lda, + Number *b, Index ldb); + + /** Wrapper for LAPACK subroutine DPOTRF. Compute Cholesky + * factorization (lower triangular factor). info is the return + * value from the LAPACK routine. */ + void IpLapackDpotrf(Index ndim, Number *a, Index lda, Index& info); + + /** Wrapper for LAPACK subroutine DSYEV. Compute the Eigenvalue + * decomposition for a given matrix. If compute_eigenvectors is + * true, a will contain the eigenvectors in its columns on + * return. */ + void IpLapackDsyev(bool compute_eigenvectors, Index ndim, Number *a, + Index lda, Number *w, Index& info); + + /** Wrapper for LAPACK subroutine DGETRF. Compute LU factorization. + * info is the return value from the LAPACK routine. */ + void IpLapackDgetrf(Index ndim, Number *a, Index* pivot, Index lda, + Index& info); + + /** Wrapper for LAPACK subroutine DGETRS. Solving a linear system + * given a LU factorization. */ + void IpLapackDgetrs(Index ndim, Index nrhs, const Number *a, Index lda, + Index* ipiv, Number *b, Index ldb); + + /** Wrapper for LAPACK subroutine DPPSV. Solves a symmetric positive + * definite linear system in packed storage format (upper triangular). + * info is the return value from the LAPACK routine. */ + void IpLapackDppsv(Index ndim, Index nrhs, const Number *a, + Number *b, Index ldb, Index& info); + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpLineSearch.hpp b/thirdparty/linux/include/coin/IpLineSearch.hpp new file mode 100644 index 0000000..70c11f1 --- /dev/null +++ b/thirdparty/linux/include/coin/IpLineSearch.hpp @@ -0,0 +1,96 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpLineSearch.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPLINESEARCH_HPP__ +#define __IPLINESEARCH_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for line search objects. + */ + class LineSearch : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + LineSearch() + {} + + /** Default destructor */ + virtual ~LineSearch() + {} + //@} + + /** Perform the line search. As search direction the delta + * in the data object is used + */ + virtual void FindAcceptableTrialPoint() = 0; + + /** Reset the line search. + * This function should be called if all previous information + * should be discarded when the line search is performed the + * next time. For example, this method should be called after + * the barrier parameter is changed. + */ + virtual void Reset() = 0; + + /** Set flag indicating whether a very rigorous line search should + * be performed. If this flag is set to true, the line search + * algorithm might decide to abort the line search and not to + * accept a new iterate. If the line search decided not to + * accept a new iterate, the return value of + * CheckSkippedLineSearch() is true at the next call. For + * example, in the non-monotone barrier parameter update + * procedure, the filter algorithm should not switch to the + * restoration phase in the free mode; instead, the algorithm + * should swtich to the fixed mode. + */ + virtual void SetRigorousLineSearch(bool rigorous) = 0; + + /** Check if the line search procedure didn't accept a new iterate + * during the last call of FindAcceptableTrialPoint(). + * + */ + virtual bool CheckSkippedLineSearch() = 0; + + /** This method should be called if the optimization process + * requires the line search object to switch to some fallback + * mechanism (like the restoration phase), when the regular + * optimization procedure cannot be continued (for example, + * because the search direction could not be computed). This + * will cause the line search object to immediately proceed with + * this mechanism when FindAcceptableTrialPoint() is call. This + * method returns false if no fallback mechanism is available. */ + virtual bool ActivateFallbackMechanism() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + LineSearch(const LineSearch&); + + /** Overloaded Equals Operator */ + void operator=(const LineSearch&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpMatrix.hpp b/thirdparty/linux/include/coin/IpMatrix.hpp new file mode 100644 index 0000000..79018da --- /dev/null +++ b/thirdparty/linux/include/coin/IpMatrix.hpp @@ -0,0 +1,345 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpMatrix.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPMATRIX_HPP__ +#define __IPMATRIX_HPP__ + +#include "IpVector.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class MatrixSpace; + + /** Matrix Base Class. This is the base class for all derived matrix + * types. All Matrices, such as Jacobian and Hessian matrices, as + * well as possibly the iteration matrices needed for the step + * computation, are of this type. + * + * Deriving from Matrix: Overload the protected XXX_Impl method. + */ + class Matrix : public TaggedObject + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor. It has to be given a pointer to the + * corresponding MatrixSpace. + */ + Matrix(const MatrixSpace* owner_space) + : + TaggedObject(), + owner_space_(owner_space), + valid_cache_tag_(0) + {} + + /** Destructor */ + virtual ~Matrix() + {} + //@} + + /**@name Operations of the Matrix on a Vector */ + //@{ + /** Matrix-vector multiply. Computes y = alpha * Matrix * x + + * beta * y. Do not overload. Overload MultVectorImpl instead. + */ + void MultVector(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + MultVectorImpl(alpha, x, beta, y); + } + + /** Matrix(transpose) vector multiply. Computes y = alpha * + * Matrix^T * x + beta * y. Do not overload. Overload + * TransMultVectorImpl instead. + */ + void TransMultVector(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + TransMultVectorImpl(alpha, x, beta, y); + } + //@} + + /** @name Methods for specialized operations. A prototype + * implementation is provided, but for efficient implementation + * those should be specially implemented. + */ + //@{ + /** X = X + alpha*(Matrix S^{-1} Z). Should be implemented + * efficiently for the ExansionMatrix + */ + void AddMSinvZ(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Should be implemented + * efficiently for the ExansionMatrix + */ + void SinvBlrmZMTdBr(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + bool HasValidNumbers() const; + + /** @name Information about the size of the matrix */ + //@{ + /** Number of rows */ + inline + Index NRows() const; + + /** Number of columns */ + inline + Index NCols() const; + //@} + + /** @name Norms of the individual rows and columns */ + //@{ + /** Compute the max-norm of the rows in the matrix. The result is + * stored in rows_norms. The vector is assumed to be initialized + * of init is false. */ + void ComputeRowAMax(Vector& rows_norms, bool init=true) const + { + DBG_ASSERT(NRows() == rows_norms.Dim()); + if (init) rows_norms.Set(0.); + ComputeRowAMaxImpl(rows_norms, init); + } + /** Compute the max-norm of the columns in the matrix. The result + * is stored in cols_norms The vector is assumed to be initialized + * of init is false. */ + void ComputeColAMax(Vector& cols_norms, bool init=true) const + { + DBG_ASSERT(NCols() == cols_norms.Dim()); + if (init) cols_norms.Set(0.); + ComputeColAMaxImpl(cols_norms, init); + } + //@} + + /** Print detailed information about the matrix. Do not overload. + * Overload PrintImpl instead. + */ + //@{ + virtual void Print(SmartPtr jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + virtual void Print(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + //@} + + /** Return the owner MatrixSpace*/ + inline + SmartPtr OwnerSpace() const; + + protected: + /** @name implementation methods (derived classes MUST + * overload these pure virtual protected methods. + */ + //@{ + /** Matrix-vector multiply. Computes y = alpha * Matrix * x + + * beta * y + */ + virtual void MultVectorImpl(Number alpha, const Vector& x, Number beta, Vector& y) const =0; + + /** Matrix(transpose) vector multiply. + * Computes y = alpha * Matrix^T * x + beta * y + */ + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, Vector& y) const =0; + + /** X = X + alpha*(Matrix S^{-1} Z). Prototype for this + * specialize method is provided, but for efficient + * implementation it should be overloaded for the expansion matrix. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Should be implemented + * efficiently for the ExpansionMatrix. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). A default implementation always returning true + * is provided, but if possible it should be implemented. */ + virtual bool HasValidNumbersImpl() const + { + return true; + } + + /** Compute the max-norm of the rows in the matrix. The result is + * stored in rows_norms. The vector is assumed to be + * initialized. */ + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const = 0; + /** Compute the max-norm of the columns in the matrix. The result + * is stored in cols_norms. The vector is assumed to be + * initialized. */ + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const = 0; + + /** Print detailed information about the matrix. */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const =0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + Matrix(); + + /** Copy constructor */ + Matrix(const Matrix&); + + /** Overloaded Equals Operator */ + Matrix& operator=(const Matrix&); + //@} + + const SmartPtr owner_space_; + + /**@name CachedResults data members */ + //@{ + mutable TaggedObject::Tag valid_cache_tag_; + mutable bool cached_valid_; + //@} + }; + + + /** MatrixSpace base class, corresponding to the Matrix base class. + * For each Matrix implementation, a corresponding MatrixSpace has + * to be implemented. A MatrixSpace is able to create new Matrices + * of a specific type. The MatrixSpace should also store + * information that is common to all Matrices of that type. For + * example, the dimensions of a Matrix is stored in the MatrixSpace + * base class. + */ + class MatrixSpace : public ReferencedObject + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the number rows and columns of all matrices + * generated by this MatrixSpace. + */ + MatrixSpace(Index nRows, Index nCols) + : + nRows_(nRows), + nCols_(nCols) + {} + + /** Destructor */ + virtual ~MatrixSpace() + {} + //@} + + /** Pure virtual method for creating a new Matrix of the + * corresponding type. + */ + virtual Matrix* MakeNew() const=0; + + /** Accessor function for the number of rows. */ + Index NRows() const + { + return nRows_; + } + /** Accessor function for the number of columns. */ + Index NCols() const + { + return nCols_; + } + + /** Method to test if a given matrix belongs to a particular + * matrix space. + */ + bool IsMatrixFromSpace(const Matrix& matrix) const + { + return (matrix.OwnerSpace() == this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + MatrixSpace(); + + /** Copy constructor */ + MatrixSpace(const MatrixSpace&); + + /** Overloaded Equals Operator */ + MatrixSpace& operator=(const MatrixSpace&); + //@} + + /** Number of rows for all matrices of this type. */ + const Index nRows_; + /** Number of columns for all matrices of this type. */ + const Index nCols_; + }; + + + /* Inline Methods */ + inline + Index Matrix::NRows() const + { + return owner_space_->NRows(); + } + + inline + Index Matrix::NCols() const + { + return owner_space_->NCols(); + } + + inline + SmartPtr Matrix::OwnerSpace() const + { + return owner_space_; + } + +} // namespace Ipopt + +// Macro definitions for debugging matrices +#if COIN_IPOPT_VERBOSITY == 0 +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) +#else +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + if (dbg_jrnl.Jnlst()!=NULL) { \ + (__mat).Print(dbg_jrnl.Jnlst(), \ + J_ERROR, J_DBG, \ + __mat_name, \ + dbg_jrnl.IndentationLevel()*2, \ + "# "); \ + } \ + } +#endif // #if COIN_IPOPT_VERBOSITY == 0 + +#endif diff --git a/thirdparty/linux/include/coin/IpMuUpdate.hpp b/thirdparty/linux/include/coin/IpMuUpdate.hpp new file mode 100644 index 0000000..b6c1d9c --- /dev/null +++ b/thirdparty/linux/include/coin/IpMuUpdate.hpp @@ -0,0 +1,69 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpMuUpdate.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPMUUPDATE_HPP__ +#define __IPMUUPDATE_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + /** Abstract Base Class for classes that implement methods for computing + * the barrier and fraction-to-the-boundary rule parameter for the + * current iteration. + */ + class MuUpdate : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + MuUpdate() + {} + + /** Default destructor */ + virtual ~MuUpdate() + {} + //@} + + /** Initialize method - overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Method for determining the barrier parameter for the next + * iteration. A LineSearch object is passed, so that this method + * can call the Reset method in the LineSearch object, for + * example when then barrier parameter is changed. This method is + * also responsible for setting the fraction-to-the-boundary + * parameter tau. This method returns false if the update could + * not be performed and the algorithm should revert to an + * emergency fallback mechanism. */ + virtual bool UpdateBarrierParameter() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + MuUpdate(const MuUpdate&); + + /** Overloaded Equals Operator */ + void operator=(const MuUpdate&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpNLP.hpp b/thirdparty/linux/include/coin/IpNLP.hpp new file mode 100644 index 0000000..dc283ca --- /dev/null +++ b/thirdparty/linux/include/coin/IpNLP.hpp @@ -0,0 +1,243 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpNLP.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPNLP_HPP__ +#define __IPNLP_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include "IpSmartPtr.hpp" +#include "IpMatrix.hpp" +#include "IpSymMatrix.hpp" +#include "IpOptionsList.hpp" +#include "IpAlgTypes.hpp" +#include "IpReturnCodes.hpp" + +namespace Ipopt +{ + // forward declarations + class IpoptData; + class IpoptCalculatedQuantities; + class IteratesVector; + + /** Brief Class Description. + * Detailed Class Description. + */ + class NLP : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor */ + NLP() + {} + + /** Default destructor */ + virtual ~NLP() + {} + //@} + + /** Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(USER_SCALING_NOT_IMPLEMENTED); + DECLARE_STD_EXCEPTION(INVALID_NLP); + //@} + + /** @name NLP Initialization (overload in + * derived classes).*/ + //@{ + /** Overload if you want the chance to process options or parameters that + * may be specific to the NLP */ + virtual bool ProcessOptions(const OptionsList& /* options */, + const std::string& /* prefix */) + { + return true; + } + + /** Method for creating the derived vector / matrix types. The + * Hess_lagrangian_space pointer can be NULL if a quasi-Newton + * options is chosen. */ + virtual bool GetSpaces(SmartPtr& /* x_space */, + SmartPtr& /* c_space */, + SmartPtr& /* d_space */, + SmartPtr& /* x_l_space */, + SmartPtr& /* px_l_space */, + SmartPtr& /* x_u_space */, + SmartPtr& /* px_u_space */, + SmartPtr& /* d_l_space */, + SmartPtr& /* pd_l_space */, + SmartPtr& /* d_u_space */, + SmartPtr& /* pd_u_space */, + SmartPtr& /* Jac_c_space */, + SmartPtr& /* Jac_d_space */, + SmartPtr& /* Hess_lagrangian_space */)=0; + + /** Method for obtaining the bounds information */ + virtual bool GetBoundsInformation(const Matrix& /* Px_L */, + Vector& /* x_L */, + const Matrix& /* Px_U */, + Vector& /* x_U */, + const Matrix& /* Pd_L */, + Vector& /* d_L */, + const Matrix& /* Pd_U */, + Vector& /* d_U */)=0; + + /** Method for obtaining the starting point for all the + * iterates. ToDo it might not make sense to ask for initial + * values for v_L and v_U? */ + virtual bool GetStartingPoint( + SmartPtr /* x */, + bool /* need_x */, + SmartPtr /* y_c */, + bool /* need_y_c */, + SmartPtr /* y_d */, + bool /* need_y_d */, + SmartPtr /* z_L */, + bool /* need_z_L */, + SmartPtr /* z_U */, + bool /* need_z_U */ + )=0; + + /** Method for obtaining an entire iterate as a warmstart point. + * The incoming IteratesVector has to be filled. The default + * dummy implementation returns false. */ + virtual bool GetWarmStartIterate(IteratesVector& /* warm_start_iterate */) + { + return false; + } + //@} + + /** @name NLP evaluation routines (overload + * in derived classes. */ + //@{ + virtual bool Eval_f(const Vector& /* x */, Number& /* f */) = 0; + + virtual bool Eval_grad_f(const Vector& /* x */, Vector& /* g_f */) = 0; + + virtual bool Eval_c(const Vector& /* x */, Vector& /* c */) = 0; + + virtual bool Eval_jac_c(const Vector& /* x */, Matrix& /* jac_c */) = 0; + + virtual bool Eval_d(const Vector& /* x */, Vector& /* d */) = 0; + + virtual bool Eval_jac_d(const Vector& /* x */, Matrix& /* jac_d */) = 0; + + virtual bool Eval_h(const Vector& /* x */, + Number /* obj_factor */, + const Vector& /* yc */, + const Vector& /* yd */, + SymMatrix& /* h */) = 0; + //@} + + /** @name NLP solution routines. Have default dummy + * implementations that can be overloaded. */ + //@{ + /** This method is called at the very end of the optimization. It + * provides the final iterate to the user, so that it can be + * stored as the solution. The status flag indicates the outcome + * of the optimization, where SolverReturn is defined in + * IpAlgTypes.hpp. */ + virtual void FinalizeSolution(SolverReturn /* status */, + const Vector& /* x */, const Vector& /* z_L */, + const Vector& /* z_U */, + const Vector& /* c */, const Vector& /* d */, + const Vector& /* y_c */, const Vector& /* y_d */, + Number /* obj_value */, + const IpoptData* /* ip_data */, + IpoptCalculatedQuantities* /* ip_cq */) + {} + + /** This method is called once per iteration, after the iteration + * summary output has been printed. It provides the current + * information to the user to do with it anything she wants. It + * also allows the user to ask for a premature termination of the + * optimization by returning false, in which case Ipopt will + * terminate with a corresponding return status. The basic + * information provided in the argument list has the quantities + * values printed in the iteration summary line. If more + * information is required, a user can obtain it from the IpData + * and IpCalculatedQuantities objects. However, note that the + * provided quantities are all for the problem that Ipopt sees, + * i.e., the quantities might be scaled, fixed variables might be + * sorted out, etc. The status indicates things like whether the + * algorithm is in the restoration phase... In the restoration + * phase, the dual variables are probably not not changing. */ + virtual bool IntermediateCallBack(AlgorithmMode /* mode */, + Index /* iter */, Number /* obj_value */, + Number /* inf_pr */, Number /* inf_du */, + Number /* mu */, Number /* d_norm */, + Number /* regularization_size */, + Number /* alpha_du */, Number /* alpha_pr */, + Index /* ls_trials */, + const IpoptData* /* ip_data */, + IpoptCalculatedQuantities* /* ip_cq */) + { + return true; + } + //@} + + /** Routines to get the scaling parameters. These do not need to + * be overloaded unless the options are set for User scaling + */ + //@{ + virtual void GetScalingParameters( + const SmartPtr /* x_space */, + const SmartPtr /* c_space */, + const SmartPtr /* d_space */, + Number& /* obj_scaling */, + SmartPtr& /* x_scaling */, + SmartPtr& /* c_scaling */, + SmartPtr& /* d_scaling */) const + { + THROW_EXCEPTION(USER_SCALING_NOT_IMPLEMENTED, + "You have set options for user provided scaling, but have" + " not implemented GetScalingParameters in the NLP interface"); + } + //@} + + /** Method for obtaining the subspace in which the limited-memory + * Hessian approximation should be done. This is only called if + * the limited-memory Hessian approximation is chosen. Since the + * Hessian is zero in the space of all variables that appear in + * the problem functions only linearly, this allows the user to + * provide a VectorSpace for all nonlinear variables, and an + * ExpansionMatrix to lift from this VectorSpace to the + * VectorSpace of the primal variables x. If the returned values + * are NULL, it is assumed that the Hessian is to be approximated + * in the space of all x variables. The default instantiation of + * this method returns NULL, and a user only has to overwrite + * this method if the approximation is to be done only in a + * subspace. */ + virtual void + GetQuasiNewtonApproximationSpaces(SmartPtr& approx_space, + SmartPtr& P_approx) + { + approx_space = NULL; + P_approx = NULL; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + NLP(const NLP&); + + /** Overloaded Equals Operator */ + void operator=(const NLP&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpNLPScaling.hpp b/thirdparty/linux/include/coin/IpNLPScaling.hpp new file mode 100644 index 0000000..be5f13d --- /dev/null +++ b/thirdparty/linux/include/coin/IpNLPScaling.hpp @@ -0,0 +1,451 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpNLPScaling.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPNLPSCALING_HPP__ +#define __IPNLPSCALING_HPP__ + +#include "IpOptionsList.hpp" +#include "IpRegOptions.hpp" + +namespace Ipopt +{ + // forward declarations + class Vector; + class VectorSpace; + class Matrix; + class MatrixSpace; + class SymMatrix; + class SymMatrixSpace; + class ScaledMatrixSpace; + class SymScaledMatrixSpace; + + /** This is the abstract base class for problem scaling. + * It is repsonsible for determining the scaling factors + * and mapping quantities in and out of scaled and unscaled + * versions + */ + class NLPScalingObject : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + NLPScalingObject(); + + /** Default destructor */ + virtual ~NLPScalingObject(); + //@} + + /** Method to initialize the options */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + jnlst_ = &jnlst; + return InitializeImpl(options, prefix); + } + + /** Methods to map scaled and unscaled matrices */ + //@{ + /** Returns an obj-scaled version of the given scalar */ + virtual Number apply_obj_scaling(const Number& f)=0; + /** Returns an obj-unscaled version of the given scalar */ + virtual Number unapply_obj_scaling(const Number& f)=0; + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_x_NonConst(const SmartPtr& v)=0; + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_x(const SmartPtr& v)=0; + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_x_NonConst(const SmartPtr& v)=0; + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_x(const SmartPtr& v)=0; + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_c(const SmartPtr& v)=0; + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_c(const SmartPtr& v)=0; + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_c_NonConst(const SmartPtr& v)=0; + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_c_NonConst(const SmartPtr& v)=0; + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_d(const SmartPtr& v)=0; + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_d(const SmartPtr& v)=0; + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_d_NonConst(const SmartPtr& v)=0; + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_d_NonConst(const SmartPtr& v)=0; + /** Returns a scaled version of the jacobian for c. If the + * overloaded method does not make a new matrix, make sure to set + * the matrix ptr passed in to NULL. + */ + virtual SmartPtr + apply_jac_c_scaling(SmartPtr matrix)=0; + /** Returns a scaled version of the jacobian for d If the + * overloaded method does not create a new matrix, make sure to + * set the matrix ptr passed in to NULL. + */ + virtual SmartPtr + apply_jac_d_scaling(SmartPtr matrix)=0; + /** Returns a scaled version of the hessian of the lagrangian If + * the overloaded method does not create a new matrix, make sure + * to set the matrix ptr passed in to NULL. + */ + virtual SmartPtr + apply_hessian_scaling(SmartPtr matrix)=0; + //@} + + /** Methods for scaling bounds - these wrap those above */ + //@{ + /** Returns an x-scaled vector in the x_L or x_U space */ + SmartPtr apply_vector_scaling_x_LU_NonConst( + const Matrix& Px_LU, + const SmartPtr& lu, + const VectorSpace& x_space); + /** Returns an x-scaled vector in the x_L or x_U space */ + SmartPtr apply_vector_scaling_x_LU( + const Matrix& Px_LU, + const SmartPtr& lu, + const VectorSpace& x_space); + /** Returns an d-scaled vector in the d_L or d_U space */ + SmartPtr apply_vector_scaling_d_LU_NonConst( + const Matrix& Pd_LU, + const SmartPtr& lu, + const VectorSpace& d_space); + /** Returns an d-scaled vector in the d_L or d_U space */ + SmartPtr apply_vector_scaling_d_LU( + const Matrix& Pd_LU, + const SmartPtr& lu, + const VectorSpace& d_space); + /** Returns an d-unscaled vector in the d_L or d_U space */ + SmartPtr unapply_vector_scaling_d_LU_NonConst( + const Matrix& Pd_LU, + const SmartPtr& lu, + const VectorSpace& d_space); + /** Returns an d-unscaled vector in the d_L or d_U space */ + SmartPtr unapply_vector_scaling_d_LU( + const Matrix& Pd_LU, + const SmartPtr& lu, + const VectorSpace& d_space); + //@} + + /** Methods for scaling the gradient of the objective - wraps the + * virtual methods above + */ + //@{ + /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ + virtual SmartPtr + apply_grad_obj_scaling_NonConst(const SmartPtr& v); + /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ + virtual SmartPtr + apply_grad_obj_scaling(const SmartPtr& v); + /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the + * given vector */ + virtual SmartPtr + unapply_grad_obj_scaling_NonConst(const SmartPtr& v); + /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the + * given vector */ + virtual SmartPtr + unapply_grad_obj_scaling(const SmartPtr& v); + //@} + + /** @name Methods for determining whether scaling for entities is + * done */ + //@{ + /** Returns true if the primal x variables are scaled. */ + virtual bool have_x_scaling()=0; + /** Returns true if the equality constraints are scaled. */ + virtual bool have_c_scaling()=0; + /** Returns true if the inequality constraints are scaled. */ + virtual bool have_d_scaling()=0; + //@} + + /** This method is called by the IpoptNLP's at a convenient time to + * compute and/or read scaling factors + */ + virtual void DetermineScaling(const SmartPtr x_space, + const SmartPtr c_space, + const SmartPtr d_space, + const SmartPtr jac_c_space, + const SmartPtr jac_d_space, + const SmartPtr h_space, + SmartPtr& new_jac_c_space, + SmartPtr& new_jac_d_space, + SmartPtr& new_h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U)=0; + protected: + /** Implementation of the initialization method that has to be + * overloaded by for each derived class. */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix)=0; + + /** Accessor method for the journalist */ + const Journalist& Jnlst() const + { + return *jnlst_; + } + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + NLPScalingObject(const NLPScalingObject&); + + /** Overloaded Equals Operator */ + void operator=(const NLPScalingObject&); + //@} + + SmartPtr jnlst_; + }; + + /** This is a base class for many standard scaling + * techniques. The overloaded classes only need to + * provide the scaling parameters + */ + class StandardScalingBase : public NLPScalingObject + { + public: + /**@name Constructors/Destructors */ + //@{ + StandardScalingBase(); + + /** Default destructor */ + virtual ~StandardScalingBase(); + //@} + + /** Methods to map scaled and unscaled matrices */ + //@{ + /** Returns an obj-scaled version of the given scalar */ + virtual Number apply_obj_scaling(const Number& f); + /** Returns an obj-unscaled version of the given scalar */ + virtual Number unapply_obj_scaling(const Number& f); + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_x_NonConst(const SmartPtr& v); + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_x(const SmartPtr& v); + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_x_NonConst(const SmartPtr& v); + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_x(const SmartPtr& v); + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_c(const SmartPtr& v); + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_c(const SmartPtr& v); + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_c_NonConst(const SmartPtr& v); + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_c_NonConst(const SmartPtr& v); + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_d(const SmartPtr& v); + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_d(const SmartPtr& v); + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr + apply_vector_scaling_d_NonConst(const SmartPtr& v); + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr + unapply_vector_scaling_d_NonConst(const SmartPtr& v); + /** Returns a scaled version of the jacobian for c. If the + * overloaded method does not make a new matrix, make sure to set + * the matrix ptr passed in to NULL. + */ + virtual SmartPtr + apply_jac_c_scaling(SmartPtr matrix); + /** Returns a scaled version of the jacobian for d If the + * overloaded method does not create a new matrix, make sure to + * set the matrix ptr passed in to NULL. + */ + virtual SmartPtr + apply_jac_d_scaling(SmartPtr matrix); + /** Returns a scaled version of the hessian of the lagrangian If + * the overloaded method does not create a new matrix, make sure + * to set the matrix ptr passed in to NULL. + */ + virtual SmartPtr + apply_hessian_scaling(SmartPtr matrix); + //@} + + /** @name Methods for determining whether scaling for entities is + * done */ + //@{ + virtual bool have_x_scaling(); + virtual bool have_c_scaling(); + virtual bool have_d_scaling(); + //@} + + /** This method is called by the IpoptNLP's at a convenient time to + * compute and/or read scaling factors + */ + virtual void DetermineScaling(const SmartPtr x_space, + const SmartPtr c_space, + const SmartPtr d_space, + const SmartPtr jac_c_space, + const SmartPtr jac_d_space, + const SmartPtr h_space, + SmartPtr& new_jac_c_space, + SmartPtr& new_jac_d_space, + SmartPtr& new_h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U); + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr roptions); + //@} + + protected: + /** Overloaded initialization method */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix); + + /** This is the method that has to be overloaded by a particular + * scaling method that somehow computes the scaling vectors dx, + * dc, and dd. The pointers to those vectors can be NULL, in + * which case no scaling for that item will be done later. */ + virtual void DetermineScalingParametersImpl( + const SmartPtr x_space, + const SmartPtr c_space, + const SmartPtr d_space, + const SmartPtr jac_c_space, + const SmartPtr jac_d_space, + const SmartPtr h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U, + Number& df, + SmartPtr& dx, + SmartPtr& dc, + SmartPtr& dd)=0; + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + StandardScalingBase(const StandardScalingBase&); + + /** Overloaded Equals Operator */ + void operator=(const StandardScalingBase&); + //@} + + /** Scaling parameters - we only need to keep copies of + * the objective scaling and the x scaling - the others we can + * get from the scaled matrix spaces. + */ + //@{ + /** objective scaling parameter */ + Number df_; + /** x scaling */ + SmartPtr dx_; + //@} + + /** Scaled Matrix Spaces */ + //@{ + /** Scaled jacobian of c space */ + SmartPtr scaled_jac_c_space_; + /** Scaled jacobian of d space */ + SmartPtr scaled_jac_d_space_; + /** Scaled hessian of lagrangian spacea */ + SmartPtr scaled_h_space_; + //@} + + /** @name Algorithmic parameters */ + //@{ + /** Additional scaling value for the objective function */ + Number obj_scaling_factor_; + //@} + }; + + /** Class implementing the scaling object that doesn't to any scaling */ + class NoNLPScalingObject : public StandardScalingBase + { + public: + /**@name Constructors/Destructors */ + //@{ + NoNLPScalingObject() + {} + + /** Default destructor */ + virtual ~NoNLPScalingObject() + {} + //@} + + + protected: + /** Overloaded from StandardScalingBase */ + virtual void DetermineScalingParametersImpl( + const SmartPtr x_space, + const SmartPtr c_space, + const SmartPtr d_space, + const SmartPtr jac_c_space, + const SmartPtr jac_d_space, + const SmartPtr h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U, + Number& df, + SmartPtr& dx, + SmartPtr& dc, + SmartPtr& dd); + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + NoNLPScalingObject(const NoNLPScalingObject&); + + /** Overloaded Equals Operator */ + void operator=(const NoNLPScalingObject&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpObserver.hpp b/thirdparty/linux/include/coin/IpObserver.hpp new file mode 100644 index 0000000..99f88b3 --- /dev/null +++ b/thirdparty/linux/include/coin/IpObserver.hpp @@ -0,0 +1,366 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpObserver.hpp 2161 2013-01-01 20:39:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPOBSERVER_HPP__ +#define __IPOBSERVER_HPP__ + +#include "IpUtils.hpp" +#include +#include + +//#define IP_DEBUG_OBSERVER +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_OBSERVER +#endif +#ifdef IP_DEBUG_OBSERVER +# include "IpDebug.hpp" +#endif + +namespace Ipopt +{ + /** Forward declarations */ + class Subject; + + /** Slight Variation of the Observer Design Pattern. + * This class implements the Observer class of the + * Observer Design Pattern. An Observer "Attach"es + * to a Subject, indicating that it would like to + * be notified of changes in the Subject. + * Any derived class wishing to recieve notifications + * from a Subject should inherit off of + * Observer and overload the protected method, + * RecieveNotification_(...). + */ + class Observer + { + public: +#ifdef IP_DEBUG_OBSERVER + + static const Index dbg_verbosity; +#endif + + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + Observer() + {} + + /** Default destructor */ + inline + virtual ~Observer(); + //@} + + /** Enumeration specifying the type of notification */ + enum NotifyType + { + NT_All, + NT_BeingDestroyed, + NT_Changed + }; + + protected: + /** Derived classes should call this method + * to request an "Attach" to a Subject. Do + * not call "Attach" explicitly on the Subject + * since further processing is done here + */ + inline + void RequestAttach(NotifyType notify_type, const Subject* subject); + + /** Derived classes should call this method + * to request a "Detach" to a Subject. Do + * not call "Detach" explicitly on the Subject + * since further processing is done here + */ + inline + void RequestDetach(NotifyType notify_type, const Subject* subject); + + /** Derived classes should overload this method to + * recieve the requested notification from + * attached Subjects + */ + virtual void RecieveNotification(NotifyType notify_type, const Subject* subject)=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Observer(const Observer&); + + /** Overloaded Equals Operator */ + void operator=(const Observer&); + //@} + + /** A list of the subjects currently being + * observed. */ + std::vector subjects_; + + /** Private Method for Recieving Notification + * should only be called by the friend class + * Subject. This method will, in turn, call + * the overloaded RecieveNotification method + * for the derived class to process. + */ + inline + void ProcessNotification(NotifyType notify_type, const Subject* subject); + + friend class Subject; + }; + + /** Slight Variation of the Observer Design Pattern (Subject part). + * This class implements the Subject class of the Observer Design + * Pattern. An Observer "Attach"es to a Subject, indicating that it + * would like to be notified of changes in the Subject. Any + * derived class that is to be observed has to inherit off the + * Subject base class. If the subject needs to notify the + * Observer, it calls the Notify method. + */ + class Subject + { + public: +#ifdef IP_DEBUG_OBSERVER + + static const Index dbg_verbosity; +#endif + + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + Subject() + {} + + /** Default destructor */ + inline + virtual ~Subject(); + //@} + + /**@name Methods to Add and Remove Observers. + * Currently, the notify_type flags are not used, + * and Observers are attached in general and will + * recieve all notifications (of the type requested + * and possibly of types not requested). It is + * up to the observer to ignore the types they + * are not interested in. The NotifyType in the + * parameter list is so a more efficient mechanism + * depending on type could be implemented later if + * necessary.*/ + //@{ + + /** Attach the specified observer + * (i.e., begin recieving notifications). */ + inline + void AttachObserver(Observer::NotifyType notify_type, Observer* observer) const; + + /** Detach the specified observer + * (i.e., no longer recieve notifications). */ + inline + void DetachObserver(Observer::NotifyType notify_type, Observer* observer) const; + //@} + + protected: + + inline + void Notify(Observer::NotifyType notify_type) const; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Subject(const Subject&); + + /** Overloaded Equals Operator */ + void operator=(const Subject&); + //@} + + mutable std::vector observers_; + + }; + + /* inline methods */ + inline + Observer::~Observer() + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::~Observer", dbg_verbosity); + if (DBG_VERBOSITY()>=1) { + for (Index i=0; i<(Index)subjects_.size(); i++) { + DBG_PRINT((1,"subjects_[%d] = 0x%x\n", i, subjects_[i])); + } + } +#endif + // Detach all subjects + for (Int i=(Int)(subjects_.size()-1); i>=0; i--) { +#ifdef IP_DEBUG_OBSERVER + DBG_PRINT((1,"About to detach subjects_[%d] = 0x%x\n", i, subjects_[i])); +#endif + + RequestDetach(NT_All, subjects_[i]); + } + } + + inline + void Observer::RequestAttach(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::RequestAttach", dbg_verbosity); + + // Add the subject to the list if it does not already exist + std::vector::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); + DBG_ASSERT(attached_subject == subjects_.end()); + DBG_ASSERT(subject); +#endif + + // add the subject to the list + subjects_.push_back(subject); + // Attach the observer to the subject + subject->AttachObserver(notify_type, this); + } + + inline + void Observer::RequestDetach(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::RequestDetach", dbg_verbosity); + DBG_PRINT((1, "Requesting detach of subject: 0x%x\n", subject)); + DBG_ASSERT(subject); +#endif + + if (subject) { + std::vector::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_subject != subjects_.end()); +#endif + + if (attached_subject != subjects_.end()) { +#ifdef IP_DEBUG_OBSERVER + DBG_PRINT((1, "Removing subject: 0x%x from the list\n", subject)); +#endif + + subjects_.erase(attached_subject); + } + + // Detach the observer from the subject + subject->DetachObserver(notify_type, this); + } + } + + inline + void Observer::ProcessNotification(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::ProcessNotification", dbg_verbosity); + DBG_ASSERT(subject); +#endif + + if (subject) { + std::vector::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); + + // We must be processing a notification for a + // subject that was previously attached. +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_subject != subjects_.end()); +#endif + + this->RecieveNotification(notify_type, subject); + + if (notify_type == NT_BeingDestroyed) { + // the subject is going away, remove it from our list + subjects_.erase(attached_subject); + } + } + } + + inline + Subject::~Subject() + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::~Subject", dbg_verbosity); +#endif + + std::vector::iterator iter; + for (iter = observers_.begin(); iter != observers_.end(); iter++) { + (*iter)->ProcessNotification(Observer::NT_BeingDestroyed, this); + } + } + + inline + void Subject::AttachObserver(Observer::NotifyType /* notify_type */, Observer* observer) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::AttachObserver", dbg_verbosity); + // current implementation notifies all observers of everything + // they must filter the notifications that they are not interested + // in (i.e. a hub, not a router) + DBG_ASSERT(observer); + + std::vector::iterator attached_observer; + attached_observer = std::find(observers_.begin(), observers_.end(), observer); + DBG_ASSERT(attached_observer == observers_.end()); + + DBG_ASSERT(observer); +#endif + + observers_.push_back(observer); + } + + inline + void Subject::DetachObserver(Observer::NotifyType /* notify_type */, Observer* observer) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::DetachObserver", dbg_verbosity); + DBG_ASSERT(observer); +#endif + + if (observer) { + std::vector::iterator attached_observer; + attached_observer = std::find(observers_.begin(), observers_.end(), observer); +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_observer != observers_.end()); +#endif + + if (attached_observer != observers_.end()) { + observers_.erase(attached_observer); + } + } + } + + inline + void Subject::Notify(Observer::NotifyType notify_type) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::Notify", dbg_verbosity); +#endif + + std::vector::iterator iter; + for (iter = observers_.begin(); iter != observers_.end(); iter++) { + (*iter)->ProcessNotification(notify_type, this); + } + } + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpOptionsList.hpp b/thirdparty/linux/include/coin/IpOptionsList.hpp new file mode 100644 index 0000000..a17863f --- /dev/null +++ b/thirdparty/linux/include/coin/IpOptionsList.hpp @@ -0,0 +1,289 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpOptionsList.hpp 2613 2015-11-04 14:42:02Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPOPTLIST_HPP__ +#define __IPOPTLIST_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpRegOptions.hpp" + +#include +#include + +namespace Ipopt +{ + /** Exception that can be used to indicate errors with options */ + DECLARE_STD_EXCEPTION(OPTION_INVALID); + + /** This class stores a list of user set options. Each options is + * identified by a case-insensitive keyword (tag). Its value is + * stored internally as a string (always lower case), but for + * convenience set and get methods are provided to obtain Index and + * Number type values. For each keyword we also keep track of how + * often the value of an option has been requested by a get method. + */ + class OptionsList : public ReferencedObject + { + /** Class for storing the value and counter for each option in + * OptionsList. */ + class OptionValue + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor (needed for the map) */ + OptionValue() + : + initialized_(false) + {} + + /** Constructor given the value */ + OptionValue(std::string value, bool allow_clobber, bool dont_print) + : + value_(value), + counter_(0), + initialized_(true), + allow_clobber_(allow_clobber), + dont_print_(dont_print) + {} + + /** Copy Constructor */ + OptionValue(const OptionValue& copy) + : + value_(copy.value_), + counter_(copy.counter_), + initialized_(copy.initialized_), + allow_clobber_(copy.allow_clobber_), + dont_print_(copy.dont_print_) + {} + + /** Equals operator */ + void operator=(const OptionValue& copy) + { + value_=copy.value_; + counter_=copy.counter_; + initialized_=copy.initialized_; + allow_clobber_=copy.allow_clobber_; + dont_print_=copy.dont_print_; + } + + /** Default Destructor */ + ~OptionValue() + {} + //@} + + /** Method for retrieving the value of an option. Calling this + * method will increase the counter by one. */ + std::string GetValue() const + { + DBG_ASSERT(initialized_); + counter_++; + return value_; + } + + /** Method for retrieving the value without increasing the + * counter */ + std::string Value() const + { + DBG_ASSERT(initialized_); + return value_; + } + + /** Method for accessing current value of the request counter */ + Index Counter() const + { + DBG_ASSERT(initialized_); + return counter_; + } + + /** True if the option can be overwritten */ + bool AllowClobber() const + { + DBG_ASSERT(initialized_); + return allow_clobber_; + } + + /** True if this option is not to show up in the + * print_user_options output */ + bool DontPrint() const + { + DBG_ASSERT(initialized_); + return dont_print_; + } + + private: + /** Value for this option */ + std::string value_; + + /** Counter for requests */ + mutable Index counter_; + + /** for debugging */ + bool initialized_; + + /** True if the option can be overwritten */ + bool allow_clobber_; + + /** True if this option is not to show up in the + * print_user_options output */ + bool dont_print_; + }; + + public: + /**@name Constructors/Destructors */ + //@{ + OptionsList(SmartPtr reg_options, SmartPtr jnlst) + : reg_options_(reg_options), jnlst_(jnlst) + {} + + OptionsList() + {} + + /** Copy Constructor */ + OptionsList(const OptionsList& copy) + { + // copy all the option strings and values + options_ = copy.options_; + // copy the registered options pointer + reg_options_ = copy.reg_options_; + } + + /** Default destructor */ + virtual ~OptionsList() + {} + + /** Overloaded Equals Operator */ + virtual void operator=(const OptionsList& source) + { + options_ = source.options_; + reg_options_ = source.reg_options_; + jnlst_ = source.jnlst_; + } + //@} + + /** Method for clearing all previously set options */ + virtual void clear() + { + options_.clear(); + } + + /** @name Get / Set Methods */ + //@{ + virtual void SetRegisteredOptions(const SmartPtr reg_options) + { + reg_options_ = reg_options; + } + virtual void SetJournalist(const SmartPtr jnlst) + { + jnlst_ = jnlst; + } + //@} + /** @name Methods for setting options */ + //@{ + virtual bool SetStringValue(const std::string& tag, const std::string& value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetNumericValue(const std::string& tag, Number value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetIntegerValue(const std::string& tag, Index value, + bool allow_clobber = true, bool dont_print = false); + //@} + + /** @name Methods for setting options only if they have not been + * set before*/ + //@{ + virtual bool SetStringValueIfUnset(const std::string& tag, const std::string& value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetNumericValueIfUnset(const std::string& tag, Number value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetIntegerValueIfUnset(const std::string& tag, Index value, + bool allow_clobber = true, bool dont_print = false); + //@} + + /** @name Methods for retrieving values from the options list. If + * a tag is not found, the methods return false, and value is set + * to the default value defined in the registered options. */ + //@{ + virtual bool GetStringValue(const std::string& tag, std::string& value, + const std::string& prefix) const; + virtual bool GetEnumValue(const std::string& tag, Index& value, + const std::string& prefix) const; + virtual bool GetBoolValue(const std::string& tag, bool& value, + const std::string& prefix) const; + virtual bool GetNumericValue(const std::string& tag, Number& value, + const std::string& prefix) const; + virtual bool GetIntegerValue(const std::string& tag, Index& value, + const std::string& prefix) const; + //@} + + /** Get a string with the list of all options (tag, value, counter) */ + virtual void PrintList(std::string& list) const; + + /** Get a string with the list of all options set by the user + * (tag, value, use/notused). Here, options with dont_print flag + * set to true are not printed. */ + virtual void PrintUserOptions(std::string& list) const; + + /** Read options from the stream is. Returns false if + * an error was encountered. */ + virtual bool ReadFromStream(const Journalist& jnlst, std::istream& is, bool allow_clobber = false); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // OptionsList(); + + //@} + + /** map for storing the options */ + std::map< std::string, OptionValue > options_; + + /** list of all the registered options to validate against */ + SmartPtr reg_options_; + + /** Journalist for writing error messages, etc. */ + SmartPtr jnlst_; + + /** auxilliary method for converting sting to all lower-case + * letters */ + const std::string& lowercase(const std::string tag) const; + + /** auxilliary method for finding the value for a tag in the + * options list. This method first looks for the concatenated + * string prefix+tag (if prefix is not ""), and if this is not + * found, it looks for tag. The return value is true iff + * prefix+tag or tag is found. In that case, the corresponding + * string value is copied into value. */ + bool find_tag(const std::string& tag, const std::string& prefix, + std::string& value) const; + + /** tells whether or not we can clobber a particular option. + * returns true if the option does not already exist, or if + * the option exists but is set to allow_clobber + */ + bool will_allow_clobber(const std::string& tag) const; + + /** read the next token from stream is. Returns false, if EOF was + * reached before a tokens was ecountered. */ + bool readnexttoken(std::istream& is, std::string& token); + + /** auxilliary string set by lowercase method */ + mutable std::string lowercase_buffer_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpOrigIpoptNLP.hpp b/thirdparty/linux/include/coin/IpOrigIpoptNLP.hpp new file mode 100644 index 0000000..41b10fa --- /dev/null +++ b/thirdparty/linux/include/coin/IpOrigIpoptNLP.hpp @@ -0,0 +1,488 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpOrigIpoptNLP.hpp 2594 2015-08-09 14:31:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPORIGIPOPTNLP_HPP__ +#define __IPORIGIPOPTNLP_HPP__ + +#include "IpIpoptNLP.hpp" +#include "IpException.hpp" +#include "IpTimingStatistics.hpp" + +namespace Ipopt +{ + + /** enumeration for the Hessian information type. */ + enum HessianApproximationType { + EXACT=0, + LIMITED_MEMORY + }; + + /** enumeration for the Hessian approximation space. */ + enum HessianApproximationSpace { + NONLINEAR_VARS=0, + ALL_VARS + }; + + /** This class maps the traditional NLP into + * something that is more useful by Ipopt. + * This class takes care of storing the + * calculated model results, handles caching, + * and (some day) takes care of addition of slacks. + */ + class OrigIpoptNLP : public IpoptNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + OrigIpoptNLP(const SmartPtr& jnlst, + const SmartPtr& nlp, + const SmartPtr& nlp_scaling); + + /** Default destructor */ + virtual ~OrigIpoptNLP(); + //@} + + /** Initialize - overloaded from IpoptNLP */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Initialize (create) structures for + * the iteration data */ + virtual bool InitializeStructures(SmartPtr& x, + bool init_x, + SmartPtr& y_c, + bool init_y_c, + SmartPtr& y_d, + bool init_y_d, + SmartPtr& z_L, + bool init_z_L, + SmartPtr& z_U, + bool init_z_U, + SmartPtr& v_L, + SmartPtr& v_U + ); + + /** Method accessing the GetWarmStartIterate of the NLP */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate) + { + return nlp_->GetWarmStartIterate(warm_start_iterate); + } + /** Accessor methods for model data */ + //@{ + /** Objective value */ + virtual Number f(const Vector& x); + + /** Objective value (depending in mu) - incorrect version for + * OrigIpoptNLP */ + virtual Number f(const Vector& x, Number mu); + + /** Gradient of the objective */ + virtual SmartPtr grad_f(const Vector& x); + + /** Gradient of the objective (depending in mu) - incorrect + * version for OrigIpoptNLP */ + virtual SmartPtr grad_f(const Vector& x, Number mu); + + /** Equality constraint residual */ + virtual SmartPtr c(const Vector& x); + + /** Jacobian Matrix for equality constraints */ + virtual SmartPtr jac_c(const Vector& x); + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + virtual SmartPtr d(const Vector& x); + + /** Jacobian Matrix for inequality constraints*/ + virtual SmartPtr jac_d(const Vector& x); + + /** Hessian of the Lagrangian */ + virtual SmartPtr h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd + ); + + /** Hessian of the Lagrangian (depending in mu) - incorrect + * version for OrigIpoptNLP */ + virtual SmartPtr h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + Number mu); + + /** Provides a Hessian matrix from the correct matrix space with + * uninitialized values. This can be used in LeastSquareMults to + * obtain a "zero Hessian". */ + virtual SmartPtr uninitialized_h(); + + /** Lower bounds on x */ + virtual SmartPtr x_L() const + { + return x_L_; + } + + /** Permutation matrix (x_L_ -> x) */ + virtual SmartPtr Px_L() const + { + return Px_L_; + } + + /** Upper bounds on x */ + virtual SmartPtr x_U() const + { + return x_U_; + } + + /** Permutation matrix (x_U_ -> x */ + virtual SmartPtr Px_U() const + { + return Px_U_; + } + + /** Lower bounds on d */ + virtual SmartPtr d_L() const + { + return d_L_; + } + + /** Permutation matrix (d_L_ -> d) */ + virtual SmartPtr Pd_L() const + { + return Pd_L_; + } + + /** Upper bounds on d */ + virtual SmartPtr d_U() const + { + return d_U_; + } + + /** Permutation matrix (d_U_ -> d */ + virtual SmartPtr Pd_U() const + { + return Pd_U_; + } + + virtual SmartPtr HessianMatrixSpace() const + { + return h_space_; + } + + virtual SmartPtr x_space() const + { + return x_space_; + } + //@} + + /** Accessor method for vector/matrix spaces pointers */ + virtual void GetSpaces(SmartPtr& x_space, + SmartPtr& c_space, + SmartPtr& d_space, + SmartPtr& x_l_space, + SmartPtr& px_l_space, + SmartPtr& x_u_space, + SmartPtr& px_u_space, + SmartPtr& d_l_space, + SmartPtr& pd_l_space, + SmartPtr& d_u_space, + SmartPtr& pd_u_space, + SmartPtr& Jac_c_space, + SmartPtr& Jac_d_space, + SmartPtr& Hess_lagrangian_space); + + /** Method for adapting the variable bounds. This is called if + * slacks are becoming too small */ + virtual void AdjustVariableBounds(const Vector& new_x_L, + const Vector& new_x_U, + const Vector& new_d_L, + const Vector& new_d_U); + + /** @name Counters for the number of function evaluations. */ + //@{ + virtual Index f_evals() const + { + return f_evals_; + } + virtual Index grad_f_evals() const + { + return grad_f_evals_; + } + virtual Index c_evals() const + { + return c_evals_; + } + virtual Index jac_c_evals() const + { + return jac_c_evals_; + } + virtual Index d_evals() const + { + return d_evals_; + } + virtual Index jac_d_evals() const + { + return jac_d_evals_; + } + virtual Index h_evals() const + { + return h_evals_; + } + //@} + + /** Solution Routines - overloaded from IpoptNLP*/ + //@{ + void FinalizeSolution(SolverReturn status, + const Vector& x, const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + SmartPtr ip_data, + SmartPtr ip_cq); + //@} + + /** @name Methods for IpoptType */ + //@{ + /** Called by IpoptType to register the options */ + static void RegisterOptions(SmartPtr roptions); + //@} + + /** Accessor method to the underlying NLP */ + SmartPtr nlp() + { + return nlp_; + } + + /**@name Methods related to function evaluation timing. */ + //@{ + + /** Reset the timing statistics */ + void ResetTimes(); + + void PrintTimingStatistics(Journalist& jnlst, + EJournalLevel level, + EJournalCategory category) const; + + const TimedTask& f_eval_time() const + { + return f_eval_time_; + } + const TimedTask& grad_f_eval_time() const + { + return grad_f_eval_time_; + } + const TimedTask& c_eval_time() const + { + return c_eval_time_; + } + const TimedTask& jac_c_eval_time() const + { + return jac_c_eval_time_; + } + const TimedTask& d_eval_time() const + { + return d_eval_time_; + } + const TimedTask& jac_d_eval_time() const + { + return jac_d_eval_time_; + } + const TimedTask& h_eval_time() const + { + return h_eval_time_; + } + + Number TotalFunctionEvaluationCpuTime() const; + Number TotalFunctionEvaluationSysTime() const; + Number TotalFunctionEvaluationWallclockTime() const; + //@} + + private: + /** journalist */ + SmartPtr jnlst_; + + /** Pointer to the NLP */ + SmartPtr nlp_; + + /** Necessary Vector/Matrix spaces */ + //@{ + SmartPtr x_space_; + SmartPtr c_space_; + SmartPtr d_space_; + SmartPtr x_l_space_; + SmartPtr px_l_space_; + SmartPtr x_u_space_; + SmartPtr px_u_space_; + SmartPtr d_l_space_; + SmartPtr pd_l_space_; + SmartPtr d_u_space_; + SmartPtr pd_u_space_; + SmartPtr jac_c_space_; + SmartPtr jac_d_space_; + SmartPtr h_space_; + + SmartPtr scaled_jac_c_space_; + SmartPtr scaled_jac_d_space_; + SmartPtr scaled_h_space_; + //@} + /**@name Storage for Model Quantities */ + //@{ + /** Objective function */ + CachedResults f_cache_; + + /** Gradient of the objective function */ + CachedResults > grad_f_cache_; + + /** Equality constraint residuals */ + CachedResults > c_cache_; + + /** Jacobian Matrix for equality constraints + * (current iteration) */ + CachedResults > jac_c_cache_; + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + CachedResults > d_cache_; + + /** Jacobian Matrix for inequality constraints + * (current iteration) */ + CachedResults > jac_d_cache_; + + /** Hessian of the lagrangian + * (current iteration) */ + CachedResults > h_cache_; + + /** Unscaled version of x vector */ + CachedResults > unscaled_x_cache_; + + /** Lower bounds on x */ + SmartPtr x_L_; + + /** Permutation matrix (x_L_ -> x) */ + SmartPtr Px_L_; + + /** Upper bounds on x */ + SmartPtr x_U_; + + /** Permutation matrix (x_U_ -> x */ + SmartPtr Px_U_; + + /** Lower bounds on d */ + SmartPtr d_L_; + + /** Permutation matrix (d_L_ -> d) */ + SmartPtr Pd_L_; + + /** Upper bounds on d */ + SmartPtr d_U_; + + /** Permutation matrix (d_U_ -> d */ + SmartPtr Pd_U_; + + /** Original unmodified lower bounds on x */ + SmartPtr orig_x_L_; + + /** Original unmodified upper bounds on x */ + SmartPtr orig_x_U_; + //@} + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + OrigIpoptNLP(); + + /** Copy Constructor */ + OrigIpoptNLP(const OrigIpoptNLP&); + + /** Overloaded Equals Operator */ + void operator=(const OrigIpoptNLP&); + //@} + + /** @name auxilliary functions */ + //@{ + /** relax the bounds by a relative move of relax_bound_factor. + * Here, relax_bound_factor should be negative (or zero) for + * lower bounds, and positive (or zero) for upper bounds. + */ + void relax_bounds(Number bound_relax_factor, Vector& bounds); + /** Method for getting the unscaled version of the x vector */ + SmartPtr get_unscaled_x(const Vector& x); + //@} + + /** @name Algorithmic parameters */ + //@{ + /** relaxation factor for the bounds */ + Number bound_relax_factor_; + /** Flag indicating whether the primal variables should be + * projected back into original bounds are optimization. */ + bool honor_original_bounds_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Flag indicating what Hessian information is to be used. */ + HessianApproximationType hessian_approximation_; + /** Flag indicating in which space Hessian is to be approximated. */ + HessianApproximationSpace hessian_approximation_space_; + /** Flag indicating whether it is desired to check if there are + * Nan or Inf entries in first and second derivative matrices. */ + bool check_derivatives_for_naninf_; + /** Flag indicating if we need to ask for equality constraint + * Jacobians only once */ + bool jac_c_constant_; + /** Flag indicating if we need to ask for inequality constraint + * Jacobians only once */ + bool jac_d_constant_; + /** Flag indicating if we need to ask for Hessian only once */ + bool hessian_constant_; + //@} + + /** @name Counters for the function evaluations */ + //@{ + Index f_evals_; + Index grad_f_evals_; + Index c_evals_; + Index jac_c_evals_; + Index d_evals_; + Index jac_d_evals_; + Index h_evals_; + //@} + + /** Flag indicating if initialization method has been called */ + bool initialized_; + + /**@name Timing statistics for the function evaluations. */ + //@{ + TimedTask f_eval_time_; + TimedTask grad_f_eval_time_; + TimedTask c_eval_time_; + TimedTask jac_c_eval_time_; + TimedTask d_eval_time_; + TimedTask jac_d_eval_time_; + TimedTask h_eval_time_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpPDSystemSolver.hpp b/thirdparty/linux/include/coin/IpPDSystemSolver.hpp new file mode 100644 index 0000000..b436e67 --- /dev/null +++ b/thirdparty/linux/include/coin/IpPDSystemSolver.hpp @@ -0,0 +1,130 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpPDSystemSolver.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPPDSYSTEMSOLVER_HPP__ +#define __IPPDSYSTEMSOLVER_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" +#include "IpAlgStrategy.hpp" +#include "IpIteratesVector.hpp" + +namespace Ipopt +{ + + /** Pure Primal Dual System Solver Base Class. + * This is the base class for all derived Primal-Dual System Solver Types. + * + * Here, we understand the primal-dual system as the following linear + * system: + * + * \f$ + * \left[\begin{array}{cccccccc} + * W & 0 & J_c^T & J_d^T & -P^x_L & P^x_U & 0 & 0 \\ + * 0 & 0 & 0 & -I & 0 & 0 & -P_L^d & P_U^d \\ + * J_c & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ + * J_d & -I & 0 & 0 & 0 & 0 & 0 & 0\\ + * Z_L(P_L^x)^T & 0 & 0 & 0 & Sl^x_L & 0 & 0 & 0\\ + * -Z_U(P_U^x)^T & 0 & 0 & 0 & 0 & Sl^x_U & 0 & 0\\ + * 0 & V_L(P_L^d)^T & 0 & 0 & 0 & 0 & Sl^s_L & 0 \\ + * 0 & -V_U(P_U^d)^T & 0 & 0 & 0 & 0 & 0 & Sl^s_U \\ + * \end{array}\right] + * \left(\begin{array}{c} + * sol_x\\ sol_s\\ sol_c\\ sol_d\\ sol^z_L\\ sol^z_U\\ sol^v_L\\ + * sol^v_U + * \end{array}\right) = + * \left(\begin{array}{c} + * rhs_x\\ rhs_s\\ rhs_c\\ rhs_d\\ rhs^z_L\\ rhs^z_U\\ rhs^v_L\\ + * rhs^v_U + * \end{array}\right) + * \f$ + * + * Here, \f$Sl^x_L = (P^x_L)^T x - x_L\f$, + * \f$Sl^x_U = x_U - (P^x_U)^T x\f$, \f$Sl^d_L = (P^d_L)^T d(x) - d_L\f$, + * \f$Sl^d_U = d_U - (P^d_U)^T d(x)\f$. The results returned to the + * caller is \f$res = \alpha * sol + \beta * res\f$. + * + * The solution of this linear system (in order to compute the search + * direction of the algorthim) usually requires a considerable amount of + * computation time. Therefore, it is important to tailor the solution + * of this system to the characteristics of the problem. The purpose of + * this base class is to provide a generic interface to the algorithm + * that it can use whenever it requires a solution of the above system. + * Particular implementation can then be written to provide the methods + * defined here. + * + * It is implicitly assumed here, that the upper left 2 by 2 block + * is possibly modified (implicitly or explicitly) so that its + * projection onto the null space of the overall constraint + * Jacobian \f$\left[\begin{array}{cc}J_c & 0\\J_d & + * -I\end{array}\right]\f$ is positive definite. This is necessary + * to guarantee certain descent properties of the resulting search + * direction. For example, in the full space implementation, a + * multiple of the identity might be added to the upper left 2 by 2 + * block. + * + * Note that the Solve method might be called several times for different + * right hand sides, but with identical data. Therefore, if possible, + * an implemetation of PDSystem should check whether the incoming data has + * changed, and not redo factorization etc. unless necessary. + */ + class PDSystemSolver: public AlgorithmStrategyObject + { + public: + /** @name /Destructor */ + //@{ + /** Default Constructor */ + PDSystemSolver() + {} + + /** Default destructor */ + virtual ~PDSystemSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Solve the primal dual system, given one right hand side. If + * the flag allow_inexact is set to true, it is not necessary to + * solve the system to best accuracy; for example, we don't want + * iterative refinement during the computation of the second + * order correction. On the other hand, if improve_solution is + * true, the solution given in res should be improved (here beta + * has to be zero, and res is assume to be the solution for the + * system using rhs, without the factor alpha...). THe return + * value is false, if a solution could not be computed (for + * example, when the Hessian regularization parameter becomes too + * large.) + */ + virtual bool Solve(Number alpha, + Number beta, + const IteratesVector& rhs, + IteratesVector& res, + bool allow_inexact=false, + bool improve_solution=false) =0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Overloaded Equals Operator */ + PDSystemSolver& operator=(const PDSystemSolver&); + //@} + }; + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpReferenced.hpp b/thirdparty/linux/include/coin/IpReferenced.hpp new file mode 100644 index 0000000..dd71434 --- /dev/null +++ b/thirdparty/linux/include/coin/IpReferenced.hpp @@ -0,0 +1,258 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReferenced.hpp 2182 2013-03-30 20:02:18Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPREFERENCED_HPP__ +#define __IPREFERENCED_HPP__ + +#include "IpTypes.hpp" +#include "IpDebug.hpp" + +#include + +#if COIN_IPOPT_CHECKLEVEL > 3 + #define IP_DEBUG_REFERENCED +#endif + +namespace Ipopt +{ + + /** Psydo-class, from which everything has to inherit that wants to + * use be registered as a Referencer for a ReferencedObject. + */ + class Referencer + {} + ; + + /** ReferencedObject class. + * This is part of the implementation of an intrusive smart pointer + * design. This class stores the reference count of all the smart + * pointers that currently reference it. See the documentation for + * the SmartPtr class for more details. + * + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "IpReferenced.hpp" + + * namespace Ipopt { + * + * class MyClass : public ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * } // namespace Ipopt + * + * + * In my_usage.cpp... + * + * #include "IpSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * For every most derived object only one ReferencedObject may exist, + * that is multiple inheritance requires virtual inheritance, see also + * the 2nd point in ticket #162. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + class ReferencedObject + { + public: + ReferencedObject() + : + reference_count_(0) + {} + + virtual ~ReferencedObject() + { + DBG_ASSERT(reference_count_ == 0); + } + + inline + Index ReferenceCount() const; + + inline + void AddRef(const Referencer* referencer) const; + + inline + void ReleaseRef(const Referencer* referencer) const; + + private: + mutable Index reference_count_; + +# ifdef IP_DEBUG_REFERENCED + mutable std::list referencers_; +# endif + + }; + + /* inline methods */ + inline + Index ReferencedObject::ReferenceCount() const + { + // DBG_START_METH("ReferencedObject::ReferenceCount()", 0); + // DBG_PRINT((1,"Returning reference_count_ = %d\n", reference_count_)); + return reference_count_; + } + + inline + void ReferencedObject::AddRef(const Referencer* /* referencer */) const + { + // DBG_START_METH("ReferencedObject::AddRef(const Referencer* referencer)", 0); + reference_count_++; + // DBG_PRINT((1, "New reference_count_ = %d\n", reference_count_)); +# ifdef IP_DEBUG_REFERENCED + referencers_.push_back(referencer); +# endif + + } + + inline + void ReferencedObject::ReleaseRef(const Referencer* /* referencer */) const + { + // DBG_START_METH("ReferencedObject::ReleaseRef(const Referencer* referencer)", + // 0); + reference_count_--; + // DBG_PRINT((1, "New reference_count_ = %d\n", reference_count_)); + +# ifdef IP_DEBUG_REFERENCED + + bool found = false; + std::list::iterator iter; + for (iter = referencers_.begin(); iter != referencers_.end(); iter++) { + if ((*iter) == referencer) { + found = true; + break; + } + } + + // cannot call release on a reference that was never added... + DBG_ASSERT(found); + + if (found) { + referencers_.erase(iter); + } +# endif + + } + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpRegOptions.hpp b/thirdparty/linux/include/coin/IpRegOptions.hpp new file mode 100644 index 0000000..5859493 --- /dev/null +++ b/thirdparty/linux/include/coin/IpRegOptions.hpp @@ -0,0 +1,658 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpRegOptions.hpp 2189 2013-03-31 15:06:11Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-06-18 + +#ifndef __IPREGOPTIONS_HPP__ +#define __IPREGOPTIONS_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpSmartPtr.hpp" + +#include + +namespace Ipopt +{ + + enum RegisteredOptionType + { + OT_Number, + OT_Integer, + OT_String, + OT_Unknown + }; + + /** Base class for registered options. The derived types are more + * specific to a string option or a Number (real) option, etc. + */ + class RegisteredOption : public ReferencedObject + { + public: + /** class to hold the valid string settings for a string option */ + class string_entry + { + public: + string_entry(const std::string& value, const std::string& description) + : value_(value), description_(description) + {} + std::string value_; + std::string description_; + }; + + /** Constructors / Destructors */ + //@{ + RegisteredOption(Index counter) + : + type_(OT_Unknown), + has_lower_(false), + has_upper_(false), + counter_(counter) + {} + + RegisteredOption(const std::string& name, + const std::string& short_description, + const std::string& long_description, + const std::string& registering_category, + Index counter) + : + name_(name), + short_description_(short_description), + long_description_(long_description), + registering_category_(registering_category), + type_(OT_Unknown), + has_lower_(false), + has_upper_(false), + counter_(counter) + {} + + RegisteredOption(const RegisteredOption& copy) + : + name_(copy.name_), + short_description_(copy.short_description_), + long_description_(copy.long_description_), + registering_category_(copy.registering_category_), + type_(copy.type_), + has_lower_(copy.has_lower_), + lower_(copy.lower_), + has_upper_(copy.has_upper_), + upper_(copy.upper_), + valid_strings_(copy.valid_strings_), + counter_(copy.counter_) + {} + + virtual ~RegisteredOption() + {} + //@} + + DECLARE_STD_EXCEPTION(ERROR_CONVERTING_STRING_TO_ENUM); + + /** Standard Get / Set Methods */ + //@{ + /** Get the option's name (tag in the input file) */ + virtual const std::string& Name() const + { + return name_; + } + /** Set the option's name (tag in the input file) */ + virtual void SetName(const std::string& name) + { + name_ = name; + } + /** Get the short description */ + virtual const std::string& ShortDescription() const + { + return short_description_; + } + /** Get the long description */ + virtual const std::string& LongDescription() const + { + return long_description_; + } + /** Set the short description */ + virtual void SetShortDescription(const std::string& short_description) + { + short_description_ = short_description; + } + /** Set the long description */ + virtual void SetLongDescription(const std::string& long_description) + { + long_description_ = long_description; + } + /** Get the registering class */ + virtual const std::string& RegisteringCategory() const + { + return registering_category_; + } + /** Set the registering class */ + virtual void SetRegisteringCategory(const std::string& registering_category) + { + registering_category_ = registering_category; + } + /** Get the Option's type */ + virtual const RegisteredOptionType& Type() const + { + return type_; + } + /** Get the Option's type */ + virtual void SetType(const RegisteredOptionType& type) + { + type_ = type; + } + /** Counter */ + virtual Index Counter() const + { + return counter_; + } + //@} + + /** @name Get / Set methods valid for specific types - NOTE: the Type + * must be set before calling these methods. + */ + //@{ + /** check if the option has a lower bound - can be called for + * OT_Number & OT_Integer*/ + virtual const bool& HasLower() const + { + DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer); + return has_lower_; + } + /** check if the lower bound is strict - can be called for + OT_Number */ + virtual const bool& LowerStrict() const + { + DBG_ASSERT(type_ == OT_Number && has_lower_ == true); + return lower_strict_; + } + /** get the Number version of the lower bound - can be called for + * OT_Number */ + virtual Number LowerNumber() const + { + DBG_ASSERT(has_lower_ == true && type_ == OT_Number); + return lower_; + } + /** set the Number version of the lower bound - can be called for + * OT_Number */ + virtual void SetLowerNumber(const Number& lower, const bool& strict) + { + DBG_ASSERT(type_ == OT_Number); + lower_ = lower; + lower_strict_ = strict, has_lower_ = true; + } + /** get the Integer version of the lower bound can be called for + * OT_Integer*/ + virtual Index LowerInteger() const + { + DBG_ASSERT(has_lower_ == true && type_ == OT_Integer); + return (Index)lower_; + } + /** set the Integer version of the lower bound - can be called for + * OT_Integer */ + virtual void SetLowerInteger(const Index& lower) + { + DBG_ASSERT(type_ == OT_Integer); + lower_ = (Number)lower; + has_lower_ = true; + } + /** check if the option has an upper bound - can be called for + * OT_Number & OT_Integer*/ + virtual const bool& HasUpper() const + { + DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer); + return has_upper_; + } + /** check if the upper bound is strict - can be called for + * OT_Number */ + virtual const bool& UpperStrict() const + { + DBG_ASSERT(type_ == OT_Number && has_upper_ == true); + return upper_strict_; + } + /** get the Number version of the upper bound - can be called for + * OT_Number */ + virtual Number UpperNumber() const + { + DBG_ASSERT(has_upper_ == true && type_ == OT_Number); + return upper_; + } + /** set the Number version of the upper bound - can be called for + * OT_Number */ + virtual void SetUpperNumber(const Number& upper, const bool& strict) + { + DBG_ASSERT(type_ == OT_Number); + upper_ = upper; + upper_strict_ = strict; + has_upper_ = true; + } + /** get the Integer version of the upper bound - can be called for + * OT_Integer*/ + virtual Index UpperInteger() const + { + DBG_ASSERT(has_upper_ == true && type_ == OT_Integer); + return (Index)upper_; + } + /** set the Integer version of the upper bound - can be called for + * OT_Integer */ + virtual void SetUpperInteger(const Index& upper) + { + DBG_ASSERT(type_ == OT_Integer); + upper_ = (Number)upper; + has_upper_ = true; + } + /** method to add valid string entries - can be called for + * OT_String */ + virtual void AddValidStringSetting(const std::string value, + const std::string description) + { + DBG_ASSERT(type_ == OT_String); + valid_strings_.push_back(string_entry(value, description)); + } + /** get the default as a Number - can be called for OT_Number */ + virtual Number DefaultNumber() const + { + DBG_ASSERT(type_ == OT_Number); + return default_number_; + } + /** Set the default as a Number - can be called for OT_Number */ + virtual void SetDefaultNumber(const Number& default_value) + { + DBG_ASSERT(type_ == OT_Number); + default_number_ = default_value; + } + /** get the default as an Integer - can be called for OT_Integer*/ + virtual Index DefaultInteger() const + { + DBG_ASSERT(type_ == OT_Integer); + return (Index)default_number_; + } + /** Set the default as an Integer - can be called for + OT_Integer */ + virtual void SetDefaultInteger(const Index& default_value) + { + DBG_ASSERT(type_ == OT_Integer); + default_number_ = (Number)default_value; + } + /** get the default as a string - can be called for OT_String */ + virtual std::string DefaultString() const + { + DBG_ASSERT(type_ == OT_String); + return default_string_; + } + /** get the default as a string, but as the index of the string in + * the list - helps map from a string to an enum- can be called + * for OT_String */ + virtual Index DefaultStringAsEnum() const + { + DBG_ASSERT(type_ == OT_String); + return MapStringSettingToEnum(default_string_); + } + /** Set the default as a string - can be called for OT_String */ + virtual void SetDefaultString(const std::string& default_value) + { + DBG_ASSERT(type_ == OT_String); + default_string_ = default_value; + } + /** get the valid string settings - can be called for OT_String */ + virtual std::vector GetValidStrings() const + { + DBG_ASSERT(type_ == OT_String); + return valid_strings_; + } + /** Check if the Number value is a valid setting - can be called + * for OT_Number */ + virtual bool IsValidNumberSetting(const Number& value) const + { + DBG_ASSERT(type_ == OT_Number); + if (has_lower_ && ((lower_strict_ == true && value <= lower_) || + (lower_strict_ == false && value < lower_))) { + return false; + } + if (has_upper_ && ((upper_strict_ == true && value >= upper_) || + (upper_strict_ == false && value > upper_))) { + return false; + } + return true; + } + /** Check if the Integer value is a valid setting - can be called + * for OT_Integer */ + virtual bool IsValidIntegerSetting(const Index& value) const + { + DBG_ASSERT(type_ == OT_Integer); + if (has_lower_ && value < lower_) { + return false; + } + if (has_upper_ && value > upper_) { + return false; + } + return true; + } + /** Check if the String value is a valid setting - can be called + * for OT_String */ + virtual bool IsValidStringSetting(const std::string& value) const; + + /** Map a user setting (allowing any case) to the case used when + * the setting was registered. + */ + virtual std::string MapStringSetting(const std::string& value) const; + + /** Map a user setting (allowing any case) to the index of the + * matched setting in the list of string settings. Helps map a + * string setting to an enumeration. + */ + virtual Index MapStringSettingToEnum(const std::string& value) const; + //@} + + /** output a description of the option */ + virtual void OutputDescription(const Journalist& jnlst) const; + /** output a more concise version */ + virtual void OutputShortDescription(const Journalist& jnlst) const; + /** output a latex version */ + virtual void OutputLatexDescription(const Journalist& jnlst) const; + + private: + std::string name_; + std::string short_description_; + std::string long_description_; + std::string registering_category_; + RegisteredOptionType type_; + + bool has_lower_; + bool lower_strict_; + Number lower_; + bool has_upper_; + bool upper_strict_; + Number upper_; + Number default_number_; + + void MakeValidLatexString(std::string source, std::string& dest) const; + std::string MakeValidLatexNumber(Number value) const; + + /** Compare two strings and return true if they are equal (case + insensitive comparison) */ + bool string_equal_insensitive(const std::string& s1, + const std::string& s2) const; + + std::vector valid_strings_; + std::string default_string_; + + /** Has the information as how many-th option this one was + * registered. */ + const Index counter_; + }; + + /** Class for storing registered options. Used for validation and + * documentation. + */ + class RegisteredOptions : public ReferencedObject + { + public: + /** Constructors / Destructors */ + //@{ + /** Standard Constructor */ + RegisteredOptions() + : + next_counter_(0), + current_registering_category_("Uncategorized") + {} + + /** Standard Destructor */ + virtual ~RegisteredOptions() + {} + //@} + + DECLARE_STD_EXCEPTION(OPTION_ALREADY_REGISTERED); + + /** Methods to interact with registered options */ + //@{ + /** set the registering class. All subsequent options will be + * added with the registered class */ + virtual void SetRegisteringCategory(const std::string& registering_category) + { + current_registering_category_ = registering_category; + } + + /** retrieve the value of the current registering category */ + virtual std::string RegisteringCategory() + { + return current_registering_category_; + } + + /** Add a Number option (with no restrictions) */ + virtual void AddNumberOption(const std::string& name, + const std::string& short_description, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a lower bound) */ + virtual void AddLowerBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number lower, bool strict, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a upper bound) */ + virtual void AddUpperBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number upper, bool strict, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a both bounds) */ + virtual void AddBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number lower, bool lower_strict, + Number upper, bool upper_strict, + Number default_value, + const std::string& long_description=""); + /** Add a Integer option (with no restrictions) */ + virtual void AddIntegerOption(const std::string& name, + const std::string& short_description, + Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a lower bound) */ + virtual void AddLowerBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index lower, Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a upper bound) */ + virtual void AddUpperBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index upper, Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a both bounds) */ + virtual void AddBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index lower, Index upper, + Index default_value, + const std::string& long_description=""); + + /** Add a String option (with no restrictions) */ + virtual void AddStringOption(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::vector& settings, + const std::vector& descriptions, + const std::string& long_description=""); + /** Methods that make adding string options with only a few + * entries easier */ + virtual void AddStringOption1(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& long_description=""); + virtual void AddStringOption2(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& long_description=""); + virtual void AddStringOption3(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& long_description=""); + virtual void AddStringOption4(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& long_description=""); + virtual void AddStringOption5(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& long_description=""); + virtual void AddStringOption6(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& long_description=""); + virtual void AddStringOption7(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& long_description=""); + virtual void AddStringOption8(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& long_description=""); + virtual void AddStringOption9(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& setting9, + const std::string& description9, + const std::string& long_description=""); + virtual void AddStringOption10(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& setting9, + const std::string& description9, + const std::string& setting10, + const std::string& description10, + const std::string& long_description=""); + + /** Get a registered option - this will return NULL if the option + * does not exist */ + virtual SmartPtr GetOption(const std::string& name); + + /** Output documentation for the options - gives a description, + * etc. */ + virtual void OutputOptionDocumentation(const Journalist& jnlst, std::list& categories); + + /** Output documentation in Latex format to include in a latex file */ + virtual void OutputLatexOptionDocumentation(const Journalist& jnlst, std::list& categories); + //@} + + typedef std::map > RegOptionsList; + + /** Giving access to iteratable representation of the registered + * options */ + virtual const RegOptionsList& RegisteredOptionsList () const + { + return registered_options_; + } + + private: + Index next_counter_; + std::string current_registering_category_; + std::map > registered_options_; + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpReturnCodes.h b/thirdparty/linux/include/coin/IpReturnCodes.h new file mode 100644 index 0000000..b16d2c6 --- /dev/null +++ b/thirdparty/linux/include/coin/IpReturnCodes.h @@ -0,0 +1,18 @@ +/*********************************************************************** +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes.h 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +************************************************************************/ + +#ifndef __IPRETURNCODES_H__ +#define __IPRETURNCODES_H__ + +/* include from a common include file */ + +#include "IpReturnCodes_inc.h" + +#endif diff --git a/thirdparty/linux/include/coin/IpReturnCodes.hpp b/thirdparty/linux/include/coin/IpReturnCodes.hpp new file mode 100644 index 0000000..36dd7d7 --- /dev/null +++ b/thirdparty/linux/include/coin/IpReturnCodes.hpp @@ -0,0 +1,21 @@ +/*********************************************************************** +// Copyright (C) 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2006-03-01 +************************************************************************/ + +#ifndef __IPRETURNCODES_HPP__ +#define __IPRETURNCODES_HPP__ + +/* include from a common include file */ + +namespace Ipopt +{ +#include "IpReturnCodes_inc.h" +} + +#endif diff --git a/thirdparty/linux/include/coin/IpReturnCodes.inc b/thirdparty/linux/include/coin/IpReturnCodes.inc new file mode 100644 index 0000000..c6bf70a --- /dev/null +++ b/thirdparty/linux/include/coin/IpReturnCodes.inc @@ -0,0 +1,70 @@ +C Copyright (C) 2005, 2009 International Business Machines and others. +C All Rights Reserved. +C This code is published under the Eclipse Public License. +C +C $Id: IpReturnCodes.inc 1861 2010-12-21 21:34:47Z andreasw $ +C +C Author: Andreas Waechter IBM 2005-08-11 +C + INTEGER IP_SOLVE_SUCCEEDED + PARAMETER( IP_SOLVE_SUCCEEDED = 0 ) + + INTEGER IP_ACCEPTABLE_LEVEL + PARAMETER( IP_ACCEPTABLE_LEVEL = 1 ) + + INTEGER IP_INFEASIBLE_PROBLEM + PARAMETER( IP_INFEASIBLE_PROBLEM = 2 ) + + INTEGER IP_SEARCH_DIRECTION_TOO_SMALL + PARAMETER( IP_SEARCH_DIRECTION_TOO_SMALL = 3 ) + + INTEGER IP_DIVERGING_ITERATES + PARAMETER( IP_DIVERGING_ITERATES = 4 ) + + INTEGER IP_USER_REQUESTED_STOP + PARAMETER( IP_USER_REQUESTED_STOP = 5 ) + + INTEGER IP_FEASIBLE_POINT_FOUND + PARAMETER( IP_FEASIBLE_POINT_FOUND = 6 ) + + INTEGER IP_ITERATION_EXCEEDED + PARAMETER( IP_ITERATION_EXCEEDED = -1 ) + + INTEGER IP_RESTORATION_FAILED + PARAMETER( IP_RESTORATION_FAILED = -2 ) + + INTEGER IP_ERROR_IN_STEP_COMPUTATION + PARAMETER( IP_ERROR_IN_STEP_COMPUTATION = -3 ) + + INTEGER IP_CPUTIME_EXCEEDED + PARAMETER( IP_CPUTIME_EXCEEDED = -4 ) + + INTEGER IP_NOT_ENOUGH_DEGREES_OF_FRE + PARAMETER( IP_NOT_ENOUGH_DEGREES_OF_FRE = -10 ) + + INTEGER IP_INVALID_PROBLEM_DEFINITION + PARAMETER( IP_INVALID_PROBLEM_DEFINITION = -11) + + INTEGER IP_INVALID_OPTION + PARAMETER( IP_INVALID_OPTION = -12 ) + + INTEGER IP_INVALID_NUMBER_DETECTED + PARAMETER( IP_INVALID_NUMBER_DETECTED = -13 ) + + INTEGER IP_UNRECOVERABLE_EXCEPTION + PARAMETER( IP_UNRECOVERABLE_EXCEPTION = -100 ) + + INTEGER IP_NON_IPOPT_EXCEPTION + PARAMETER( IP_NON_IPOPT_EXCEPTION = -101 ) + + INTEGER IP_INSUFFICIENT_MEMORY + PARAMETER( IP_INSUFFICIENT_MEMORY = -102 ) + + INTEGER IP_INTERNAL_ERROR + PARAMETER( IP_INTERNAL_ERROR = -199 ) + + INTEGER IP_REGULAR_MODE + PARAMETER( IP_REGULAR_MODE = 0 ) + + INTEGER IP_RESTORATION_PHASE_MODE + PARAMETER( IP_RESTORATION_PHASE_MODE = 1 ) diff --git a/thirdparty/linux/include/coin/IpReturnCodes_inc.h b/thirdparty/linux/include/coin/IpReturnCodes_inc.h new file mode 100644 index 0000000..80190ed --- /dev/null +++ b/thirdparty/linux/include/coin/IpReturnCodes_inc.h @@ -0,0 +1,46 @@ +/*********************************************************************** +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes_inc.h 2216 2013-04-14 17:06:00Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +************************************************************************/ + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +/* !!!!!!!!! REMEMBER TO UPDATE IpReturnCodes.inc and Ipopt.java !!!!!!!! */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +/** Return codes for the Optimize call for an application */ +enum ApplicationReturnStatus + { + Solve_Succeeded=0, + Solved_To_Acceptable_Level=1, + Infeasible_Problem_Detected=2, + Search_Direction_Becomes_Too_Small=3, + Diverging_Iterates=4, + User_Requested_Stop=5, + Feasible_Point_Found=6, + + Maximum_Iterations_Exceeded=-1, + Restoration_Failed=-2, + Error_In_Step_Computation=-3, + Maximum_CpuTime_Exceeded=-4, + Not_Enough_Degrees_Of_Freedom=-10, + Invalid_Problem_Definition=-11, + Invalid_Option=-12, + Invalid_Number_Detected=-13, + + Unrecoverable_Exception=-100, + NonIpopt_Exception_Thrown=-101, + Insufficient_Memory=-102, + Internal_Error=-199 + }; + +/** enum to indicate the mode in which the algorithm is */ +enum AlgorithmMode + { + RegularMode=0, + RestorationPhaseMode=1 + }; diff --git a/thirdparty/linux/include/coin/IpScaledMatrix.hpp b/thirdparty/linux/include/coin/IpScaledMatrix.hpp new file mode 100644 index 0000000..c182a05 --- /dev/null +++ b/thirdparty/linux/include/coin/IpScaledMatrix.hpp @@ -0,0 +1,254 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpScaledMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSCALEDMATRIX_HPP__ +#define __IPSCALEDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class ScaledMatrixSpace; + + /** Class for a Matrix in conjunction with its scaling factors for + * row and column scaling. Operations on the matrix are performed using + * the scaled matrix. You can pull out the pointer to the + * unscaled matrix for unscaled calculations. + */ + class ScaledMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + ScaledMatrix(const ScaledMatrixSpace* owner_space); + + /** Destructor */ + ~ScaledMatrix(); + //@} + + /** Set the unscaled matrix */ + void SetUnscaledMatrix(const SmartPtr unscaled_matrix); + + /** Set the unscaled matrix in a non-const version */ + void SetUnscaledMatrixNonConst(const SmartPtr& unscaled_matrix); + + /** Return the unscaled matrix in const form */ + SmartPtr GetUnscaledMatrix() const; + + /** Return the unscaled matrix in non-const form */ + SmartPtr GetUnscaledMatrixNonConst(); + + /** return the vector for the row scaling */ + SmartPtr RowScaling() const; + + /** return the vector for the column scaling */ + SmartPtr ColumnScaling() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). It is assumed that the scaling factors are + * valid. */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized + * implementation missing so far! + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation + * missing so far! + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ScaledMatrix(); + + /** Copy Constructor */ + ScaledMatrix(const ScaledMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ScaledMatrix&); + //@} + + /** const version of the unscaled matrix */ + SmartPtr matrix_; + /** non-const version of the unscaled matrix */ + SmartPtr nonconst_matrix_; + + /** Matrix space stored as a ScaledMatrixSpace */ + SmartPtr owner_space_; + }; + + /** This is the matrix space for ScaledMatrix. + */ + class ScaledMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + ScaledMatrixSpace(const SmartPtr& row_scaling, + bool row_scaling_reciprocal, + const SmartPtr& unscaled_matrix_space, + const SmartPtr& column_scaling, + bool column_scaling_reciprocal); + + /** Destructor */ + ~ScaledMatrixSpace() + {} + //@} + + /** Method for creating a new matrix of this specific type. */ + ScaledMatrix* MakeNewScaledMatrix(bool allocate_unscaled_matrix = false) const + { + ScaledMatrix* ret = new ScaledMatrix(this); + if (allocate_unscaled_matrix) { + SmartPtr unscaled_matrix = unscaled_matrix_space_->MakeNew(); + ret->SetUnscaledMatrixNonConst(unscaled_matrix); + } + return ret; + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewScaledMatrix(); + } + + /** return the vector for the row scaling */ + SmartPtr RowScaling() const + { + return ConstPtr(row_scaling_); + } + + /** return the matrix space for the unscaled matrix */ + SmartPtr UnscaledMatrixSpace() const + { + return unscaled_matrix_space_; + } + + /** return the vector for the column scaling */ + SmartPtr ColumnScaling() const + { + return ConstPtr(column_scaling_); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + ScaledMatrixSpace(); + + /** Copy Constructor */ + ScaledMatrixSpace(const ScaledMatrixSpace&); + + /** Overloaded Equals Operator */ + ScaledMatrixSpace& operator=(const ScaledMatrixSpace&); + //@} + + /** Row scaling vector */ + SmartPtr row_scaling_; + /** unscaled matrix space */ + SmartPtr unscaled_matrix_space_; + /** column scaling vector */ + SmartPtr column_scaling_; + }; + + inline + void ScaledMatrix::SetUnscaledMatrix(const SmartPtr unscaled_matrix) + { + matrix_ = unscaled_matrix; + nonconst_matrix_ = NULL; + ObjectChanged(); + } + + inline + void ScaledMatrix::SetUnscaledMatrixNonConst(const SmartPtr& unscaled_matrix) + { + nonconst_matrix_ = unscaled_matrix; + matrix_ = GetRawPtr(unscaled_matrix); + ObjectChanged(); + } + + inline + SmartPtr ScaledMatrix::GetUnscaledMatrix() const + { + return matrix_; + } + + inline + SmartPtr ScaledMatrix::GetUnscaledMatrixNonConst() + { + DBG_ASSERT(IsValid(nonconst_matrix_)); + ObjectChanged(); + return nonconst_matrix_; + } + + inline + SmartPtr ScaledMatrix::RowScaling() const + { + return ConstPtr(owner_space_->RowScaling()); + } + + inline + SmartPtr ScaledMatrix::ColumnScaling() const + { + return ConstPtr(owner_space_->ColumnScaling()); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpSearchDirCalculator.hpp b/thirdparty/linux/include/coin/IpSearchDirCalculator.hpp new file mode 100644 index 0000000..3425c43 --- /dev/null +++ b/thirdparty/linux/include/coin/IpSearchDirCalculator.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2005, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSearchDirCalculator.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-10-13 + +#ifndef __IPSEARCHDIRCALCULATOR_HPP__ +#define __IPSEARCHDIRCALCULATOR_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Base class for computing the search direction for the line + * search. + */ + class SearchDirectionCalculator : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + SearchDirectionCalculator() + {} + + /** Default destructor */ + virtual ~SearchDirectionCalculator() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Pure virtual method for computing the search direction. The + * computed direction is stored in IpData().delta().*/ + virtual bool ComputeSearchDirection()=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // SearchDirectionCalculator(); + + /** Copy Constructor */ + SearchDirectionCalculator(const SearchDirectionCalculator&); + + /** Overloaded Equals Operator */ + void operator=(const SearchDirectionCalculator&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpSmartPtr.hpp b/thirdparty/linux/include/coin/IpSmartPtr.hpp new file mode 100644 index 0000000..dec0ab5 --- /dev/null +++ b/thirdparty/linux/include/coin/IpSmartPtr.hpp @@ -0,0 +1,734 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSmartPtr.hpp 2182 2013-03-30 20:02:18Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSMARTPTR_HPP__ +#define __IPSMARTPTR_HPP__ + +#include "IpReferenced.hpp" + +#include "IpDebug.hpp" +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_SMARTPTR +#endif +#ifndef IPOPT_UNUSED +# if defined(__GNUC__) +# define IPOPT_UNUSED __attribute__((unused)) +# else +# define IPOPT_UNUSED +# endif +#endif + +namespace Ipopt +{ + + /** Template class for Smart Pointers. + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "IpReferenced.hpp" + + * namespace Ipopt { + * + * class MyClass : public ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * } // namespace Ipopt + * + * + * In my_usage.cpp... + * + * #include "IpSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * It is not necessary to use SmartPtr's in all cases where an + * object is used that has been allocated "into" a SmartPtr. It is + * possible to just pass objects by reference or regular pointers, + * even if lower down in the stack a SmartPtr is to be held on to. + * Everything should work fine as long as a pointer created by "new" + * is immediately passed into a SmartPtr, and if SmartPtr's are used + * to hold on to objects. + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + template + class SmartPtr : public Referencer + { + public: +#define ipopt_dbg_smartptr_verbosity 0 + + /**@name Constructors/Destructors */ + //@{ + /** Default constructor, initialized to NULL */ + SmartPtr(); + + /** Copy constructor, initialized from copy of type T */ + SmartPtr(const SmartPtr& copy); + + /** Copy constructor, initialized from copy of type U */ + template + SmartPtr(const SmartPtr& copy); + + /** Constructor, initialized from T* ptr */ + SmartPtr(T* ptr); + + /** Destructor, automatically decrements the + * reference count, deletes the object if + * necessary.*/ + ~SmartPtr(); + //@} + + /**@name Overloaded operators. */ + //@{ + /** Overloaded arrow operator, allows the user to call + * methods using the contained pointer. */ + T* operator->() const; + + /** Overloaded dereference operator, allows the user + * to dereference the contained pointer. */ + T& operator*() const; + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from a raw pointer */ + SmartPtr& operator=(T* rhs); + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr */ + SmartPtr& operator=(const SmartPtr& rhs); + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr of a different type */ + template + SmartPtr& operator=(const SmartPtr& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template + friend + bool operator==(const SmartPtr& lhs, const SmartPtr& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template + friend + bool operator==(const SmartPtr& lhs, U2* raw_rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a raw pointer with a SmartPtr. */ + template + friend + bool operator==(U1* lhs, const SmartPtr& raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template + friend + bool operator!=(const SmartPtr& lhs, const SmartPtr& rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template + friend + bool operator!=(const SmartPtr& lhs, U2* raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template + friend + bool operator!=(U1* lhs, const SmartPtr& raw_rhs); + + /** Overloaded less-than comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template + friend + bool operator<(const SmartPtr& lhs, const SmartPtr& rhs); + //@} + + /**@name friend method declarations. */ + //@{ + /** Returns the raw pointer contained. + * Use to get the value of + * the raw ptr (i.e. to pass to other + * methods/functions, etc.) + * Note: This method does NOT copy, + * therefore, modifications using this + * value modify the underlying object + * contained by the SmartPtr, + * NEVER delete this returned value. + */ + template + friend + U* GetRawPtr(const SmartPtr& smart_ptr); + + /** Returns a const pointer */ + template + friend + SmartPtr ConstPtr(const SmartPtr& smart_ptr); + + /** Returns true if the SmartPtr is NOT NULL. + * Use this to check if the SmartPtr is not null + * This is preferred to if(GetRawPtr(sp) != NULL) + */ + template + friend + bool IsValid(const SmartPtr& smart_ptr); + + /** Returns true if the SmartPtr is NULL. + * Use this to check if the SmartPtr IsNull. + * This is preferred to if(GetRawPtr(sp) == NULL) + */ + template + friend + bool IsNull(const SmartPtr& smart_ptr); + //@} + + private: + /**@name Private Data/Methods */ + //@{ + /** Actual raw pointer to the object. */ + T* ptr_; + + /** Set the value of the internal raw pointer + * from another raw pointer, releasing the + * previously referenced object if necessary. */ + SmartPtr& SetFromRawPtr_(T* rhs); + + /** Set the value of the internal raw pointer + * from a SmartPtr, releasing the previously referenced + * object if necessary. */ + SmartPtr& SetFromSmartPtr_(const SmartPtr& rhs); + + /** Release the currently referenced object. */ + void ReleasePointer_(); + //@} + }; + + /**@name SmartPtr friend function declarations.*/ + //@{ + template + U* GetRawPtr(const SmartPtr& smart_ptr); + + template + SmartPtr ConstPtr(const SmartPtr& smart_ptr); + + template + bool IsNull(const SmartPtr& smart_ptr); + + template + bool IsValid(const SmartPtr& smart_ptr); + + template + bool operator==(const SmartPtr& lhs, const SmartPtr& rhs); + + template + bool operator==(const SmartPtr& lhs, U2* raw_rhs); + + template + bool operator==(U1* lhs, const SmartPtr& raw_rhs); + + template + bool operator!=(const SmartPtr& lhs, const SmartPtr& rhs); + + template + bool operator!=(const SmartPtr& lhs, U2* raw_rhs); + + template + bool operator!=(U1* lhs, const SmartPtr& raw_rhs); + + //@} + + + template + SmartPtr::SmartPtr() + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr::SmartPtr()", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + } + + + template + SmartPtr::SmartPtr(const SmartPtr& copy) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr::SmartPtr(const SmartPtr& copy)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromSmartPtr_(copy); + } + + + template + template + SmartPtr::SmartPtr(const SmartPtr& copy) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr::SmartPtr(const SmartPtr& copy)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromSmartPtr_(GetRawPtr(copy)); + } + + + template + SmartPtr::SmartPtr(T* ptr) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr::SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromRawPtr_(ptr); + } + + template + SmartPtr::~SmartPtr() + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr::~SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity); +#endif + + ReleasePointer_(); + } + + + template + T* SmartPtr::operator->() const + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("T* SmartPtr::operator->()", ipopt_dbg_smartptr_verbosity); +#endif + + // cannot deref a null pointer +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + + return ptr_; + } + + + template + T& SmartPtr::operator*() const + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("T& SmartPtr::operator*()", ipopt_dbg_smartptr_verbosity); +#endif + + // cannot dereference a null pointer +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + + return *ptr_; + } + + + template + SmartPtr& SmartPtr::operator=(T* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr& SmartPtr::operator=(T* rhs)", ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromRawPtr_(rhs); + } + + + template + SmartPtr& SmartPtr::operator=(const SmartPtr& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr& SmartPtr::operator=(const SmartPtr& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromSmartPtr_(rhs); + } + + + template + template + SmartPtr& SmartPtr::operator=(const SmartPtr& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr& SmartPtr::operator=(const SmartPtr& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromSmartPtr_(GetRawPtr(rhs)); + } + + + template + SmartPtr& SmartPtr::SetFromRawPtr_(T* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr& SmartPtr::SetFromRawPtr_(T* rhs)", ipopt_dbg_smartptr_verbosity); +#endif + + if (rhs != 0) + rhs->AddRef(this); + + // Release any old pointer + ReleasePointer_(); + + ptr_ = rhs; + + return *this; + } + + template + SmartPtr& SmartPtr::SetFromSmartPtr_(const SmartPtr& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr& SmartPtr::SetFromSmartPtr_(const SmartPtr& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + SetFromRawPtr_(GetRawPtr(rhs)); + + return (*this); + } + + + template + void SmartPtr::ReleasePointer_() + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "void SmartPtr::ReleasePointer()", + ipopt_dbg_smartptr_verbosity); +#endif + + if (ptr_) { + ptr_->ReleaseRef(this); + if (ptr_->ReferenceCount() == 0) + delete ptr_; + } + } + + + template + U* GetRawPtr(const SmartPtr& smart_ptr) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "T* GetRawPtr(const SmartPtr& smart_ptr)", + 0); +#endif + + return smart_ptr.ptr_; + } + + template + SmartPtr ConstPtr(const SmartPtr& smart_ptr) + { + // compiler should implicitly cast + return GetRawPtr(smart_ptr); + } + + template + bool IsValid(const SmartPtr& smart_ptr) + { + return !IsNull(smart_ptr); + } + + template + bool IsNull(const SmartPtr& smart_ptr) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool IsNull(const SmartPtr& smart_ptr)", + 0); +#endif + + return (smart_ptr.ptr_ == 0); + } + + + template + bool ComparePointers(const U1* lhs, const U2* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool ComparePtrs(const U1* lhs, const U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + // Even if lhs and rhs point to the same object + // with different interfaces U1 and U2, we cannot guarantee that + // the value of the pointers will be equivalent. We can + // guarantee this if we convert to ReferencedObject* (see also #162) + const ReferencedObject* v_lhs = lhs; + const ReferencedObject* v_rhs = rhs; + + return v_lhs == v_rhs; + } + + template + bool operator==(const SmartPtr& lhs, const SmartPtr& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(const SmartPtr& lhs, const SmartPtr& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + U1* raw_lhs = GetRawPtr(lhs); + U2* raw_rhs = GetRawPtr(rhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template + bool operator==(const SmartPtr& lhs, U2* raw_rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(SmartPtr& lhs, U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + U1* raw_lhs = GetRawPtr(lhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template + bool operator==(U1* raw_lhs, const SmartPtr& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(U1* raw_lhs, SmartPtr& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + const U2* raw_rhs = GetRawPtr(rhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template + bool operator!=(const SmartPtr& lhs, const SmartPtr& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(const SmartPtr& lhs, const SmartPtr& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(lhs, rhs); + return !retValue; + } + + template + bool operator!=(const SmartPtr& lhs, U2* raw_rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(SmartPtr& lhs, U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(lhs, raw_rhs); + return !retValue; + } + + template + bool operator!=(U1* raw_lhs, const SmartPtr& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(U1* raw_lhs, SmartPtr& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(raw_lhs, rhs); + return !retValue; + } + + template + void swap(SmartPtr& a, SmartPtr& b) + { +#ifdef IP_DEBUG_REFERENCED + SmartPtr tmp(a); + a = b; + b = tmp; +#else + std::swap(a.prt_, b.ptr_); +#endif + } + + template + bool operator<(const SmartPtr& lhs, const SmartPtr& rhs) + { + return lhs.ptr_ < rhs.ptr_; + } + + template + bool operator> (const SmartPtr& lhs, const SmartPtr& rhs) + { + return rhs < lhs; + } + + template bool + operator<=(const SmartPtr& lhs, const SmartPtr& rhs) + { + return !( rhs < lhs ); + } + + template bool + operator>=(const SmartPtr& lhs, const SmartPtr& rhs) + { + return !( lhs < rhs ); + } +} // namespace Ipopt + +#undef ipopt_dbg_smartptr_verbosity + +#endif diff --git a/thirdparty/linux/include/coin/IpSolveStatistics.hpp b/thirdparty/linux/include/coin/IpSolveStatistics.hpp new file mode 100644 index 0000000..625ddfb --- /dev/null +++ b/thirdparty/linux/include/coin/IpSolveStatistics.hpp @@ -0,0 +1,150 @@ +// Copyright (C) 2005, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSolveStatistics.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-08-15 + +#ifndef __IPSOLVESTATISTICS_HPP__ +#define __IPSOLVESTATISTICS_HPP__ + +#include "IpReferenced.hpp" +#include "IpSmartPtr.hpp" + +namespace Ipopt +{ + // forward declaration (to avoid inclusion of too many header files) + class IpoptNLP; + class IpoptData; + class IpoptCalculatedQuantities; + + /** This class collects statistics about an optimziation run, such + * as iteration count, final infeasibilities etc. It is meant to + * provide such information to a user of Ipopt during the + * finalize_solution call. + */ + class SolveStatistics : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. It takes in those collecting Ipopt + * objects that can provide the statistics information. Those + * statistics are retrieved at the time of the constructor + * call. */ + SolveStatistics(const SmartPtr& ip_nlp, + const SmartPtr& ip_data, + const SmartPtr& ip_cq); + + /** Default destructor */ + virtual ~SolveStatistics() + {} + //@} + + /** @name Accessor methods for retrieving different kind of solver + * statistics information */ + //@{ + /** Iteration counts. */ + virtual Index IterationCount() const; + /** Total CPU time, including function evaluations. */ + virtual Number TotalCpuTime() const; + /** Total CPU time, including function evaluations. Included for + * backward compatibility. */ + Number TotalCPUTime() const + { + return TotalCpuTime(); + } + /** Total System time, including function evaluations. */ + virtual Number TotalSysTime() const; + /** Total wall clock time, including function evaluations. */ + virtual Number TotalWallclockTime() const; + /** Number of NLP function evaluations. */ + virtual void NumberOfEvaluations(Index& num_obj_evals, + Index& num_constr_evals, + Index& num_obj_grad_evals, + Index& num_constr_jac_evals, + Index& num_hess_evals) const; + /** Unscaled solution infeasibilities */ + virtual void Infeasibilities(Number& dual_inf, + Number& constr_viol, + Number& complementarity, + Number& kkt_error) const; + /** Scaled solution infeasibilities */ + virtual void ScaledInfeasibilities(Number& scaled_dual_inf, + Number& scaled_constr_viol, + Number& scaled_complementarity, + Number& scaled_kkt_error) const; + /** Final value of objective function */ + virtual Number FinalObjective() const; + /** Final scaled value of objective function */ + virtual Number FinalScaledObjective() const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SolveStatistics(); + + /** Copy Constructor */ + SolveStatistics(const SolveStatistics&); + + /** Overloaded Equals Operator */ + void operator=(const SolveStatistics&); + //@} + + /** @name Fields for storing the statistics data */ + //@{ + /** Number of iterations. */ + Index num_iters_; + /* Total CPU time */ + Number total_cpu_time_; + /* Total system time */ + Number total_sys_time_; + /* Total wall clock time */ + Number total_wallclock_time_; + /** Number of objective function evaluations. */ + Index num_obj_evals_; + /** Number of constraints evaluations (max of equality and + * inequality) */ + Index num_constr_evals_; + /** Number of objective gradient evaluations. */ + Index num_obj_grad_evals_; + /** Number of constraint Jacobian evaluations. */ + Index num_constr_jac_evals_; + /** Number of Lagrangian Hessian evaluations. */ + Index num_hess_evals_; + + /** Final scaled value of objective function */ + Number scaled_obj_val_; + /** Final unscaled value of objective function */ + Number obj_val_; + /** Final scaled dual infeasibility (max-norm) */ + Number scaled_dual_inf_; + /** Final unscaled dual infeasibility (max-norm) */ + Number dual_inf_; + /** Final scaled constraint violation (max-norm) */ + Number scaled_constr_viol_; + /** Final unscaled constraint violation (max-norm) */ + Number constr_viol_; + /** Final scaled complementarity error (max-norm) */ + Number scaled_compl_; + /** Final unscaled complementarity error (max-norm) */ + Number compl_; + /** Final overall scaled KKT error (max-norm) */ + Number scaled_kkt_error_; + /** Final overall unscaled KKT error (max-norm) */ + Number kkt_error_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpStdCInterface.h b/thirdparty/linux/include/coin/IpStdCInterface.h new file mode 100644 index 0000000..4f11336 --- /dev/null +++ b/thirdparty/linux/include/coin/IpStdCInterface.h @@ -0,0 +1,271 @@ +/************************************************************************* + Copyright (C) 2004, 2010 International Business Machines and others. + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: IpStdCInterface.h 2082 2012-02-16 03:00:34Z andreasw $ + + Authors: Carl Laird, Andreas Waechter IBM 2004-09-02 + *************************************************************************/ + +#ifndef __IPSTDCINTERFACE_H__ +#define __IPSTDCINTERFACE_H__ + +#ifndef IPOPT_EXPORT +#ifdef _MSC_VER +#ifdef IPOPT_DLL +#define IPOPT_EXPORT(type) __declspec(dllexport) type __cdecl +#else +#define IPOPT_EXPORT(type) type __cdecl +#endif +#else +#define IPOPT_EXPORT(type) type +#endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** Type for all number. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef double Number; + + /** Type for all incides. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef int Index; + + /** Type for all integers. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef int Int; + + /* This includes the SolverReturn enum type */ +#include "IpReturnCodes.h" + + /** Structure collecting all information about the problem + * definition and solve statistics etc. This is defined in the + * source file. */ + struct IpoptProblemInfo; + + /** Pointer to a Ipopt Problem. */ + typedef struct IpoptProblemInfo* IpoptProblem; + + /** define a boolean type for C */ + typedef int Bool; +#ifndef TRUE +# define TRUE (1) +#endif +#ifndef FALSE +# define FALSE (0) +#endif + + /** A pointer for anything that is to be passed between the called + * and individual callback function */ + typedef void * UserDataPtr; + + /** Type defining the callback function for evaluating the value of + * the objective function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_F_CB)(Index n, Number* x, Bool new_x, + Number* obj_value, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the gradient of + * the objective function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_Grad_F_CB)(Index n, Number* x, Bool new_x, + Number* grad_f, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the value of + * the constraint functions. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_G_CB)(Index n, Number* x, Bool new_x, + Index m, Number* g, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the Jacobian of + * the constrant functions. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_Jac_G_CB)(Index n, Number *x, Bool new_x, + Index m, Index nele_jac, + Index *iRow, Index *jCol, Number *values, + UserDataPtr user_data); + + /** Type defining the callback function for evaluating the Hessian of + * the Lagrangian function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_H_CB)(Index n, Number *x, Bool new_x, Number obj_factor, + Index m, Number *lambda, Bool new_lambda, + Index nele_hess, Index *iRow, Index *jCol, + Number *values, UserDataPtr user_data); + + /** Type defining the callback function for giving intermediate + * execution control to the user. If set, it is called once per + * iteration, providing the user with some information on the state + * of the optimization. This can be used to print some + * user-defined output. It also gives the user a way to terminate + * the optimization prematurely. If this method returns false, + * Ipopt will terminate the optimization. */ + typedef Bool (*Intermediate_CB)(Index alg_mod, /* 0 is regular, 1 is resto */ + Index iter_count, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, UserDataPtr user_data); + + /** Function for creating a new Ipopt Problem object. This function + * returns an object that can be passed to the IpoptSolve call. It + * contains the basic definition of the optimization problem, such + * as number of variables and constraints, bounds on variables and + * constraints, information about the derivatives, and the callback + * function for the computation of the optimization problem + * functions and derivatives. During this call, the options file + * PARAMS.DAT is read as well. + * + * If NULL is returned, there was a problem with one of the inputs + * or reading the options file. */ + IPOPT_EXPORT(IpoptProblem) CreateIpoptProblem( + Index n /** Number of optimization variables */ + , Number* x_L /** Lower bounds on variables. This array of + size n is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value less or equal than + the number specified by option + 'nlp_lower_bound_inf' is interpreted to + be minus infinity. */ + , Number* x_U /** Upper bounds on variables. This array of + size n is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value greater or equal + than the number specified by option + 'nlp_upper_bound_inf' is interpreted to + be plus infinity. */ + , Index m /** Number of constraints. */ + , Number* g_L /** Lower bounds on constraints. This array of + size m is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value less or equal than + the number specified by option + 'nlp_lower_bound_inf' is interpreted to + be minus infinity. */ + , Number* g_U /** Upper bounds on constraints. This array of + size m is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value greater or equal + than the number specified by option + 'nlp_upper_bound_inf' is interpreted to + be plus infinity. */ + , Index nele_jac /** Number of non-zero elements in constraint + Jacobian. */ + , Index nele_hess /** Number of non-zero elements in Hessian of + Lagrangian. */ + , Index index_style /** indexing style for iRow & jCol, + 0 for C style, 1 for Fortran style */ + , Eval_F_CB eval_f /** Callback function for evaluating + objective function */ + , Eval_G_CB eval_g /** Callback function for evaluating + constraint functions */ + , Eval_Grad_F_CB eval_grad_f + /** Callback function for evaluating gradient + of objective function */ + , Eval_Jac_G_CB eval_jac_g + /** Callback function for evaluating Jacobian + of constraint functions */ + , Eval_H_CB eval_h /** Callback function for evaluating Hessian + of Lagrangian function */ + ); + + /** Method for freeing a previously created IpoptProblem. After + freeing an IpoptProblem, it cannot be used anymore. */ + IPOPT_EXPORT(void) FreeIpoptProblem(IpoptProblem ipopt_problem); + + + /** Function for adding a string option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptStrOption(IpoptProblem ipopt_problem, char* keyword, char* val); + + /** Function for adding a Number option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptNumOption(IpoptProblem ipopt_problem, char* keyword, Number val); + + /** Function for adding an Int option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptIntOption(IpoptProblem ipopt_problem, char* keyword, Int val); + + /** Function for opening an output file for a given name with given + * printlevel. Returns false, if there was a problem opening the + * file. */ + IPOPT_EXPORT(Bool) OpenIpoptOutputFile(IpoptProblem ipopt_problem, char* file_name, + Int print_level); + + /** Optional function for setting scaling parameter for the NLP. + * This corresponds to the get_scaling_parameters method in TNLP. + * If the pointers x_scaling or g_scaling are NULL, then no scaling + * for x resp. g is done. */ + IPOPT_EXPORT(Bool) SetIpoptProblemScaling(IpoptProblem ipopt_problem, + Number obj_scaling, + Number* x_scaling, + Number* g_scaling); + + /** Setting a callback function for the "intermediate callback" + * method in the TNLP. This gives control back to the user once + * per iteration. If set, it provides the user with some + * information on the state of the optimization. This can be used + * to print some user-defined output. It also gives the user a way + * to terminate the optimization prematurely. If the callback + * method returns false, Ipopt will terminate the optimization. + * Calling this set method to set the CB pointer to NULL disables + * the intermediate callback functionality. */ + IPOPT_EXPORT(Bool) SetIntermediateCallback(IpoptProblem ipopt_problem, + Intermediate_CB intermediate_cb); + + /** Function calling the Ipopt optimization algorithm for a problem + previously defined with CreateIpoptProblem. The return + specified outcome of the optimization procedure (e.g., success, + failure etc). + */ + IPOPT_EXPORT(enum ApplicationReturnStatus) IpoptSolve( + IpoptProblem ipopt_problem + /** Problem that is to be optimized. Ipopt + will use the options previously specified with + AddIpoptOption (etc) for this problem. */ + , Number* x /** Input: Starting point + Output: Optimal solution */ + , Number* g /** Values of constraint at final point + (output only - ignored if set to NULL) */ + , Number* obj_val /** Final value of objective function + (output only - ignored if set to NULL) */ + , Number* mult_g /** Input: Initial values for the constraint + multipliers (only if warm start option + is chosen) + Output: Final multipliers for constraints + (ignored if set to NULL) */ + , Number* mult_x_L /** Input: Initial values for the multipliers for + lower variable bounds (only if warm start + option is chosen) + Output: Final multipliers for lower variable + bounds (ignored if set to NULL) */ + , Number* mult_x_U /** Input: Initial values for the multipliers for + upper variable bounds (only if warm start + option is chosen) + Output: Final multipliers for upper variable + bounds (ignored if set to NULL) */ + , UserDataPtr user_data + /** Pointer to user data. This will be + passed unmodified to the callback + functions. */ + ); + + /** + void IpoptStatisticsCounts; + + void IpoptStatisticsInfeasibilities; */ +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif diff --git a/thirdparty/linux/include/coin/IpSumSymMatrix.hpp b/thirdparty/linux/include/coin/IpSumSymMatrix.hpp new file mode 100644 index 0000000..42b1168 --- /dev/null +++ b/thirdparty/linux/include/coin/IpSumSymMatrix.hpp @@ -0,0 +1,152 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSumSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSUMSYMMATRIX_HPP__ +#define __IPSUMSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SumSymMatrixSpace; + + /** Class for Matrices which are sum of symmetric matrices. + * For each term in the we store the matrix and a factor. + */ + class SumSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, initializing with dimensions of the matrix and + * the number of terms in the sum. + */ + SumSymMatrix(const SumSymMatrixSpace* owner_space); + + /** Destructor */ + ~SumSymMatrix(); + //@} + + /** Method for setting term iterm for the sum. Note that counting + * of terms starts at 0. */ + void SetTerm(Index iterm, Number factor, const SymMatrix& matrix); + + /** Method for getting term iterm for the sum. Note that counting + * of terms starts at 0. */ + void GetTerm(Index iterm, Number& factor, SmartPtr& matrix) const; + + /** Return the number of terms */ + Index NTerms() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SumSymMatrix(); + + /** Copy Constructor */ + SumSymMatrix(const SumSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SumSymMatrix&); + //@} + + /** std::vector storing the factors for each term. */ + std::vector factors_; + + /** std::vector storing the matrices for each term. */ + std::vector > matrices_; + + /** Copy of the owner_space as a SumSymMatrixSpace */ + const SumSymMatrixSpace* owner_space_; + }; + + /** Class for matrix space for SumSymMatrix */ + class SumSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix and the number + * of terms in the sum. */ + SumSymMatrixSpace(Index ndim, Index nterms) + : + SymMatrixSpace(ndim), + nterms_(nterms) + {} + + /** Destructor */ + ~SumSymMatrixSpace() + {} + //@} + + /** @name Accessor functions */ + //@{ + /** Number of terms in the sum. */ + Index NTerms() const + { + return nterms_; + } + //@} + + /** Use this method to set the matrix spaces for the various terms. + * You will not be able to create a matrix until all these spaces + * are set. */ + void SetTermSpace(Index term_idx, const SymMatrixSpace& space); + + /** Get the matix space for a particular term */ + SmartPtr GetTermSpace(Index term_idx) const; + + /** Method for creating a new matrix of this specific type. */ + SumSymMatrix* MakeNewSumSymMatrix() const; + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const; + + private: + Index nterms_; + + std::vector< SmartPtr > term_spaces_; + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpSymLinearSolver.hpp b/thirdparty/linux/include/coin/IpSymLinearSolver.hpp new file mode 100644 index 0000000..82e7dd4 --- /dev/null +++ b/thirdparty/linux/include/coin/IpSymLinearSolver.hpp @@ -0,0 +1,130 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymLinearSolver.hpp 2322 2013-06-12 17:45:57Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMLINEARSOLVER_HPP__ +#define __IPSYMLINEARSOLVER_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" +#include "IpAlgStrategy.hpp" +#include + +namespace Ipopt +{ + + /** Enum to report outcome of a linear solve */ + enum ESymSolverStatus { + /** Successful solve */ + SYMSOLVER_SUCCESS, + /** Matrix seems to be singular; solve was aborted */ + SYMSOLVER_SINGULAR, + /** The number of negative eigenvalues is not correct */ + SYMSOLVER_WRONG_INERTIA, + /** Call the solver interface again after the matrix values have + * been restored */ + SYMSOLVER_CALL_AGAIN, + /** Unrecoverable error in linear solver occurred. The + * optimization will be aborted. */ + SYMSOLVER_FATAL_ERROR + }; + + /** Base class for all derived symmetric linear + * solvers. In the full space version of Ipopt a large linear + * system has to be solved for the augmented system. This case is + * meant to be the base class for all derived linear solvers for + * symmetric matrices (of type SymMatrix). + * + * A linear solver can be used repeatedly for matrices with + * identical structure of nonzero elements. The nonzero structure + * of those matrices must not be changed between calls. + * + * The called might ask the solver to only solve the linear system + * if the system is nonsingular, and if the number of negative + * eigenvalues matches a given number. + */ + class SymLinearSolver: public AlgorithmStrategyObject + { + public: + /** @name Constructor/Destructor */ + //@{ + SymLinearSolver() + {} + + virtual ~SymLinearSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** @name Methods for requesting solution of the linear system. */ + //@{ + /** Solve operation for multiple right hand sides. Solves the + * linear system A * Sol = Rhs with multiple right hand sides. If + * necessary, A is factorized. Correct solutions are only + * guaranteed if the return values is SYMSOLVER_SUCCESS. The + * solver will return SYMSOLVER_SINGULAR if the linear system is + * singular, and it will return SYMSOLVER_WRONG_INERTIA if + * check_NegEVals is true and the number of negative eigenvalues + * in the matrix does not match numberOfNegEVals. + * + * check_NegEVals cannot be chosen true, if ProvidesInertia() + * returns false. + */ + virtual ESymSolverStatus MultiSolve(const SymMatrix &A, + std::vector >& rhsV, + std::vector >& solV, + bool check_NegEVals, + Index numberOfNegEVals)=0; + + /** Solve operation for a single right hand side. Solves the + * linear system A * Sol = Rhs. See MultiSolve for more + * details. */ + ESymSolverStatus Solve(const SymMatrix &A, + const Vector& rhs, Vector& sol, + bool check_NegEVals, + Index numberOfNegEVals) + { + std::vector > rhsV(1); + rhsV[0] = &rhs; + std::vector > solV(1); + solV[0] = / + return MultiSolve(A, rhsV, solV, check_NegEVals, + numberOfNegEVals); + } + + /** Number of negative eigenvalues detected during last + * factorization. Returns the number of negative eigenvalues of + * the most recent factorized matrix. This must not be called if + * the linear solver does not compute this quantities (see + * ProvidesInertia). + */ + virtual Index NumberOfNegEVals() const =0; + //@} + + //* @name Options of Linear solver */ + //@{ + /** Request to increase quality of solution for next solve. + * Ask linear solver to increase quality of solution for the next + * solve (e.g. increase pivot tolerance). Returns false, if this + * is not possible (e.g. maximal pivot tolerance already used.) + */ + virtual bool IncreaseQuality() =0; + + /** Query whether inertia is computed by linear solver. + * Returns true, if linear solver provides inertia. + */ + virtual bool ProvidesInertia() const =0; + //@} + }; + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpSymMatrix.hpp b/thirdparty/linux/include/coin/IpSymMatrix.hpp new file mode 100644 index 0000000..4a0137b --- /dev/null +++ b/thirdparty/linux/include/coin/IpSymMatrix.hpp @@ -0,0 +1,162 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMMATRIX_HPP__ +#define __IPSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymMatrixSpace; + + /** This is the base class for all derived symmetric matrix types. + */ + class SymMatrix : public Matrix + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor, taking the owner_space. + */ + inline + SymMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + virtual ~SymMatrix() + {} + //@} + + /** @name Information about the size of the matrix */ + //@{ + /** Dimension of the matrix (number of rows and columns) */ + inline + Index Dim() const; + //@} + + inline + SmartPtr OwnerSymMatrixSpace() const; + + protected: + /** @name Overloaded methods from Matrix. */ + //@{ + /** Since the matrix is + * symmetric, it is only necessary to implement the + * MultVectorImpl method in a class that inherits from this base + * class. If the TransMultVectorImpl is called, this base class + * automatically calls MultVectorImpl instead. */ + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + // Since this matrix is symetric, this is the same operation as + // MultVector + MultVector(alpha, x, beta, y); + } + /** Since the matrix is symmetric, the row and column max norms + * are identical */ + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const + { + ComputeRowAMaxImpl(cols_norms, init); + } + //@} + + private: + /** Copy of the owner space ptr as a SymMatrixSpace instead + * of a MatrixSpace + */ + const SymMatrixSpace* owner_space_; + }; + + + /** SymMatrixSpace base class, corresponding to the SymMatrix base + * class. */ + class SymMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the dimension (identical to the number of + * rows and columns). + */ + SymMatrixSpace(Index dim) + : + MatrixSpace(dim,dim) + {} + + /** Destructor */ + virtual ~SymMatrixSpace() + {} + //@} + + /** Pure virtual method for creating a new matrix of this specific + * type. */ + virtual SymMatrix* MakeNewSymMatrix() const=0; + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewSymMatrix(); + } + + /** Accessor method for the dimension of the matrices in this + * matrix space. + */ + Index Dim() const + { + DBG_ASSERT(NRows() == NCols()); + return NRows(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + SymMatrixSpace(); + + /* Copy constructor */ + SymMatrixSpace(const SymMatrixSpace&); + + /** Overloaded Equals Operator */ + SymMatrixSpace& operator=(const SymMatrixSpace&); + //@} + + }; + + /* inline methods */ + inline + SymMatrix::SymMatrix(const SymMatrixSpace* owner_space) + : + Matrix(owner_space), + owner_space_(owner_space) + {} + + inline + Index SymMatrix::Dim() const + { + return owner_space_->Dim(); + } + + inline + SmartPtr SymMatrix::OwnerSymMatrixSpace() const + { + return owner_space_; + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpSymScaledMatrix.hpp b/thirdparty/linux/include/coin/IpSymScaledMatrix.hpp new file mode 100644 index 0000000..d58742f --- /dev/null +++ b/thirdparty/linux/include/coin/IpSymScaledMatrix.hpp @@ -0,0 +1,230 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymScaledMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMSCALEDMATRIX_HPP__ +#define __IPSYMSCALEDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymScaledMatrixSpace; + + /** Class for a Matrix in conjunction with its scaling factors for + * row and column scaling. Operations on the matrix are performed using + * the scaled matrix. You can pull out the pointer to the + * unscaled matrix for unscaled calculations. + */ + class SymScaledMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + SymScaledMatrix(const SymScaledMatrixSpace* owner_space); + + /** Destructor */ + ~SymScaledMatrix(); + //@} + + /** Set the unscaled matrix */ + void SetUnscaledMatrix(const SmartPtr unscaled_matrix); + + /** Set the unscaled matrix in a non-const version */ + void SetUnscaledMatrixNonConst(const SmartPtr& unscaled_matrix); + + /** Return the unscaled matrix in const form */ + SmartPtr GetUnscaledMatrix() const; + + /** Return the unscaled matrix in non-const form */ + SmartPtr GetUnscaledMatrixNonConst(); + + /** return the vector for the row and column scaling */ + SmartPtr RowColScaling() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). It is assumed here that the scaling factors + * are always valid numbers. */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SymScaledMatrix(); + + /** Copy Constructor */ + SymScaledMatrix(const SymScaledMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SymScaledMatrix&); + //@} + + /** const version of the unscaled matrix */ + SmartPtr matrix_; + /** non-const version of the unscaled matrix */ + SmartPtr nonconst_matrix_; + + /** Matrix space stored as a SymScaledMatrixSpace */ + SmartPtr owner_space_; + }; + + /** This is the matrix space for SymScaledMatrix. + */ + class SymScaledMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + SymScaledMatrixSpace(const SmartPtr& row_col_scaling, + bool row_col_scaling_reciprocal, + const SmartPtr& unscaled_matrix_space) + : + SymMatrixSpace(unscaled_matrix_space->Dim()), + unscaled_matrix_space_(unscaled_matrix_space) + { + scaling_ = row_col_scaling->MakeNewCopy(); + if (row_col_scaling_reciprocal) { + scaling_->ElementWiseReciprocal(); + } + } + + /** Destructor */ + ~SymScaledMatrixSpace() + {} + //@} + + /** Method for creating a new matrix of this specific type. */ + SymScaledMatrix* MakeNewSymScaledMatrix(bool allocate_unscaled_matrix = false) const + { + SymScaledMatrix* ret = new SymScaledMatrix(this); + if (allocate_unscaled_matrix) { + SmartPtr unscaled_matrix = unscaled_matrix_space_->MakeNewSymMatrix(); + ret->SetUnscaledMatrixNonConst(unscaled_matrix); + } + return ret; + } + + /** Overloaded method from SymMatrixSpace */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewSymScaledMatrix(); + } + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewSymScaledMatrix(); + } + + /** return the vector for the row and column scaling */ + SmartPtr RowColScaling() const + { + return ConstPtr(scaling_); + } + + /** return the matrix space for the unscaled matrix */ + SmartPtr UnscaledMatrixSpace() const + { + return unscaled_matrix_space_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + SymScaledMatrixSpace(); + + /** Copy Constructor */ + SymScaledMatrixSpace(const SymScaledMatrixSpace&); + + /** Overloaded Equals Operator */ + SymScaledMatrixSpace& operator=(const SymScaledMatrixSpace&); + //@} + + /** Row scaling vector */ + SmartPtr scaling_; + /** unscaled matrix space */ + SmartPtr unscaled_matrix_space_; + }; + + inline + void SymScaledMatrix::SetUnscaledMatrix(const SmartPtr unscaled_matrix) + { + matrix_ = unscaled_matrix; + nonconst_matrix_ = NULL; + ObjectChanged(); + } + + inline + void SymScaledMatrix::SetUnscaledMatrixNonConst(const SmartPtr& unscaled_matrix) + { + nonconst_matrix_ = unscaled_matrix; + matrix_ = GetRawPtr(unscaled_matrix); + ObjectChanged(); + } + + inline + SmartPtr SymScaledMatrix::GetUnscaledMatrix() const + { + return matrix_; + } + + inline + SmartPtr SymScaledMatrix::GetUnscaledMatrixNonConst() + { + DBG_ASSERT(IsValid(nonconst_matrix_)); + ObjectChanged(); + return nonconst_matrix_; + } + + inline SmartPtr SymScaledMatrix::RowColScaling() const + { + return ConstPtr(owner_space_->RowColScaling()); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpSymTMatrix.hpp b/thirdparty/linux/include/coin/IpSymTMatrix.hpp new file mode 100644 index 0000000..ead2d85 --- /dev/null +++ b/thirdparty/linux/include/coin/IpSymTMatrix.hpp @@ -0,0 +1,253 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymTMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMTMATRIX_HPP__ +#define __IPSYMTMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymTMatrixSpace; + + /** Class for symmetric matrices stored in triplet format. In the + * triplet format, the nonzeros elements of a symmetric matrix is + * stored in three arrays, Irn, Jcn, and Values, all of length + * Nonzeros. The first two arrays indicate the location of a + * non-zero element (as the row and column indices), and the last + * array stores the value at that location. Off-diagonal elements + * need to be stored only once since the matrix is symmetric. For + * example, the element \f$a_{1,2}=a_{2,1}\f$ would be stored only + * once, either with Irn[i]=1 and Jcn[i]=2, or with Irn[i]=2 and + * Jcn[i]=1. Both representations are identical. If nonzero + * elements (or their symmetric counter part) are listed more than + * once, their values are added. + * + * The structure of the nonzeros (i.e. the arrays Irn and Jcn) + * cannot be changed after the matrix can been initialized. Only + * the values of the nonzero elements can be modified. + * + * Note that the first row and column of a matrix has index 1, not + * 0. + * + */ + class SymTMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the corresponding matrix space. + */ + SymTMatrix(const SymTMatrixSpace* owner_space); + + /** Destructor */ + ~SymTMatrix(); + //@} + + /**@name Changing the Values.*/ + //@{ + /** Set values of nonzero elements. The values of the nonzero + * elements is copied from the incoming Number array. Important: + * It is assume that the order of the values in Values + * corresponds to the one of Irn and Jcn given to the matrix + * space. */ + void SetValues(const Number* Values); + //@} + + /** @name Accessor Methods */ + //@{ + /** Number of nonzero entries */ + Index Nonzeros() const; + + /** Obtain pointer to the internal Index array irn_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Index* Irows() const; + + /** Obtain pointer to the internal Index array jcn_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Index* Jcols() const; + + /** Obtain pointer to the internal Number array values_ with the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + Number* Values(); + /** Obtain pointer to the internal Number array values_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Number* Values() const; + //@} + + /**@name Methods for providing copy of the matrix data */ + //@{ + /** Copy the nonzero structure into provided space */ + void FillStruct(ipfint* Irn, ipfint* Jcn) const; + + /** Copy the value data into provided space */ + void FillValues(Number* Values) const; + //@} + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SymTMatrix(); + + /** Copy Constructor */ + SymTMatrix(const SymTMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SymTMatrix&); + //@} + + /** Copy of the owner_space ptr as a SymTMatrixSpace insteaqd + * of a MatrixSpace + */ + const SymTMatrixSpace* owner_space_; + + /** Values of nonzeros */ + Number* values_; + + /** Flag for Initialization */ + bool initialized_; + + }; + + /** This is the matrix space for a SymTMatrix with fixed sparsity + * structure. The sparsity structure is stored here in the matrix + * space. + */ + class SymTMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of rows and columns (both as + * dim), as well as the number of nonzeros and the position of + * the nonzero elements. Note that the counting of the nonzeros + * starts a 1, i.e., iRows[i]==1 and jCols[i]==1 refers to the + * first element in the first row. This is in accordance with + * the HSL data structure. Off-diagonal elements are stored only + * once. + */ + SymTMatrixSpace(Index dim, Index nonZeros, const Index* iRows, + const Index* jCols); + + /** Destructor */ + ~SymTMatrixSpace(); + //@} + + /** Overloaded MakeNew method for the sYMMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewSymTMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + SymTMatrix* MakeNewSymTMatrix() const + { + return new SymTMatrix(this); + } + + /**@name Methods describing Matrix structure */ + //@{ + /** Number of non-zeros in the sparse matrix */ + Index Nonzeros() const + { + return nonZeros_; + } + + /** Row index of each non-zero element */ + const Index* Irows() const + { + return iRows_; + } + + /** Column index of each non-zero element */ + const Index* Jcols() const + { + return jCols_; + } + //@} + + private: + /**@name Methods called by SymTMatrix for memory management */ + //@{ + /** Allocate internal storage for the SymTMatrix values */ + Number* AllocateInternalStorage() const; + + /** Deallocate internal storage for the SymTMatrix values */ + void FreeInternalStorage(Number* values) const; + //@} + + const Index nonZeros_; + Index* iRows_; + Index* jCols_; + + friend class SymTMatrix; + }; + + /* Inline Methods */ + inline + Index SymTMatrix::Nonzeros() const + { + return owner_space_->Nonzeros(); + } + + inline + const Index* SymTMatrix::Irows() const + { + return owner_space_->Irows(); + } + + inline + const Index* SymTMatrix::Jcols() const + { + return owner_space_->Jcols(); + } + + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpTNLP.hpp b/thirdparty/linux/include/coin/IpTNLP.hpp new file mode 100644 index 0000000..4faf385 --- /dev/null +++ b/thirdparty/linux/include/coin/IpTNLP.hpp @@ -0,0 +1,301 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLP.hpp 2212 2013-04-14 14:51:52Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTNLP_HPP__ +#define __IPTNLP_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpAlgTypes.hpp" +#include "IpReturnCodes.hpp" + +#include + +namespace Ipopt +{ + // forward declarations + class IpoptData; + class IpoptCalculatedQuantities; + class IteratesVector; + + /** Base class for all NLP's that use standard triplet matrix form + * and dense vectors. This is the standard base class for all + * NLP's that use the standard triplet matrix form (as for Harwell + * routines) and dense vectors. The class TNLPAdapter then converts + * this interface to an interface that can be used directly by + * ipopt. + * + * This interface presents the problem form: + * + * min f(x) + * + * s.t. gL <= g(x) <= gU + * + * xL <= x <= xU + * + * In order to specify an equality constraint, set gL_i = gU_i = + * rhs. The value that indicates "infinity" for the bounds + * (i.e. the variable or constraint has no lower bound (-infinity) + * or upper bound (+infinity)) is set through the option + * nlp_lower_bound_inf and nlp_upper_bound_inf. To indicate that a + * variable has no upper or lower bound, set the bound to + * -ipopt_inf or +ipopt_inf respectively + */ + class TNLP : public ReferencedObject + { + public: + /** Type of the constraints*/ + enum LinearityType + { + LINEAR/** Constraint/Variable is linear.*/, + NON_LINEAR/**Constraint/Varaible is non-linear.*/ + }; + + /**@name Constructors/Destructors */ + //@{ + TNLP() + {} + + /** Default destructor */ + virtual ~TNLP() + {} + //@} + + DECLARE_STD_EXCEPTION(INVALID_TNLP); + + /**@name methods to gather information about the NLP */ + //@{ + /** overload this method to return the number of variables + * and constraints, and the number of non-zeros in the jacobian and + * the hessian. The index_style parameter lets you specify C or Fortran + * style indexing for the sparse matrix iRow and jCol parameters. + * C_STYLE is 0-based, and FORTRAN_STYLE is 1-based. + */ + enum IndexStyleEnum { C_STYLE=0, FORTRAN_STYLE=1 }; + virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, + Index& nnz_h_lag, IndexStyleEnum& index_style)=0; + + typedef std::map > StringMetaDataMapType; + typedef std::map > IntegerMetaDataMapType; + typedef std::map > NumericMetaDataMapType; + + /** overload this method to return any meta data for + * the variables and the constraints */ + virtual bool get_var_con_metadata(Index /* n */, + StringMetaDataMapType& /* var_string_md */, + IntegerMetaDataMapType& /* var_integer_md */, + NumericMetaDataMapType& /* var_numeric_md */, + Index /* m */, + StringMetaDataMapType& /* con_string_md */, + IntegerMetaDataMapType& /* con_integer_md */, + NumericMetaDataMapType& /* con_numeric_md */) + + { + return false; + } + + /** overload this method to return the information about the bound + * on the variables and constraints. The value that indicates + * that a bound does not exist is specified in the parameters + * nlp_lower_bound_inf and nlp_upper_bound_inf. By default, + * nlp_lower_bound_inf is -1e19 and nlp_upper_bound_inf is + * 1e19. (see TNLPAdapter) */ + virtual bool get_bounds_info(Index /* n */, Number* /* x_l */, Number* /* x_u */, + Index /* m */, Number* /* g_l */, Number* /* g_u */)=0; + + /** overload this method to return scaling parameters. This is + * only called if the options are set to retrieve user scaling. + * There, use_x_scaling (or use_g_scaling) should get set to true + * only if the variables (or constraints) are to be scaled. This + * method should return true only if the scaling parameters could + * be provided. + */ + virtual bool get_scaling_parameters(Number& /* obj_scaling */, + bool& /* use_x_scaling */, Index /* n */, + Number* /* x_scaling */, + bool& /* use_g_scaling */, Index /* m */, + Number* /* g_scaling */) + { + return false; + } + + /** overload this method to return the variables linearity + * (TNLP::LINEAR or TNLP::NON_LINEAR). The var_types + * array has been allocated with length at least n. (default implementation + * just return false and does not fill the array).*/ + virtual bool get_variables_linearity(Index /* n */, LinearityType* /* var_types */) + { + return false; + } + + /** overload this method to return the constraint linearity. + * array has been allocated with length at least n. (default implementation + * just return false and does not fill the array).*/ + virtual bool get_constraints_linearity(Index /* m */, LinearityType* /* const_types */) + { + return false; + } + + /** overload this method to return the starting point. The bool + * variables indicate whether the algorithm wants you to + * initialize x, z_L/z_u, and lambda, respectively. If, for some + * reason, the algorithm wants you to initialize these and you + * cannot, return false, which will cause Ipopt to stop. You + * will have to run Ipopt with different options then. + */ + virtual bool get_starting_point(Index /* n */, bool /* init_x */, Number* /* x */, + bool /* init_z */, Number* /* z_L */, Number* /* z_U */, + Index /* m */, bool /* init_lambda */, + Number* /* lambda */)=0; + + /** overload this method to provide an Ipopt iterate (already in + * the form Ipopt requires it internally) for a warm start. + * Since this is only for expert users, a default dummy + * implementation is provided and returns false. */ + virtual bool get_warm_start_iterate(IteratesVector& /* warm_start_iterate */) + { + return false; + } + + /** overload this method to return the value of the objective function */ + virtual bool eval_f(Index /* n */, const Number* /* x */, bool /* new_x */, + Number& /* obj_value */)=0; + + /** overload this method to return the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Index /* n */, const Number* /* x */, bool /* new_x */, + Number* /* grad_f */)=0; + + /** overload this method to return the vector of constraint values */ + virtual bool eval_g(Index /* n */, const Number* /* x */, bool /* new_x */, + Index /* m */, Number* /* g */)=0; + /** overload this method to return the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Index /* n */, const Number* /* x */, bool /* new_x */, + Index /* m */, Index /* nele_jac */, Index* /* iRow */, + Index* /* jCol */, Number* /* values */)=0; + + /** overload this method to return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only. A default implementation is provided, in case the user + * wants to se quasi-Newton approximations to estimate the second + * derivatives and doesn't not neet to implement this method. */ + virtual bool eval_h(Index /* n */, const Number* /* x */, bool /* new_x */, + Number /* obj_factor */, Index /* m */, const Number* /* lambda */, + bool /* new_lambda */, Index /* nele_hess */, + Index* /* iRow */, Index* /* jCol */, Number* /* values */) + { + return false; + } + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(SolverReturn /* status */, + Index /* n */, const Number* /* x */, const Number* /* z_L */, const Number* /* z_U */, + Index /* m */, const Number* /* g */, const Number* /* lambda */, + Number /* obj_value */, + const IpoptData* /* ip_data */, + IpoptCalculatedQuantities* /* ip_cq */)=0; + /** This method is called just before finalize_solution. With + * this method, the algorithm returns any metadata collected + * during its run, including the metadata provided by the user + * with the above get_var_con_metadata. Each metadata can be of + * type string, integer, and numeric. It can be associated to + * either the variables or the constraints. The metadata that + * was associated with the primal variable vector is stored in + * var_..._md. The metadata associated with the constraint + * multipliers is stored in con_..._md. The metadata associated + * with the bound multipliers is stored in var_..._md, with the + * suffixes "_z_L", and "_z_U", denoting lower and upper + * bounds. */ + virtual void finalize_metadata(Index /* n */, + const StringMetaDataMapType& /* var_string_md */, + const IntegerMetaDataMapType& /* var_integer_md */, + const NumericMetaDataMapType& /* var_numeric_md */, + Index /* m */, + const StringMetaDataMapType& /* con_string_md */, + const IntegerMetaDataMapType& /* con_integer_md */, + const NumericMetaDataMapType& /* con_numeric_md */) + {} + + + /** Intermediate Callback method for the user. Providing dummy + * default implementation. For details see IntermediateCallBack + * in IpNLP.hpp. */ + virtual bool intermediate_callback(AlgorithmMode /* mode */, + Index /* iter */, Number /* obj_value */, + Number /* inf_pr */, Number /* inf_du */, + Number /* mu */, Number /* d_norm */, + Number /* regularization_size */, + Number /* alpha_du */, Number /* alpha_pr */, + Index /* ls_trials */, + const IpoptData* /* ip_data */, + IpoptCalculatedQuantities* /* ip_cq */) + { + return true; + } + //@} + + /** @name Methods for quasi-Newton approximation. If the second + * derivatives are approximated by Ipopt, it is better to do this + * only in the space of nonlinear variables. The following + * methods are call by Ipopt if the quasi-Newton approximation is + * selected. If -1 is returned as number of nonlinear variables, + * Ipopt assumes that all variables are nonlinear. Otherwise, it + * calls get_list_of_nonlinear_variables with an array into which + * the indices of the nonlinear variables should be written - the + * array has the lengths num_nonlin_vars, which is identical with + * the return value of get_number_of_nonlinear_variables(). It + * is assumed that the indices are counted starting with 1 in the + * FORTRAN_STYLE, and 0 for the C_STYLE. */ + //@{ + virtual Index get_number_of_nonlinear_variables() + { + return -1; + } + + virtual bool get_list_of_nonlinear_variables(Index /* num_nonlin_vars */, + Index* /* pos_nonlin_vars */) + { + return false; + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //TNLP(); + + /** Copy Constructor */ + TNLP(const TNLP&); + + /** Overloaded Equals Operator */ + void operator=(const TNLP&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpTNLPAdapter.hpp b/thirdparty/linux/include/coin/IpTNLPAdapter.hpp new file mode 100644 index 0000000..6eea8e3 --- /dev/null +++ b/thirdparty/linux/include/coin/IpTNLPAdapter.hpp @@ -0,0 +1,427 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLPAdapter.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTNLPADAPTER_HPP__ +#define __IPTNLPADAPTER_HPP__ + +#include "IpNLP.hpp" +#include "IpTNLP.hpp" +#include "IpOrigIpoptNLP.hpp" +#include + +namespace Ipopt +{ + + // forward declarations + class ExpansionMatrix; + class ExpansionMatrixSpace; + class IteratesVector; + class TDependencyDetector; + + /** This class Adapts the TNLP interface so it looks like an NLP interface. + * This is an Adapter class (Design Patterns) that converts a TNLP to an + * NLP. This allows users to write to the "more convenient" TNLP interface. + */ + class TNLPAdapter : public NLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor */ + TNLPAdapter(const SmartPtr tnlp, + const SmartPtr jnlst = NULL); + + /** Default destructor */ + virtual ~TNLPAdapter(); + //@} + + /**@name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(INVALID_TNLP); + DECLARE_STD_EXCEPTION(ERROR_IN_TNLP_DERIVATIVE_TEST); + //@} + + /** @name TNLPAdapter Initialization. */ + //@{ + virtual bool ProcessOptions(const OptionsList& options, + const std::string& prefix); + + /** Method for creating the derived vector / matrix types + * (Do not delete these, the ). */ + virtual bool GetSpaces(SmartPtr& x_space, + SmartPtr& c_space, + SmartPtr& d_space, + SmartPtr& x_l_space, + SmartPtr& px_l_space, + SmartPtr& x_u_space, + SmartPtr& px_u_space, + SmartPtr& d_l_space, + SmartPtr& pd_l_space, + SmartPtr& d_u_space, + SmartPtr& pd_u_space, + SmartPtr& Jac_c_space, + SmartPtr& Jac_d_space, + SmartPtr& Hess_lagrangian_space); + + /** Method for obtaining the bounds information */ + virtual bool GetBoundsInformation(const Matrix& Px_L, + Vector& x_L, + const Matrix& Px_U, + Vector& x_U, + const Matrix& Pd_L, + Vector& d_L, + const Matrix& Pd_U, + Vector& d_U); + + /** Method for obtaining the starting point + * for all the iterates. */ + virtual bool GetStartingPoint( + SmartPtr x, + bool need_x, + SmartPtr y_c, + bool need_y_c, + SmartPtr y_d, + bool need_y_d, + SmartPtr z_L, + bool need_z_L, + SmartPtr z_U, + bool need_z_U + ); + + /** Method for obtaining an entire iterate as a warmstart point. + * The incoming IteratesVector has to be filled. */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate); + //@} + + /** @name TNLPAdapter evaluation routines. */ + //@{ + virtual bool Eval_f(const Vector& x, Number& f); + + virtual bool Eval_grad_f(const Vector& x, Vector& g_f); + + virtual bool Eval_c(const Vector& x, Vector& c); + + virtual bool Eval_jac_c(const Vector& x, Matrix& jac_c); + + virtual bool Eval_d(const Vector& x, Vector& d); + + virtual bool Eval_jac_d(const Vector& x, Matrix& jac_d); + + virtual bool Eval_h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + SymMatrix& h); + + virtual void GetScalingParameters( + const SmartPtr x_space, + const SmartPtr c_space, + const SmartPtr d_space, + Number& obj_scaling, + SmartPtr& x_scaling, + SmartPtr& c_scaling, + SmartPtr& d_scaling) const; + //@} + + /** @name Solution Reporting Methods */ + //@{ + virtual void FinalizeSolution(SolverReturn status, + const Vector& x, + const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + //@} + + /** Method returning information on quasi-Newton approximation. */ + virtual void + GetQuasiNewtonApproximationSpaces(SmartPtr& approx_space, + SmartPtr& P_approx); + + /** Enum for treatment of fixed variables option */ + enum FixedVariableTreatmentEnum + { + MAKE_PARAMETER=0, + MAKE_CONSTRAINT, + RELAX_BOUNDS + }; + + /** Enum for specifying which derivative test is to be performed. */ + enum DerivativeTestEnum + { + NO_TEST=0, + FIRST_ORDER_TEST, + SECOND_ORDER_TEST, + ONLY_SECOND_ORDER_TEST + }; + + /** Enum for specifying technique for computing Jacobian */ + enum JacobianApproxEnum + { + JAC_EXACT=0, + JAC_FINDIFF_VALUES + }; + + /** Method for performing the derivative test */ + bool CheckDerivatives(DerivativeTestEnum deriv_test, + Index deriv_test_start_index); + + /** @name Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr roptions); + //@} + + /** Accessor method for the underlying TNLP. */ + SmartPtr tnlp() const + { + return tnlp_; + } + + /** @name Methods for translating data for IpoptNLP into the TNLP + * data. These methods are used to obtain the current (or + * final) data for the TNLP formulation from the IpoptNLP + * structure. */ + //@{ + /** Sort the primal variables, and add the fixed values in x */ + void ResortX(const Vector& x, Number* x_orig); + void ResortG(const Vector& c, const Vector& d, Number *g_orig); + void ResortBnds(const Vector& x_L, Number* x_L_orig, + const Vector& x_U, Number* x_U_orig); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TNLPAdapter(const TNLPAdapter&); + + /** Overloaded Equals Operator */ + void operator=(const TNLPAdapter&); + //@} + + /** @name Method implementing the detection of linearly dependent + equality constraints */ + bool DetermineDependentConstraints(Index n_x_var, + const Index* x_not_fixed_map, + const Number* x_l, const Number* x_u, + const Number* g_l, const Number* g_u, + Index n_c, const Index* c_map, + std::list& c_deps); + + /** Pointer to the TNLP class (class specific to Number* vectors and + * harwell triplet matrices) */ + SmartPtr tnlp_; + + /** Journalist */ + SmartPtr jnlst_; + + /** Object that can be used to detect linearly dependent rows in + * the equality constraint Jacobian */ + SmartPtr dependency_detector_; + + /**@name Algorithmic parameters */ + //@{ + /** Value for a lower bound that denotes -infinity */ + Number nlp_lower_bound_inf_; + /** Value for a upper bound that denotes infinity */ + Number nlp_upper_bound_inf_; + /** Flag indicating how fixed variables should be handled */ + FixedVariableTreatmentEnum fixed_variable_treatment_; + /* Determines relaxation of fixing bound for RELAX_BOUNDS. */ + Number bound_relax_factor_; + /* Maximal slack for one-sidedly bounded variables. If a + * variable has only one bound, say a lower bound xL, then an + * upper bound xL + max_onesided_bound_slack_. If this value is + * zero, no upper bound is added. */ + /* Took this out: Number max_onesided_bound_slack_; */ + /** Enum indicating whether and which derivative test should be + * performed at starting point. */ + DerivativeTestEnum derivative_test_; + /** Size of the perturbation for the derivative test */ + Number derivative_test_perturbation_; + /** Relative threshold for marking deviation from finite + * difference test */ + Number derivative_test_tol_; + /** Flag indicating if all test values should be printed, or only + * those violating the threshold. */ + bool derivative_test_print_all_; + /** Index of first quantity to be checked. */ + Index derivative_test_first_index_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Flag indicating what Hessian information is to be used. */ + HessianApproximationType hessian_approximation_; + /** Number of linear variables. */ + Index num_linear_variables_; + /** Flag indicating how Jacobian is computed. */ + JacobianApproxEnum jacobian_approximation_; + /** Size of the perturbation for the derivative approximation */ + Number findiff_perturbation_; + /** Maximal perturbation of the initial point */ + Number point_perturbation_radius_; + /** Flag indicating if rhs should be considered during dependency + * detection */ + bool dependency_detection_with_rhs_; + + /** Overall convergence tolerance */ + Number tol_; + //@} + + /**@name Problem Size Data */ + //@{ + /** full dimension of x (fixed + non-fixed) */ + Index n_full_x_; + /** full dimension of g (c + d) */ + Index n_full_g_; + /** non-zeros of the jacobian of c */ + Index nz_jac_c_; + /** non-zeros of the jacobian of c without added constraints for + * fixed variables. */ + Index nz_jac_c_no_extra_; + /** non-zeros of the jacobian of d */ + Index nz_jac_d_; + /** number of non-zeros in full-size Jacobian of g */ + Index nz_full_jac_g_; + /** number of non-zeros in full-size Hessian */ + Index nz_full_h_; + /** number of non-zeros in the non-fixed-size Hessian */ + Index nz_h_; + /** Number of fixed variables */ + Index n_x_fixed_; + //@} + + /** Numbering style of variables and constraints */ + TNLP::IndexStyleEnum index_style_; + + /** @name Local copy of spaces (for warm start) */ + //@{ + SmartPtr x_space_; + SmartPtr c_space_; + SmartPtr d_space_; + SmartPtr x_l_space_; + SmartPtr px_l_space_; + SmartPtr x_u_space_; + SmartPtr px_u_space_; + SmartPtr d_l_space_; + SmartPtr pd_l_space_; + SmartPtr d_u_space_; + SmartPtr pd_u_space_; + SmartPtr Jac_c_space_; + SmartPtr Jac_d_space_; + SmartPtr Hess_lagrangian_space_; + //@} + + /**@name Local Copy of the Data */ + //@{ + Number* full_x_; /** copy of the full x vector (fixed & non-fixed) */ + Number* full_lambda_; /** copy of lambda (yc & yd) */ + Number* full_g_; /** copy of g (c & d) */ + Number* jac_g_; /** the values for the full jacobian of g */ + Number* c_rhs_; /** the rhs values of c */ + //@} + + /**@name Tags for deciding when to update internal copies of vectors */ + //@{ + TaggedObject::Tag x_tag_for_iterates_; + TaggedObject::Tag y_c_tag_for_iterates_; + TaggedObject::Tag y_d_tag_for_iterates_; + TaggedObject::Tag x_tag_for_g_; + TaggedObject::Tag x_tag_for_jac_g_; + //@} + + /**@name Methods to update the values in the local copies of vectors */ + //@{ + bool update_local_x(const Vector& x); + bool update_local_lambda(const Vector& y_c, const Vector& y_d); + //@} + + /**@name Internal routines for evaluating g and jac_g (values stored since + * they are used in both c and d routines */ + //@{ + bool internal_eval_g(bool new_x); + bool internal_eval_jac_g(bool new_x); + //@} + + /** @name Internal methods for dealing with finite difference + approxation */ + //@{ + /** Initialize sparsity structure for finite difference Jacobian */ + void initialize_findiff_jac(const Index* iRow, const Index* jCol); + //@} + + /**@name Internal Permutation Spaces and matrices + */ + //@{ + /** Expansion from fixed x (ipopt) to full x */ + SmartPtr P_x_full_x_; + SmartPtr P_x_full_x_space_; + + /** Expansion from fixed x_L (ipopt) to full x */ + SmartPtr P_x_x_L_; + SmartPtr P_x_x_L_space_; + + /** Expansion from fixed x_U (ipopt) to full x */ + SmartPtr P_x_x_U_; + SmartPtr P_x_x_U_space_; + + /** Expansion from c only (ipopt) to full ampl c */ + SmartPtr P_c_g_space_; + SmartPtr P_c_g_; + + /** Expansion from d only (ipopt) to full ampl d */ + SmartPtr P_d_g_space_; + SmartPtr P_d_g_; + + Index* jac_idx_map_; + Index* h_idx_map_; + + /** Position of fixed variables. This is required for a warm start */ + Index* x_fixed_map_; + //@} + + /** @name Data for finite difference approximations of derivatives */ + //@{ + /** Number of unique nonzeros in constraint Jacobian */ + Index findiff_jac_nnz_; + /** Start position for nonzero indices in ja for each column of + Jacobian */ + Index* findiff_jac_ia_; + /** Ordered by columns, for each column the row indices in + Jacobian */ + Index* findiff_jac_ja_; + /** Position of entry in original triplet matrix */ + Index* findiff_jac_postriplet_; + /** Copy of the lower bounds */ + Number* findiff_x_l_; + /** Copy of the upper bounds */ + Number* findiff_x_u_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpTNLPReducer.hpp b/thirdparty/linux/include/coin/IpTNLPReducer.hpp new file mode 100644 index 0000000..bce1478 --- /dev/null +++ b/thirdparty/linux/include/coin/IpTNLPReducer.hpp @@ -0,0 +1,180 @@ +// Copyright (C) 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLPReducer.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2008-08-10 + +#ifndef __IPTNLPREDUCER_HPP__ +#define __IPTNLPREDUCER_HPP__ + +#include "IpTNLP.hpp" + +namespace Ipopt +{ + /** This is a wrapper around a given TNLP class that takes out a + * list of constraints that are given to the constructor. It is + * provided for convenience, if one wants to experiment with + * problems that consist of only a subset of the constraints. But + * keep in mind that this is not efficient, since behind the scenes + * we are still evaluation all functions and derivatives, and are + * making copies of the original data. */ + class TNLPReducer : public TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor is given the indices of the constraints that + * should be taken out of the problem statement, as well as the + * original TNLP. */ + TNLPReducer(TNLP& tnlp, Index n_g_skip, const Index* index_g_skip, + Index n_xL_skip, const Index* index_xL_skip, + Index n_xU_skip, const Index* index_xU_skip, + Index n_x_fix, const Index* index_f_fix); + + /** Default destructor */ + virtual ~TNLPReducer(); + //@} + + /** @name Overloaded methods from TNLP */ + virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, + Index& nnz_h_lag, IndexStyleEnum& index_style); + + virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, + Index m, Number* g_l, Number* g_u); + + virtual bool get_scaling_parameters(Number& obj_scaling, + bool& use_x_scaling, Index n, + Number* x_scaling, + bool& use_g_scaling, Index m, + Number* g_scaling); + + virtual bool get_variables_linearity(Index n, LinearityType* var_types); + + virtual bool get_constraints_linearity(Index m, LinearityType* const_types); + + virtual bool get_starting_point(Index n, bool init_x, Number* x, + bool init_z, Number* z_L, Number* z_U, + Index m, bool init_lambda, + Number* lambda); + + virtual bool get_warm_start_iterate(IteratesVector& warm_start_iterate); + + virtual bool eval_f(Index n, const Number* x, bool new_x, + Number& obj_value); + + virtual bool eval_grad_f(Index n, const Number* x, bool new_x, + Number* grad_f); + + virtual bool eval_g(Index n, const Number* x, bool new_x, + Index m, Number* g); + + virtual bool eval_jac_g(Index n, const Number* x, bool new_x, + Index m, Index nele_jac, Index* iRow, + Index *jCol, Number* values); + + virtual bool eval_h(Index n, const Number* x, bool new_x, + Number obj_factor, Index m, const Number* lambda, + bool new_lambda, Index nele_hess, + Index* iRow, Index* jCol, Number* values); + + virtual void finalize_solution(SolverReturn status, + Index n, const Number* x, const Number* z_L, const Number* z_U, + Index m, const Number* g, const Number* lambda, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual bool intermediate_callback(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual Index get_number_of_nonlinear_variables(); + + virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars, + Index* pos_nonlin_vars); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TNLPReducer(); + + /** Copy Constructor */ + TNLPReducer(const TNLPReducer&); + + /** Overloaded Equals Operator */ + void operator=(const TNLPReducer&); + //@} + + /** @name original TNLP */ + //@{ + SmartPtr tnlp_; + Index m_orig_; + Index nnz_jac_g_orig_; + //@} + + /** Number of constraints to be skipped */ + Index n_g_skip_; + + /** Array of indices of the constraints that are to be skipped. + * This is provided at the beginning in the constructor. */ + Index* index_g_skip_; + + /** Index style for original problem. Internally, we use C-Style + * now. */ + IndexStyleEnum index_style_orig_; + + /** Map from original constraints to new constraints. A -1 means + * that a constraint is skipped. */ + Index* g_keep_map_; + + /** Number of constraints in reduced NLP */ + Index m_reduced_; + + /** Number of Jacobian nonzeros in the reduced NLP */ + Index nnz_jac_g_reduced_; + + /** Number of Jacobian nonzeros that are skipped */ + Index nnz_jac_g_skipped_; + + /** Array of Jacobian elements that are to be skipped. This is in + * increasing order. */ + Index* jac_g_skipped_; + + /** Number of lower variable bounds to be skipped. */ + Index n_xL_skip_; + + /** Array of indices of the lower variable bounds to be skipped. */ + Index* index_xL_skip_; + + /** Number of upper variable bounds to be skipped. */ + Index n_xU_skip_; + + /** Array of indices of the upper variable bounds to be skipped. */ + Index* index_xU_skip_; + + /** Number of variables that are to be fixed to initial value. */ + Index n_x_fix_; + + /** Array of indices of the variables that are to be fixed. */ + Index* index_x_fix_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpTaggedObject.hpp b/thirdparty/linux/include/coin/IpTaggedObject.hpp new file mode 100644 index 0000000..7262c43 --- /dev/null +++ b/thirdparty/linux/include/coin/IpTaggedObject.hpp @@ -0,0 +1,162 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTaggedObject.hpp 2613 2015-11-04 14:42:02Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTAGGEDOBJECT_HPP__ +#define __IPTAGGEDOBJECT_HPP__ + +#include "IpUtils.hpp" +#include "IpDebug.hpp" +#include "IpReferenced.hpp" +#include "IpObserver.hpp" +#include + +/* keyword to declare a thread-local variable according to http://en.wikipedia.org/wiki/Thread-local_storage + * GCC < 4.5 on MacOS X does not support TLS + * With Intel compiler on MacOS X, problems with TLS were reported. + */ +#ifndef IPOPT_THREAD_LOCAL + +#if defined(_MSC_VER) +#define IPOPT_THREAD_LOCAL __declspec(thread) +#elif defined(__APPLE__) && ((defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 405)) || defined(__INTEL_COMPILER)) +#define IPOPT_THREAD_LOCAL +#else +#define IPOPT_THREAD_LOCAL __thread +#endif + +#endif + +namespace Ipopt +{ + + /** TaggedObject class. + * Often, certain calculations or operations are expensive, + * and it can be very inefficient to perform these calculations + * again if the input to the calculation has not changed + * since the result was last stored. + * This base class provides an efficient mechanism to update + * a tag, indicating that the object has changed. + * Users of a TaggedObject class, need their own Tag data + * member to keep track of the state of the TaggedObject, the + * last time they performed a calculation. A basic use case for + * users of a class inheriting from TaggedObject follows like + * this: + * + * 1. Initialize your own Tag to zero in constructor. + * + * 2. Before an expensive calculation, + * check if the TaggedObject has changed, passing in + * your own Tag, indicating the last time you used + * the object for the calculation. If it has changed, + * perform the calculation again, and store the result. + * If it has not changed, simply return the stored result. + * + * Here is a simple example: + \verbatim + if (vector.HasChanged(my_vector_tag_)) { + my_vector_tag_ = vector.GetTag(); + result = PerformExpensiveCalculation(vector); + return result; + } + else { + return result; + } + \endverbatim + * + * Objects derived from TaggedObject must indicate that they have changed to + * the base class using the protected member function ObjectChanged(). For + * example, a Vector class, inside its own set method, MUST call + * ObjectChanged() to update the internally stored tag for comparison. + */ + class TaggedObject : public ReferencedObject, public Subject + { + public: + /** Type for the Tag values */ + typedef unsigned int Tag; + + /** Constructor. */ + TaggedObject() + : + Subject() + { + ObjectChanged(); + } + + /** Destructor. */ + virtual ~TaggedObject() + {} + + /** Users of TaggedObjects call this to + * update their own internal tags every time + * they perform the expensive operation. + */ + Tag GetTag() const + { + return tag_; + } + + /** Users of TaggedObjects call this to + * check if the object HasChanged since + * they last updated their own internal + * tag. + */ + bool HasChanged(const Tag comparison_tag) const + { + return (comparison_tag == tag_) ? false : true; + } + protected: + /** Objects derived from TaggedObject MUST call this + * method every time their internal state changes to + * update the internal tag for comparison + */ + void ObjectChanged() + { + DBG_START_METH("TaggedObject::ObjectChanged()", 0); + tag_ = unique_tag_; + unique_tag_++; + DBG_ASSERT(unique_tag_ < std::numeric_limits::max()); + // The Notify method from the Subject base class notifies all + // registered Observers that this subject has changed. + Notify(Observer::NT_Changed); + } + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TaggedObject(const TaggedObject&); + + /** Overloaded Equals Operator */ + void operator=(const TaggedObject&); + //@} + + /** static data member that is incremented every + * time ANY TaggedObject changes. This allows us + * to obtain a unique Tag when the object changes + */ + static IPOPT_THREAD_LOCAL Tag unique_tag_; + + /** The tag indicating the current state of the object. + * We use this to compare against the comparison_tag + * in the HasChanged method. This member is updated + * from the unique_tag_ every time the object changes. + */ + Tag tag_; + + /** The index indicating the cache priority for this + * TaggedObject. If a result that depended on this + * TaggedObject is cached, it will be cached with this + * priority + */ + Index cache_priority_; + }; +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpTimedTask.hpp b/thirdparty/linux/include/coin/IpTimedTask.hpp new file mode 100644 index 0000000..a1c5bac --- /dev/null +++ b/thirdparty/linux/include/coin/IpTimedTask.hpp @@ -0,0 +1,146 @@ +// Copyright (C) 2006, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTimedTask.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-09-19 + +#ifndef __IPTIMEDTASK_HPP__ +#define __IPTIMEDTASK_HPP__ + +#include "IpUtils.hpp" + +namespace Ipopt +{ + /** This class is used to collect timing information for a + * particular task. */ + class TimedTask + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + TimedTask() + : + total_cputime_(0.), + total_systime_(0.), + total_walltime_(0.), + start_called_(false), + end_called_(true) + {} + + /** Default destructor */ + ~TimedTask() + {} + //@} + + /** Method for resetting time to zero. */ + void Reset() + { + total_cputime_ = 0.; + total_systime_ = 0.; + total_walltime_ = 0.; + start_called_ = false; + end_called_ = true; + } + + /** Method that is called before execution of the task. */ + void Start() + { + DBG_ASSERT(end_called_); + DBG_ASSERT(!start_called_); + end_called_ = false; + start_called_ = true; + start_cputime_ = CpuTime(); + start_systime_ = SysTime(); + start_walltime_ = WallclockTime(); + } + + /** Method that is called after execution of the task. */ + void End() + { + DBG_ASSERT(!end_called_); + DBG_ASSERT(start_called_); + end_called_ = true; + start_called_ = false; + total_cputime_ += CpuTime() - start_cputime_; + total_systime_ += SysTime() - start_systime_; + total_walltime_ += WallclockTime() - start_walltime_; + } + + /** Method that is called after execution of the task for which + * timing might have been started. This only updates the timing + * if the timing has indeed been conducted. This is useful to + * stop timing after catching exceptions. */ + void EndIfStarted() + { + if (start_called_) { + end_called_ = true; + start_called_ = false; + total_cputime_ += CpuTime() - start_cputime_; + total_systime_ += SysTime() - start_systime_; + total_walltime_ += WallclockTime() - start_walltime_; + } + DBG_ASSERT(end_called_); + } + + /** Method returning total CPU time spend for task so far. */ + Number TotalCpuTime() const + { + DBG_ASSERT(end_called_); + return total_cputime_; + } + + /** Method returning total system time spend for task so far. */ + Number TotalSysTime() const + { + DBG_ASSERT(end_called_); + return total_systime_; + } + + /** Method returning total wall clock time spend for task so far. */ + Number TotalWallclockTime() const + { + DBG_ASSERT(end_called_); + return total_walltime_; + } + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not + * implemented and we do not want the compiler to implement them + * for us, so we declare them private and do not define + * them. This ensures that they will not be implicitly + * created/called. */ + //@{ + /** Copy Constructor */ + TimedTask(const TimedTask&); + + /** Overloaded Equals Operator */ + void operator=(const TimedTask&); + //@} + + /** CPU time at beginning of task. */ + Number start_cputime_; + /** Total CPU time for task measured so far. */ + Number total_cputime_; + /** System time at beginning of task. */ + Number start_systime_; + /** Total system time for task measured so far. */ + Number total_systime_; + /** Wall clock time at beginning of task. */ + Number start_walltime_; + /** Total wall clock time for task measured so far. */ + Number total_walltime_; + + /** @name fields for debugging */ + //@{ + bool start_called_; + bool end_called_; + //@} + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpTimingStatistics.hpp b/thirdparty/linux/include/coin/IpTimingStatistics.hpp new file mode 100644 index 0000000..850ed1b --- /dev/null +++ b/thirdparty/linux/include/coin/IpTimingStatistics.hpp @@ -0,0 +1,213 @@ +// Copyright (C) 2005, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTimingStatistics.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Andreas Waechter IBM 2005-09-19 + +#ifndef __IPTIMINGSTATISTICS_HPP__ +#define __IPTIMINGSTATISTICS_HPP__ + +#include "IpReferenced.hpp" +#include "IpJournalist.hpp" +#include "IpTimedTask.hpp" + +namespace Ipopt +{ + /** This class collects all timing statistics for Ipopt. + */ + class TimingStatistics : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + TimingStatistics() + {} + + /** Default destructor */ + virtual ~TimingStatistics() + {} + //@} + + /** Method for resetting all times. */ + void ResetTimes(); + + /** Method for printing all timing information */ + void PrintAllTimingStatistics(Journalist& jnlst, + EJournalLevel level, + EJournalCategory category) const; + + /**@name Accessor methods to all timed tasks. */ + //@{ + TimedTask& OverallAlgorithm() + { + return OverallAlgorithm_; + } + TimedTask& PrintProblemStatistics() + { + return PrintProblemStatistics_; + } + TimedTask& InitializeIterates() + { + return InitializeIterates_; + } + TimedTask& UpdateHessian() + { + return UpdateHessian_; + } + TimedTask& OutputIteration() + { + return OutputIteration_; + } + TimedTask& UpdateBarrierParameter() + { + return UpdateBarrierParameter_; + } + TimedTask& ComputeSearchDirection() + { + return ComputeSearchDirection_; + } + TimedTask& ComputeAcceptableTrialPoint() + { + return ComputeAcceptableTrialPoint_; + } + TimedTask& AcceptTrialPoint() + { + return AcceptTrialPoint_; + } + TimedTask& CheckConvergence() + { + return CheckConvergence_; + } + + TimedTask& PDSystemSolverTotal() + { + return PDSystemSolverTotal_; + } + TimedTask& PDSystemSolverSolveOnce() + { + return PDSystemSolverSolveOnce_; + } + TimedTask& ComputeResiduals() + { + return ComputeResiduals_; + } + TimedTask& StdAugSystemSolverMultiSolve() + { + return StdAugSystemSolverMultiSolve_; + } + TimedTask& LinearSystemScaling() + { + return LinearSystemScaling_; + } + TimedTask& LinearSystemSymbolicFactorization() + { + return LinearSystemSymbolicFactorization_; + } + TimedTask& LinearSystemFactorization() + { + return LinearSystemFactorization_; + } + TimedTask& LinearSystemBackSolve() + { + return LinearSystemBackSolve_; + } + TimedTask& LinearSystemStructureConverter() + { + return LinearSystemStructureConverter_; + } + TimedTask& LinearSystemStructureConverterInit() + { + return LinearSystemStructureConverterInit_; + } + TimedTask& QualityFunctionSearch() + { + return QualityFunctionSearch_; + } + TimedTask& TryCorrector() + { + return TryCorrector_; + } + + TimedTask& Task1() + { + return Task1_; + } + TimedTask& Task2() + { + return Task2_; + } + TimedTask& Task3() + { + return Task3_; + } + TimedTask& Task4() + { + return Task4_; + } + TimedTask& Task5() + { + return Task5_; + } + TimedTask& Task6() + { + return Task6_; + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TimingStatistics(const TimingStatistics&); + + /** Overloaded Equals Operator */ + void operator=(const TimingStatistics&); + //@} + + /**@name All timed tasks. */ + //@{ + TimedTask OverallAlgorithm_; + TimedTask PrintProblemStatistics_; + TimedTask InitializeIterates_; + TimedTask UpdateHessian_; + TimedTask OutputIteration_; + TimedTask UpdateBarrierParameter_; + TimedTask ComputeSearchDirection_; + TimedTask ComputeAcceptableTrialPoint_; + TimedTask AcceptTrialPoint_; + TimedTask CheckConvergence_; + + TimedTask PDSystemSolverTotal_; + TimedTask PDSystemSolverSolveOnce_; + TimedTask ComputeResiduals_; + TimedTask StdAugSystemSolverMultiSolve_; + TimedTask LinearSystemScaling_; + TimedTask LinearSystemSymbolicFactorization_; + TimedTask LinearSystemFactorization_; + TimedTask LinearSystemBackSolve_; + TimedTask LinearSystemStructureConverter_; + TimedTask LinearSystemStructureConverterInit_; + TimedTask QualityFunctionSearch_; + TimedTask TryCorrector_; + + TimedTask Task1_; + TimedTask Task2_; + TimedTask Task3_; + TimedTask Task4_; + TimedTask Task5_; + TimedTask Task6_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpTripletHelper.hpp b/thirdparty/linux/include/coin/IpTripletHelper.hpp new file mode 100644 index 0000000..35424c0 --- /dev/null +++ b/thirdparty/linux/include/coin/IpTripletHelper.hpp @@ -0,0 +1,135 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTripletHelper.hpp 2380 2013-09-06 22:57:49Z ghackebeil $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTRIPLETHELPER_HPP__ +#define __IPTRIPLETHELPER_HPP__ + +#include "IpTypes.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + + DECLARE_STD_EXCEPTION(UNKNOWN_MATRIX_TYPE); + DECLARE_STD_EXCEPTION(UNKNOWN_VECTOR_TYPE); + + /** forward declarations */ + class Matrix; + class GenTMatrix; + class SymTMatrix; + class DiagMatrix; + class IdentityMatrix; + class ExpansionMatrix; + class ScaledMatrix; + class SymScaledMatrix; + class SumMatrix; + class SumSymMatrix; + class ZeroMatrix; + class ZeroSymMatrix; + class CompoundMatrix; + class CompoundSymMatrix; + class TransposeMatrix; + class ExpandedMultiVectorMatrix; + class Vector; + + class TripletHelper + { + public: + /**@name A set of recursive routines that help with the Triplet format. */ + //@{ + /** find the total number of triplet entries of a Matrix */ + static Index GetNumberEntries(const Matrix& matrix); + + /** fill the irows, jcols structure for the triplet format from the matrix */ + static void FillRowCol(Index n_entries, const Matrix& matrix, Index* iRow, Index* jCol, Index row_offset=0, Index col_offset=0); + + /** fill the values for the triplet format from the matrix */ + static void FillValues(Index n_entries, const Matrix& matrix, Number* values); + + /** fill the values from the vector into a dense double* structure */ + static void FillValuesFromVector(Index dim, const Vector& vector, Number* values); + + /** put the values from the double* back into the vector */ + static void PutValuesInVector(Index dim, const double* values, Vector& vector); + //@} + + private: + /** find the total number of triplet entries for the SumMatrix */ + static Index GetNumberEntries_(const SumMatrix& matrix); + + /** find the total number of triplet entries for the SumSymMatrix */ + static Index GetNumberEntries_(const SumSymMatrix& matrix); + + /** find the total number of triplet entries for the CompoundMatrix */ + static Index GetNumberEntries_(const CompoundMatrix& matrix); + + /** find the total number of triplet entries for the CompoundSymMatrix */ + static Index GetNumberEntries_(const CompoundSymMatrix& matrix); + + /** find the total number of triplet entries for the TransposeMatrix */ + static Index GetNumberEntries_(const TransposeMatrix& matrix); + + /** find the total number of triplet entries for the TransposeMatrix */ + static Index GetNumberEntries_(const ExpandedMultiVectorMatrix& matrix); + + static void FillRowCol_(Index n_entries, const GenTMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const GenTMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SymTMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SymTMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const DiagMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const DiagMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const IdentityMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const IdentityMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ExpansionMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ExpansionMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SumMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SumMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SumSymMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SumSymMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const CompoundMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const CompoundMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const CompoundSymMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const CompoundSymMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ScaledMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ScaledMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SymScaledMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SymScaledMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const TransposeMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const TransposeMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ExpandedMultiVectorMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ExpandedMultiVectorMatrix& matrix, Number* values); + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpTypes.hpp b/thirdparty/linux/include/coin/IpTypes.hpp new file mode 100644 index 0000000..9c41b8f --- /dev/null +++ b/thirdparty/linux/include/coin/IpTypes.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTypes.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTYPES_HPP__ +#define __IPTYPES_HPP__ + +#include "IpoptConfig.h" + +namespace Ipopt +{ + /** Type of all numbers */ + typedef double Number; + /** Type of all indices of vectors, matrices etc */ + typedef int Index; + /** Type of default integer */ + typedef int Int; + +} // namespace Ipopt + +/* Type of Fortran integer translated into C */ +typedef FORTRAN_INTEGER_TYPE ipfint; + +#endif diff --git a/thirdparty/linux/include/coin/IpUtils.hpp b/thirdparty/linux/include/coin/IpUtils.hpp new file mode 100644 index 0000000..4e5f045 --- /dev/null +++ b/thirdparty/linux/include/coin/IpUtils.hpp @@ -0,0 +1,128 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpUtils.hpp 2167 2013-03-08 11:15:38Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPUTILS_HPP__ +#define __IPUTILS_HPP__ + +// Standard Ip Include Files +#include "IpTypes.hpp" +#include "IpDebug.hpp" + +namespace Ipopt +{ + + inline Index Max(Index a, Index b) + { + return ((a) > (b) ? (a) : (b)); + } + + inline Index Max(Index a, Index b, Index c) + { + Index max = Max(a,b); + max = Max(max, c); + return max; + } + + inline Index Max(Index a, Index b, Index c, Index d) + { + Index max = Max(a, b, c); + max = Max(max, d); + return max; + } + + inline Index Min(Index a, Index b) + { + return ((a) < (b) ? (a) : (b)); + } + + inline Index Min(Index a, Index b, Index c) + { + Index min = Min(a,b); + min = Min(min, c); + return min; + } + + inline Index Min(Index a, Index b, Index c, Index d) + { + Index min = Min(a, b, c); + min = Min(min, d); + return min; + } + + /////////////////////////////////////////// + + inline Number Max(Number a, Number b) + { + return ((a) > (b) ? (a) : (b)); + } + + inline Number Max(Number a, Number b, Number c) + { + Number max = Max(a,b); + max = Max(max, c); + return max; + } + + inline Number Max(Number a, Number b, Number c, Number d) + { + Number max = Max(a, b, c); + max = Max(max, d); + return max; + } + + inline Number Min(Number a, Number b) + { + return ((a) < (b) ? (a) : (b)); + } + + inline Number Min(Number a, Number b, Number c) + { + Number min = Min(a,b); + min = Min(min, c); + return min; + } + + inline Number Min(Number a, Number b, Number c, Number d) + { + Number min = Min(a, b, c); + min = Min(min, d); + return min; + } + + /** Function returning true iff the argument is a valid double number + * (not NaN or Inf). */ + bool IsFiniteNumber(Number val); + + /** Function returning a random number between 0 and 1 */ + Number IpRandom01(); + + /** Function resetting the random number generator */ + void IpResetRandom01(); + + /** method determining CPU time */ + Number CpuTime(); + + /** method determining system time */ + Number SysTime(); + + /** method determining wallclock time since first call */ + Number WallclockTime(); + + /** Method for comparing two numbers within machine precision. The + * return value is true if lhs is less or equal the rhs, relaxing + * this inequality by something a little larger than machine + * precision relative to the absolute value of BasVal. */ + bool Compare_le(Number lhs, Number rhs, Number BasVal); + + /** Method for printing a formatted output to a string with given size. + */ + int Snprintf(char* str, long size, const char* format, ...); + +} //namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/IpVector.hpp b/thirdparty/linux/include/coin/IpVector.hpp new file mode 100644 index 0000000..a903558 --- /dev/null +++ b/thirdparty/linux/include/coin/IpVector.hpp @@ -0,0 +1,774 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpVector.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPVECTOR_HPP__ +#define __IPVECTOR_HPP__ + +#include "IpTypes.hpp" +#include "IpTaggedObject.hpp" +#include "IpCachedResults.hpp" +#include "IpSmartPtr.hpp" +#include "IpJournalist.hpp" +#include "IpException.hpp" + +#include + +namespace Ipopt +{ + /** Exception that can be used to flag unimplemented linear algebra + * methods */ + DECLARE_STD_EXCEPTION(UNIMPLEMENTED_LINALG_METHOD_CALLED); + + /* forward declarations */ + class VectorSpace; + + /** Vector Base Class. + * This is the base class for all derived vector types. Those vectors + * are meant to store entities like iterates, Lagrangian multipliers, + * constraint values etc. The implementation of a vector type depends + * on the computational environment (e.g. just a double array on a shared + * memory machine, or distributed double arrays for a distributed + * memory machine.) + * + * Deriving from Vector: This class inherits from tagged object to + * implement an advanced caching scheme. Because of this, the + * TaggedObject method ObjectChanged() must be called each time the + * Vector changes. If you overload the XXXX_Impl protected methods, + * this taken care of (along with caching if possible) for you. If + * you have additional methods in your derived class that change the + * underlying data (vector values), you MUST remember to call + * ObjectChanged() AFTER making the change! + */ + class Vector : public TaggedObject + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor. It has to be given a pointer to the + * corresponding VectorSpace. + */ + inline + Vector(const VectorSpace* owner_space); + + /** Destructor */ + inline + virtual ~Vector(); + //@} + + /** Create new Vector of the same type with uninitialized data */ + inline + Vector* MakeNew() const; + + /** Create new Vector of the same type and copy the data over */ + inline + Vector* MakeNewCopy() const; + + /**@name Standard BLAS-1 Operations + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + inline + void Copy(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + void Scal(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + inline + void Axpy(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + inline + Number Dot(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + inline + Number Nrm2() const; + + /** Computes the 1-norm of this vector (DASUM) */ + inline + Number Asum() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + inline + Number Amax() const; + //@} + + /** @name Additional (Non-BLAS) Vector Methods + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Set each element in the vector to the scalar alpha. */ + inline + void Set(Number alpha); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$*/ + inline + void ElementWiseDivide(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$ */ + inline + void ElementWiseMultiply(const Vector& x); + + /** Element-wise max against entries in x */ + inline + void ElementWiseMax(const Vector& x); + + /** Element-wise min against entries in x */ + inline + void ElementWiseMin(const Vector& x); + + /** Reciprocates the entries in the vector */ + inline + void ElementWiseReciprocal(); + + /** Absolute values of the entries in the vector */ + inline + void ElementWiseAbs(); + + /** Element-wise square root of the entries in the vector */ + inline + void ElementWiseSqrt(); + + /** Replaces the vector values with their sgn values + ( -1 if x_i < 0, 0 if x_i == 0, and 1 if x_i > 0) + */ + inline + void ElementWiseSgn(); + + /** Add scalar to every vector component */ + inline + void AddScalar(Number scalar); + + /** Returns the maximum value in the vector */ + inline + Number Max() const; + + /** Returns the minimum value in the vector */ + inline + Number Min() const; + + /** Returns the sum of the vector entries */ + inline + Number Sum() const; + + /** Returns the sum of the logs of each vector entry */ + inline + Number SumLogs() const; + //@} + + /** @name Methods for specialized operations. A prototype + * implementation is provided, but for efficient implementation + * those should be specially implemented. + */ + //@{ + /** Add one vector, y = a * v1 + c * y. This is automatically + * reduced to call AddTwoVectors. */ + inline + void AddOneVector(Number a, const Vector& v1, Number c); + + /** Add two vectors, y = a * v1 + b * v2 + c * y. Here, this + * vector is y */ + inline void AddTwoVectors(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. Computes \f$\alpha = + * \max\{\bar\alpha\in(0,1] : x + \bar\alpha \Delta \geq (1-\tau)x\}\f$ + */ + inline + Number FracToBound(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + inline + void AddVectorQuotient(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + inline + bool HasValidNumbers() const; + + /** @name Accessor methods */ + //@{ + /** Dimension of the Vector */ + inline + Index Dim() const; + + /** Return the owner VectorSpace*/ + inline + SmartPtr OwnerSpace() const; + //@} + + /** @name Output methods + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Print the entire vector */ + void Print(SmartPtr jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + void Print(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + //@} + + protected: + /** @name implementation methods (derived classes MUST + * overload these pure virtual protected methods.) + */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x)=0; + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha)=0; + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x)=0; + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const =0; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const =0; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const =0; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const =0; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number alpha)=0; + + /** Element-wise division \f$y_i \gets y_i/x_i\f$*/ + virtual void ElementWiseDivideImpl(const Vector& x)=0; + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$ */ + virtual void ElementWiseMultiplyImpl(const Vector& x)=0; + + /** Element-wise max against entries in x */ + virtual void ElementWiseMaxImpl(const Vector& x)=0; + + /** Element-wise min against entries in x */ + virtual void ElementWiseMinImpl(const Vector& x)=0; + + /** Reciprocates the elements of the vector */ + virtual void ElementWiseReciprocalImpl()=0; + + /** Take elementwise absolute values of the elements of the vector */ + virtual void ElementWiseAbsImpl()=0; + + /** Take elementwise square-root of the elements of the vector */ + virtual void ElementWiseSqrtImpl()=0; + + /** Replaces entries with sgn of the entry */ + virtual void ElementWiseSgnImpl()=0; + + /** Add scalar to every component of vector */ + virtual void AddScalarImpl(Number scalar)=0; + + /** Max value in the vector */ + virtual Number MaxImpl() const=0; + + /** Min number in the vector */ + virtual Number MinImpl() const=0; + + /** Sum of entries in the vector */ + virtual Number SumImpl() const=0; + + /** Sum of logs of entries in the vector */ + virtual Number SumLogsImpl() const=0; + + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + virtual void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + + /** Fraction to boundary parameter. */ + virtual Number FracToBoundImpl(const Vector& delta, Number tau) const; + + /** Add the quotient of two vectors */ + virtual void AddVectorQuotientImpl(Number a, const Vector& z, + const Vector& s, Number c); + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). A default implementation using Asum is + * provided. */ + virtual bool HasValidNumbersImpl() const; + + /** Print the entire vector */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const =0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + Vector(); + + /** Copy constructor */ + Vector(const Vector&); + + /** Overloaded Equals Operator */ + Vector& operator=(const Vector&); + //@} + + /** Vector Space */ + const SmartPtr owner_space_; + + /**@name CachedResults data members */ + //@{ + /** Cache for dot products */ + mutable CachedResults dot_cache_; + + mutable TaggedObject::Tag nrm2_cache_tag_; + mutable Number cached_nrm2_; + + mutable TaggedObject::Tag asum_cache_tag_; + mutable Number cached_asum_; + + mutable TaggedObject::Tag amax_cache_tag_; + mutable Number cached_amax_; + + mutable TaggedObject::Tag max_cache_tag_; + mutable Number cached_max_; + + mutable TaggedObject::Tag min_cache_tag_; + mutable Number cached_min_; + + mutable TaggedObject::Tag sum_cache_tag_; + mutable Number cached_sum_; + + mutable TaggedObject::Tag sumlogs_cache_tag_; + mutable Number cached_sumlogs_; + + mutable TaggedObject::Tag valid_cache_tag_; + mutable bool cached_valid_; + + // AW: I removed this cache since it gets in the way for the + // quality function search + // /** Cache for FracToBound */ + // mutable CachedResults frac_to_bound_cache_; + //@} + + }; + + /** VectorSpace base class, corresponding to the Vector base class. + * For each Vector implementation, a corresponding VectorSpace has + * to be implemented. A VectorSpace is able to create new Vectors + * of a specific type. The VectorSpace should also store + * information that is common to all Vectors of that type. For + * example, the dimension of a Vector is stored in the VectorSpace + * base class. + */ + class VectorSpace : public ReferencedObject + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the dimension of all vectors generated by + * this VectorSpace. + */ + VectorSpace(Index dim); + + /** Destructor */ + virtual ~VectorSpace() + {} + //@} + + /** Pure virtual method for creating a new Vector of the + * corresponding type. + */ + virtual Vector* MakeNew() const=0; + + /** Accessor function for the dimension of the vectors of this type.*/ + Index Dim() const + { + return dim_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + VectorSpace(); + + /** Copy constructor */ + VectorSpace(const VectorSpace&); + + /** Overloaded Equals Operator */ + VectorSpace& operator=(const VectorSpace&); + //@} + + /** Dimension of the vectors in this vector space. */ + const Index dim_; + }; + + /* inline methods */ + inline + Vector::~Vector() + {} + + inline + Vector::Vector(const VectorSpace* owner_space) + : + TaggedObject(), + owner_space_(owner_space), + dot_cache_(10), + nrm2_cache_tag_(0), + asum_cache_tag_(0), + amax_cache_tag_(0), + max_cache_tag_(0), + min_cache_tag_(0), + sum_cache_tag_(0), + sumlogs_cache_tag_(0), + cached_valid_(0) + { + DBG_ASSERT(IsValid(owner_space_)); + } + + inline + Vector* Vector::MakeNew() const + { + return owner_space_->MakeNew(); + } + + inline + Vector* Vector::MakeNewCopy() const + { + // ToDo: We can probably copy also the cached values for Norms etc here + Vector* copy = MakeNew(); + copy->Copy(*this); + return copy; + } + + inline + void Vector::Copy(const Vector& x) + { + CopyImpl(x); + ObjectChanged(); + // Also copy any cached scalar values from the original vector + // ToDo: Check if that is too much overhead + TaggedObject::Tag x_tag = x.GetTag(); + if (x_tag == x.nrm2_cache_tag_) { + nrm2_cache_tag_ = GetTag(); + cached_nrm2_ = x.cached_nrm2_; + } + if (x_tag == x.asum_cache_tag_) { + asum_cache_tag_ = GetTag(); + cached_asum_ = x.cached_asum_; + } + if (x_tag == x.amax_cache_tag_) { + amax_cache_tag_ = GetTag(); + cached_amax_ = x.cached_amax_; + } + if (x_tag == x.max_cache_tag_) { + max_cache_tag_ = GetTag(); + cached_max_ = x.cached_max_; + } + if (x_tag == x.min_cache_tag_) { + min_cache_tag_ = GetTag(); + cached_min_ = x.cached_min_; + } + if (x_tag == x.sum_cache_tag_) { + sum_cache_tag_ = GetTag(); + cached_sum_ = x.cached_sum_; + } + if (x_tag == x.sumlogs_cache_tag_) { + sumlogs_cache_tag_ = GetTag(); + cached_sumlogs_ = x.cached_sumlogs_; + } + } + + inline + void Vector::Axpy(Number alpha, const Vector &x) + { + AxpyImpl(alpha, x); + ObjectChanged(); + } + + inline + Number Vector::Dot(const Vector &x) const + { + // The current implementation of the caching doesn't allow to have + // a dependency of something with itself. Therefore, we use the + // Nrm2 method if the dot product is to be taken with the vector + // itself. Might be more efficient anyway. + if (this==&x) { + Number nrm2 = Nrm2(); + return nrm2*nrm2; + } + Number retValue; + if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) { + retValue = DotImpl(x); + dot_cache_.AddCachedResult2Dep(retValue, this, &x); + } + return retValue; + } + + inline + Number Vector::Nrm2() const + { + if (nrm2_cache_tag_ != GetTag()) { + cached_nrm2_ = Nrm2Impl(); + nrm2_cache_tag_ = GetTag(); + } + return cached_nrm2_; + } + + inline + Number Vector::Asum() const + { + if (asum_cache_tag_ != GetTag()) { + cached_asum_ = AsumImpl(); + asum_cache_tag_ = GetTag(); + } + return cached_asum_; + } + + inline + Number Vector::Amax() const + { + if (amax_cache_tag_ != GetTag()) { + cached_amax_ = AmaxImpl(); + amax_cache_tag_ = GetTag(); + } + return cached_amax_; + } + + inline + Number Vector::Sum() const + { + if (sum_cache_tag_ != GetTag()) { + cached_sum_ = SumImpl(); + sum_cache_tag_ = GetTag(); + } + return cached_sum_; + } + + inline + Number Vector::SumLogs() const + { + if (sumlogs_cache_tag_ != GetTag()) { + cached_sumlogs_ = SumLogsImpl(); + sumlogs_cache_tag_ = GetTag(); + } + return cached_sumlogs_; + } + + inline + void Vector::ElementWiseSgn() + { + ElementWiseSgnImpl(); + ObjectChanged(); + } + + inline + void Vector::Set(Number alpha) + { + // Could initialize caches here + SetImpl(alpha); + ObjectChanged(); + } + + inline + void Vector::ElementWiseDivide(const Vector& x) + { + ElementWiseDivideImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMultiply(const Vector& x) + { + ElementWiseMultiplyImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseReciprocal() + { + ElementWiseReciprocalImpl(); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMax(const Vector& x) + { + // Could initialize some caches here + ElementWiseMaxImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMin(const Vector& x) + { + // Could initialize some caches here + ElementWiseMinImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseAbs() + { + // Could initialize some caches here + ElementWiseAbsImpl(); + ObjectChanged(); + } + + inline + void Vector::ElementWiseSqrt() + { + ElementWiseSqrtImpl(); + ObjectChanged(); + } + + inline + void Vector::AddScalar(Number scalar) + { + // Could initialize some caches here + AddScalarImpl(scalar); + ObjectChanged(); + } + + inline + Number Vector::Max() const + { + if (max_cache_tag_ != GetTag()) { + cached_max_ = MaxImpl(); + max_cache_tag_ = GetTag(); + } + return cached_max_; + } + + inline + Number Vector::Min() const + { + if (min_cache_tag_ != GetTag()) { + cached_min_ = MinImpl(); + min_cache_tag_ = GetTag(); + } + return cached_min_; + } + + inline + void Vector::AddOneVector(Number a, const Vector& v1, Number c) + { + AddTwoVectors(a, v1, 0., v1, c); + } + + inline + void Vector::AddTwoVectors(Number a, const Vector& v1, + Number b, const Vector& v2, Number c) + { + AddTwoVectorsImpl(a, v1, b, v2, c); + ObjectChanged(); + } + + inline + Number Vector::FracToBound(const Vector& delta, Number tau) const + { + /* AW: I avoid the caching here, since it leads to overhead in the + quality function search. Caches for this are in + CalculatedQuantities. + Number retValue; + std::vector tdeps(1); + tdeps[0] = δ + std::vector sdeps(1); + sdeps[0] = tau; + if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) { + retValue = FracToBoundImpl(delta, tau); + frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps); + } + return retValue; + */ + return FracToBoundImpl(delta, tau); + } + + inline + void Vector::AddVectorQuotient(Number a, const Vector& z, + const Vector& s, Number c) + { + AddVectorQuotientImpl(a, z, s, c); + ObjectChanged(); + } + + inline + bool Vector::HasValidNumbers() const + { + if (valid_cache_tag_ != GetTag()) { + cached_valid_ = HasValidNumbersImpl(); + valid_cache_tag_ = GetTag(); + } + return cached_valid_; + } + + inline + Index Vector::Dim() const + { + return owner_space_->Dim(); + } + + inline + SmartPtr Vector::OwnerSpace() const + { + return owner_space_; + } + + inline + VectorSpace::VectorSpace(Index dim) + : + dim_(dim) + {} + +} // namespace Ipopt + +// Macro definitions for debugging vectors +#if COIN_IPOPT_VERBOSITY == 0 +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) +#else +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + if (dbg_jrnl.Jnlst()!=NULL) { \ + (__vec).Print(dbg_jrnl.Jnlst(), \ + J_ERROR, J_DBG, \ + __vec_name, \ + dbg_jrnl.IndentationLevel()*2, \ + "# "); \ + } \ + } +#endif //if COIN_IPOPT_VERBOSITY == 0 + +#endif diff --git a/thirdparty/linux/include/coin/IpZeroSymMatrix.hpp b/thirdparty/linux/include/coin/IpZeroSymMatrix.hpp new file mode 100644 index 0000000..35ad95e --- /dev/null +++ b/thirdparty/linux/include/coin/IpZeroSymMatrix.hpp @@ -0,0 +1,135 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpZeroSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPZEROSYMMATRIX_HPP__ +#define __IPZEROSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for Symmetric Matrices with only zero entries. + */ + class ZeroSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the corresponding matrix space. + */ + ZeroSymMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~ZeroSymMatrix(); + //@} + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const + {} + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const + {} + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ZeroSymMatrix(); + + /** Copy Constructor */ + ZeroSymMatrix(const ZeroSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ZeroSymMatrix&); + //@} + }; + + /** Class for matrix space for ZeroSymMatrix. */ + class ZeroSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns. + */ + ZeroSymMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~ZeroSymMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewZeroSymMatrix(); + } + + /** Overloaded method from SymMatrixSpace base class + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewZeroSymMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + ZeroSymMatrix* MakeNewZeroSymMatrix() const + { + return new ZeroSymMatrix(this); + } + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ZeroSymMatrixSpace(); + + /** Copy Constructor */ + ZeroSymMatrixSpace(const ZeroSymMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const ZeroSymMatrixSpace&); + //@} + }; +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/IpoptConfig.h b/thirdparty/linux/include/coin/IpoptConfig.h new file mode 100644 index 0000000..78dadd3 --- /dev/null +++ b/thirdparty/linux/include/coin/IpoptConfig.h @@ -0,0 +1,22 @@ +/* src/Common/config_ipopt.h. Generated by configure. */ +/* src/Common/config_ipopt.h.in. */ + +#ifndef __CONFIG_IPOPT_H__ +#define __CONFIG_IPOPT_H__ + +/* Version number of project */ +#define IPOPT_VERSION "3.12.7" + +/* Major Version number of project */ +#define IPOPT_VERSION_MAJOR 3 + +/* Minor Version number of project */ +#define IPOPT_VERSION_MINOR 12 + +/* Release Version number of project */ +#define IPOPT_VERSION_RELEASE 7 + +/* Define to the C type corresponding to Fortran INTEGER */ +#define FORTRAN_INTEGER_TYPE int + +#endif diff --git a/thirdparty/linux/include/coin/OsiAuxInfo.hpp b/thirdparty/linux/include/coin/OsiAuxInfo.hpp new file mode 100644 index 0000000..182d981 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiAuxInfo.hpp @@ -0,0 +1,206 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiAuxInfo_H +#define OsiAuxInfo_H + +class OsiSolverInterface; + +//############################################################################# +/** This class allows for a more structured use of algorithmic tweaking to + an OsiSolverInterface. It is designed to replace the simple use of + appData_ pointer. + + This has been done to make it easier to use NonLinear solvers and other + exotic beasts in a branch and bound mode. After this class definition + there is one for a derived class for just such a purpose. + +*/ + +class OsiAuxInfo { +public: + // Default Constructor + OsiAuxInfo (void * appData = NULL); + + // Copy Constructor + OsiAuxInfo (const OsiAuxInfo & rhs); + // Destructor + virtual ~OsiAuxInfo(); + + /// Clone + virtual OsiAuxInfo * clone() const; + /// Assignment operator + OsiAuxInfo & operator=(const OsiAuxInfo& rhs); + + /// Get application data + inline void * getApplicationData() const + { return appData_;} +protected: + /// Pointer to user-defined data structure + void * appData_; +}; +//############################################################################# +/** This class allows for the use of more exotic solvers e.g. Non-Linear or Volume. + + You can derive from this although at present I can't see the need. +*/ + +class OsiBabSolver : public OsiAuxInfo { +public: + // Default Constructor + OsiBabSolver (int solverType=0); + + // Copy Constructor + OsiBabSolver (const OsiBabSolver & rhs); + // Destructor + virtual ~OsiBabSolver(); + + /// Clone + virtual OsiAuxInfo * clone() const; + /// Assignment operator + OsiBabSolver & operator=(const OsiBabSolver& rhs); + + /// Update solver + inline void setSolver(const OsiSolverInterface * solver) + { solver_ = solver;} + /// Update solver + inline void setSolver(const OsiSolverInterface & solver) + { solver_ = &solver;} + + /** returns 0 if no heuristic solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value + numberColumns is size of newSolution + */ + int solution(double & objectiveValue, + double * newSolution, int numberColumns); + /** Set solution and objective value. + Number of columns and optimization direction taken from current solver. + Size of solution is numberColumns (may be padded or truncated in function) */ + void setSolution(const double * solution, int numberColumns, double objectiveValue); + + /** returns true if the object stores a solution, false otherwise. If there + is a solution then solutionValue and solution will be filled out as well. + In that case the user needs to allocate solution to be a big enough + array. + */ + bool hasSolution(double & solutionValue, double * solution); + + /** Sets solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check solver to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + 4 - normal solver but cuts are needed for integral solution + */ + inline void setSolverType(int value) + { solverType_=value;} + /** gets solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + 4 - normal solver but cuts are needed for integral solution + */ + inline int solverType() const + { return solverType_;} + /** Return true if getting solution may add cuts so hot start etc will + be obsolete */ + inline bool solutionAddsCuts() const + { return solverType_==3;} + /// Return true if we should try cuts at root even if looks satisfied + inline bool alwaysTryCutsAtRootNode() const + { return solverType_==4;} + /** Returns true if can use solver objective or feasible values, + otherwise use mipBound etc */ + inline bool solverAccurate() const + { return solverType_==0||solverType_==2||solverType_==4;} + /// Returns true if can use reduced costs for fixing + inline bool reducedCostsAccurate() const + { return solverType_==0||solverType_==4;} + /// Get objective (well mip bound) + double mipBound() const; + /// Returns true if node feasible + bool mipFeasible() const; + /// Set mip bound (only used for some solvers) + inline void setMipBound(double value) + { mipBound_ = value;} + /// Get objective value of saved solution + inline double bestObjectiveValue() const + { return bestObjectiveValue_;} + /// Says whether we want to try cuts at all + inline bool tryCuts() const + { return solverType_!=2;} + /// Says whether we have a warm start (so can do strong branching) + inline bool warmStart() const + { return solverType_!=2;} + /** Get bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + inline int extraCharacteristics() const + { return extraCharacteristics_;} + /** Set bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + inline void setExtraCharacteristics(int value) + { extraCharacteristics_=value;} + /// Pointer to lower bounds before branch (only if extraCharacteristics set) + inline const double * beforeLower() const + { return beforeLower_;} + /// Set pointer to lower bounds before branch (only if extraCharacteristics set) + inline void setBeforeLower(const double * array) + { beforeLower_ = array;} + /// Pointer to upper bounds before branch (only if extraCharacteristics set) + inline const double * beforeUpper() const + { return beforeUpper_;} + /// Set pointer to upper bounds before branch (only if extraCharacteristics set) + inline void setBeforeUpper(const double * array) + { beforeUpper_ = array;} +protected: + /// Objective value of best solution (if there is one) (minimization) + double bestObjectiveValue_; + /// Current lower bound on solution ( if > 1.0e50 infeasible) + double mipBound_; + /// Solver to use for getting/setting solutions etc + const OsiSolverInterface * solver_; + /// Best integer feasible solution + double * bestSolution_; + /// Pointer to lower bounds before branch (only if extraCharacteristics set) + const double * beforeLower_; + /// Pointer to upper bounds before branch (only if extraCharacteristics set) + const double * beforeUpper_; + /** Solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + */ + int solverType_; + /// Size of solution + int sizeSolution_; + /** Bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + int extraCharacteristics_; +}; + +#endif diff --git a/thirdparty/linux/include/coin/OsiBranchingObject.hpp b/thirdparty/linux/include/coin/OsiBranchingObject.hpp new file mode 100644 index 0000000..78b6984 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiBranchingObject.hpp @@ -0,0 +1,1005 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiBranchingObject_H +#define OsiBranchingObject_H + +#include +#include +#include + +#include "CoinError.hpp" +#include "CoinTypes.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiBranchingObject; +class OsiBranchingInformation; + +//############################################################################# +//This contains the abstract base class for an object and for branching. +//It also contains a simple integer class +//############################################################################# + +/** Abstract base class for `objects'. + + The branching model used in Osi is based on the idea of an object. + In the abstract, an object is something that has a feasible region, can be + evaluated for infeasibility, can be branched on (i.e., there's some + constructive action to be taken to move toward feasibility), and allows + comparison of the effect of branching. + + This class (OsiObject) is the base class for an object. To round out the + branching model, the class OsiBranchingObject describes how to perform a + branch, and the class OsiBranchDecision describes how to compare two + OsiBranchingObjects. + + To create a new type of object you need to provide three methods: + #infeasibility(), #feasibleRegion(), and #createBranch(), described below. + + This base class is primarily virtual to allow for any form of structure. + Any form of discontinuity is allowed. + + As there is an overhead in getting information from solvers and because + other useful information is available there is also an OsiBranchingInformation + class which can contain pointers to information. + If used it must at minimum contain pointers to current value of objective, + maximum allowed objective and pointers to arrays for bounds and solution + and direction of optimization. Also integer and primal tolerance. + + Classes which inherit might have other information such as depth, number of + solutions, pseudo-shadow prices etc etc. + May be easier just to throw in here - as I keep doing +*/ +class OsiObject { + +public: + + /// Default Constructor + OsiObject (); + + /// Copy constructor + OsiObject ( const OsiObject &); + + /// Assignment operator + OsiObject & operator=( const OsiObject& rhs); + + /// Clone + virtual OsiObject * clone() const=0; + + /// Destructor + virtual ~OsiObject (); + + /** Infeasibility of the object + + This is some measure of the infeasibility of the object. 0.0 + indicates that the object is satisfied. + + The preferred branching direction is returned in whichWay, where for + normal two-way branching 0 is down, 1 is up + + This is used to prepare for strong branching but should also think of + case when no strong branching + + The object may also compute an estimate of cost of going "up" or "down". + This will probably be based on pseudo-cost ideas + + This should also set mutable infeasibility_ and whichWay_ + This is for instant re-use for speed + + Default for this just calls infeasibility with OsiBranchingInformation + NOTE - Convention says that an infeasibility of COIN_DBL_MAX means + object has worked out it can't be satisfied! + */ + double infeasibility(const OsiSolverInterface * solver,int &whichWay) const ; + // Faster version when more information available + virtual double infeasibility(const OsiBranchingInformation * info, int &whichWay) const =0; + // This does NOT set mutable stuff + virtual double checkInfeasibility(const OsiBranchingInformation * info) const; + + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + Returns measure of how much it had to move solution to make feasible + */ + virtual double feasibleRegion(OsiSolverInterface * solver) const ; + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + Returns measure of how much it had to move solution to make feasible + Faster version + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const =0; + + /** Create a branching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * /*solver*/, + const OsiBranchingInformation * /*info*/, + int /*way*/) const {throw CoinError("Need code","createBranch","OsiBranchingObject"); return NULL; } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return true;} + /** \brief Return true if object can take part in move to nearest heuristic + */ + virtual bool canMoveToNearest() const + {return false;} + /** Column number if single column object -1 otherwise, + Used by heuristics + */ + virtual int columnNumber() const; + /// Return Priority - note 1 is highest priority + inline int priority() const + { return priority_;} + /// Set priority + inline void setPriority(int priority) + { priority_ = priority;} + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const + {return true;} + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return false;} + /// Return maximum number of ways branch may have + inline int numberWays() const + { return numberWays_;} + /// Set maximum number of ways branch may have + inline void setNumberWays(int numberWays) + { numberWays_ = static_cast(numberWays) ; } + /** Return preferred way to branch. If two + then way=0 means down and 1 means up, otherwise + way points to preferred branch + */ + inline void setWhichWay(int way) + { whichWay_ = static_cast(way) ; } + /** Return current preferred way to branch. If two + then way=0 means down and 1 means up, otherwise + way points to preferred branch + */ + inline int whichWay() const + { return whichWay_;} + /// Get pre-emptive preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + virtual int preferredWay() const + { return -1;} + /// Return infeasibility + inline double infeasibility() const + { return infeasibility_;} + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /** Reset variable bounds to their original values. + Bounds may be tightened, so it may be good to be able to reset them to + their original values. + */ + virtual void resetBounds(const OsiSolverInterface * ) {} + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int , const int * ) {} + /// Updates stuff like pseudocosts before threads + virtual void updateBefore(const OsiObject * ) {} + /// Updates stuff like pseudocosts after threads finished + virtual void updateAfter(const OsiObject * , const OsiObject * ) {} + +protected: + /// data + + /// Computed infeasibility + mutable double infeasibility_; + /// Computed preferred way to branch + mutable short whichWay_; + /// Maximum number of ways on branch + short numberWays_; + /// Priority + int priority_; + +}; +/// Define a class to add a bit of complexity to OsiObject +/// This assumes 2 way branching + + +class OsiObject2 : public OsiObject { + +public: + + /// Default Constructor + OsiObject2 (); + + /// Copy constructor + OsiObject2 ( const OsiObject2 &); + + /// Assignment operator + OsiObject2 & operator=( const OsiObject2& rhs); + + /// Destructor + virtual ~OsiObject2 (); + + /// Set preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + inline void setPreferredWay(int value) + {preferredWay_=value;} + + /// Get preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + virtual int preferredWay() const + { return preferredWay_;} +protected: + /// Preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + int preferredWay_; + /// "Infeasibility" on other way + mutable double otherInfeasibility_; + +}; + +/** \brief Abstract branching object base class + + In the abstract, an OsiBranchingObject contains instructions for how to + branch. We want an abstract class so that we can describe how to branch on + simple objects (e.g., integers) and more exotic objects + (e.g., cliques or hyperplanes). + + The #branch() method is the crucial routine: it is expected to be able to + step through a set of branch arms, executing the actions required to create + each subproblem in turn. The base class is primarily virtual to allow for + a wide range of problem modifications. + + See OsiObject for an overview of the two classes (OsiObject and + OsiBranchingObject) which make up Osi's branching + model. +*/ + +class OsiBranchingObject { + +public: + + /// Default Constructor + OsiBranchingObject (); + + /// Constructor + OsiBranchingObject (OsiSolverInterface * solver, double value); + + /// Copy constructor + OsiBranchingObject ( const OsiBranchingObject &); + + /// Assignment operator + OsiBranchingObject & operator=( const OsiBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const=0; + + /// Destructor + virtual ~OsiBranchingObject (); + + /// The number of branch arms created for this branching object + inline int numberBranches() const + {return numberBranches_;} + + /// The number of branch arms left for this branching object + inline int numberBranchesLeft() const + {return numberBranches_-branchIndex_;} + + /// Increment the number of branch arms left for this branching object + inline void incrementNumberBranchesLeft() + { numberBranches_ ++;} + + /** Set the number of branch arms left for this branching object + Just for forcing + */ + inline void setNumberBranchesLeft(int /*value*/) + {/*assert (value==1&&!branchIndex_);*/ numberBranches_=1;} + + /// Decrement the number of branch arms left for this branching object + inline void decrementNumberBranchesLeft() + {branchIndex_++;} + + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver)=0; + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. + Returns change in guessed objective on next branch + */ + virtual double branch() {return branch(NULL);} + /** \brief Return true if branch should fix variables + */ + virtual bool boundBranch() const + {return true;} + /** Get the state of the branching object + This is just the branch index + */ + inline int branchIndex() const + {return branchIndex_;} + + /** Set the state of the branching object. + */ + inline void setBranchingIndex(int branchIndex) + { branchIndex_ = static_cast(branchIndex) ; } + + /// Current value + inline double value() const + {return value_;} + + /// Return pointer back to object which created + inline const OsiObject * originalObject() const + {return originalObject_;} + /// Set pointer back to object which created + inline void setOriginalObject(const OsiObject * object) + {originalObject_=object;} + /** Double checks in case node can change its mind! + Returns objective value + Can change objective etc */ + virtual void checkIsCutoff(double ) {} + /// For debug + int columnNumber() const; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * =NULL) const {} + +protected: + + /// Current value - has some meaning about branch + double value_; + + /// Pointer back to object which created + const OsiObject * originalObject_; + + /** Number of branches + */ + int numberBranches_; + + /** The state of the branching object. i.e. branch index + This starts at 0 when created + */ + short branchIndex_; + +}; +/* This contains information + This could also contain pseudo shadow prices + or information for dealing with computing and trusting pseudo-costs +*/ +class OsiBranchingInformation { + +public: + + /// Default Constructor + OsiBranchingInformation (); + + /** Useful Constructor + (normalSolver true if has matrix etc etc) + copySolution true if constructot should make a copy + */ + OsiBranchingInformation (const OsiSolverInterface * solver, bool normalSolver,bool copySolution=false); + + /// Copy constructor + OsiBranchingInformation ( const OsiBranchingInformation &); + + /// Assignment operator + OsiBranchingInformation & operator=( const OsiBranchingInformation& rhs); + + /// Clone + virtual OsiBranchingInformation * clone() const; + + /// Destructor + virtual ~OsiBranchingInformation (); + + // Note public +public: + /// data + + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + int stateOfSearch_; + /// Value of objective function (in minimization sense) + double objectiveValue_; + /// Value of objective cutoff (in minimization sense) + double cutoff_; + /// Direction 1.0 for minimization, -1.0 for maximization + double direction_; + /// Integer tolerance + double integerTolerance_; + /// Primal tolerance + double primalTolerance_; + /// Maximum time remaining before stopping on time + double timeRemaining_; + /// Dual to use if row bound violated (if negative then pseudoShadowPrices off) + double defaultDual_; + /// Pointer to solver + mutable const OsiSolverInterface * solver_; + /// The number of columns + int numberColumns_; + /// Pointer to current lower bounds on columns + mutable const double * lower_; + /// Pointer to current solution + mutable const double * solution_; + /// Pointer to current upper bounds on columns + mutable const double * upper_; + /// Highly optional target (hot start) solution + const double * hotstartSolution_; + /// Pointer to duals + const double * pi_; + /// Pointer to row activity + const double * rowActivity_; + /// Objective + const double * objective_; + /// Pointer to current lower bounds on rows + const double * rowLower_; + /// Pointer to current upper bounds on rows + const double * rowUpper_; + /// Elements in column copy of matrix + const double * elementByColumn_; + /// Column starts + const CoinBigIndex * columnStart_; + /// Column lengths + const int * columnLength_; + /// Row indices + const int * row_; + /** Useful region of length CoinMax(numberColumns,2*numberRows) + This is allocated and deleted before OsiObject::infeasibility + It is zeroed on entry and should be so on exit + It only exists if defaultDual_>=0.0 + */ + double * usefulRegion_; + /// Useful index region to go with usefulRegion_ + int * indexRegion_; + /// Number of solutions found + int numberSolutions_; + /// Number of branching solutions found (i.e. exclude heuristics) + int numberBranchingSolutions_; + /// Depth in tree + int depth_; + /// TEMP + bool owningSolution_; +}; + +/// This just adds two-wayness to a branching object + +class OsiTwoWayBranchingObject : public OsiBranchingObject { + +public: + + /// Default constructor + OsiTwoWayBranchingObject (); + + /** Create a standard tw0-way branch object + + Specifies a simple two-way branch. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiTwoWayBranchingObject (OsiSolverInterface *solver,const OsiObject * originalObject, + int way , double value) ; + + /// Copy constructor + OsiTwoWayBranchingObject ( const OsiTwoWayBranchingObject &); + + /// Assignment operator + OsiTwoWayBranchingObject & operator= (const OsiTwoWayBranchingObject& rhs); + + /// Destructor + virtual ~OsiTwoWayBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver)=0; + + inline int firstBranch() const { return firstBranch_; } + /// Way returns -1 on down +1 on up + inline int way() const + { return !branchIndex_ ? firstBranch_ : -firstBranch_;} +protected: + /// Which way was first branch -1 = down, +1 = up + int firstBranch_; +}; +/// Define a single integer class + + +class OsiSimpleInteger : public OsiObject2 { + +public: + + /// Default Constructor + OsiSimpleInteger (); + + /// Useful constructor - passed solver index + OsiSimpleInteger (const OsiSolverInterface * solver, int iColumn); + + /// Useful constructor - passed solver index and original bounds + OsiSimpleInteger (int iColumn, double lower, double upper); + + /// Copy constructor + OsiSimpleInteger ( const OsiSimpleInteger &); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiSimpleInteger & operator=( const OsiSimpleInteger& rhs); + + /// Destructor + virtual ~OsiSimpleInteger (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + + /// Set solver column number + inline void setColumnNumber(int value) + {columnNumber_=value;} + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + + /// Original bounds + inline double originalLowerBound() const + { return originalLower_;} + inline void setOriginalLowerBound(double value) + { originalLower_=value;} + inline double originalUpperBound() const + { return originalUpper_;} + inline void setOriginalUpperBound(double value) + { originalUpper_=value;} + /** Reset variable bounds to their original values. + Bounds may be tightened, so it may be good to be able to reset them to + their original values. + */ + virtual void resetBounds(const OsiSolverInterface * solver) ; + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return false;} +protected: + /// data + /// Original lower bound + double originalLower_; + /// Original upper bound + double originalUpper_; + /// Column number in solver + int columnNumber_; + +}; +/** Simple branching object for an integer variable + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. 0 -> down, 1-> up. +*/ + +class OsiIntegerBranchingObject : public OsiTwoWayBranchingObject { + +public: + + /// Default constructor + OsiIntegerBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject, + int way , double value) ; + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch in a more flexible way. One arm of the + branch will be lb <= x <= downUpperBound, the other upLowerBound <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject, + int way , double value, double downUpperBound, double upLowerBound) ; + + /// Copy constructor + OsiIntegerBranchingObject ( const OsiIntegerBranchingObject &); + + /// Assignment operator + OsiIntegerBranchingObject & operator= (const OsiIntegerBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + /// Destructor + virtual ~OsiIntegerBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); + +protected: + // Probably could get away with just value which is already stored + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +}; + + +/** Define Special Ordered Sets of type 1 and 2. These do not have to be + integer - so do not appear in lists of integers. + + which_ points columns of matrix +*/ + + +class OsiSOS : public OsiObject2 { + +public: + + // Default Constructor + OsiSOS (); + + /** Useful constructor - which are indices + and weights are also given. If null then 0,1,2.. + type is SOS type + */ + OsiSOS (const OsiSolverInterface * solver, int numberMembers, + const int * which, const double * weights, int type=1); + + // Copy constructor + OsiSOS ( const OsiSOS &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiSOS & operator=( const OsiSOS& rhs); + + // Destructor + virtual ~OsiSOS (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info,int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of members + inline int numberMembers() const + {return numberMembers_;} + + /// Members (indices in range 0 ... numberColumns-1) + inline const int * members() const + {return members_;} + + /// SOS type + inline int sosType() const + {return sosType_;} + + /// SOS type + inline int setType() const + {return sosType_;} + + /** Array of weights */ + inline const double * weights() const + { return weights_;} + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return (sosType_==1&&integerValued_);} + /// Set whether set is integer valued or not + inline void setIntegerValued(bool yesNo) + { integerValued_=yesNo;} + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return true;} + /// Set number of members + inline void setNumberMembers(int value) + {numberMembers_=value;} + + /// Members (indices in range 0 ... numberColumns-1) + inline int * mutableMembers() const + {return members_;} + + /// Set SOS type + inline void setSosType(int value) + {sosType_=value;} + + /** Array of weights */ + inline double * mutableWeights() const + { return weights_;} +protected: + /// data + + /// Members (indices in range 0 ... numberColumns-1) + int * members_; + /// Weights + double * weights_; + + /// Number of members + int numberMembers_; + /// SOS type + int sosType_; + /// Whether integer valued + bool integerValued_; +}; + +/** Branching object for Special ordered sets + + */ +class OsiSOSBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiSOSBranchingObject (); + + // Useful constructor + OsiSOSBranchingObject (OsiSolverInterface * solver, const OsiSOS * originalObject, + int way, + double separator); + + // Copy constructor + OsiSOSBranchingObject ( const OsiSOSBranchingObject &); + + // Assignment operator + OsiSOSBranchingObject & operator=( const OsiSOSBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiSOSBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); +private: + /// data +}; +/** Lotsize class */ + + +class OsiLotsize : public OsiObject2 { + +public: + + // Default Constructor + OsiLotsize (); + + /* Useful constructor - passed model index. + Also passed valid values - if range then pairs + */ + OsiLotsize (const OsiSolverInterface * solver, int iColumn, + int numberPoints, const double * points, bool range=false); + + // Copy constructor + OsiLotsize ( const OsiLotsize &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiLotsize & operator=( const OsiLotsize& rhs); + + // Destructor + virtual ~OsiLotsize (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to contain the current solution. + + More precisely, for the variable associated with this object, take the + value given in the current solution, force it within the current bounds + if required, then set the bounds to fix the variable at the integer + nearest the solution value. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + + /// Set solver column number + inline void setColumnNumber(int value) + {columnNumber_=value;} + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + /** Reset original upper and lower bound values from the solver. + + Handy for updating bounds held in this object after bounds held in the + solver have been tightened. + */ + virtual void resetBounds(const OsiSolverInterface * solver); + + /** Finds range of interest so value is feasible in range range_ or infeasible + between hi[range_] and lo[range_+1]. Returns true if feasible. + */ + bool findRange(double value, double integerTolerance) const; + + /** Returns floor and ceiling + */ + virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value, + double tolerance) const; + + /// Original bounds + inline double originalLowerBound() const + { return bound_[0];} + inline double originalUpperBound() const + { return bound_[rangeType_*numberRanges_-1];} + /// Type - 1 points, 2 ranges + inline int rangeType() const + { return rangeType_;} + /// Number of points + inline int numberRanges() const + { return numberRanges_;} + /// Ranges + inline double * bound() const + { return bound_;} + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return true;} + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return false;} + +private: + /// data + + /// Column number in model + int columnNumber_; + /// Type - 1 points, 2 ranges + int rangeType_; + /// Number of points + int numberRanges_; + // largest gap + double largestGap_; + /// Ranges + double * bound_; + /// Current range + mutable int range_; +}; + + +/** Lotsize branching object + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class OsiLotsizeBranchingObject : public OsiTwoWayBranchingObject { + +public: + + /// Default constructor + OsiLotsizeBranchingObject (); + + /** Create a lotsize floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= valid range below(x*), the other valid range above(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiLotsizeBranchingObject (OsiSolverInterface *solver,const OsiLotsize * originalObject, + int way , double value) ; + + /// Copy constructor + OsiLotsizeBranchingObject ( const OsiLotsizeBranchingObject &); + + /// Assignment operator + OsiLotsizeBranchingObject & operator= (const OsiLotsizeBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + /// Destructor + virtual ~OsiLotsizeBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); + +protected: + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +}; +#endif diff --git a/thirdparty/linux/include/coin/OsiChooseVariable.hpp b/thirdparty/linux/include/coin/OsiChooseVariable.hpp new file mode 100644 index 0000000..1613bca --- /dev/null +++ b/thirdparty/linux/include/coin/OsiChooseVariable.hpp @@ -0,0 +1,534 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiChooseVariable_H +#define OsiChooseVariable_H + +#include +#include + +#include "CoinWarmStartBasis.hpp" +#include "OsiBranchingObject.hpp" + +class OsiSolverInterface; +class OsiHotInfo; + +/** This class chooses a variable to branch on + + The base class just chooses the variable and direction without strong branching but it + has information which would normally be used by strong branching e.g. to re-enter + having fixed a variable but using same candidates for strong branching. + + The flow is : + a) initialize the process. This decides on strong branching list + and stores indices of all infeasible objects + b) do strong branching on list. If list is empty then just + choose one candidate and return without strong branching. If not empty then + go through list and return best. However we may find that the node is infeasible + or that we can fix a variable. If so we return and it is up to user to call + again (after fixing a variable). +*/ + +class OsiChooseVariable { + +public: + + /// Default Constructor + OsiChooseVariable (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseVariable (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseVariable (const OsiChooseVariable &); + + /// Assignment operator + OsiChooseVariable & operator= (const OsiChooseVariable& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseVariable (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + /// Returns true if solution looks feasible against given objects + virtual bool feasibleSolution(const OsiBranchingInformation * info, + const double * solution, + int numberObjects, + const OsiObject ** objects); + /// Saves a good solution + void saveSolution(const OsiSolverInterface * solver); + /// Clears out good solution after use + void clearGoodSolution(); + /// Given a candidate fill in useful information e.g. estimates + virtual void updateInformation( const OsiBranchingInformation *info, + int branch, OsiHotInfo * hotInfo); +#if 1 + /// Given a branch fill in useful information e.g. estimates + virtual void updateInformation( int whichObject, int branch, + double changeInObjective, double changeInValue, + int status); +#endif + /// Objective value for feasible solution + inline double goodObjectiveValue() const + { return goodObjectiveValue_;} + /// Estimate of up change or change on chosen if n-way + inline double upChange() const + { return upChange_;} + /// Estimate of down change or max change on other possibilities if n-way + inline double downChange() const + { return downChange_;} + /// Good solution - deleted by finalize + inline const double * goodSolution() const + { return goodSolution_;} + /// Index of chosen object + inline int bestObjectIndex() const + { return bestObjectIndex_;} + /// Set index of chosen object + inline void setBestObjectIndex(int value) + { bestObjectIndex_ = value;} + /// Preferred way of chosen object + inline int bestWhichWay() const + { return bestWhichWay_;} + /// Set preferred way of chosen object + inline void setBestWhichWay(int value) + { bestWhichWay_ = value;} + /// Index of forced object + inline int firstForcedObjectIndex() const + { return firstForcedObjectIndex_;} + /// Set index of forced object + inline void setFirstForcedObjectIndex(int value) + { firstForcedObjectIndex_ = value;} + /// Preferred way of forced object + inline int firstForcedWhichWay() const + { return firstForcedWhichWay_;} + /// Set preferred way of forced object + inline void setFirstForcedWhichWay(int value) + { firstForcedWhichWay_ = value;} + /// Get the number of objects unsatisfied at this node - accurate on first pass + inline int numberUnsatisfied() const + {return numberUnsatisfied_;} + /// Number of objects to choose for strong branching + inline int numberStrong() const + { return numberStrong_;} + /// Set number of objects to choose for strong branching + inline void setNumberStrong(int value) + { numberStrong_ = value;} + /// Number left on strong list + inline int numberOnList() const + { return numberOnList_;} + /// Number of strong branches actually done + inline int numberStrongDone() const + { return numberStrongDone_;} + /// Number of strong iterations actually done + inline int numberStrongIterations() const + { return numberStrongIterations_;} + /// Number of strong branches which changed bounds + inline int numberStrongFixed() const + { return numberStrongFixed_;} + /// List of candidates + inline const int * candidates() const + { return list_;} + /// Trust results from strong branching for changing bounds + inline bool trustStrongForBound() const + { return trustStrongForBound_;} + /// Set trust results from strong branching for changing bounds + inline void setTrustStrongForBound(bool yesNo) + { trustStrongForBound_ = yesNo;} + /// Trust results from strong branching for valid solution + inline bool trustStrongForSolution() const + { return trustStrongForSolution_;} + /// Set trust results from strong branching for valid solution + inline void setTrustStrongForSolution(bool yesNo) + { trustStrongForSolution_ = yesNo;} + /// Set solver and redo arrays + void setSolver (const OsiSolverInterface * solver); + /** Return status - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + */ + inline int status() const + { return status_;} + inline void setStatus(int value) + { status_ = value;} + + +protected: + // Data + /// Objective value for feasible solution + double goodObjectiveValue_; + /// Estimate of up change or change on chosen if n-way + double upChange_; + /// Estimate of down change or max change on other possibilities if n-way + double downChange_; + /// Good solution - deleted by finalize + double * goodSolution_; + /// List of candidates + int * list_; + /// Useful array (for sorting etc) + double * useful_; + /// Pointer to solver + const OsiSolverInterface * solver_; + /* Status - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + */ + int status_; + /// Index of chosen object + int bestObjectIndex_; + /// Preferred way of chosen object + int bestWhichWay_; + /// Index of forced object + int firstForcedObjectIndex_; + /// Preferred way of forced object + int firstForcedWhichWay_; + /// The number of objects unsatisfied at this node. + int numberUnsatisfied_; + /// Number of objects to choose for strong branching + int numberStrong_; + /// Number left on strong list + int numberOnList_; + /// Number of strong branches actually done + int numberStrongDone_; + /// Number of strong iterations actually done + int numberStrongIterations_; + /// Number of bound changes due to strong branching + int numberStrongFixed_; + /// List of unsatisfied objects - first numberOnList_ for strong branching + /// Trust results from strong branching for changing bounds + bool trustStrongForBound_; + /// Trust results from strong branching for valid solution + bool trustStrongForSolution_; +}; + +/** This class is the placeholder for the pseudocosts used by OsiChooseStrong. + It can also be used by any other pseudocost based strong branching + algorithm. +*/ + +class OsiPseudoCosts { +protected: + // Data + /// Total of all changes up + double * upTotalChange_; + /// Total of all changes down + double * downTotalChange_; + /// Number of times up + int * upNumber_; + /// Number of times down + int * downNumber_; + /// Number of objects (could be found from solver) + int numberObjects_; + /// Number before we trust + int numberBeforeTrusted_; + +private: + void gutsOfDelete(); + void gutsOfCopy(const OsiPseudoCosts& rhs); + +public: + OsiPseudoCosts(); + virtual ~OsiPseudoCosts(); + OsiPseudoCosts(const OsiPseudoCosts& rhs); + OsiPseudoCosts& operator=(const OsiPseudoCosts& rhs); + + /// Number of times before trusted + inline int numberBeforeTrusted() const + { return numberBeforeTrusted_; } + /// Set number of times before trusted + inline void setNumberBeforeTrusted(int value) + { numberBeforeTrusted_ = value; } + /// Initialize the pseudocosts with n entries + void initialize(int n); + /// Give the number of objects for which pseudo costs are stored + inline int numberObjects() const + { return numberObjects_; } + + /** @name Accessor methods to pseudo costs data */ + //@{ + inline double* upTotalChange() { return upTotalChange_; } + inline const double* upTotalChange() const { return upTotalChange_; } + + inline double* downTotalChange() { return downTotalChange_; } + inline const double* downTotalChange() const { return downTotalChange_; } + + inline int* upNumber() { return upNumber_; } + inline const int* upNumber() const { return upNumber_; } + + inline int* downNumber() { return downNumber_; } + inline const int* downNumber() const { return downNumber_; } + //@} + + /// Given a candidate fill in useful information e.g. estimates + virtual void updateInformation(const OsiBranchingInformation *info, + int branch, OsiHotInfo * hotInfo); +#if 1 + /// Given a branch fill in useful information e.g. estimates + virtual void updateInformation( int whichObject, int branch, + double changeInObjective, double changeInValue, + int status); +#endif +}; + +/** This class chooses a variable to branch on + + This chooses the variable and direction with reliability strong branching. + + The flow is : + a) initialize the process. This decides on strong branching list + and stores indices of all infeasible objects + b) do strong branching on list. If list is empty then just + choose one candidate and return without strong branching. If not empty then + go through list and return best. However we may find that the node is infeasible + or that we can fix a variable. If so we return and it is up to user to call + again (after fixing a variable). +*/ + +class OsiChooseStrong : public OsiChooseVariable { + +public: + + /// Default Constructor + OsiChooseStrong (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseStrong (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseStrong (const OsiChooseStrong &); + + /// Assignment operator + OsiChooseStrong & operator= (const OsiChooseStrong& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseStrong (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + + /** Pseudo Shadow Price mode + 0 - off + 1 - use if no strong info + 2 - use if strong not trusted + 3 - use even if trusted + */ + inline int shadowPriceMode() const + { return shadowPriceMode_;} + /// Set Shadow price mode + inline void setShadowPriceMode(int value) + { shadowPriceMode_ = value;} + + /** Accessor method to pseudo cost object*/ + const OsiPseudoCosts& pseudoCosts() const + { return pseudoCosts_; } + + /** Accessor method to pseudo cost object*/ + OsiPseudoCosts& pseudoCosts() + { return pseudoCosts_; } + + /** A feww pass-through methods to access members of pseudoCosts_ as if they + were members of OsiChooseStrong object */ + inline int numberBeforeTrusted() const { + return pseudoCosts_.numberBeforeTrusted(); } + inline void setNumberBeforeTrusted(int value) { + pseudoCosts_.setNumberBeforeTrusted(value); } + inline int numberObjects() const { + return pseudoCosts_.numberObjects(); } + +protected: + + /** This is a utility function which does strong branching on + a list of objects and stores the results in OsiHotInfo.objects. + On entry the object sequence is stored in the OsiHotInfo object + and maybe more. + It returns - + -1 - one branch was infeasible both ways + 0 - all inspected - nothing can be fixed + 1 - all inspected - some can be fixed (returnCriterion==0) + 2 - may be returning early - one can be fixed (last one done) (returnCriterion==1) + 3 - returning because max time + + */ + int doStrongBranching( OsiSolverInterface * solver, + OsiBranchingInformation *info, + int numberToDo, int returnCriterion); + + /** Clear out the results array */ + void resetResults(int num); + +protected: + /** Pseudo Shadow Price mode + 0 - off + 1 - use and multiply by strong info + 2 - use + */ + int shadowPriceMode_; + + /** The pseudo costs for the chooser */ + OsiPseudoCosts pseudoCosts_; + + /** The results of the strong branching done on the candidates where the + pseudocosts were not sufficient */ + OsiHotInfo* results_; + /** The number of OsiHotInfo objetcs that contain information */ + int numResults_; +}; + +/** This class contains the result of strong branching on a variable + When created it stores enough information for strong branching +*/ + +class OsiHotInfo { + +public: + + /// Default Constructor + OsiHotInfo (); + + /// Constructor from useful information + OsiHotInfo ( OsiSolverInterface * solver, + const OsiBranchingInformation *info, + const OsiObject * const * objects, + int whichObject); + + /// Copy constructor + OsiHotInfo (const OsiHotInfo &); + + /// Assignment operator + OsiHotInfo & operator= (const OsiHotInfo& rhs); + + /// Clone + virtual OsiHotInfo * clone() const; + + /// Destructor + virtual ~OsiHotInfo (); + + /** Fill in useful information after strong branch. + Return status + */ + int updateInformation( const OsiSolverInterface * solver, const OsiBranchingInformation * info, + OsiChooseVariable * choose); + /// Original objective value + inline double originalObjectiveValue() const + { return originalObjectiveValue_;} + /// Up change - invalid if n-way + inline double upChange() const + { assert (branchingObject_->numberBranches()==2); return changes_[1];} + /// Down change - invalid if n-way + inline double downChange() const + { assert (branchingObject_->numberBranches()==2); return changes_[0];} + /// Set up change - invalid if n-way + inline void setUpChange(double value) + { assert (branchingObject_->numberBranches()==2); changes_[1] = value;} + /// Set down change - invalid if n-way + inline void setDownChange(double value) + { assert (branchingObject_->numberBranches()==2); changes_[0] = value;} + /// Change on way k + inline double change(int k) const + { return changes_[k];} + + /// Up iteration count - invalid if n-way + inline int upIterationCount() const + { assert (branchingObject_->numberBranches()==2); return iterationCounts_[1];} + /// Down iteration count - invalid if n-way + inline int downIterationCount() const + { assert (branchingObject_->numberBranches()==2); return iterationCounts_[0];} + /// Iteration count on way k + inline int iterationCount(int k) const + { return iterationCounts_[k];} + + /// Up status - invalid if n-way + inline int upStatus() const + { assert (branchingObject_->numberBranches()==2); return statuses_[1];} + /// Down status - invalid if n-way + inline int downStatus() const + { assert (branchingObject_->numberBranches()==2); return statuses_[0];} + /// Set up status - invalid if n-way + inline void setUpStatus(int value) + { assert (branchingObject_->numberBranches()==2); statuses_[1] = value;} + /// Set down status - invalid if n-way + inline void setDownStatus(int value) + { assert (branchingObject_->numberBranches()==2); statuses_[0] = value;} + /// Status on way k + inline int status(int k) const + { return statuses_[k];} + /// Branching object + inline OsiBranchingObject * branchingObject() const + { return branchingObject_;} + inline int whichObject() const + { return whichObject_;} + +protected: + // Data + /// Original objective value + double originalObjectiveValue_; + /// Objective changes + double * changes_; + /// Iteration counts + int * iterationCounts_; + /** Status + -1 - not done + 0 - feasible and finished + 1 - infeasible + 2 - not finished + */ + int * statuses_; + /// Branching object + OsiBranchingObject * branchingObject_; + /// Which object on list + int whichObject_; +}; + + +#endif diff --git a/thirdparty/linux/include/coin/OsiClpSolverInterface.hpp b/thirdparty/linux/include/coin/OsiClpSolverInterface.hpp new file mode 100644 index 0000000..ebc7e64 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiClpSolverInterface.hpp @@ -0,0 +1,1509 @@ +// $Id$ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +#ifndef OsiClpSolverInterface_H +#define OsiClpSolverInterface_H + +#include +#include +#include + +#include "ClpSimplex.hpp" +#include "ClpLinearObjective.hpp" +#include "CoinPackedMatrix.hpp" +#include "OsiSolverInterface.hpp" +#include "CoinWarmStartBasis.hpp" +#include "ClpEventHandler.hpp" +#include "ClpNode.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinFinite.hpp" + +class OsiRowCut; +class OsiClpUserSolver; +class OsiClpDisasterHandler; +class CoinSet; +static const double OsiClpInfinity = COIN_DBL_MAX; + +//############################################################################# + +/** Clp Solver Interface + +Instantiation of OsiClpSolverInterface for the Model Algorithm. + +*/ + +class OsiClpSolverInterface : + virtual public OsiSolverInterface { + friend void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an LP relaxation after problem modification + virtual void resolve(); + + /// Resolve an LP relaxation after problem modification (try GUB) + virtual void resolveGub(int needed); + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound(); + + /** Solve when primal column and dual row solutions are near-optimal + options - 0 no presolve (use primal and dual) + 1 presolve (just use primal) + 2 no presolve (just use primal) + basis - 0 use all slack basis + 1 try and put some in basis + */ + void crossover(int options,int basis); + //@} + + /*! @name OsiSimplexInterface methods + \brief Methods for the Osi Simplex API. + + The current implementation should work for both minimisation and + maximisation in mode 1 (tableau access). In mode 2 (single pivot), only + minimisation is supported as of 100907. + */ + //@{ + /** \brief Simplex API capability. + + Returns + - 0 if no simplex API + - 1 if can just do getBInv etc + - 2 if has all OsiSimplex methods + */ + virtual int canDoSimplexInterface() const; + + /*! \brief Enables simplex mode 1 (tableau access) + + Tells solver that calls to getBInv etc are about to take place. + Underlying code may need mutable as this may be called from + CglCut::generateCuts which is const. If that is too horrific then + each solver e.g. BCP or CBC will have to do something outside + main loop. + */ + virtual void enableFactorization() const; + + /*! \brief Undo any setting changes made by #enableFactorization */ + virtual void disableFactorization() const; + + /** Returns true if a basis is available + AND problem is optimal. This should be used to see if + the BInvARow type operations are possible and meaningful. + */ + virtual bool basisIsAvailable() const; + + /** The following two methods may be replaced by the + methods of OsiSolverInterface using OsiWarmStartBasis if: + 1. OsiWarmStartBasis resize operation is implemented + more efficiently and + 2. It is ensured that effects on the solver are the same + + Returns a basis status of the structural/artificial variables + At present as warm start i.e 0 free, 1 basic, 2 upper, 3 lower + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + virtual void getBasisStatus(int* cstat, int* rstat) const; + + /** Set the status of structural/artificial variables and + factorize, update solution etc + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + Returns 0 if OK, 1 if problem is bad e.g. duplicate elements, too large ... + */ + virtual int setBasisStatus(const int* cstat, const int* rstat); + + ///Get the reduced gradient for the cost vector c + virtual void getReducedGradient(double* columnReducedCosts, + double * duals, + const double * c) const ; + + ///Get a row of the tableau (slack part in slack if not NULL) + virtual void getBInvARow(int row, double* z, double * slack=NULL) const; + + /** Get a row of the tableau (slack part in slack if not NULL) + If keepScaled is true then scale factors not applied after so + user has to use coding similar to what is in this method + */ + virtual void getBInvARow(int row, CoinIndexedVector * z, CoinIndexedVector * slack=NULL, + bool keepScaled=false) const; + + ///Get a row of the basis inverse + virtual void getBInvRow(int row, double* z) const; + + ///Get a column of the tableau + virtual void getBInvACol(int col, double* vec) const ; + + ///Get a column of the tableau + virtual void getBInvACol(int col, CoinIndexedVector * vec) const ; + + /** Update (i.e. ftran) the vector passed in. + Unscaling is applied after - can't be applied before + */ + + virtual void getBInvACol(CoinIndexedVector * vec) const ; + + ///Get a column of the basis inverse + virtual void getBInvCol(int col, double* vec) const ; + + /** Get basic indices (order of indices corresponds to the + order of elements in a vector retured by getBInvACol() and + getBInvCol()). + */ + virtual void getBasics(int* index) const; + + /*! \brief Enables simplex mode 2 (individual pivot control) + + This method is supposed to ensure that all typical things (like + reduced costs, etc.) are updated when individual pivots are executed + and can be queried by other methods. + */ + virtual void enableSimplexInterface(bool doingPrimal); + /// Copy across enabled stuff from one solver to another + void copyEnabledSuff(OsiClpSolverInterface & rhs); + + /*! \brief Undo setting changes made by #enableSimplexInterface */ + virtual void disableSimplexInterface(); + /// Copy across enabled stuff from one solver to another + void copyEnabledStuff(ClpSimplex & rhs); + + /** Perform a pivot by substituting a colIn for colOut in the basis. + The status of the leaving variable is given in statOut. Where + 1 is to upper bound, -1 to lower bound + Return code is 0 for okay, + 1 if inaccuracy forced re-factorization (should be okay) and + -1 for singular factorization + */ + virtual int pivot(int colIn, int colOut, int outStatus); + + /** Obtain a result of the primal pivot + Outputs: colOut -- leaving column, outStatus -- its status, + t -- step size, and, if dx!=NULL, *dx -- primal ray direction. + Inputs: colIn -- entering column, sign -- direction of its change (+/-1). + Both for colIn and colOut, artificial variables are index by + the negative of the row index minus 1. + Return code (for now): 0 -- leaving variable found, + -1 -- everything else? + Clearly, more informative set of return values is required + Primal and dual solutions are updated + */ + virtual int primalPivotResult(int colIn, int sign, + int& colOut, int& outStatus, + double& t, CoinPackedVector* dx); + + /** Obtain a result of the dual pivot (similar to the previous method) + Differences: entering variable and a sign of its change are now + the outputs, the leaving variable and its statuts -- the inputs + If dx!=NULL, then *dx contains dual ray + Return code: same + */ + virtual int dualPivotResult(int& colIn, int& sign, + int colOut, int outStatus, + double& t, CoinPackedVector* dx); + + + //@} + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the clp algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + */ + //@{ + // Set an integer parameter + bool setIntParam(OsiIntParam key, int value); + // Set an double parameter + bool setDblParam(OsiDblParam key, double value); + // Set a string parameter + bool setStrParam(OsiStrParam key, const std::string & value); + // Get an integer parameter + bool getIntParam(OsiIntParam key, int& value) const; + // Get an double parameter + bool getDblParam(OsiDblParam key, double& value) const; + // Get a string parameter + bool getStrParam(OsiStrParam key, std::string& value) const; + // Set a hint parameter - overrides OsiSolverInterface + virtual bool setHintParam(OsiHintParam key, bool yesNo=true, + OsiHintStrength strength=OsiHintTry, + void * otherInformation=NULL); + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + virtual bool isAbandoned() const; + /// Is optimality proven? + virtual bool isProvenOptimal() const; + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + //@} + + //--------------------------------------------------------------------------- + /**@name WarmStart related methods */ + //@{ + + /*! \brief Get an empty warm start object + + This routine returns an empty CoinWarmStartBasis object. Its purpose is + to provide a way to give a client a warm start basis object of the + appropriate type, which can resized and modified as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const; + + /// Get warmstarting information + virtual CoinWarmStart* getWarmStart() const; + /// Get warmstarting information + inline CoinWarmStartBasis* getPointerToWarmStart() + { return &basis_;} + /// Get warmstarting information + inline const CoinWarmStartBasis* getConstPointerToWarmStart() const + { return &basis_;} + /** Set warmstarting information. Return true/false depending on whether + the warmstart information was accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. This does not necessarily create an + object - may just point to one. must Delete set true if user + should delete returned object. + OsiClp version always returns pointer and false. + */ + virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ; + + /// Set column status in ClpSimplex and warmStart + void setColumnStatus(int iColumn, ClpSimplex::Status status); + + //@} + + //--------------------------------------------------------------------------- + /**@name Hotstart related methods (primarily used in strong branching). + The user can create a hotstart (a snapshot) of the optimization process + then reoptimize over and over again always starting from there.
+ NOTE: between hotstarted optimizations only + bound changes are allowed. */ + //@{ + /// Create a hotstart point of the optimization process + virtual void markHotStart(); + /// Optimize starting from the hotstart + virtual void solveFromHotStart(); + /// Delete the snapshot + virtual void unmarkHotStart(); + /** Start faster dual - returns negative if problems 1 if infeasible, + Options to pass to solver + 1 - create external reduced costs for columns + 2 - create external reduced costs for rows + 4 - create external row activity (columns always done) + Above only done if feasible + When set resolve does less work + */ + int startFastDual(int options); + /// Stop fast dual + void stopFastDual(); + /// Sets integer tolerance and increment + void setStuff(double tolerance,double increment); + /// Return a conflict analysis cut from small model + OsiRowCut * smallModelCut(const double * originalLower, const double * originalUpper, + int numberRowsAtContinuous,const int * whichGenerator, + int typeCut=0); + /** Return a conflict analysis cut from model + If type is 0 then genuine cut, if 1 then only partially processed + */ + OsiRowCut * modelCut(const double * originalLower, const double * originalUpper, + int numberRowsAtContinuous,const int * whichGenerator, + int typeCut=0); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /**@name Methods related to querying the input data */ + //@{ + /// Get number of columns + virtual int getNumCols() const { + return modelPtr_->numberColumns(); } + + /// Get number of rows + virtual int getNumRows() const { + return modelPtr_->numberRows(); } + + /// Get number of nonzero elements + virtual int getNumElements() const { + int retVal = 0; + const CoinPackedMatrix * matrix =modelPtr_->matrix(); + if ( matrix != NULL ) retVal=matrix->getNumElements(); + return retVal; } + + /// Return name of row if one exists or Rnnnnnnn + /// maxLen is currently ignored and only there to match the signature from the base class! + virtual std::string getRowName(int rowIndex, + unsigned maxLen = static_cast(std::string::npos)) const; + + /// Return name of column if one exists or Cnnnnnnn + /// maxLen is currently ignored and only there to match the signature from the base class! + virtual std::string getColName(int colIndex, + unsigned maxLen = static_cast(std::string::npos)) const; + + + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const { return modelPtr_->columnLower(); } + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const { return modelPtr_->columnUpper(); } + + /** Get pointer to array[getNumRows()] of row constraint senses. +
    +
  • 'L' <= constraint +
  • 'E' = constraint +
  • 'G' >= constraint +
  • 'R' ranged constraint +
  • 'N' free constraint +
+ */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of rows right-hand sides +
    +
  • if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] +
  • if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] +
  • if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] +
  • if rowsense()[i] == 'N' then rhs()[i] == 0.0 +
+ */ + virtual const double * getRightHandSide() const ; + + /** Get pointer to array[getNumRows()] of row ranges. +
    +
  • if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] +
  • if rowsense()[i] != 'R' then + rowrange()[i] is undefined +
+ */ + virtual const double * getRowRange() const ; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const { return modelPtr_->rowLower(); } + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const { return modelPtr_->rowUpper(); } + + /// Get pointer to array[getNumCols()] of objective function coefficients + virtual const double * getObjCoefficients() const + { if (fakeMinInSimplex_) + return linearObjective_ ; + else + return modelPtr_->objective(); } + + /// Get objective function sense (1 for min (default), -1 for max) + virtual double getObjSense() const + { return ((fakeMinInSimplex_)?-modelPtr_->optimizationDirection(): + modelPtr_->optimizationDirection()); } + + /// Return true if column is continuous + virtual bool isContinuous(int colNumber) const; + /// Return true if variable is binary + virtual bool isBinary(int colIndex) const; + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + virtual bool isInteger(int colIndex) const; + + /// Return true if variable is general integer + virtual bool isIntegerNonBinary(int colIndex) const; + + /// Return true if variable is binary and not fixed at either bound + virtual bool isFreeBinary(int colIndex) const; + /** Return array of column length + 0 - continuous + 1 - binary (may get fixed later) + 2 - general integer (may get fixed later) + */ + virtual const char * getColType(bool refresh=false) const; + + /** Return true if column is integer but does not have to + be declared as such. + Note: This function returns true if the the column + is binary or a general integer. + */ + bool isOptionalInteger(int colIndex) const; + /** Set the index-th variable to be an optional integer variable */ + void setOptionalInteger(int index); + + /// Get pointer to row-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByCol() const; + + /// Get pointer to mutable column-wise copy of matrix + virtual CoinPackedMatrix * getMutableMatrixByCol() const; + + /// Get solver's value for infinity + virtual double getInfinity() const { return OsiClpInfinity; } + //@} + + /**@name Methods related to querying the solution */ + //@{ + /// Get pointer to array[getNumCols()] of primal solution vector + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual prices + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector */ + virtual const double * getRowActivity() const; + + /// Get objective function value + virtual double getObjValue() const; + + /** Get how many iterations it took to solve the problem (whatever + "iteration" mean to the solver. */ + virtual int getIterationCount() const + { return modelPtr_->numberIterations(); } + + /** Get as many dual rays as the solver can provide. (In case of proven + primal infeasibility there should be at least one.) + + The first getNumRows() ray components will always be associated with + the row duals (as returned by getRowPrice()). If \c fullRay is true, + the final getNumCols() entries will correspond to the ray components + associated with the nonbasic variables. If the full ray is requested + and the method cannot provide it, it will throw an exception. + + NOTE for implementers of solver interfaces:
+ The double pointers in the vector should point to arrays of length + getNumRows() and they should be allocated via new[].
+ + NOTE for users of solver interfaces:
+ It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector getDualRays(int maxNumRays, + bool fullRay = false) const; + /** Get as many primal rays as the solver can provide. (In case of proven + dual infeasibility there should be at least one.) + + NOTE for implementers of solver interfaces:
+ The double pointers in the vector should point to arrays of length + getNumCols() and they should be allocated via new[].
+ + NOTE for users of solver interfaces:
+ It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector getPrimalRays(int maxNumRays) const; + + //@} + //@} + + //--------------------------------------------------------------------------- + + /**@name Problem modifying methods */ + //@{ + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ); + + /** Set a single column lower bound
+ Use -DBL_MAX for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound
+ Use DBL_MAX for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + virtual void setColBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously
+ The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + either bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + virtual void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single row lower bound
+ Use -DBL_MAX for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound
+ Use DBL_MAX for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + virtual void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the type of a single row
*/ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + /** Set the bounds on a number of rows simultaneously
+ The default implementation just invokes setRowLower() and + setRowUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + either bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + virtual void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set the type of a number of rows simultaneously
+ The default implementation just invokes setRowType() + over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + any characteristics changes + @param senseList the new senses + @param rhsList the new right hand sides + @param rangeList the new ranges + */ + virtual void setRowSetTypes(const int* indexFirst, + const int* indexLast, + const char* senseList, + const double* rhsList, + const double* rangeList); + /** Set the objective coefficients for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setObjective(const double * array); + + /** Set the lower bounds for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColLower(const double * array); + + /** Set the upper bounds for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColUpper(const double * array); + +// using OsiSolverInterface::setRowName ; + /// Set name of row +// virtual void setRowName(int rowIndex, std::string & name) ; + virtual void setRowName(int rowIndex, std::string name) ; + +// using OsiSolverInterface::setColName ; + /// Set name of column +// virtual void setColName(int colIndex, std::string & name) ; + virtual void setColName(int colIndex, std::string name) ; + + //@} + + //------------------------------------------------------------------------- + /**@name Integrality related changing methods */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + /** Set the variables listed in indices (which is of length len) to be + continuous variables */ + virtual void setContinuous(const int* indices, int len); + /** Set the variables listed in indices (which is of length len) to be + integer variables */ + virtual void setInteger(const int* indices, int len); + /// Number of SOS sets + inline int numberSOS() const + { return numberSOS_;} + /// SOS set info + inline const CoinSet * setInfo() const + { return setInfo_;} + /** \brief Identify integer variables and SOS and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If the solver supports SOS then do the same for SOS. + If justCount then no objects created and we just store numberIntegers_ + Returns number of SOS + */ + + virtual int findIntegersAndSOS(bool justCount); + //@} + + //------------------------------------------------------------------------- + /// Set objective function sense (1 for min (default), -1 for max,) + virtual void setObjSense(double s ) + { modelPtr_->setOptimizationDirection( s < 0 ? -1 : 1); } + + /** Set the primal solution column values + + colsol[numcols()] is an array of values of the problem column + variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of colsol() until changed by another call to + setColsol() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setColSolution(const double * colsol); + + /** Set dual solution vector + + rowprice[numrows()] is an array of values of the problem row + dual variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of rowprice() until changed by another call to + setRowprice() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setRowPrice(const double * rowprice); + + //------------------------------------------------------------------------- + /**@name Methods to expand a problem.
+ Note that if a column is added then by default it will correspond to a + continuous variable. */ + //@{ + + //using OsiSolverInterface::addCol ; + /** */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj); + /*! \brief Add a named column (primal variable) to the problem. + */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj, std::string name) ; + /** Add a column (primal variable) to the problem. */ + virtual void addCol(int numberElements, const int * rows, const double * elements, + const double collb, const double colub, + const double obj) ; + /*! \brief Add a named column (primal variable) to the problem. + */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj, std::string name) ; + /** */ + virtual void addCols(const int numcols, + const CoinPackedVectorBase * const * cols, + const double* collb, const double* colub, + const double* obj); + /** */ + virtual void addCols(const int numcols, + const int * columnStarts, const int * rows, const double * elements, + const double* collb, const double* colub, + const double* obj); + /** */ + virtual void deleteCols(const int num, const int * colIndices); + + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub); + /** */ + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub, + std::string name) ; + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng); + /** Add a row (constraint) to the problem. */ + virtual void addRow(int numberElements, const int * columns, const double * element, + const double rowlb, const double rowub) ; + /*! \brief Add a named row (constraint) to the problem. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng, std::string name) ; + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const double* rowlb, const double* rowub); + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** */ + virtual void addRows(const int numrows, + const int * rowStarts, const int * columns, const double * element, + const double* rowlb, const double* rowub); + /// + void modifyCoefficient(int row, int column, double newElement, + bool keepZero=false) + {modelPtr_->modifyCoefficient(row,column,newElement, keepZero);} + + /** */ + virtual void deleteRows(const int num, const int * rowIndices); + /** If solver wants it can save a copy of "base" (continuous) model here + */ + virtual void saveBaseModel() ; + /** Strip off rows to get to this number of rows. + If solver wants it can restore a copy of "base" (continuous) model here + */ + virtual void restoreBaseModel(int numberRows); + + //----------------------------------------------------------------------- + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + This uses array of pointers + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); + /** Apply a collection of cuts. + + Only cuts which have an effectiveness >= effectivenessLb + are applied. +
    +
  • ReturnCode.getNumineffective() -- number of cuts which were + not applied because they had an + effectiveness < effectivenessLb +
  • ReturnCode.getNuminconsistent() -- number of invalid cuts +
  • ReturnCode.getNuminconsistentWrtIntegerModel() -- number of + cuts that are invalid with respect to this integer model +
  • ReturnCode.getNuminfeasible() -- number of cuts that would + make this integer model infeasible +
  • ReturnCode.getNumApplied() -- number of integer cuts which + were applied to the integer model +
  • cs.size() == getNumineffective() + + getNuminconsistent() + + getNuminconsistentWrtIntegerModel() + + getNuminfeasible() + + getNumApplied() +
+ */ + virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, + double effectivenessLb = 0.0); + + //@} + //@} + + //--------------------------------------------------------------------------- + +public: + + /**@name Methods to input a problem */ + //@{ + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • rowub: all rows have upper bound infinity +
  • rowlb: all rows have lower bound -infinity +
  • obj: all variables have 0 objective coefficient +
+ */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by lower and upper bounds). For + default values see the previous method.
+ WARNING: The arguments passed to this method will be + freed using the C++ delete and delete[] + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by sense/rhs/range triplets). If a pointer is NULL then the + following values are the default: +
    +
  • colub: all columns have upper bound infinity +
  • collb: all columns have lower bound 0 +
  • obj: all variables have 0 objective coefficient +
  • rowsen: all rows are >= +
  • rowrhs: all right hand sides are 0 +
  • rowrng: 0 for the ranged rows +
+ */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by sense/rhs/range triplets). For + default values see the previous method.
+ WARNING: The arguments passed to this method will be + freed using the C++ delete and delete[] + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng); + + /** Just like the other loadProblem() methods except that the matrix is + given as a ClpMatrixBase. */ + virtual void loadProblem(const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + /// This loads a model from a coinModel object - returns number of errors + virtual int loadFromCoinModel ( CoinModel & modelObject, bool keepSolution=false); + + using OsiSolverInterface::readMps ; + /** Read an mps file from the given filename (defaults to Osi reader) - returns + number of errors (see OsiMpsReader class) */ + virtual int readMps(const char *filename, + const char *extension = "mps") ; + /** Read an mps file from the given filename returns + number of errors (see OsiMpsReader class) */ + int readMps(const char *filename,bool keepNames,bool allowErrors); + /// Read an mps file + virtual int readMps (const char *filename, const char*extension, + int & numberSets, CoinSet ** & sets); + + /** Write the problem into an mps file of the given filename. + If objSense is non zero then -1.0 forces the code to write a + maximization objective and +1.0 to write a minimization one. + If 0.0 then solver can do what it wants */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const; + /** Write the problem into an mps file of the given filename, + names may be null. formatType is + 0 - normal + 1 - extra accuracy + 2 - IEEE hex (later) + + Returns non-zero on I/O error + */ + virtual int writeMpsNative(const char *filename, + const char ** rowNames, const char ** columnNames, + int formatType=0,int numberAcross=2, + double objSense=0.0) const ; + /// Read file in LP format (with names) + virtual int readLp(const char *filename, const double epsilon = 1e-5); + /** Write the problem into an Lp file of the given filename. + If objSense is non zero then -1.0 forces the code to write a + maximization objective and +1.0 to write a minimization one. + If 0.0 then solver can do what it wants. + This version calls writeLpNative with names */ + virtual void writeLp(const char *filename, + const char *extension = "lp", + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLp() with first parameter filename. + */ + virtual void writeLp(FILE *fp, + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + /** + I (JJF) am getting annoyed because I can't just replace a matrix. + The default behavior of this is do nothing so only use where that would not matter + e.g. strengthening a matrix for MIP + */ + virtual void replaceMatrixOptional(const CoinPackedMatrix & matrix); + /// And if it does matter (not used at present) + virtual void replaceMatrix(const CoinPackedMatrix & matrix) ; + //@} + + /**@name Message handling (extra for Clp messages). + Normally I presume you would want the same language. + If not then you could use underlying model pointer */ + //@{ + /** Pass in a message handler + + It is the client's responsibility to destroy a message handler installed + by this routine; it will not be destroyed when the solver interface is + destroyed. + */ + virtual void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + /// Set log level (will also set underlying solver's log level) + void setLogLevel(int value); + /// Create C++ lines to get to current state + void generateCpp( FILE * fp); + //@} + //--------------------------------------------------------------------------- + + /**@name Clp specific public interfaces */ + //@{ + /// Get pointer to Clp model + ClpSimplex * getModelPtr() const ; + /// Set pointer to Clp model and return old + inline ClpSimplex * swapModelPtr(ClpSimplex * newModel) + { ClpSimplex * model = modelPtr_; modelPtr_=newModel;return model;} + /// Get special options + inline unsigned int specialOptions() const + { return specialOptions_;} + void setSpecialOptions(unsigned int value); + /// Last algorithm used , 1 = primal, 2 = dual other unknown + inline int lastAlgorithm() const + { return lastAlgorithm_;} + /// Set last algorithm used , 1 = primal, 2 = dual other unknown + inline void setLastAlgorithm(int value) + { lastAlgorithm_ = value;} + /// Get scaling action option + inline int cleanupScaling() const + { return cleanupScaling_;} + /** Set Scaling option + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + */ + inline void setCleanupScaling(int value) + { cleanupScaling_=value;} + /** Get smallest allowed element in cut. + If smaller than this then ignored */ + inline double smallestElementInCut() const + { return smallestElementInCut_;} + /** Set smallest allowed element in cut. + If smaller than this then ignored */ + inline void setSmallestElementInCut(double value) + { smallestElementInCut_=value;} + /** Get smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. + (upper-lower) is taken to be at least 1.0 and + this is assumed >= smallestElementInCut_ + */ + inline double smallestChangeInCut() const + { return smallestChangeInCut_;} + /** Set smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. + (upper-lower) is taken to be at least 1.0 and + this is assumed >= smallestElementInCut_ + */ + inline void setSmallestChangeInCut(double value) + { smallestChangeInCut_=value;} + /// Pass in initial solve options + inline void setSolveOptions(const ClpSolve & options) + { solveOptions_ = options;} + /** Tighten bounds - lightweight or very lightweight + 0 - normal, 1 lightweight but just integers, 2 lightweight and all + */ + virtual int tightenBounds(int lightweight=0); + /// See if any integer variables make infeasible other way + int infeasibleOtherWay(char * whichWay); + /// Return number of entries in L part of current factorization + virtual CoinBigIndex getSizeL() const; + /// Return number of entries in U part of current factorization + virtual CoinBigIndex getSizeU() const; + /// Get disaster handler + const OsiClpDisasterHandler * disasterHandler() const + { return disasterHandler_;} + /// Pass in disaster handler + void passInDisasterHandler(OsiClpDisasterHandler * handler); + /// Get fake objective + ClpLinearObjective * fakeObjective() const + { return fakeObjective_;} + /// Set fake objective (and take ownership) + void setFakeObjective(ClpLinearObjective * fakeObjective); + /// Set fake objective + void setFakeObjective(double * fakeObjective); + /*! \brief Set up solver for repeated use by Osi interface. + + The normal usage does things like keeping factorization around so can be + used. Will also do things like keep scaling and row copy of matrix if + matrix does not change. + + \p senseOfAdventure: + - 0 - safe stuff as above + - 1 - will take more risks - if it does not work then bug which will be + fixed + - 2 - don't bother doing most extreme termination checks e.g. don't bother + re-factorizing if less than 20 iterations. + - 3 - Actually safer than 1 (mainly just keeps factorization) + + \p printOut + - -1 always skip round common messages instead of doing some work + - 0 skip if normal defaults + - 1 leaves + */ + void setupForRepeatedUse(int senseOfAdventure=0, int printOut=0); + /// Synchronize model (really if no cuts in tree) + virtual void synchronizeModel(); + /*! \brief Set special options in underlying clp solver. + + Safe as const because #modelPtr_ is mutable. + */ + void setSpecialOptionsMutable(unsigned int value) const; + + //@} + + //--------------------------------------------------------------------------- + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiClpSolverInterface (); + + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiClpSolverInterface (const OsiClpSolverInterface &); + + /// Borrow constructor - only delete one copy + OsiClpSolverInterface (ClpSimplex * rhs, bool reallyOwn=false); + + /// Releases so won't error + void releaseClp(); + + /// Assignment operator + OsiClpSolverInterface & operator=(const OsiClpSolverInterface& rhs); + + /// Destructor + virtual ~OsiClpSolverInterface (); + + /// Resets as if default constructor + virtual void reset(); + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to constraint matrix). */ + virtual void applyRowCut(const OsiRowCut& rc); + + /** Apply a column cut (adjust one or more bounds). */ + virtual void applyColCut(const OsiColCut& cc); + //@} + + //--------------------------------------------------------------------------- + +protected: + /**@name Protected methods */ + //@{ + /// The real work of a copy constructor (used by copy and assignment) + void gutsOfDestructor(); + + /// Deletes all mutable stuff + void freeCachedResults() const; + + /// Deletes all mutable stuff for row ranges etc + void freeCachedResults0() const; + + /// Deletes all mutable stuff for matrix etc + void freeCachedResults1() const; + + /// A method that fills up the rowsense_, rhs_ and rowrange_ arrays + void extractSenseRhsRange() const; + + /// + void fillParamMaps(); + /** Warm start + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + CoinWarmStartBasis getBasis(ClpSimplex * model) const; + /** Sets up working basis as a copy of input + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + void setBasis( const CoinWarmStartBasis & basis, ClpSimplex * model); + /// Crunch down problem a bit + void crunch(); + /// Extend scale factors + void redoScaleFactors(int numberRows,const CoinBigIndex * starts, + const int * indices, const double * elements); +public: + /** Sets up working basis as a copy of input and puts in as basis + */ + void setBasis( const CoinWarmStartBasis & basis); + /// Just puts current basis_ into ClpSimplex model + inline void setBasis( ) + { setBasis(basis_,modelPtr_);} + /// Warm start difference from basis_ to statusArray + CoinWarmStartDiff * getBasisDiff(const unsigned char * statusArray) const ; + /// Warm start from statusArray + CoinWarmStartBasis * getBasis(const unsigned char * statusArray) const ; + /// Delete all scale factor stuff and reset option + void deleteScaleFactors(); + /// If doing fast hot start then ranges are computed + inline const double * upRange() const + { return rowActivity_;} + inline const double * downRange() const + { return columnActivity_;} + /// Pass in range array + inline void passInRanges(int * array) + { whichRange_=array;} + /// Pass in sos stuff from AMPl + void setSOSData(int numberSOS,const char * type, + const int * start,const int * indices, const double * weights=NULL); + /// Compute largest amount any at continuous away from bound + void computeLargestAway(); + /// Get largest amount continuous away from bound + inline double largestAway() const + { return largestAway_;} + /// Set largest amount continuous away from bound + inline void setLargestAway(double value) + { largestAway_ = value;} + /// Sort of lexicographic resolve + void lexSolve(); + //@} + +protected: + /**@name Protected member data */ + //@{ + /// Clp model represented by this class instance + mutable ClpSimplex * modelPtr_; + //@} + /**@name Cached information derived from the OSL model */ + //@{ + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /** Pointer to dense vector of slack upper bounds for range + constraints (undefined for non-range rows) + */ + mutable double *rowrange_; + + /** A pointer to the warmstart information to be used in the hotstarts. + This is NOT efficient and more thought should be given to it... */ + mutable CoinWarmStartBasis* ws_; + /** also save row and column information for hot starts + only used in hotstarts so can be casual */ + mutable double * rowActivity_; + mutable double * columnActivity_; + /// Stuff for fast dual + ClpNodeStuff stuff_; + /// Number of SOS sets + int numberSOS_; + /// SOS set info + CoinSet * setInfo_; + /// Alternate model (hot starts) - but also could be permanent and used for crunch + ClpSimplex * smallModel_; + /// factorization for hot starts + ClpFactorization * factorization_; + /** Smallest allowed element in cut. + If smaller than this then ignored */ + double smallestElementInCut_; + /** Smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. */ + double smallestChangeInCut_; + /// Largest amount continuous away from bound + double largestAway_; + /// Arrays for hot starts + char * spareArrays_; + /** Warmstart information to be used in resolves. */ + CoinWarmStartBasis basis_; + /** The original iteration limit before hotstarts started. */ + int itlimOrig_; + + /*! \brief Last algorithm used + + Coded as + - 0 invalid + - 1 primal + - 2 dual + - -911 disaster in the algorithm that was attempted + - 999 current solution no longer optimal due to change in problem or + basis + */ + mutable int lastAlgorithm_; + + /// To say if destructor should delete underlying model + bool notOwned_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByRow_; + + /// Pointer to row-wise copy of continuous problem matrix coefficients. + CoinPackedMatrix *matrixByRowAtContinuous_; + + /// Pointer to integer information + char * integerInformation_; + + /** Pointer to variables for which we want range information + The number is in [0] + memory is not owned by OsiClp + */ + int * whichRange_; + + //std::map intParamMap_; + //std::map dblParamMap_; + //std::map strParamMap_; + + /*! \brief Faking min to get proper dual solution signs in simplex API */ + mutable bool fakeMinInSimplex_ ; + /*! \brief Linear objective + + Normally a pointer to the linear coefficient array in the clp objective. + An independent copy when #fakeMinInSimplex_ is true, because we need + something permanent to point to when #getObjCoefficients is called. + */ + mutable double *linearObjective_; + + /// To save data in OsiSimplex stuff + mutable ClpDataSave saveData_; + /// Options for initialSolve + ClpSolve solveOptions_; + /** Scaling option + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + */ + int cleanupScaling_; + /** Special options + 0x80000000 off + 0 simple stuff for branch and bound + 1 try and keep work regions as much as possible + 2 do not use any perturbation + 4 allow exit before re-factorization + 8 try and re-use factorization if no cuts + 16 use standard strong branching rather than clp's + 32 Just go to first factorization in fast dual + 64 try and tighten bounds in crunch + 128 Model will only change in column bounds + 256 Clean up model before hot start + 512 Give user direct access to Clp regions in getBInvARow etc (i.e., + do not unscale, and do not return result in getBInv parameters; + you have to know where to look for the answer) + 1024 Don't "borrow" model in initialSolve + 2048 Don't crunch + 4096 quick check for optimality + Bits above 8192 give where called from in Cbc + At present 0 is normal, 1 doing fast hotstarts, 2 is can do quick check + 65536 Keep simple i.e. no crunch etc + 131072 Try and keep scaling factors around + 262144 Don't try and tighten bounds (funny global cuts) + 524288 Fake objective and 0-1 + 1048576 Don't recompute ray after crunch + 2097152 + */ + mutable unsigned int specialOptions_; + /// Copy of model when option 131072 set + ClpSimplex * baseModel_; + /// Number of rows when last "scaled" + int lastNumberRows_; + /// Continuous model + ClpSimplex * continuousModel_; + /// Possible disaster handler + OsiClpDisasterHandler * disasterHandler_ ; + /// Fake objective + ClpLinearObjective * fakeObjective_; + /// Row scale factors (has inverse at end) + CoinDoubleArrayWithLength rowScale_; + /// Column scale factors (has inverse at end) + CoinDoubleArrayWithLength columnScale_; + //@} +}; + +class OsiClpDisasterHandler : public ClpDisasterHandler { +public: + /**@name Virtual methods that the derived classe should provide. + */ + //@{ + /// Into simplex + virtual void intoSimplex(); + /// Checks if disaster + virtual bool check() const ; + /// saves information for next attempt + virtual void saveInfo(); + /// Type of disaster 0 can fix, 1 abort + virtual int typeOfDisaster(); + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + OsiClpDisasterHandler(OsiClpSolverInterface * model = NULL); + /** Destructor */ + virtual ~OsiClpDisasterHandler(); + // Copy + OsiClpDisasterHandler(const OsiClpDisasterHandler&); + // Assignment + OsiClpDisasterHandler& operator=(const OsiClpDisasterHandler&); + /// Clone + virtual ClpDisasterHandler * clone() const; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setOsiModel(OsiClpSolverInterface * model); + /// Get model + inline OsiClpSolverInterface * osiModel() const + { return osiModel_;} + /// Set where from + inline void setWhereFrom(int value) + { whereFrom_=value;} + /// Get where from + inline int whereFrom() const + { return whereFrom_;} + /// Set phase + inline void setPhase(int value) + { phase_=value;} + /// Get phase + inline int phase() const + { return phase_;} + /// are we in trouble + bool inTrouble() const; + + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to model + OsiClpSolverInterface * osiModel_; + /** Where from + 0 dual (resolve) + 1 crunch + 2 primal (resolve) + 4 dual (initialSolve) + 6 primal (initialSolve) + */ + int whereFrom_; + /** phase + 0 initial + 1 trying continuing with back in and maybe different perturb + 2 trying continuing with back in and different scaling + 3 trying dual from all slack + 4 trying primal from previous stored basis + */ + int phase_; + /// Are we in trouble + bool inTrouble_; + //@} +}; +// So unit test can find out if NDEBUG set +bool OsiClpHasNDEBUG(); +//############################################################################# +/** A function that tests the methods in the OsiClpSolverInterface class. */ +void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); +#endif diff --git a/thirdparty/linux/include/coin/OsiColCut.hpp b/thirdparty/linux/include/coin/OsiColCut.hpp new file mode 100644 index 0000000..c98eb5c --- /dev/null +++ b/thirdparty/linux/include/coin/OsiColCut.hpp @@ -0,0 +1,324 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiColCut_H +#define OsiColCut_H + +#include + +#include "CoinPackedVector.hpp" + +#include "OsiCollections.hpp" +#include "OsiCut.hpp" + +/** Column Cut Class + +Column Cut Class has: +
    +
  • a sparse vector of column lower bounds +
  • a sparse vector of column upper bounds +
+*/ +class OsiColCut : public OsiCut { + friend void OsiColCutUnitTest(const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +public: + + //---------------------------------------------------------------- + + /**@name Setting column bounds */ + //@{ + /// Set column lower bounds + inline void setLbs( + int nElements, + const int * colIndices, + const double * lbElements ); + + /// Set column lower bounds from a packed vector + inline void setLbs( const CoinPackedVector & lbs ); + + /// Set column upper bounds + inline void setUbs( + int nElements, + const int * colIndices, + const double * ubElements ); + + /// Set column upper bounds from a packed vector + inline void setUbs( const CoinPackedVector & ubs ); + //@} + + //---------------------------------------------------------------- + + /**@name Getting column bounds */ + //@{ + /// Get column lower bounds + inline const CoinPackedVector & lbs() const; + /// Get column upper bounds + inline const CoinPackedVector & ubs() const; + //@} + + /**@name Comparison operators */ + //@{ +#if __GNUC__ != 2 + using OsiCut::operator== ; +#endif + /** equal - true if lower bounds, upper bounds, + and OsiCut are equal. + */ + inline virtual bool operator==(const OsiColCut& rhs) const; + +#if __GNUC__ != 2 + using OsiCut::operator!= ; +#endif + /// not equal + inline virtual bool operator!=(const OsiColCut& rhs) const; + //@} + + + //---------------------------------------------------------------- + + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent with respect to itself. + This checks to ensure that: +
    +
  • The bound vectors do not have duplicate indices, +
  • The bound vectors indices are >=0 +
+ */ + inline virtual bool consistent() const; + + /** Returns true if cut is consistent with respect to the solver + interface's model. This checks to ensure that + the lower & upperbound packed vectors: +
    +
  • do not have an index >= the number of column is the model. +
+ */ + inline virtual bool consistent(const OsiSolverInterface& im) const; + + /** Returns true if the cut is infeasible with respect to its bounds and the + column bounds in the solver interface's models. + This checks whether: +
    +
  • the maximum of the new and existing lower bounds is strictly + greater than the minimum of the new and existing upper bounds. +
+ */ + inline virtual bool infeasible(const OsiSolverInterface &im) const; + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const; + //@} + + //---------------------------------------------------------------- + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiColCut & operator=( const OsiColCut& rhs); + + /// Copy constructor + OsiColCut ( const OsiColCut &); + + /// Default Constructor + OsiColCut (); + + /// Clone + virtual OsiColCut * clone() const; + + /// Destructor + virtual ~OsiColCut (); + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const; + //@} + +private: + + /**@name Private member data */ + //@{ + /// Lower bounds + CoinPackedVector lbs_; + /// Upper bounds + CoinPackedVector ubs_; + //@} + +}; + + + +//------------------------------------------------------------------- +// Set lower & upper bound vectors +//------------------------------------------------------------------- +void OsiColCut::setLbs( + int size, + const int * colIndices, + const double * lbElements ) +{ + lbs_.setVector(size,colIndices,lbElements); +} +// +void OsiColCut::setUbs( + int size, + const int * colIndices, + const double * ubElements ) +{ + ubs_.setVector(size,colIndices,ubElements); +} +// +void OsiColCut::setLbs( const CoinPackedVector & lbs ) +{ + lbs_ = lbs; +} +// +void OsiColCut::setUbs( const CoinPackedVector & ubs ) +{ + ubs_ = ubs; +} + +//------------------------------------------------------------------- +// Get Column Lower Bounds and Column Upper Bounds +//------------------------------------------------------------------- +const CoinPackedVector & OsiColCut::lbs() const +{ + return lbs_; +} +// +const CoinPackedVector & OsiColCut::ubs() const +{ + return ubs_; +} + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiColCut::operator==( + const OsiColCut& rhs) const +{ + if ( this->OsiCut::operator!=(rhs) ) + return false; + if ( lbs() != rhs.lbs() ) + return false; + if ( ubs() != rhs.ubs() ) + return false; + return true; +} +// +bool +OsiColCut::operator!=( + const OsiColCut& rhs) const +{ + return !( (*this)==rhs ); +} + +//---------------------------------------------------------------- +// consistent & infeasible +//------------------------------------------------------------------- +bool OsiColCut::consistent() const +{ + const CoinPackedVector & lb = lbs(); + const CoinPackedVector & ub = ubs(); + // Test for consistent cut. + // Are packed vectors consistent? + lb.duplicateIndex("consistent", "OsiColCut"); + ub.duplicateIndex("consistent", "OsiColCut"); + if ( lb.getMinIndex() < 0 ) return false; + if ( ub.getMinIndex() < 0 ) return false; + return true; +} +// +bool OsiColCut::consistent(const OsiSolverInterface& im) const +{ + const CoinPackedVector & lb = lbs(); + const CoinPackedVector & ub = ubs(); + + // Test for consistent cut. + if ( lb.getMaxIndex() >= im.getNumCols() ) return false; + if ( ub.getMaxIndex() >= im.getNumCols() ) return false; + + return true; +} + +#if 0 +bool OsiColCut::feasible(const OsiSolverInterface &im) const +{ + const double * oldColLb = im.getColLower(); + const double * oldColUb = im.getColUpper(); + const CoinPackedVector & cutLbs = lbs(); + const CoinPackedVector & cutUbs = ubs(); + int i; + + for ( i=0; i oldColLb[colIndx] ) + newLb = cutLbs.elements()[i]; + else + newLb = oldColLb[colIndx]; + + double newUb = oldColUb[colIndx]; + if ( cutUbs.indexExists(colIndx) ) + if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx]; + if ( newLb > newUb ) + return false; + } + + for ( i=0; i newLb ) newLb = cutLbs[colIndx]; + if ( newUb < newLb ) + return false; + } + + return true; +} +#endif + + +bool OsiColCut::infeasible(const OsiSolverInterface &im) const +{ + const double * oldColLb = im.getColLower(); + const double * oldColUb = im.getColUpper(); + const CoinPackedVector & cutLbs = lbs(); + const CoinPackedVector & cutUbs = ubs(); + int i; + + for ( i=0; i oldColLb[colIndx] ? + cutLbs.getElements()[i] : oldColLb[colIndx]; + + double newUb = oldColUb[colIndx]; + if ( cutUbs.isExistingIndex(colIndx) ) + if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx]; + if ( newLb > newUb ) + return true; + } + + for ( i=0; i newLb ) newLb = cutLbs[colIndx]; + if ( newUb < newLb ) + return true; + } + + return false; +} + +#endif diff --git a/thirdparty/linux/include/coin/OsiCollections.hpp b/thirdparty/linux/include/coin/OsiCollections.hpp new file mode 100644 index 0000000..d68df1a --- /dev/null +++ b/thirdparty/linux/include/coin/OsiCollections.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCollections_H +#define OsiCollections_H + +#include + +//Forward declarations +class OsiColCut; +class OsiRowCut; +class OsiCut; + + + +/* Collection Classes */ + +/**@name Typedefs for Standard Template Library collections of Osi Objects. */ +//@{ +/// Vector of int +typedef std::vector OsiVectorInt; +/// Vector of double +typedef std::vector OsiVectorDouble; +/// Vector of OsiColCut pointers +typedef std::vector OsiVectorColCutPtr; +/// Vector of OsiRowCut pointers +typedef std::vector OsiVectorRowCutPtr; +/// Vector of OsiCut pointers +typedef std::vector OsiVectorCutPtr; +//@} + + + +#endif diff --git a/thirdparty/linux/include/coin/OsiConfig.h b/thirdparty/linux/include/coin/OsiConfig.h new file mode 100644 index 0000000..f6285d0 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiConfig.h @@ -0,0 +1,19 @@ +/* src/Osi/config_osi.h. Generated by configure. */ +/* src/Osi/config_osi.h.in. */ + +#ifndef __CONFIG_OSI_H__ +#define __CONFIG_OSI_H__ + +/* Version number of project */ +#define OSI_VERSION "0.107.6" + +/* Major Version number of project */ +#define OSI_VERSION_MAJOR 0 + +/* Minor Version number of project */ +#define OSI_VERSION_MINOR 107 + +/* Release Version number of project */ +#define OSI_VERSION_RELEASE 6 + +#endif diff --git a/thirdparty/linux/include/coin/OsiCut.hpp b/thirdparty/linux/include/coin/OsiCut.hpp new file mode 100644 index 0000000..0b2cc5c --- /dev/null +++ b/thirdparty/linux/include/coin/OsiCut.hpp @@ -0,0 +1,245 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCut_H +#define OsiCut_H + +#include "OsiCollections.hpp" +#include "OsiSolverInterface.hpp" + +/** Base Class for cut. + +The Base cut class contains: +
    +
  • a measure of the cut's effectivness +
+*/ + +/* + COIN_NOTEST_DUPLICATE is rooted in CoinUtils. Check there before you + meddle here. +*/ +#ifdef COIN_FAST_CODE +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_NOTEST_DUPLICATE +#endif +#endif + +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE true +#else +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE false +#endif + + +class OsiCut { + +public: + + //------------------------------------------------------------------- + /**@name Effectiveness */ + //@{ + /// Set effectiveness + inline void setEffectiveness( double e ); + /// Get effectiveness + inline double effectiveness() const; + //@} + + /**@name GloballyValid */ + //@{ + /// Set globallyValid (nonzero true) + inline void setGloballyValid( bool trueFalse ) + { globallyValid_=trueFalse ? 1 : 0;} + inline void setGloballyValid( ) + { globallyValid_=1;} + inline void setNotGloballyValid( ) + { globallyValid_=0;} + /// Get globallyValid + inline bool globallyValid() const + { return globallyValid_!=0;} + /// Set globallyValid as integer (nonzero true) + inline void setGloballyValidAsInteger( int trueFalse ) + { globallyValid_=trueFalse;} + /// Get globallyValid + inline int globallyValidAsInteger() const + { return globallyValid_;} + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const {} + //@} + +#if 0 + / **@name Times used */ + / /@{ + / // Set times used + inline void setTimesUsed( int t ); + / // Increment times used + inline void incrementTimesUsed(); + / // Get times used + inline int timesUsed() const; + / /@} + + / **@name Times tested */ + / /@{ + / // Set times tested + inline void setTimesTested( int t ); + / // Increment times tested + inline void incrementTimesTested(); + / // Get times tested + inline int timesTested() const; + / /@} +#endif + + //---------------------------------------------------------------- + + /**@name Comparison operators */ + //@{ + ///equal. 2 cuts are equal if there effectiveness are equal + inline virtual bool operator==(const OsiCut& rhs) const; + /// not equal + inline virtual bool operator!=(const OsiCut& rhs) const; + /// less than. True if this.effectiveness < rhs.effectiveness + inline virtual bool operator< (const OsiCut& rhs) const; + /// less than. True if this.effectiveness > rhs.effectiveness + inline virtual bool operator> (const OsiCut& rhs) const; + //@} + + //---------------------------------------------------------------- + // consistent() - returns true if the cut is consistent with repect to itself. + // This might include checks to ensure that a packed vector + // itself does not have a negative index. + // consistent(const OsiSolverInterface& si) - returns true if cut is consistent with + // respect to the solver interface's model. This might include a check to + // make sure a column index is not greater than the number + // of columns in the problem. + // infeasible(const OsiSolverInterface& si) - returns true if the cut is infeasible + // "with respect to itself". This might include a check to ensure + // the lower bound is greater than the upper bound, or if the + // cut simply replaces bounds that the new bounds are feasible with + // respect to the old bounds. + //----------------------------------------------------------------- + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent with respect to itself, + without considering any + data in the model. For example, it might check to ensure + that a column index is not negative. + */ + inline virtual bool consistent() const=0; + + /** Returns true if cut is consistent when considering the solver + interface's model. For example, it might check to ensure + that a column index is not greater than the number of columns + in the model. Assumes consistent() is true. + */ + inline virtual bool consistent(const OsiSolverInterface& si) const=0; + + /** Returns true if the cut is infeasible "with respect to itself" and + cannot be satisfied. This method does NOT check whether adding the + cut to the solver interface's model will make the -model- infeasble. + A cut which returns !infeasible(si) may very well make the model + infeasible. (Of course, adding a cut with returns infeasible(si) + will make the model infeasible.) + + The "with respect to itself" is in quotes becaues + in the case where the cut + simply replaces existing bounds, it may make + sense to test infeasibility with respect to the current bounds + held in the solver interface's model. For example, if the cut + has a single variable in it, it might check that the maximum + of new and existing lower bounds is greater than the minium of + the new and existing upper bounds. + + Assumes that consistent(si) is true.
+ Infeasible cuts can be a useful mechanism for a cut generator to + inform the solver interface that its detected infeasibility of the + problem. + */ + inline virtual bool infeasible(const OsiSolverInterface &si) const=0; + + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const=0; + //@} + +protected: + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiCut (); + + /// Copy constructor + OsiCut ( const OsiCut &); + + /// Assignment operator + OsiCut & operator=( const OsiCut& rhs); + + /// Destructor + virtual ~OsiCut (); + //@} + +private: + + /**@name Private member data */ + //@{ + /// Effectiveness + double effectiveness_; + /// If cut has global validity i.e. can be used anywhere in tree + int globallyValid_; +#if 0 + /// Times used + int timesUsed_; + /// Times tested + int timesTested_; +#endif + //@} +}; + + +//------------------------------------------------------------------- +// Set/Get member data +//------------------------------------------------------------------- +void OsiCut::setEffectiveness(double e) { effectiveness_=e; } +double OsiCut::effectiveness() const { return effectiveness_; } + +#if 0 +void OsiCut::setTimesUsed( int t ) { timesUsed_=t; } +void OsiCut::incrementTimesUsed() { timesUsed_++; } +int OsiCut::timesUsed() const { return timesUsed_; } + +void OsiCut::setTimesTested( int t ) { timesTested_=t; } +void OsiCut::incrementTimesTested() { timesTested_++; } +int OsiCut::timesTested() const{ return timesTested_; } +#endif + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiCut::operator==(const OsiCut& rhs) const +{ + return effectiveness()==rhs.effectiveness(); +} +bool +OsiCut::operator!=(const OsiCut& rhs) const +{ + return !( (*this)==rhs ); +} +bool +OsiCut::operator< (const OsiCut& rhs) const +{ + return effectiveness() (const OsiCut& rhs) const +{ + return effectiveness()>rhs.effectiveness(); +} +#endif diff --git a/thirdparty/linux/include/coin/OsiCuts.hpp b/thirdparty/linux/include/coin/OsiCuts.hpp new file mode 100644 index 0000000..5eea264 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiCuts.hpp @@ -0,0 +1,474 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCuts_H +#define OsiCuts_H + +#include "CoinPragma.hpp" + +#include +#include +#include "OsiCollections.hpp" +#include "OsiRowCut.hpp" +#include "OsiColCut.hpp" +#include "CoinFloatEqual.hpp" + +/** Collections of row cuts and column cuts +*/ +class OsiCuts { + friend void OsiCutsUnitTest(); + +public: + /**@name Iterator classes + */ + //@{ + /** Iterator + + This is a class for iterating over the collection of cuts. + */ + class iterator { + friend class OsiCuts; + public: + iterator(OsiCuts& cuts); + iterator(const iterator & src); + iterator & operator=( const iterator& rhs); + ~iterator (); + OsiCut* operator*() const { return cutP_; } + iterator operator++(); + + iterator operator++(int) + { + iterator temp = *this; + ++*this; + return temp; + } + + bool operator==(const iterator& it) const { + return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); + } + + bool operator!=(const iterator& it) const { + return !((*this)==it); + } + + bool operator<(const iterator& it) const { + return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); + } + + private: + iterator(); + // *THINK* : how to inline these without sticking the code here (ugly...) + iterator begin(); + iterator end(); + OsiCuts& cuts_; + int rowCutIndex_; + int colCutIndex_; + OsiCut * cutP_; + }; + + /** Const Iterator + + This is a class for iterating over the collection of cuts. + */ + class const_iterator { + friend class OsiCuts; + public: + typedef std::forward_iterator_tag iterator_category; + typedef OsiCut* value_type; + typedef size_t difference_type; + typedef OsiCut ** pointer; + typedef OsiCut *& reference; + + public: + const_iterator(const OsiCuts& cuts); + const_iterator(const const_iterator & src); + const_iterator & operator=( const const_iterator& rhs); + ~const_iterator (); + const OsiCut* operator*() const { return cutP_; } + + const_iterator operator++(); + + const_iterator operator++(int) + { + const_iterator temp = *this; + ++*this; + return temp; + } + + bool operator==(const const_iterator& it) const { + return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); + } + + bool operator!=(const const_iterator& it) const { + return !((*this)==it); + } + + bool operator<(const const_iterator& it) const { + return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); + } + private: + inline const_iterator(); + // *THINK* : how to inline these without sticking the code here (ugly...) + const_iterator begin(); + const_iterator end(); + const OsiCuts * cutsPtr_; + int rowCutIndex_; + int colCutIndex_; + const OsiCut * cutP_; + }; + //@} + + //------------------------------------------------------------------- + // + // Cuts class definition begins here: + // + //------------------------------------------------------------------- + + /** \name Inserting a cut into collection */ + //@{ + /** \brief Insert a row cut */ + inline void insert( const OsiRowCut & rc ); + /** \brief Insert a row cut unless it is a duplicate - cut may get sorted. + Duplicate is defined as CoinAbsFltEq says same*/ + void insertIfNotDuplicate( OsiRowCut & rc , CoinAbsFltEq treatAsSame=CoinAbsFltEq(1.0e-12) ); + /** \brief Insert a row cut unless it is a duplicate - cut may get sorted. + Duplicate is defined as CoinRelFltEq says same*/ + void insertIfNotDuplicate( OsiRowCut & rc , CoinRelFltEq treatAsSame ); + /** \brief Insert a column cut */ + inline void insert( const OsiColCut & cc ); + + /** \brief Insert a row cut. + + The OsiCuts object takes control of the cut object. + On return, \c rcPtr is NULL. + */ + inline void insert( OsiRowCut * & rcPtr ); + /** \brief Insert a column cut. + + The OsiCuts object takes control of the cut object. + On return \c ccPtr is NULL. + */ + inline void insert( OsiColCut * & ccPtr ); +#if 0 + inline void insert( OsiCut * & cPtr ); +#endif + + /** \brief Insert a set of cuts */ + inline void insert(const OsiCuts & cs); + + //@} + + /**@name Number of cuts in collection */ + //@{ + /// Number of row cuts in collection + inline int sizeRowCuts() const; + /// Number of column cuts in collection + inline int sizeColCuts() const; + /// Number of cuts in collection + inline int sizeCuts() const; + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + inline void printCuts() const; + //@} + + /**@name Get a cut from collection */ + //@{ + /// Get pointer to i'th row cut + inline OsiRowCut * rowCutPtr(int i); + /// Get const pointer to i'th row cut + inline const OsiRowCut * rowCutPtr(int i) const; + /// Get pointer to i'th column cut + inline OsiColCut * colCutPtr(int i); + /// Get const pointer to i'th column cut + inline const OsiColCut * colCutPtr(int i) const; + + /// Get reference to i'th row cut + inline OsiRowCut & rowCut(int i); + /// Get const reference to i'th row cut + inline const OsiRowCut & rowCut(int i) const; + /// Get reference to i'th column cut + inline OsiColCut & colCut(int i); + /// Get const reference to i'th column cut + inline const OsiColCut & colCut(int i) const; + + /// Get const pointer to the most effective cut + inline const OsiCut * mostEffectiveCutPtr() const; + /// Get pointer to the most effective cut + inline OsiCut * mostEffectiveCutPtr(); + //@} + + /**@name Deleting cut from collection */ + //@{ + /// Remove i'th row cut from collection + inline void eraseRowCut(int i); + /// Remove i'th column cut from collection + inline void eraseColCut(int i); + /// Get pointer to i'th row cut and remove ptr from collection + inline OsiRowCut * rowCutPtrAndZap(int i); + /*! \brief Clear all row cuts without deleting them + + Handy in case one wants to use CGL without managing cuts in one of + the OSI containers. Client is ultimately responsible for deleting the + data structures holding the row cuts. + */ + inline void dumpCuts() ; + /*! \brief Selective delete and clear for row cuts. + + Deletes the cuts specified in \p to_erase then clears remaining cuts + without deleting them. A hybrid of eraseRowCut(int) and dumpCuts(). + Client is ultimately responsible for deleting the data structures + for row cuts not specified in \p to_erase. + */ + inline void eraseAndDumpCuts(const std::vector to_erase) ; + //@} + + /**@name Sorting collection */ + //@{ + /// Cuts with greatest effectiveness are first. + inline void sort(); + //@} + + + /**@name Iterators + Example of using an iterator to sum effectiveness + of all cuts in the collection. +
+     double sumEff=0.0;
+     for ( OsiCuts::iterator it=cuts.begin(); it!=cuts.end(); ++it )
+           sumEff+= (*it)->effectiveness();
+     
+ */ + //@{ + /// Get iterator to beginning of collection + inline iterator begin() { iterator it(*this); it.begin(); return it; } + /// Get const iterator to beginning of collection + inline const_iterator begin() const { const_iterator it(*this); it.begin(); return it; } + /// Get iterator to end of collection + inline iterator end() { iterator it(*this); it.end(); return it; } + /// Get const iterator to end of collection + inline const_iterator end() const { const_iterator it(*this); it.end(); return it; } + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + OsiCuts (); + + /// Copy constructor + OsiCuts ( const OsiCuts &); + + /// Assignment operator + OsiCuts & operator=( const OsiCuts& rhs); + + /// Destructor + virtual ~OsiCuts (); + //@} + +private: + //*@name Function operator for sorting cuts by efectiveness */ + //@{ + class OsiCutCompare + { + public: + /// Function for sorting cuts by effectiveness + inline bool operator()(const OsiCut * c1P,const OsiCut * c2P) + { return c1P->effectiveness() > c2P->effectiveness(); } + }; + //@} + + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfCopy( const OsiCuts & source ); + /// Delete internal data + void gutsOfDestructor(); + //@} + + /**@name Private member data */ + //@{ + /// Vector of row cuts pointers + OsiVectorRowCutPtr rowCutPtrs_; + /// Vector of column cuts pointers + OsiVectorColCutPtr colCutPtrs_; + //@} + +}; + + +//------------------------------------------------------------------- +// insert cuts into collection +//------------------------------------------------------------------- +void OsiCuts::insert( const OsiRowCut & rc ) +{ + OsiRowCut * newCutPtr = rc.clone(); + //assert(dynamic_cast(newCutPtr) != NULL ); + rowCutPtrs_.push_back(static_cast(newCutPtr)); +} +void OsiCuts::insert( const OsiColCut & cc ) +{ + OsiColCut * newCutPtr = cc.clone(); + //assert(dynamic_cast(newCutPtr) != NULL ); + colCutPtrs_.push_back(static_cast(newCutPtr)); +} + +void OsiCuts::insert( OsiRowCut* & rcPtr ) +{ + rowCutPtrs_.push_back(rcPtr); + rcPtr = NULL; +} +void OsiCuts::insert( OsiColCut* &ccPtr ) +{ + colCutPtrs_.push_back(ccPtr); + ccPtr = NULL; +} +#if 0 +void OsiCuts::insert( OsiCut* & cPtr ) +{ + OsiRowCut * rcPtr = dynamic_cast(cPtr); + if ( rcPtr != NULL ) { + insert( rcPtr ); + cPtr = rcPtr; + } + else { + OsiColCut * ccPtr = dynamic_cast(cPtr); + assert( ccPtr != NULL ); + insert( ccPtr ); + cPtr = ccPtr; + } +} +#endif + +// LANNEZ SEBASTIEN added Thu May 25 01:22:51 EDT 2006 +void OsiCuts::insert(const OsiCuts & cs) +{ + for (OsiCuts::const_iterator it = cs.begin (); it != cs.end (); it++) + { + const OsiRowCut * rCut = dynamic_cast (*it); + const OsiColCut * cCut = dynamic_cast (*it); + assert (rCut || cCut); + if (rCut) + insert (*rCut); + else + insert (*cCut); + } +} + +//------------------------------------------------------------------- +// sort +//------------------------------------------------------------------- +void OsiCuts::sort() +{ + std::sort(colCutPtrs_.begin(),colCutPtrs_.end(),OsiCutCompare()); + std::sort(rowCutPtrs_.begin(),rowCutPtrs_.end(),OsiCutCompare()); +} + + +//------------------------------------------------------------------- +// Get number of in collections +//------------------------------------------------------------------- +int OsiCuts::sizeRowCuts() const { + return static_cast(rowCutPtrs_.size()); } +int OsiCuts::sizeColCuts() const { + return static_cast(colCutPtrs_.size()); } +int OsiCuts::sizeCuts() const { + return static_cast(sizeRowCuts()+sizeColCuts()); } + +//---------------------------------------------------------------- +// Get i'th cut from the collection +//---------------------------------------------------------------- +const OsiRowCut * OsiCuts::rowCutPtr(int i) const { return rowCutPtrs_[i]; } +const OsiColCut * OsiCuts::colCutPtr(int i) const { return colCutPtrs_[i]; } +OsiRowCut * OsiCuts::rowCutPtr(int i) { return rowCutPtrs_[i]; } +OsiColCut * OsiCuts::colCutPtr(int i) { return colCutPtrs_[i]; } + +const OsiRowCut & OsiCuts::rowCut(int i) const { return *rowCutPtr(i); } +const OsiColCut & OsiCuts::colCut(int i) const { return *colCutPtr(i); } +OsiRowCut & OsiCuts::rowCut(int i) { return *rowCutPtr(i); } +OsiColCut & OsiCuts::colCut(int i) { return *colCutPtr(i); } + +//---------------------------------------------------------------- +// Get most effective cut from collection +//---------------------------------------------------------------- +const OsiCut * OsiCuts::mostEffectiveCutPtr() const +{ + const_iterator b=begin(); + const_iterator e=end(); + return *(std::min_element(b,e,OsiCutCompare())); +} +OsiCut * OsiCuts::mostEffectiveCutPtr() +{ + iterator b=begin(); + iterator e=end(); + //return *(std::min_element(b,e,OsiCutCompare())); + OsiCut * retVal = NULL; + double maxEff = COIN_DBL_MIN; + for ( OsiCuts::iterator it=b; it!=e; ++it ) { + if (maxEff < (*it)->effectiveness() ) { + maxEff = (*it)->effectiveness(); + retVal = *it; + } + } + return retVal; +} + +//---------------------------------------------------------------- +// Print all cuts +//---------------------------------------------------------------- +void +OsiCuts::printCuts() const +{ + // do all column cuts first + int i; + int numberColCuts=sizeColCuts(); + for (i=0;iprint(); + } + int numberRowCuts=sizeRowCuts(); + for (i=0;iprint(); + } +} + +//---------------------------------------------------------------- +// Erase i'th cut from the collection +//---------------------------------------------------------------- +void OsiCuts::eraseRowCut(int i) +{ + delete rowCutPtrs_[i]; + rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); +} +void OsiCuts::eraseColCut(int i) +{ + delete colCutPtrs_[i]; + colCutPtrs_.erase( colCutPtrs_.begin()+i ); +} +/// Get pointer to i'th row cut and remove ptr from collection +OsiRowCut * +OsiCuts::rowCutPtrAndZap(int i) +{ + OsiRowCut * cut = rowCutPtrs_[i]; + rowCutPtrs_[i]=NULL; + rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); + return cut; +} +void OsiCuts::dumpCuts() +{ + rowCutPtrs_.clear() ; +} +void OsiCuts::eraseAndDumpCuts(const std::vector to_erase) +{ + for (unsigned i=0; i +
  • + Create a copy of the original problem. +
  • +
  • + Subject the copy to a series of transformations (the presolve + methods) to produce a presolved model. Each transformation is also + expected to provide a method to reverse the transformation (the + postsolve method). The postsolve methods are collected in a + linked list; the postsolve method for the final presolve transformation + is at the head of the list. +
  • +
  • + Hand the presolved problem to the solver for optimization. +
  • +
  • + Apply the collected postsolve methods to the presolved problem + and solution, restating the solution in terms of the original problem. +
  • + + + The COIN presolve algorithms are unaware of OSI. The OsiPresolve class takes + care of the interface. Given an OsiSolverInterface \c origModel, it will take + care of creating a clone properly loaded with the presolved problem and ready + for optimization. After optimization, it will apply postsolve + transformations and load the result back into \c origModel. + + Assuming a problem has been loaded into an + \c OsiSolverInterface \c origModel, a bare-bones application looks like this: + \code + OsiPresolve pinfo ; + OsiSolverInterface *presolvedModel ; + // Return an OsiSolverInterface loaded with the presolved problem. + presolvedModel = pinfo.presolvedModel(*origModel,1.0e-8,false,numberPasses) ; + presolvedModel->initialSolve() ; + // Restate the solution and load it back into origModel. + pinfo.postsolve(true) ; + delete presolvedModel ; + \endcode +*/ + + + +class OsiPresolve { +public: + /// Default constructor (empty object) + OsiPresolve(); + + /// Virtual destructor + virtual ~OsiPresolve(); + + /*! \brief Create a new OsiSolverInterface loaded with the presolved problem. + + This method implements the first two steps described in the class + documentation. It clones \c origModel and applies presolve + transformations, storing the resulting list of postsolve + transformations. It returns a pointer to a new OsiSolverInterface loaded + with the presolved problem, or NULL if the problem is infeasible or + unbounded. If \c keepIntegers is true then bounds may be tightened in + the original. Bounds will be moved by up to \c feasibilityTolerance to + try and stay feasible. When \c doStatus is true, the current solution will + be transformed to match the presolved model. + + This should be paired with postsolve(). It is up to the client to + destroy the returned OsiSolverInterface, after calling postsolve(). + + This method is virtual. Override this method if you need to customize + the steps of creating a model to apply presolve transformations. + + In some sense, a wrapper for presolve(CoinPresolveMatrix*). + */ + virtual OsiSolverInterface *presolvedModel(OsiSolverInterface & origModel, + double feasibilityTolerance=0.0, + bool keepIntegers=true, + int numberPasses=5, + const char * prohibited=NULL, + bool doStatus=true, + const char * rowProhibited=NULL); + + /*! \brief Restate the solution to the presolved problem in terms of the + original problem and load it into the original model. + + postsolve() restates the solution in terms of the original problem and + updates the original OsiSolverInterface supplied to presolvedModel(). If + the problem has not been solved to optimality, there are no guarantees. + If you are using an algorithm like simplex that has a concept of a basic + solution, then set updateStatus + + The advantage of going back to the original problem is that it + will be exactly as it was, i.e., 0.0 will not become 1.0e-19. + + Note that if you modified the original problem after presolving, then you + must ``undo'' these modifications before calling postsolve(). + + In some sense, a wrapper for postsolve(CoinPostsolveMatrix&). + */ + virtual void postsolve(bool updateStatus=true); + + /*! \brief Return a pointer to the presolved model. */ + OsiSolverInterface * model() const; + + /// Return a pointer to the original model + OsiSolverInterface * originalModel() const; + + /// Set the pointer to the original model + void setOriginalModel(OsiSolverInterface *model); + + /// Return a pointer to the original columns + const int * originalColumns() const; + + /// Return a pointer to the original rows + const int * originalRows() const; + + /// Return number of rows in original model + inline int getNumRows() const + { return nrows_;} + + /// Return number of columns in original model + inline int getNumCols() const + { return ncols_;} + + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + */ + inline void setNonLinearValue(double value) + { nonLinearValue_ = value;} + inline double nonLinearValue() const + { return nonLinearValue_;} + /*! \brief Fine control over presolve actions + + Set/clear the following bits to allow or suppress actions: + - 0x01 allow duplicate column processing on integer columns + and dual stuff on integers + - 0x02 switch off actions which can change +1 to something else + (doubleton, tripleton, implied free) + - 0x04 allow transfer of costs from singletons and between integer + variables (when advantageous) + - 0x08 do not allow x+y+z=1 transform + - 0x10 allow actions that don't easily unroll + - 0x20 allow dubious gub element reduction + + GUB element reduction is only partially implemented in CoinPresolve (see + gubrow_action) and willl cause an abort at postsolve. It's not clear + what's meant by `dual stuff on integers'. + -- lh, 110605 -- + */ + inline void setPresolveActions(int action) + { presolveActions_ = (presolveActions_&0xffff0000)|(action&0xffff);} + +private: + /*! Original model (solver interface loaded with the original problem). + + Must not be destroyed until after postsolve(). + */ + OsiSolverInterface * originalModel_; + + /*! Presolved model (solver interface loaded with the presolved problem) + + Must be destroyed by the client (using delete) after postsolve(). + */ + OsiSolverInterface * presolvedModel_; + + /*! "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + One could also allow for cases where sign of coefficient is known. + */ + double nonLinearValue_; + + /// Original column numbers + int * originalColumn_; + + /// Original row numbers + int * originalRow_; + + /// The list of transformations applied. + const CoinPresolveAction *paction_; + + /*! \brief Number of columns in original model. + + The problem will expand back to its former size as postsolve + transformations are applied. It is efficient to allocate data structures + for the final size of the problem rather than expand them as needed. + */ + int ncols_; + + /*! \brief Number of rows in original model. */ + int nrows_; + + /*! \brief Number of nonzero matrix coefficients in the original model. */ + CoinBigIndex nelems_; + + /** Whether we want to skip dual part of presolve etc. + 1 bit allows duplicate column processing on integer columns + and dual stuff on integers + 4 transfers costs to integer variables + */ + int presolveActions_; + /// Number of major passes + int numberPasses_; + +protected: + /*! \brief Apply presolve transformations to the problem. + + Handles the core activity of applying presolve transformations. + + If you want to apply the individual presolve routines differently, or + perhaps add your own to the mix, define a derived class and override + this method + */ + virtual const CoinPresolveAction *presolve(CoinPresolveMatrix *prob); + + /*! \brief Reverse presolve transformations to recover the solution + to the original problem. + + Handles the core activity of applying postsolve transformations. + + Postsolving is pretty generic; just apply the transformations in reverse + order. You will probably only be interested in overriding this method if + you want to add code to test for consistency while debugging new presolve + techniques. + */ + virtual void postsolve(CoinPostsolveMatrix &prob); + + /*! \brief Destroys queued postsolve actions. + + E.g., when presolve() determines the problem is infeasible, so that + it will not be necessary to actually solve the presolved problem and + convert the result back to the original problem. + */ + void gutsOfDestroy(); +}; +#endif diff --git a/thirdparty/linux/include/coin/OsiRowCut.hpp b/thirdparty/linux/include/coin/OsiRowCut.hpp new file mode 100644 index 0000000..1332802 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiRowCut.hpp @@ -0,0 +1,331 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiRowCut_H +#define OsiRowCut_H + +#include "CoinPackedVector.hpp" + +#include "OsiCollections.hpp" +#include "OsiCut.hpp" + +//#define OSI_INLINE_ROWCUT_METHODS +#ifdef OSI_INLINE_ROWCUT_METHODS +#define OsiRowCut_inline inline +#else +#define OsiRowCut_inline +#endif + +/** Row Cut Class + +A row cut has: +
      +
    • a lower bound
      +
    • an upper bound
      +
    • a vector of row elements +
    +*/ +class OsiRowCut : public OsiCut { + friend void OsiRowCutUnitTest(const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +public: + + /**@name Row bounds */ + //@{ + /// Get lower bound + OsiRowCut_inline double lb() const; + /// Set lower bound + OsiRowCut_inline void setLb(double lb); + /// Get upper bound + OsiRowCut_inline double ub() const; + /// Set upper bound + OsiRowCut_inline void setUb(double ub); + //@} + + /**@name Row rhs, sense, range */ + //@{ + /// Get sense ('E', 'G', 'L', 'N', 'R') + char sense() const; + /// Get right-hand side + double rhs() const; + /// Get range (ub - lb for 'R' rows, 0 otherwise) + double range() const; + //@} + + //------------------------------------------------------------------- + /**@name Row elements */ + //@{ + /// Set row elements + OsiRowCut_inline void setRow( + int size, + const int * colIndices, + const double * elements, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /// Set row elements from a packed vector + OsiRowCut_inline void setRow( const CoinPackedVector & v ); + /// Get row elements + OsiRowCut_inline const CoinPackedVector & row() const; + /// Get row elements for changing + OsiRowCut_inline CoinPackedVector & mutableRow() ; + //@} + + /**@name Comparison operators */ + //@{ +#if __GNUC__ != 2 + using OsiCut::operator== ; +#endif + /** equal - true if lower bound, upper bound, row elements, + and OsiCut are equal. + */ + OsiRowCut_inline bool operator==(const OsiRowCut& rhs) const; + +#if __GNUC__ != 2 + using OsiCut::operator!= ; +#endif + /// not equal + OsiRowCut_inline bool operator!=(const OsiRowCut& rhs) const; + //@} + + + //---------------------------------------------------------------- + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent. + This checks to ensure that: +
      +
    • The row element vector does not have duplicate indices +
    • The row element vector indices are >= 0 +
    + */ + OsiRowCut_inline bool consistent() const; + + /** Returns true if cut is consistent with respect to the solver + interface's model. + This checks to ensure that +
      +
    • The row element vector indices are < the number of columns + in the model +
    + */ + OsiRowCut_inline bool consistent(const OsiSolverInterface& im) const; + + /** Returns true if the row cut itself is infeasible and cannot be satisfied. + This checks whether +
      +
    • the lower bound is strictly greater than the + upper bound. +
    + */ + OsiRowCut_inline bool infeasible(const OsiSolverInterface &im) const; + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const; + //@} + + /**@name Arithmetic operators. Apply CoinPackedVector methods to the vector */ + //@{ + /// add value to every vector entry + void operator+=(double value) + { row_ += value; } + + /// subtract value from every vector entry + void operator-=(double value) + { row_ -= value; } + + /// multiply every vector entry by value + void operator*=(double value) + { row_ *= value; } + + /// divide every vector entry by value + void operator/=(double value) + { row_ /= value; } + //@} + + /// Allow access row sorting function + void sortIncrIndex() + {row_.sortIncrIndex();} + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiRowCut & operator=( const OsiRowCut& rhs); + + /// Copy constructor + OsiRowCut ( const OsiRowCut &); + + /// Clone + virtual OsiRowCut * clone() const; + + /// Default Constructor + OsiRowCut (); + + /** \brief Ownership Constructor + + This constructor assumes ownership of the vectors passed as parameters + for indices and elements. \p colIndices and \p elements will be NULL + on return. + */ + OsiRowCut(double cutlb, double cutub, + int capacity, int size, + int *&colIndices, double *&elements); + + /// Destructor + virtual ~OsiRowCut (); + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const ; + //@} + +private: + + + /**@name Private member data */ + //@{ + /// Row elements + CoinPackedVector row_; + /// Row lower bound + double lb_; + /// Row upper bound + double ub_; + //@} +}; + +#ifdef OSI_INLINE_ROWCUT_METHODS + +//------------------------------------------------------------------- +// Set/Get lower & upper bounds +//------------------------------------------------------------------- +double OsiRowCut::lb() const { return lb_; } +void OsiRowCut::setLb(double lb) { lb_ = lb; } +double OsiRowCut::ub() const { return ub_; } +void OsiRowCut::setUb(double ub) { ub_ = ub; } + +//------------------------------------------------------------------- +// Set row elements +//------------------------------------------------------------------- +void OsiRowCut::setRow(int size, + const int * colIndices, const double * elements) +{ + row_.setVector(size,colIndices,elements); +} +void OsiRowCut::setRow( const CoinPackedVector & v ) +{ + row_ = v; +} + +//------------------------------------------------------------------- +// Get the row +//------------------------------------------------------------------- +const CoinPackedVector & OsiRowCut::row() const +{ + return row_; +} + +//------------------------------------------------------------------- +// Get the row so we can change +//------------------------------------------------------------------- +CoinPackedVector & OsiRowCut::mutableRow() +{ + return row_; +} + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiRowCut::operator==(const OsiRowCut& rhs) const +{ + if ( this->OsiCut::operator!=(rhs) ) return false; + if ( row() != rhs.row() ) return false; + if ( lb() != rhs.lb() ) return false; + if ( ub() != rhs.ub() ) return false; + return true; +} +bool +OsiRowCut::operator!=(const OsiRowCut& rhs) const +{ + return !( (*this)==rhs ); +} + + +//---------------------------------------------------------------- +// consistent & infeasible +//------------------------------------------------------------------- +bool OsiRowCut::consistent() const +{ + const CoinPackedVector & r=row(); + r.duplicateIndex("consistent", "OsiRowCut"); + if ( r.getMinIndex() < 0 ) return false; + return true; +} +bool OsiRowCut::consistent(const OsiSolverInterface& im) const +{ + const CoinPackedVector & r=row(); + if ( r.getMaxIndex() >= im.getNumCols() ) return false; + + return true; +} +bool OsiRowCut::infeasible(const OsiSolverInterface &im) const +{ + if ( lb() > ub() ) return true; + + return false; +} + +#endif + +/** Row Cut Class which refers back to row which created it. + It may be useful to strengthen a row rather than add a cut. To do this + we need to know which row is strengthened. This trivial extension + to OsiRowCut does that. + +*/ +class OsiRowCut2 : public OsiRowCut { + +public: + + /**@name Which row */ + //@{ + /// Get row + inline int whichRow() const + { return whichRow_;} + /// Set row + inline void setWhichRow(int row) + { whichRow_=row;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiRowCut2 & operator=( const OsiRowCut2& rhs); + + /// Copy constructor + OsiRowCut2 ( const OsiRowCut2 &); + + /// Clone + virtual OsiRowCut * clone() const; + + /// Default Constructor + OsiRowCut2 (int row=-1); + + /// Destructor + virtual ~OsiRowCut2 (); + //@} + +private: + + + /**@name Private member data */ + //@{ + /// Which row + int whichRow_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/OsiRowCutDebugger.hpp b/thirdparty/linux/include/coin/OsiRowCutDebugger.hpp new file mode 100644 index 0000000..548e8e3 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiRowCutDebugger.hpp @@ -0,0 +1,187 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiRowCutDebugger_H +#define OsiRowCutDebugger_H + +/*! \file OsiRowCutDebugger.hpp + + \brief Provides a facility to validate cut constraints to ensure that they + do not cut off a given solution. +*/ + +#include + +#include "OsiCuts.hpp" +#include "OsiSolverInterface.hpp" + +/*! \brief Validate cuts against a known solution + + OsiRowCutDebugger provides a facility for validating cuts against a known + solution for a problem. The debugger knows an optimal solution for many of + the miplib3 problems. Check the source for + #activate(const OsiSolverInterface&,const char*) + in OsiRowCutDebugger.cpp for the full set of known problems. + + A full solution vector can be supplied as a parameter with + (#activate(const OsiSolverInterface&,const double*,bool)). + Only the integer values need to be valid. + The default behaviour is to solve an lp relaxation with the integer + variables fixed to the specified values and use the optimal solution to fill + in the continuous variables in the solution. + The debugger can be instructed to preserve the continuous variables (useful + when debugging solvers where the linear relaxation doesn't capture all the + constraints). + + Note that the solution must match the problem held in the solver interface. + If you want to use the row cut debugger on a problem after applying presolve + transformations, your solution must match the presolved problem. (But see + #redoSolution().) +*/ +class OsiRowCutDebugger { + friend void OsiRowCutDebuggerUnitTest(const OsiSolverInterface * siP, + const std::string & mpsDir); + +public: + + /*! @name Validate Row Cuts + + Check that the specified cuts do not cut off the known solution. + */ + //@{ + /*! \brief Check that the set of cuts does not cut off the solution known + to the debugger. + + Check if any generated cuts cut off the solution known to the debugger! + If so then print offending cuts. Return the number of invalid cuts. + */ + virtual int validateCuts(const OsiCuts & cs, int first, int last) const; + + /*! \brief Check that the cut does not cut off the solution known to the + debugger. + + Return true if cut is invalid + */ + virtual bool invalidCut(const OsiRowCut & rowcut) const; + + /*! \brief Returns true if the solution held in the solver is compatible + with the known solution. + + More specifically, returns true if the known solution satisfies the column + bounds held in the solver. + */ + bool onOptimalPath(const OsiSolverInterface &si) const; + //@} + + /*! @name Activate the Debugger + + The debugger is considered to be active when it holds a known solution. + */ + //@{ + /*! \brief Activate a debugger using the name of a problem. + + The debugger knows an optimal solution for most of miplib3. Check the + source code for the full list. Returns true if the debugger is + successfully activated. + */ + bool activate(const OsiSolverInterface &si, const char *model) ; + + /*! \brief Activate a debugger using a full solution array. + + The solution must have one entry for every variable, but only the entries + for integer values are used. By default the debugger will solve an lp + relaxation with the integer variables fixed and fill in values for the + continuous variables from this solution. If the debugger should preserve + the given values for the continuous variables, set \p keepContinuous to + \c true. + + Returns true if debugger activates successfully. + */ + bool activate(const OsiSolverInterface &si, const double* solution, + bool keepContinuous = false) ; + + /// Returns true if the debugger is active + bool active() const; + //@} + + /*! @name Query or Manipulate the Known Solution */ + //@{ + /// Return the known solution + inline const double * optimalSolution() const + { return knownSolution_;} + + /// Return the number of columns in the known solution + inline int numberColumns() const { return (numberColumns_) ; } + + /// Return the value of the objective for the known solution + inline double optimalValue() const { return knownValue_;} + + /*! \brief Edit the known solution to reflect column changes + + Given a translation array \p originalColumns[numberColumns] which can + translate current column indices to original column indices, this method + will edit the solution held in the debugger so that it matches the current + set of columns. + + Useful when the original problem is preprocessed prior to cut generation. + The debugger does keep a record of the changes. + */ + void redoSolution(int numberColumns, const int *originalColumns); + + /// Print optimal solution (returns -1 bad debug, 0 on optimal, 1 not) + int printOptimalSolution(const OsiSolverInterface & si) const; + //@} + + /**@name Constructors and Destructors */ + //@{ + /// Default constructor - no checking + OsiRowCutDebugger (); + + /*! \brief Constructor with name of model. + + See #activate(const OsiSolverInterface&,const char*). + */ + OsiRowCutDebugger(const OsiSolverInterface &si, const char *model) ; + + /*! \brief Constructor with full solution. + + See #activate(const OsiSolverInterface&,const double*,bool). + */ + OsiRowCutDebugger(const OsiSolverInterface &si, const double *solution, + bool enforceOptimality = false) ; + + /// Copy constructor + OsiRowCutDebugger(const OsiRowCutDebugger &); + + /// Assignment operator + OsiRowCutDebugger& operator=(const OsiRowCutDebugger& rhs); + + /// Destructor + virtual ~OsiRowCutDebugger (); + //@} + +private: + + // Private member data + + /**@name Private member data */ + //@{ + /// Value of known solution + double knownValue_; + + /*! \brief Number of columns in known solution + + This must match the number of columns reported by the solver. + */ + int numberColumns_; + + /// array specifying integer variables + bool * integerVariable_; + + /// array specifying known solution + double * knownSolution_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/OsiSolverBranch.hpp b/thirdparty/linux/include/coin/OsiSolverBranch.hpp new file mode 100644 index 0000000..98c4343 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiSolverBranch.hpp @@ -0,0 +1,152 @@ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverBranch_H +#define OsiSolverBranch_H + +class OsiSolverInterface; +#include "CoinWarmStartBasis.hpp" + +//############################################################################# + +/** Solver Branch Class + + This provides information on a branch as a set of tighter bounds on both ways +*/ + +class OsiSolverBranch { + +public: + ///@name Add and Get methods + //@{ + /// Add a simple branch (i.e. first sets ub of floor(value), second lb of ceil(value)) + void addBranch(int iColumn, double value); + + /// Add bounds - way =-1 is first , +1 is second + void addBranch(int way,int numberTighterLower, const int * whichLower, const double * newLower, + int numberTighterUpper, const int * whichUpper, const double * newUpper); + /// Add bounds - way =-1 is first , +1 is second + void addBranch(int way,int numberColumns,const double * oldLower, const double * newLower, + const double * oldUpper, const double * newUpper); + + /// Apply bounds + void applyBounds(OsiSolverInterface & solver,int way) const; + /// Returns true if current solution satsifies one side of branch + bool feasibleOneWay(const OsiSolverInterface & solver) const; + /// Starts + inline const int * starts() const + { return start_;} + /// Which variables + inline const int * which() const + { return indices_;} + /// Bounds + inline const double * bounds() const + { return bound_;} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverBranch(); + + /// Copy constructor + OsiSolverBranch(const OsiSolverBranch & rhs); + + /// Assignment operator + OsiSolverBranch & operator=(const OsiSolverBranch & rhs); + + /// Destructor + ~OsiSolverBranch (); + + //@} + +private: + ///@name Private member data + //@{ + /// Start of lower first, upper first, lower second, upper second + int start_[5]; + /// Column numbers (if >= numberColumns treat as rows) + int * indices_; + /// New bounds + double * bound_; + //@} +}; +//############################################################################# + +/** Solver Result Class + + This provides information on a result as a set of tighter bounds on both ways +*/ + +class OsiSolverResult { + +public: + ///@name Add and Get methods + //@{ + /// Create result + void createResult(const OsiSolverInterface & solver,const double * lowerBefore, + const double * upperBefore); + + /// Restore result + void restoreResult(OsiSolverInterface & solver) const; + + /// Get basis + inline const CoinWarmStartBasis & basis() const + { return basis_;} + + /// Objective value (as minimization) + inline double objectiveValue() const + { return objectiveValue_;} + + /// Primal solution + inline const double * primalSolution() const + { return primalSolution_;} + + /// Dual solution + inline const double * dualSolution() const + { return dualSolution_;} + + /// Extra fixed + inline const OsiSolverBranch & fixed() const + { return fixed_;} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverResult(); + + /// Constructor from solver + OsiSolverResult(const OsiSolverInterface & solver,const double * lowerBefore, + const double * upperBefore); + + /// Copy constructor + OsiSolverResult(const OsiSolverResult & rhs); + + /// Assignment operator + OsiSolverResult & operator=(const OsiSolverResult & rhs); + + /// Destructor + ~OsiSolverResult (); + + //@} + +private: + ///@name Private member data + //@{ + /// Value of objective (if >= OsiSolverInterface::getInfinity() then infeasible) + double objectiveValue_; + /// Warm start information + CoinWarmStartBasis basis_; + /// Primal solution (numberColumns) + double * primalSolution_; + /// Dual solution (numberRows) + double * dualSolution_; + /// Which extra variables have been fixed (only way==-1 counts) + OsiSolverBranch fixed_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/OsiSolverInterface.hpp b/thirdparty/linux/include/coin/OsiSolverInterface.hpp new file mode 100644 index 0000000..a581961 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiSolverInterface.hpp @@ -0,0 +1,2143 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverInterface_H +#define OsiSolverInterface_H + +#include +#include +#include + +#include "CoinTypes.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinPackedVectorBase.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinWarmStart.hpp" +#include "CoinFinite.hpp" +#include "CoinError.hpp" + +#include "OsiCollections.hpp" +#include "OsiSolverParameters.hpp" + +class CoinSnapshot; +class CoinLpIO; +class CoinMpsIO; + +class OsiCuts; +class OsiAuxInfo; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinSet; +class CoinBuild; +class CoinModel; +class OsiSolverBranch; +class OsiSolverResult; +class OsiObject; + + +//############################################################################# + +/*! \brief Abstract Base Class for describing an interface to a solver. + + Many OsiSolverInterface query methods return a const pointer to the + requested read-only data. If the model data is changed or the solver + is called, these pointers may no longer be valid and should be + refreshed by invoking the member function to obtain an updated copy + of the pointer. + For example: + \code + OsiSolverInterface solverInterfacePtr ; + const double * ruBnds = solverInterfacePtr->getRowUpper(); + solverInterfacePtr->applyCuts(someSetOfCuts); + // ruBnds is no longer a valid pointer and must be refreshed + ruBnds = solverInterfacePtr->getRowUpper(); + \endcode + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. +*/ + +class OsiSolverInterface { + friend void OsiSolverInterfaceCommonUnitTest( + const OsiSolverInterface* emptySi, + const std::string & mpsDir, + const std::string & netlibDir); + friend void OsiSolverInterfaceMpsUnitTest( + const std::vector & vecSiP, + const std::string & mpsDir); + +public: + + /// Internal class for obtaining status from the applyCuts method + class ApplyCutsReturnCode { + friend class OsiSolverInterface; + friend class OsiClpSolverInterface; + friend class OsiGrbSolverInterface; + + public: + ///@name Constructors and desctructors + //@{ + /// Default constructor + ApplyCutsReturnCode(): + intInconsistent_(0), + extInconsistent_(0), + infeasible_(0), + ineffective_(0), + applied_(0) {} + /// Copy constructor + ApplyCutsReturnCode(const ApplyCutsReturnCode & rhs): + intInconsistent_(rhs.intInconsistent_), + extInconsistent_(rhs.extInconsistent_), + infeasible_(rhs.infeasible_), + ineffective_(rhs.ineffective_), + applied_(rhs.applied_) {} + /// Assignment operator + ApplyCutsReturnCode & operator=(const ApplyCutsReturnCode& rhs) + { + if (this != &rhs) { + intInconsistent_ = rhs.intInconsistent_; + extInconsistent_ = rhs.extInconsistent_; + infeasible_ = rhs.infeasible_; + ineffective_ = rhs.ineffective_; + applied_ = rhs.applied_; + } + return *this; + } + /// Destructor + ~ApplyCutsReturnCode(){} + //@} + + /**@name Accessing return code attributes */ + //@{ + /// Number of logically inconsistent cuts + inline int getNumInconsistent() const + {return intInconsistent_;} + /// Number of cuts inconsistent with the current model + inline int getNumInconsistentWrtIntegerModel() const + {return extInconsistent_;} + /// Number of cuts that cause obvious infeasibility + inline int getNumInfeasible() const + {return infeasible_;} + /// Number of redundant or ineffective cuts + inline int getNumIneffective() const + {return ineffective_;} + /// Number of cuts applied + inline int getNumApplied() const + {return applied_;} + //@} + + private: + /**@name Private methods */ + //@{ + /// Increment logically inconsistent cut counter + inline void incrementInternallyInconsistent(){intInconsistent_++;} + /// Increment model-inconsistent counter + inline void incrementExternallyInconsistent(){extInconsistent_++;} + /// Increment infeasible cut counter + inline void incrementInfeasible(){infeasible_++;} + /// Increment ineffective cut counter + inline void incrementIneffective(){ineffective_++;} + /// Increment applied cut counter + inline void incrementApplied(){applied_++;} + //@} + + ///@name Private member data + //@{ + /// Counter for logically inconsistent cuts + int intInconsistent_; + /// Counter for model-inconsistent cuts + int extInconsistent_; + /// Counter for infeasible cuts + int infeasible_; + /// Counter for ineffective cuts + int ineffective_; + /// Counter for applied cuts + int applied_; + //@} + }; + + //--------------------------------------------------------------------------- + + ///@name Solve methods + //@{ + /// Solve initial LP relaxation + virtual void initialSolve() = 0; + + /*! \brief Resolve an LP relaxation after problem modification + + Note the `re-' in `resolve'. initialSolve() should be used to solve the + problem for the first time. + */ + virtual void resolve() = 0; + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound() = 0; + +#ifdef CBC_NEXT_VERSION + /* + Would it make sense to collect all of these routines in a `MIP Helper' + section? It'd make it easier for users and implementors to find them. + */ + /** + Solve 2**N (N==depth) problems and return solutions and bases. + There are N branches each of which changes bounds on both sides + as given by branch. The user should provide an array of (empty) + results which will be filled in. See OsiSolveResult for more details + (in OsiSolveBranch.?pp) but it will include a basis and primal solution. + + The order of results is left to right at feasible leaf nodes so first one + is down, down, ..... + + Returns number of feasible leaves. Also sets number of solves done and number + of iterations. + + This is provided so a solver can do faster. + + If forceBranch true then branch done even if satisfied + */ + virtual int solveBranches(int depth,const OsiSolverBranch * branch, + OsiSolverResult * result, + int & numberSolves, int & numberIterations, + bool forceBranch=false); +#endif + //@} + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. When a set method returns false, the original value (if + any) should be unchanged. There can be various reasons for failure: the + given parameter is not applicable for the solver (e.g., refactorization + frequency for the volume algorithm), the parameter is not yet + implemented for the solver or simply the value of the parameter is out + of the range the solver accepts. If a parameter setting call returns + false check the details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + + \note + There is a default implementation of the set/get + methods, namely to store/retrieve the given value using an array in the + base class. A specific solver implementation can use this feature, for + example, to store parameters that should be used later on. Implementors + of a solver interface should overload these functions to provide the + proper interface to and accurately reflect the capabilities of a + specific solver. + + The format for hints is slightly different in that a boolean specifies + the sense of the hint and an enum specifies the strength of the hint. + Hints should be initialised when a solver is instantiated. + (See OsiSolverParameters.hpp for defined hint parameters and strength.) + When specifying the sense of the hint, a value of true means to work with + the hint, false to work against it. For example, +
      +
    • \code setHintParam(OsiDoScale,true,OsiHintTry) \endcode + is a mild suggestion to the solver to scale the constraint + system. +
    • \code setHintParam(OsiDoScale,false,OsiForceDo) \endcode + tells the solver to disable scaling, or throw an exception if + it cannot comply. +
    + As another example, a solver interface could use the value and strength + of the \c OsiDoReducePrint hint to adjust the amount of information + printed by the interface and/or solver. The extent to which a solver + obeys hints is left to the solver. The value and strength returned by + \c getHintParam will match the most recent call to \c setHintParam, + and will not necessarily reflect the solver's ability to comply with the + hint. If the hint strength is \c OsiForceDo, the solver is required to + throw an exception if it cannot perform the specified action. + + \note + As with the other set/get methods, there is a default implementation + which maintains arrays in the base class for hint sense and strength. + The default implementation does not store the \c otherInformation + pointer, and always throws an exception for strength \c OsiForceDo. + Implementors of a solver interface should override these functions to + provide the proper interface to and accurately reflect the capabilities + of a specific solver. + */ + //@{ + //! Set an integer parameter + virtual bool setIntParam(OsiIntParam key, int value) { + if (key == OsiLastIntParam) return (false) ; + intParam_[key] = value; + return true; + } + //! Set a double parameter + virtual bool setDblParam(OsiDblParam key, double value) { + if (key == OsiLastDblParam) return (false) ; + dblParam_[key] = value; + return true; + } + //! Set a string parameter + virtual bool setStrParam(OsiStrParam key, const std::string & value) { + if (key == OsiLastStrParam) return (false) ; + strParam_[key] = value; + return true; + } + /*! \brief Set a hint parameter + + The \c otherInformation parameter can be used to pass in an arbitrary + block of information which is interpreted by the OSI and the underlying + solver. Users are cautioned that this hook is solver-specific. + + Implementors: + The default implementation completely ignores \c otherInformation and + always throws an exception for OsiForceDo. This is almost certainly not + the behaviour you want; you really should override this method. + */ + virtual bool setHintParam(OsiHintParam key, bool yesNo=true, + OsiHintStrength strength=OsiHintTry, + void * /*otherInformation*/ = NULL) { + if (key==OsiLastHintParam) + return false; + hintParam_[key] = yesNo; + hintStrength_[key] = strength; + if (strength == OsiForceDo) + throw CoinError("OsiForceDo illegal", + "setHintParam", "OsiSolverInterface"); + return true; + } + //! Get an integer parameter + virtual bool getIntParam(OsiIntParam key, int& value) const { + if (key == OsiLastIntParam) return (false) ; + value = intParam_[key]; + return true; + } + //! Get a double parameter + virtual bool getDblParam(OsiDblParam key, double& value) const { + if (key == OsiLastDblParam) return (false) ; + value = dblParam_[key]; + return true; + } + //! Get a string parameter + virtual bool getStrParam(OsiStrParam key, std::string& value) const { + if (key == OsiLastStrParam) return (false) ; + value = strParam_[key]; + return true; + } + /*! \brief Get a hint parameter (all information) + + Return all available information for the hint: sense, strength, + and any extra information associated with the hint. + + Implementors: The default implementation will always set + \c otherInformation to NULL. This is almost certainly not the + behaviour you want; you really should override this method. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength, + void *& otherInformation) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + strength = hintStrength_[key]; + otherInformation=NULL; + return true; + } + /*! \brief Get a hint parameter (sense and strength only) + + Return only the sense and strength of the hint. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + strength = hintStrength_[key]; + return true; + } + /*! \brief Get a hint parameter (sense only) + + Return only the sense (true/false) of the hint. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + return true; + } + /*! \brief Copy all parameters in this section from one solver to another + + Note that the current implementation also copies the appData block, + message handler, and rowCutDebugger. Arguably these should have + independent copy methods. + */ + void copyParameters(OsiSolverInterface & rhs); + + /** \brief Return the integrality tolerance of the underlying solver. + + We should be able to get an integrality tolerance, but + until that time just use the primal tolerance + + \todo + This method should be replaced; it's architecturally wrong. This + should be an honest dblParam with a keyword. Underlying solvers + that do not support integer variables should return false for set and + get on this parameter. Underlying solvers that support integrality + should add this to the parameters they support, using whatever + tolerance is appropriate. -lh, 091021- + */ + inline double getIntegerTolerance() const + { return dblParam_[OsiPrimalTolerance];} + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there numerical difficulties? + virtual bool isAbandoned() const = 0; + /// Is optimality proven? + virtual bool isProvenOptimal() const = 0; + /// Is primal infeasibility proven? + virtual bool isProvenPrimalInfeasible() const = 0; + /// Is dual infeasibility proven? + virtual bool isProvenDualInfeasible() const = 0; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const = 0; + //@} + + //--------------------------------------------------------------------------- + /** \name Warm start methods + + Note that the warm start methods return a generic CoinWarmStart object. + The precise characteristics of this object are solver-dependent. Clients + who wish to maintain a maximum degree of solver independence should take + care to avoid unnecessary assumptions about the properties of a warm start + object. + */ + //@{ + /*! \brief Get an empty warm start object + + This routine returns an empty warm start object. Its purpose is + to provide a way for a client to acquire a warm start object of the + appropriate type for the solver, which can then be resized and modified + as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const = 0 ; + + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. + */ + virtual CoinWarmStart* getWarmStart() const = 0; + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. This does not necessarily create an + object - may just point to one. must Delete set true if user + should delete returned object. + */ + virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ; + + /** \brief Set warm start information. + + Return true or false depending on whether the warm start information was + accepted or not. + By definition, a call to setWarmStart with a null parameter should + cause the solver interface to refresh its warm start information + from the underlying solver. + */ + virtual bool setWarmStart(const CoinWarmStart* warmstart) = 0; + //@} + + //--------------------------------------------------------------------------- + /**@name Hot start methods + + Primarily used in strong branching. The user can create a hot start + object --- a snapshot of the optimization process --- then reoptimize + over and over again, starting from the same point. + + \note +
      +
    • Between hot started optimizations only bound changes are allowed. +
    • The copy constructor and assignment operator should NOT copy any + hot start information. +
    • The default implementation simply extracts a warm start object in + \c markHotStart, resets to the warm start object in + \c solveFromHotStart, and deletes the warm start object in + \c unmarkHotStart. + Actual solver implementations are encouraged to do better. +
    + + */ + //@{ + /// Create a hot start snapshot of the optimization process. + virtual void markHotStart(); + /// Optimize starting from the hot start snapshot. + virtual void solveFromHotStart(); + /// Delete the hot start snapshot. + virtual void unmarkHotStart(); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem query methods + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from the + methods that return vectors. + + Const pointers returned from any data-query method are valid as long as + the data is unchanged and the solver is not called. + */ + //@{ + /// Get the number of columns + virtual int getNumCols() const = 0; + + /// Get the number of rows + virtual int getNumRows() const = 0; + + /// Get the number of nonzero elements + virtual int getNumElements() const = 0; + + /// Get the number of integer variables + virtual int getNumIntegers() const ; + + /// Get a pointer to an array[getNumCols()] of column lower bounds + virtual const double * getColLower() const = 0; + + /// Get a pointer to an array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row constraint senses. + +
      +
    • 'L': <= constraint +
    • 'E': = constraint +
    • 'G': >= constraint +
    • 'R': ranged constraint +
    • 'N': free constraint +
    + */ + virtual const char * getRowSense() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row right-hand sides + +
      +
    • if getRowSense()[i] == 'L' then + getRightHandSide()[i] == getRowUpper()[i] +
    • if getRowSense()[i] == 'G' then + getRightHandSide()[i] == getRowLower()[i] +
    • if getRowSense()[i] == 'R' then + getRightHandSide()[i] == getRowUpper()[i] +
    • if getRowSense()[i] == 'N' then + getRightHandSide()[i] == 0.0 +
    + */ + virtual const double * getRightHandSide() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row ranges. + +
      +
    • if getRowSense()[i] == 'R' then + getRowRange()[i] == getRowUpper()[i] - getRowLower()[i] +
    • if getRowSense()[i] != 'R' then + getRowRange()[i] is 0.0 +
    + */ + virtual const double * getRowRange() const = 0; + + /// Get a pointer to an array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const = 0; + + /// Get a pointer to an array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const = 0; + + /*! \brief Get a pointer to an array[getNumCols()] of objective + function coefficients. + */ + virtual const double * getObjCoefficients() const = 0; + + /*! \brief Get the objective function sense + + - 1 for minimisation (default) + - -1 for maximisation + */ + virtual double getObjSense() const = 0; + + /// Return true if the variable is continuous + virtual bool isContinuous(int colIndex) const = 0; + + /// Return true if the variable is binary + virtual bool isBinary(int colIndex) const; + + /*! \brief Return true if the variable is integer. + + This method returns true if the variable is binary or general integer. + */ + virtual bool isInteger(int colIndex) const; + + /// Return true if the variable is general integer + virtual bool isIntegerNonBinary(int colIndex) const; + + /// Return true if the variable is binary and not fixed + virtual bool isFreeBinary(int colIndex) const; + + /*! \brief Return an array[getNumCols()] of column types + + \deprecated See #getColType + */ + inline const char *columnType(bool refresh=false) const + { return getColType(refresh); } + + /*! \brief Return an array[getNumCols()] of column types + + - 0 - continuous + - 1 - binary + - 2 - general integer + + If \p refresh is true, the classification of integer variables as + binary or general integer will be reevaluated. If the current bounds + are [0,1], or if the variable is fixed at 0 or 1, it will be classified + as binary, otherwise it will be classified as general integer. + */ + virtual const char * getColType(bool refresh=false) const; + + /// Get a pointer to a row-wise copy of the matrix + virtual const CoinPackedMatrix * getMatrixByRow() const = 0; + + /// Get a pointer to a column-wise copy of the matrix + virtual const CoinPackedMatrix * getMatrixByCol() const = 0; + + /*! \brief Get a pointer to a mutable row-wise copy of the matrix. + + Returns NULL if the request is not meaningful (i.e., the OSI will not + recognise any modifications to the matrix). + */ + virtual CoinPackedMatrix * getMutableMatrixByRow() const {return NULL;} + + /*! \brief Get a pointer to a mutable column-wise copy of the matrix + + Returns NULL if the request is not meaningful (i.e., the OSI will not + recognise any modifications to the matrix). + */ + virtual CoinPackedMatrix * getMutableMatrixByCol() const {return NULL;} + + /// Get the solver's value for infinity + virtual double getInfinity() const = 0; + //@} + + /**@name Solution query methods */ + //@{ + /// Get a pointer to an array[getNumCols()] of primal variable values + virtual const double * getColSolution() const = 0; + + /** Get a pointer to an array[getNumCols()] of primal variable values + guaranteed to be between the column lower and upper bounds. + */ + virtual const double * getStrictColSolution(); + + /// Get pointer to array[getNumRows()] of dual variable values + virtual const double * getRowPrice() const = 0; + + /// Get a pointer to an array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const = 0; + + /** Get a pointer to array[getNumRows()] of row activity levels. + + The row activity for a row is the left-hand side evaluated at the + current solution. + */ + virtual const double * getRowActivity() const = 0; + + /// Get the objective function value. + virtual double getObjValue() const = 0; + + /** Get the number of iterations it took to solve the problem (whatever + `iteration' means to the solver). + */ + virtual int getIterationCount() const = 0; + + /** Get as many dual rays as the solver can provide. In case of proven + primal infeasibility there should (with high probability) be at least + one. + + The first getNumRows() ray components will always be associated with + the row duals (as returned by getRowPrice()). If \c fullRay is true, + the final getNumCols() entries will correspond to the ray components + associated with the nonbasic variables. If the full ray is requested + and the method cannot provide it, it will throw an exception. + + \note + Implementors of solver interfaces note that the double pointers in + the vector should point to arrays of length getNumRows() (fullRay = + false) or (getNumRows()+getNumCols()) (fullRay = true) and they should + be allocated with new[]. + + \note + Clients of solver interfaces note that it is the client's + responsibility to free the double pointers in the vector using + delete[]. Clients are reminded that a problem can be dual and primal + infeasible. + */ + virtual std::vector getDualRays(int maxNumRays, + bool fullRay = false) const = 0; + + /** Get as many primal rays as the solver can provide. In case of proven + dual infeasibility there should (with high probability) be at least + one. + + \note + Implementors of solver interfaces note that the double pointers in + the vector should point to arrays of length getNumCols() and they + should be allocated with new[]. + + \note + Clients of solver interfaces note that it is the client's + responsibility to free the double pointers in the vector using + delete[]. Clients are reminded that a problem can be dual and primal + infeasible. + */ + virtual std::vector getPrimalRays(int maxNumRays) const = 0; + + /** Get vector of indices of primal variables which are integer variables + but have fractional values in the current solution. */ + virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05) + const; + //@} + + //------------------------------------------------------------------------- + /**@name Methods to modify the objective, bounds, and solution + + For functions which take a set of indices as parameters + (\c setObjCoeffSet(), \c setColSetBounds(), \c setRowSetBounds(), + \c setRowSetTypes()), the parameters follow the C++ STL iterator + convention: \c indexFirst points to the first index in the + set, and \c indexLast points to a position one past the last index + in the set. + + */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ) = 0; + + /** Set a set of objective function coefficients */ + virtual void setObjCoeffSet(const int* indexFirst, + const int* indexLast, + const double* coeffList); + + /** Set the objective coefficients for all columns. + + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setObjective(const double * array); + + /** Set the objective function sense. + + Use 1 for minimisation (default), -1 for maximisation. + + \note + Implementors note that objective function sense is a parameter of + the OSI, not a property of the problem. Objective sense can be + set prior to problem load and should not be affected by loading a + new problem. + */ + virtual void setObjSense(double s) = 0; + + + /** Set a single column lower bound. + Use -getInfinity() for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ) = 0; + + /** Set the lower bounds for all columns. + + array [getNumCols()] is an array of values for the lower bounds. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColLower(const double * array); + + /** Set a single column upper bound. + Use getInfinity() for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ) = 0; + + /** Set the upper bounds for all columns. + + array [getNumCols()] is an array of values for the upper bounds. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColUpper(const double * array); + + + /** Set a single column lower and upper bound. + The default implementation just invokes setColLower() and + setColUpper() */ + virtual void setColBounds( int elementIndex, + double lower, double upper ) { + setColLower(elementIndex, lower); + setColUpper(elementIndex, upper); + } + + /** Set the upper and lower bounds of a set of columns. + + The default implementation just invokes setColBounds() over and over + again. For each column, boundList must contain both a lower and + upper bound, in that order. + */ + virtual void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single row lower bound. + Use -getInfinity() for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ) = 0; + + /** Set a single row upper bound. + Use getInfinity() for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ) = 0; + + /** Set a single row lower and upper bound. + The default implementation just invokes setRowLower() and + setRowUpper() */ + virtual void setRowBounds( int elementIndex, + double lower, double upper ) { + setRowLower(elementIndex, lower); + setRowUpper(elementIndex, upper); + } + + /** Set the bounds on a set of rows. + + The default implementation just invokes setRowBounds() over and over + again. For each row, boundList must contain both a lower and + upper bound, in that order. + */ + virtual void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + + /** Set the type of a single row */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range) = 0; + + /** Set the type of a set of rows. + The default implementation just invokes setRowType() + over and over again. + */ + virtual void setRowSetTypes(const int* indexFirst, + const int* indexLast, + const char* senseList, + const double* rhsList, + const double* rangeList); + + /** Set the primal solution variable values + + colsol[getNumCols()] is an array of values for the primal variables. + These values are copied to memory owned by the solver interface + object or the solver. They will be returned as the result of + getColSolution() until changed by another call to setColSolution() or + by a call to any solver routine. Whether the solver makes use of the + solution in any way is solver-dependent. + */ + virtual void setColSolution(const double *colsol) = 0; + + /** Set dual solution variable values + + rowprice[getNumRows()] is an array of values for the dual variables. + These values are copied to memory owned by the solver interface + object or the solver. They will be returned as the result of + getRowPrice() until changed by another call to setRowPrice() or by a + call to any solver routine. Whether the solver makes use of the + solution in any way is solver-dependent. + */ + virtual void setRowPrice(const double * rowprice) = 0; + + /** Fix variables at bound based on reduced cost + + For variables currently at bound, fix the variable at bound if the + reduced cost exceeds the gap. Return the number of variables fixed. + + If justInteger is set to false, the routine will also fix continuous + variables, but the test still assumes a delta of 1.0. + */ + virtual int reducedCostFix(double gap, bool justInteger=true); + //@} + + //------------------------------------------------------------------------- + /**@name Methods to set variable type */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index) = 0; + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index) = 0; + /** Set the variables listed in indices (which is of length len) to be + continuous variables */ + virtual void setContinuous(const int* indices, int len); + /** Set the variables listed in indices (which is of length len) to be + integer variables */ + virtual void setInteger(const int* indices, int len); + //@} + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + + /*! \brief Data type for name vectors. */ + typedef std::vector OsiNameVec ; + + /*! \name Methods for row and column names + + Osi defines three name management disciplines: `auto names' (0), `lazy + names' (1), and `full names' (2). See the description of + #OsiNameDiscipline for details. Changing the name discipline (via + setIntParam()) will not automatically add or remove name information, + but setting the discipline to auto will make existing information + inaccessible until the discipline is reset to lazy or full. + + By definition, a row index of getNumRows() (i.e., one larger than + the largest valid row index) refers to the objective function. + + OSI users and implementors: While the OSI base class can define an + interface and provide rudimentary support, use of names really depends + on support by the OsiXXX class to ensure that names are managed + correctly. If an OsiXXX class does not support names, it should return + false for calls to getIntParam() or setIntParam() that reference + OsiNameDiscipline. + */ + //@{ + + /*! \brief Generate a standard name of the form Rnnnnnnn or Cnnnnnnn + + Set \p rc to 'r' for a row name, 'c' for a column name. + The `nnnnnnn' part is generated from ndx and will contain 7 digits + by default, padded with zeros if necessary. As a special case, + ndx = getNumRows() is interpreted as a request for the name of the + objective function. OBJECTIVE is returned, truncated to digits+1 + characters to match the row and column names. + */ + virtual std::string dfltRowColName(char rc, + int ndx, unsigned digits = 7) const ; + + /*! \brief Return the name of the objective function */ + + virtual std::string getObjName (unsigned maxLen = static_cast(std::string::npos)) const ; + + /*! \brief Set the name of the objective function */ + + virtual inline void setObjName (std::string name) + { objName_ = name ; } + + /*! \brief Return the name of the row. + + The routine will always return some name, regardless of the name + discipline or the level of support by an OsiXXX derived class. Use + maxLen to limit the length. + */ + virtual std::string getRowName(int rowIndex, + unsigned maxLen = static_cast(std::string::npos)) const ; + + /*! \brief Return a pointer to a vector of row names + + If the name discipline (#OsiNameDiscipline) is auto, the return value + will be a vector of length zero. If the name discipline is lazy, the + vector will contain only names supplied by the client and will be no + larger than needed to hold those names; entries not supplied will be + null strings. In particular, the objective name is not + included in the vector for lazy names. If the name discipline is + full, the vector will have getNumRows() names, either supplied or + generated, plus one additional entry for the objective name. + */ + virtual const OsiNameVec &getRowNames() ; + + /*! \brief Set a row name + + Quietly does nothing if the name discipline (#OsiNameDiscipline) is + auto. Quietly fails if the row index is invalid. + */ + virtual void setRowName(int ndx, std::string name) ; + + /*! \brief Set multiple row names + + The run of len entries starting at srcNames[srcStart] are installed as + row names starting at row index tgtStart. The base class implementation + makes repeated calls to setRowName. + */ + virtual void setRowNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len row names starting at index tgtStart + + The specified row names are removed and the remaining row names are + copied down to close the gap. + */ + virtual void deleteRowNames(int tgtStart, int len) ; + + /*! \brief Return the name of the column + + The routine will always return some name, regardless of the name + discipline or the level of support by an OsiXXX derived class. Use + maxLen to limit the length. + */ + virtual std::string getColName(int colIndex, + unsigned maxLen = static_cast(std::string::npos)) const ; + + /*! \brief Return a pointer to a vector of column names + + If the name discipline (#OsiNameDiscipline) is auto, the return value + will be a vector of length zero. If the name discipline is lazy, the + vector will contain only names supplied by the client and will be no + larger than needed to hold those names; entries not supplied will be + null strings. If the name discipline is full, the vector will have + getNumCols() names, either supplied or generated. + */ + virtual const OsiNameVec &getColNames() ; + + /*! \brief Set a column name + + Quietly does nothing if the name discipline (#OsiNameDiscipline) is + auto. Quietly fails if the column index is invalid. + */ + virtual void setColName(int ndx, std::string name) ; + + /*! \brief Set multiple column names + + The run of len entries starting at srcNames[srcStart] are installed as + column names starting at column index tgtStart. The base class + implementation makes repeated calls to setColName. + */ + virtual void setColNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len column names starting at index tgtStart + + The specified column names are removed and the remaining column names + are copied down to close the gap. + */ + virtual void deleteColNames(int tgtStart, int len) ; + + + /*! \brief Set row and column names from a CoinMpsIO object. + + Also sets the name of the objective function. If the name discipline + is auto, you get what you asked for. This routine does not use + setRowName or setColName. + */ + void setRowColNames(const CoinMpsIO &mps) ; + + /*! \brief Set row and column names from a CoinModel object. + + If the name discipline is auto, you get what you asked for. + This routine does not use setRowName or setColName. + */ + void setRowColNames(CoinModel &mod) ; + + /*! \brief Set row and column names from a CoinLpIO object. + + Also sets the name of the objective function. If the name discipline is + auto, you get what you asked for. This routine does not use setRowName + or setColName. + */ + void setRowColNames(CoinLpIO &mod) ; + + //@} + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + /**@name Methods to modify the constraint system. + + Note that new columns are added as continuous variables. + */ + //@{ + + /** Add a column (primal variable) to the problem. */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj) = 0; + + /*! \brief Add a named column (primal variable) to the problem. + + The default implementation adds the column, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj, std::string name) ; + + /** Add a column (primal variable) to the problem. */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj) ; + + /*! \brief Add a named column (primal variable) to the problem. + + The default implementation adds the column, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj, std::string name) ; + + /** Add a set of columns (primal variables) to the problem. + + The default implementation simply makes repeated calls to + addCol(). + */ + virtual void addCols(const int numcols, + const CoinPackedVectorBase * const * cols, + const double* collb, const double* colub, + const double* obj); + + /** Add a set of columns (primal variables) to the problem. + + The default implementation simply makes repeated calls to + addCol(). + */ + virtual void addCols(const int numcols, const int* columnStarts, + const int* rows, const double* elements, + const double* collb, const double* colub, + const double* obj); + + /// Add columns using a CoinBuild object + void addCols(const CoinBuild & buildObject); + + /** Add columns from a model object. returns + -1 if object in bad state (i.e. has row information) + otherwise number of errors + modelObject non const as can be regularized as part of build + */ + int addCols(CoinModel & modelObject); + +#if 0 + /** */ + virtual void addCols(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj); +#endif + + /** \brief Remove a set of columns (primal variables) from the + problem. + + The solver interface for a basis-oriented solver will maintain valid + warm start information if all deleted variables are nonbasic. + */ + virtual void deleteCols(const int num, const int * colIndices) = 0; + + /*! \brief Add a row (constraint) to the problem. */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub) = 0; + + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub, + std::string name) ; + + /*! \brief Add a row (constraint) to the problem. */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng) = 0; + + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng, std::string name) ; + + /*! Add a row (constraint) to the problem. + + Converts to addRow(CoinPackedVectorBase&,const double,const double). + */ + virtual void addRow(int numberElements, + const int *columns, const double *element, + const double rowlb, const double rowub) ; + + /*! Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const double* rowlb, const double* rowub); + + /** Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, const int *rowStarts, + const int *columns, const double *element, + const double *rowlb, const double *rowub); + + /// Add rows using a CoinBuild object + void addRows(const CoinBuild &buildObject); + + /*! Add rows from a CoinModel object. + + Returns -1 if the object is in the wrong state (i.e., has + column-major information), otherwise the number of errors. + + The modelObject is not const as it can be regularized as part of + the build. + */ + int addRows(CoinModel &modelObject); + +#if 0 + /** */ + virtual void addRows(const CoinPackedMatrix& matrix, + const double* rowlb, const double* rowub); + /** */ + virtual void addRows(const CoinPackedMatrix& matrix, + const char* rowsen, const double* rowrhs, + const double* rowrng); +#endif + + /** \brief Delete a set of rows (constraints) from the problem. + + The solver interface for a basis-oriented solver will maintain valid + warm start information if all deleted rows are loose. + */ + virtual void deleteRows(const int num, const int * rowIndices) = 0; + + /** \brief Replace the constraint matrix + + I (JJF) am getting annoyed because I can't just replace a matrix. + The default behavior of this is do nothing so only use where that would + not matter, e.g. strengthening a matrix for MIP. + */ + virtual void replaceMatrixOptional(const CoinPackedMatrix & ) {} + + /** \brief Replace the constraint matrix + + And if it does matter (not used at present) + */ + virtual void replaceMatrix(const CoinPackedMatrix & ) {abort();} + + /** \brief Save a copy of the base model + + If solver wants it can save a copy of "base" (continuous) model here. + */ + virtual void saveBaseModel() {} + + /** \brief Reduce the constraint system to the specified number of + constraints. + + If solver wants it can restore a copy of "base" (continuous) model + here. + + \note + The name is somewhat misleading. Implementors should consider + the opportunity to optimise behaviour in the common case where + \p numberRows is exactly the number of original constraints. Do not, + however, neglect the possibility that \p numberRows does not equal + the number of original constraints. + */ + virtual void restoreBaseModel(int numberRows); + //----------------------------------------------------------------------- + /** Apply a collection of cuts. + + Only cuts which have an effectiveness >= effectivenessLb + are applied. +
      +
    • ReturnCode.getNumineffective() -- number of cuts which were + not applied because they had an + effectiveness < effectivenessLb +
    • ReturnCode.getNuminconsistent() -- number of invalid cuts +
    • ReturnCode.getNuminconsistentWrtIntegerModel() -- number of + cuts that are invalid with respect to this integer model +
    • ReturnCode.getNuminfeasible() -- number of cuts that would + make this integer model infeasible +
    • ReturnCode.getNumApplied() -- number of integer cuts which + were applied to the integer model +
    • cs.size() == getNumineffective() + + getNuminconsistent() + + getNuminconsistentWrtIntegerModel() + + getNuminfeasible() + + getNumApplied() +
    + */ + virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, + double effectivenessLb = 0.0); + + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + Would be even more efficient to pass an array of pointers. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + + /** Apply a collection of row cuts which are all effective. + This is passed in as an array of pointers. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); + + /// Deletes branching information before columns deleted + void deleteBranchingInfo(int numberDeleted, const int * which); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Methods for problem input and output */ + //@{ + /*! \brief Load in a problem by copying the arguments. The constraints on + the rows are given by lower and upper bounds. + + If a pointer is 0 then the following values are the default: +
      +
    • colub: all columns have upper bound infinity +
    • collb: all columns have lower bound 0 +
    • rowub: all rows have upper bound infinity +
    • rowlb: all rows have lower bound -infinity +
    • obj: all variables have 0 objective coefficient +
    + + Note that the default values for rowub and rowlb produce the + constraint -infty <= ax <= infty. This is probably not what you want. + */ + virtual void loadProblem (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) = 0; + + /*! \brief Load in a problem by assuming ownership of the arguments. + The constraints on the rows are given by lower and upper bounds. + + For default argument values see the matching loadProblem method. + + \warning + The arguments passed to this method will be freed using the + C++ delete and delete[] functions. + */ + virtual void assignProblem (CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub) = 0; + + /*! \brief Load in a problem by copying the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + If a pointer is 0 then the following values are the default: +
      +
    • colub: all columns have upper bound infinity +
    • collb: all columns have lower bound 0 +
    • obj: all variables have 0 objective coefficient +
    • rowsen: all rows are >= +
    • rowrhs: all right hand sides are 0 +
    • rowrng: 0 for the ranged rows +
    + + Note that the default values for rowsen, rowrhs, and rowrng produce the + constraint ax >= 0. + */ + virtual void loadProblem (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) = 0; + + /*! \brief Load in a problem by assuming ownership of the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + For default argument values see the matching loadProblem method. + + \warning + The arguments passed to this method will be freed using the + C++ delete and delete[] functions. + */ + virtual void assignProblem (CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng) = 0; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by lower and upper bounds. + + The matrix vectors must be gap-free. Note that start must + have numcols+1 entries so that the length of the last column + can be calculated as start[numcols]-start[numcols-1]. + + See the previous loadProblem method using rowlb and rowub for default + argument values. + */ + virtual void loadProblem (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) = 0; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by sense/rhs/range triplets. + + The matrix vectors must be gap-free. Note that start must + have numcols+1 entries so that the length of the last column + can be calculated as start[numcols]-start[numcols-1]. + + See the previous loadProblem method using sense/rhs/range for default + argument values. + */ + virtual void loadProblem (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) = 0; + + /*! \brief Load a model from a CoinModel object. Return the number of + errors encountered. + + The modelObject parameter cannot be const as it may be changed as part + of process. If keepSolution is true will try and keep warmStart. + */ + virtual int loadFromCoinModel (CoinModel & modelObject, + bool keepSolution=false); + + /*! \brief Read a problem in MPS format from the given filename. + + The default implementation uses CoinMpsIO::readMps() to read + the MPS file and returns the number of errors encountered. + */ + virtual int readMps (const char *filename, + const char *extension = "mps") ; + + /*! \brief Read a problem in MPS format from the given full filename. + + This uses CoinMpsIO::readMps() to read the MPS file and returns the + number of errors encountered. It also may return an array of set + information + */ + virtual int readMps (const char *filename, const char*extension, + int & numberSets, CoinSet ** & sets); + + /*! \brief Read a problem in GMPL format from the given filenames. + + The default implementation uses CoinMpsIO::readGMPL(). This capability + is available only if the third-party package Glpk is installed. + */ + virtual int readGMPL (const char *filename, const char *dataname=NULL); + + /*! \brief Write the problem in MPS format to the specified file. + + If objSense is non-zero, a value of -1.0 causes the problem to be + written with a maximization objective; +1.0 forces a minimization + objective. If objSense is zero, the choice is left to the implementation. + */ + virtual void writeMps (const char *filename, + const char *extension = "mps", + double objSense=0.0) const = 0; + + /*! \brief Write the problem in MPS format to the specified file with + more control over the output. + + Row and column names may be null. + formatType is +
      +
    • 0 - normal +
    • 1 - extra accuracy +
    • 2 - IEEE hex +
    + + Returns non-zero on I/O error + */ + int writeMpsNative (const char *filename, + const char ** rowNames, const char ** columnNames, + int formatType=0,int numberAcross=2, + double objSense=0.0, int numberSOS=0, + const CoinSet * setInfo=NULL) const ; + +/***********************************************************************/ +// Lp files + + /** Write the problem into an Lp file of the given filename with the + specified extension. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + + The written problem is always a minimization problem. + If the current problem is a maximization problem, the + intended objective function for the written problem is the current + objective function multiplied by -1. If the current problem is a + minimization problem, the intended objective function for the + written problem is the current objective function. + If objSense < 0, the intended objective function is multiplied by -1 + before writing the problem. It is left unchanged otherwise. + + Write objective function name and constraint names if useRowNames is + true. This version calls writeLpNative(). + */ + virtual void writeLp(const char *filename, + const char *extension = "lp", + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLp() with first parameter filename. + */ + virtual void writeLp(FILE *fp, + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + + /** Write the problem into an Lp file. Parameters are similar to + those of writeLp(), but in addition row names and column names + may be given. + + Parameter rowNames may be NULL, in which case default row names + are used. If rowNames is not NULL, it must have exactly one entry + per row in the problem and one additional + entry (rowNames[getNumRows()] with the objective function name. + These getNumRows()+1 entries must be distinct. If this is not the + case, default row names + are used. In addition, format restrictions are imposed on names + (see CoinLpIO::is_invalid_name() for details). + + Similar remarks can be made for the parameter columnNames which + must either be NULL or have exactly getNumCols() distinct entries. + + Write objective function name and constraint names if + useRowNames is true. */ + int writeLpNative(const char *filename, + char const * const * const rowNames, + char const * const * const columnNames, + const double epsilon = 1.0e-5, + const int numberAcross = 10, + const int decimals = 5, + const double objSense = 0.0, + const bool useRowNames = true) const; + + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLpNative() with first parameter filename. + */ + int writeLpNative(FILE *fp, + char const * const * const rowNames, + char const * const * const columnNames, + const double epsilon = 1.0e-5, + const int numberAcross = 10, + const int decimals = 5, + const double objSense = 0.0, + const bool useRowNames = true) const; + + /// Read file in LP format from file with name filename. + /// See class CoinLpIO for description of this format. + virtual int readLp(const char *filename, const double epsilon = 1e-5); + + /// Read file in LP format from the file pointed to by fp. + /// See class CoinLpIO for description of this format. + int readLp(FILE *fp, const double epsilon = 1e-5); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Miscellaneous */ + //@{ + /** Check two models against each other. Return nonzero if different. + Ignore names if that set. + (Note initial version does not check names) + May modify both models by cleaning up + */ + int differentModel(OsiSolverInterface & other, + bool ignoreNames=true); +#ifdef COIN_SNAPSHOT + /// Return a CoinSnapshot + virtual CoinSnapshot * snapshot(bool createArrays=true) const; +#endif +#ifdef COIN_FACTORIZATION_INFO + /// Return number of entries in L part of current factorization + virtual CoinBigIndex getSizeL() const; + /// Return number of entries in U part of current factorization + virtual CoinBigIndex getSizeU() const; +#endif + //@} + + //--------------------------------------------------------------------------- + + /**@name Setting/Accessing application data */ + //@{ + /** Set application data. + + This is a pointer that the application can store into and + retrieve from the solver interface. + This field is available for the application to optionally + define and use. + */ + void setApplicationData (void * appData); + /** Create a clone of an Auxiliary Information object. + The base class just stores an application data pointer + but can be more general. Application data pointer is + designed for one user while this can be extended to cope + with more general extensions. + */ + void setAuxiliaryInfo(OsiAuxInfo * auxiliaryInfo); + + /// Get application data + void * getApplicationData() const; + /// Get pointer to auxiliary info object + OsiAuxInfo * getAuxiliaryInfo() const; + //@} + //--------------------------------------------------------------------------- + + /**@name Message handling + + See the COIN library documentation for additional information about + COIN message facilities. + + */ + //@{ + /** Pass in a message handler + + It is the client's responsibility to destroy a message handler installed + by this routine; it will not be destroyed when the solver interface is + destroyed. + */ + virtual void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + /// Return a pointer to the current message handler + inline CoinMessageHandler * messageHandler() const + {return handler_;} + /// Return the current set of messages + inline CoinMessages messages() + {return messages_;} + /// Return a pointer to the current set of messages + inline CoinMessages * messagesPointer() + {return &messages_;} + /// Return true if default handler + inline bool defaultHandler() const + { return defaultHandler_;} + //@} + //--------------------------------------------------------------------------- + /**@name Methods for dealing with discontinuities other than integers. + + Osi should be able to know about SOS and other types. This is an optional + section where such information can be stored. + + */ + //@{ + /** \brief Identify integer variables and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If justCount then no objects created and we just store numberIntegers_ + */ + + void findIntegers(bool justCount); + /** \brief Identify integer variables and SOS and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If the solver supports SOS then do the same for SOS. + + If justCount then no objects created and we just store numberIntegers_ + Returns number of SOS + */ + + virtual int findIntegersAndSOS(bool justCount); + /// Get the number of objects + inline int numberObjects() const { return numberObjects_;} + /// Set the number of objects + inline void setNumberObjects(int number) + { numberObjects_=number;} + + /// Get the array of objects + inline OsiObject ** objects() const { return object_;} + + /// Get the specified object + const inline OsiObject * object(int which) const { return object_[which];} + /// Get the specified object + inline OsiObject * modifiableObject(int which) const { return object_[which];} + + /// Delete all object information + void deleteObjects(); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, OsiObject ** objects); + /** Use current solution to set bounds so current integer feasible solution will stay feasible. + Only feasible bounds will be used, even if current solution outside bounds. The amount of + such violation will be returned (and if small can be ignored) + */ + double forceFeasible(); + //@} + //--------------------------------------------------------------------------- + + /*! @name Methods related to testing generated cuts + + See the documentation for OsiRowCutDebugger for additional details. + */ + //@{ + /*! \brief Activate the row cut debugger. + + If \p modelName is in the set of known models then all cuts are + checked to see that they do NOT cut off the optimal solution known + to the debugger. + */ + virtual void activateRowCutDebugger (const char *modelName); + + /*! \brief Activate the row cut debugger using a full solution array. + + + Activate the debugger for a model not included in the debugger's + internal database. Cuts will be checked to see that they do NOT + cut off the given solution. + + \p solution must be a full solution vector, but only the integer + variables need to be correct. The debugger will fill in the continuous + variables by solving an lp relaxation with the integer variables + fixed as specified. If the given values for the continuous variables + should be preserved, set \p keepContinuous to true. + */ + virtual void activateRowCutDebugger(const double *solution, + bool enforceOptimality = true); + + /*! \brief Get the row cut debugger provided the solution known to the + debugger is within the feasible region held in the solver. + + If there is a row cut debugger object associated with model AND if + the solution known to the debugger is within the solver's current + feasible region (i.e., the column bounds held in the solver are + compatible with the known solution) then a pointer to the debugger + is returned which may be used to test validity of cuts. + + Otherwise NULL is returned + */ + const OsiRowCutDebugger *getRowCutDebugger() const; + + /*! \brief Get the row cut debugger object + + Return the row cut debugger object if it exists. One common usage of + this method is to obtain a debugger object in order to execute + OsiRowCutDebugger::redoSolution (so that the stored solution is again + compatible with the problem held in the solver). + */ + OsiRowCutDebugger * getRowCutDebuggerAlways() const; + //@} + + /*! \name OsiSimplexInterface + \brief Simplex Interface + + Methods for an advanced interface to a simplex solver. The interface + comprises two groups of methods. Group 1 contains methods for tableau + access. Group 2 contains methods for dictating individual simplex pivots. + */ + //@{ + + /*! \brief Return the simplex implementation level. + + The return codes are: + - 0: the simplex interface is not implemented. + - 1: the Group 1 (tableau access) methods are implemented. + - 2: the Group 2 (pivoting) methods are implemented + + The codes are cumulative - a solver which implements Group 2 also + implements Group 1. + */ + virtual int canDoSimplexInterface() const ; + //@} + + /*! \name OsiSimplex Group 1 + \brief Tableau access methods. + + This group of methods provides access to rows and columns of the basis + inverse and to rows and columns of the tableau. + */ + //@{ + + /*! \brief Prepare the solver for the use of tableau access methods. + + Prepares the solver for the use of the tableau access methods, if + any such preparation is required. + + The \c const attribute is required due to the places this method + may be called (e.g., within CglCutGenerator::generateCuts()). + */ + virtual void enableFactorization() const ; + + /*! \brief Undo the effects of #enableFactorization. */ + virtual void disableFactorization() const ; + + /*! \brief Check if an optimal basis is available. + + Returns true if the problem has been solved to optimality and a + basis is available. This should be used to see if the tableau access + operations are possible and meaningful. + + \note + Implementors please note that this method may be called + before #enableFactorization. + */ + virtual bool basisIsAvailable() const ; + + /// Synonym for #basisIsAvailable + inline bool optimalBasisIsAvailable() const { return basisIsAvailable() ; } + + /*! \brief Retrieve status information for column and row variables. + + This method returns status as integer codes: +
      +
    • 0: free +
    • 1: basic +
    • 2: nonbasic at upper bound +
    • 3: nonbasic at lower bound +
    + + The #getWarmStart method provides essentially the same functionality + for a simplex-oriented solver, but the implementation details are very + different. + + \note + Logical variables associated with rows are all assumed to have +1 + coefficients, so for a <= constraint the logical will be at lower + bound if the constraint is tight. + + \note + Implementors may choose to implement this method as a wrapper which + converts a CoinWarmStartBasis to the requested representation. + */ + virtual void getBasisStatus(int* cstat, int* rstat) const ; + + /*! \brief Set the status of column and row variables and update + the basis factorization and solution. + + Status information should be coded as documented for #getBasisStatus. + Returns 0 if all goes well, 1 if something goes wrong. + + This method differs from #setWarmStart in the format of the input + and in its immediate effect. Think of it as #setWarmStart immediately + followed by #resolve, but no pivots are allowed. + + \note + Implementors may choose to implement this method as a wrapper that calls + #setWarmStart and #resolve if the no pivot requirement can be satisfied. + */ + virtual int setBasisStatus(const int* cstat, const int* rstat) ; + + /*! \brief Calculate duals and reduced costs for the given objective + coefficients. + + The solver's objective coefficient vector is not changed. + */ + virtual void getReducedGradient(double* columnReducedCosts, + double* duals, const double* c) const ; + + /*! \brief Get a row of the tableau + + If \p slack is not null, it will be loaded with the coefficients for + the artificial (logical) variables (i.e., the row of the basis inverse). + */ + virtual void getBInvARow(int row, double* z, double* slack = NULL) const ; + + /*! \brief Get a row of the basis inverse */ + virtual void getBInvRow(int row, double* z) const ; + + /*! \brief Get a column of the tableau */ + virtual void getBInvACol(int col, double* vec) const ; + + /*! \brief Get a column of the basis inverse */ + virtual void getBInvCol(int col, double* vec) const ; + + /*! \brief Get indices of basic variables + + If the logical (artificial) for row i is basic, the index should be coded + as (#getNumCols + i). + The order of indices must match the order of elements in the vectors + returned by #getBInvACol and #getBInvCol. + */ + virtual void getBasics(int* index) const ; + + //@} + + /*! \name OsiSimplex Group 2 + \brief Pivoting methods + + This group of methods provides for control of individual pivots by a + simplex solver. + */ + //@{ + + /**Enables normal operation of subsequent functions. + This method is supposed to ensure that all typical things (like + reduced costs, etc.) are updated when individual pivots are executed + and can be queried by other methods. says whether will be + doing primal or dual + */ + virtual void enableSimplexInterface(bool doingPrimal) ; + + ///Undo whatever setting changes the above method had to make + virtual void disableSimplexInterface() ; + /** Perform a pivot by substituting a colIn for colOut in the basis. + The status of the leaving variable is given in outStatus. Where + 1 is to upper bound, -1 to lower bound + Return code was undefined - now for OsiClp is 0 for okay, + 1 if inaccuracy forced re-factorization (should be okay) and + -1 for singular factorization + */ + virtual int pivot(int colIn, int colOut, int outStatus) ; + + /** Obtain a result of the primal pivot + Outputs: colOut -- leaving column, outStatus -- its status, + t -- step size, and, if dx!=NULL, *dx -- primal ray direction. + Inputs: colIn -- entering column, sign -- direction of its change (+/-1). + Both for colIn and colOut, artificial variables are index by + the negative of the row index minus 1. + Return code (for now): 0 -- leaving variable found, + -1 -- everything else? + Clearly, more informative set of return values is required + Primal and dual solutions are updated + */ + virtual int primalPivotResult(int colIn, int sign, + int& colOut, int& outStatus, + double& t, CoinPackedVector* dx); + + /** Obtain a result of the dual pivot (similar to the previous method) + Differences: entering variable and a sign of its change are now + the outputs, the leaving variable and its statuts -- the inputs + If dx!=NULL, then *dx contains dual ray + Return code: same + */ + virtual int dualPivotResult(int& colIn, int& sign, + int colOut, int outStatus, + double& t, CoinPackedVector* dx) ; + //@} + + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverInterface(); + + /** Clone + + The result of calling clone(false) is defined to be equivalent to + calling the default constructor OsiSolverInterface(). + */ + virtual OsiSolverInterface * clone(bool copyData = true) const = 0; + + /// Copy constructor + OsiSolverInterface(const OsiSolverInterface &); + + /// Assignment operator + OsiSolverInterface & operator=(const OsiSolverInterface& rhs); + + /// Destructor + virtual ~OsiSolverInterface (); + + /** Reset the solver interface. + + A call to reset() returns the solver interface to the same state as + it would have if it had just been constructed by calling the default + constructor OsiSolverInterface(). + */ + virtual void reset(); + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to the constraint matrix). */ + virtual void applyRowCut( const OsiRowCut & rc ) = 0; + + /** Apply a column cut (adjust the bounds of one or more variables). */ + virtual void applyColCut( const OsiColCut & cc ) = 0; + + /** A quick inlined function to convert from the lb/ub style of + constraint definition to the sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + /** A quick inlined function to convert from the sense/rhs/range style + of constraint definition to the lb/ub style */ + inline void + convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const; + /** A quick inlined function to force a value to be between a minimum and + a maximum value */ + template inline T + forceIntoRange(const T value, const T lower, const T upper) const { + return value < lower ? lower : (value > upper ? upper : value); + } + /** Set OsiSolverInterface object state for default constructor + + This routine establishes the initial values of data fields in the + OsiSolverInterface object when the object is created using the + default constructor. + */ + void setInitialData(); + //@} + + ///@name Protected member data + //@{ + /*! \brief Pointer to row cut debugger object + + Mutable so that we can update the solution held in the debugger while + maintaining const'ness for the Osi object. + */ + mutable OsiRowCutDebugger * rowCutDebugger_; + // Why not just make useful stuff protected? + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the currrent handler is the default handler. + Indicates if the solver interface object is responsible + for destruction of the handler (true) or if the client is + responsible (false). + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + /// Number of integers + int numberIntegers_; + /// Total number of objects + int numberObjects_; + + /// Integer and ... information (integer info normally at beginning) + OsiObject ** object_; + /** Column type + 0 - continuous + 1 - binary (may get fixed later) + 2 - general integer (may get fixed later) + */ + mutable char * columnType_; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + /// Pointer to user-defined data structure - and more if user wants + OsiAuxInfo * appDataEtc_; + /// Array of integer parameters + int intParam_[OsiLastIntParam]; + /// Array of double parameters + double dblParam_[OsiLastDblParam]; + /// Array of string parameters + std::string strParam_[OsiLastStrParam]; + /// Array of hint parameters + bool hintParam_[OsiLastHintParam]; + /// Array of hint strengths + OsiHintStrength hintStrength_[OsiLastHintParam]; + /** Warm start information used for hot starts when the default + hot start implementation is used. */ + CoinWarmStart* ws_; + /// Column solution satisfying lower and upper column bounds + std::vector strictColSolution_; + + /// Row names + OsiNameVec rowNames_ ; + /// Column names + OsiNameVec colNames_ ; + /// Objective name + std::string objName_ ; + + //@} +}; + +//############################################################################# +/** A quick inlined function to convert from the lb/ub style of constraint + definition to the sense/rhs/range style */ +inline void +OsiSolverInterface::convertBoundToSense(const double lower, const double upper, + char& sense, double& right, + double& range) const +{ + double inf = getInfinity(); + range = 0.0; + if (lower > -inf) { + if (upper < inf) { + right = upper; + if (upper==lower) { + sense = 'E'; + } else { + sense = 'R'; + range = upper - lower; + } + } else { + sense = 'G'; + right = lower; + } + } else { + if (upper < inf) { + sense = 'L'; + right = upper; + } else { + sense = 'N'; + right = 0.0; + } + } +} + +//----------------------------------------------------------------------------- +/** A quick inlined function to convert from the sense/rhs/range style of + constraint definition to the lb/ub style */ +inline void +OsiSolverInterface::convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const +{ + double inf=getInfinity(); + switch (sense) { + case 'E': + lower = upper = right; + break; + case 'L': + lower = -inf; + upper = right; + break; + case 'G': + lower = right; + upper = inf; + break; + case 'R': + lower = right - range; + upper = right; + break; + case 'N': + lower = -inf; + upper = inf; + break; + } +} + +#endif diff --git a/thirdparty/linux/include/coin/OsiSolverParameters.hpp b/thirdparty/linux/include/coin/OsiSolverParameters.hpp new file mode 100644 index 0000000..5f607f5 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiSolverParameters.hpp @@ -0,0 +1,142 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverParameters_H +#define OsiSolverParameters_H + +enum OsiIntParam { + /*! \brief Iteration limit for initial solve and resolve. + + The maximum number of iterations (whatever that means for the given + solver) the solver can execute in the OsiSolverinterface::initialSolve() + and OsiSolverinterface::resolve() methods before terminating. + */ + OsiMaxNumIteration = 0, + /*! \brief Iteration limit for hot start + + The maximum number of iterations (whatever that means for the given + solver) the solver can execute in the + OsiSolverinterface::solveFromHotStart() method before terminating. + */ + OsiMaxNumIterationHotStart, + /*! \brief Handling of row and column names. + + The name discipline specifies how the solver will handle row and column + names: + - 0: Auto names: Names cannot be set by the client. Names of the form + Rnnnnnnn or Cnnnnnnn are generated on demand when a name for a + specific row or column is requested; nnnnnnn is derived from the row + or column index. Requests for a vector of names return a vector with + zero entries. + - 1: Lazy names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to the largest index of a name supplied by the client; + some entries in the vector may be null strings. + - 2: Full names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to match the constraint system, and all entries will + contain either the name specified by the client or a generated name. + */ + OsiNameDiscipline, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + integer parameters. + */ + OsiLastIntParam +} ; + +enum OsiDblParam { + /*! \brief Dual objective limit. + + This is to be used as a termination criteria in algorithms where the dual + objective changes monotonically (e.g., dual simplex, volume algorithm). + */ + OsiDualObjectiveLimit = 0, + /*! \brief Primal objective limit. + + This is to be used as a termination criteria in algorithms where the + primal objective changes monotonically (e.g., primal simplex) + */ + OsiPrimalObjectiveLimit, + /*! \brief Dual feasibility tolerance. + + The maximum amount a dual constraint can be violated and still be + considered feasible. + */ + OsiDualTolerance, + /*! \brief Primal feasibility tolerance. + + The maximum amount a primal constraint can be violated and still be + considered feasible. + */ + OsiPrimalTolerance, + /** The value of any constant term in the objective function. */ + OsiObjOffset, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + double parameters. + */ + OsiLastDblParam +}; + + +enum OsiStrParam { + /*! \brief The name of the loaded problem. + + This is the string specified on the Name card of an mps file. + */ + OsiProbName = 0, + /*! \brief The name of the solver. + + This parameter is read-only. + */ + OsiSolverName, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + string parameters. + */ + OsiLastStrParam +}; + +enum OsiHintParam { + /** Whether to do a presolve in initialSolve */ + OsiDoPresolveInInitial = 0, + /** Whether to use a dual algorithm in initialSolve. + The reverse is to use a primal algorithm */ + OsiDoDualInInitial, + /** Whether to do a presolve in resolve */ + OsiDoPresolveInResolve, + /** Whether to use a dual algorithm in resolve. + The reverse is to use a primal algorithm */ + OsiDoDualInResolve, + /** Whether to scale problem */ + OsiDoScale, + /** Whether to create a non-slack basis (only in initialSolve) */ + OsiDoCrash, + /** Whether to reduce amount of printout, e.g., for branch and cut */ + OsiDoReducePrint, + /** Whether we are in branch and cut - so can modify behavior */ + OsiDoInBranchAndCut, + /** Just a marker, so that OsiSolverInterface can allocate a static sized + array to store parameters. */ + OsiLastHintParam +}; + +enum OsiHintStrength { + /** Ignore hint (default) */ + OsiHintIgnore = 0, + /** This means it is only a hint */ + OsiHintTry, + /** This means do hint if at all possible */ + OsiHintDo, + /** And this means throw an exception if not possible */ + OsiForceDo +}; + +#endif diff --git a/thirdparty/linux/include/coin/OsiUnitTests.hpp b/thirdparty/linux/include/coin/OsiUnitTests.hpp new file mode 100644 index 0000000..fbb4fc1 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiUnitTests.hpp @@ -0,0 +1,374 @@ +// Copyright (C) 2010 +// All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/*! \file OsiUnitTests.hpp + + Utility methods for OSI unit tests. +*/ + +#ifndef OSISOLVERINTERFACETEST_HPP_ +#define OSISOLVERINTERFACETEST_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include + +class OsiSolverInterface; +class CoinPackedVectorBase; + +/** A function that tests that a lot of problems given in MPS files (mostly the NETLIB problems) solve properly with all the specified solvers. + * + * The routine creates a vector of NetLib problems (problem name, objective, + * various other characteristics), and a vector of solvers to be tested. + * + * Each solver is run on each problem. The run is deemed successful if the + * solver reports the correct problem size after loading and returns the + * correct objective value after optimization. + + * If multiple solvers are available, the results are compared pairwise against + * the results reported by adjacent solvers in the solver vector. Due to + * limitations of the volume solver, it must be the last solver in vecEmptySiP. + */ +void OsiSolverInterfaceMpsUnitTest + (const std::vector & vecEmptySiP, + const std::string& mpsDir); + +/** A function that tests the methods in the OsiSolverInterface class. + * Some time ago, if this method is compiled with optimization, + * the compilation took 10-15 minutes and the machine pages (has 256M core memory!)... + */ +void OsiSolverInterfaceCommonUnitTest + (const OsiSolverInterface* emptySi, + const std::string& mpsDir, + const std::string& netlibDir); + +/** A function that tests the methods in the OsiColCut class. */ +void OsiColCutUnitTest + (const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiRowCut class. */ +void OsiRowCutUnitTest + (const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiRowCutDebugger class. */ +void OsiRowCutDebuggerUnitTest + (const OsiSolverInterface * siP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiCuts class. */ +void OsiCutsUnitTest(); + +/// A namespace so we can define a few `global' variables to use during tests. +namespace OsiUnitTest { + +class TestOutcomes; + +/*! \brief Verbosity level of unit tests + + 0 (default) for minimal output; larger numbers produce more output +*/ +extern unsigned int verbosity; + +/*! \brief Behaviour on failing a test + + - 0 (= default) continue + - 1 press any key to continue + - 2 stop with abort() +*/ +extern unsigned int haltonerror; + +/*! \brief Test outcomes + + A global TestOutcomes object to store test outcomes during the run of the unit test + for an OSI. + */ +extern TestOutcomes outcomes; + +/*! \brief Print an error message + + Formatted as "XxxSolverInterface testing issue: message" where Xxx is the string + provided as \p solverName. + + Flushes std::cout before printing to std::cerr. +*/ +void failureMessage(const std::string &solverName, + const std::string &message) ; +/// \overload +void failureMessage(const OsiSolverInterface &si, + const std::string &message) ; + +/*! \brief Print an error message, specifying the test name and condition + + Formatted as "XxxSolverInterface testing issue: testname failed: testcond" where + Xxx is the OsiStrParam::OsiSolverName parameter of the \p si. + Flushes std::cout before printing to std::cerr. +*/ +void failureMessage(const std::string &solverName, + const std::string &testname, const std::string &testcond) ; + +/// \overload +void failureMessage(const OsiSolverInterface &si, + const std::string &testname, const std::string &testcond) ; + +/*! \brief Print a message. + + Prints the message as given. Flushes std::cout before printing to std::cerr. +*/ +void testingMessage(const char *const msg) ; + +/*! \brief Utility method to check equality + + Tests for equality using CoinRelFltEq with tolerance \p tol. Understands the + notion of solver infinity and obtains the value for infinity from the solver + interfaces supplied as parameters. +*/ +bool equivalentVectors(const OsiSolverInterface * si1, + const OsiSolverInterface * si2, + double tol, const double * v1, const double * v2, int size) ; + +/*! \brief Compare two problems for equality + + Compares the problems held in the two solvers: constraint matrix, row and column + bounds, column type, and objective. Rows are checked using upper and lower bounds + and using sense, bound, and range. +*/ +bool compareProblems(OsiSolverInterface *osi1, OsiSolverInterface *osi2) ; + +/*! \brief Compare a packed vector with an expanded vector + + Checks that all values present in the packed vector are present in the full vector + and checks that there are no extra entries in the full vector. Uses CoinRelFltEq + with the default tolerance. +*/ +bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv) ; + +/*! \brief Process command line parameters. + + An unrecognised keyword which is not in the \p ignorekeywords map will trigger the + help message and a return value of false. For each keyword in \p ignorekeywords, you + can specify the number of following parameters that should be ignored. + + This should be replaced with the one of the standard CoinUtils parameter mechanisms. + */ +bool processParameters (int argc, const char **argv, + std::map& parms, + const std::map& ignorekeywords = std::map()); + +/// A single test outcome record. +class TestOutcome { + public: + /// Test result + typedef enum { + NOTE = 0, + PASSED = 1, + WARNING = 2, + ERROR = 3, + LAST = 4 + } SeverityLevel; + /// Print strings for SeverityLevel + static std::string SeverityLevelName[LAST]; + /// Name of component under test + std::string component; + /// Name of test + std::string testname; + /// Condition being tested + std::string testcond; + /// Test result + SeverityLevel severity; + /// Set to true if problem is expected + bool expected; + /// Name of code file where test executed + std::string filename; + /// Line number in code file where test executed + int linenumber; + /// Standard constructor + TestOutcome(const std::string& comp, const std::string& tst, + const char* cond, SeverityLevel sev, + const char* file, int line, bool exp = false) + : component(comp),testname(tst),testcond(cond),severity(sev), + expected(exp),filename(file),linenumber(line) + { } + /// Print the test outcome + void print() const; +}; + +/// Utility class to maintain a list of test outcomes. +class TestOutcomes : public std::list { + public: + /// Add an outcome to the list + void add(std::string comp, std::string tst, const char* cond, + TestOutcome::SeverityLevel sev, const char* file, int line, + bool exp = false) + { push_back(TestOutcome(comp,tst,cond,sev,file,line,exp)); } + + /*! \brief Add an outcome to the list + + Get the component name from the solver interface. + */ + void add(const OsiSolverInterface& si, std::string tst, const char* cond, + TestOutcome::SeverityLevel sev, const char* file, int line, + bool exp = false); + /// Print the list of outcomes + void print() const; + /*! \brief Count total and expected outcomes at given severity level + + Given a severity level, walk the list of outcomes and count the total number + of outcomes at this severity level and the number expected. + */ + void getCountBySeverity(TestOutcome::SeverityLevel sev, + int& total, int& expected) const; +}; + +/// Convert parameter to a string (stringification) +#define OSIUNITTEST_QUOTEME_(x) #x +/// Convert to string with one level of expansion of the parameter +#define OSIUNITTEST_QUOTEME(x) OSIUNITTEST_QUOTEME_(x) + +template +bool OsiUnitTestAssertSeverityExpected( + bool condition, const char * condition_str, const char *filename, + int line, const Component& component, const std::string& testname, + TestOutcome::SeverityLevel severity, bool expected) +{ + if (condition) { + OsiUnitTest::outcomes.add(component, testname, condition_str, + OsiUnitTest::TestOutcome::PASSED, filename, line, false); + if (OsiUnitTest::verbosity >= 2) { + std::ostringstream successmsg; + successmsg << __FILE__ << ":" << __LINE__ << ": " << testname + << " (condition \'" << condition_str << "\') passed.\n"; + OsiUnitTest::testingMessage(successmsg.str().c_str()); + } + return true; + } + OsiUnitTest::outcomes.add(component, testname, condition_str, + severity, filename, line, expected); + OsiUnitTest::failureMessage(component, testname, condition_str); + switch (OsiUnitTest::haltonerror) { + case 2: + { if (severity >= OsiUnitTest::TestOutcome::ERROR ) std::abort(); break; } + case 1: + { std::cout << std::endl << "press any key to continue..." << std::endl; + std::getchar(); + break ; } + default: ; + } + return false; +} + +/// Add a test outcome to the list held in OsiUnitTest::outcomes +#define OSIUNITTEST_ADD_OUTCOME(component,testname,testcondition,severity,expected) \ + OsiUnitTest::outcomes.add(component,testname,testcondition,severity,\ + __FILE__,__LINE__,expected) +/*! \brief Test for a condition and record the result + + Test \p condition and record the result in OsiUnitTest::outcomes. + If it succeeds, record the result as OsiUnitTest::TestOutcome::PASSED and print + a message for OsiUnitTest::verbosity >= 2. + If it fails, record the test as failed with \p severity and \p expected and + react as specified by OsiUnitTest::haltonerror. + + \p failurecode is executed when failure is not fatal. +*/ +#define OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,\ + testname, severity, expected) \ +{ \ + if (!OsiUnitTestAssertSeverityExpected(condition, #condition, \ + __FILE__, __LINE__, component, testname, severity, expected)) { \ + failurecode; \ + } \ +} + +/*! \brief Perform a test with severity OsiUnitTest::TestOutcome::ERROR, failure not + expected. +*/ +#define OSIUNITTEST_ASSERT_ERROR(condition, failurecode, component, testname) \ + OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\ + OsiUnitTest::TestOutcome::ERROR,false) + +/*! \brief Perform a test with severity OsiUnitTest::TestOutcome::WARNING, failure + not expected. +*/ +#define OSIUNITTEST_ASSERT_WARNING(condition, failurecode, component, testname) \ + OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\ + OsiUnitTest::TestOutcome::WARNING,false) + +/*! \brief Perform a test surrounded by a try/catch block + + \p trycode is executed in a try/catch block; if there's no throw the test is deemed + to have succeeded and is recorded in OsiUnitTest::outcomes with status + OsiUnitTest::TestOutcome::PASSED. If the \p trycode throws a CoinError, the failure + is recorded with status \p severity and \p expected and the value of + OsiUnitTest::haltonerror is consulted. If the failure is not fatal, \p catchcode is + executed. If any other error is thrown, the failure is recorded as for a CoinError + and \p catchcode is executed (haltonerror is not consulted). +*/ +#define OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname,\ + severity, expected) \ +{ \ + try { \ + trycode; \ + OSIUNITTEST_ADD_OUTCOME(component,testname,#trycode " did not throw exception",\ + OsiUnitTest::TestOutcome::PASSED,false); \ + if (OsiUnitTest::verbosity >= 2) { \ + std::string successmsg( __FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \ + successmsg = successmsg + testname; \ + successmsg = successmsg + " (code \'" #trycode "\') did not throw exception"; \ + successmsg = successmsg + ".\n" ; \ + OsiUnitTest::testingMessage(successmsg.c_str()); \ + } \ + } catch (CoinError& e) { \ + std::stringstream errmsg; \ + errmsg << #trycode " threw CoinError: " << e.message(); \ + if (e.className().length() > 0) \ + errmsg << " in " << e.className(); \ + if (e.methodName().length() > 0) \ + errmsg << " in " << e.methodName(); \ + if (e.lineNumber() >= 0) \ + errmsg << " at " << e.fileName() << ":" << e.lineNumber(); \ + OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.str().c_str(),\ + severity,expected); \ + OsiUnitTest::failureMessage(component,testname,errmsg.str().c_str()); \ + switch(OsiUnitTest::haltonerror) { \ + case 2: \ + { if (severity >= OsiUnitTest::TestOutcome::ERROR) abort(); break; } \ + case 1: \ + { std::cout << std::endl << "press any key to continue..." << std::endl; \ + getchar(); \ + break ; } \ + default: ; \ + } \ + catchcode; \ + } catch (...) { \ + std::string errmsg; \ + errmsg = #trycode; \ + errmsg = errmsg + " threw unknown exception"; \ + OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.c_str(),severity,false); \ + OsiUnitTest::failureMessage(component,testname,errmsg.c_str()); \ + catchcode; \ + } \ +} + +/*! \brief Perform a try/catch test with severity OsiUnitTest::TestOutcome::ERROR, + failure not expected. +*/ +#define OSIUNITTEST_CATCH_ERROR(trycode, catchcode, component, testname) \ + OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::ERROR, false) + +/*! \brief Perform a try/catch test with severity OsiUnitTest::TestOutcome::WARNING, + failure not expected. +*/ +#define OSIUNITTEST_CATCH_WARNING(trycode, catchcode, component, testname) \ + OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::WARNING, false) + +} // end namespace OsiUnitTest + +#endif /*OSISOLVERINTERFACETEST_HPP_*/ diff --git a/thirdparty/linux/include/coin/PardisoLoader.h b/thirdparty/linux/include/coin/PardisoLoader.h new file mode 100644 index 0000000..0942521 --- /dev/null +++ b/thirdparty/linux/include/coin/PardisoLoader.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2008 GAMS Development and others + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: PardisoLoader.h 2204 2013-04-13 13:49:26Z stefan $ + + Author: Stefan Vigerske +*/ + +#ifndef PARDISOLOADER_H_ +#define PARDISOLOADER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + /** Tries to load a dynamically linked library with Pardiso. + * Return a failure if the library cannot be loaded or not all Pardiso symbols are found. + * @param libname The name under which the Pardiso lib can be found, or NULL to use a default name (libpardiso.SHAREDLIBEXT). + * @param msgbuf A buffer where we can store a failure message. Assumed to be NOT NULL! + * @param msglen Length of the message buffer. + * @return Zero on success, nonzero on failure. + */ + int LSL_loadPardisoLib(const char* libname, char* msgbuf, int msglen); + + /** Unloads a loaded Pardiso library. + * @return Zero on success, nonzero on failure. + */ + int LSL_unloadPardisoLib(); + + /** Indicates whether a Pardiso library has been successfully loaded. + * @return Zero if not loaded, nonzero if handle is loaded + */ + int LSL_isPardisoLoaded(); + + /** Returns name of the shared library that should contain Pardiso */ + char* LSL_PardisoLibraryName(); +#ifdef __cplusplus +} +#endif + +#endif /*PARADISOLOADER_H_*/ diff --git a/thirdparty/linux/include/coin/ThirdParty/dmumps_c.h b/thirdparty/linux/include/coin/ThirdParty/dmumps_c.h new file mode 100644 index 0000000..1d5c2c9 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/dmumps_c.h @@ -0,0 +1,159 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +/* Mostly written in march 2002 (JYL) */ + +#ifndef DMUMPS_C_H +#define DMUMPS_C_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mumps_compat.h" +/* Next line defines MUMPS_INT, DMUMPS_COMPLEX and DMUMPS_REAL */ +#include "mumps_c_types.h" + +#ifndef MUMPS_VERSION +/* Protected in case headers of other arithmetics are included */ +#define MUMPS_VERSION "4.10.0" +#endif +#ifndef MUMPS_VERSION_MAX_LEN +#define MUMPS_VERSION_MAX_LEN 14 +#endif + +/* + * Definition of the (simplified) MUMPS C structure. + * NB: DMUMPS_COMPLEX are REAL types in s and d arithmetics. + */ +typedef struct { + + MUMPS_INT sym, par, job; + MUMPS_INT comm_fortran; /* Fortran communicator */ + MUMPS_INT icntl[40]; + DMUMPS_REAL cntl[15]; + MUMPS_INT n; + + MUMPS_INT nz_alloc; /* used in matlab interface to decide if we + free + malloc when we have large variation */ + + /* Assembled entry */ + MUMPS_INT nz; + MUMPS_INT *irn; + MUMPS_INT *jcn; + DMUMPS_COMPLEX *a; + + /* Distributed entry */ + MUMPS_INT nz_loc; + MUMPS_INT *irn_loc; + MUMPS_INT *jcn_loc; + DMUMPS_COMPLEX *a_loc; + + /* Element entry */ + MUMPS_INT nelt; + MUMPS_INT *eltptr; + MUMPS_INT *eltvar; + DMUMPS_COMPLEX *a_elt; + + /* Ordering, if given by user */ + MUMPS_INT *perm_in; + + /* Orderings returned to user */ + MUMPS_INT *sym_perm; /* symmetric permutation */ + MUMPS_INT *uns_perm; /* column permutation */ + + /* Scaling (input only in this version) */ + DMUMPS_REAL *colsca; + DMUMPS_REAL *rowsca; + + /* RHS, solution, ouptput data and statistics */ + DMUMPS_COMPLEX *rhs, *redrhs, *rhs_sparse, *sol_loc; + MUMPS_INT *irhs_sparse, *irhs_ptr, *isol_loc; + MUMPS_INT nrhs, lrhs, lredrhs, nz_rhs, lsol_loc; + MUMPS_INT schur_mloc, schur_nloc, schur_lld; + MUMPS_INT mblock, nblock, nprow, npcol; + MUMPS_INT info[40],infog[40]; + DMUMPS_REAL rinfo[40], rinfog[40]; + + /* Null space */ + MUMPS_INT deficiency; + MUMPS_INT *pivnul_list; + MUMPS_INT *mapping; + + /* Schur */ + MUMPS_INT size_schur; + MUMPS_INT *listvar_schur; + DMUMPS_COMPLEX *schur; + + /* Internal parameters */ + MUMPS_INT instance_number; + DMUMPS_COMPLEX *wk_user; + + /* Version number: length=14 in FORTRAN + 1 for final \0 + 1 for alignment */ + char version_number[MUMPS_VERSION_MAX_LEN + 1 + 1]; + /* For out-of-core */ + char ooc_tmpdir[256]; + char ooc_prefix[64]; + /* To save the matrix in matrix market format */ + char write_problem[256]; + MUMPS_INT lwk_user; + +} DMUMPS_STRUC_C; + + +void MUMPS_CALL +dmumps_c( DMUMPS_STRUC_C * dmumps_par ); + +#ifdef __cplusplus +} +#endif + +#endif /* DMUMPS_C_H */ + diff --git a/thirdparty/linux/include/coin/ThirdParty/mumps_c_types.h b/thirdparty/linux/include/coin/ThirdParty/mumps_c_types.h new file mode 100644 index 0000000..aef6212 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/mumps_c_types.h @@ -0,0 +1,92 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + + +#ifndef MUMPS_C_TYPES_H +#define MUMPS_C_TYPES_H + +#define MUMPS_INT int + +#define SMUMPS_COMPLEX float +#define SMUMPS_REAL float + +#define DMUMPS_COMPLEX double +#define DMUMPS_REAL double + +/* Complex datatypes */ +typedef struct {float r,i;} mumps_complex; +typedef struct {double r,i;} mumps_double_complex; + +#define CMUMPS_COMPLEX mumps_complex +#define CMUMPS_REAL float + +#define ZMUMPS_COMPLEX mumps_double_complex +#define ZMUMPS_REAL double + + +#ifndef mumps_ftnlen +/* When passing a string, what is the type of the extra argument + * passed by value ? */ +# define mumps_ftnlen int +#endif + + +#define MUMPS_ARITH_s 1 +#define MUMPS_ARITH_d 2 +#define MUMPS_ARITH_c 4 +#define MUMPS_ARITH_z 8 + +#define MUMPS_ARITH_REAL ( MUMPS_ARITH_s | MUMPS_ARITH_d ) +#define MUMPS_ARITH_CMPLX ( MUMPS_ARITH_c | MUMPS_ARITH_z ) +#define MUMPS_ARITH_SINGLE ( MUMPS_ARITH_s | MUMPS_ARITH_c ) +#define MUMPS_ARITH_DBL ( MUMPS_ARITH_d | MUMPS_ARITH_z ) + + +#endif /* MUMPS_C_TYPES_H */ diff --git a/thirdparty/linux/include/coin/ThirdParty/mumps_compat.h b/thirdparty/linux/include/coin/ThirdParty/mumps_compat.h new file mode 100644 index 0000000..d63120e --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/mumps_compat.h @@ -0,0 +1,78 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +/* Compatibility issues between various Windows versions */ +#ifndef MUMPS_COMPAT_H +#define MUMPS_COMPAT_H + + +#if defined(_WIN32) && ! defined(__MINGW32__) +# define MUMPS_WIN32 1 +#endif + +#ifndef MUMPS_CALL +# ifdef MUMPS_WIN32 +/* Modify/choose between next 2 lines depending + * on your Windows calling conventions */ +/* # define MUMPS_CALL __stdcall */ +# define MUMPS_CALL +# else +# define MUMPS_CALL +# endif +#endif + +#if (__STDC_VERSION__ >= 199901L) +# define MUMPS_INLINE static inline +#else +# define MUMPS_INLINE +#endif + + +#endif /* MUMPS_COMPAT_H */ diff --git a/thirdparty/linux/include/coin/ThirdParty/mumps_mpi.h b/thirdparty/linux/include/coin/ThirdParty/mumps_mpi.h new file mode 100644 index 0000000..7ab0c37 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/mumps_mpi.h @@ -0,0 +1,77 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +#ifndef MUMPS_MPI_H +#define MUMPS_MPI_H + +/* We define all symbols as extern "C" for users who call MUMPS with its + libseq from a C++ driver. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the minimum to have the C interface of MUMPS work. + * Most of the time, users who need this file have no call to MPI functions in + * their own code. Hence it is not worth declaring all MPI functions here. + * However if some users come to request some more stub functions of the MPI + * standards, we may add them. But it is not worth doing it until then. */ + +typedef int MPI_Comm; /* Simple type for MPI communicator */ +static MPI_Comm MPI_COMM_WORLD=(MPI_Comm)0; + +int MPI_Init(int *pargc, char ***pargv); +int MPI_Comm_rank(int comm, int *rank); +int MPI_Finalize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* MUMPS_MPI_H */ diff --git a/thirdparty/linux/include/gflags/gflags.h b/thirdparty/linux/include/gflags/gflags.h new file mode 100644 index 0000000..3acee2e --- /dev/null +++ b/thirdparty/linux/include/gflags/gflags.h @@ -0,0 +1,606 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// --- +// Revamped and reorganized by Craig Silverstein +// +// This is the file that should be included by any file which declares +// or defines a command line flag or wants to parse command line flags +// or print a program usage message (which will include information about +// flags). Executive summary, in the form of an example foo.cc file: +// +// #include "foo.h" // foo.h has a line "DECLARE_int32(start);" +// #include "validators.h" // hypothetical file defining ValidateIsFile() +// +// DEFINE_int32(end, 1000, "The last record to read"); +// +// DEFINE_string(filename, "my_file.txt", "The file to read"); +// // Crash if the specified file does not exist. +// static bool dummy = RegisterFlagValidator(&FLAGS_filename, +// &ValidateIsFile); +// +// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...) +// +// void MyFunc() { +// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end); +// } +// +// Then, at the command-line: +// ./foo --noverbose --start=5 --end=100 +// +// For more details, see +// doc/gflags.html +// +// --- A note about thread-safety: +// +// We describe many functions in this routine as being thread-hostile, +// thread-compatible, or thread-safe. Here are the meanings we use: +// +// thread-safe: it is safe for multiple threads to call this routine +// (or, when referring to a class, methods of this class) +// concurrently. +// thread-hostile: it is not safe for multiple threads to call this +// routine (or methods of this class) concurrently. In gflags, +// most thread-hostile routines are intended to be called early in, +// or even before, main() -- that is, before threads are spawned. +// thread-compatible: it is safe for multiple threads to read from +// this variable (when applied to variables), or to call const +// methods of this class (when applied to classes), as long as no +// other thread is writing to the variable or calling non-const +// methods of this class. + +#ifndef GFLAGS_GFLAGS_H_ +#define GFLAGS_GFLAGS_H_ + +#include +#include + +#include "gflags/gflags_declare.h" // IWYU pragma: export + + +// We always want to export variables defined in user code +#ifndef GFLAGS_DLL_DEFINE_FLAG +# ifdef _MSC_VER +# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport) +# else +# define GFLAGS_DLL_DEFINE_FLAG +# endif +#endif + + +namespace GFLAGS_NAMESPACE { + + +// -------------------------------------------------------------------- +// To actually define a flag in a file, use DEFINE_bool, +// DEFINE_string, etc. at the bottom of this file. You may also find +// it useful to register a validator with the flag. This ensures that +// when the flag is parsed from the commandline, or is later set via +// SetCommandLineOption, we call the validation function. It is _not_ +// called when you assign the value to the flag directly using the = operator. +// +// The validation function should return true if the flag value is valid, and +// false otherwise. If the function returns false for the new setting of the +// flag, the flag will retain its current value. If it returns false for the +// default value, ParseCommandLineFlags() will die. +// +// This function is safe to call at global construct time (as in the +// example below). +// +// Example use: +// static bool ValidatePort(const char* flagname, int32 value) { +// if (value > 0 && value < 32768) // value is ok +// return true; +// printf("Invalid value for --%s: %d\n", flagname, (int)value); +// return false; +// } +// DEFINE_int32(port, 0, "What port to listen on"); +// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort); + +// Returns true if successfully registered, false if not (because the +// first argument doesn't point to a command-line flag, or because a +// validator is already registered for this flag). +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint32* flag, bool (*validate_fn)(const char*, uint32)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&)); + +// Convenience macro for the registration of a flag validator +#define DEFINE_validator(name, validator) \ + static const bool name##_validator_registered = \ + GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator) + + +// -------------------------------------------------------------------- +// These methods are the best way to get access to info about the +// list of commandline flags. Note that these routines are pretty slow. +// GetAllFlags: mostly-complete info about the list, sorted by file. +// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does) +// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr +// +// In addition to accessing flags, you can also access argv[0] (the program +// name) and argv (the entire commandline), which we sock away a copy of. +// These variables are static, so you should only set them once. +// +// No need to export this data only structure from DLL, avoiding VS warning 4251. +struct CommandLineFlagInfo { + std::string name; // the name of the flag + std::string type; // the type of the flag: int32, etc + std::string description; // the "help text" associated with the flag + std::string current_value; // the current value, as a string + std::string default_value; // the default value, as a string + std::string filename; // 'cleaned' version of filename holding the flag + bool has_validator_fn; // true if RegisterFlagValidator called on this flag + bool is_default; // true if the flag has the default value and + // has not been set explicitly from the cmdline + // or via SetCommandLineOption + const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo) +}; + +// Using this inside of a validator is a recipe for a deadlock. +// TODO(user) Fix locking when validators are running, to make it safe to +// call validators during ParseAllFlags. +// Also make sure then to uncomment the corresponding unit test in +// gflags_unittest.sh +extern GFLAGS_DLL_DECL void GetAllFlags(std::vector* OUTPUT); +// These two are actually defined in gflags_reporting.cc. +extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does +extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict); + +// Create a descriptive string for a flag. +// Goes to some trouble to make pretty line breaks. +extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag); + +// Thread-hostile; meant to be called before any threads are spawned. +extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv); + +// The following functions are thread-safe as long as SetArgv() is +// only called before any threads start. +extern GFLAGS_DLL_DECL const std::vector& GetArgvs(); +extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string +extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0 +extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv +extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set +extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0) + +// ProgramUsage() is thread-safe as long as SetUsageMessage() is only +// called before any threads start. +extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage() + +// VersionString() is thread-safe as long as SetVersionString() is only +// called before any threads start. +extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString() + + + +// -------------------------------------------------------------------- +// Normally you access commandline flags by just saying "if (FLAGS_foo)" +// or whatever, and set them by calling "FLAGS_foo = bar" (or, more +// commonly, via the DEFINE_foo macro). But if you need a bit more +// control, we have programmatic ways to get/set the flags as well. +// These programmatic ways to access flags are thread-safe, but direct +// access is only thread-compatible. + +// Return true iff the flagname was found. +// OUTPUT is set to the flag's value, or unchanged if we return false. +extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT); + +// Return true iff the flagname was found. OUTPUT is set to the flag's +// CommandLineFlagInfo or unchanged if we return false. +extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT); + +// Return the CommandLineFlagInfo of the flagname. exit() if name not found. +// Example usage, to check if a flag's value is currently the default value: +// if (GetCommandLineFlagInfoOrDie("foo").is_default) ... +extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name); + +enum GFLAGS_DLL_DECL FlagSettingMode { + // update the flag's value (can call this multiple times). + SET_FLAGS_VALUE, + // update the flag's value, but *only if* it has not yet been updated + // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef". + SET_FLAG_IF_DEFAULT, + // set the flag's default value to this. If the flag has not yet updated + // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef") + // change the flag's current value to the new default value as well. + SET_FLAGS_DEFAULT +}; + +// Set a particular flag ("command line option"). Returns a string +// describing the new value that the option has been set to. The +// return value API is not well-specified, so basically just depend on +// it to be empty if the setting failed for some reason -- the name is +// not a valid flag name, or the value is not a valid value -- and +// non-empty else. + +// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case) +extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value); +extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode); + + +// -------------------------------------------------------------------- +// Saves the states (value, default value, whether the user has set +// the flag, registered validators, etc) of all flags, and restores +// them when the FlagSaver is destroyed. This is very useful in +// tests, say, when you want to let your tests change the flags, but +// make sure that they get reverted to the original states when your +// test is complete. +// +// Example usage: +// void TestFoo() { +// FlagSaver s1; +// FLAG_foo = false; +// FLAG_bar = "some value"; +// +// // test happens here. You can return at any time +// // without worrying about restoring the FLAG values. +// } +// +// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all +// the work is done in the constructor and destructor, so in the standard +// usage example above, the compiler would complain that it's an +// unused variable. +// +// This class is thread-safe. However, its destructor writes to +// exactly the set of flags that have changed value during its +// lifetime, so concurrent _direct_ access to those flags +// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe. + +class GFLAGS_DLL_DECL FlagSaver { + public: + FlagSaver(); + ~FlagSaver(); + + private: + class FlagSaverImpl* impl_; // we use pimpl here to keep API steady + + FlagSaver(const FlagSaver&); // no copying! + void operator=(const FlagSaver&); +}__attribute((unused)); + +// -------------------------------------------------------------------- +// Some deprecated or hopefully-soon-to-be-deprecated functions. + +// This is often used for logging. TODO(csilvers): figure out a better way +extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString(); +// Usually where this is used, a FlagSaver should be used instead. +extern GFLAGS_DLL_DECL +bool ReadFlagsFromString(const std::string& flagfilecontents, + const char* prog_name, + bool errors_are_fatal); // uses SET_FLAGS_VALUE + +// These let you manually implement --flagfile functionality. +// DEPRECATED. +extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name); +extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE + + +// -------------------------------------------------------------------- +// Useful routines for initializing flags from the environment. +// In each case, if 'varname' does not exist in the environment +// return defval. If 'varname' does exist but is not valid +// (e.g., not a number for an int32 flag), abort with an error. +// Otherwise, return the value. NOTE: for booleans, for true use +// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'. + +extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval); +extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval); +extern GFLAGS_DLL_DECL uint32 Uint32FromEnv(const char *varname, uint32 defval); +extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval); +extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval); +extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval); +extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval); + + +// -------------------------------------------------------------------- +// The next two functions parse gflags from main(): + +// Set the "usage" message for this program. For example: +// string usage("This program does nothing. Sample usage:\n"); +// usage += argv[0] + " "; +// SetUsageMessage(usage); +// Do not include commandline flags in the usage: we do that for you! +// Thread-hostile; meant to be called before any threads are spawned. +extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage); + +// Sets the version string, which is emitted with --version. +// For instance: SetVersionString("1.3"); +// Thread-hostile; meant to be called before any threads are spawned. +extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version); + + +// Looks for flags in argv and parses them. Rearranges argv to put +// flags first, or removes them entirely if remove_flags is true. +// If a flag is defined more than once in the command line or flag +// file, the last definition is used. Returns the index (into argv) +// of the first non-flag argument. +// See top-of-file for more details on this function. +#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead. +extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags); +#endif + + +// Calls to ParseCommandLineNonHelpFlags and then to +// HandleCommandLineHelpFlags can be used instead of a call to +// ParseCommandLineFlags during initialization, in order to allow for +// changing default values for some FLAGS (via +// e.g. SetCommandLineOptionWithMode calls) between the time of +// command line parsing and the time of dumping help information for +// the flags as a result of command line parsing. If a flag is +// defined more than once in the command line or flag file, the last +// definition is used. Returns the index (into argv) of the first +// non-flag argument. (If remove_flags is true, will always return 1.) +extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags); + +// This is actually defined in gflags_reporting.cc. +// This function is misnamed (it also handles --version, etc.), but +// it's too late to change that now. :-( +extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc + +// Allow command line reparsing. Disables the error normally +// generated when an unknown flag is found, since it may be found in a +// later parse. Thread-hostile; meant to be called before any threads +// are spawned. +extern GFLAGS_DLL_DECL void AllowCommandLineReparsing(); + +// Reparse the flags that have not yet been recognized. Only flags +// registered since the last parse will be recognized. Any flag value +// must be provided as part of the argument using "=", not as a +// separate command line argument that follows the flag argument. +// Intended for handling flags from dynamically loaded libraries, +// since their flags are not registered until they are loaded. +extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags(); + +// Clean up memory allocated by flags. This is only needed to reduce +// the quantity of "potentially leaked" reports emitted by memory +// debugging tools such as valgrind. It is not required for normal +// operation, or for the google perftools heap-checker. It must only +// be called when the process is about to exit, and all threads that +// might access flags are quiescent. Referencing flags after this is +// called will have unexpected consequences. This is not safe to run +// when multiple threads might be running: the function is +// thread-hostile. +extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags(); + + +// -------------------------------------------------------------------- +// Now come the command line flag declaration/definition macros that +// will actually be used. They're kind of hairy. A major reason +// for this is initialization: we want people to be able to access +// variables in global constructors and have that not crash, even if +// their global constructor runs before the global constructor here. +// (Obviously, we can't guarantee the flags will have the correct +// default value in that case, but at least accessing them is safe.) +// The only way to do that is have flags point to a static buffer. +// So we make one, using a union to ensure proper alignment, and +// then use placement-new to actually set up the flag with the +// correct default value. In the same vein, we have to worry about +// flag access in global destructors, so FlagRegisterer has to be +// careful never to destroy the flag-values it constructs. +// +// Note that when we define a flag variable FLAGS_, we also +// preemptively define a junk variable, FLAGS_no. This is to +// cause a link-time error if someone tries to define 2 flags with +// names like "logging" and "nologging". We do this because a bool +// flag FLAG can be set from the command line to true with a "-FLAG" +// argument, and to false with a "-noFLAG" argument, and so this can +// potentially avert confusion. +// +// We also put flags into their own namespace. It is purposefully +// named in an opaque way that people should have trouble typing +// directly. The idea is that DEFINE puts the flag in the weird +// namespace, and DECLARE imports the flag from there into the current +// namespace. The net result is to force people to use DECLARE to get +// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;" +// or some such instead. We want this so we can put extra +// functionality (like sanity-checking) in DECLARE if we want, and +// make sure it is picked up everywhere. +// +// We also put the type of the variable in the namespace, so that +// people can't DECLARE_int32 something that they DEFINE_bool'd +// elsewhere. + +class GFLAGS_DLL_DECL FlagRegisterer { + public: + // We instantiate this template ctor for all supported types, + // so it is possible to place implementation of the FlagRegisterer ctor in + // .cc file. + // Calling this constructor with unsupported type will produce linker error. + template + FlagRegisterer(const char* name, + const char* help, const char* filename, + FlagType* current_storage, FlagType* defvalue_storage); +}; + +// If your application #defines STRIP_FLAG_HELP to a non-zero value +// before #including this file, we remove the help message from the +// binary file. This can reduce the size of the resulting binary +// somewhat, and may also be useful for security reasons. + +extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[]; + + +} // namespace GFLAGS_NAMESPACE + + +#ifndef SWIG // In swig, ignore the main flag declarations + +#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0 +// Need this construct to avoid the 'defined but not used' warning. +#define MAYBE_STRIPPED_HELP(txt) \ + (false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp) +#else +#define MAYBE_STRIPPED_HELP(txt) txt +#endif + +// Each command-line flag has two variables associated with it: one +// with the current value, and one with the default value. However, +// we have a third variable, which is where value is assigned; it's a +// constant. This guarantees that FLAG_##value is initialized at +// static initialization time (e.g. before program-start) rather than +// than global construction time (which is after program-start but +// before main), at least when 'value' is a compile-time constant. We +// use a small trick for the "default value" variable, and call it +// FLAGS_no. This serves the second purpose of assuring a +// compile error if someone tries to define a flag named no +// which is illegal (--foo and --nofoo both affect the "foo" flag). +#define DEFINE_VARIABLE(type, shorttype, name, value, help) \ + namespace fL##shorttype { \ + static const type FLAGS_nono##name = value; \ + /* We always want to export defined variables, dll or no */ \ + GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \ + type FLAGS_no##name = FLAGS_nono##name; \ + static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \ + #name, MAYBE_STRIPPED_HELP(help), __FILE__, \ + &FLAGS_##name, &FLAGS_no##name); \ + } \ + using fL##shorttype::FLAGS_##name + +// For DEFINE_bool, we want to do the extra check that the passed-in +// value is actually a bool, and not a string or something that can be +// coerced to a bool. These declarations (no definition needed!) will +// help us do that, and never evaluate From, which is important. +// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires +// that the compiler have different sizes for bool & double. Since +// this is not guaranteed by the standard, we check it with a +// COMPILE_ASSERT. +namespace fLB { +struct CompileAssert {}; +typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[ + (sizeof(double) != sizeof(bool)) ? 1 : -1]; +template double GFLAGS_DLL_DECL IsBoolFlag(const From& from); +GFLAGS_DLL_DECL bool IsBoolFlag(bool from); +} // namespace fLB + +// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros +// are in a separate include, gflags_declare.h, for reducing +// the physical transitive size for DECLARE use. +#define DEFINE_bool(name, val, txt) \ + namespace fLB { \ + typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \ + (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \ + } \ + DEFINE_VARIABLE(bool, B, name, val, txt) + +#define DEFINE_int32(name, val, txt) \ + DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \ + name, val, txt) + +#define DEFINE_uint32(name,val, txt) \ + DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint32, U, \ + name, val, txt) + +#define DEFINE_int64(name, val, txt) \ + DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \ + name, val, txt) + +#define DEFINE_uint64(name,val, txt) \ + DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \ + name, val, txt) + +#define DEFINE_double(name, val, txt) \ + DEFINE_VARIABLE(double, D, name, val, txt) + +// Strings are trickier, because they're not a POD, so we can't +// construct them at static-initialization time (instead they get +// constructed at global-constructor time, which is much later). To +// try to avoid crashes in that case, we use a char buffer to store +// the string, which we can static-initialize, and then placement-new +// into it later. It's not perfect, but the best we can do. + +namespace fLS { + +inline clstring* dont_pass0toDEFINE_string(char *stringspot, + const char *value) { + return new(stringspot) clstring(value); +} +inline clstring* dont_pass0toDEFINE_string(char *stringspot, + const clstring &value) { + return new(stringspot) clstring(value); +} +inline clstring* dont_pass0toDEFINE_string(char *stringspot, + int value); + +// Auxiliary class used to explicitly call destructor of string objects +// allocated using placement new during static program deinitialization. +// The destructor MUST be an inline function such that the explicit +// destruction occurs in the same compilation unit as the placement new. +class StringFlagDestructor { + void *current_storage_; + void *defvalue_storage_; + +public: + + StringFlagDestructor(void *current, void *defvalue) + : current_storage_(current), defvalue_storage_(defvalue) {} + + ~StringFlagDestructor() { + reinterpret_cast(current_storage_ )->~clstring(); + reinterpret_cast(defvalue_storage_)->~clstring(); + } +}; + +} // namespace fLS + +// We need to define a var named FLAGS_no##name so people don't define +// --string and --nostring. And we need a temporary place to put val +// so we don't have to evaluate it twice. Two great needs that go +// great together! +// The weird 'using' + 'extern' inside the fLS namespace is to work around +// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See +// http://code.google.com/p/google-gflags/issues/detail?id=20 +#define DEFINE_string(name, val, txt) \ + namespace fLS { \ + using ::fLS::clstring; \ + using ::fLS::StringFlagDestructor; \ + static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \ + clstring* const FLAGS_no##name = ::fLS:: \ + dont_pass0toDEFINE_string(s_##name[0].s, \ + val); \ + static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \ + #name, MAYBE_STRIPPED_HELP(txt), __FILE__, \ + FLAGS_no##name, new (s_##name[1].s) clstring(*FLAGS_no##name)); \ + static StringFlagDestructor d_##name(s_##name[0].s, s_##name[1].s); \ + extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \ + using fLS::FLAGS_##name; \ + clstring& FLAGS_##name = *FLAGS_no##name; \ + } \ + using fLS::FLAGS_##name + +#endif // SWIG + + +// Import gflags library symbols into alternative/deprecated namespace(s) +#include "gflags_gflags.h" + + +#endif // GFLAGS_GFLAGS_H_ diff --git a/thirdparty/linux/include/gflags/gflags_completions.h b/thirdparty/linux/include/gflags/gflags_completions.h new file mode 100644 index 0000000..f951c1e --- /dev/null +++ b/thirdparty/linux/include/gflags/gflags_completions.h @@ -0,0 +1,121 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --- + +// +// Implement helpful bash-style command line flag completions +// +// ** Functional API: +// HandleCommandLineCompletions() should be called early during +// program startup, but after command line flag code has been +// initialized, such as the beginning of HandleCommandLineHelpFlags(). +// It checks the value of the flag --tab_completion_word. If this +// flag is empty, nothing happens here. If it contains a string, +// however, then HandleCommandLineCompletions() will hijack the +// process, attempting to identify the intention behind this +// completion. Regardless of the outcome of this deduction, the +// process will be terminated, similar to --helpshort flag +// handling. +// +// ** Overview of Bash completions: +// Bash can be told to programatically determine completions for the +// current 'cursor word'. It does this by (in this case) invoking a +// command with some additional arguments identifying the command +// being executed, the word being completed, and the previous word +// (if any). Bash then expects a sequence of output lines to be +// printed to stdout. If these lines all contain a common prefix +// longer than the cursor word, bash will replace the cursor word +// with that common prefix, and display nothing. If there isn't such +// a common prefix, bash will display the lines in pages using 'more'. +// +// ** Strategy taken for command line completions: +// If we can deduce either the exact flag intended, or a common flag +// prefix, we'll output exactly that. Otherwise, if information +// must be displayed to the user, we'll take the opportunity to add +// some helpful information beyond just the flag name (specifically, +// we'll include the default flag value and as much of the flag's +// description as can fit on a single terminal line width, as specified +// by the flag --tab_completion_columns). Furthermore, we'll try to +// make bash order the output such that the most useful or relevent +// flags are the most likely to be shown at the top. +// +// ** Additional features: +// To assist in finding that one really useful flag, substring matching +// was implemented. Before pressing a to get completion for the +// current word, you can append one or more '?' to the flag to do +// substring matching. Here's the semantics: +// --foo Show me all flags with names prefixed by 'foo' +// --foo? Show me all flags with 'foo' somewhere in the name +// --foo?? Same as prior case, but also search in module +// definition path for 'foo' +// --foo??? Same as prior case, but also search in flag +// descriptions for 'foo' +// Finally, we'll trim the output to a relatively small number of +// flags to keep bash quiet about the verbosity of output. If one +// really wanted to see all possible matches, appending a '+' to the +// search word will force the exhaustive list of matches to be printed. +// +// ** How to have bash accept completions from a binary: +// Bash requires that it be informed about each command that programmatic +// completion should be enabled for. Example addition to a .bashrc +// file would be (your path to gflags_completions.sh file may differ): + +/* +$ complete -o bashdefault -o default -o nospace -C \ + '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \ + time env binary_name another_binary [...] +*/ + +// This would allow the following to work: +// $ /path/to/binary_name --vmodule +// Or: +// $ ./bin/path/another_binary --gfs_u +// (etc) +// +// Sadly, it appears that bash gives no easy way to force this behavior for +// all commands. That's where the "time" in the above example comes in. +// If you haven't specifically added a command to the list of completion +// supported commands, you can still get completions by prefixing the +// entire command with "env". +// $ env /some/brand/new/binary --vmod +// Assuming that "binary" is a newly compiled binary, this should still +// produce the expected completion output. + + +#ifndef GFLAGS_COMPLETIONS_H_ +#define GFLAGS_COMPLETIONS_H_ + +namespace google { + +extern void HandleCommandLineCompletions(void); + +} + +#endif // GFLAGS_COMPLETIONS_H_ diff --git a/thirdparty/linux/include/gflags/gflags_declare.h b/thirdparty/linux/include/gflags/gflags_declare.h new file mode 100644 index 0000000..98747f3 --- /dev/null +++ b/thirdparty/linux/include/gflags/gflags_declare.h @@ -0,0 +1,153 @@ +// Copyright (c) 1999, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// --- +// +// Revamped and reorganized by Craig Silverstein +// +// This is the file that should be included by any file which declares +// command line flag. + +#ifndef GFLAGS_DECLARE_H_ +#define GFLAGS_DECLARE_H_ + + +// --------------------------------------------------------------------------- +// Namespace of gflags library symbols. +#define GFLAGS_NAMESPACE google + +// --------------------------------------------------------------------------- +// Windows DLL import/export. + +// Whether gflags library is a DLL. +// +// Set to 1 by default when the shared gflags library was built on Windows. +// Must be overwritten when this header file is used with the optionally also +// built static library instead; set by CMake's INTERFACE_COMPILE_DEFINITIONS. +#ifndef GFLAGS_IS_A_DLL +# define GFLAGS_IS_A_DLL 1 +#endif + +// We always want to import the symbols of the gflags library. +#ifndef GFLAGS_DLL_DECL +# if GFLAGS_IS_A_DLL && defined(_MSC_VER) +# define GFLAGS_DLL_DECL __declspec(dllimport) +# else +# define GFLAGS_DLL_DECL +# endif +#endif + +// We always want to import variables declared in user code. +#ifndef GFLAGS_DLL_DECLARE_FLAG +# if GFLAGS_IS_A_DLL && defined(_MSC_VER) +# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport) +# else +# define GFLAGS_DLL_DECLARE_FLAG +# endif +#endif + +// --------------------------------------------------------------------------- +// Flag types +#include +#if 1 +# include // the normal place uint32_t is defined +#elif 1 +# include // the normal place u_int32_t is defined +#elif 1 +# include // a third place for uint32_t or u_int32_t +#endif + +namespace GFLAGS_NAMESPACE { + +#if 1 // C99 +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; +#elif 0 // BSD +typedef int32_t int32; +typedef u_int32_t uint32; +typedef int64_t int64; +typedef u_int64_t uint64; +#elif 0 // Windows +typedef __int32 int32; +typedef unsigned __int32 uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +# error Do not know how to define a 32-bit integer quantity on your system +#endif + +} // namespace GFLAGS_NAMESPACE + + +namespace fLS { + +// The meaning of "string" might be different between now and when the +// macros below get invoked (e.g., if someone is experimenting with +// other string implementations that get defined after this file is +// included). Save the current meaning now and use it in the macros. +typedef std::string clstring; + +} // namespace fLS + + +#define DECLARE_VARIABLE(type, shorttype, name) \ + /* We always want to import declared variables, dll or no */ \ + namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \ + using fL##shorttype::FLAGS_##name + +#define DECLARE_bool(name) \ + DECLARE_VARIABLE(bool, B, name) + +#define DECLARE_int32(name) \ + DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name) + +#define DECLARE_uint32(name) \ + DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint32, U, name) + +#define DECLARE_int64(name) \ + DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name) + +#define DECLARE_uint64(name) \ + DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name) + +#define DECLARE_double(name) \ + DECLARE_VARIABLE(double, D, name) + +#define DECLARE_string(name) \ + /* We always want to import declared variables, dll or no */ \ + namespace fLS { \ + using ::fLS::clstring; \ + extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \ + } \ + using fLS::FLAGS_##name + + +#endif // GFLAGS_DECLARE_H_ diff --git a/thirdparty/linux/include/gflags/gflags_gflags.h b/thirdparty/linux/include/gflags/gflags_gflags.h new file mode 100644 index 0000000..36d0ba1 --- /dev/null +++ b/thirdparty/linux/include/gflags/gflags_gflags.h @@ -0,0 +1,102 @@ +// Copyright (c) 2014, Andreas Schuh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// ----------------------------------------------------------------------------- +// Imports the gflags library symbols into an alternative/deprecated namespace. + +#ifndef GFLAGS_GFLAGS_H_ +# error The internal header gflags_gflags.h may only be included by gflags.h +#endif + +#ifndef GFLAGS_NS_GFLAGS_H_ +#define GFLAGS_NS_GFLAGS_H_ + + +namespace gflags { + + +using GFLAGS_NAMESPACE::int32; +using GFLAGS_NAMESPACE::uint32; +using GFLAGS_NAMESPACE::int64; +using GFLAGS_NAMESPACE::uint64; + +using GFLAGS_NAMESPACE::RegisterFlagValidator; +using GFLAGS_NAMESPACE::CommandLineFlagInfo; +using GFLAGS_NAMESPACE::GetAllFlags; +using GFLAGS_NAMESPACE::ShowUsageWithFlags; +using GFLAGS_NAMESPACE::ShowUsageWithFlagsRestrict; +using GFLAGS_NAMESPACE::DescribeOneFlag; +using GFLAGS_NAMESPACE::SetArgv; +using GFLAGS_NAMESPACE::GetArgvs; +using GFLAGS_NAMESPACE::GetArgv; +using GFLAGS_NAMESPACE::GetArgv0; +using GFLAGS_NAMESPACE::GetArgvSum; +using GFLAGS_NAMESPACE::ProgramInvocationName; +using GFLAGS_NAMESPACE::ProgramInvocationShortName; +using GFLAGS_NAMESPACE::ProgramUsage; +using GFLAGS_NAMESPACE::VersionString; +using GFLAGS_NAMESPACE::GetCommandLineOption; +using GFLAGS_NAMESPACE::GetCommandLineFlagInfo; +using GFLAGS_NAMESPACE::GetCommandLineFlagInfoOrDie; +using GFLAGS_NAMESPACE::FlagSettingMode; +using GFLAGS_NAMESPACE::SET_FLAGS_VALUE; +using GFLAGS_NAMESPACE::SET_FLAG_IF_DEFAULT; +using GFLAGS_NAMESPACE::SET_FLAGS_DEFAULT; +using GFLAGS_NAMESPACE::SetCommandLineOption; +using GFLAGS_NAMESPACE::SetCommandLineOptionWithMode; +using GFLAGS_NAMESPACE::FlagSaver; +using GFLAGS_NAMESPACE::CommandlineFlagsIntoString; +using GFLAGS_NAMESPACE::ReadFlagsFromString; +using GFLAGS_NAMESPACE::AppendFlagsIntoFile; +using GFLAGS_NAMESPACE::ReadFromFlagsFile; +using GFLAGS_NAMESPACE::BoolFromEnv; +using GFLAGS_NAMESPACE::Int32FromEnv; +using GFLAGS_NAMESPACE::Uint32FromEnv; +using GFLAGS_NAMESPACE::Int64FromEnv; +using GFLAGS_NAMESPACE::Uint64FromEnv; +using GFLAGS_NAMESPACE::DoubleFromEnv; +using GFLAGS_NAMESPACE::StringFromEnv; +using GFLAGS_NAMESPACE::SetUsageMessage; +using GFLAGS_NAMESPACE::SetVersionString; +using GFLAGS_NAMESPACE::ParseCommandLineNonHelpFlags; +using GFLAGS_NAMESPACE::HandleCommandLineHelpFlags; +using GFLAGS_NAMESPACE::AllowCommandLineReparsing; +using GFLAGS_NAMESPACE::ReparseCommandLineNonHelpFlags; +using GFLAGS_NAMESPACE::ShutDownCommandLineFlags; +using GFLAGS_NAMESPACE::FlagRegisterer; + +#ifndef SWIG +using GFLAGS_NAMESPACE::ParseCommandLineFlags; +#endif + + +} // namespace gflags + + +#endif // GFLAGS_NS_GFLAGS_H_ diff --git a/thirdparty/linux/include/google/protobuf/any.h b/thirdparty/linux/include/google/protobuf/any.h new file mode 100644 index 0000000..04e5416 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/any.h @@ -0,0 +1,107 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_ANY_H__ +#define GOOGLE_PROTOBUF_ANY_H__ + +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +// Helper class used to implement google::protobuf::Any. +class LIBPROTOBUF_EXPORT AnyMetadata { + typedef ArenaStringPtr UrlType; + typedef ArenaStringPtr ValueType; + public: + // AnyMetadata does not take ownership of "type_url" and "value". + AnyMetadata(UrlType* type_url, ValueType* value); + + // Packs a message using the default type URL prefix: "type.googleapis.com". + // The resulted type URL will be "type.googleapis.com/". + void PackFrom(const Message& message); + // Packs a message using the given type URL prefix. The type URL will be + // constructed by concatenating the message type's full name to the prefix + // with an optional "/" separator if the prefix doesn't already end up "/". + // For example, both PackFrom(message, "type.googleapis.com") and + // PackFrom(message, "type.googleapis.com/") yield the same result type + // URL: "type.googleapis.com/". + void PackFrom(const Message& message, const string& type_url_prefix); + + // Unpacks the payload into the given message. Returns false if the message's + // type doesn't match the type specified in the type URL (i.e., the full + // name after the last "/" of the type URL doesn't match the message's actaul + // full name) or parsing the payload has failed. + bool UnpackTo(Message* message) const; + + // Checks whether the type specified in the type URL matches the given type. + // A type is consdiered matching if its full name matches the full name after + // the last "/" in the type URL. + template + bool Is() const { + return InternalIs(T::default_instance().GetDescriptor()); + } + + private: + bool InternalIs(const Descriptor* message) const; + + UrlType* type_url_; + ValueType* value_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AnyMetadata); +}; + +extern const char kAnyFullTypeName[]; // "google.protobuf.Any". +extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/". +extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/". + +// Get the proto type name from Any::type_url value. For example, passing +// "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in +// *full_type_name. Returns false if type_url does not start with +// "type.googleapis.com" or "type.googleprod.com". +bool ParseAnyTypeUrl(const string& type_url, string* full_type_name); + +// See if message is of type google.protobuf.Any, if so, return the descriptors +// for "type_url" and "value" fields. +bool GetAnyFieldDescriptors(const Message& message, + const FieldDescriptor** type_url_field, + const FieldDescriptor** value_field); + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_ANY_H__ diff --git a/thirdparty/linux/include/google/protobuf/any.pb.h b/thirdparty/linux/include/google/protobuf/any.pb.h new file mode 100644 index 0000000..d8cbee2 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/any.pb.h @@ -0,0 +1,258 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/any.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fany_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto(); + +class Any; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ { + public: + Any(); + virtual ~Any(); + + Any(const Any& from); + + inline Any& operator=(const Any& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Any& default_instance(); + + // implements Any ----------------------------------------------- + + void PackFrom(const ::google::protobuf::Message& message); + void PackFrom(const ::google::protobuf::Message& message, + const ::std::string& type_url_prefix); + bool UnpackTo(::google::protobuf::Message* message) const; + template bool Is() const { + return _any_metadata_.Is(); + } + + void Swap(Any* other); + + // implements Message ---------------------------------------------- + + inline Any* New() const { return New(NULL); } + + Any* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Any& from); + void MergeFrom(const Any& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Any* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string type_url = 1; + void clear_type_url(); + static const int kTypeUrlFieldNumber = 1; + const ::std::string& type_url() const; + void set_type_url(const ::std::string& value); + void set_type_url(const char* value); + void set_type_url(const char* value, size_t size); + ::std::string* mutable_type_url(); + ::std::string* release_type_url(); + void set_allocated_type_url(::std::string* type_url); + + // optional bytes value = 2; + void clear_value(); + static const int kValueFieldNumber = 2; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const void* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Any) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr type_url_; + ::google::protobuf::internal::ArenaStringPtr value_; + mutable int _cached_size_; + ::google::protobuf::internal::AnyMetadata _any_metadata_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fany_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto(); + + void InitAsDefaultInstance(); + static Any* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Any + +// optional string type_url = 1; +inline void Any::clear_type_url() { + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Any::type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Any.type_url) + return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Any::set_type_url(const ::std::string& value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url) +} +inline void Any::set_type_url(const char* value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url) +} +inline void Any::set_type_url(const char* value, size_t size) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.type_url) +} +inline ::std::string* Any::mutable_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Any.type_url) + return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Any::release_type_url() { + // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url) + + return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Any::set_allocated_type_url(::std::string* type_url) { + if (type_url != NULL) { + + } else { + + } + type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url) +} + +// optional bytes value = 2; +inline void Any::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Any::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Any.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Any::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Any.value) +} +inline void Any::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value) +} +inline void Any::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.value) +} +inline ::std::string* Any::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Any.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Any::release_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Any.value) + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Any::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/any.proto b/thirdparty/linux/include/google/protobuf/any.proto new file mode 100644 index 0000000..81dcf46 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/any.proto @@ -0,0 +1,140 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/any"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name whose content describes the type of the + // serialized protocol buffer message. + // + // For URLs which use the scheme `http`, `https`, or no scheme, the + // following restrictions and interpretations apply: + // + // * If no scheme is provided, `https` is assumed. + // * The last segment of the URL's path must represent the fully + // qualified name of the type (as in `path/google.protobuf.Duration`). + // The name should be in a canonical form (e.g., leading "." is + // not accepted). + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/thirdparty/linux/include/google/protobuf/api.pb.h b/thirdparty/linux/include/google/protobuf/api.pb.h new file mode 100644 index 0000000..c9ec923 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/api.pb.h @@ -0,0 +1,996 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/api.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fapi_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fapi_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto(); + +class Api; +class Method; +class Mixin; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ { + public: + Api(); + virtual ~Api(); + + Api(const Api& from); + + inline Api& operator=(const Api& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Api& default_instance(); + + void Swap(Api* other); + + // implements Message ---------------------------------------------- + + inline Api* New() const { return New(NULL); } + + Api* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Api& from); + void MergeFrom(const Api& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Api* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.Method methods = 2; + int methods_size() const; + void clear_methods(); + static const int kMethodsFieldNumber = 2; + const ::google::protobuf::Method& methods(int index) const; + ::google::protobuf::Method* mutable_methods(int index); + ::google::protobuf::Method* add_methods(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >* + mutable_methods(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >& + methods() const; + + // repeated .google.protobuf.Option options = 3; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + + // optional string version = 4; + void clear_version(); + static const int kVersionFieldNumber = 4; + const ::std::string& version() const; + void set_version(const ::std::string& value); + void set_version(const char* value); + void set_version(const char* value, size_t size); + ::std::string* mutable_version(); + ::std::string* release_version(); + void set_allocated_version(::std::string* version); + + // optional .google.protobuf.SourceContext source_context = 5; + bool has_source_context() const; + void clear_source_context(); + static const int kSourceContextFieldNumber = 5; + const ::google::protobuf::SourceContext& source_context() const; + ::google::protobuf::SourceContext* mutable_source_context(); + ::google::protobuf::SourceContext* release_source_context(); + void set_allocated_source_context(::google::protobuf::SourceContext* source_context); + + // repeated .google.protobuf.Mixin mixins = 6; + int mixins_size() const; + void clear_mixins(); + static const int kMixinsFieldNumber = 6; + const ::google::protobuf::Mixin& mixins(int index) const; + ::google::protobuf::Mixin* mutable_mixins(int index); + ::google::protobuf::Mixin* add_mixins(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >* + mutable_mixins(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >& + mixins() const; + + // optional .google.protobuf.Syntax syntax = 7; + void clear_syntax(); + static const int kSyntaxFieldNumber = 7; + ::google::protobuf::Syntax syntax() const; + void set_syntax(::google::protobuf::Syntax value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Api) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method > methods_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::internal::ArenaStringPtr version_; + ::google::protobuf::SourceContext* source_context_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin > mixins_; + int syntax_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto(); + + void InitAsDefaultInstance(); + static Api* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ { + public: + Method(); + virtual ~Method(); + + Method(const Method& from); + + inline Method& operator=(const Method& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Method& default_instance(); + + void Swap(Method* other); + + // implements Message ---------------------------------------------- + + inline Method* New() const { return New(NULL); } + + Method* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Method& from); + void MergeFrom(const Method& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Method* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional string request_type_url = 2; + void clear_request_type_url(); + static const int kRequestTypeUrlFieldNumber = 2; + const ::std::string& request_type_url() const; + void set_request_type_url(const ::std::string& value); + void set_request_type_url(const char* value); + void set_request_type_url(const char* value, size_t size); + ::std::string* mutable_request_type_url(); + ::std::string* release_request_type_url(); + void set_allocated_request_type_url(::std::string* request_type_url); + + // optional bool request_streaming = 3; + void clear_request_streaming(); + static const int kRequestStreamingFieldNumber = 3; + bool request_streaming() const; + void set_request_streaming(bool value); + + // optional string response_type_url = 4; + void clear_response_type_url(); + static const int kResponseTypeUrlFieldNumber = 4; + const ::std::string& response_type_url() const; + void set_response_type_url(const ::std::string& value); + void set_response_type_url(const char* value); + void set_response_type_url(const char* value, size_t size); + ::std::string* mutable_response_type_url(); + ::std::string* release_response_type_url(); + void set_allocated_response_type_url(::std::string* response_type_url); + + // optional bool response_streaming = 5; + void clear_response_streaming(); + static const int kResponseStreamingFieldNumber = 5; + bool response_streaming() const; + void set_response_streaming(bool value); + + // repeated .google.protobuf.Option options = 6; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 6; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + + // optional .google.protobuf.Syntax syntax = 7; + void clear_syntax(); + static const int kSyntaxFieldNumber = 7; + ::google::protobuf::Syntax syntax() const; + void set_syntax(::google::protobuf::Syntax value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Method) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::internal::ArenaStringPtr request_type_url_; + ::google::protobuf::internal::ArenaStringPtr response_type_url_; + bool request_streaming_; + bool response_streaming_; + int syntax_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto(); + + void InitAsDefaultInstance(); + static Method* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ { + public: + Mixin(); + virtual ~Mixin(); + + Mixin(const Mixin& from); + + inline Mixin& operator=(const Mixin& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Mixin& default_instance(); + + void Swap(Mixin* other); + + // implements Message ---------------------------------------------- + + inline Mixin* New() const { return New(NULL); } + + Mixin* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Mixin& from); + void MergeFrom(const Mixin& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Mixin* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional string root = 2; + void clear_root(); + static const int kRootFieldNumber = 2; + const ::std::string& root() const; + void set_root(const ::std::string& value); + void set_root(const char* value); + void set_root(const char* value, size_t size); + ::std::string* mutable_root(); + ::std::string* release_root(); + void set_allocated_root(::std::string* root); + + // @@protoc_insertion_point(class_scope:google.protobuf.Mixin) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::internal::ArenaStringPtr root_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto(); + + void InitAsDefaultInstance(); + static Mixin* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Api + +// optional string name = 1; +inline void Api::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Api::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Api::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Api.name) +} +inline void Api::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name) +} +inline void Api::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.name) +} +inline ::std::string* Api::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Api::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Api.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Api::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name) +} + +// repeated .google.protobuf.Method methods = 2; +inline int Api::methods_size() const { + return methods_.size(); +} +inline void Api::clear_methods() { + methods_.Clear(); +} +inline const ::google::protobuf::Method& Api::methods(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.methods) + return methods_.Get(index); +} +inline ::google::protobuf::Method* Api::mutable_methods(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods) + return methods_.Mutable(index); +} +inline ::google::protobuf::Method* Api::add_methods() { + // @@protoc_insertion_point(field_add:google.protobuf.Api.methods) + return methods_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >* +Api::mutable_methods() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods) + return &methods_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >& +Api::methods() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.methods) + return methods_; +} + +// repeated .google.protobuf.Option options = 3; +inline int Api::options_size() const { + return options_.size(); +} +inline void Api::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Api::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Api::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Api::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Api.options) + return options_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Api::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options) + return &options_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Api::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.options) + return options_; +} + +// optional string version = 4; +inline void Api::clear_version() { + version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Api::version() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.version) + return version_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Api::set_version(const ::std::string& value) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Api.version) +} +inline void Api::set_version(const char* value) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version) +} +inline void Api::set_version(const char* value, size_t size) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.version) +} +inline ::std::string* Api::mutable_version() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.version) + return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Api::release_version() { + // @@protoc_insertion_point(field_release:google.protobuf.Api.version) + + return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Api::set_allocated_version(::std::string* version) { + if (version != NULL) { + + } else { + + } + version_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), version); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version) +} + +// optional .google.protobuf.SourceContext source_context = 5; +inline bool Api::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +inline void Api::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} +inline const ::google::protobuf::SourceContext& Api::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} +inline ::google::protobuf::SourceContext* Api::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context) + return source_context_; +} +inline ::google::protobuf::SourceContext* Api::release_source_context() { + // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context) + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} +inline void Api::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context) +} + +// repeated .google.protobuf.Mixin mixins = 6; +inline int Api::mixins_size() const { + return mixins_.size(); +} +inline void Api::clear_mixins() { + mixins_.Clear(); +} +inline const ::google::protobuf::Mixin& Api::mixins(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins) + return mixins_.Get(index); +} +inline ::google::protobuf::Mixin* Api::mutable_mixins(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins) + return mixins_.Mutable(index); +} +inline ::google::protobuf::Mixin* Api::add_mixins() { + // @@protoc_insertion_point(field_add:google.protobuf.Api.mixins) + return mixins_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >* +Api::mutable_mixins() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins) + return &mixins_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >& +Api::mixins() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins) + return mixins_; +} + +// optional .google.protobuf.Syntax syntax = 7; +inline void Api::clear_syntax() { + syntax_ = 0; +} +inline ::google::protobuf::Syntax Api::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax) + return static_cast< ::google::protobuf::Syntax >(syntax_); +} +inline void Api::set_syntax(::google::protobuf::Syntax value) { + + syntax_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax) +} + +// ------------------------------------------------------------------- + +// Method + +// optional string name = 1; +inline void Method::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Method::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.name) +} +inline void Method::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name) +} +inline void Method::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.name) +} +inline ::std::string* Method::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Method::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Method.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name) +} + +// optional string request_type_url = 2; +inline void Method::clear_request_type_url() { + request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Method::request_type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url) + return request_type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_request_type_url(const ::std::string& value) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url) +} +inline void Method::set_request_type_url(const char* value) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url) +} +inline void Method::set_request_type_url(const char* value, size_t size) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.request_type_url) +} +inline ::std::string* Method::mutable_request_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.request_type_url) + return request_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Method::release_request_type_url() { + // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url) + + return request_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_allocated_request_type_url(::std::string* request_type_url) { + if (request_type_url != NULL) { + + } else { + + } + request_type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), request_type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url) +} + +// optional bool request_streaming = 3; +inline void Method::clear_request_streaming() { + request_streaming_ = false; +} +inline bool Method::request_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.request_streaming) + return request_streaming_; +} +inline void Method::set_request_streaming(bool value) { + + request_streaming_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming) +} + +// optional string response_type_url = 4; +inline void Method::clear_response_type_url() { + response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Method::response_type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url) + return response_type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_response_type_url(const ::std::string& value) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url) +} +inline void Method::set_response_type_url(const char* value) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url) +} +inline void Method::set_response_type_url(const char* value, size_t size) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.response_type_url) +} +inline ::std::string* Method::mutable_response_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.response_type_url) + return response_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Method::release_response_type_url() { + // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url) + + return response_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_allocated_response_type_url(::std::string* response_type_url) { + if (response_type_url != NULL) { + + } else { + + } + response_type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), response_type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url) +} + +// optional bool response_streaming = 5; +inline void Method::clear_response_streaming() { + response_streaming_ = false; +} +inline bool Method::response_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.response_streaming) + return response_streaming_; +} +inline void Method::set_response_streaming(bool value) { + + response_streaming_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Method.response_streaming) +} + +// repeated .google.protobuf.Option options = 6; +inline int Method::options_size() const { + return options_.size(); +} +inline void Method::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Method::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Method::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Method::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Method.options) + return options_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Method::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options) + return &options_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Method::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Method.options) + return options_; +} + +// optional .google.protobuf.Syntax syntax = 7; +inline void Method::clear_syntax() { + syntax_ = 0; +} +inline ::google::protobuf::Syntax Method::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax) + return static_cast< ::google::protobuf::Syntax >(syntax_); +} +inline void Method::set_syntax(::google::protobuf::Syntax value) { + + syntax_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax) +} + +// ------------------------------------------------------------------- + +// Mixin + +// optional string name = 1; +inline void Mixin::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Mixin::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Mixin::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name) +} +inline void Mixin::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name) +} +inline void Mixin::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name) +} +inline ::std::string* Mixin::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Mixin::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Mixin::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name) +} + +// optional string root = 2; +inline void Mixin::clear_root() { + root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Mixin::root() const { + // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root) + return root_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Mixin::set_root(const ::std::string& value) { + + root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root) +} +inline void Mixin::set_root(const char* value) { + + root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root) +} +inline void Mixin::set_root(const char* value, size_t size) { + + root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root) +} +inline ::std::string* Mixin::mutable_root() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root) + return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Mixin::release_root() { + // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root) + + return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Mixin::set_allocated_root(::std::string* root) { + if (root != NULL) { + + } else { + + } + root_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), root); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fapi_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/api.proto b/thirdparty/linux/include/google/protobuf/api.proto new file mode 100644 index 0000000..dbe87b8 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/api.proto @@ -0,0 +1,202 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/source_context.proto"; +import "google/protobuf/type.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "ApiProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; + +// Api is a light-weight descriptor for a protocol buffer service. +message Api { + + // The fully qualified name of this api, including package name + // followed by the api's simple name. + string name = 1; + + // The methods of this api, in unspecified order. + repeated Method methods = 2; + + // Any metadata attached to the API. + repeated Option options = 3; + + // A version string for this api. If specified, must have the form + // `major-version.minor-version`, as in `1.10`. If the minor version + // is omitted, it defaults to zero. If the entire version field is + // empty, the major version is derived from the package name, as + // outlined below. If the field is not empty, the version in the + // package name will be verified to be consistent with what is + // provided here. + // + // The versioning schema uses [semantic + // versioning](http://semver.org) where the major version number + // indicates a breaking change and the minor version an additive, + // non-breaking change. Both version numbers are signals to users + // what to expect from different versions, and should be carefully + // chosen based on the product plan. + // + // The major version is also reflected in the package name of the + // API, which must end in `v`, as in + // `google.feature.v1`. For major versions 0 and 1, the suffix can + // be omitted. Zero major versions must only be used for + // experimental, none-GA apis. + // + // + string version = 4; + + // Source context for the protocol buffer service represented by this + // message. + SourceContext source_context = 5; + + // Included APIs. See [Mixin][]. + repeated Mixin mixins = 6; + + // The source syntax of the service. + Syntax syntax = 7; +} + +// Method represents a method of an api. +message Method { + + // The simple name of this method. + string name = 1; + + // A URL of the input message type. + string request_type_url = 2; + + // If true, the request is streamed. + bool request_streaming = 3; + + // The URL of the output message type. + string response_type_url = 4; + + // If true, the response is streamed. + bool response_streaming = 5; + + // Any metadata attached to the method. + repeated Option options = 6; + + // The source syntax of this method. + Syntax syntax = 7; +} + +// Declares an API to be included in this API. The including API must +// redeclare all the methods from the included API, but documentation +// and options are inherited as follows: +// +// - If after comment and whitespace stripping, the documentation +// string of the redeclared method is empty, it will be inherited +// from the original method. +// +// - Each annotation belonging to the service config (http, +// visibility) which is not set in the redeclared method will be +// inherited. +// +// - If an http annotation is inherited, the path pattern will be +// modified as follows. Any version prefix will be replaced by the +// version of the including API plus the [root][] path if specified. +// +// Example of a simple mixin: +// +// package google.acl.v1; +// service AccessControl { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v1/{resource=**}:getAcl"; +// } +// } +// +// package google.storage.v2; +// service Storage { +// rpc GetAcl(GetAclRequest) returns (Acl); +// +// // Get a data record. +// rpc GetData(GetDataRequest) returns (Data) { +// option (google.api.http).get = "/v2/{resource=**}"; +// } +// } +// +// Example of a mixin configuration: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// +// The mixin construct implies that all methods in `AccessControl` are +// also declared with same name and request/response types in +// `Storage`. A documentation generator or annotation processor will +// see the effective `Storage.GetAcl` method after inherting +// documentation and annotations as follows: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/{resource=**}:getAcl"; +// } +// ... +// } +// +// Note how the version in the path pattern changed from `v1` to `v2`. +// +// If the `root` field in the mixin is specified, it should be a +// relative path under which inherited HTTP paths are placed. Example: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// root: acls +// +// This implies the following inherited HTTP annotation: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; +// } +// ... +// } +message Mixin { + // The fully qualified name of the API which is included. + string name = 1; + + // If non-empty specifies a path under which inherited HTTP paths + // are rooted. + string root = 2; +} diff --git a/thirdparty/linux/include/google/protobuf/arena.h b/thirdparty/linux/include/google/protobuf/arena.h new file mode 100644 index 0000000..58b1e12 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/arena.h @@ -0,0 +1,925 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_ARENA_H__ +#define GOOGLE_PROTOBUF_ARENA_H__ + +#include +#ifdef max +#undef max // Visual Studio defines this macro +#endif +#if __cplusplus >= 201103L +#include +#endif +#if defined(_MSC_VER) && !_HAS_EXCEPTIONS +// Work around bugs in MSVC header when _HAS_EXCEPTIONS=0. +#include +#include +namespace std { +using type_info = ::type_info; +} +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { + +class Arena; // defined below +class Message; // message.h + +namespace internal { +class ArenaString; // arenastring.h +class LazyField; // lazy_field.h + +template +class GenericTypeHandler; // repeated_field.h + +// Templated cleanup methods. +template void arena_destruct_object(void* object) { + reinterpret_cast(object)->~T(); +} +template void arena_delete_object(void* object) { + delete reinterpret_cast(object); +} +inline void arena_free(void* object, size_t /* size */) { + free(object); +} + +} // namespace internal + +// ArenaOptions provides optional additional parameters to arena construction +// that control its block-allocation behavior. +struct ArenaOptions { + // This defines the size of the first block requested from the system malloc. + // Subsequent block sizes will increase in a geometric series up to a maximum. + size_t start_block_size; + + // This defines the maximum block size requested from system malloc (unless an + // individual arena allocation request occurs with a size larger than this + // maximum). Requested block sizes increase up to this value, then remain + // here. + size_t max_block_size; + + // An initial block of memory for the arena to use, or NULL for none. If + // provided, the block must live at least as long as the arena itself. The + // creator of the Arena retains ownership of the block after the Arena is + // destroyed. + char* initial_block; + + // The size of the initial block, if provided. + size_t initial_block_size; + + // A function pointer to an alloc method that returns memory blocks of size + // requested. By default, it contains a ptr to the malloc function. + // + // NOTE: block_alloc and dealloc functions are expected to behave like + // malloc and free, including Asan poisoning. + void* (*block_alloc)(size_t); + // A function pointer to a dealloc method that takes ownership of the blocks + // from the arena. By default, it contains a ptr to a wrapper function that + // calls free. + void (*block_dealloc)(void*, size_t); + + // Hooks for adding external functionality such as user-specific metrics + // collection, specific debugging abilities, etc. + // Init hook may return a pointer to a cookie to be stored in the arena. + // reset and destruction hooks will then be called with the same cookie + // pointer. This allows us to save an external object per arena instance and + // use it on the other hooks (Note: It is just as legal for init to return + // NULL and not use the cookie feature). + // on_arena_reset and on_arena_destruction also receive the space used in + // the arena just before the reset. + void* (*on_arena_init)(Arena* arena); + void (*on_arena_reset)(Arena* arena, void* cookie, uint64 space_used); + void (*on_arena_destruction)(Arena* arena, void* cookie, uint64 space_used); + + // type_info is promised to be static - its lifetime extends to + // match program's lifetime (It is given by typeid operator). + // Note: typeid(void) will be passed as allocated_type every time we + // intentionally want to avoid monitoring an allocation. (i.e. internal + // allocations for managing the arena) + void (*on_arena_allocation)(const std::type_info* allocated_type, + uint64 alloc_size, void* cookie); + + ArenaOptions() + : start_block_size(kDefaultStartBlockSize), + max_block_size(kDefaultMaxBlockSize), + initial_block(NULL), + initial_block_size(0), + block_alloc(&malloc), + block_dealloc(&internal::arena_free), + on_arena_init(NULL), + on_arena_reset(NULL), + on_arena_destruction(NULL), + on_arena_allocation(NULL) {} + + private: + // Constants define default starting block size and max block size for + // arena allocator behavior -- see descriptions above. + static const size_t kDefaultStartBlockSize = 256; + static const size_t kDefaultMaxBlockSize = 8192; +}; + +// Support for non-RTTI environments. (The metrics hooks API uses type +// information.) +#ifndef GOOGLE_PROTOBUF_NO_RTTI +#define RTTI_TYPE_ID(type) (&typeid(type)) +#else +#define RTTI_TYPE_ID(type) (NULL) +#endif + +// Arena allocator. Arena allocation replaces ordinary (heap-based) allocation +// with new/delete, and improves performance by aggregating allocations into +// larger blocks and freeing allocations all at once. Protocol messages are +// allocated on an arena by using Arena::CreateMessage(Arena*), below, and +// are automatically freed when the arena is destroyed. +// +// This is a thread-safe implementation: multiple threads may allocate from the +// arena concurrently. Destruction is not thread-safe and the destructing +// thread must synchronize with users of the arena first. +// +// An arena provides two allocation interfaces: CreateMessage, which works +// for arena-enabled proto2 message types as well as other types that satisfy +// the appropriate protocol (described below), and Create, which works for +// any arbitrary type T. CreateMessage is better when the type T supports it, +// because this interface (i) passes the arena pointer to the created object so +// that its sub-objects and internal allocations can use the arena too, and (ii) +// elides the object's destructor call when possible. Create does not place +// any special requirements on the type T, and will invoke the object's +// destructor when the arena is destroyed. +// +// The arena message allocation protocol, required by CreateMessage, is as +// follows: +// +// - The type T must have (at least) two constructors: a constructor with no +// arguments, called when a T is allocated on the heap; and a constructor with +// a google::protobuf::Arena* argument, called when a T is allocated on an arena. If the +// second constructor is called with a NULL arena pointer, it must be +// equivalent to invoking the first (no-argument) constructor. +// +// - The type T must have a particular type trait: a nested type +// |InternalArenaConstructable_|. This is usually a typedef to |void|. If no +// such type trait exists, then the instantiation CreateMessage will fail +// to compile. +// +// - The type T *may* have the type trait |DestructorSkippable_|. If this type +// trait is present in the type, then its destructor will not be called if and +// only if it was passed a non-NULL arena pointer. If this type trait is not +// present on the type, then its destructor is always called when the +// containing arena is destroyed. +// +// - One- and two-user-argument forms of CreateMessage() also exist that +// forward these constructor arguments to T's constructor: for example, +// CreateMessage(Arena*, arg1, arg2) forwards to a constructor T(Arena*, +// arg1, arg2). +// +// This protocol is implemented by all arena-enabled proto2 message classes as +// well as RepeatedPtrField. + +#if __cplusplus >= 201103L +class LIBPROTOBUF_EXPORT Arena final { +#else +class LIBPROTOBUF_EXPORT Arena { +#endif + public: + // Arena constructor taking custom options. See ArenaOptions below for + // descriptions of the options available. + explicit Arena(const ArenaOptions& options) : options_(options) { + Init(); + } + + // Default constructor with sensible default options, tuned for average + // use-cases. + Arena() { + Init(); + } + + // Destructor deletes all owned heap allocated objects, and destructs objects + // that have non-trivial destructors, except for proto2 message objects whose + // destructors can be skipped. Also, frees all blocks except the initial block + // if it was passed in. + ~Arena(); + + // API to create proto2 message objects on the arena. If the arena passed in + // is NULL, then a heap allocated object is returned. Type T must be a message + // defined in a .proto file with cc_enable_arenas set to true, otherwise a + // compilation error will occur. + // + // RepeatedField and RepeatedPtrField may also be instantiated directly on an + // arena with this method. + // + // This function also accepts any type T that satisfies the arena message + // allocation protocol, documented above. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* CreateMessage(::google::protobuf::Arena* arena) { + if (arena == NULL) { + return new T; + } else { + return arena->CreateMessageInternal(static_cast(0)); + } + } + + // One-argument form of CreateMessage. This is useful for constructing objects + // that implement the arena message construction protocol described above but + // take additional constructor arguments. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* CreateMessage(::google::protobuf::Arena* arena, const Arg& arg) { + if (arena == NULL) { + return new T(NULL, arg); + } else { + return arena->CreateMessageInternal(static_cast(0), + arg); + } + } + + // Two-argument form of CreateMessage. This is useful for constructing objects + // that implement the arena message construction protocol described above but + // take additional constructor arguments. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* CreateMessage(::google::protobuf::Arena* arena, + const Arg1& arg1, + const Arg2& arg2) { + if (arena == NULL) { + return new T(NULL, arg1, arg2); + } else { + return arena->CreateMessageInternal(static_cast(0), + arg1, arg2); + } + } + + // API to create any objects on the arena. Note that only the object will + // be created on the arena; the underlying ptrs (in case of a proto2 message) + // will be still heap allocated. Proto messages should usually be allocated + // with CreateMessage() instead. + // + // Note that even if T satisfies the arena message construction protocol + // (InternalArenaConstructable_ trait and optional DestructorSkippable_ + // trait), as described above, this function does not follow the protocol; + // instead, it treats T as a black-box type, just as if it did not have these + // traits. Specifically, T's constructor arguments will always be only those + // passed to Create() -- no additional arena pointer is implicitly added. + // Furthermore, the destructor will always be called at arena destruction time + // (unless the destructor is trivial). Hence, from T's point of view, it is as + // if the object were allocated on the heap (except that the underlying memory + // is obtained from the arena). + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* Create(::google::protobuf::Arena* arena) { + if (arena == NULL) { + return new T(); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value); + } + } + + // Version of the above with one constructor argument for the created object. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* Create(::google::protobuf::Arena* arena, const Arg& arg) { + if (arena == NULL) { + return new T(arg); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, + arg); + } + } + + // Version of the above with two constructor arguments for the created object. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* Create(::google::protobuf::Arena* arena, const Arg1& arg1, const Arg2& arg2) { + if (arena == NULL) { + return new T(arg1, arg2); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, + arg1, arg2); + } + } + + // Version of the above with three constructor arguments for the created + // object. + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3) { + if (arena == NULL) { + return new T(arg1, arg2, arg3); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, + arg1, arg2, arg3); + } + } + + // Version of the above with four constructor arguments for the created + // object. + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, + arg1, arg2, arg3, arg4); + } + } + + // Version of the above with five constructor arguments for the created + // object. + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, + const Arg5& arg5) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4, arg5); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, + arg1, arg2, arg3, arg4, arg5); + } + } + + // Version of the above with six constructor arguments for the created + // object. + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, + const Arg5& arg5, const Arg6& arg6) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4, arg5, arg6); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, + arg1, arg2, arg3, arg4, arg5, arg6); + } + } + + // Version of the above with seven constructor arguments for the created + // object. + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, + const Arg5& arg5, const Arg6& arg6, + const Arg7& arg7) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, + arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + } + + // Version of the above with eight constructor arguments for the created + // object. + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, + const Arg5& arg5, const Arg6& arg6, + const Arg7& arg7, const Arg8& arg8) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } else { + return arena->CreateInternal( + google::protobuf::internal::has_trivial_destructor::value, + arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + } + + // Create an array of object type T on the arena *without* invoking the + // constructor of T. If `arena` is null, then the return value should be freed + // with `delete[] x;` (or `::operator delete[](x);`). + // To ensure safe uses, this function checks at compile time + // (when compiled as C++11) that T is trivially default-constructible and + // trivially destructible. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* CreateArray(::google::protobuf::Arena* arena, size_t num_elements) { + GOOGLE_CHECK_LE(num_elements, + std::numeric_limits::max() / sizeof(T)) + << "Requested size is too large to fit into size_t."; + if (arena == NULL) { + return static_cast(::operator new[](num_elements * sizeof(T))); + } else { + return arena->CreateInternalRawArray(num_elements); + } + } + + // Returns the total space used by the arena, which is the sums of the sizes + // of the underlying blocks. The total space used may not include the new + // blocks that are allocated by this arena from other threads concurrently + // with the call to this method. + GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceAllocated() const; + // As above, but does not include any free space in underlying blocks. + GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceUsed() const; + + // Combines SpaceAllocated and SpaceUsed. Returns a pair of + // . + GOOGLE_ATTRIBUTE_NOINLINE pair SpaceAllocatedAndUsed() const; + + // Frees all storage allocated by this arena after calling destructors + // registered with OwnDestructor() and freeing objects registered with Own(). + // Any objects allocated on this arena are unusable after this call. It also + // returns the total space used by the arena which is the sums of the sizes + // of the allocated blocks. This method is not thread-safe. + GOOGLE_ATTRIBUTE_NOINLINE uint64 Reset(); + + // Adds |object| to a list of heap-allocated objects to be freed with |delete| + // when the arena is destroyed or reset. + template GOOGLE_ATTRIBUTE_NOINLINE + void Own(T* object) { + OwnInternal(object, google::protobuf::internal::is_convertible()); + } + + // Adds |object| to a list of objects whose destructors will be manually + // called when the arena is destroyed or reset. This differs from Own() in + // that it does not free the underlying memory with |delete|; hence, it is + // normally only used for objects that are placement-newed into + // arena-allocated memory. + template GOOGLE_ATTRIBUTE_NOINLINE + void OwnDestructor(T* object) { + if (object != NULL) { + AddListNode(object, &internal::arena_destruct_object); + } + } + + // Adds a custom member function on an object to the list of destructors that + // will be manually called when the arena is destroyed or reset. This differs + // from OwnDestructor() in that any member function may be specified, not only + // the class destructor. + GOOGLE_ATTRIBUTE_NOINLINE void OwnCustomDestructor(void* object, + void (*destruct)(void*)) { + AddListNode(object, destruct); + } + + // Retrieves the arena associated with |value| if |value| is an arena-capable + // message, or NULL otherwise. This differs from value->GetArena() in that the + // latter is a virtual call, while this method is a templated call that + // resolves at compile-time. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static ::google::protobuf::Arena* GetArena(const T* value) { + return GetArenaInternal(value, static_cast(0)); + } + + private: + struct InternalIsArenaConstructableHelper { + template + static char ArenaConstructable( + const typename U::InternalArenaConstructable_*); + template + static double ArenaConstructable(...); + }; + + public: + // Helper typetrait that indicates support for arenas in a type T at compile + // time. This is public only to allow construction of higher-level templated + // utilities. is_arena_constructable::value is true if the message type T + // has arena support enabled, and false otherwise. + // + // This is inside Arena because only Arena has the friend relationships + // necessary to see the underlying generated code traits. + template + struct is_arena_constructable + : public google::protobuf::internal::integral_constant< + bool, sizeof(InternalIsArenaConstructableHelper::ArenaConstructable< + const T>(static_cast(0))) == sizeof(char)> { + }; + + private: + // Blocks are variable length malloc-ed objects. The following structure + // describes the common header for all blocks. + struct Block { + void* owner; // &ThreadCache of thread that owns this block, or + // &this->owner if not yet owned by a thread. + Block* next; // Next block in arena (may have different owner) + // ((char*) &block) + pos is next available byte. It is always + // aligned at a multiple of 8 bytes. + size_t pos; + size_t size; // total size of the block. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE size_t avail() const { return size - pos; } + // data follows + }; + + template friend class ::google::protobuf::internal::GenericTypeHandler; + friend class MockArena; // For unit-testing. + friend class internal::ArenaString; // For AllocateAligned. + friend class internal::LazyField; // For CreateMaybeMessage. + + struct ThreadCache { + // The ThreadCache is considered valid as long as this matches the + // lifecycle_id of the arena being used. + int64 last_lifecycle_id_seen; + Block* last_block_used_; + }; + + static const size_t kHeaderSize = sizeof(Block); + static google::protobuf::internal::SequenceNumber lifecycle_id_generator_; +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) + // Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread + // local storage class we implemented. + // iOS also does not support the GOOGLE_THREAD_LOCAL keyword. + static ThreadCache& thread_cache(); +#elif defined(PROTOBUF_USE_DLLS) + // Thread local variables cannot be exposed through DLL interface but we can + // wrap them in static functions. + static ThreadCache& thread_cache(); +#else + static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_; + static ThreadCache& thread_cache() { return thread_cache_; } +#endif + + // SFINAE for skipping addition to delete list for a message type when created + // with CreateMessage. This is mainly to skip proto2/proto1 message objects + // with cc_enable_arenas=true from being part of the delete list. Also, note, + // compiler will optimize out the branch in CreateInternal. + template + static inline bool SkipDeleteList(typename T::DestructorSkippable_*) { + return true; + } + + // For message objects that don't have the DestructorSkippable_ trait, we + // always add to the delete list. + template + static inline bool SkipDeleteList(...) { + return google::protobuf::internal::has_trivial_destructor::value; + } + + private: + struct InternalIsDestructorSkippableHelper { + template + static char DestructorSkippable( + const typename U::DestructorSkippable_*); + template + static double DestructorSkippable(...); + }; + + public: + // Helper typetrait that indicates whether the desctructor of type T should be + // called when arena is destroyed at compile time. This is only to allow + // construction of higher-level templated utilities. + // is_destructor_skippable::value is true if the destructor of the message + // type T should not be called when arena is destroyed or false otherwise. + // This is inside Arena because only Arena has the friend relationships + // necessary to see the underlying generated code traits. + template + struct is_destructor_skippable + : public google::protobuf::internal::integral_constant< + bool, + sizeof(InternalIsDestructorSkippableHelper::DestructorSkippable< + const T>(static_cast(0))) == sizeof(char) || + google::protobuf::internal::has_trivial_destructor::value> {}; + + // CreateMessage requires that T supports arenas, but this private method + // works whether or not T supports arenas. These are not exposed to user code + // as it can cause confusing API usages, and end up having double free in + // user code. These are used only internally from LazyField and Repeated + // fields, since they are designed to work in all mode combinations. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static Msg* CreateMaybeMessage( + Arena* arena, typename Msg::InternalArenaConstructable_*) { + return CreateMessage(arena); + } + + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* CreateMaybeMessage(Arena* arena, ...) { + return Create(arena); + } + + // Just allocate the required size for the given type assuming the + // type has a trivial constructor. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + T* CreateInternalRawArray(size_t num_elements) { + GOOGLE_CHECK_LE(num_elements, + std::numeric_limits::max() / sizeof(T)) + << "Requested size is too large to fit into size_t."; + return static_cast( + AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements)); + } + + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + T* CreateInternal(bool skip_explicit_ownership) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + T* CreateInternal(bool skip_explicit_ownership, const Arg& arg) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + T* CreateInternal( + bool skip_explicit_ownership, const Arg1& arg1, const Arg2& arg2) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg1, arg2); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4, + const Arg5& arg5) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4, arg5); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4, + const Arg5& arg5, + const Arg6& arg6) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4, arg5, arg6); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4, + const Arg5& arg5, + const Arg6& arg6, + const Arg7& arg7) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4, + const Arg5& arg5, + const Arg6& arg6, + const Arg7& arg7, + const Arg8& arg8) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object); + } + return t; + } + + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + T* CreateMessageInternal(typename T::InternalArenaConstructable_*) { + return CreateInternal(SkipDeleteList(static_cast(0)), + this); + } + + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + T* CreateMessageInternal(typename T::InternalArenaConstructable_*, + const Arg& arg) { + return CreateInternal(SkipDeleteList(static_cast(0)), + this, arg); + } + + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + T* CreateMessageInternal(typename T::InternalArenaConstructable_*, + const Arg1& arg1, const Arg2& arg2) { + return CreateInternal(SkipDeleteList(static_cast(0)), + this, arg1, arg2); + } + + // CreateInArenaStorage is used to implement map field. Without it, + // google::protobuf::Map need to call generated message's protected arena constructor, + // which needs to declare google::protobuf::Map as friend of generated message. + template + static void CreateInArenaStorage(T* ptr, Arena* arena) { + CreateInArenaStorageInternal(ptr, arena, + typename is_arena_constructable::type()); + RegisterDestructorInternal(ptr, arena, + typename is_destructor_skippable::type()); + } + + template + static void CreateInArenaStorageInternal( + T* ptr, Arena* arena, google::protobuf::internal::true_type) { + new (ptr) T(arena); + } + template + static void CreateInArenaStorageInternal( + T* ptr, Arena* arena, google::protobuf::internal::false_type) { + new (ptr) T(); + } + + template + static void RegisterDestructorInternal( + T* ptr, Arena* arena, google::protobuf::internal::true_type) {} + template + static void RegisterDestructorInternal( + T* ptr, Arena* arena, google::protobuf::internal::false_type) { + arena->OwnDestructor(ptr); + } + + // These implement Own(), which registers an object for deletion (destructor + // call and operator delete()). The second parameter has type 'true_type' if T + // is a subtype of ::google::protobuf::Message and 'false_type' otherwise. Collapsing + // all template instantiations to one for generic Message reduces code size, + // using the virtual destructor instead. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + void OwnInternal(T* object, google::protobuf::internal::true_type) { + if (object != NULL) { + AddListNode(object, &internal::arena_delete_object< ::google::protobuf::Message >); + } + } + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + void OwnInternal(T* object, google::protobuf::internal::false_type) { + if (object != NULL) { + AddListNode(object, &internal::arena_delete_object); + } + } + + // Implementation for GetArena(). Only message objects with + // InternalArenaConstructable_ tags can be associated with an arena, and such + // objects must implement a GetArenaNoVirtual() method. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static ::google::protobuf::Arena* GetArenaInternal( + const T* value, typename T::InternalArenaConstructable_*) { + return value->GetArenaNoVirtual(); + } + + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static ::google::protobuf::Arena* GetArenaInternal(const T* value, ...) { + return NULL; + } + + // Allocate and also optionally call on_arena_allocation callback with the + // allocated type info when the hooks are in place in ArenaOptions and + // the cookie is not null. + void* AllocateAligned(const std::type_info* allocated, size_t n); + + // Allocate an internal allocation, avoiding optional typed monitoring. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* AllocateAligned(size_t n) { + return AllocateAligned(NULL, n); + } + + void Init(); + + // Free all blocks and return the total space used which is the sums of sizes + // of the all the allocated blocks. + uint64 FreeBlocks(); + + // Add object pointer and cleanup function pointer to the list. + // TODO(rohananil, cfallin): We could pass in a sub-arena into this method + // to avoid polluting blocks of this arena with list nodes. This would help in + // mixed mode (where many protobufs have cc_enable_arenas=false), and is an + // alternative to a chunked linked-list, but with extra overhead of *next. + void AddListNode(void* elem, void (*cleanup)(void*)); + // Delete or Destruct all objects owned by the arena. + void CleanupList(); + uint64 ResetInternal(); + + inline void SetThreadCacheBlock(Block* block) { + thread_cache().last_block_used_ = block; + thread_cache().last_lifecycle_id_seen = lifecycle_id_; + } + + int64 lifecycle_id_; // Unique for each arena. Changes on Reset(). + + google::protobuf::internal::AtomicWord blocks_; // Head of linked list of all allocated blocks + google::protobuf::internal::AtomicWord hint_; // Fast thread-local block access + + // Node contains the ptr of the object to be cleaned up and the associated + // cleanup function ptr. + struct Node { + void* elem; // Pointer to the object to be cleaned up. + void (*cleanup)(void*); // Function pointer to the destructor or deleter. + Node* next; // Next node in the list. + }; + + google::protobuf::internal::AtomicWord cleanup_list_; // Head of a linked list of nodes containing object + // ptrs and cleanup methods. + + bool owns_first_block_; // Indicates that arena owns the first block + Mutex blocks_lock_; + + void AddBlock(Block* b); + // Access must be synchronized, either by blocks_lock_ or by being called from + // Init()/Reset(). + void AddBlockInternal(Block* b); + void* SlowAlloc(size_t n); + Block* FindBlock(void* me); + Block* NewBlock(void* me, Block* my_last_block, size_t n, + size_t start_block_size, size_t max_block_size); + static void* AllocFromBlock(Block* b, size_t n); + template + friend class Map; + + // The arena may save a cookie it receives from the external on_init hook + // and then use it when calling the on_reset and on_destruction hooks. + void* hooks_cookie_; + + ArenaOptions options_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Arena); +}; + +// Defined above for supporting environments without RTTI. +#undef RTTI_TYPE_ID + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_ARENA_H__ diff --git a/thirdparty/linux/include/google/protobuf/arenastring.h b/thirdparty/linux/include/google/protobuf/arenastring.h new file mode 100644 index 0000000..590ffce --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/arenastring.h @@ -0,0 +1,314 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ +#define GOOGLE_PROTOBUF_ARENASTRING_H__ + +#include + +#include +#include +#include +#include +#include + + + +// This is the implementation of arena string fields written for the open-source +// release. The ArenaStringPtr struct below is an internal implementation class +// and *should not be used* by user code. It is used to collect string +// operations together into one place and abstract away the underlying +// string-field pointer representation, so that (for example) an alternate +// implementation that knew more about ::std::string's internals could integrate more +// closely with the arena allocator. + +namespace google { +namespace protobuf { +namespace internal { + +struct LIBPROTOBUF_EXPORT ArenaStringPtr { + inline void Set(const ::std::string* default_value, + const ::std::string& value, ::google::protobuf::Arena* arena) { + if (ptr_ == default_value) { + CreateInstance(arena, &value); + } else { + *ptr_ = value; + } + } + + // Basic accessors. + inline const ::std::string& Get(const ::std::string* /* default_value */) const { + return *ptr_; + } + + inline ::std::string* Mutable(const ::std::string* default_value, + ::google::protobuf::Arena* arena) { + if (ptr_ == default_value) { + CreateInstance(arena, default_value); + } + return ptr_; + } + + // Release returns a ::std::string* instance that is heap-allocated and is not + // Own()'d by any arena. If the field was not set, it returns NULL. The caller + // retains ownership. Clears this field back to NULL state. Used to implement + // release_() methods on generated classes. + inline ::std::string* Release(const ::std::string* default_value, + ::google::protobuf::Arena* arena) { + if (ptr_ == default_value) { + return NULL; + } + ::std::string* released = NULL; + if (arena != NULL) { + // ptr_ is owned by the arena -- we need to return a copy. + released = new ::std::string(*ptr_); + } else { + released = ptr_; + } + ptr_ = const_cast< ::std::string* >(default_value); + return released; + } + + // UnsafeArenaRelease returns a ::std::string*, but it may be arena-owned (i.e. + // have its destructor already registered) if arena != NULL. If the field was + // not set, this returns NULL. This method clears this field back to NULL + // state. Used to implement unsafe_arena_release_() methods on + // generated classes. + inline ::std::string* UnsafeArenaRelease(const ::std::string* default_value, + ::google::protobuf::Arena* /* arena */) { + if (ptr_ == default_value) { + return NULL; + } + ::std::string* released = ptr_; + ptr_ = const_cast< ::std::string* >(default_value); + return released; + } + + // Takes a string that is heap-allocated, and takes ownership. The string's + // destructor is registered with the arena. Used to implement + // set_allocated_ in generated classes. + inline void SetAllocated(const ::std::string* default_value, + ::std::string* value, ::google::protobuf::Arena* arena) { + if (arena == NULL && ptr_ != default_value) { + Destroy(default_value, arena); + } + if (value != NULL) { + ptr_ = value; + if (arena != NULL) { + arena->Own(value); + } + } else { + ptr_ = const_cast< ::std::string* >(default_value); + } + } + + // Takes a string that has lifetime equal to the arena's lifetime. The arena + // must be non-null. It is safe only to pass this method a value returned by + // UnsafeArenaRelease() on another field of a message in the same arena. Used + // to implement unsafe_arena_set_allocated_ in generated classes. + inline void UnsafeArenaSetAllocated(const ::std::string* default_value, + ::std::string* value, + ::google::protobuf::Arena* /* arena */) { + if (value != NULL) { + ptr_ = value; + } else { + ptr_ = const_cast< ::std::string* >(default_value); + } + } + + // Swaps internal pointers. Arena-safety semantics: this is guarded by the + // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is + // 'unsafe' if called directly. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) { + std::swap(ptr_, other->ptr_); + } + + // Frees storage (if not on an arena) and sets field to default value. + inline void Destroy(const ::std::string* default_value, + ::google::protobuf::Arena* arena) { + if (arena == NULL && ptr_ != default_value) { + delete ptr_; + } + ptr_ = const_cast< ::std::string* >(default_value); + } + + // Clears content, but keeps allocated string if arena != NULL, to avoid the + // overhead of heap operations. After this returns, the content (as seen by + // the user) will always be the empty string. Assumes that |default_value| + // is an empty string. + inline void ClearToEmpty(const ::std::string* default_value, + ::google::protobuf::Arena* /* arena */) { + if (ptr_ == default_value) { + // Already set to default (which is empty) -- do nothing. + } else { + ptr_->clear(); + } + } + + // Clears content, but keeps allocated string if arena != NULL, to avoid the + // overhead of heap operations. After this returns, the content (as seen by + // the user) will always be equal to |default_value|. + inline void ClearToDefault(const ::std::string* default_value, + ::google::protobuf::Arena* /* arena */) { + if (ptr_ == default_value) { + // Already set to default -- do nothing. + } else { + // Have another allocated string -- rather than throwing this away and + // resetting ptr_ to the canonical default string instance, we just reuse + // this instance. + *ptr_ = *default_value; + } + } + + // Called from generated code / reflection runtime only. Resets value to point + // to a default string pointer, with the semantics that this ArenaStringPtr + // does not own the pointed-to memory. Disregards initial value of ptr_ (so + // this is the *ONLY* safe method to call after construction or when + // reinitializing after becoming the active field in a oneof union). + inline void UnsafeSetDefault(const ::std::string* default_value) { + // Casting away 'const' is safe here: accessors ensure that ptr_ is only + // returned as a const if it is equal to default_value. + ptr_ = const_cast< ::std::string* >(default_value); + } + + // The 'NoArena' variants of methods below assume arena == NULL and are + // optimized to provide very little overhead relative to a raw string pointer + // (while still being in-memory compatible with other code that assumes + // ArenaStringPtr). Note the invariant that a class instance that has only + // ever been mutated by NoArena methods must *only* be in the String state + // (i.e., tag bits are not used), *NEVER* ArenaString. This allows all + // tagged-pointer manipulations to be avoided. + inline void SetNoArena(const ::std::string* default_value, + const ::std::string& value) { + if (ptr_ == default_value) { + CreateInstanceNoArena(&value); + } else { + *ptr_ = value; + } + } + + void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr value); + + inline const ::std::string& GetNoArena(const ::std::string* /* default_value */) const { + return *ptr_; + } + + inline ::std::string* MutableNoArena(const ::std::string* default_value) { + if (ptr_ == default_value) { + CreateInstanceNoArena(default_value); + } + return ptr_; + } + + inline ::std::string* ReleaseNoArena(const ::std::string* default_value) { + if (ptr_ == default_value) { + return NULL; + } else { + ::std::string* released = ptr_; + ptr_ = const_cast< ::std::string* >(default_value); + return released; + } + } + + inline void SetAllocatedNoArena(const ::std::string* default_value, + ::std::string* value) { + if (ptr_ != default_value) { + delete ptr_; + } + if (value != NULL) { + ptr_ = value; + } else { + ptr_ = const_cast< ::std::string* >(default_value); + } + } + + inline void DestroyNoArena(const ::std::string* default_value) { + if (ptr_ != default_value) { + delete ptr_; + } + ptr_ = NULL; + } + + inline void ClearToEmptyNoArena(const ::std::string* default_value) { + if (ptr_ == default_value) { + // Nothing: already equal to default (which is the empty string). + } else { + ptr_->clear(); + } + } + + inline void ClearToDefaultNoArena(const ::std::string* default_value) { + if (ptr_ == default_value) { + // Nothing: already set to default. + } else { + // Reuse existing allocated instance. + *ptr_ = *default_value; + } + } + + // Internal accessor used only at parse time to provide direct access to the + // raw pointer from the shared parse routine (in the non-arenas case). The + // parse routine does the string allocation in order to save code size in the + // generated parsing code. + inline ::std::string** UnsafeRawStringPointer() { + return &ptr_; + } + + private: + ::std::string* ptr_; + + GOOGLE_ATTRIBUTE_NOINLINE void CreateInstance(::google::protobuf::Arena* arena, + const ::std::string* initial_value) { + // Assumes ptr_ is not NULL. + if (initial_value != NULL) { + ptr_ = new ::std::string(*initial_value); + } else { + ptr_ = new ::std::string(); + } + if (arena != NULL) { + arena->Own(ptr_); + } + } + GOOGLE_ATTRIBUTE_NOINLINE void CreateInstanceNoArena(const ::std::string* initial_value) { + if (initial_value != NULL) { + ptr_ = new ::std::string(*initial_value); + } else { + ptr_ = new ::std::string(); + } + } +}; + +} // namespace internal +} // namespace protobuf + + + +} // namespace google +#endif // GOOGLE_PROTOBUF_ARENASTRING_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/code_generator.h b/thirdparty/linux/include/google/protobuf/compiler/code_generator.h new file mode 100644 index 0000000..b989f15 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/code_generator.h @@ -0,0 +1,176 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines the abstract interface implemented by each of the language-specific +// code generators. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ + +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace io { class ZeroCopyOutputStream; } +class FileDescriptor; + +namespace compiler { + +// Defined in this file. +class CodeGenerator; +class GeneratorContext; + +// The abstract interface to a class which generates code implementing a +// particular proto file in a particular language. A number of these may +// be registered with CommandLineInterface to support various languages. +class LIBPROTOC_EXPORT CodeGenerator { + public: + inline CodeGenerator() {} + virtual ~CodeGenerator(); + + // Generates code for the given proto file, generating one or more files in + // the given output directory. + // + // A parameter to be passed to the generator can be specified on the + // command line. This is intended to be used by Java and similar languages + // to specify which specific class from the proto file is to be generated, + // though it could have other uses as well. It is empty if no parameter was + // given. + // + // Returns true if successful. Otherwise, sets *error to a description of + // the problem (e.g. "invalid parameter") and returns false. + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const = 0; + + // Generates code for all given proto files, generating one or more files in + // the given output directory. + // + // This method should be called instead of |Generate()| when + // |HasGenerateAll()| returns |true|. It is used to emulate legacy semantics + // when more than one `.proto` file is specified on one compiler invocation. + // + // WARNING: Please do not use unless legacy semantics force the code generator + // to produce a single output file for all input files, or otherwise require + // an examination of all input files first. The canonical code generator + // design produces one output file per input .proto file, and we do not wish + // to encourage alternate designs. + // + // A parameter is given as passed on the command line, as in |Generate()| + // above. + // + // Returns true if successful. Otherwise, sets *error to a description of + // the problem (e.g. "invalid parameter") and returns false. + virtual bool GenerateAll(const vector& files, + const string& parameter, + GeneratorContext* generator_context, + string* error) const { + *error = "Unimplemented GenerateAll() method."; + return false; + } + + // Returns true if the code generator expects to receive all FileDescriptors + // at once (via |GenerateAll()|), rather than one at a time (via + // |Generate()|). This is required to implement legacy semantics. + virtual bool HasGenerateAll() const { return false; } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodeGenerator); +}; + +// CodeGenerators generate one or more files in a given directory. This +// abstract interface represents the directory to which the CodeGenerator is +// to write and other information about the context in which the Generator +// runs. +class LIBPROTOC_EXPORT GeneratorContext { + public: + inline GeneratorContext() {} + virtual ~GeneratorContext(); + + // Opens the given file, truncating it if it exists, and returns a + // ZeroCopyOutputStream that writes to the file. The caller takes ownership + // of the returned object. This method never fails (a dummy stream will be + // returned instead). + // + // The filename given should be relative to the root of the source tree. + // E.g. the C++ generator, when generating code for "foo/bar.proto", will + // generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that + // "foo/" is included in these filenames. The filename is not allowed to + // contain "." or ".." components. + virtual io::ZeroCopyOutputStream* Open(const string& filename) = 0; + + // Similar to Open() but the output will be appended to the file if exists + virtual io::ZeroCopyOutputStream* OpenForAppend(const string& filename); + + // Creates a ZeroCopyOutputStream which will insert code into the given file + // at the given insertion point. See plugin.proto (plugin.pb.h) for more + // information on insertion points. The default implementation + // assert-fails -- it exists only for backwards-compatibility. + // + // WARNING: This feature is currently EXPERIMENTAL and is subject to change. + virtual io::ZeroCopyOutputStream* OpenForInsert( + const string& filename, const string& insertion_point); + + // Returns a vector of FileDescriptors for all the files being compiled + // in this run. Useful for languages, such as Go, that treat files + // differently when compiled as a set rather than individually. + virtual void ListParsedFiles(vector* output); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext); +}; + +// The type GeneratorContext was once called OutputDirectory. This typedef +// provides backward compatibility. +typedef GeneratorContext OutputDirectory; + +// Several code generators treat the parameter argument as holding a +// list of options separated by commas. This helper function parses +// a set of comma-delimited name/value pairs: e.g., +// "foo=bar,baz,qux=corge" +// parses to the pairs: +// ("foo", "bar"), ("baz", ""), ("qux", "corge") +extern void ParseGeneratorParameter(const string&, + vector >*); + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/command_line_interface.h b/thirdparty/linux/include/google/protobuf/compiler/command_line_interface.h new file mode 100644 index 0000000..d137766 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/command_line_interface.h @@ -0,0 +1,394 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Implements the Protocol Compiler front-end such that it may be reused by +// custom compilers written to support other languages. + +#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ +#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +class Descriptor; // descriptor.h +class DescriptorPool; // descriptor.h +class FileDescriptor; // descriptor.h +class FileDescriptorProto; // descriptor.pb.h +template class RepeatedPtrField; // repeated_field.h + +namespace compiler { + +class CodeGenerator; // code_generator.h +class GeneratorContext; // code_generator.h +class DiskSourceTree; // importer.h + +// This class implements the command-line interface to the protocol compiler. +// It is designed to make it very easy to create a custom protocol compiler +// supporting the languages of your choice. For example, if you wanted to +// create a custom protocol compiler binary which includes both the regular +// C++ support plus support for your own custom output "Foo", you would +// write a class "FooGenerator" which implements the CodeGenerator interface, +// then write a main() procedure like this: +// +// int main(int argc, char* argv[]) { +// google::protobuf::compiler::CommandLineInterface cli; +// +// // Support generation of C++ source and headers. +// google::protobuf::compiler::cpp::CppGenerator cpp_generator; +// cli.RegisterGenerator("--cpp_out", &cpp_generator, +// "Generate C++ source and header."); +// +// // Support generation of Foo code. +// FooGenerator foo_generator; +// cli.RegisterGenerator("--foo_out", &foo_generator, +// "Generate Foo file."); +// +// return cli.Run(argc, argv); +// } +// +// The compiler is invoked with syntax like: +// protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto +// +// For a full description of the command-line syntax, invoke it with --help. +class LIBPROTOC_EXPORT CommandLineInterface { + public: + CommandLineInterface(); + ~CommandLineInterface(); + + // Register a code generator for a language. + // + // Parameters: + // * flag_name: The command-line flag used to specify an output file of + // this type. The name must start with a '-'. If the name is longer + // than one letter, it must start with two '-'s. + // * generator: The CodeGenerator which will be called to generate files + // of this type. + // * help_text: Text describing this flag in the --help output. + // + // Some generators accept extra parameters. You can specify this parameter + // on the command-line by placing it before the output directory, separated + // by a colon: + // protoc --foo_out=enable_bar:outdir + // The text before the colon is passed to CodeGenerator::Generate() as the + // "parameter". + void RegisterGenerator(const string& flag_name, + CodeGenerator* generator, + const string& help_text); + + // Register a code generator for a language. + // Besides flag_name you can specify another option_flag_name that could be + // used to pass extra parameters to the registered code generator. + // Suppose you have registered a generator by calling: + // command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...) + // Then you could invoke the compiler with a command like: + // protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz + // This will pass "enable_bar,enable_baz" as the parameter to the generator. + void RegisterGenerator(const string& flag_name, + const string& option_flag_name, + CodeGenerator* generator, + const string& help_text); + + // Enables "plugins". In this mode, if a command-line flag ends with "_out" + // but does not match any registered generator, the compiler will attempt to + // find a "plugin" to implement the generator. Plugins are just executables. + // They should live somewhere in the PATH. + // + // The compiler determines the executable name to search for by concatenating + // exe_name_prefix with the unrecognized flag name, removing "_out". So, for + // example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out, + // the compiler will try to run the program "protoc-foo". + // + // The plugin program should implement the following usage: + // plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS + // --out indicates the output directory (as passed to the --foo_out + // parameter); if omitted, the current directory should be used. --parameter + // gives the generator parameter, if any was provided. The PROTO_FILES list + // the .proto files which were given on the compiler command-line; these are + // the files for which the plugin is expected to generate output code. + // Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in + // descriptor.proto). This is piped to the plugin's stdin. The set will + // include descriptors for all the files listed in PROTO_FILES as well as + // all files that they import. The plugin MUST NOT attempt to read the + // PROTO_FILES directly -- it must use the FileDescriptorSet. + // + // The plugin should generate whatever files are necessary, as code generators + // normally do. It should write the names of all files it generates to + // stdout. The names should be relative to the output directory, NOT absolute + // names or relative to the current directory. If any errors occur, error + // messages should be written to stderr. If an error is fatal, the plugin + // should exit with a non-zero exit code. + void AllowPlugins(const string& exe_name_prefix); + + // Run the Protocol Compiler with the given command-line parameters. + // Returns the error code which should be returned by main(). + // + // It may not be safe to call Run() in a multi-threaded environment because + // it calls strerror(). I'm not sure why you'd want to do this anyway. + int Run(int argc, const char* const argv[]); + + // Call SetInputsAreCwdRelative(true) if the input files given on the command + // line should be interpreted relative to the proto import path specified + // using --proto_path or -I flags. Otherwise, input file names will be + // interpreted relative to the current working directory (or as absolute + // paths if they start with '/'), though they must still reside inside + // a directory given by --proto_path or the compiler will fail. The latter + // mode is generally more intuitive and easier to use, especially e.g. when + // defining implicit rules in Makefiles. + void SetInputsAreProtoPathRelative(bool enable) { + inputs_are_proto_path_relative_ = enable; + } + + // Provides some text which will be printed when the --version flag is + // used. The version of libprotoc will also be printed on the next line + // after this text. + void SetVersionInfo(const string& text) { + version_info_ = text; + } + + + private: + // ----------------------------------------------------------------- + + class ErrorPrinter; + class GeneratorContextImpl; + class MemoryOutputStream; + typedef hash_map GeneratorContextMap; + + // Clear state from previous Run(). + void Clear(); + + // Remaps each file in input_files_ so that it is relative to one of the + // directories in proto_path_. Returns false if an error occurred. This + // is only used if inputs_are_proto_path_relative_ is false. + bool MakeInputsBeProtoPathRelative( + DiskSourceTree* source_tree); + + // Return status for ParseArguments() and InterpretArgument(). + enum ParseArgumentStatus { + PARSE_ARGUMENT_DONE_AND_CONTINUE, + PARSE_ARGUMENT_DONE_AND_EXIT, + PARSE_ARGUMENT_FAIL + }; + + // Parse all command-line arguments. + ParseArgumentStatus ParseArguments(int argc, const char* const argv[]); + + + // Parses a command-line argument into a name/value pair. Returns + // true if the next argument in the argv should be used as the value, + // false otherwise. + // + // Examples: + // "-Isrc/protos" -> + // name = "-I", value = "src/protos" + // "--cpp_out=src/foo.pb2.cc" -> + // name = "--cpp_out", value = "src/foo.pb2.cc" + // "foo.proto" -> + // name = "", value = "foo.proto" + bool ParseArgument(const char* arg, string* name, string* value); + + // Interprets arguments parsed with ParseArgument. + ParseArgumentStatus InterpretArgument(const string& name, + const string& value); + + // Print the --help text to stderr. + void PrintHelpText(); + + // Generate the given output file from the given input. + struct OutputDirective; // see below + bool GenerateOutput(const vector& parsed_files, + const OutputDirective& output_directive, + GeneratorContext* generator_context); + bool GeneratePluginOutput(const vector& parsed_files, + const string& plugin_name, + const string& parameter, + GeneratorContext* generator_context, + string* error); + + // Implements --encode and --decode. + bool EncodeOrDecode(const DescriptorPool* pool); + + // Implements the --descriptor_set_out option. + bool WriteDescriptorSet(const vector parsed_files); + + // Implements the --dependency_out option + bool GenerateDependencyManifestFile( + const vector& parsed_files, + const GeneratorContextMap& output_directories, + DiskSourceTree* source_tree); + + // Get all transitive dependencies of the given file (including the file + // itself), adding them to the given list of FileDescriptorProtos. The + // protos will be ordered such that every file is listed before any file that + // depends on it, so that you can call DescriptorPool::BuildFile() on them + // in order. Any files in *already_seen will not be added, and each file + // added will be inserted into *already_seen. If include_source_code_info is + // true then include the source code information in the FileDescriptorProtos. + // If include_json_name is true, populate the json_name field of + // FieldDescriptorProto for all fields. + static void GetTransitiveDependencies( + const FileDescriptor* file, + bool include_json_name, + bool include_source_code_info, + set* already_seen, + RepeatedPtrField* output); + + // Implements the --print_free_field_numbers. This function prints free field + // numbers into stdout for the message and it's nested message types in + // post-order, i.e. nested types first. Printed range are left-right + // inclusive, i.e. [a, b]. + // + // Groups: + // For historical reasons, groups are considered to share the same + // field number space with the parent message, thus it will not print free + // field numbers for groups. The field numbers used in the groups are + // excluded in the free field numbers of the parent message. + // + // Extension Ranges: + // Extension ranges are considered ocuppied field numbers and they will not be + // listed as free numbers in the output. + void PrintFreeFieldNumbers(const Descriptor* descriptor); + + // ----------------------------------------------------------------- + + // The name of the executable as invoked (i.e. argv[0]). + string executable_name_; + + // Version info set with SetVersionInfo(). + string version_info_; + + // Registered generators. + struct GeneratorInfo { + string flag_name; + string option_flag_name; + CodeGenerator* generator; + string help_text; + }; + typedef map GeneratorMap; + GeneratorMap generators_by_flag_name_; + GeneratorMap generators_by_option_name_; + // A map from generator names to the parameters specified using the option + // flag. For example, if the user invokes the compiler with: + // protoc --foo_out=outputdir --foo_opt=enable_bar ... + // Then there will be an entry ("--foo_out", "enable_bar") in this map. + map generator_parameters_; + + // See AllowPlugins(). If this is empty, plugins aren't allowed. + string plugin_prefix_; + + // Maps specific plugin names to files. When executing a plugin, this map + // is searched first to find the plugin executable. If not found here, the + // PATH (or other OS-specific search strategy) is searched. + map plugins_; + + // Stuff parsed from command line. + enum Mode { + MODE_COMPILE, // Normal mode: parse .proto files and compile them. + MODE_ENCODE, // --encode: read text from stdin, write binary to stdout. + MODE_DECODE, // --decode: read binary from stdin, write text to stdout. + MODE_PRINT, // Print mode: print info of the given .proto files and exit. + }; + + Mode mode_; + + enum PrintMode { + PRINT_NONE, // Not in MODE_PRINT + PRINT_FREE_FIELDS, // --print_free_fields + }; + + PrintMode print_mode_; + + enum ErrorFormat { + ERROR_FORMAT_GCC, // GCC error output format (default). + ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs). + }; + + ErrorFormat error_format_; + + vector > proto_path_; // Search path for proto files. + vector input_files_; // Names of the input proto files. + + // output_directives_ lists all the files we are supposed to output and what + // generator to use for each. + struct OutputDirective { + string name; // E.g. "--foo_out" + CodeGenerator* generator; // NULL for plugins + string parameter; + string output_location; + }; + vector output_directives_; + + // When using --encode or --decode, this names the type we are encoding or + // decoding. (Empty string indicates --decode_raw.) + string codec_type_; + + // If --descriptor_set_out was given, this is the filename to which the + // FileDescriptorSet should be written. Otherwise, empty. + string descriptor_set_name_; + + // If --dependency_out was given, this is the path to the file where the + // dependency file will be written. Otherwise, empty. + string dependency_out_name_; + + // True if --include_imports was given, meaning that we should + // write all transitive dependencies to the DescriptorSet. Otherwise, only + // the .proto files listed on the command-line are added. + bool imports_in_descriptor_set_; + + // True if --include_source_info was given, meaning that we should not strip + // SourceCodeInfo from the DescriptorSet. + bool source_info_in_descriptor_set_; + + // Was the --disallow_services flag used? + bool disallow_services_; + + // See SetInputsAreProtoPathRelative(). + bool inputs_are_proto_path_relative_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface); +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/cpp/cpp_generator.h b/thirdparty/linux/include/google/protobuf/compiler/cpp/cpp_generator.h new file mode 100644 index 0000000..3d517cf --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/cpp/cpp_generator.h @@ -0,0 +1,72 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Generates C++ code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// CodeGenerator implementation which generates a C++ source file and +// header. If you create your own protocol compiler binary and you want +// it to support C++ output, you can do so by registering an instance of this +// CodeGenerator with the CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator { + public: + CppGenerator(); + ~CppGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/csharp/csharp_generator.h b/thirdparty/linux/include/google/protobuf/compiler/csharp/csharp_generator.h new file mode 100644 index 0000000..9b54e91 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/csharp/csharp_generator.h @@ -0,0 +1,58 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ + +#include + +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class LIBPROTOC_EXPORT Generator + : public google::protobuf::compiler::CodeGenerator { + virtual bool Generate( + const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const; +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ + diff --git a/thirdparty/linux/include/google/protobuf/compiler/csharp/csharp_names.h b/thirdparty/linux/include/google/protobuf/compiler/csharp/csharp_names.h new file mode 100644 index 0000000..3080518 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/csharp/csharp_names.h @@ -0,0 +1,103 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Provides a mechanism for mapping a descriptor to the +// fully-qualified name of the corresponding C# class. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__ + +#include + +namespace google { +namespace protobuf { + +class Descriptor; +class EnumDescriptor; +class FileDescriptor; +class ServiceDescriptor; + +namespace compiler { +namespace csharp { + +// Requires: +// descriptor != NULL +// +// Returns: +// The namespace to use for given file descriptor. +string GetFileNamespace(const FileDescriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified C# class name. +string GetClassName(const Descriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified name of the C# class that provides +// access to the file descriptor. Proto compiler generates +// such class for each .proto file processed. +string GetReflectionClassName(const FileDescriptor* descriptor); + +// Generates output file name for given file descriptor. If generate_directories +// is true, the output file will be put under directory corresponding to file's +// namespace. base_namespace can be used to strip some of the top level +// directories. E.g. for file with namespace "Bar.Foo" and base_namespace="Bar", +// the resulting file will be put under directory "Foo" (and not "Bar/Foo"). +// +// Requires: +// descriptor != NULL +// error != NULL +// +// Returns: +// The file name to use as output file for given file descriptor. In case +// of failure, this function will return empty string and error parameter +// will contain the error message. +string GetOutputFile( + const google::protobuf::FileDescriptor* descriptor, + const string file_extension, + const bool generate_directories, + const string base_namespace, + string* error); + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/importer.h b/thirdparty/linux/include/google/protobuf/compiler/importer.h new file mode 100644 index 0000000..cc8fcc3 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/importer.h @@ -0,0 +1,326 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file is the public interface to the .proto file parser. + +#ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ +#define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace io { class ZeroCopyInputStream; } + +namespace compiler { + +// Defined in this file. +class Importer; +class MultiFileErrorCollector; +class SourceTree; +class DiskSourceTree; + +// TODO(kenton): Move all SourceTree stuff to a separate file? + +// An implementation of DescriptorDatabase which loads files from a SourceTree +// and parses them. +// +// Note: This class is not thread-safe since it maintains a table of source +// code locations for error reporting. However, when a DescriptorPool wraps +// a DescriptorDatabase, it uses mutex locking to make sure only one method +// of the database is called at a time, even if the DescriptorPool is used +// from multiple threads. Therefore, there is only a problem if you create +// multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase +// and use them from multiple threads. +// +// Note: This class does not implement FindFileContainingSymbol() or +// FindFileContainingExtension(); these will always return false. +class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { + public: + SourceTreeDescriptorDatabase(SourceTree* source_tree); + ~SourceTreeDescriptorDatabase(); + + // Instructs the SourceTreeDescriptorDatabase to report any parse errors + // to the given MultiFileErrorCollector. This should be called before + // parsing. error_collector must remain valid until either this method + // is called again or the SourceTreeDescriptorDatabase is destroyed. + void RecordErrorsTo(MultiFileErrorCollector* error_collector) { + error_collector_ = error_collector; + } + + // Gets a DescriptorPool::ErrorCollector which records errors to the + // MultiFileErrorCollector specified with RecordErrorsTo(). This collector + // has the ability to determine exact line and column numbers of errors + // from the information given to it by the DescriptorPool. + DescriptorPool::ErrorCollector* GetValidationErrorCollector() { + using_validation_error_collector_ = true; + return &validation_error_collector_; + } + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + + private: + class SingleFileErrorCollector; + + SourceTree* source_tree_; + MultiFileErrorCollector* error_collector_; + + class LIBPROTOBUF_EXPORT ValidationErrorCollector : public DescriptorPool::ErrorCollector { + public: + ValidationErrorCollector(SourceTreeDescriptorDatabase* owner); + ~ValidationErrorCollector(); + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message); + + virtual void AddWarning(const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message); + + private: + SourceTreeDescriptorDatabase* owner_; + }; + friend class ValidationErrorCollector; + + bool using_validation_error_collector_; + SourceLocationTable source_locations_; + ValidationErrorCollector validation_error_collector_; +}; + +// Simple interface for parsing .proto files. This wraps the process +// of opening the file, parsing it with a Parser, recursively parsing all its +// imports, and then cross-linking the results to produce a FileDescriptor. +// +// This is really just a thin wrapper around SourceTreeDescriptorDatabase. +// You may find that SourceTreeDescriptorDatabase is more flexible. +// +// TODO(kenton): I feel like this class is not well-named. +class LIBPROTOBUF_EXPORT Importer { + public: + Importer(SourceTree* source_tree, + MultiFileErrorCollector* error_collector); + ~Importer(); + + // Import the given file and build a FileDescriptor representing it. If + // the file is already in the DescriptorPool, the existing FileDescriptor + // will be returned. The FileDescriptor is property of the DescriptorPool, + // and will remain valid until it is destroyed. If any errors occur, they + // will be reported using the error collector and Import() will return NULL. + // + // A particular Importer object will only report errors for a particular + // file once. All future attempts to import the same file will return NULL + // without reporting any errors. The idea is that you might want to import + // a lot of files without seeing the same errors over and over again. If + // you want to see errors for the same files repeatedly, you can use a + // separate Importer object to import each one (but use the same + // DescriptorPool so that they can be cross-linked). + const FileDescriptor* Import(const string& filename); + + // The DescriptorPool in which all imported FileDescriptors and their + // contents are stored. + inline const DescriptorPool* pool() const { + return &pool_; + } + + void AddUnusedImportTrackFile(const string& file_name); + void ClearUnusedImportTrackFiles(); + + private: + SourceTreeDescriptorDatabase database_; + DescriptorPool pool_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer); +}; + +// If the importer encounters problems while trying to import the proto files, +// it reports them to a MultiFileErrorCollector. +class LIBPROTOBUF_EXPORT MultiFileErrorCollector { + public: + inline MultiFileErrorCollector() {} + virtual ~MultiFileErrorCollector(); + + // Line and column numbers are zero-based. A line number of -1 indicates + // an error with the entire file (e.g. "not found"). + virtual void AddError(const string& filename, int line, int column, + const string& message) = 0; + + virtual void AddWarning(const string& filename, int line, int column, + const string& message) {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector); +}; + +// Abstract interface which represents a directory tree containing proto files. +// Used by the default implementation of Importer to resolve import statements +// Most users will probably want to use the DiskSourceTree implementation, +// below. +class LIBPROTOBUF_EXPORT SourceTree { + public: + inline SourceTree() {} + virtual ~SourceTree(); + + // Open the given file and return a stream that reads it, or NULL if not + // found. The caller takes ownership of the returned object. The filename + // must be a path relative to the root of the source tree and must not + // contain "." or ".." components. + virtual io::ZeroCopyInputStream* Open(const string& filename) = 0; + + // If Open() returns NULL, calling this method immediately will return an + // description of the error. + // Subclasses should implement this method and return a meaningful value for + // better error reporting. + // TODO(xiaofeng): change this to a pure virtual function. + virtual string GetLastErrorMessage(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree); +}; + +// An implementation of SourceTree which loads files from locations on disk. +// Multiple mappings can be set up to map locations in the DiskSourceTree to +// locations in the physical filesystem. +class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree { + public: + DiskSourceTree(); + ~DiskSourceTree(); + + // Map a path on disk to a location in the SourceTree. The path may be + // either a file or a directory. If it is a directory, the entire tree + // under it will be mapped to the given virtual location. To map a directory + // to the root of the source tree, pass an empty string for virtual_path. + // + // If multiple mapped paths apply when opening a file, they will be searched + // in order. For example, if you do: + // MapPath("bar", "foo/bar"); + // MapPath("", "baz"); + // and then you do: + // Open("bar/qux"); + // the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux, + // returning the first one that opens successfuly. + // + // disk_path may be an absolute path or relative to the current directory, + // just like a path you'd pass to open(). + void MapPath(const string& virtual_path, const string& disk_path); + + // Return type for DiskFileToVirtualFile(). + enum DiskFileToVirtualFileResult { + SUCCESS, + SHADOWED, + CANNOT_OPEN, + NO_MAPPING + }; + + // Given a path to a file on disk, find a virtual path mapping to that + // file. The first mapping created with MapPath() whose disk_path contains + // the filename is used. However, that virtual path may not actually be + // usable to open the given file. Possible return values are: + // * SUCCESS: The mapping was found. *virtual_file is filled in so that + // calling Open(*virtual_file) will open the file named by disk_file. + // * SHADOWED: A mapping was found, but using Open() to open this virtual + // path will end up returning some different file. This is because some + // other mapping with a higher precedence also matches this virtual path + // and maps it to a different file that exists on disk. *virtual_file + // is filled in as it would be in the SUCCESS case. *shadowing_disk_file + // is filled in with the disk path of the file which would be opened if + // you were to call Open(*virtual_file). + // * CANNOT_OPEN: The mapping was found and was not shadowed, but the + // file specified cannot be opened. When this value is returned, + // errno will indicate the reason the file cannot be opened. *virtual_file + // will be set to the virtual path as in the SUCCESS case, even though + // it is not useful. + // * NO_MAPPING: Indicates that no mapping was found which contains this + // file. + DiskFileToVirtualFileResult + DiskFileToVirtualFile(const string& disk_file, + string* virtual_file, + string* shadowing_disk_file); + + // Given a virtual path, find the path to the file on disk. + // Return true and update disk_file with the on-disk path if the file exists. + // Return false and leave disk_file untouched if the file doesn't exist. + bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file); + + // implements SourceTree ------------------------------------------- + virtual io::ZeroCopyInputStream* Open(const string& filename); + + virtual string GetLastErrorMessage(); + + private: + struct Mapping { + string virtual_path; + string disk_path; + + inline Mapping(const string& virtual_path_param, + const string& disk_path_param) + : virtual_path(virtual_path_param), disk_path(disk_path_param) {} + }; + vector mappings_; + string last_error_message_; + + // Like Open(), but returns the on-disk path in disk_file if disk_file is + // non-NULL and the file could be successfully opened. + io::ZeroCopyInputStream* OpenVirtualFile(const string& virtual_file, + string* disk_file); + + // Like Open() but given the actual on-disk path. + io::ZeroCopyInputStream* OpenDiskFile(const string& filename); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree); +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/java/java_generator.h b/thirdparty/linux/include/google/protobuf/compiler/java/java_generator.h new file mode 100644 index 0000000..47f76be --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/java/java_generator.h @@ -0,0 +1,72 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Generates Java code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// CodeGenerator implementation which generates Java code. If you create your +// own protocol compiler binary and you want it to support Java output, you +// can do so by registering an instance of this CodeGenerator with the +// CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator { + public: + JavaGenerator(); + ~JavaGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/java/java_names.h b/thirdparty/linux/include/google/protobuf/compiler/java/java_names.h new file mode 100644 index 0000000..0d61433 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/java/java_names.h @@ -0,0 +1,87 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Provides a mechanism for mapping a descriptor to the +// fully-qualified name of the corresponding Java class. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__ + +#include + +namespace google { +namespace protobuf { + +class Descriptor; +class EnumDescriptor; +class FileDescriptor; +class ServiceDescriptor; + +namespace compiler { +namespace java { + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified Java class name. +string ClassName(const Descriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified Java class name. +string ClassName(const EnumDescriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified Java class name. +string ClassName(const FileDescriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified Java class name. +string ClassName(const ServiceDescriptor* descriptor); + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/javanano/javanano_generator.h b/thirdparty/linux/include/google/protobuf/compiler/javanano/javanano_generator.h new file mode 100644 index 0000000..6f9f7f2 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/javanano/javanano_generator.h @@ -0,0 +1,72 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Generates Java nano code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_NANO_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_NANO_GENERATOR_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace javanano { + +// CodeGenerator implementation which generates Java nano code. If you create your +// own protocol compiler binary and you want it to support Java output for the +// nano runtime, you can do so by registering an instance of this CodeGenerator with +// the CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT JavaNanoGenerator : public CodeGenerator { + public: + JavaNanoGenerator(); + ~JavaNanoGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* output_directory, + string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaNanoGenerator); +}; + +} // namespace javanano +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVANANO_NANO_GENERATOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/js/js_generator.h b/thirdparty/linux/include/google/protobuf/compiler/js/js_generator.h new file mode 100644 index 0000000..6fd7ca5 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/js/js_generator.h @@ -0,0 +1,281 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ + +#include +#include + +#include + +namespace google { +namespace protobuf { + +class Descriptor; +class EnumDescriptor; +class FieldDescriptor; +class OneofDescriptor; +class FileDescriptor; + +namespace io { class Printer; } + +namespace compiler { +namespace js { + +struct GeneratorOptions { + // Add a `goog.requires()` call for each enum type used. If not set, a forward + // declaration with `goog.forwardDeclare` is produced instead. + bool add_require_for_enums; + // Set this as a test-only module via `goog.setTestOnly();`. + bool testonly; + // Output path. + string output_dir; + // Namespace prefix. + string namespace_prefix; + // Create a library with name _lib.js rather than a separate .js file + // per type? + string library; + // Error if there are two types that would generate the same output file? + bool error_on_name_conflict; + // Enable binary-format support? + bool binary; + // What style of imports should be used. + enum ImportStyle { + IMPORT_CLOSURE, // goog.require() + IMPORT_COMMONJS, // require() + IMPORT_BROWSER, // no import statements + IMPORT_ES6, // import { member } from '' + } import_style; + + GeneratorOptions() + : add_require_for_enums(false), + testonly(false), + output_dir("."), + namespace_prefix(""), + library(""), + error_on_name_conflict(false), + binary(false), + import_style(IMPORT_CLOSURE) {} + + bool ParseFromOptions( + const vector< pair< string, string > >& options, + string* error); +}; + +class LIBPROTOC_EXPORT Generator : public CodeGenerator { + public: + Generator() {} + virtual ~Generator() {} + + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + *error = "Unimplemented Generate() method. Call GenerateAll() instead."; + return false; + } + + virtual bool HasGenerateAll() const { return true; } + + virtual bool GenerateAll(const vector& files, + const string& parameter, + GeneratorContext* context, + string* error) const; + + private: + void GenerateHeader(const GeneratorOptions& options, + io::Printer* printer) const; + + // Generate goog.provides() calls. + void FindProvides(const GeneratorOptions& options, + io::Printer* printer, + const vector& file, + std::set* provided) const; + void FindProvidesForFile(const GeneratorOptions& options, + io::Printer* printer, + const FileDescriptor* file, + std::set* provided) const; + void FindProvidesForMessage(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc, + std::set* provided) const; + void FindProvidesForEnum(const GeneratorOptions& options, + io::Printer* printer, + const EnumDescriptor* enumdesc, + std::set* provided) const; + // For extension fields at file scope. + void FindProvidesForFields(const GeneratorOptions& options, + io::Printer* printer, + const vector& fields, + std::set* provided) const; + // Print the goog.provides() found by the methods above. + void GenerateProvides(const GeneratorOptions& options, + io::Printer* printer, + std::set* provided) const; + + // Generate goog.setTestOnly() if indicated. + void GenerateTestOnly(const GeneratorOptions& options, + io::Printer* printer) const; + + // Generate goog.requires() calls. + void GenerateRequiresForLibrary(const GeneratorOptions& options, + io::Printer* printer, + const vector& files, + std::set* provided) const; + void GenerateRequiresForMessage(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc, + std::set* provided) const; + // For extension fields at file scope. + void GenerateRequiresForExtensions( + const GeneratorOptions& options, io::Printer* printer, + const vector& fields, + std::set* provided) const; + void GenerateRequiresImpl(const GeneratorOptions& options, + io::Printer* printer, + std::set* required, + std::set* forwards, + std::set* provided, + bool require_jspb, + bool require_extension) const; + void FindRequiresForMessage(const GeneratorOptions& options, + const Descriptor* desc, + std::set* required, + std::set* forwards, + bool* have_message) const; + void FindRequiresForField(const GeneratorOptions& options, + const FieldDescriptor* field, + std::set* required, + std::set* forwards) const; + void FindRequiresForExtension(const GeneratorOptions& options, + const FieldDescriptor* field, + std::set* required, + std::set* forwards) const; + + void GenerateFile(const GeneratorOptions& options, + io::Printer* printer, + const FileDescriptor* file) const; + + // Generate definitions for all message classes and enums in all files, + // processing the files in dependence order. + void GenerateFilesInDepOrder(const GeneratorOptions& options, + io::Printer* printer, + const vector& file) const; + // Helper for above. + void GenerateFileAndDeps(const GeneratorOptions& options, + io::Printer* printer, + const FileDescriptor* root, + std::set* all_files, + std::set* generated) const; + + // Generate definitions for all message classes and enums. + void GenerateClassesAndEnums(const GeneratorOptions& options, + io::Printer* printer, + const FileDescriptor* file) const; + + // Generate definition for one class. + void GenerateClass(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassConstructor(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassFieldInfo(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassXid(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateOneofCaseDefinition(const GeneratorOptions& options, + io::Printer* printer, + const OneofDescriptor* oneof) const; + void GenerateClassToObject(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassFieldToObject(const GeneratorOptions& options, + io::Printer* printer, + const FieldDescriptor* field) const; + void GenerateClassFromObject(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassFieldFromObject(const GeneratorOptions& options, + io::Printer* printer, + const FieldDescriptor* field) const; + void GenerateClassClone(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassRegistration(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassFields(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassField(const GeneratorOptions& options, + io::Printer* printer, + const FieldDescriptor* desc) const; + void GenerateClassExtensionFieldInfo(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassDeserialize(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassDeserializeBinary(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassDeserializeBinaryField(const GeneratorOptions& options, + io::Printer* printer, + const FieldDescriptor* field) const; + void GenerateClassSerializeBinary(const GeneratorOptions& options, + io::Printer* printer, + const Descriptor* desc) const; + void GenerateClassSerializeBinaryField(const GeneratorOptions& options, + io::Printer* printer, + const FieldDescriptor* field) const; + + // Generate definition for one enum. + void GenerateEnum(const GeneratorOptions& options, + io::Printer* printer, + const EnumDescriptor* enumdesc) const; + + // Generate an extension definition. + void GenerateExtension(const GeneratorOptions& options, + io::Printer* printer, + const FieldDescriptor* field) const; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); +}; + +} // namespace js +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/objectivec/objectivec_generator.h b/thirdparty/linux/include/google/protobuf/compiler/objectivec/objectivec_generator.h new file mode 100644 index 0000000..09266b0 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/objectivec/objectivec_generator.h @@ -0,0 +1,61 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Generates ObjectiveC code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class LIBPROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { + public: + ObjectiveCGenerator(); + ~ObjectiveCGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, const string& parameter, + OutputDirectory* output_directory, string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectiveCGenerator); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/objectivec/objectivec_helpers.h b/thirdparty/linux/include/google/protobuf/compiler/objectivec/objectivec_helpers.h new file mode 100644 index 0000000..344723a --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -0,0 +1,269 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ + +#include +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +// Generator options (see objectivec_generator.cc for a description of each): +struct Options { + Options(); + string expected_prefixes_path; + string generate_for_named_framework; + string named_framework_to_proto_path_mappings_path; +}; + +// Escape C++ trigraphs by escaping question marks to "\?". +string EscapeTrigraphs(const string& to_escape); + +// Strips ".proto" or ".protodevel" from the end of a filename. +string StripProto(const string& filename); + +// Remove white space from either end of a StringPiece. +void StringPieceTrimWhitespace(StringPiece* input); + +// Returns true if the name requires a ns_returns_not_retained attribute applied +// to it. +bool IsRetainedName(const string& name); + +// Returns true if the name starts with "init" and will need to have special +// handling under ARC. +bool IsInitName(const string& name); + +// Gets the path of the file we're going to generate (sans the .pb.h +// extension). The path will be dependent on the objectivec package +// declared in the proto package. +string FilePath(const FileDescriptor* file); + +// Just like FilePath(), but without the directory part. +string FilePathBasename(const FileDescriptor* file); + +// Gets the name of the root class we'll generate in the file. This class +// is not meant for external consumption, but instead contains helpers that +// the rest of the classes need +string FileClassName(const FileDescriptor* file); + +// These return the fully-qualified class name corresponding to the given +// descriptor. +string ClassName(const Descriptor* descriptor); +string EnumName(const EnumDescriptor* descriptor); + +// Returns the fully-qualified name of the enum value corresponding to the +// the descriptor. +string EnumValueName(const EnumValueDescriptor* descriptor); + +// Returns the name of the enum value corresponding to the descriptor. +string EnumValueShortName(const EnumValueDescriptor* descriptor); + +// Reverse what an enum does. +string UnCamelCaseEnumShortName(const string& name); + +// Returns the name to use for the extension (used as the method off the file's +// Root class). +string ExtensionMethodName(const FieldDescriptor* descriptor); + +// Returns the transformed field name. +string FieldName(const FieldDescriptor* field); +string FieldNameCapitalized(const FieldDescriptor* field); + +// Returns the transformed oneof name. +string OneofEnumName(const OneofDescriptor* descriptor); +string OneofName(const OneofDescriptor* descriptor); +string OneofNameCapitalized(const OneofDescriptor* descriptor); + +inline bool HasFieldPresence(const FileDescriptor* file) { + return file->syntax() != FileDescriptor::SYNTAX_PROTO3; +} + +inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) { + return file->syntax() == FileDescriptor::SYNTAX_PROTO3; +} + +inline bool IsMapEntryMessage(const Descriptor* descriptor) { + return descriptor->options().map_entry(); +} + +// Reverse of the above. +string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field); + +enum ObjectiveCType { + OBJECTIVECTYPE_INT32, + OBJECTIVECTYPE_UINT32, + OBJECTIVECTYPE_INT64, + OBJECTIVECTYPE_UINT64, + OBJECTIVECTYPE_FLOAT, + OBJECTIVECTYPE_DOUBLE, + OBJECTIVECTYPE_BOOLEAN, + OBJECTIVECTYPE_STRING, + OBJECTIVECTYPE_DATA, + OBJECTIVECTYPE_ENUM, + OBJECTIVECTYPE_MESSAGE +}; + +template +string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, bool preSpace = true, bool postNewline = false) { + if (descriptor->options().deprecated()) { + string result = "DEPRECATED_ATTRIBUTE"; + if (preSpace) { + result.insert(0, " "); + } + if (postNewline) { + result.append("\n"); + } + return result; + } else { + return ""; + } +} + +string GetCapitalizedType(const FieldDescriptor* field); + +ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type); + +inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) { + return GetObjectiveCType(field->type()); +} + +bool IsPrimitiveType(const FieldDescriptor* field); +bool IsReferenceType(const FieldDescriptor* field); + +string GPBGenericValueFieldName(const FieldDescriptor* field); +string DefaultValue(const FieldDescriptor* field); +bool HasNonZeroDefaultValue(const FieldDescriptor* field); + +string BuildFlagsString(const vector& strings); + +// Builds HeaderDoc/appledoc style comments out of the comments in the .proto +// file. +string BuildCommentsString(const SourceLocation& location, + bool prefer_single_line); + +// The name the commonly used by the library when built as a framework. +// This lines up to the name used in the CocoaPod. +extern const char* const ProtobufLibraryFrameworkName; +// Returns the CPP symbol name to use as the gate for framework style imports +// for the given framework name to use. +string ProtobufFrameworkImportSymbol(const string& framework_name); + +// Checks if the file is one of the proto's bundled with the library. +bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); + +// Checks the prefix for a given file and outputs any warnings needed, if +// there are flat out errors, then out_error is filled in and the result is +// false. +bool ValidateObjCClassPrefix(const FileDescriptor* file, + const Options& generation_options, + string* out_error); + +// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform +// the input into the expected output. +class LIBPROTOC_EXPORT TextFormatDecodeData { + public: + TextFormatDecodeData(); + ~TextFormatDecodeData(); + + void AddString(int32 key, const string& input_for_decode, + const string& desired_output); + size_t num_entries() const { return entries_.size(); } + string Data() const; + + static string DecodeDataForString(const string& input_for_decode, + const string& desired_output); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormatDecodeData); + + typedef std::pair DataEntry; + vector entries_; +}; + +// Helper for parsing simple files. +class LIBPROTOC_EXPORT LineConsumer { + public: + LineConsumer(); + virtual ~LineConsumer(); + virtual bool ConsumeLine(const StringPiece& line, string* out_error) = 0; +}; + +bool ParseSimpleFile( + const string& path, LineConsumer* line_consumer, string* out_error); + + +// Helper class for parsing framework import mappings and generating +// import statements. +class LIBPROTOC_EXPORT ImportWriter { + public: + ImportWriter(const string& generate_for_named_framework, + const string& named_framework_to_proto_path_mappings_path); + ~ImportWriter(); + + void AddFile(const FileDescriptor* file, const string& header_extension); + void Print(io::Printer *printer) const; + + private: + class ProtoFrameworkCollector : public LineConsumer { + public: + ProtoFrameworkCollector(map* inout_proto_file_to_framework_name) + : map_(inout_proto_file_to_framework_name) {} + + virtual bool ConsumeLine(const StringPiece& line, string* out_error); + + private: + map* map_; + }; + + void ParseFrameworkMappings(); + + const string generate_for_named_framework_; + const string named_framework_to_proto_path_mappings_path_; + map proto_file_to_framework_name_; + bool need_to_parse_mapping_file_; + + vector protobuf_framework_imports_; + vector protobuf_non_framework_imports_; + vector other_framework_imports_; + vector other_imports_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/parser.h b/thirdparty/linux/include/google/protobuf/compiler/parser.h new file mode 100644 index 0000000..0f80e78 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/parser.h @@ -0,0 +1,569 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Implements parsing of .proto files to FileDescriptorProtos. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__ +#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__ + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { class Message; } + +namespace protobuf { +namespace compiler { + +// Defined in this file. +class Parser; +class SourceLocationTable; + +// Implements parsing of protocol definitions (such as .proto files). +// +// Note that most users will be more interested in the Importer class. +// Parser is a lower-level class which simply converts a single .proto file +// to a FileDescriptorProto. It does not resolve import directives or perform +// many other kinds of validation needed to construct a complete +// FileDescriptor. +class LIBPROTOBUF_EXPORT Parser { + public: + Parser(); + ~Parser(); + + // Parse the entire input and construct a FileDescriptorProto representing + // it. Returns true if no errors occurred, false otherwise. + bool Parse(io::Tokenizer* input, FileDescriptorProto* file); + + // Optional features: + + // DEPRECATED: New code should use the SourceCodeInfo embedded in the + // FileDescriptorProto. + // + // Requests that locations of certain definitions be recorded to the given + // SourceLocationTable while parsing. This can be used to look up exact line + // and column numbers for errors reported by DescriptorPool during validation. + // Set to NULL (the default) to discard source location information. + void RecordSourceLocationsTo(SourceLocationTable* location_table) { + source_location_table_ = location_table; + } + + // Requests that errors be recorded to the given ErrorCollector while + // parsing. Set to NULL (the default) to discard error messages. + void RecordErrorsTo(io::ErrorCollector* error_collector) { + error_collector_ = error_collector; + } + + // Returns the identifier used in the "syntax = " declaration, if one was + // seen during the last call to Parse(), or the empty string otherwise. + const string& GetSyntaxIdentifier() { return syntax_identifier_; } + + // If set true, input files will be required to begin with a syntax + // identifier. Otherwise, files may omit this. If a syntax identifier + // is provided, it must be 'syntax = "proto2";' and must appear at the + // top of this file regardless of whether or not it was required. + void SetRequireSyntaxIdentifier(bool value) { + require_syntax_identifier_ = value; + } + + // Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop + // parsing as soon as it has seen the syntax identifier, or lack thereof. + // This is useful for quickly identifying the syntax of the file without + // parsing the whole thing. If this is enabled, no error will be recorded + // if the syntax identifier is something other than "proto2" (since + // presumably the caller intends to deal with that), but other kinds of + // errors (e.g. parse errors) will still be reported. When this is enabled, + // you may pass a NULL FileDescriptorProto to Parse(). + void SetStopAfterSyntaxIdentifier(bool value) { + stop_after_syntax_identifier_ = value; + } + + private: + class LocationRecorder; + + // ================================================================= + // Error recovery helpers + + // Consume the rest of the current statement. This consumes tokens + // until it sees one of: + // ';' Consumes the token and returns. + // '{' Consumes the brace then calls SkipRestOfBlock(). + // '}' Returns without consuming. + // EOF Returns (can't consume). + // The Parser often calls SkipStatement() after encountering a syntax + // error. This allows it to go on parsing the following lines, allowing + // it to report more than just one error in the file. + void SkipStatement(); + + // Consume the rest of the current block, including nested blocks, + // ending after the closing '}' is encountered and consumed, or at EOF. + void SkipRestOfBlock(); + + // ----------------------------------------------------------------- + // Single-token consuming helpers + // + // These make parsing code more readable. + + // True if the current token is TYPE_END. + inline bool AtEnd(); + + // True if the next token matches the given text. + inline bool LookingAt(const char* text); + // True if the next token is of the given type. + inline bool LookingAtType(io::Tokenizer::TokenType token_type); + + // If the next token exactly matches the text given, consume it and return + // true. Otherwise, return false without logging an error. + bool TryConsume(const char* text); + + // These attempt to read some kind of token from the input. If successful, + // they return true. Otherwise they return false and add the given error + // to the error list. + + // Consume a token with the exact text given. + bool Consume(const char* text, const char* error); + // Same as above, but automatically generates the error "Expected \"text\".", + // where "text" is the expected token text. + bool Consume(const char* text); + // Consume a token of type IDENTIFIER and store its text in "output". + bool ConsumeIdentifier(string* output, const char* error); + // Consume an integer and store its value in "output". + bool ConsumeInteger(int* output, const char* error); + // Consume a signed integer and store its value in "output". + bool ConsumeSignedInteger(int* output, const char* error); + // Consume a 64-bit integer and store its value in "output". If the value + // is greater than max_value, an error will be reported. + bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error); + // Consume a number and store its value in "output". This will accept + // tokens of either INTEGER or FLOAT type. + bool ConsumeNumber(double* output, const char* error); + // Consume a string literal and store its (unescaped) value in "output". + bool ConsumeString(string* output, const char* error); + + // Consume a token representing the end of the statement. Comments between + // this token and the next will be harvested for documentation. The given + // LocationRecorder should refer to the declaration that was just parsed; + // it will be populated with these comments. + // + // TODO(kenton): The LocationRecorder is const because historically locations + // have been passed around by const reference, for no particularly good + // reason. We should probably go through and change them all to mutable + // pointer to make this more intuitive. + bool TryConsumeEndOfDeclaration( + const char* text, const LocationRecorder* location); + bool TryConsumeEndOfDeclarationFinishScope( + const char* text, const LocationRecorder* location); + + bool ConsumeEndOfDeclaration( + const char* text, const LocationRecorder* location); + + // ----------------------------------------------------------------- + // Error logging helpers + + // Invokes error_collector_->AddError(), if error_collector_ is not NULL. + void AddError(int line, int column, const string& error); + + // Invokes error_collector_->AddError() with the line and column number + // of the current token. + void AddError(const string& error); + + // Records a location in the SourceCodeInfo.location table (see + // descriptor.proto). We use RAII to ensure that the start and end locations + // are recorded -- the constructor records the start location and the + // destructor records the end location. Since the parser is + // recursive-descent, this works out beautifully. + class LIBPROTOBUF_EXPORT LocationRecorder { + public: + // Construct the file's "root" location. + LocationRecorder(Parser* parser); + + // Construct a location that represents a declaration nested within the + // given parent. E.g. a field's location is nested within the location + // for a message type. The parent's path will be copied, so you should + // call AddPath() only to add the path components leading from the parent + // to the child (as opposed to leading from the root to the child). + LocationRecorder(const LocationRecorder& parent); + + // Convenience constructors that call AddPath() one or two times. + LocationRecorder(const LocationRecorder& parent, int path1); + LocationRecorder(const LocationRecorder& parent, int path1, int path2); + + ~LocationRecorder(); + + // Add a path component. See SourceCodeInfo.Location.path in + // descriptor.proto. + void AddPath(int path_component); + + // By default the location is considered to start at the current token at + // the time the LocationRecorder is created. StartAt() sets the start + // location to the given token instead. + void StartAt(const io::Tokenizer::Token& token); + + // Start at the same location as some other LocationRecorder. + void StartAt(const LocationRecorder& other); + + // By default the location is considered to end at the previous token at + // the time the LocationRecorder is destroyed. EndAt() sets the end + // location to the given token instead. + void EndAt(const io::Tokenizer::Token& token); + + // Records the start point of this location to the SourceLocationTable that + // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable + // is an older way of keeping track of source locations which is still + // used in some places. + void RecordLegacyLocation(const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location); + + // Attaches leading and trailing comments to the location. The two strings + // will be swapped into place, so after this is called *leading and + // *trailing will be empty. + // + // TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for + // why this is const. + void AttachComments(string* leading, string* trailing, + vector* detached_comments) const; + + private: + // Indexes of parent and current location in the parent + // SourceCodeInfo.location repeated field. For top-level elements, + // parent_index_ is -1. + Parser* parser_; + SourceCodeInfo::Location* location_; + + void Init(const LocationRecorder& parent); + }; + + // ================================================================= + // Parsers for various language constructs + + // Parses the "syntax = \"proto2\";" line at the top of the file. Returns + // false if it failed to parse or if the syntax identifier was not + // recognized. + bool ParseSyntaxIdentifier(const LocationRecorder& parent); + + // These methods parse various individual bits of code. They return + // false if they completely fail to parse the construct. In this case, + // it is probably necessary to skip the rest of the statement to recover. + // However, if these methods return true, it does NOT mean that there + // were no errors; only that there were no *syntax* errors. For instance, + // if a service method is defined using proper syntax but uses a primitive + // type as its input or output, ParseMethodField() still returns true + // and only reports the error by calling AddError(). In practice, this + // makes logic much simpler for the caller. + + // Parse a top-level message, enum, service, etc. + bool ParseTopLevelStatement(FileDescriptorProto* file, + const LocationRecorder& root_location); + + // Parse various language high-level language construrcts. + bool ParseMessageDefinition(DescriptorProto* message, + const LocationRecorder& message_location, + const FileDescriptorProto* containing_file); + bool ParseEnumDefinition(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location, + const FileDescriptorProto* containing_file); + bool ParseServiceDefinition(ServiceDescriptorProto* service, + const LocationRecorder& service_location, + const FileDescriptorProto* containing_file); + bool ParsePackage(FileDescriptorProto* file, + const LocationRecorder& root_location, + const FileDescriptorProto* containing_file); + bool ParseImport(RepeatedPtrField* dependency, + RepeatedField* public_dependency, + RepeatedField* weak_dependency, + const LocationRecorder& root_location, + const FileDescriptorProto* containing_file); + + // These methods parse the contents of a message, enum, or service type and + // add them to the given object. They consume the entire block including + // the beginning and ending brace. + bool ParseMessageBlock(DescriptorProto* message, + const LocationRecorder& message_location, + const FileDescriptorProto* containing_file); + bool ParseEnumBlock(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location, + const FileDescriptorProto* containing_file); + bool ParseServiceBlock(ServiceDescriptorProto* service, + const LocationRecorder& service_location, + const FileDescriptorProto* containing_file); + + // Parse one statement within a message, enum, or service block, including + // final semicolon. + bool ParseMessageStatement(DescriptorProto* message, + const LocationRecorder& message_location, + const FileDescriptorProto* containing_file); + bool ParseEnumStatement(EnumDescriptorProto* message, + const LocationRecorder& enum_location, + const FileDescriptorProto* containing_file); + bool ParseServiceStatement(ServiceDescriptorProto* message, + const LocationRecorder& service_location, + const FileDescriptorProto* containing_file); + + // Parse a field of a message. If the field is a group, its type will be + // added to "messages". + // + // parent_location and location_field_number_for_nested_type are needed when + // parsing groups -- we need to generate a nested message type within the + // parent and record its location accordingly. Since the parent could be + // either a FileDescriptorProto or a DescriptorProto, we must pass in the + // correct field number to use. + bool ParseMessageField(FieldDescriptorProto* field, + RepeatedPtrField* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& field_location, + const FileDescriptorProto* containing_file); + + // Like ParseMessageField() but expects the label has already been filled in + // by the caller. + bool ParseMessageFieldNoLabel(FieldDescriptorProto* field, + RepeatedPtrField* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& field_location, + const FileDescriptorProto* containing_file); + + // Parse an "extensions" declaration. + bool ParseExtensions(DescriptorProto* message, + const LocationRecorder& extensions_location, + const FileDescriptorProto* containing_file); + + // Parse a "reserved" declaration. + bool ParseReserved(DescriptorProto* message, + const LocationRecorder& message_location); + bool ParseReservedNames(DescriptorProto* message, + const LocationRecorder& parent_location); + bool ParseReservedNumbers(DescriptorProto* message, + const LocationRecorder& parent_location); + + // Parse an "extend" declaration. (See also comments for + // ParseMessageField().) + bool ParseExtend(RepeatedPtrField* extensions, + RepeatedPtrField* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& extend_location, + const FileDescriptorProto* containing_file); + + // Parse a "oneof" declaration. The caller is responsible for setting + // oneof_decl->label() since it will have had to parse the label before it + // knew it was parsing a oneof. + bool ParseOneof(OneofDescriptorProto* oneof_decl, + DescriptorProto* containing_type, + int oneof_index, + const LocationRecorder& oneof_location, + const LocationRecorder& containing_type_location, + const FileDescriptorProto* containing_file); + + // Parse a single enum value within an enum block. + bool ParseEnumConstant(EnumValueDescriptorProto* enum_value, + const LocationRecorder& enum_value_location, + const FileDescriptorProto* containing_file); + + // Parse enum constant options, i.e. the list in square brackets at the end + // of the enum constant value definition. + bool ParseEnumConstantOptions(EnumValueDescriptorProto* value, + const LocationRecorder& enum_value_location, + const FileDescriptorProto* containing_file); + + // Parse a single method within a service definition. + bool ParseServiceMethod(MethodDescriptorProto* method, + const LocationRecorder& method_location, + const FileDescriptorProto* containing_file); + + + // Parse options of a single method or stream. + bool ParseMethodOptions(const LocationRecorder& parent_location, + const FileDescriptorProto* containing_file, + const int optionsFieldNumber, + Message* mutable_options); + + // Parse "required", "optional", or "repeated" and fill in "label" + // with the value. Returns true if such a label is consumed. + bool ParseLabel(FieldDescriptorProto::Label* label, + const FileDescriptorProto* containing_file); + + // Parse a type name and fill in "type" (if it is a primitive) or + // "type_name" (if it is not) with the type parsed. + bool ParseType(FieldDescriptorProto::Type* type, + string* type_name); + // Parse a user-defined type and fill in "type_name" with the name. + // If a primitive type is named, it is treated as an error. + bool ParseUserDefinedType(string* type_name); + + // Parses field options, i.e. the stuff in square brackets at the end + // of a field definition. Also parses default value. + bool ParseFieldOptions(FieldDescriptorProto* field, + const LocationRecorder& field_location, + const FileDescriptorProto* containing_file); + + // Parse the "default" option. This needs special handling because its + // type is the field's type. + bool ParseDefaultAssignment(FieldDescriptorProto* field, + const LocationRecorder& field_location, + const FileDescriptorProto* containing_file); + + bool ParseJsonName(FieldDescriptorProto* field, + const LocationRecorder& field_location, + const FileDescriptorProto* containing_file); + + enum OptionStyle { + OPTION_ASSIGNMENT, // just "name = value" + OPTION_STATEMENT // "option name = value;" + }; + + // Parse a single option name/value pair, e.g. "ctype = CORD". The name + // identifies a field of the given Message, and the value of that field + // is set to the parsed value. + bool ParseOption(Message* options, + const LocationRecorder& options_location, + const FileDescriptorProto* containing_file, + OptionStyle style); + + // Parses a single part of a multipart option name. A multipart name consists + // of names separated by dots. Each name is either an identifier or a series + // of identifiers separated by dots and enclosed in parentheses. E.g., + // "foo.(bar.baz).qux". + bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option, + const LocationRecorder& part_location, + const FileDescriptorProto* containing_file); + + // Parses a string surrounded by balanced braces. Strips off the outer + // braces and stores the enclosed string in *value. + // E.g., + // { foo } *value gets 'foo' + // { foo { bar: box } } *value gets 'foo { bar: box }' + // {} *value gets '' + // + // REQUIRES: LookingAt("{") + // When finished successfully, we are looking at the first token past + // the ending brace. + bool ParseUninterpretedBlock(string* value); + + struct MapField { + // Whether the field is a map field. + bool is_map_field; + // The types of the key and value if they are primitive types. + FieldDescriptorProto::Type key_type; + FieldDescriptorProto::Type value_type; + // Or the type names string if the types are customized types. + string key_type_name; + string value_type_name; + + MapField() : is_map_field(false) {} + }; + // Desugar the map syntax to generate a nested map entry message. + void GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field, + RepeatedPtrField* messages); + + // Whether fields without label default to optional fields. + bool DefaultToOptionalFields() const { + return syntax_identifier_ == "proto3"; + } + + + bool ValidateEnum(const EnumDescriptorProto* proto); + + // ================================================================= + + io::Tokenizer* input_; + io::ErrorCollector* error_collector_; + SourceCodeInfo* source_code_info_; + SourceLocationTable* source_location_table_; // legacy + bool had_errors_; + bool require_syntax_identifier_; + bool stop_after_syntax_identifier_; + string syntax_identifier_; + + // Leading doc comments for the next declaration. These are not complete + // yet; use ConsumeEndOfDeclaration() to get the complete comments. + string upcoming_doc_comments_; + + // Detached comments are not connected to any syntax entities. Elements in + // this vector are paragraphs of comments separated by empty lines. The + // detached comments will be put into the leading_detached_comments field for + // the next element (See SourceCodeInfo.Location in descriptor.proto), when + // ConsumeEndOfDeclaration() is called. + vector upcoming_detached_comments_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser); +}; + +// A table mapping (descriptor, ErrorLocation) pairs -- as reported by +// DescriptorPool when validating descriptors -- to line and column numbers +// within the original source code. +// +// This is semi-obsolete: FileDescriptorProto.source_code_info now contains +// far more complete information about source locations. However, as of this +// writing you still need to use SourceLocationTable when integrating with +// DescriptorPool. +class LIBPROTOBUF_EXPORT SourceLocationTable { + public: + SourceLocationTable(); + ~SourceLocationTable(); + + // Finds the precise location of the given error and fills in *line and + // *column with the line and column numbers. If not found, sets *line to + // -1 and *column to 0 (since line = -1 is used to mean "error has no exact + // location" in the ErrorCollector interface). Returns true if found, false + // otherwise. + bool Find(const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + int* line, int* column) const; + + // Adds a location to the table. + void Add(const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location, + int line, int column); + + // Clears the contents of the table. + void Clear(); + + private: + typedef map< + pair, + pair > LocationMap; + LocationMap location_map_; +}; + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/plugin.h b/thirdparty/linux/include/google/protobuf/compiler/plugin.h new file mode 100644 index 0000000..d2793a9 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/plugin.h @@ -0,0 +1,90 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// Front-end for protoc code generator plugins written in C++. +// +// To implement a protoc plugin in C++, simply write an implementation of +// CodeGenerator, then create a main() function like: +// int main(int argc, char* argv[]) { +// MyCodeGenerator generator; +// return google::protobuf::compiler::PluginMain(argc, argv, &generator); +// } +// You must link your plugin against libprotobuf and libprotoc. +// +// The core part of PluginMain is to invoke the given CodeGenerator on a +// CodeGeneratorRequest to generate a CodeGeneratorResponse. This part is +// abstracted out and made into function GenerateCode so that it can be reused, +// for example, to implement a variant of PluginMain that does some +// preprocessing on the input CodeGeneratorRequest before feeding the request +// to the given code generator. +// +// To get protoc to use the plugin, do one of the following: +// * Place the plugin binary somewhere in the PATH and give it the name +// "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you +// then invoke protoc with the parameter --NAME_out=OUT_DIR (again, replace +// "NAME" with your plugin's name), protoc will invoke your plugin to generate +// the output, which will be placed in OUT_DIR. +// * Place the plugin binary anywhere, with any name, and pass the --plugin +// parameter to protoc to direct it to your plugin like so: +// protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR +// On Windows, make sure to include the .exe suffix: +// protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR + +#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ +#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ + +#include + +#include +namespace google { +namespace protobuf { +namespace compiler { + +class CodeGenerator; // code_generator.h +class CodeGeneratorRequest; +class CodeGeneratorResponse; + +// Implements main() for a protoc plugin exposing the given code generator. +LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator); + +// Generates code using the given code generator. Returns true if the code +// generation is successful. If the code geneartion fails, error_msg may be +// populated to describe the failure cause. +bool GenerateCode(const CodeGeneratorRequest& request, + const CodeGenerator& generator, CodeGeneratorResponse* response, + string* error_msg); + +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/plugin.pb.h b/thirdparty/linux/include/google/protobuf/compiler/plugin.pb.h new file mode 100644 index 0000000..13eeb69 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/plugin.pb.h @@ -0,0 +1,830 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/compiler/plugin.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { +namespace compiler { + +// Internal implementation detail -- do not call these. +void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + +class CodeGeneratorRequest; +class CodeGeneratorResponse; +class CodeGeneratorResponse_File; + +// =================================================================== + +class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ { + public: + CodeGeneratorRequest(); + virtual ~CodeGeneratorRequest(); + + CodeGeneratorRequest(const CodeGeneratorRequest& from); + + inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorRequest& default_instance(); + + void Swap(CodeGeneratorRequest* other); + + // implements Message ---------------------------------------------- + + inline CodeGeneratorRequest* New() const { return New(NULL); } + + CodeGeneratorRequest* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorRequest& from); + void MergeFrom(const CodeGeneratorRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CodeGeneratorRequest* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string file_to_generate = 1; + int file_to_generate_size() const; + void clear_file_to_generate(); + static const int kFileToGenerateFieldNumber = 1; + const ::std::string& file_to_generate(int index) const; + ::std::string* mutable_file_to_generate(int index); + void set_file_to_generate(int index, const ::std::string& value); + void set_file_to_generate(int index, const char* value); + void set_file_to_generate(int index, const char* value, size_t size); + ::std::string* add_file_to_generate(); + void add_file_to_generate(const ::std::string& value); + void add_file_to_generate(const char* value); + void add_file_to_generate(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate(); + + // optional string parameter = 2; + bool has_parameter() const; + void clear_parameter(); + static const int kParameterFieldNumber = 2; + const ::std::string& parameter() const; + void set_parameter(const ::std::string& value); + void set_parameter(const char* value); + void set_parameter(const char* value, size_t size); + ::std::string* mutable_parameter(); + ::std::string* release_parameter(); + void set_allocated_parameter(::std::string* parameter); + + // repeated .google.protobuf.FileDescriptorProto proto_file = 15; + int proto_file_size() const; + void clear_proto_file(); + static const int kProtoFileFieldNumber = 15; + const ::google::protobuf::FileDescriptorProto& proto_file(int index) const; + ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index); + ::google::protobuf::FileDescriptorProto* add_proto_file(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* + mutable_proto_file(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& + proto_file() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) + private: + inline void set_has_parameter(); + inline void clear_has_parameter(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_; + ::google::protobuf::internal::ArenaStringPtr parameter_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_; + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + void InitAsDefaultInstance(); + static CodeGeneratorRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ { + public: + CodeGeneratorResponse_File(); + virtual ~CodeGeneratorResponse_File(); + + CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from); + + inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorResponse_File& default_instance(); + + void Swap(CodeGeneratorResponse_File* other); + + // implements Message ---------------------------------------------- + + inline CodeGeneratorResponse_File* New() const { return New(NULL); } + + CodeGeneratorResponse_File* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorResponse_File& from); + void MergeFrom(const CodeGeneratorResponse_File& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CodeGeneratorResponse_File* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional string insertion_point = 2; + bool has_insertion_point() const; + void clear_insertion_point(); + static const int kInsertionPointFieldNumber = 2; + const ::std::string& insertion_point() const; + void set_insertion_point(const ::std::string& value); + void set_insertion_point(const char* value); + void set_insertion_point(const char* value, size_t size); + ::std::string* mutable_insertion_point(); + ::std::string* release_insertion_point(); + void set_allocated_insertion_point(::std::string* insertion_point); + + // optional string content = 15; + bool has_content() const; + void clear_content(); + static const int kContentFieldNumber = 15; + const ::std::string& content() const; + void set_content(const ::std::string& value); + void set_content(const char* value); + void set_content(const char* value, size_t size); + ::std::string* mutable_content(); + ::std::string* release_content(); + void set_allocated_content(::std::string* content); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_insertion_point(); + inline void clear_has_insertion_point(); + inline void set_has_content(); + inline void clear_has_content(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::internal::ArenaStringPtr insertion_point_; + ::google::protobuf::internal::ArenaStringPtr content_; + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + void InitAsDefaultInstance(); + static CodeGeneratorResponse_File* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ { + public: + CodeGeneratorResponse(); + virtual ~CodeGeneratorResponse(); + + CodeGeneratorResponse(const CodeGeneratorResponse& from); + + inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CodeGeneratorResponse& default_instance(); + + void Swap(CodeGeneratorResponse* other); + + // implements Message ---------------------------------------------- + + inline CodeGeneratorResponse* New() const { return New(NULL); } + + CodeGeneratorResponse* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CodeGeneratorResponse& from); + void MergeFrom(const CodeGeneratorResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CodeGeneratorResponse* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef CodeGeneratorResponse_File File; + + // accessors ------------------------------------------------------- + + // optional string error = 1; + bool has_error() const; + void clear_error(); + static const int kErrorFieldNumber = 1; + const ::std::string& error() const; + void set_error(const ::std::string& value); + void set_error(const char* value); + void set_error(const char* value, size_t size); + ::std::string* mutable_error(); + ::std::string* release_error(); + void set_allocated_error(::std::string* error); + + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + int file_size() const; + void clear_file(); + static const int kFileFieldNumber = 15; + const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const; + ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index); + ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* + mutable_file(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& + file() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) + private: + inline void set_has_error(); + inline void clear_has_error(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr error_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_; + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + + void InitAsDefaultInstance(); + static CodeGeneratorResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// CodeGeneratorRequest + +// repeated string file_to_generate = 1; +inline int CodeGeneratorRequest::file_to_generate_size() const { + return file_to_generate_.size(); +} +inline void CodeGeneratorRequest::clear_file_to_generate() { + file_to_generate_.Clear(); +} +inline const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return file_to_generate_.Get(index); +} +inline ::std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return file_to_generate_.Mutable(index); +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + file_to_generate_.Mutable(index)->assign(value); +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) { + file_to_generate_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} +inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) { + file_to_generate_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} +inline ::std::string* CodeGeneratorRequest::add_file_to_generate() { + // @@protoc_insertion_point(field_add_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return file_to_generate_.Add(); +} +inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) { + file_to_generate_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} +inline void CodeGeneratorRequest::add_file_to_generate(const char* value) { + file_to_generate_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} +inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) { + file_to_generate_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +CodeGeneratorRequest::file_to_generate() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return file_to_generate_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +CodeGeneratorRequest::mutable_file_to_generate() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return &file_to_generate_; +} + +// optional string parameter = 2; +inline bool CodeGeneratorRequest::has_parameter() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CodeGeneratorRequest::set_has_parameter() { + _has_bits_[0] |= 0x00000002u; +} +inline void CodeGeneratorRequest::clear_has_parameter() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CodeGeneratorRequest::clear_parameter() { + parameter_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_parameter(); +} +inline const ::std::string& CodeGeneratorRequest::parameter() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter) + return parameter_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) { + set_has_parameter(); + parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter) +} +inline void CodeGeneratorRequest::set_parameter(const char* value) { + set_has_parameter(); + parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter) +} +inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) { + set_has_parameter(); + parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter) +} +inline ::std::string* CodeGeneratorRequest::mutable_parameter() { + set_has_parameter(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter) + return parameter_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CodeGeneratorRequest::release_parameter() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter) + clear_has_parameter(); + return parameter_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) { + if (parameter != NULL) { + set_has_parameter(); + } else { + clear_has_parameter(); + } + parameter_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parameter); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter) +} + +// repeated .google.protobuf.FileDescriptorProto proto_file = 15; +inline int CodeGeneratorRequest::proto_file_size() const { + return proto_file_.size(); +} +inline void CodeGeneratorRequest::clear_proto_file() { + proto_file_.Clear(); +} +inline const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_.Get(index); +} +inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_.Mutable(index); +} +inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* +CodeGeneratorRequest::mutable_proto_file() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return &proto_file_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& +CodeGeneratorRequest::proto_file() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_; +} + +// ------------------------------------------------------------------- + +// CodeGeneratorResponse_File + +// optional string name = 1; +inline bool CodeGeneratorResponse_File::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void CodeGeneratorResponse_File::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CodeGeneratorResponse_File::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& CodeGeneratorResponse_File::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name) +} +inline void CodeGeneratorResponse_File::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name) +} +inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name) +} +inline ::std::string* CodeGeneratorResponse_File::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CodeGeneratorResponse_File::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name) +} + +// optional string insertion_point = 2; +inline bool CodeGeneratorResponse_File::has_insertion_point() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_insertion_point() { + _has_bits_[0] |= 0x00000002u; +} +inline void CodeGeneratorResponse_File::clear_has_insertion_point() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CodeGeneratorResponse_File::clear_insertion_point() { + insertion_point_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_insertion_point(); +} +inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) + return insertion_point_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) { + set_has_insertion_point(); + insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) +} +inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) { + set_has_insertion_point(); + insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) +} +inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) { + set_has_insertion_point(); + insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) +} +inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() { + set_has_insertion_point(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) + return insertion_point_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) + clear_has_insertion_point(); + return insertion_point_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) { + if (insertion_point != NULL) { + set_has_insertion_point(); + } else { + clear_has_insertion_point(); + } + insertion_point_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), insertion_point); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) +} + +// optional string content = 15; +inline bool CodeGeneratorResponse_File::has_content() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_content() { + _has_bits_[0] |= 0x00000004u; +} +inline void CodeGeneratorResponse_File::clear_has_content() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CodeGeneratorResponse_File::clear_content() { + content_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_content(); +} +inline const ::std::string& CodeGeneratorResponse_File::content() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content) + return content_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) { + set_has_content(); + content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content) +} +inline void CodeGeneratorResponse_File::set_content(const char* value) { + set_has_content(); + content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content) +} +inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) { + set_has_content(); + content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content) +} +inline ::std::string* CodeGeneratorResponse_File::mutable_content() { + set_has_content(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content) + return content_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CodeGeneratorResponse_File::release_content() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content) + clear_has_content(); + return content_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) { + if (content != NULL) { + set_has_content(); + } else { + clear_has_content(); + } + content_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), content); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content) +} + +// ------------------------------------------------------------------- + +// CodeGeneratorResponse + +// optional string error = 1; +inline bool CodeGeneratorResponse::has_error() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CodeGeneratorResponse::set_has_error() { + _has_bits_[0] |= 0x00000001u; +} +inline void CodeGeneratorResponse::clear_has_error() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CodeGeneratorResponse::clear_error() { + error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_error(); +} +inline const ::std::string& CodeGeneratorResponse::error() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error) + return error_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorResponse::set_error(const ::std::string& value) { + set_has_error(); + error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error) +} +inline void CodeGeneratorResponse::set_error(const char* value) { + set_has_error(); + error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error) +} +inline void CodeGeneratorResponse::set_error(const char* value, size_t size) { + set_has_error(); + error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error) +} +inline ::std::string* CodeGeneratorResponse::mutable_error() { + set_has_error(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error) + return error_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CodeGeneratorResponse::release_error() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error) + clear_has_error(); + return error_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) { + if (error != NULL) { + set_has_error(); + } else { + clear_has_error(); + } + error_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error) +} + +// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; +inline int CodeGeneratorResponse::file_size() const { + return file_.size(); +} +inline void CodeGeneratorResponse::clear_file() { + file_.Clear(); +} +inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_.Get(index); +} +inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_.Mutable(index); +} +inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* +CodeGeneratorResponse::mutable_file() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file) + return &file_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& +CodeGeneratorResponse::file() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace compiler +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/compiler/plugin.proto b/thirdparty/linux/include/google/protobuf/compiler/plugin.proto new file mode 100644 index 0000000..acaee1f --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/plugin.proto @@ -0,0 +1,150 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to +// change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +option go_package = "plugin_go"; + +import "google/protobuf/descriptor.proto"; + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + repeated FileDescriptorProto proto_file = 15; +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + } + repeated File file = 15; +} diff --git a/thirdparty/linux/include/google/protobuf/compiler/python/python_generator.h b/thirdparty/linux/include/google/protobuf/compiler/python/python_generator.h new file mode 100644 index 0000000..7583aa6 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/python/python_generator.h @@ -0,0 +1,174 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: robinson@google.com (Will Robinson) +// +// Generates Python code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ + +#include + +#include +#include +#include + +namespace google { +namespace protobuf { + +class Descriptor; +class EnumDescriptor; +class EnumValueDescriptor; +class FieldDescriptor; +class OneofDescriptor; +class ServiceDescriptor; + +namespace io { class Printer; } + +namespace compiler { +namespace python { + +// CodeGenerator implementation for generated Python protocol buffer classes. +// If you create your own protocol compiler binary and you want it to support +// Python output, you can do so by registering an instance of this +// CodeGenerator with the CommandLineInterface in your main() function. +class LIBPROTOC_EXPORT Generator : public CodeGenerator { + public: + Generator(); + virtual ~Generator(); + + // CodeGenerator methods. + virtual bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const; + + private: + void PrintImports() const; + void PrintFileDescriptor() const; + void PrintTopLevelEnums() const; + void PrintAllNestedEnumsInFile() const; + void PrintNestedEnums(const Descriptor& descriptor) const; + void PrintEnum(const EnumDescriptor& enum_descriptor) const; + + void PrintTopLevelExtensions() const; + + void PrintFieldDescriptor( + const FieldDescriptor& field, bool is_extension) const; + void PrintFieldDescriptorsInDescriptor( + const Descriptor& message_descriptor, + bool is_extension, + const string& list_variable_name, + int (Descriptor::*CountFn)() const, + const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const; + void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const; + void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const; + void PrintMessageDescriptors() const; + void PrintDescriptor(const Descriptor& message_descriptor) const; + void PrintNestedDescriptors(const Descriptor& containing_descriptor) const; + + void PrintMessages() const; + void PrintMessage(const Descriptor& message_descriptor, const string& prefix, + vector* to_register) const; + void PrintNestedMessages(const Descriptor& containing_descriptor, + const string& prefix, + vector* to_register) const; + + void FixForeignFieldsInDescriptors() const; + void FixForeignFieldsInDescriptor( + const Descriptor& descriptor, + const Descriptor* containing_descriptor) const; + void FixForeignFieldsInField(const Descriptor* containing_type, + const FieldDescriptor& field, + const string& python_dict_name) const; + void AddMessageToFileDescriptor(const Descriptor& descriptor) const; + void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const; + void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const; + string FieldReferencingExpression(const Descriptor* containing_type, + const FieldDescriptor& field, + const string& python_dict_name) const; + template + void FixContainingTypeInDescriptor( + const DescriptorT& descriptor, + const Descriptor* containing_descriptor) const; + + void FixForeignFieldsInExtensions() const; + void FixForeignFieldsInExtension( + const FieldDescriptor& extension_field) const; + void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const; + + void PrintServices() const; + void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const; + void PrintServiceClass(const ServiceDescriptor& descriptor) const; + void PrintServiceStub(const ServiceDescriptor& descriptor) const; + void PrintDescriptorKeyAndModuleName( + const ServiceDescriptor& descriptor) const ; + + void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; + string OptionsValue(const string& class_name, + const string& serialized_options) const; + bool GeneratingDescriptorProto() const; + + template + string ModuleLevelDescriptorName(const DescriptorT& descriptor) const; + string ModuleLevelMessageName(const Descriptor& descriptor) const; + string ModuleLevelServiceDescriptorName( + const ServiceDescriptor& descriptor) const; + + template + void PrintSerializedPbInterval( + const DescriptorT& descriptor, DescriptorProtoT& proto) const; + + void FixAllDescriptorOptions() const; + void FixOptionsForField(const FieldDescriptor& field) const; + void FixOptionsForOneof(const OneofDescriptor& oneof) const; + void FixOptionsForEnum(const EnumDescriptor& descriptor) const; + void FixOptionsForMessage(const Descriptor& descriptor) const; + + void CopyPublicDependenciesAliases( + const string& copy_from, const FileDescriptor* file) const; + + // Very coarse-grained lock to ensure that Generate() is reentrant. + // Guards file_, printer_ and file_descriptor_serialized_. + mutable Mutex mutex_; + mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. + mutable string file_descriptor_serialized_; + mutable io::Printer* printer_; // Set in Generate(). Under mutex_. + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); +}; + +} // namespace python +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/compiler/ruby/ruby_generator.h b/thirdparty/linux/include/google/protobuf/compiler/ruby/ruby_generator.h new file mode 100644 index 0000000..75555c3 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/compiler/ruby/ruby_generator.h @@ -0,0 +1,58 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__ + +#include + +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace ruby { + +class LIBPROTOC_EXPORT Generator + : public google::protobuf::compiler::CodeGenerator { + virtual bool Generate( + const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const; +}; + +} // namespace ruby +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__ + diff --git a/thirdparty/linux/include/google/protobuf/descriptor.h b/thirdparty/linux/include/google/protobuf/descriptor.h new file mode 100644 index 0000000..b040b62 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/descriptor.h @@ -0,0 +1,1919 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains classes which describe a type of protocol message. +// You can use a message's descriptor to learn at runtime what fields +// it contains and what the types of those fields are. The Message +// interface also allows you to dynamically access and modify individual +// fields by passing the FieldDescriptor of the field you are interested +// in. +// +// Most users will not care about descriptors, because they will write +// code specific to certain protocol types and will simply use the classes +// generated by the protocol compiler directly. Advanced users who want +// to operate on arbitrary types (not known at compile time) may want to +// read descriptors in order to learn about the contents of a message. +// A very small number of users will want to construct their own +// Descriptors, either because they are implementing Message manually or +// because they are writing something like the protocol compiler. +// +// For an example of how you might use descriptors, see the code example +// at the top of message.h. + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__ +#define GOOGLE_PROTOBUF_DESCRIPTOR_H__ + +#include +#ifndef _SHARED_PTR_H +#include +#endif +#include +#include +#include +#include + +// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h. +#ifdef TYPE_BOOL +#undef TYPE_BOOL +#endif // TYPE_BOOL + +namespace google { +namespace protobuf { + +// Defined in this file. +class Descriptor; +class FieldDescriptor; +class OneofDescriptor; +class EnumDescriptor; +class EnumValueDescriptor; +class ServiceDescriptor; +class MethodDescriptor; +class FileDescriptor; +class DescriptorDatabase; +class DescriptorPool; + +// Defined in descriptor.proto +class DescriptorProto; +class FieldDescriptorProto; +class OneofDescriptorProto; +class EnumDescriptorProto; +class EnumValueDescriptorProto; +class ServiceDescriptorProto; +class MethodDescriptorProto; +class FileDescriptorProto; +class MessageOptions; +class FieldOptions; +class OneofOptions; +class EnumOptions; +class EnumValueOptions; +class ServiceOptions; +class MethodOptions; +class FileOptions; +class UninterpretedOption; +class SourceCodeInfo; + +// Defined in message.h +class Message; + +// Defined in descriptor.cc +class DescriptorBuilder; +class FileDescriptorTables; + +// Defined in unknown_field_set.h. +class UnknownField; + +// Defined in generated_message_reflection.h. +namespace internal { +class GeneratedMessageReflection; +} // namespace internal + +// Defined in command_line_interface.cc +namespace compiler { +class CommandLineInterface; +} // namespace compiler + +namespace descriptor_unittest { +class DescriptorTest; +} // namespace descriptor_unittest + +// Defined in printer.h +namespace io { +class Printer; +} // namespace io + +// NB, all indices are zero-based. +struct SourceLocation { + int start_line; + int end_line; + int start_column; + int end_column; + + // Doc comments found at the source location. + // See the comments in SourceCodeInfo.Location (descriptor.proto) for details. + string leading_comments; + string trailing_comments; + vector leading_detached_comments; +}; + +// Options when generating machine-parsable output from a descriptor with +// DebugString(). +struct DebugStringOptions { + // include original user comments as recorded in SourceLocation entries. N.B. + // that this must be |false| by default: several other pieces of code (for + // example, the C++ code generation for fields in the proto compiler) rely on + // DebugString() output being unobstructed by user comments. + bool include_comments; + // If true, elide the braced body in the debug string. + bool elide_group_body; + bool elide_oneof_body; + + DebugStringOptions() + : include_comments(false), + elide_group_body(false), + elide_oneof_body(false) {} +}; + +// Describes a type of protocol message, or a particular group within a +// message. To obtain the Descriptor for a given message object, call +// Message::GetDescriptor(). Generated message classes also have a +// static method called descriptor() which returns the type's descriptor. +// Use DescriptorPool to construct your own descriptors. +class LIBPROTOBUF_EXPORT Descriptor { + public: + // The name of the message type, not including its scope. + const string& name() const; + + // The fully-qualified name of the message type, scope delimited by + // periods. For example, message type "Foo" which is declared in package + // "bar" has full name "bar.Foo". If a type "Baz" is nested within + // Foo, Baz's full_name is "bar.Foo.Baz". To get only the part that + // comes after the last '.', use name(). + const string& full_name() const; + + // Index of this descriptor within the file or containing type's message + // type array. + int index() const; + + // The .proto file in which this message type was defined. Never NULL. + const FileDescriptor* file() const; + + // If this Descriptor describes a nested type, this returns the type + // in which it is nested. Otherwise, returns NULL. + const Descriptor* containing_type() const; + + // Get options for this message type. These are specified in the .proto file + // by placing lines like "option foo = 1234;" in the message definition. + // Allowed options are defined by MessageOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const MessageOptions& options() const; + + // Write the contents of this Descriptor into the given DescriptorProto. + // The target DescriptorProto must be clear before calling this; if it + // isn't, the result may be garbage. + void CopyTo(DescriptorProto* proto) const; + + // Write the contents of this decriptor in a human-readable form. Output + // will be suitable for re-parsing. + string DebugString() const; + + // Similar to DebugString(), but additionally takes options (e.g., + // include original user comments in output). + string DebugStringWithOptions(const DebugStringOptions& options) const; + + // Returns true if this is a placeholder for an unknown type. This will + // only be the case if this descriptor comes from a DescriptorPool + // with AllowUnknownDependencies() set. + bool is_placeholder() const; + + // Field stuff ----------------------------------------------------- + + // The number of fields in this message type. + int field_count() const; + // Gets a field by index, where 0 <= index < field_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* field(int index) const; + + // Looks up a field by declared tag number. Returns NULL if no such field + // exists. + const FieldDescriptor* FindFieldByNumber(int number) const; + // Looks up a field by name. Returns NULL if no such field exists. + const FieldDescriptor* FindFieldByName(const string& name) const; + + // Looks up a field by lowercased name (as returned by lowercase_name()). + // This lookup may be ambiguous if multiple field names differ only by case, + // in which case the field returned is chosen arbitrarily from the matches. + const FieldDescriptor* FindFieldByLowercaseName( + const string& lowercase_name) const; + + // Looks up a field by camel-case name (as returned by camelcase_name()). + // This lookup may be ambiguous if multiple field names differ in a way that + // leads them to have identical camel-case names, in which case the field + // returned is chosen arbitrarily from the matches. + const FieldDescriptor* FindFieldByCamelcaseName( + const string& camelcase_name) const; + + // The number of oneofs in this message type. + int oneof_decl_count() const; + // Get a oneof by index, where 0 <= index < oneof_decl_count(). + // These are returned in the order they were defined in the .proto file. + const OneofDescriptor* oneof_decl(int index) const; + + // Looks up a oneof by name. Returns NULL if no such oneof exists. + const OneofDescriptor* FindOneofByName(const string& name) const; + + // Nested type stuff ----------------------------------------------- + + // The number of nested types in this message type. + int nested_type_count() const; + // Gets a nested type by index, where 0 <= index < nested_type_count(). + // These are returned in the order they were defined in the .proto file. + const Descriptor* nested_type(int index) const; + + // Looks up a nested type by name. Returns NULL if no such nested type + // exists. + const Descriptor* FindNestedTypeByName(const string& name) const; + + // Enum stuff ------------------------------------------------------ + + // The number of enum types in this message type. + int enum_type_count() const; + // Gets an enum type by index, where 0 <= index < enum_type_count(). + // These are returned in the order they were defined in the .proto file. + const EnumDescriptor* enum_type(int index) const; + + // Looks up an enum type by name. Returns NULL if no such enum type exists. + const EnumDescriptor* FindEnumTypeByName(const string& name) const; + + // Looks up an enum value by name, among all enum types in this message. + // Returns NULL if no such value exists. + const EnumValueDescriptor* FindEnumValueByName(const string& name) const; + + // Extensions ------------------------------------------------------ + + // A range of field numbers which are designated for third-party + // extensions. + struct ExtensionRange { + int start; // inclusive + int end; // exclusive + }; + + // The number of extension ranges in this message type. + int extension_range_count() const; + // Gets an extension range by index, where 0 <= index < + // extension_range_count(). These are returned in the order they were defined + // in the .proto file. + const ExtensionRange* extension_range(int index) const; + + // Returns true if the number is in one of the extension ranges. + bool IsExtensionNumber(int number) const; + + // Returns NULL if no extension range contains the given number. + const ExtensionRange* FindExtensionRangeContainingNumber(int number) const; + + // The number of extensions -- extending *other* messages -- that were + // defined nested within this message type's scope. + int extension_count() const; + // Get an extension by index, where 0 <= index < extension_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* extension(int index) const; + + // Looks up a named extension (which extends some *other* message type) + // defined within this message type's scope. + const FieldDescriptor* FindExtensionByName(const string& name) const; + + // Similar to FindFieldByLowercaseName(), but finds extensions defined within + // this message type's scope. + const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const; + + // Similar to FindFieldByCamelcaseName(), but finds extensions defined within + // this message type's scope. + const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const; + + // Reserved fields ------------------------------------------------- + + // A range of reserved field numbers. + struct ReservedRange { + int start; // inclusive + int end; // exclusive + }; + + // The number of reserved ranges in this message type. + int reserved_range_count() const; + // Gets an reserved range by index, where 0 <= index < + // reserved_range_count(). These are returned in the order they were defined + // in the .proto file. + const ReservedRange* reserved_range(int index) const; + + // Returns true if the number is in one of the reserved ranges. + bool IsReservedNumber(int number) const; + + // Returns NULL if no reserved range contains the given number. + const ReservedRange* FindReservedRangeContainingNumber(int number) const; + + // The number of reserved field names in this message type. + int reserved_name_count() const; + + // Gets a reserved name by index, where 0 <= index < reserved_name_count(). + const string& reserved_name(int index) const; + + // Returns true if the field name is reserved. + bool IsReservedName(const string& name) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this message declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef MessageOptions OptionsType; + + // Allows tests to test CopyTo(proto, true). + friend class ::google::protobuf::descriptor_unittest::DescriptorTest; + + // Allows access to GetLocationPath for annotations. + friend class ::google::protobuf::io::Printer; + + // Fill the json_name field of FieldDescriptorProto. + void CopyJsonNameTo(DescriptorProto* proto) const; + + // Internal version of DebugString; controls the level of indenting for + // correct depth. Takes |options| to control debug-string options, and + // |include_opening_clause| to indicate whether the "message ... " part of the + // clause has already been generated (this varies depending on context). + void DebugString(int depth, string *contents, + const DebugStringOptions& options, + bool include_opening_clause) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector* output) const; + + const string* name_; + const string* full_name_; + const FileDescriptor* file_; + const Descriptor* containing_type_; + const MessageOptions* options_; + + // True if this is a placeholder for an unknown type. + bool is_placeholder_; + // True if this is a placeholder and the type name wasn't fully-qualified. + bool is_unqualified_placeholder_; + + int field_count_; + FieldDescriptor* fields_; + int oneof_decl_count_; + OneofDescriptor* oneof_decls_; + int nested_type_count_; + Descriptor* nested_types_; + int enum_type_count_; + EnumDescriptor* enum_types_; + int extension_range_count_; + ExtensionRange* extension_ranges_; + int extension_count_; + FieldDescriptor* extensions_; + int reserved_range_count_; + ReservedRange* reserved_ranges_; + int reserved_name_count_; + const string** reserved_names_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in descriptor.cc + // and update them to initialize the field. + + // Must be constructed using DescriptorPool. + Descriptor() {} + friend class DescriptorBuilder; + friend class EnumDescriptor; + friend class FieldDescriptor; + friend class OneofDescriptor; + friend class MethodDescriptor; + friend class FileDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor); +}; + +// Describes a single field of a message. To get the descriptor for a given +// field, first get the Descriptor for the message in which it is defined, +// then call Descriptor::FindFieldByName(). To get a FieldDescriptor for +// an extension, do one of the following: +// - Get the Descriptor or FileDescriptor for its containing scope, then +// call Descriptor::FindExtensionByName() or +// FileDescriptor::FindExtensionByName(). +// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber(). +// - Given a Reflection for a message object, call +// Reflection::FindKnownExtensionByName() or +// Reflection::FindKnownExtensionByNumber(). +// Use DescriptorPool to construct your own descriptors. +class LIBPROTOBUF_EXPORT FieldDescriptor { + public: + // Identifies a field type. 0 is reserved for errors. The order is weird + // for historical reasons. Types 12 and up are new in proto2. + enum Type { + TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. + TYPE_FLOAT = 2, // float, exactly four bytes on the wire. + TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT64 if negative + // values are likely. + TYPE_UINT64 = 4, // uint64, varint on the wire. + TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT32 if negative + // values are likely. + TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. + TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. + TYPE_BOOL = 8, // bool, varint on the wire. + TYPE_STRING = 9, // UTF-8 text. + TYPE_GROUP = 10, // Tag-delimited message. Deprecated. + TYPE_MESSAGE = 11, // Length-delimited message. + + TYPE_BYTES = 12, // Arbitrary byte array. + TYPE_UINT32 = 13, // uint32, varint on the wire + TYPE_ENUM = 14, // Enum, varint on the wire + TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire + TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire + TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire + TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire + + MAX_TYPE = 18, // Constant useful for defining lookup tables + // indexed by Type. + }; + + // Specifies the C++ data type used to represent the field. There is a + // fixed mapping from Type to CppType where each Type maps to exactly one + // CppType. 0 is reserved for errors. + enum CppType { + CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 + CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 + CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 + CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 + CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE + CPPTYPE_FLOAT = 6, // TYPE_FLOAT + CPPTYPE_BOOL = 7, // TYPE_BOOL + CPPTYPE_ENUM = 8, // TYPE_ENUM + CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES + CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP + + MAX_CPPTYPE = 10, // Constant useful for defining lookup tables + // indexed by CppType. + }; + + // Identifies whether the field is optional, required, or repeated. 0 is + // reserved for errors. + enum Label { + LABEL_OPTIONAL = 1, // optional + LABEL_REQUIRED = 2, // required + LABEL_REPEATED = 3, // repeated + + MAX_LABEL = 3, // Constant useful for defining lookup tables + // indexed by Label. + }; + + // Valid field numbers are positive integers up to kMaxNumber. + static const int kMaxNumber = (1 << 29) - 1; + + // First field number reserved for the protocol buffer library implementation. + // Users may not declare fields that use reserved numbers. + static const int kFirstReservedNumber = 19000; + // Last field number reserved for the protocol buffer library implementation. + // Users may not declare fields that use reserved numbers. + static const int kLastReservedNumber = 19999; + + const string& name() const; // Name of this field within the message. + const string& full_name() const; // Fully-qualified name of the field. + const string& json_name() const; // JSON name of this field. + const FileDescriptor* file() const;// File in which this field was defined. + bool is_extension() const; // Is this an extension field? + int number() const; // Declared tag number. + + // Same as name() except converted to lower-case. This (and especially the + // FindFieldByLowercaseName() method) can be useful when parsing formats + // which prefer to use lowercase naming style. (Although, technically + // field names should be lowercased anyway according to the protobuf style + // guide, so this only makes a difference when dealing with old .proto files + // which do not follow the guide.) + const string& lowercase_name() const; + + // Same as name() except converted to camel-case. In this conversion, any + // time an underscore appears in the name, it is removed and the next + // letter is capitalized. Furthermore, the first letter of the name is + // lower-cased. Examples: + // FooBar -> fooBar + // foo_bar -> fooBar + // fooBar -> fooBar + // This (and especially the FindFieldByCamelcaseName() method) can be useful + // when parsing formats which prefer to use camel-case naming style. + const string& camelcase_name() const; + + Type type() const; // Declared type of this field. + const char* type_name() const; // Name of the declared type. + CppType cpp_type() const; // C++ type of this field. + const char* cpp_type_name() const; // Name of the C++ type. + Label label() const; // optional/required/repeated + + bool is_required() const; // shorthand for label() == LABEL_REQUIRED + bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL + bool is_repeated() const; // shorthand for label() == LABEL_REPEATED + bool is_packable() const; // shorthand for is_repeated() && + // IsTypePackable(type()) + bool is_packed() const; // shorthand for is_packable() && + // options().packed() + bool is_map() const; // shorthand for type() == TYPE_MESSAGE && + // message_type()->options().map_entry() + + // Index of this field within the message's field array, or the file or + // extension scope's extensions array. + int index() const; + + // Does this field have an explicitly-declared default value? + bool has_default_value() const; + + // Get the field default value if cpp_type() == CPPTYPE_INT32. If no + // explicit default was defined, the default is 0. + int32 default_value_int32() const; + // Get the field default value if cpp_type() == CPPTYPE_INT64. If no + // explicit default was defined, the default is 0. + int64 default_value_int64() const; + // Get the field default value if cpp_type() == CPPTYPE_UINT32. If no + // explicit default was defined, the default is 0. + uint32 default_value_uint32() const; + // Get the field default value if cpp_type() == CPPTYPE_UINT64. If no + // explicit default was defined, the default is 0. + uint64 default_value_uint64() const; + // Get the field default value if cpp_type() == CPPTYPE_FLOAT. If no + // explicit default was defined, the default is 0.0. + float default_value_float() const; + // Get the field default value if cpp_type() == CPPTYPE_DOUBLE. If no + // explicit default was defined, the default is 0.0. + double default_value_double() const; + // Get the field default value if cpp_type() == CPPTYPE_BOOL. If no + // explicit default was defined, the default is false. + bool default_value_bool() const; + // Get the field default value if cpp_type() == CPPTYPE_ENUM. If no + // explicit default was defined, the default is the first value defined + // in the enum type (all enum types are required to have at least one value). + // This never returns NULL. + const EnumValueDescriptor* default_value_enum() const; + // Get the field default value if cpp_type() == CPPTYPE_STRING. If no + // explicit default was defined, the default is the empty string. + const string& default_value_string() const; + + // The Descriptor for the message of which this is a field. For extensions, + // this is the extended type. Never NULL. + const Descriptor* containing_type() const; + + // If the field is a member of a oneof, this is the one, otherwise this is + // NULL. + const OneofDescriptor* containing_oneof() const; + + // If the field is a member of a oneof, returns the index in that oneof. + int index_in_oneof() const; + + // An extension may be declared within the scope of another message. If this + // field is an extension (is_extension() is true), then extension_scope() + // returns that message, or NULL if the extension was declared at global + // scope. If this is not an extension, extension_scope() is undefined (may + // assert-fail). + const Descriptor* extension_scope() const; + + // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the + // message or the group type. Otherwise, returns null. + const Descriptor* message_type() const; + // If type is TYPE_ENUM, returns a descriptor for the enum. Otherwise, + // returns null. + const EnumDescriptor* enum_type() const; + + // Get the FieldOptions for this field. This includes things listed in + // square brackets after the field definition. E.g., the field: + // optional string text = 1 [ctype=CORD]; + // has the "ctype" option set. Allowed options are defined by FieldOptions + // in google/protobuf/descriptor.proto, and any available extensions of that + // message. + const FieldOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(FieldDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + string DebugStringWithOptions(const DebugStringOptions& options) const; + + // Helper method to get the CppType for a particular Type. + static CppType TypeToCppType(Type type); + + // Helper method to get the name of a Type. + static const char* TypeName(Type type); + + // Helper method to get the name of a CppType. + static const char* CppTypeName(CppType cpp_type); + + // Return true iff [packed = true] is valid for fields of this type. + static inline bool IsTypePackable(Type field_type); + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this field declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef FieldOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class ::google::protobuf::io::Printer; + + // Fill the json_name field of FieldDescriptorProto. + void CopyJsonNameTo(FieldDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + enum PrintLabelFlag { PRINT_LABEL, OMIT_LABEL }; + void DebugString(int depth, PrintLabelFlag print_label_flag, + string* contents, const DebugStringOptions& options) const; + + // formats the default value appropriately and returns it as a string. + // Must have a default value to call this. If quote_string_type is true, then + // types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped. + string DefaultValueAsString(bool quote_string_type) const; + + // Helper function that returns the field type name for DebugString. + string FieldTypeNameDebugString() const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector* output) const; + + const string* name_; + const string* full_name_; + const string* lowercase_name_; + const string* camelcase_name_; + // Whether the user has specified the json_name field option in the .proto + // file. + bool has_json_name_; + // If has_json_name_ is true, it's the value specified by the user. + // Otherwise, it has the same value as lowercase_name_. + const string* json_name_; + const FileDescriptor* file_; + int number_; + Type type_; + Label label_; + bool is_extension_; + int index_in_oneof_; + const Descriptor* containing_type_; + const OneofDescriptor* containing_oneof_; + const Descriptor* extension_scope_; + const Descriptor* message_type_; + const EnumDescriptor* enum_type_; + const FieldOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + bool has_default_value_; + union { + int32 default_value_int32_; + int64 default_value_int64_; + uint32 default_value_uint32_; + uint64 default_value_uint64_; + float default_value_float_; + double default_value_double_; + bool default_value_bool_; + + const EnumValueDescriptor* default_value_enum_; + const string* default_value_string_; + }; + + static const CppType kTypeToCppTypeMap[MAX_TYPE + 1]; + + static const char * const kTypeToName[MAX_TYPE + 1]; + + static const char * const kCppTypeToName[MAX_CPPTYPE + 1]; + + static const char * const kLabelToName[MAX_LABEL + 1]; + + // Must be constructed using DescriptorPool. + FieldDescriptor() {} + friend class DescriptorBuilder; + friend class FileDescriptor; + friend class Descriptor; + friend class OneofDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor); +}; + +// Describes a oneof defined in a message type. +class LIBPROTOBUF_EXPORT OneofDescriptor { + public: + const string& name() const; // Name of this oneof. + const string& full_name() const; // Fully-qualified name of the oneof. + + // Index of this oneof within the message's oneof array. + int index() const; + + // The Descriptor for the message containing this oneof. + const Descriptor* containing_type() const; + + // The number of (non-extension) fields which are members of this oneof. + int field_count() const; + // Get a member of this oneof, in the order in which they were declared in the + // .proto file. Does not include extensions. + const FieldDescriptor* field(int index) const; + + const OneofOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(OneofDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + string DebugStringWithOptions(const DebugStringOptions& options) const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this oneof declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef OneofOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class ::google::protobuf::io::Printer; + + // See Descriptor::DebugString(). + void DebugString(int depth, string* contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector* output) const; + + const string* name_; + const string* full_name_; + const Descriptor* containing_type_; + bool is_extendable_; + int field_count_; + const FieldDescriptor** fields_; + const OneofOptions* options_; + + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() + // in descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + OneofDescriptor() {} + friend class DescriptorBuilder; + friend class Descriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofDescriptor); +}; + +// Describes an enum type defined in a .proto file. To get the EnumDescriptor +// for a generated enum type, call TypeName_descriptor(). Use DescriptorPool +// to construct your own descriptors. +class LIBPROTOBUF_EXPORT EnumDescriptor { + public: + // The name of this enum type in the containing scope. + const string& name() const; + + // The fully-qualified name of the enum type, scope delimited by periods. + const string& full_name() const; + + // Index of this enum within the file or containing message's enum array. + int index() const; + + // The .proto file in which this enum type was defined. Never NULL. + const FileDescriptor* file() const; + + // The number of values for this EnumDescriptor. Guaranteed to be greater + // than zero. + int value_count() const; + // Gets a value by index, where 0 <= index < value_count(). + // These are returned in the order they were defined in the .proto file. + const EnumValueDescriptor* value(int index) const; + + // Looks up a value by name. Returns NULL if no such value exists. + const EnumValueDescriptor* FindValueByName(const string& name) const; + // Looks up a value by number. Returns NULL if no such value exists. If + // multiple values have this number, the first one defined is returned. + const EnumValueDescriptor* FindValueByNumber(int number) const; + + // If this enum type is nested in a message type, this is that message type. + // Otherwise, NULL. + const Descriptor* containing_type() const; + + // Get options for this enum type. These are specified in the .proto file by + // placing lines like "option foo = 1234;" in the enum definition. Allowed + // options are defined by EnumOptions in google/protobuf/descriptor.proto, + // and any available extensions of that message. + const EnumOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(EnumDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + string DebugStringWithOptions(const DebugStringOptions& options) const; + + + // Returns true if this is a placeholder for an unknown enum. This will + // only be the case if this descriptor comes from a DescriptorPool + // with AllowUnknownDependencies() set. + bool is_placeholder() const; + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this enum declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef EnumOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class ::google::protobuf::io::Printer; + + // Looks up a value by number. If the value does not exist, dynamically + // creates a new EnumValueDescriptor for that value, assuming that it was + // unknown. If a new descriptor is created, this is done in a thread-safe way, + // and future calls will return the same value descriptor pointer. + // + // This is private but is used by GeneratedMessageReflection (which is + // friended below) to return a valid EnumValueDescriptor from GetEnum() when + // this feature is enabled. + const EnumValueDescriptor* + FindValueByNumberCreatingIfUnknown(int number) const; + + + // See Descriptor::DebugString(). + void DebugString(int depth, string *contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector* output) const; + + const string* name_; + const string* full_name_; + const FileDescriptor* file_; + const Descriptor* containing_type_; + const EnumOptions* options_; + + // True if this is a placeholder for an unknown type. + bool is_placeholder_; + // True if this is a placeholder and the type name wasn't fully-qualified. + bool is_unqualified_placeholder_; + + int value_count_; + EnumValueDescriptor* values_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + EnumDescriptor() {} + friend class DescriptorBuilder; + friend class Descriptor; + friend class FieldDescriptor; + friend class EnumValueDescriptor; + friend class FileDescriptor; + friend class internal::GeneratedMessageReflection; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor); +}; + +// Describes an individual enum constant of a particular type. To get the +// EnumValueDescriptor for a given enum value, first get the EnumDescriptor +// for its type, then use EnumDescriptor::FindValueByName() or +// EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct +// your own descriptors. +class LIBPROTOBUF_EXPORT EnumValueDescriptor { + public: + const string& name() const; // Name of this enum constant. + int index() const; // Index within the enums's Descriptor. + int number() const; // Numeric value of this enum constant. + + // The full_name of an enum value is a sibling symbol of the enum type. + // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually + // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT + // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32". This is to conform + // with C++ scoping rules for enums. + const string& full_name() const; + + // The type of this value. Never NULL. + const EnumDescriptor* type() const; + + // Get options for this enum value. These are specified in the .proto file + // by adding text like "[foo = 1234]" after an enum value definition. + // Allowed options are defined by EnumValueOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const EnumValueOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(EnumValueDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + string DebugStringWithOptions(const DebugStringOptions& options) const; + + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this enum value declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef EnumValueOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class ::google::protobuf::io::Printer; + + // See Descriptor::DebugString(). + void DebugString(int depth, string *contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector* output) const; + + const string* name_; + const string* full_name_; + int number_; + const EnumDescriptor* type_; + const EnumValueOptions* options_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() + // in descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + EnumValueDescriptor() {} + friend class DescriptorBuilder; + friend class EnumDescriptor; + friend class FileDescriptorTables; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor); +}; + +// Describes an RPC service. To get the ServiceDescriptor for a service, +// call Service::GetDescriptor(). Generated service classes also have a +// static method called descriptor() which returns the type's +// ServiceDescriptor. Use DescriptorPool to construct your own descriptors. +class LIBPROTOBUF_EXPORT ServiceDescriptor { + public: + // The name of the service, not including its containing scope. + const string& name() const; + // The fully-qualified name of the service, scope delimited by periods. + const string& full_name() const; + // Index of this service within the file's services array. + int index() const; + + // The .proto file in which this service was defined. Never NULL. + const FileDescriptor* file() const; + + // Get options for this service type. These are specified in the .proto file + // by placing lines like "option foo = 1234;" in the service definition. + // Allowed options are defined by ServiceOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const ServiceOptions& options() const; + + // The number of methods this service defines. + int method_count() const; + // Gets a MethodDescriptor by index, where 0 <= index < method_count(). + // These are returned in the order they were defined in the .proto file. + const MethodDescriptor* method(int index) const; + + // Look up a MethodDescriptor by name. + const MethodDescriptor* FindMethodByName(const string& name) const; + // See Descriptor::CopyTo(). + void CopyTo(ServiceDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + string DebugStringWithOptions(const DebugStringOptions& options) const; + + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this service declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef ServiceOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class ::google::protobuf::io::Printer; + + // See Descriptor::DebugString(). + void DebugString(string *contents, const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector* output) const; + + const string* name_; + const string* full_name_; + const FileDescriptor* file_; + const ServiceOptions* options_; + int method_count_; + MethodDescriptor* methods_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + ServiceDescriptor() {} + friend class DescriptorBuilder; + friend class FileDescriptor; + friend class MethodDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor); +}; + +// Describes an individual service method. To obtain a MethodDescriptor given +// a service, first get its ServiceDescriptor, then call +// ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your +// own descriptors. +class LIBPROTOBUF_EXPORT MethodDescriptor { + public: + // Name of this method, not including containing scope. + const string& name() const; + // The fully-qualified name of the method, scope delimited by periods. + const string& full_name() const; + // Index within the service's Descriptor. + int index() const; + + // Gets the service to which this method belongs. Never NULL. + const ServiceDescriptor* service() const; + + // Gets the type of protocol message which this method accepts as input. + const Descriptor* input_type() const; + // Gets the type of protocol message which this message produces as output. + const Descriptor* output_type() const; + + // Gets whether the client streams multiple requests. + bool client_streaming() const; + // Gets whether the server streams multiple responses. + bool server_streaming() const; + + // Get options for this method. These are specified in the .proto file by + // placing lines like "option foo = 1234;" in curly-braces after a method + // declaration. Allowed options are defined by MethodOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const MethodOptions& options() const; + + // See Descriptor::CopyTo(). + void CopyTo(MethodDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + string DebugStringWithOptions(const DebugStringOptions& options) const; + + + // Source Location --------------------------------------------------- + + // Updates |*out_location| to the source location of the complete + // extent of this method declaration. Returns false and leaves + // |*out_location| unchanged iff location information was not available. + bool GetSourceLocation(SourceLocation* out_location) const; + + private: + typedef MethodOptions OptionsType; + + // Allows access to GetLocationPath for annotations. + friend class ::google::protobuf::io::Printer; + + // See Descriptor::DebugString(). + void DebugString(int depth, string *contents, + const DebugStringOptions& options) const; + + // Walks up the descriptor tree to generate the source location path + // to this descriptor from the file root. + void GetLocationPath(std::vector* output) const; + + const string* name_; + const string* full_name_; + const ServiceDescriptor* service_; + const Descriptor* input_type_; + const Descriptor* output_type_; + const MethodOptions* options_; + bool client_streaming_; + bool server_streaming_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + // Must be constructed using DescriptorPool. + MethodDescriptor() {} + friend class DescriptorBuilder; + friend class ServiceDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor); +}; + + +// Describes a whole .proto file. To get the FileDescriptor for a compiled-in +// file, get the descriptor for something defined in that file and call +// descriptor->file(). Use DescriptorPool to construct your own descriptors. +class LIBPROTOBUF_EXPORT FileDescriptor { + public: + // The filename, relative to the source tree. + // e.g. "google/protobuf/descriptor.proto" + const string& name() const; + + // The package, e.g. "google.protobuf.compiler". + const string& package() const; + + // The DescriptorPool in which this FileDescriptor and all its contents were + // allocated. Never NULL. + const DescriptorPool* pool() const; + + // The number of files imported by this one. + int dependency_count() const; + // Gets an imported file by index, where 0 <= index < dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* dependency(int index) const; + + // The number of files public imported by this one. + // The public dependency list is a subset of the dependency list. + int public_dependency_count() const; + // Gets a public imported file by index, where 0 <= index < + // public_dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* public_dependency(int index) const; + + // The number of files that are imported for weak fields. + // The weak dependency list is a subset of the dependency list. + int weak_dependency_count() const; + // Gets a weak imported file by index, where 0 <= index < + // weak_dependency_count(). + // These are returned in the order they were defined in the .proto file. + const FileDescriptor* weak_dependency(int index) const; + + // Number of top-level message types defined in this file. (This does not + // include nested types.) + int message_type_count() const; + // Gets a top-level message type, where 0 <= index < message_type_count(). + // These are returned in the order they were defined in the .proto file. + const Descriptor* message_type(int index) const; + + // Number of top-level enum types defined in this file. (This does not + // include nested types.) + int enum_type_count() const; + // Gets a top-level enum type, where 0 <= index < enum_type_count(). + // These are returned in the order they were defined in the .proto file. + const EnumDescriptor* enum_type(int index) const; + + // Number of services defined in this file. + int service_count() const; + // Gets a service, where 0 <= index < service_count(). + // These are returned in the order they were defined in the .proto file. + const ServiceDescriptor* service(int index) const; + + // Number of extensions defined at file scope. (This does not include + // extensions nested within message types.) + int extension_count() const; + // Gets an extension's descriptor, where 0 <= index < extension_count(). + // These are returned in the order they were defined in the .proto file. + const FieldDescriptor* extension(int index) const; + + // Get options for this file. These are specified in the .proto file by + // placing lines like "option foo = 1234;" at the top level, outside of any + // other definitions. Allowed options are defined by FileOptions in + // google/protobuf/descriptor.proto, and any available extensions of that + // message. + const FileOptions& options() const; + + // Syntax of this file. + enum Syntax { + SYNTAX_UNKNOWN = 0, + SYNTAX_PROTO2 = 2, + SYNTAX_PROTO3 = 3, + }; + Syntax syntax() const; + static const char* SyntaxName(Syntax syntax); + + // Find a top-level message type by name. Returns NULL if not found. + const Descriptor* FindMessageTypeByName(const string& name) const; + // Find a top-level enum type by name. Returns NULL if not found. + const EnumDescriptor* FindEnumTypeByName(const string& name) const; + // Find an enum value defined in any top-level enum by name. Returns NULL if + // not found. + const EnumValueDescriptor* FindEnumValueByName(const string& name) const; + // Find a service definition by name. Returns NULL if not found. + const ServiceDescriptor* FindServiceByName(const string& name) const; + // Find a top-level extension definition by name. Returns NULL if not found. + const FieldDescriptor* FindExtensionByName(const string& name) const; + // Similar to FindExtensionByName(), but searches by lowercased-name. See + // Descriptor::FindFieldByLowercaseName(). + const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const; + // Similar to FindExtensionByName(), but searches by camelcased-name. See + // Descriptor::FindFieldByCamelcaseName(). + const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const; + + // See Descriptor::CopyTo(). + // Notes: + // - This method does NOT copy source code information since it is relatively + // large and rarely needed. See CopySourceCodeInfoTo() below. + void CopyTo(FileDescriptorProto* proto) const; + // Write the source code information of this FileDescriptor into the given + // FileDescriptorProto. See CopyTo() above. + void CopySourceCodeInfoTo(FileDescriptorProto* proto) const; + // Fill the json_name field of FieldDescriptorProto for all fields. Can only + // be called after CopyTo(). + void CopyJsonNameTo(FileDescriptorProto* proto) const; + + // See Descriptor::DebugString(). + string DebugString() const; + + // See Descriptor::DebugStringWithOptions(). + string DebugStringWithOptions(const DebugStringOptions& options) const; + + // Returns true if this is a placeholder for an unknown file. This will + // only be the case if this descriptor comes from a DescriptorPool + // with AllowUnknownDependencies() set. + bool is_placeholder() const; + + // Updates |*out_location| to the source location of the complete extent of + // this file declaration (namely, the empty path). + bool GetSourceLocation(SourceLocation* out_location) const; + + // Updates |*out_location| to the source location of the complete + // extent of the declaration or declaration-part denoted by |path|. + // Returns false and leaves |*out_location| unchanged iff location + // information was not available. (See SourceCodeInfo for + // description of path encoding.) + bool GetSourceLocation(const std::vector& path, + SourceLocation* out_location) const; + + private: + typedef FileOptions OptionsType; + + const string* name_; + const string* package_; + const DescriptorPool* pool_; + int dependency_count_; + const FileDescriptor** dependencies_; + int public_dependency_count_; + int* public_dependencies_; + int weak_dependency_count_; + int* weak_dependencies_; + int message_type_count_; + Descriptor* message_types_; + int enum_type_count_; + EnumDescriptor* enum_types_; + int service_count_; + ServiceDescriptor* services_; + int extension_count_; + Syntax syntax_; + bool is_placeholder_; + FieldDescriptor* extensions_; + const FileOptions* options_; + + const FileDescriptorTables* tables_; + const SourceCodeInfo* source_code_info_; + // IMPORTANT: If you add a new field, make sure to search for all instances + // of Allocate() and AllocateArray() in + // descriptor.cc and update them to initialize the field. + + FileDescriptor() {} + friend class DescriptorBuilder; + friend class Descriptor; + friend class FieldDescriptor; + friend class OneofDescriptor; + friend class EnumDescriptor; + friend class EnumValueDescriptor; + friend class MethodDescriptor; + friend class ServiceDescriptor; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor); +}; + +// =================================================================== + +// Used to construct descriptors. +// +// Normally you won't want to build your own descriptors. Message classes +// constructed by the protocol compiler will provide them for you. However, +// if you are implementing Message on your own, or if you are writing a +// program which can operate on totally arbitrary types and needs to load +// them from some sort of database, you might need to. +// +// Since Descriptors are composed of a whole lot of cross-linked bits of +// data that would be a pain to put together manually, the +// DescriptorPool class is provided to make the process easier. It can +// take a FileDescriptorProto (defined in descriptor.proto), validate it, +// and convert it to a set of nicely cross-linked Descriptors. +// +// DescriptorPool also helps with memory management. Descriptors are +// composed of many objects containing static data and pointers to each +// other. In all likelihood, when it comes time to delete this data, +// you'll want to delete it all at once. In fact, it is not uncommon to +// have a whole pool of descriptors all cross-linked with each other which +// you wish to delete all at once. This class represents such a pool, and +// handles the memory management for you. +// +// You can also search for descriptors within a DescriptorPool by name, and +// extensions by number. +class LIBPROTOBUF_EXPORT DescriptorPool { + public: + // Create a normal, empty DescriptorPool. + DescriptorPool(); + + // Constructs a DescriptorPool that, when it can't find something among the + // descriptors already in the pool, looks for it in the given + // DescriptorDatabase. + // Notes: + // - If a DescriptorPool is constructed this way, its BuildFile*() methods + // must not be called (they will assert-fail). The only way to populate + // the pool with descriptors is to call the Find*By*() methods. + // - The Find*By*() methods may block the calling thread if the + // DescriptorDatabase blocks. This in turn means that parsing messages + // may block if they need to look up extensions. + // - The Find*By*() methods will use mutexes for thread-safety, thus making + // them slower even when they don't have to fall back to the database. + // In fact, even the Find*By*() methods of descriptor objects owned by + // this pool will be slower, since they will have to obtain locks too. + // - An ErrorCollector may optionally be given to collect validation errors + // in files loaded from the database. If not given, errors will be printed + // to GOOGLE_LOG(ERROR). Remember that files are built on-demand, so this + // ErrorCollector may be called from any thread that calls one of the + // Find*By*() methods. + // - The DescriptorDatabase must not be mutated during the lifetime of + // the DescriptorPool. Even if the client takes care to avoid data races, + // changes to the content of the DescriptorDatabase may not be reflected + // in subsequent lookups in the DescriptorPool. + class ErrorCollector; + explicit DescriptorPool(DescriptorDatabase* fallback_database, + ErrorCollector* error_collector = NULL); + + ~DescriptorPool(); + + // Get a pointer to the generated pool. Generated protocol message classes + // which are compiled into the binary will allocate their descriptors in + // this pool. Do not add your own descriptors to this pool. + static const DescriptorPool* generated_pool(); + + + // Find a FileDescriptor in the pool by file name. Returns NULL if not + // found. + const FileDescriptor* FindFileByName(const string& name) const; + + // Find the FileDescriptor in the pool which defines the given symbol. + // If any of the Find*ByName() methods below would succeed, then this is + // equivalent to calling that method and calling the result's file() method. + // Otherwise this returns NULL. + const FileDescriptor* FindFileContainingSymbol( + const string& symbol_name) const; + + // Looking up descriptors ------------------------------------------ + // These find descriptors by fully-qualified name. These will find both + // top-level descriptors and nested descriptors. They return NULL if not + // found. + + const Descriptor* FindMessageTypeByName(const string& name) const; + const FieldDescriptor* FindFieldByName(const string& name) const; + const FieldDescriptor* FindExtensionByName(const string& name) const; + const OneofDescriptor* FindOneofByName(const string& name) const; + const EnumDescriptor* FindEnumTypeByName(const string& name) const; + const EnumValueDescriptor* FindEnumValueByName(const string& name) const; + const ServiceDescriptor* FindServiceByName(const string& name) const; + const MethodDescriptor* FindMethodByName(const string& name) const; + + // Finds an extension of the given type by number. The extendee must be + // a member of this DescriptorPool or one of its underlays. + const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee, + int number) const; + + // Finds extensions of extendee. The extensions will be appended to + // out in an undefined order. Only extensions defined directly in + // this DescriptorPool or one of its underlays are guaranteed to be + // found: extensions defined in the fallback database might not be found + // depending on the database implementation. + void FindAllExtensions(const Descriptor* extendee, + std::vector* out) const; + + // Building descriptors -------------------------------------------- + + // When converting a FileDescriptorProto to a FileDescriptor, various + // errors might be detected in the input. The caller may handle these + // programmatically by implementing an ErrorCollector. + class LIBPROTOBUF_EXPORT ErrorCollector { + public: + inline ErrorCollector() {} + virtual ~ErrorCollector(); + + // These constants specify what exact part of the construct is broken. + // This is useful e.g. for mapping the error back to an exact location + // in a .proto file. + enum ErrorLocation { + NAME, // the symbol name, or the package name for files + NUMBER, // field or extension range number + TYPE, // field type + EXTENDEE, // field extendee + DEFAULT_VALUE, // field default value + INPUT_TYPE, // method input type + OUTPUT_TYPE, // method output type + OPTION_NAME, // name in assignment + OPTION_VALUE, // value in option assignment + OTHER // some other problem + }; + + // Reports an error in the FileDescriptorProto. Use this function if the + // problem occurred should interrupt building the FileDescriptorProto. + virtual void AddError( + const string& filename, // File name in which the error occurred. + const string& element_name, // Full name of the erroneous element. + const Message* descriptor, // Descriptor of the erroneous element. + ErrorLocation location, // One of the location constants, above. + const string& message // Human-readable error message. + ) = 0; + + // Reports a warning in the FileDescriptorProto. Use this function if the + // problem occurred should NOT interrupt building the FileDescriptorProto. + virtual void AddWarning( + const string& /*filename*/, // File name in which the error occurred. + const string& /*element_name*/, // Full name of the erroneous element. + const Message* /*descriptor*/, // Descriptor of the erroneous element. + ErrorLocation /*location*/, // One of the location constants, above. + const string& /*message*/ // Human-readable error message. + ) {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); + }; + + // Convert the FileDescriptorProto to real descriptors and place them in + // this DescriptorPool. All dependencies of the file must already be in + // the pool. Returns the resulting FileDescriptor, or NULL if there were + // problems with the input (e.g. the message was invalid, or dependencies + // were missing). Details about the errors are written to GOOGLE_LOG(ERROR). + const FileDescriptor* BuildFile(const FileDescriptorProto& proto); + + // Same as BuildFile() except errors are sent to the given ErrorCollector. + const FileDescriptor* BuildFileCollectingErrors( + const FileDescriptorProto& proto, + ErrorCollector* error_collector); + + // By default, it is an error if a FileDescriptorProto contains references + // to types or other files that are not found in the DescriptorPool (or its + // backing DescriptorDatabase, if any). If you call + // AllowUnknownDependencies(), however, then unknown types and files + // will be replaced by placeholder descriptors (which can be identified by + // the is_placeholder() method). This can allow you to + // perform some useful operations with a .proto file even if you do not + // have access to other .proto files on which it depends. However, some + // heuristics must be used to fill in the gaps in information, and these + // can lead to descriptors which are inaccurate. For example, the + // DescriptorPool may be forced to guess whether an unknown type is a message + // or an enum, as well as what package it resides in. Furthermore, + // placeholder types will not be discoverable via FindMessageTypeByName() + // and similar methods, which could confuse some descriptor-based algorithms. + // Generally, the results of this option should be handled with extreme care. + void AllowUnknownDependencies() { allow_unknown_ = true; } + + // By default, weak imports are allowed to be missing, in which case we will + // use a placeholder for the dependency and convert the field to be an Empty + // message field. If you call EnforceWeakDependencies(true), however, the + // DescriptorPool will report a import not found error. + void EnforceWeakDependencies(bool enforce) { enforce_weak_ = enforce; } + + // Internal stuff -------------------------------------------------- + // These methods MUST NOT be called from outside the proto2 library. + // These methods may contain hidden pitfalls and may be removed in a + // future library version. + + // Create a DescriptorPool which is overlaid on top of some other pool. + // If you search for a descriptor in the overlay and it is not found, the + // underlay will be searched as a backup. If the underlay has its own + // underlay, that will be searched next, and so on. This also means that + // files built in the overlay will be cross-linked with the underlay's + // descriptors if necessary. The underlay remains property of the caller; + // it must remain valid for the lifetime of the newly-constructed pool. + // + // Example: Say you want to parse a .proto file at runtime in order to use + // its type with a DynamicMessage. Say this .proto file has dependencies, + // but you know that all the dependencies will be things that are already + // compiled into the binary. For ease of use, you'd like to load the types + // right out of generated_pool() rather than have to parse redundant copies + // of all these .protos and runtime. But, you don't want to add the parsed + // types directly into generated_pool(): this is not allowed, and would be + // bad design anyway. So, instead, you could use generated_pool() as an + // underlay for a new DescriptorPool in which you add only the new file. + // + // WARNING: Use of underlays can lead to many subtle gotchas. Instead, + // try to formulate what you want to do in terms of DescriptorDatabases. + explicit DescriptorPool(const DescriptorPool* underlay); + + // Called by generated classes at init time to add their descriptors to + // generated_pool. Do NOT call this in your own code! filename must be a + // permanent string (e.g. a string literal). + static void InternalAddGeneratedFile( + const void* encoded_file_descriptor, int size); + + + // For internal use only: Gets a non-const pointer to the generated pool. + // This is called at static-initialization time only, so thread-safety is + // not a concern. If both an underlay and a fallback database are present, + // the underlay takes precedence. + static DescriptorPool* internal_generated_pool(); + + // For internal use only: Changes the behavior of BuildFile() such that it + // allows the file to make reference to message types declared in other files + // which it did not officially declare as dependencies. + void InternalDontEnforceDependencies(); + + // For internal use only. + void internal_set_underlay(const DescriptorPool* underlay) { + underlay_ = underlay; + } + + // For internal (unit test) use only: Returns true if a FileDescriptor has + // been constructed for the given file, false otherwise. Useful for testing + // lazy descriptor initialization behavior. + bool InternalIsFileLoaded(const string& filename) const; + + + // Add a file to unused_import_track_files_. DescriptorBuilder will log + // warnings for those files if there is any unused import. + void AddUnusedImportTrackFile(const string& file_name); + void ClearUnusedImportTrackFiles(); + + private: + friend class Descriptor; + friend class FieldDescriptor; + friend class EnumDescriptor; + friend class ServiceDescriptor; + friend class FileDescriptor; + friend class DescriptorBuilder; + friend class FileDescriptorTables; + + // Return true if the given name is a sub-symbol of any non-package + // descriptor that already exists in the descriptor pool. (The full + // definition of such types is already known.) + bool IsSubSymbolOfBuiltType(const string& name) const; + + // Tries to find something in the fallback database and link in the + // corresponding proto file. Returns true if successful, in which case + // the caller should search for the thing again. These are declared + // const because they are called by (semantically) const methods. + bool TryFindFileInFallbackDatabase(const string& name) const; + bool TryFindSymbolInFallbackDatabase(const string& name) const; + bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type, + int field_number) const; + + // Like BuildFile() but called internally when the file has been loaded from + // fallback_database_. Declared const because it is called by (semantically) + // const methods. + const FileDescriptor* BuildFileFromDatabase( + const FileDescriptorProto& proto) const; + + // If fallback_database_ is NULL, this is NULL. Otherwise, this is a mutex + // which must be locked while accessing tables_. + Mutex* mutex_; + + // See constructor. + DescriptorDatabase* fallback_database_; + ErrorCollector* default_error_collector_; + const DescriptorPool* underlay_; + + // This class contains a lot of hash maps with complicated types that + // we'd like to keep out of the header. + class Tables; + google::protobuf::scoped_ptr tables_; + + bool enforce_dependencies_; + bool allow_unknown_; + bool enforce_weak_; + std::set unused_import_track_files_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool); +}; + +// inline methods ==================================================== + +// These macros makes this repetitive code more readable. +#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \ + inline TYPE CLASS::FIELD() const { return FIELD##_; } + +// Strings fields are stored as pointers but returned as const references. +#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \ + inline const string& CLASS::FIELD() const { return *FIELD##_; } + +// Arrays take an index parameter, obviously. +#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \ + inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; } + +#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \ + inline const TYPE& CLASS::options() const { return *options_; } + +PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) + +PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, oneof_decl_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int) + +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, oneof_decl, const OneofDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*) + +PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range, + const Descriptor::ExtensionRange*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension, + const FieldDescriptor*) + +PROTOBUF_DEFINE_ACCESSOR(Descriptor, reserved_range_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, reserved_range, + const Descriptor::ReservedRange*) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, reserved_name_count, int) + +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, is_placeholder, bool) + +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, json_name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_oneof, + const OneofDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, index_in_oneof, int) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 ) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 ) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float ) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool , bool ) +PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum, + const EnumValueDescriptor*) +PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string) + +PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions) + +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value, + const EnumValueDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions) +PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, is_placeholder, bool) + +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int) +PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions) + +PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method, + const MethodDescriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions) + +PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, client_streaming, bool) +PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, server_streaming, bool) + +PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name) +PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, public_dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, weak_dependency_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions) +PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, is_placeholder, bool) + +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service, + const ServiceDescriptor*) +PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension, + const FieldDescriptor*) + +#undef PROTOBUF_DEFINE_ACCESSOR +#undef PROTOBUF_DEFINE_STRING_ACCESSOR +#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR + +// A few accessors differ from the macros... + +inline bool Descriptor::IsExtensionNumber(int number) const { + return FindExtensionRangeContainingNumber(number) != NULL; +} + +inline bool Descriptor::IsReservedNumber(int number) const { + return FindReservedRangeContainingNumber(number) != NULL; +} + +inline bool Descriptor::IsReservedName(const string& name) const { + for (int i = 0; i < reserved_name_count(); i++) { + if (name == reserved_name(i)) { + return true; + } + } + return false; +} + +// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because reserved_names_ is actually +// an array of pointers rather than the usual array of objects. +inline const string& Descriptor::reserved_name(int index) const { + return *reserved_names_[index]; +} + +inline bool FieldDescriptor::is_required() const { + return label() == LABEL_REQUIRED; +} + +inline bool FieldDescriptor::is_optional() const { + return label() == LABEL_OPTIONAL; +} + +inline bool FieldDescriptor::is_repeated() const { + return label() == LABEL_REPEATED; +} + +inline bool FieldDescriptor::is_packable() const { + return is_repeated() && IsTypePackable(type()); +} + +// To save space, index() is computed by looking at the descriptor's position +// in the parent's array of children. +inline int FieldDescriptor::index() const { + if (!is_extension_) { + return static_cast(this - containing_type_->fields_); + } else if (extension_scope_ != NULL) { + return static_cast(this - extension_scope_->extensions_); + } else { + return static_cast(this - file_->extensions_); + } +} + +inline int Descriptor::index() const { + if (containing_type_ == NULL) { + return static_cast(this - file_->message_types_); + } else { + return static_cast(this - containing_type_->nested_types_); + } +} + +inline int OneofDescriptor::index() const { + return static_cast(this - containing_type_->oneof_decls_); +} + +inline int EnumDescriptor::index() const { + if (containing_type_ == NULL) { + return static_cast(this - file_->enum_types_); + } else { + return static_cast(this - containing_type_->enum_types_); + } +} + +inline int EnumValueDescriptor::index() const { + return static_cast(this - type_->values_); +} + +inline int ServiceDescriptor::index() const { + return static_cast(this - file_->services_); +} + +inline int MethodDescriptor::index() const { + return static_cast(this - service_->methods_); +} + +inline const char* FieldDescriptor::type_name() const { + return kTypeToName[type_]; +} + +inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const { + return kTypeToCppTypeMap[type_]; +} + +inline const char* FieldDescriptor::cpp_type_name() const { + return kCppTypeToName[kTypeToCppTypeMap[type_]]; +} + +inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) { + return kTypeToCppTypeMap[type]; +} + +inline const char* FieldDescriptor::TypeName(Type type) { + return kTypeToName[type]; +} + +inline const char* FieldDescriptor::CppTypeName(CppType cpp_type) { + return kCppTypeToName[cpp_type]; +} + +inline bool FieldDescriptor::IsTypePackable(Type field_type) { + return (field_type != FieldDescriptor::TYPE_STRING && + field_type != FieldDescriptor::TYPE_GROUP && + field_type != FieldDescriptor::TYPE_MESSAGE && + field_type != FieldDescriptor::TYPE_BYTES); +} + +inline const FileDescriptor* FileDescriptor::dependency(int index) const { + return dependencies_[index]; +} + +inline const FileDescriptor* FileDescriptor::public_dependency( + int index) const { + return dependencies_[public_dependencies_[index]]; +} + +inline const FileDescriptor* FileDescriptor::weak_dependency( + int index) const { + return dependencies_[weak_dependencies_[index]]; +} + +inline FileDescriptor::Syntax FileDescriptor::syntax() const { + return syntax_; +} + +// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because fields_ is actually an array +// of pointers rather than the usual array of objects. +inline const FieldDescriptor* OneofDescriptor::field(int index) const { + return fields_[index]; +} + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_DESCRIPTOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/descriptor.pb.h b/thirdparty/linux/include/google/protobuf/descriptor.pb.h new file mode 100644 index 0000000..5a9e12b --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/descriptor.pb.h @@ -0,0 +1,8002 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/descriptor.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + +class DescriptorProto; +class DescriptorProto_ExtensionRange; +class DescriptorProto_ReservedRange; +class EnumDescriptorProto; +class EnumOptions; +class EnumValueDescriptorProto; +class EnumValueOptions; +class FieldDescriptorProto; +class FieldOptions; +class FileDescriptorProto; +class FileDescriptorSet; +class FileOptions; +class GeneratedCodeInfo; +class GeneratedCodeInfo_Annotation; +class MessageOptions; +class MethodDescriptorProto; +class MethodOptions; +class OneofDescriptorProto; +class OneofOptions; +class ServiceDescriptorProto; +class ServiceOptions; +class SourceCodeInfo; +class SourceCodeInfo_Location; +class UninterpretedOption; +class UninterpretedOption_NamePart; + +enum FieldDescriptorProto_Type { + FieldDescriptorProto_Type_TYPE_DOUBLE = 1, + FieldDescriptorProto_Type_TYPE_FLOAT = 2, + FieldDescriptorProto_Type_TYPE_INT64 = 3, + FieldDescriptorProto_Type_TYPE_UINT64 = 4, + FieldDescriptorProto_Type_TYPE_INT32 = 5, + FieldDescriptorProto_Type_TYPE_FIXED64 = 6, + FieldDescriptorProto_Type_TYPE_FIXED32 = 7, + FieldDescriptorProto_Type_TYPE_BOOL = 8, + FieldDescriptorProto_Type_TYPE_STRING = 9, + FieldDescriptorProto_Type_TYPE_GROUP = 10, + FieldDescriptorProto_Type_TYPE_MESSAGE = 11, + FieldDescriptorProto_Type_TYPE_BYTES = 12, + FieldDescriptorProto_Type_TYPE_UINT32 = 13, + FieldDescriptorProto_Type_TYPE_ENUM = 14, + FieldDescriptorProto_Type_TYPE_SFIXED32 = 15, + FieldDescriptorProto_Type_TYPE_SFIXED64 = 16, + FieldDescriptorProto_Type_TYPE_SINT32 = 17, + FieldDescriptorProto_Type_TYPE_SINT64 = 18 +}; +LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value); +const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE; +const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64; +const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor(); +inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) { + return ::google::protobuf::internal::NameOfEnum( + FieldDescriptorProto_Type_descriptor(), value); +} +inline bool FieldDescriptorProto_Type_Parse( + const ::std::string& name, FieldDescriptorProto_Type* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FieldDescriptorProto_Type_descriptor(), name, value); +} +enum FieldDescriptorProto_Label { + FieldDescriptorProto_Label_LABEL_OPTIONAL = 1, + FieldDescriptorProto_Label_LABEL_REQUIRED = 2, + FieldDescriptorProto_Label_LABEL_REPEATED = 3 +}; +LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value); +const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL; +const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED; +const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor(); +inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) { + return ::google::protobuf::internal::NameOfEnum( + FieldDescriptorProto_Label_descriptor(), value); +} +inline bool FieldDescriptorProto_Label_Parse( + const ::std::string& name, FieldDescriptorProto_Label* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FieldDescriptorProto_Label_descriptor(), name, value); +} +enum FileOptions_OptimizeMode { + FileOptions_OptimizeMode_SPEED = 1, + FileOptions_OptimizeMode_CODE_SIZE = 2, + FileOptions_OptimizeMode_LITE_RUNTIME = 3 +}; +LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value); +const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED; +const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME; +const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor(); +inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) { + return ::google::protobuf::internal::NameOfEnum( + FileOptions_OptimizeMode_descriptor(), value); +} +inline bool FileOptions_OptimizeMode_Parse( + const ::std::string& name, FileOptions_OptimizeMode* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FileOptions_OptimizeMode_descriptor(), name, value); +} +enum FieldOptions_CType { + FieldOptions_CType_STRING = 0, + FieldOptions_CType_CORD = 1, + FieldOptions_CType_STRING_PIECE = 2 +}; +LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value); +const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING; +const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE; +const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor(); +inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) { + return ::google::protobuf::internal::NameOfEnum( + FieldOptions_CType_descriptor(), value); +} +inline bool FieldOptions_CType_Parse( + const ::std::string& name, FieldOptions_CType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FieldOptions_CType_descriptor(), name, value); +} +enum FieldOptions_JSType { + FieldOptions_JSType_JS_NORMAL = 0, + FieldOptions_JSType_JS_STRING = 1, + FieldOptions_JSType_JS_NUMBER = 2 +}; +LIBPROTOBUF_EXPORT bool FieldOptions_JSType_IsValid(int value); +const FieldOptions_JSType FieldOptions_JSType_JSType_MIN = FieldOptions_JSType_JS_NORMAL; +const FieldOptions_JSType FieldOptions_JSType_JSType_MAX = FieldOptions_JSType_JS_NUMBER; +const int FieldOptions_JSType_JSType_ARRAYSIZE = FieldOptions_JSType_JSType_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor(); +inline const ::std::string& FieldOptions_JSType_Name(FieldOptions_JSType value) { + return ::google::protobuf::internal::NameOfEnum( + FieldOptions_JSType_descriptor(), value); +} +inline bool FieldOptions_JSType_Parse( + const ::std::string& name, FieldOptions_JSType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FieldOptions_JSType_descriptor(), name, value); +} +// =================================================================== + +class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ { + public: + FileDescriptorSet(); + virtual ~FileDescriptorSet(); + + FileDescriptorSet(const FileDescriptorSet& from); + + inline FileDescriptorSet& operator=(const FileDescriptorSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileDescriptorSet& default_instance(); + + void Swap(FileDescriptorSet* other); + + // implements Message ---------------------------------------------- + + inline FileDescriptorSet* New() const { return New(NULL); } + + FileDescriptorSet* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileDescriptorSet& from); + void MergeFrom(const FileDescriptorSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FileDescriptorSet* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.FileDescriptorProto file = 1; + int file_size() const; + void clear_file(); + static const int kFileFieldNumber = 1; + const ::google::protobuf::FileDescriptorProto& file(int index) const; + ::google::protobuf::FileDescriptorProto* mutable_file(int index); + ::google::protobuf::FileDescriptorProto* add_file(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* + mutable_file(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& + file() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FileDescriptorSet* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ { + public: + FileDescriptorProto(); + virtual ~FileDescriptorProto(); + + FileDescriptorProto(const FileDescriptorProto& from); + + inline FileDescriptorProto& operator=(const FileDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileDescriptorProto& default_instance(); + + void Swap(FileDescriptorProto* other); + + // implements Message ---------------------------------------------- + + inline FileDescriptorProto* New() const { return New(NULL); } + + FileDescriptorProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileDescriptorProto& from); + void MergeFrom(const FileDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FileDescriptorProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional string package = 2; + bool has_package() const; + void clear_package(); + static const int kPackageFieldNumber = 2; + const ::std::string& package() const; + void set_package(const ::std::string& value); + void set_package(const char* value); + void set_package(const char* value, size_t size); + ::std::string* mutable_package(); + ::std::string* release_package(); + void set_allocated_package(::std::string* package); + + // repeated string dependency = 3; + int dependency_size() const; + void clear_dependency(); + static const int kDependencyFieldNumber = 3; + const ::std::string& dependency(int index) const; + ::std::string* mutable_dependency(int index); + void set_dependency(int index, const ::std::string& value); + void set_dependency(int index, const char* value); + void set_dependency(int index, const char* value, size_t size); + ::std::string* add_dependency(); + void add_dependency(const ::std::string& value); + void add_dependency(const char* value); + void add_dependency(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency(); + + // repeated int32 public_dependency = 10; + int public_dependency_size() const; + void clear_public_dependency(); + static const int kPublicDependencyFieldNumber = 10; + ::google::protobuf::int32 public_dependency(int index) const; + void set_public_dependency(int index, ::google::protobuf::int32 value); + void add_public_dependency(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + public_dependency() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_public_dependency(); + + // repeated int32 weak_dependency = 11; + int weak_dependency_size() const; + void clear_weak_dependency(); + static const int kWeakDependencyFieldNumber = 11; + ::google::protobuf::int32 weak_dependency(int index) const; + void set_weak_dependency(int index, ::google::protobuf::int32 value); + void add_weak_dependency(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + weak_dependency() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_weak_dependency(); + + // repeated .google.protobuf.DescriptorProto message_type = 4; + int message_type_size() const; + void clear_message_type(); + static const int kMessageTypeFieldNumber = 4; + const ::google::protobuf::DescriptorProto& message_type(int index) const; + ::google::protobuf::DescriptorProto* mutable_message_type(int index); + ::google::protobuf::DescriptorProto* add_message_type(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* + mutable_message_type(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& + message_type() const; + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; + int enum_type_size() const; + void clear_enum_type(); + static const int kEnumTypeFieldNumber = 5; + const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; + ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); + ::google::protobuf::EnumDescriptorProto* add_enum_type(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* + mutable_enum_type(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& + enum_type() const; + + // repeated .google.protobuf.ServiceDescriptorProto service = 6; + int service_size() const; + void clear_service(); + static const int kServiceFieldNumber = 6; + const ::google::protobuf::ServiceDescriptorProto& service(int index) const; + ::google::protobuf::ServiceDescriptorProto* mutable_service(int index); + ::google::protobuf::ServiceDescriptorProto* add_service(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* + mutable_service(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& + service() const; + + // repeated .google.protobuf.FieldDescriptorProto extension = 7; + int extension_size() const; + void clear_extension(); + static const int kExtensionFieldNumber = 7; + const ::google::protobuf::FieldDescriptorProto& extension(int index) const; + ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); + ::google::protobuf::FieldDescriptorProto* add_extension(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_extension(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + extension() const; + + // optional .google.protobuf.FileOptions options = 8; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 8; + const ::google::protobuf::FileOptions& options() const; + ::google::protobuf::FileOptions* mutable_options(); + ::google::protobuf::FileOptions* release_options(); + void set_allocated_options(::google::protobuf::FileOptions* options); + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + bool has_source_code_info() const; + void clear_source_code_info(); + static const int kSourceCodeInfoFieldNumber = 9; + const ::google::protobuf::SourceCodeInfo& source_code_info() const; + ::google::protobuf::SourceCodeInfo* mutable_source_code_info(); + ::google::protobuf::SourceCodeInfo* release_source_code_info(); + void set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info); + + // optional string syntax = 12; + bool has_syntax() const; + void clear_syntax(); + static const int kSyntaxFieldNumber = 12; + const ::std::string& syntax() const; + void set_syntax(const ::std::string& value); + void set_syntax(const char* value); + void set_syntax(const char* value, size_t size); + ::std::string* mutable_syntax(); + ::std::string* release_syntax(); + void set_allocated_syntax(::std::string* syntax); + + // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_package(); + inline void clear_has_package(); + inline void set_has_options(); + inline void clear_has_options(); + inline void set_has_source_code_info(); + inline void clear_has_source_code_info(); + inline void set_has_syntax(); + inline void clear_has_syntax(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::internal::ArenaStringPtr package_; + ::google::protobuf::RepeatedPtrField< ::std::string> dependency_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; + ::google::protobuf::FileOptions* options_; + ::google::protobuf::SourceCodeInfo* source_code_info_; + ::google::protobuf::internal::ArenaStringPtr syntax_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FileDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ { + public: + DescriptorProto_ExtensionRange(); + virtual ~DescriptorProto_ExtensionRange(); + + DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from); + + inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DescriptorProto_ExtensionRange& default_instance(); + + void Swap(DescriptorProto_ExtensionRange* other); + + // implements Message ---------------------------------------------- + + inline DescriptorProto_ExtensionRange* New() const { return New(NULL); } + + DescriptorProto_ExtensionRange* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DescriptorProto_ExtensionRange& from); + void MergeFrom(const DescriptorProto_ExtensionRange& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(DescriptorProto_ExtensionRange* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 start = 1; + bool has_start() const; + void clear_start(); + static const int kStartFieldNumber = 1; + ::google::protobuf::int32 start() const; + void set_start(::google::protobuf::int32 value); + + // optional int32 end = 2; + bool has_end() const; + void clear_end(); + static const int kEndFieldNumber = 2; + ::google::protobuf::int32 end() const; + void set_end(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange) + private: + inline void set_has_start(); + inline void clear_has_start(); + inline void set_has_end(); + inline void clear_has_end(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 start_; + ::google::protobuf::int32 end_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static DescriptorProto_ExtensionRange* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ { + public: + DescriptorProto_ReservedRange(); + virtual ~DescriptorProto_ReservedRange(); + + DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from); + + inline DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DescriptorProto_ReservedRange& default_instance(); + + void Swap(DescriptorProto_ReservedRange* other); + + // implements Message ---------------------------------------------- + + inline DescriptorProto_ReservedRange* New() const { return New(NULL); } + + DescriptorProto_ReservedRange* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DescriptorProto_ReservedRange& from); + void MergeFrom(const DescriptorProto_ReservedRange& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(DescriptorProto_ReservedRange* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 start = 1; + bool has_start() const; + void clear_start(); + static const int kStartFieldNumber = 1; + ::google::protobuf::int32 start() const; + void set_start(::google::protobuf::int32 value); + + // optional int32 end = 2; + bool has_end() const; + void clear_end(); + static const int kEndFieldNumber = 2; + ::google::protobuf::int32 end() const; + void set_end(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ReservedRange) + private: + inline void set_has_start(); + inline void clear_has_start(); + inline void set_has_end(); + inline void clear_has_end(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 start_; + ::google::protobuf::int32 end_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static DescriptorProto_ReservedRange* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ { + public: + DescriptorProto(); + virtual ~DescriptorProto(); + + DescriptorProto(const DescriptorProto& from); + + inline DescriptorProto& operator=(const DescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DescriptorProto& default_instance(); + + void Swap(DescriptorProto* other); + + // implements Message ---------------------------------------------- + + inline DescriptorProto* New() const { return New(NULL); } + + DescriptorProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DescriptorProto& from); + void MergeFrom(const DescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(DescriptorProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef DescriptorProto_ExtensionRange ExtensionRange; + typedef DescriptorProto_ReservedRange ReservedRange; + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.FieldDescriptorProto field = 2; + int field_size() const; + void clear_field(); + static const int kFieldFieldNumber = 2; + const ::google::protobuf::FieldDescriptorProto& field(int index) const; + ::google::protobuf::FieldDescriptorProto* mutable_field(int index); + ::google::protobuf::FieldDescriptorProto* add_field(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_field(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + field() const; + + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + int extension_size() const; + void clear_extension(); + static const int kExtensionFieldNumber = 6; + const ::google::protobuf::FieldDescriptorProto& extension(int index) const; + ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); + ::google::protobuf::FieldDescriptorProto* add_extension(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_extension(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + extension() const; + + // repeated .google.protobuf.DescriptorProto nested_type = 3; + int nested_type_size() const; + void clear_nested_type(); + static const int kNestedTypeFieldNumber = 3; + const ::google::protobuf::DescriptorProto& nested_type(int index) const; + ::google::protobuf::DescriptorProto* mutable_nested_type(int index); + ::google::protobuf::DescriptorProto* add_nested_type(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* + mutable_nested_type(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& + nested_type() const; + + // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; + int enum_type_size() const; + void clear_enum_type(); + static const int kEnumTypeFieldNumber = 4; + const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; + ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); + ::google::protobuf::EnumDescriptorProto* add_enum_type(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* + mutable_enum_type(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& + enum_type() const; + + // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; + int extension_range_size() const; + void clear_extension_range(); + static const int kExtensionRangeFieldNumber = 5; + const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const; + ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index); + ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* + mutable_extension_range(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& + extension_range() const; + + // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; + int oneof_decl_size() const; + void clear_oneof_decl(); + static const int kOneofDeclFieldNumber = 8; + const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const; + ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index); + ::google::protobuf::OneofDescriptorProto* add_oneof_decl(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >* + mutable_oneof_decl(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >& + oneof_decl() const; + + // optional .google.protobuf.MessageOptions options = 7; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 7; + const ::google::protobuf::MessageOptions& options() const; + ::google::protobuf::MessageOptions* mutable_options(); + ::google::protobuf::MessageOptions* release_options(); + void set_allocated_options(::google::protobuf::MessageOptions* options); + + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + int reserved_range_size() const; + void clear_reserved_range(); + static const int kReservedRangeFieldNumber = 9; + const ::google::protobuf::DescriptorProto_ReservedRange& reserved_range(int index) const; + ::google::protobuf::DescriptorProto_ReservedRange* mutable_reserved_range(int index); + ::google::protobuf::DescriptorProto_ReservedRange* add_reserved_range(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >* + mutable_reserved_range(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >& + reserved_range() const; + + // repeated string reserved_name = 10; + int reserved_name_size() const; + void clear_reserved_name(); + static const int kReservedNameFieldNumber = 10; + const ::std::string& reserved_name(int index) const; + ::std::string* mutable_reserved_name(int index); + void set_reserved_name(int index, const ::std::string& value); + void set_reserved_name(int index, const char* value); + void set_reserved_name(int index, const char* value, size_t size); + ::std::string* add_reserved_name(); + void add_reserved_name(const ::std::string& value); + void add_reserved_name(const char* value); + void add_reserved_name(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& reserved_name() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_reserved_name(); + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_; + ::google::protobuf::MessageOptions* options_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange > reserved_range_; + ::google::protobuf::RepeatedPtrField< ::std::string> reserved_name_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static DescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ { + public: + FieldDescriptorProto(); + virtual ~FieldDescriptorProto(); + + FieldDescriptorProto(const FieldDescriptorProto& from); + + inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FieldDescriptorProto& default_instance(); + + void Swap(FieldDescriptorProto* other); + + // implements Message ---------------------------------------------- + + inline FieldDescriptorProto* New() const { return New(NULL); } + + FieldDescriptorProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FieldDescriptorProto& from); + void MergeFrom(const FieldDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FieldDescriptorProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef FieldDescriptorProto_Type Type; + static const Type TYPE_DOUBLE = + FieldDescriptorProto_Type_TYPE_DOUBLE; + static const Type TYPE_FLOAT = + FieldDescriptorProto_Type_TYPE_FLOAT; + static const Type TYPE_INT64 = + FieldDescriptorProto_Type_TYPE_INT64; + static const Type TYPE_UINT64 = + FieldDescriptorProto_Type_TYPE_UINT64; + static const Type TYPE_INT32 = + FieldDescriptorProto_Type_TYPE_INT32; + static const Type TYPE_FIXED64 = + FieldDescriptorProto_Type_TYPE_FIXED64; + static const Type TYPE_FIXED32 = + FieldDescriptorProto_Type_TYPE_FIXED32; + static const Type TYPE_BOOL = + FieldDescriptorProto_Type_TYPE_BOOL; + static const Type TYPE_STRING = + FieldDescriptorProto_Type_TYPE_STRING; + static const Type TYPE_GROUP = + FieldDescriptorProto_Type_TYPE_GROUP; + static const Type TYPE_MESSAGE = + FieldDescriptorProto_Type_TYPE_MESSAGE; + static const Type TYPE_BYTES = + FieldDescriptorProto_Type_TYPE_BYTES; + static const Type TYPE_UINT32 = + FieldDescriptorProto_Type_TYPE_UINT32; + static const Type TYPE_ENUM = + FieldDescriptorProto_Type_TYPE_ENUM; + static const Type TYPE_SFIXED32 = + FieldDescriptorProto_Type_TYPE_SFIXED32; + static const Type TYPE_SFIXED64 = + FieldDescriptorProto_Type_TYPE_SFIXED64; + static const Type TYPE_SINT32 = + FieldDescriptorProto_Type_TYPE_SINT32; + static const Type TYPE_SINT64 = + FieldDescriptorProto_Type_TYPE_SINT64; + static inline bool Type_IsValid(int value) { + return FieldDescriptorProto_Type_IsValid(value); + } + static const Type Type_MIN = + FieldDescriptorProto_Type_Type_MIN; + static const Type Type_MAX = + FieldDescriptorProto_Type_Type_MAX; + static const int Type_ARRAYSIZE = + FieldDescriptorProto_Type_Type_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Type_descriptor() { + return FieldDescriptorProto_Type_descriptor(); + } + static inline const ::std::string& Type_Name(Type value) { + return FieldDescriptorProto_Type_Name(value); + } + static inline bool Type_Parse(const ::std::string& name, + Type* value) { + return FieldDescriptorProto_Type_Parse(name, value); + } + + typedef FieldDescriptorProto_Label Label; + static const Label LABEL_OPTIONAL = + FieldDescriptorProto_Label_LABEL_OPTIONAL; + static const Label LABEL_REQUIRED = + FieldDescriptorProto_Label_LABEL_REQUIRED; + static const Label LABEL_REPEATED = + FieldDescriptorProto_Label_LABEL_REPEATED; + static inline bool Label_IsValid(int value) { + return FieldDescriptorProto_Label_IsValid(value); + } + static const Label Label_MIN = + FieldDescriptorProto_Label_Label_MIN; + static const Label Label_MAX = + FieldDescriptorProto_Label_Label_MAX; + static const int Label_ARRAYSIZE = + FieldDescriptorProto_Label_Label_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Label_descriptor() { + return FieldDescriptorProto_Label_descriptor(); + } + static inline const ::std::string& Label_Name(Label value) { + return FieldDescriptorProto_Label_Name(value); + } + static inline bool Label_Parse(const ::std::string& name, + Label* value) { + return FieldDescriptorProto_Label_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional int32 number = 3; + bool has_number() const; + void clear_number(); + static const int kNumberFieldNumber = 3; + ::google::protobuf::int32 number() const; + void set_number(::google::protobuf::int32 value); + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + bool has_label() const; + void clear_label(); + static const int kLabelFieldNumber = 4; + ::google::protobuf::FieldDescriptorProto_Label label() const; + void set_label(::google::protobuf::FieldDescriptorProto_Label value); + + // optional .google.protobuf.FieldDescriptorProto.Type type = 5; + bool has_type() const; + void clear_type(); + static const int kTypeFieldNumber = 5; + ::google::protobuf::FieldDescriptorProto_Type type() const; + void set_type(::google::protobuf::FieldDescriptorProto_Type value); + + // optional string type_name = 6; + bool has_type_name() const; + void clear_type_name(); + static const int kTypeNameFieldNumber = 6; + const ::std::string& type_name() const; + void set_type_name(const ::std::string& value); + void set_type_name(const char* value); + void set_type_name(const char* value, size_t size); + ::std::string* mutable_type_name(); + ::std::string* release_type_name(); + void set_allocated_type_name(::std::string* type_name); + + // optional string extendee = 2; + bool has_extendee() const; + void clear_extendee(); + static const int kExtendeeFieldNumber = 2; + const ::std::string& extendee() const; + void set_extendee(const ::std::string& value); + void set_extendee(const char* value); + void set_extendee(const char* value, size_t size); + ::std::string* mutable_extendee(); + ::std::string* release_extendee(); + void set_allocated_extendee(::std::string* extendee); + + // optional string default_value = 7; + bool has_default_value() const; + void clear_default_value(); + static const int kDefaultValueFieldNumber = 7; + const ::std::string& default_value() const; + void set_default_value(const ::std::string& value); + void set_default_value(const char* value); + void set_default_value(const char* value, size_t size); + ::std::string* mutable_default_value(); + ::std::string* release_default_value(); + void set_allocated_default_value(::std::string* default_value); + + // optional int32 oneof_index = 9; + bool has_oneof_index() const; + void clear_oneof_index(); + static const int kOneofIndexFieldNumber = 9; + ::google::protobuf::int32 oneof_index() const; + void set_oneof_index(::google::protobuf::int32 value); + + // optional string json_name = 10; + bool has_json_name() const; + void clear_json_name(); + static const int kJsonNameFieldNumber = 10; + const ::std::string& json_name() const; + void set_json_name(const ::std::string& value); + void set_json_name(const char* value); + void set_json_name(const char* value, size_t size); + ::std::string* mutable_json_name(); + ::std::string* release_json_name(); + void set_allocated_json_name(::std::string* json_name); + + // optional .google.protobuf.FieldOptions options = 8; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 8; + const ::google::protobuf::FieldOptions& options() const; + ::google::protobuf::FieldOptions* mutable_options(); + ::google::protobuf::FieldOptions* release_options(); + void set_allocated_options(::google::protobuf::FieldOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_number(); + inline void clear_has_number(); + inline void set_has_label(); + inline void clear_has_label(); + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_type_name(); + inline void clear_has_type_name(); + inline void set_has_extendee(); + inline void clear_has_extendee(); + inline void set_has_default_value(); + inline void clear_has_default_value(); + inline void set_has_oneof_index(); + inline void clear_has_oneof_index(); + inline void set_has_json_name(); + inline void clear_has_json_name(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::int32 number_; + int label_; + ::google::protobuf::internal::ArenaStringPtr type_name_; + ::google::protobuf::internal::ArenaStringPtr extendee_; + int type_; + ::google::protobuf::int32 oneof_index_; + ::google::protobuf::internal::ArenaStringPtr default_value_; + ::google::protobuf::internal::ArenaStringPtr json_name_; + ::google::protobuf::FieldOptions* options_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FieldDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ { + public: + OneofDescriptorProto(); + virtual ~OneofDescriptorProto(); + + OneofDescriptorProto(const OneofDescriptorProto& from); + + inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const OneofDescriptorProto& default_instance(); + + void Swap(OneofDescriptorProto* other); + + // implements Message ---------------------------------------------- + + inline OneofDescriptorProto* New() const { return New(NULL); } + + OneofDescriptorProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const OneofDescriptorProto& from); + void MergeFrom(const OneofDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(OneofDescriptorProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional .google.protobuf.OneofOptions options = 2; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 2; + const ::google::protobuf::OneofOptions& options() const; + ::google::protobuf::OneofOptions* mutable_options(); + ::google::protobuf::OneofOptions* release_options(); + void set_allocated_options(::google::protobuf::OneofOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::OneofOptions* options_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static OneofDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ { + public: + EnumDescriptorProto(); + virtual ~EnumDescriptorProto(); + + EnumDescriptorProto(const EnumDescriptorProto& from); + + inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumDescriptorProto& default_instance(); + + void Swap(EnumDescriptorProto* other); + + // implements Message ---------------------------------------------- + + inline EnumDescriptorProto* New() const { return New(NULL); } + + EnumDescriptorProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumDescriptorProto& from); + void MergeFrom(const EnumDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(EnumDescriptorProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.EnumValueDescriptorProto value = 2; + int value_size() const; + void clear_value(); + static const int kValueFieldNumber = 2; + const ::google::protobuf::EnumValueDescriptorProto& value(int index) const; + ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index); + ::google::protobuf::EnumValueDescriptorProto* add_value(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* + mutable_value(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& + value() const; + + // optional .google.protobuf.EnumOptions options = 3; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::EnumOptions& options() const; + ::google::protobuf::EnumOptions* mutable_options(); + ::google::protobuf::EnumOptions* release_options(); + void set_allocated_options(::google::protobuf::EnumOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_; + ::google::protobuf::EnumOptions* options_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static EnumDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ { + public: + EnumValueDescriptorProto(); + virtual ~EnumValueDescriptorProto(); + + EnumValueDescriptorProto(const EnumValueDescriptorProto& from); + + inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumValueDescriptorProto& default_instance(); + + void Swap(EnumValueDescriptorProto* other); + + // implements Message ---------------------------------------------- + + inline EnumValueDescriptorProto* New() const { return New(NULL); } + + EnumValueDescriptorProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumValueDescriptorProto& from); + void MergeFrom(const EnumValueDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(EnumValueDescriptorProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional int32 number = 2; + bool has_number() const; + void clear_number(); + static const int kNumberFieldNumber = 2; + ::google::protobuf::int32 number() const; + void set_number(::google::protobuf::int32 value); + + // optional .google.protobuf.EnumValueOptions options = 3; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::EnumValueOptions& options() const; + ::google::protobuf::EnumValueOptions* mutable_options(); + ::google::protobuf::EnumValueOptions* release_options(); + void set_allocated_options(::google::protobuf::EnumValueOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_number(); + inline void clear_has_number(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::EnumValueOptions* options_; + ::google::protobuf::int32 number_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static EnumValueDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ { + public: + ServiceDescriptorProto(); + virtual ~ServiceDescriptorProto(); + + ServiceDescriptorProto(const ServiceDescriptorProto& from); + + inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServiceDescriptorProto& default_instance(); + + void Swap(ServiceDescriptorProto* other); + + // implements Message ---------------------------------------------- + + inline ServiceDescriptorProto* New() const { return New(NULL); } + + ServiceDescriptorProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServiceDescriptorProto& from); + void MergeFrom(const ServiceDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(ServiceDescriptorProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.MethodDescriptorProto method = 2; + int method_size() const; + void clear_method(); + static const int kMethodFieldNumber = 2; + const ::google::protobuf::MethodDescriptorProto& method(int index) const; + ::google::protobuf::MethodDescriptorProto* mutable_method(int index); + ::google::protobuf::MethodDescriptorProto* add_method(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* + mutable_method(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& + method() const; + + // optional .google.protobuf.ServiceOptions options = 3; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::ServiceOptions& options() const; + ::google::protobuf::ServiceOptions* mutable_options(); + ::google::protobuf::ServiceOptions* release_options(); + void set_allocated_options(::google::protobuf::ServiceOptions* options); + + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_; + ::google::protobuf::ServiceOptions* options_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static ServiceDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ { + public: + MethodDescriptorProto(); + virtual ~MethodDescriptorProto(); + + MethodDescriptorProto(const MethodDescriptorProto& from); + + inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MethodDescriptorProto& default_instance(); + + void Swap(MethodDescriptorProto* other); + + // implements Message ---------------------------------------------- + + inline MethodDescriptorProto* New() const { return New(NULL); } + + MethodDescriptorProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MethodDescriptorProto& from); + void MergeFrom(const MethodDescriptorProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MethodDescriptorProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional string input_type = 2; + bool has_input_type() const; + void clear_input_type(); + static const int kInputTypeFieldNumber = 2; + const ::std::string& input_type() const; + void set_input_type(const ::std::string& value); + void set_input_type(const char* value); + void set_input_type(const char* value, size_t size); + ::std::string* mutable_input_type(); + ::std::string* release_input_type(); + void set_allocated_input_type(::std::string* input_type); + + // optional string output_type = 3; + bool has_output_type() const; + void clear_output_type(); + static const int kOutputTypeFieldNumber = 3; + const ::std::string& output_type() const; + void set_output_type(const ::std::string& value); + void set_output_type(const char* value); + void set_output_type(const char* value, size_t size); + ::std::string* mutable_output_type(); + ::std::string* release_output_type(); + void set_allocated_output_type(::std::string* output_type); + + // optional .google.protobuf.MethodOptions options = 4; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 4; + const ::google::protobuf::MethodOptions& options() const; + ::google::protobuf::MethodOptions* mutable_options(); + ::google::protobuf::MethodOptions* release_options(); + void set_allocated_options(::google::protobuf::MethodOptions* options); + + // optional bool client_streaming = 5 [default = false]; + bool has_client_streaming() const; + void clear_client_streaming(); + static const int kClientStreamingFieldNumber = 5; + bool client_streaming() const; + void set_client_streaming(bool value); + + // optional bool server_streaming = 6 [default = false]; + bool has_server_streaming() const; + void clear_server_streaming(); + static const int kServerStreamingFieldNumber = 6; + bool server_streaming() const; + void set_server_streaming(bool value); + + // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_input_type(); + inline void clear_has_input_type(); + inline void set_has_output_type(); + inline void clear_has_output_type(); + inline void set_has_options(); + inline void clear_has_options(); + inline void set_has_client_streaming(); + inline void clear_has_client_streaming(); + inline void set_has_server_streaming(); + inline void clear_has_server_streaming(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::internal::ArenaStringPtr input_type_; + ::google::protobuf::internal::ArenaStringPtr output_type_; + ::google::protobuf::MethodOptions* options_; + bool client_streaming_; + bool server_streaming_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static MethodDescriptorProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ { + public: + FileOptions(); + virtual ~FileOptions(); + + FileOptions(const FileOptions& from); + + inline FileOptions& operator=(const FileOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileOptions& default_instance(); + + void Swap(FileOptions* other); + + // implements Message ---------------------------------------------- + + inline FileOptions* New() const { return New(NULL); } + + FileOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileOptions& from); + void MergeFrom(const FileOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FileOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef FileOptions_OptimizeMode OptimizeMode; + static const OptimizeMode SPEED = + FileOptions_OptimizeMode_SPEED; + static const OptimizeMode CODE_SIZE = + FileOptions_OptimizeMode_CODE_SIZE; + static const OptimizeMode LITE_RUNTIME = + FileOptions_OptimizeMode_LITE_RUNTIME; + static inline bool OptimizeMode_IsValid(int value) { + return FileOptions_OptimizeMode_IsValid(value); + } + static const OptimizeMode OptimizeMode_MIN = + FileOptions_OptimizeMode_OptimizeMode_MIN; + static const OptimizeMode OptimizeMode_MAX = + FileOptions_OptimizeMode_OptimizeMode_MAX; + static const int OptimizeMode_ARRAYSIZE = + FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + OptimizeMode_descriptor() { + return FileOptions_OptimizeMode_descriptor(); + } + static inline const ::std::string& OptimizeMode_Name(OptimizeMode value) { + return FileOptions_OptimizeMode_Name(value); + } + static inline bool OptimizeMode_Parse(const ::std::string& name, + OptimizeMode* value) { + return FileOptions_OptimizeMode_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional string java_package = 1; + bool has_java_package() const; + void clear_java_package(); + static const int kJavaPackageFieldNumber = 1; + const ::std::string& java_package() const; + void set_java_package(const ::std::string& value); + void set_java_package(const char* value); + void set_java_package(const char* value, size_t size); + ::std::string* mutable_java_package(); + ::std::string* release_java_package(); + void set_allocated_java_package(::std::string* java_package); + + // optional string java_outer_classname = 8; + bool has_java_outer_classname() const; + void clear_java_outer_classname(); + static const int kJavaOuterClassnameFieldNumber = 8; + const ::std::string& java_outer_classname() const; + void set_java_outer_classname(const ::std::string& value); + void set_java_outer_classname(const char* value); + void set_java_outer_classname(const char* value, size_t size); + ::std::string* mutable_java_outer_classname(); + ::std::string* release_java_outer_classname(); + void set_allocated_java_outer_classname(::std::string* java_outer_classname); + + // optional bool java_multiple_files = 10 [default = false]; + bool has_java_multiple_files() const; + void clear_java_multiple_files(); + static const int kJavaMultipleFilesFieldNumber = 10; + bool java_multiple_files() const; + void set_java_multiple_files(bool value); + + // optional bool java_generate_equals_and_hash = 20 [default = false]; + bool has_java_generate_equals_and_hash() const; + void clear_java_generate_equals_and_hash(); + static const int kJavaGenerateEqualsAndHashFieldNumber = 20; + bool java_generate_equals_and_hash() const; + void set_java_generate_equals_and_hash(bool value); + + // optional bool java_string_check_utf8 = 27 [default = false]; + bool has_java_string_check_utf8() const; + void clear_java_string_check_utf8(); + static const int kJavaStringCheckUtf8FieldNumber = 27; + bool java_string_check_utf8() const; + void set_java_string_check_utf8(bool value); + + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + bool has_optimize_for() const; + void clear_optimize_for(); + static const int kOptimizeForFieldNumber = 9; + ::google::protobuf::FileOptions_OptimizeMode optimize_for() const; + void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value); + + // optional string go_package = 11; + bool has_go_package() const; + void clear_go_package(); + static const int kGoPackageFieldNumber = 11; + const ::std::string& go_package() const; + void set_go_package(const ::std::string& value); + void set_go_package(const char* value); + void set_go_package(const char* value, size_t size); + ::std::string* mutable_go_package(); + ::std::string* release_go_package(); + void set_allocated_go_package(::std::string* go_package); + + // optional bool cc_generic_services = 16 [default = false]; + bool has_cc_generic_services() const; + void clear_cc_generic_services(); + static const int kCcGenericServicesFieldNumber = 16; + bool cc_generic_services() const; + void set_cc_generic_services(bool value); + + // optional bool java_generic_services = 17 [default = false]; + bool has_java_generic_services() const; + void clear_java_generic_services(); + static const int kJavaGenericServicesFieldNumber = 17; + bool java_generic_services() const; + void set_java_generic_services(bool value); + + // optional bool py_generic_services = 18 [default = false]; + bool has_py_generic_services() const; + void clear_py_generic_services(); + static const int kPyGenericServicesFieldNumber = 18; + bool py_generic_services() const; + void set_py_generic_services(bool value); + + // optional bool deprecated = 23 [default = false]; + bool has_deprecated() const; + void clear_deprecated(); + static const int kDeprecatedFieldNumber = 23; + bool deprecated() const; + void set_deprecated(bool value); + + // optional bool cc_enable_arenas = 31 [default = false]; + bool has_cc_enable_arenas() const; + void clear_cc_enable_arenas(); + static const int kCcEnableArenasFieldNumber = 31; + bool cc_enable_arenas() const; + void set_cc_enable_arenas(bool value); + + // optional string objc_class_prefix = 36; + bool has_objc_class_prefix() const; + void clear_objc_class_prefix(); + static const int kObjcClassPrefixFieldNumber = 36; + const ::std::string& objc_class_prefix() const; + void set_objc_class_prefix(const ::std::string& value); + void set_objc_class_prefix(const char* value); + void set_objc_class_prefix(const char* value, size_t size); + ::std::string* mutable_objc_class_prefix(); + ::std::string* release_objc_class_prefix(); + void set_allocated_objc_class_prefix(::std::string* objc_class_prefix); + + // optional string csharp_namespace = 37; + bool has_csharp_namespace() const; + void clear_csharp_namespace(); + static const int kCsharpNamespaceFieldNumber = 37; + const ::std::string& csharp_namespace() const; + void set_csharp_namespace(const ::std::string& value); + void set_csharp_namespace(const char* value); + void set_csharp_namespace(const char* value, size_t size); + ::std::string* mutable_csharp_namespace(); + ::std::string* release_csharp_namespace(); + void set_allocated_csharp_namespace(::std::string* csharp_namespace); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) + private: + inline void set_has_java_package(); + inline void clear_has_java_package(); + inline void set_has_java_outer_classname(); + inline void clear_has_java_outer_classname(); + inline void set_has_java_multiple_files(); + inline void clear_has_java_multiple_files(); + inline void set_has_java_generate_equals_and_hash(); + inline void clear_has_java_generate_equals_and_hash(); + inline void set_has_java_string_check_utf8(); + inline void clear_has_java_string_check_utf8(); + inline void set_has_optimize_for(); + inline void clear_has_optimize_for(); + inline void set_has_go_package(); + inline void clear_has_go_package(); + inline void set_has_cc_generic_services(); + inline void clear_has_cc_generic_services(); + inline void set_has_java_generic_services(); + inline void clear_has_java_generic_services(); + inline void set_has_py_generic_services(); + inline void clear_has_py_generic_services(); + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + inline void set_has_cc_enable_arenas(); + inline void clear_has_cc_enable_arenas(); + inline void set_has_objc_class_prefix(); + inline void clear_has_objc_class_prefix(); + inline void set_has_csharp_namespace(); + inline void clear_has_csharp_namespace(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr java_package_; + ::google::protobuf::internal::ArenaStringPtr java_outer_classname_; + bool java_multiple_files_; + bool java_generate_equals_and_hash_; + bool java_string_check_utf8_; + bool cc_generic_services_; + int optimize_for_; + ::google::protobuf::internal::ArenaStringPtr go_package_; + ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_; + ::google::protobuf::internal::ArenaStringPtr csharp_namespace_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool java_generic_services_; + bool py_generic_services_; + bool deprecated_; + bool cc_enable_arenas_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FileOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ { + public: + MessageOptions(); + virtual ~MessageOptions(); + + MessageOptions(const MessageOptions& from); + + inline MessageOptions& operator=(const MessageOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MessageOptions& default_instance(); + + void Swap(MessageOptions* other); + + // implements Message ---------------------------------------------- + + inline MessageOptions* New() const { return New(NULL); } + + MessageOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MessageOptions& from); + void MergeFrom(const MessageOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MessageOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool message_set_wire_format = 1 [default = false]; + bool has_message_set_wire_format() const; + void clear_message_set_wire_format(); + static const int kMessageSetWireFormatFieldNumber = 1; + bool message_set_wire_format() const; + void set_message_set_wire_format(bool value); + + // optional bool no_standard_descriptor_accessor = 2 [default = false]; + bool has_no_standard_descriptor_accessor() const; + void clear_no_standard_descriptor_accessor(); + static const int kNoStandardDescriptorAccessorFieldNumber = 2; + bool no_standard_descriptor_accessor() const; + void set_no_standard_descriptor_accessor(bool value); + + // optional bool deprecated = 3 [default = false]; + bool has_deprecated() const; + void clear_deprecated(); + static const int kDeprecatedFieldNumber = 3; + bool deprecated() const; + void set_deprecated(bool value); + + // optional bool map_entry = 7; + bool has_map_entry() const; + void clear_map_entry(); + static const int kMapEntryFieldNumber = 7; + bool map_entry() const; + void set_map_entry(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) + private: + inline void set_has_message_set_wire_format(); + inline void clear_has_message_set_wire_format(); + inline void set_has_no_standard_descriptor_accessor(); + inline void clear_has_no_standard_descriptor_accessor(); + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + inline void set_has_map_entry(); + inline void clear_has_map_entry(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool message_set_wire_format_; + bool no_standard_descriptor_accessor_; + bool deprecated_; + bool map_entry_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static MessageOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ { + public: + FieldOptions(); + virtual ~FieldOptions(); + + FieldOptions(const FieldOptions& from); + + inline FieldOptions& operator=(const FieldOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FieldOptions& default_instance(); + + void Swap(FieldOptions* other); + + // implements Message ---------------------------------------------- + + inline FieldOptions* New() const { return New(NULL); } + + FieldOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FieldOptions& from); + void MergeFrom(const FieldOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FieldOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef FieldOptions_CType CType; + static const CType STRING = + FieldOptions_CType_STRING; + static const CType CORD = + FieldOptions_CType_CORD; + static const CType STRING_PIECE = + FieldOptions_CType_STRING_PIECE; + static inline bool CType_IsValid(int value) { + return FieldOptions_CType_IsValid(value); + } + static const CType CType_MIN = + FieldOptions_CType_CType_MIN; + static const CType CType_MAX = + FieldOptions_CType_CType_MAX; + static const int CType_ARRAYSIZE = + FieldOptions_CType_CType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + CType_descriptor() { + return FieldOptions_CType_descriptor(); + } + static inline const ::std::string& CType_Name(CType value) { + return FieldOptions_CType_Name(value); + } + static inline bool CType_Parse(const ::std::string& name, + CType* value) { + return FieldOptions_CType_Parse(name, value); + } + + typedef FieldOptions_JSType JSType; + static const JSType JS_NORMAL = + FieldOptions_JSType_JS_NORMAL; + static const JSType JS_STRING = + FieldOptions_JSType_JS_STRING; + static const JSType JS_NUMBER = + FieldOptions_JSType_JS_NUMBER; + static inline bool JSType_IsValid(int value) { + return FieldOptions_JSType_IsValid(value); + } + static const JSType JSType_MIN = + FieldOptions_JSType_JSType_MIN; + static const JSType JSType_MAX = + FieldOptions_JSType_JSType_MAX; + static const int JSType_ARRAYSIZE = + FieldOptions_JSType_JSType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + JSType_descriptor() { + return FieldOptions_JSType_descriptor(); + } + static inline const ::std::string& JSType_Name(JSType value) { + return FieldOptions_JSType_Name(value); + } + static inline bool JSType_Parse(const ::std::string& name, + JSType* value) { + return FieldOptions_JSType_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; + bool has_ctype() const; + void clear_ctype(); + static const int kCtypeFieldNumber = 1; + ::google::protobuf::FieldOptions_CType ctype() const; + void set_ctype(::google::protobuf::FieldOptions_CType value); + + // optional bool packed = 2; + bool has_packed() const; + void clear_packed(); + static const int kPackedFieldNumber = 2; + bool packed() const; + void set_packed(bool value); + + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + bool has_jstype() const; + void clear_jstype(); + static const int kJstypeFieldNumber = 6; + ::google::protobuf::FieldOptions_JSType jstype() const; + void set_jstype(::google::protobuf::FieldOptions_JSType value); + + // optional bool lazy = 5 [default = false]; + bool has_lazy() const; + void clear_lazy(); + static const int kLazyFieldNumber = 5; + bool lazy() const; + void set_lazy(bool value); + + // optional bool deprecated = 3 [default = false]; + bool has_deprecated() const; + void clear_deprecated(); + static const int kDeprecatedFieldNumber = 3; + bool deprecated() const; + void set_deprecated(bool value); + + // optional bool weak = 10 [default = false]; + bool has_weak() const; + void clear_weak(); + static const int kWeakFieldNumber = 10; + bool weak() const; + void set_weak(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) + private: + inline void set_has_ctype(); + inline void clear_has_ctype(); + inline void set_has_packed(); + inline void clear_has_packed(); + inline void set_has_jstype(); + inline void clear_has_jstype(); + inline void set_has_lazy(); + inline void clear_has_lazy(); + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + inline void set_has_weak(); + inline void clear_has_weak(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + int ctype_; + int jstype_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool packed_; + bool lazy_; + bool deprecated_; + bool weak_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static FieldOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT OneofOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ { + public: + OneofOptions(); + virtual ~OneofOptions(); + + OneofOptions(const OneofOptions& from); + + inline OneofOptions& operator=(const OneofOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const OneofOptions& default_instance(); + + void Swap(OneofOptions* other); + + // implements Message ---------------------------------------------- + + inline OneofOptions* New() const { return New(NULL); } + + OneofOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const OneofOptions& from); + void MergeFrom(const OneofOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(OneofOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(OneofOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions) + private: + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static OneofOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ { + public: + EnumOptions(); + virtual ~EnumOptions(); + + EnumOptions(const EnumOptions& from); + + inline EnumOptions& operator=(const EnumOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumOptions& default_instance(); + + void Swap(EnumOptions* other); + + // implements Message ---------------------------------------------- + + inline EnumOptions* New() const { return New(NULL); } + + EnumOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumOptions& from); + void MergeFrom(const EnumOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(EnumOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool allow_alias = 2; + bool has_allow_alias() const; + void clear_allow_alias(); + static const int kAllowAliasFieldNumber = 2; + bool allow_alias() const; + void set_allow_alias(bool value); + + // optional bool deprecated = 3 [default = false]; + bool has_deprecated() const; + void clear_deprecated(); + static const int kDeprecatedFieldNumber = 3; + bool deprecated() const; + void set_deprecated(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) + private: + inline void set_has_allow_alias(); + inline void clear_has_allow_alias(); + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool allow_alias_; + bool deprecated_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static EnumOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ { + public: + EnumValueOptions(); + virtual ~EnumValueOptions(); + + EnumValueOptions(const EnumValueOptions& from); + + inline EnumValueOptions& operator=(const EnumValueOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumValueOptions& default_instance(); + + void Swap(EnumValueOptions* other); + + // implements Message ---------------------------------------------- + + inline EnumValueOptions* New() const { return New(NULL); } + + EnumValueOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumValueOptions& from); + void MergeFrom(const EnumValueOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(EnumValueOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool deprecated = 1 [default = false]; + bool has_deprecated() const; + void clear_deprecated(); + static const int kDeprecatedFieldNumber = 1; + bool deprecated() const; + void set_deprecated(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) + private: + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool deprecated_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static EnumValueOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ { + public: + ServiceOptions(); + virtual ~ServiceOptions(); + + ServiceOptions(const ServiceOptions& from); + + inline ServiceOptions& operator=(const ServiceOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ServiceOptions& default_instance(); + + void Swap(ServiceOptions* other); + + // implements Message ---------------------------------------------- + + inline ServiceOptions* New() const { return New(NULL); } + + ServiceOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ServiceOptions& from); + void MergeFrom(const ServiceOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(ServiceOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool deprecated = 33 [default = false]; + bool has_deprecated() const; + void clear_deprecated(); + static const int kDeprecatedFieldNumber = 33; + bool deprecated() const; + void set_deprecated(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) + private: + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool deprecated_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static ServiceOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ { + public: + MethodOptions(); + virtual ~MethodOptions(); + + MethodOptions(const MethodOptions& from); + + inline MethodOptions& operator=(const MethodOptions& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MethodOptions& default_instance(); + + void Swap(MethodOptions* other); + + // implements Message ---------------------------------------------- + + inline MethodOptions* New() const { return New(NULL); } + + MethodOptions* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MethodOptions& from); + void MergeFrom(const MethodOptions& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MethodOptions* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool deprecated = 33 [default = false]; + bool has_deprecated() const; + void clear_deprecated(); + static const int kDeprecatedFieldNumber = 33; + bool deprecated() const; + void set_deprecated(bool value); + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) + private: + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + bool deprecated_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static MethodOptions* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ { + public: + UninterpretedOption_NamePart(); + virtual ~UninterpretedOption_NamePart(); + + UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from); + + inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UninterpretedOption_NamePart& default_instance(); + + void Swap(UninterpretedOption_NamePart* other); + + // implements Message ---------------------------------------------- + + inline UninterpretedOption_NamePart* New() const { return New(NULL); } + + UninterpretedOption_NamePart* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UninterpretedOption_NamePart& from); + void MergeFrom(const UninterpretedOption_NamePart& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(UninterpretedOption_NamePart* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string name_part = 1; + bool has_name_part() const; + void clear_name_part(); + static const int kNamePartFieldNumber = 1; + const ::std::string& name_part() const; + void set_name_part(const ::std::string& value); + void set_name_part(const char* value); + void set_name_part(const char* value, size_t size); + ::std::string* mutable_name_part(); + ::std::string* release_name_part(); + void set_allocated_name_part(::std::string* name_part); + + // required bool is_extension = 2; + bool has_is_extension() const; + void clear_is_extension(); + static const int kIsExtensionFieldNumber = 2; + bool is_extension() const; + void set_is_extension(bool value); + + // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart) + private: + inline void set_has_name_part(); + inline void clear_has_name_part(); + inline void set_has_is_extension(); + inline void clear_has_is_extension(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_part_; + bool is_extension_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static UninterpretedOption_NamePart* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ { + public: + UninterpretedOption(); + virtual ~UninterpretedOption(); + + UninterpretedOption(const UninterpretedOption& from); + + inline UninterpretedOption& operator=(const UninterpretedOption& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UninterpretedOption& default_instance(); + + void Swap(UninterpretedOption* other); + + // implements Message ---------------------------------------------- + + inline UninterpretedOption* New() const { return New(NULL); } + + UninterpretedOption* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UninterpretedOption& from); + void MergeFrom(const UninterpretedOption& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(UninterpretedOption* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef UninterpretedOption_NamePart NamePart; + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; + int name_size() const; + void clear_name(); + static const int kNameFieldNumber = 2; + const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const; + ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index); + ::google::protobuf::UninterpretedOption_NamePart* add_name(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* + mutable_name(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& + name() const; + + // optional string identifier_value = 3; + bool has_identifier_value() const; + void clear_identifier_value(); + static const int kIdentifierValueFieldNumber = 3; + const ::std::string& identifier_value() const; + void set_identifier_value(const ::std::string& value); + void set_identifier_value(const char* value); + void set_identifier_value(const char* value, size_t size); + ::std::string* mutable_identifier_value(); + ::std::string* release_identifier_value(); + void set_allocated_identifier_value(::std::string* identifier_value); + + // optional uint64 positive_int_value = 4; + bool has_positive_int_value() const; + void clear_positive_int_value(); + static const int kPositiveIntValueFieldNumber = 4; + ::google::protobuf::uint64 positive_int_value() const; + void set_positive_int_value(::google::protobuf::uint64 value); + + // optional int64 negative_int_value = 5; + bool has_negative_int_value() const; + void clear_negative_int_value(); + static const int kNegativeIntValueFieldNumber = 5; + ::google::protobuf::int64 negative_int_value() const; + void set_negative_int_value(::google::protobuf::int64 value); + + // optional double double_value = 6; + bool has_double_value() const; + void clear_double_value(); + static const int kDoubleValueFieldNumber = 6; + double double_value() const; + void set_double_value(double value); + + // optional bytes string_value = 7; + bool has_string_value() const; + void clear_string_value(); + static const int kStringValueFieldNumber = 7; + const ::std::string& string_value() const; + void set_string_value(const ::std::string& value); + void set_string_value(const char* value); + void set_string_value(const void* value, size_t size); + ::std::string* mutable_string_value(); + ::std::string* release_string_value(); + void set_allocated_string_value(::std::string* string_value); + + // optional string aggregate_value = 8; + bool has_aggregate_value() const; + void clear_aggregate_value(); + static const int kAggregateValueFieldNumber = 8; + const ::std::string& aggregate_value() const; + void set_aggregate_value(const ::std::string& value); + void set_aggregate_value(const char* value); + void set_aggregate_value(const char* value, size_t size); + ::std::string* mutable_aggregate_value(); + ::std::string* release_aggregate_value(); + void set_allocated_aggregate_value(::std::string* aggregate_value); + + // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption) + private: + inline void set_has_identifier_value(); + inline void clear_has_identifier_value(); + inline void set_has_positive_int_value(); + inline void clear_has_positive_int_value(); + inline void set_has_negative_int_value(); + inline void clear_has_negative_int_value(); + inline void set_has_double_value(); + inline void clear_has_double_value(); + inline void set_has_string_value(); + inline void clear_has_string_value(); + inline void set_has_aggregate_value(); + inline void clear_has_aggregate_value(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_; + ::google::protobuf::internal::ArenaStringPtr identifier_value_; + ::google::protobuf::uint64 positive_int_value_; + ::google::protobuf::int64 negative_int_value_; + double double_value_; + ::google::protobuf::internal::ArenaStringPtr string_value_; + ::google::protobuf::internal::ArenaStringPtr aggregate_value_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static UninterpretedOption* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ { + public: + SourceCodeInfo_Location(); + virtual ~SourceCodeInfo_Location(); + + SourceCodeInfo_Location(const SourceCodeInfo_Location& from); + + inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SourceCodeInfo_Location& default_instance(); + + void Swap(SourceCodeInfo_Location* other); + + // implements Message ---------------------------------------------- + + inline SourceCodeInfo_Location* New() const { return New(NULL); } + + SourceCodeInfo_Location* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SourceCodeInfo_Location& from); + void MergeFrom(const SourceCodeInfo_Location& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(SourceCodeInfo_Location* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 path = 1 [packed = true]; + int path_size() const; + void clear_path(); + static const int kPathFieldNumber = 1; + ::google::protobuf::int32 path(int index) const; + void set_path(int index, ::google::protobuf::int32 value); + void add_path(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + path() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_path(); + + // repeated int32 span = 2 [packed = true]; + int span_size() const; + void clear_span(); + static const int kSpanFieldNumber = 2; + ::google::protobuf::int32 span(int index) const; + void set_span(int index, ::google::protobuf::int32 value); + void add_span(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + span() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_span(); + + // optional string leading_comments = 3; + bool has_leading_comments() const; + void clear_leading_comments(); + static const int kLeadingCommentsFieldNumber = 3; + const ::std::string& leading_comments() const; + void set_leading_comments(const ::std::string& value); + void set_leading_comments(const char* value); + void set_leading_comments(const char* value, size_t size); + ::std::string* mutable_leading_comments(); + ::std::string* release_leading_comments(); + void set_allocated_leading_comments(::std::string* leading_comments); + + // optional string trailing_comments = 4; + bool has_trailing_comments() const; + void clear_trailing_comments(); + static const int kTrailingCommentsFieldNumber = 4; + const ::std::string& trailing_comments() const; + void set_trailing_comments(const ::std::string& value); + void set_trailing_comments(const char* value); + void set_trailing_comments(const char* value, size_t size); + ::std::string* mutable_trailing_comments(); + ::std::string* release_trailing_comments(); + void set_allocated_trailing_comments(::std::string* trailing_comments); + + // repeated string leading_detached_comments = 6; + int leading_detached_comments_size() const; + void clear_leading_detached_comments(); + static const int kLeadingDetachedCommentsFieldNumber = 6; + const ::std::string& leading_detached_comments(int index) const; + ::std::string* mutable_leading_detached_comments(int index); + void set_leading_detached_comments(int index, const ::std::string& value); + void set_leading_detached_comments(int index, const char* value); + void set_leading_detached_comments(int index, const char* value, size_t size); + ::std::string* add_leading_detached_comments(); + void add_leading_detached_comments(const ::std::string& value); + void add_leading_detached_comments(const char* value); + void add_leading_detached_comments(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& leading_detached_comments() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_leading_detached_comments(); + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location) + private: + inline void set_has_leading_comments(); + inline void clear_has_leading_comments(); + inline void set_has_trailing_comments(); + inline void clear_has_trailing_comments(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_; + mutable int _path_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_; + mutable int _span_cached_byte_size_; + ::google::protobuf::internal::ArenaStringPtr leading_comments_; + ::google::protobuf::internal::ArenaStringPtr trailing_comments_; + ::google::protobuf::RepeatedPtrField< ::std::string> leading_detached_comments_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static SourceCodeInfo_Location* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ { + public: + SourceCodeInfo(); + virtual ~SourceCodeInfo(); + + SourceCodeInfo(const SourceCodeInfo& from); + + inline SourceCodeInfo& operator=(const SourceCodeInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SourceCodeInfo& default_instance(); + + void Swap(SourceCodeInfo* other); + + // implements Message ---------------------------------------------- + + inline SourceCodeInfo* New() const { return New(NULL); } + + SourceCodeInfo* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SourceCodeInfo& from); + void MergeFrom(const SourceCodeInfo& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(SourceCodeInfo* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef SourceCodeInfo_Location Location; + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + int location_size() const; + void clear_location(); + static const int kLocationFieldNumber = 1; + const ::google::protobuf::SourceCodeInfo_Location& location(int index) const; + ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index); + ::google::protobuf::SourceCodeInfo_Location* add_location(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >* + mutable_location(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >& + location() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static SourceCodeInfo* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ { + public: + GeneratedCodeInfo_Annotation(); + virtual ~GeneratedCodeInfo_Annotation(); + + GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from); + + inline GeneratedCodeInfo_Annotation& operator=(const GeneratedCodeInfo_Annotation& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const GeneratedCodeInfo_Annotation& default_instance(); + + void Swap(GeneratedCodeInfo_Annotation* other); + + // implements Message ---------------------------------------------- + + inline GeneratedCodeInfo_Annotation* New() const { return New(NULL); } + + GeneratedCodeInfo_Annotation* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const GeneratedCodeInfo_Annotation& from); + void MergeFrom(const GeneratedCodeInfo_Annotation& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(GeneratedCodeInfo_Annotation* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 path = 1 [packed = true]; + int path_size() const; + void clear_path(); + static const int kPathFieldNumber = 1; + ::google::protobuf::int32 path(int index) const; + void set_path(int index, ::google::protobuf::int32 value); + void add_path(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + path() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_path(); + + // optional string source_file = 2; + bool has_source_file() const; + void clear_source_file(); + static const int kSourceFileFieldNumber = 2; + const ::std::string& source_file() const; + void set_source_file(const ::std::string& value); + void set_source_file(const char* value); + void set_source_file(const char* value, size_t size); + ::std::string* mutable_source_file(); + ::std::string* release_source_file(); + void set_allocated_source_file(::std::string* source_file); + + // optional int32 begin = 3; + bool has_begin() const; + void clear_begin(); + static const int kBeginFieldNumber = 3; + ::google::protobuf::int32 begin() const; + void set_begin(::google::protobuf::int32 value); + + // optional int32 end = 4; + bool has_end() const; + void clear_end(); + static const int kEndFieldNumber = 4; + ::google::protobuf::int32 end() const; + void set_end(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation) + private: + inline void set_has_source_file(); + inline void clear_has_source_file(); + inline void set_has_begin(); + inline void clear_has_begin(); + inline void set_has_end(); + inline void clear_has_end(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_; + mutable int _path_cached_byte_size_; + ::google::protobuf::internal::ArenaStringPtr source_file_; + ::google::protobuf::int32 begin_; + ::google::protobuf::int32 end_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static GeneratedCodeInfo_Annotation* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ { + public: + GeneratedCodeInfo(); + virtual ~GeneratedCodeInfo(); + + GeneratedCodeInfo(const GeneratedCodeInfo& from); + + inline GeneratedCodeInfo& operator=(const GeneratedCodeInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const GeneratedCodeInfo& default_instance(); + + void Swap(GeneratedCodeInfo* other); + + // implements Message ---------------------------------------------- + + inline GeneratedCodeInfo* New() const { return New(NULL); } + + GeneratedCodeInfo* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const GeneratedCodeInfo& from); + void MergeFrom(const GeneratedCodeInfo& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(GeneratedCodeInfo* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef GeneratedCodeInfo_Annotation Annotation; + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; + int annotation_size() const; + void clear_annotation(); + static const int kAnnotationFieldNumber = 1; + const ::google::protobuf::GeneratedCodeInfo_Annotation& annotation(int index) const; + ::google::protobuf::GeneratedCodeInfo_Annotation* mutable_annotation(int index); + ::google::protobuf::GeneratedCodeInfo_Annotation* add_annotation(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >* + mutable_annotation(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >& + annotation() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation > annotation_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static GeneratedCodeInfo* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// FileDescriptorSet + +// repeated .google.protobuf.FileDescriptorProto file = 1; +inline int FileDescriptorSet::file_size() const { + return file_.size(); +} +inline void FileDescriptorSet::clear_file() { + file_.Clear(); +} +inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file) + return file_.Get(index); +} +inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file) + return file_.Mutable(index); +} +inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() { + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file) + return file_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* +FileDescriptorSet::mutable_file() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file) + return &file_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& +FileDescriptorSet::file() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file) + return file_; +} + +// ------------------------------------------------------------------- + +// FileDescriptorProto + +// optional string name = 1; +inline bool FileDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FileDescriptorProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& FileDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name) +} +inline void FileDescriptorProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name) +} +inline void FileDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name) +} +inline ::std::string* FileDescriptorProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileDescriptorProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name) +} + +// optional string package = 2; +inline bool FileDescriptorProto::has_package() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FileDescriptorProto::set_has_package() { + _has_bits_[0] |= 0x00000002u; +} +inline void FileDescriptorProto::clear_has_package() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FileDescriptorProto::clear_package() { + package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_package(); +} +inline const ::std::string& FileDescriptorProto::package() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package) + return package_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileDescriptorProto::set_package(const ::std::string& value) { + set_has_package(); + package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package) +} +inline void FileDescriptorProto::set_package(const char* value) { + set_has_package(); + package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package) +} +inline void FileDescriptorProto::set_package(const char* value, size_t size) { + set_has_package(); + package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package) +} +inline ::std::string* FileDescriptorProto::mutable_package() { + set_has_package(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package) + return package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileDescriptorProto::release_package() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package) + clear_has_package(); + return package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileDescriptorProto::set_allocated_package(::std::string* package) { + if (package != NULL) { + set_has_package(); + } else { + clear_has_package(); + } + package_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), package); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package) +} + +// repeated string dependency = 3; +inline int FileDescriptorProto::dependency_size() const { + return dependency_.size(); +} +inline void FileDescriptorProto::clear_dependency() { + dependency_.Clear(); +} +inline const ::std::string& FileDescriptorProto::dependency(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency) + return dependency_.Get(index); +} +inline ::std::string* FileDescriptorProto::mutable_dependency(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency) + return dependency_.Mutable(index); +} +inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency) + dependency_.Mutable(index)->assign(value); +} +inline void FileDescriptorProto::set_dependency(int index, const char* value) { + dependency_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) { + dependency_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency) +} +inline ::std::string* FileDescriptorProto::add_dependency() { + // @@protoc_insertion_point(field_add_mutable:google.protobuf.FileDescriptorProto.dependency) + return dependency_.Add(); +} +inline void FileDescriptorProto::add_dependency(const ::std::string& value) { + dependency_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::add_dependency(const char* value) { + dependency_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency) +} +inline void FileDescriptorProto::add_dependency(const char* value, size_t size) { + dependency_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +FileDescriptorProto::dependency() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency) + return dependency_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +FileDescriptorProto::mutable_dependency() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency) + return &dependency_; +} + +// repeated int32 public_dependency = 10; +inline int FileDescriptorProto::public_dependency_size() const { + return public_dependency_.size(); +} +inline void FileDescriptorProto::clear_public_dependency() { + public_dependency_.Clear(); +} +inline ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.public_dependency) + return public_dependency_.Get(index); +} +inline void FileDescriptorProto::set_public_dependency(int index, ::google::protobuf::int32 value) { + public_dependency_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency) +} +inline void FileDescriptorProto::add_public_dependency(::google::protobuf::int32 value) { + public_dependency_.Add(value); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +FileDescriptorProto::public_dependency() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency) + return public_dependency_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +FileDescriptorProto::mutable_public_dependency() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency) + return &public_dependency_; +} + +// repeated int32 weak_dependency = 11; +inline int FileDescriptorProto::weak_dependency_size() const { + return weak_dependency_.size(); +} +inline void FileDescriptorProto::clear_weak_dependency() { + weak_dependency_.Clear(); +} +inline ::google::protobuf::int32 FileDescriptorProto::weak_dependency(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.weak_dependency) + return weak_dependency_.Get(index); +} +inline void FileDescriptorProto::set_weak_dependency(int index, ::google::protobuf::int32 value) { + weak_dependency_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency) +} +inline void FileDescriptorProto::add_weak_dependency(::google::protobuf::int32 value) { + weak_dependency_.Add(value); + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +FileDescriptorProto::weak_dependency() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency) + return weak_dependency_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +FileDescriptorProto::mutable_weak_dependency() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency) + return &weak_dependency_; +} + +// repeated .google.protobuf.DescriptorProto message_type = 4; +inline int FileDescriptorProto::message_type_size() const { + return message_type_.size(); +} +inline void FileDescriptorProto::clear_message_type() { + message_type_.Clear(); +} +inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type) + return message_type_.Get(index); +} +inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type) + return message_type_.Mutable(index); +} +inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() { + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type) + return message_type_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* +FileDescriptorProto::mutable_message_type() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type) + return &message_type_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& +FileDescriptorProto::message_type() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type) + return message_type_; +} + +// repeated .google.protobuf.EnumDescriptorProto enum_type = 5; +inline int FileDescriptorProto::enum_type_size() const { + return enum_type_.size(); +} +inline void FileDescriptorProto::clear_enum_type() { + enum_type_.Clear(); +} +inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type) + return enum_type_.Get(index); +} +inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type) + return enum_type_.Mutable(index); +} +inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() { + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type) + return enum_type_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* +FileDescriptorProto::mutable_enum_type() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type) + return &enum_type_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& +FileDescriptorProto::enum_type() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type) + return enum_type_; +} + +// repeated .google.protobuf.ServiceDescriptorProto service = 6; +inline int FileDescriptorProto::service_size() const { + return service_.size(); +} +inline void FileDescriptorProto::clear_service() { + service_.Clear(); +} +inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service) + return service_.Get(index); +} +inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service) + return service_.Mutable(index); +} +inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() { + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service) + return service_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* +FileDescriptorProto::mutable_service() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service) + return &service_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& +FileDescriptorProto::service() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service) + return service_; +} + +// repeated .google.protobuf.FieldDescriptorProto extension = 7; +inline int FileDescriptorProto::extension_size() const { + return extension_.size(); +} +inline void FileDescriptorProto::clear_extension() { + extension_.Clear(); +} +inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension) + return extension_.Get(index); +} +inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension) + return extension_.Mutable(index); +} +inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() { + // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension) + return extension_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +FileDescriptorProto::mutable_extension() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension) + return &extension_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +FileDescriptorProto::extension() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension) + return extension_; +} + +// optional .google.protobuf.FileOptions options = 8; +inline bool FileDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void FileDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000200u; +} +inline void FileDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000200u; +} +inline void FileDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::FileOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options) + return options_; +} +inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.options) + clear_has_options(); + ::google::protobuf::FileOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options) +} + +// optional .google.protobuf.SourceCodeInfo source_code_info = 9; +inline bool FileDescriptorProto::has_source_code_info() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void FileDescriptorProto::set_has_source_code_info() { + _has_bits_[0] |= 0x00000400u; +} +inline void FileDescriptorProto::clear_has_source_code_info() { + _has_bits_[0] &= ~0x00000400u; +} +inline void FileDescriptorProto::clear_source_code_info() { + if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear(); + clear_has_source_code_info(); +} +inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info) + return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_; +} +inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() { + set_has_source_code_info(); + if (source_code_info_ == NULL) { + source_code_info_ = new ::google::protobuf::SourceCodeInfo; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info) + return source_code_info_; +} +inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.source_code_info) + clear_has_source_code_info(); + ::google::protobuf::SourceCodeInfo* temp = source_code_info_; + source_code_info_ = NULL; + return temp; +} +inline void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) { + delete source_code_info_; + source_code_info_ = source_code_info; + if (source_code_info) { + set_has_source_code_info(); + } else { + clear_has_source_code_info(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info) +} + +// optional string syntax = 12; +inline bool FileDescriptorProto::has_syntax() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void FileDescriptorProto::set_has_syntax() { + _has_bits_[0] |= 0x00000800u; +} +inline void FileDescriptorProto::clear_has_syntax() { + _has_bits_[0] &= ~0x00000800u; +} +inline void FileDescriptorProto::clear_syntax() { + syntax_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_syntax(); +} +inline const ::std::string& FileDescriptorProto::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.syntax) + return syntax_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileDescriptorProto::set_syntax(const ::std::string& value) { + set_has_syntax(); + syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax) +} +inline void FileDescriptorProto::set_syntax(const char* value) { + set_has_syntax(); + syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax) +} +inline void FileDescriptorProto::set_syntax(const char* value, size_t size) { + set_has_syntax(); + syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.syntax) +} +inline ::std::string* FileDescriptorProto::mutable_syntax() { + set_has_syntax(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.syntax) + return syntax_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileDescriptorProto::release_syntax() { + // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax) + clear_has_syntax(); + return syntax_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileDescriptorProto::set_allocated_syntax(::std::string* syntax) { + if (syntax != NULL) { + set_has_syntax(); + } else { + clear_has_syntax(); + } + syntax_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), syntax); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.syntax) +} + +// ------------------------------------------------------------------- + +// DescriptorProto_ExtensionRange + +// optional int32 start = 1; +inline bool DescriptorProto_ExtensionRange::has_start() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto_ExtensionRange::set_has_start() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto_ExtensionRange::clear_has_start() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DescriptorProto_ExtensionRange::clear_start() { + start_ = 0; + clear_has_start(); +} +inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start) + return start_; +} +inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) { + set_has_start(); + start_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start) +} + +// optional int32 end = 2; +inline bool DescriptorProto_ExtensionRange::has_end() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DescriptorProto_ExtensionRange::set_has_end() { + _has_bits_[0] |= 0x00000002u; +} +inline void DescriptorProto_ExtensionRange::clear_has_end() { + _has_bits_[0] &= ~0x00000002u; +} +inline void DescriptorProto_ExtensionRange::clear_end() { + end_ = 0; + clear_has_end(); +} +inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end) + return end_; +} +inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) { + set_has_end(); + end_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end) +} + +// ------------------------------------------------------------------- + +// DescriptorProto_ReservedRange + +// optional int32 start = 1; +inline bool DescriptorProto_ReservedRange::has_start() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto_ReservedRange::set_has_start() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto_ReservedRange::clear_has_start() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DescriptorProto_ReservedRange::clear_start() { + start_ = 0; + clear_has_start(); +} +inline ::google::protobuf::int32 DescriptorProto_ReservedRange::start() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.start) + return start_; +} +inline void DescriptorProto_ReservedRange::set_start(::google::protobuf::int32 value) { + set_has_start(); + start_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.start) +} + +// optional int32 end = 2; +inline bool DescriptorProto_ReservedRange::has_end() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DescriptorProto_ReservedRange::set_has_end() { + _has_bits_[0] |= 0x00000002u; +} +inline void DescriptorProto_ReservedRange::clear_has_end() { + _has_bits_[0] &= ~0x00000002u; +} +inline void DescriptorProto_ReservedRange::clear_end() { + end_ = 0; + clear_has_end(); +} +inline ::google::protobuf::int32 DescriptorProto_ReservedRange::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.end) + return end_; +} +inline void DescriptorProto_ReservedRange::set_end(::google::protobuf::int32 value) { + set_has_end(); + end_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.end) +} + +// ------------------------------------------------------------------- + +// DescriptorProto + +// optional string name = 1; +inline bool DescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DescriptorProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& DescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void DescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name) +} +inline void DescriptorProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name) +} +inline void DescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name) +} +inline ::std::string* DescriptorProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* DescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void DescriptorProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name) +} + +// repeated .google.protobuf.FieldDescriptorProto field = 2; +inline int DescriptorProto::field_size() const { + return field_.size(); +} +inline void DescriptorProto::clear_field() { + field_.Clear(); +} +inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field) + return field_.Get(index); +} +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field) + return field_.Mutable(index); +} +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field) + return field_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +DescriptorProto::mutable_field() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field) + return &field_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +DescriptorProto::field() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field) + return field_; +} + +// repeated .google.protobuf.FieldDescriptorProto extension = 6; +inline int DescriptorProto::extension_size() const { + return extension_.size(); +} +inline void DescriptorProto::clear_extension() { + extension_.Clear(); +} +inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension) + return extension_.Get(index); +} +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension) + return extension_.Mutable(index); +} +inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension) + return extension_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* +DescriptorProto::mutable_extension() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension) + return &extension_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& +DescriptorProto::extension() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension) + return extension_; +} + +// repeated .google.protobuf.DescriptorProto nested_type = 3; +inline int DescriptorProto::nested_type_size() const { + return nested_type_.size(); +} +inline void DescriptorProto::clear_nested_type() { + nested_type_.Clear(); +} +inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type) + return nested_type_.Get(index); +} +inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type) + return nested_type_.Mutable(index); +} +inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type) + return nested_type_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* +DescriptorProto::mutable_nested_type() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type) + return &nested_type_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& +DescriptorProto::nested_type() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type) + return nested_type_; +} + +// repeated .google.protobuf.EnumDescriptorProto enum_type = 4; +inline int DescriptorProto::enum_type_size() const { + return enum_type_.size(); +} +inline void DescriptorProto::clear_enum_type() { + enum_type_.Clear(); +} +inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type) + return enum_type_.Get(index); +} +inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type) + return enum_type_.Mutable(index); +} +inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type) + return enum_type_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* +DescriptorProto::mutable_enum_type() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type) + return &enum_type_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& +DescriptorProto::enum_type() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type) + return enum_type_; +} + +// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; +inline int DescriptorProto::extension_range_size() const { + return extension_range_.size(); +} +inline void DescriptorProto::clear_extension_range() { + extension_range_.Clear(); +} +inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range) + return extension_range_.Get(index); +} +inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range) + return extension_range_.Mutable(index); +} +inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range) + return extension_range_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* +DescriptorProto::mutable_extension_range() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range) + return &extension_range_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& +DescriptorProto::extension_range() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range) + return extension_range_; +} + +// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; +inline int DescriptorProto::oneof_decl_size() const { + return oneof_decl_.size(); +} +inline void DescriptorProto::clear_oneof_decl() { + oneof_decl_.Clear(); +} +inline const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl) + return oneof_decl_.Get(index); +} +inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl) + return oneof_decl_.Mutable(index); +} +inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl) + return oneof_decl_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >* +DescriptorProto::mutable_oneof_decl() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl) + return &oneof_decl_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >& +DescriptorProto::oneof_decl() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl) + return oneof_decl_; +} + +// optional .google.protobuf.MessageOptions options = 7; +inline bool DescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void DescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000080u; +} +inline void DescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000080u; +} +inline void DescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::MessageOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options) + return options_; +} +inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options) + clear_has_options(); + ::google::protobuf::MessageOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options) +} + +// repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; +inline int DescriptorProto::reserved_range_size() const { + return reserved_range_.size(); +} +inline void DescriptorProto::clear_reserved_range() { + reserved_range_.Clear(); +} +inline const ::google::protobuf::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Get(index); +} +inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Mutable(index); +} +inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >* +DescriptorProto::mutable_reserved_range() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range) + return &reserved_range_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >& +DescriptorProto::reserved_range() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_; +} + +// repeated string reserved_name = 10; +inline int DescriptorProto::reserved_name_size() const { + return reserved_name_.size(); +} +inline void DescriptorProto::clear_reserved_name() { + reserved_name_.Clear(); +} +inline const ::std::string& DescriptorProto::reserved_name(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_.Get(index); +} +inline ::std::string* DescriptorProto::mutable_reserved_name(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_.Mutable(index); +} +inline void DescriptorProto::set_reserved_name(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name) + reserved_name_.Mutable(index)->assign(value); +} +inline void DescriptorProto::set_reserved_name(int index, const char* value) { + reserved_name_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::set_reserved_name(int index, const char* value, size_t size) { + reserved_name_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.reserved_name) +} +inline ::std::string* DescriptorProto::add_reserved_name() { + // @@protoc_insertion_point(field_add_mutable:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_.Add(); +} +inline void DescriptorProto::add_reserved_name(const ::std::string& value) { + reserved_name_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::add_reserved_name(const char* value) { + reserved_name_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name) +} +inline void DescriptorProto::add_reserved_name(const char* value, size_t size) { + reserved_name_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.DescriptorProto.reserved_name) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +DescriptorProto::reserved_name() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +DescriptorProto::mutable_reserved_name() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name) + return &reserved_name_; +} + +// ------------------------------------------------------------------- + +// FieldDescriptorProto + +// optional string name = 1; +inline bool FieldDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FieldDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FieldDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FieldDescriptorProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& FieldDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name) +} +inline void FieldDescriptorProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name) +} +inline void FieldDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name) +} +inline ::std::string* FieldDescriptorProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FieldDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name) +} + +// optional int32 number = 3; +inline bool FieldDescriptorProto::has_number() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FieldDescriptorProto::set_has_number() { + _has_bits_[0] |= 0x00000002u; +} +inline void FieldDescriptorProto::clear_has_number() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FieldDescriptorProto::clear_number() { + number_ = 0; + clear_has_number(); +} +inline ::google::protobuf::int32 FieldDescriptorProto::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number) + return number_; +} +inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) { + set_has_number(); + number_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number) +} + +// optional .google.protobuf.FieldDescriptorProto.Label label = 4; +inline bool FieldDescriptorProto::has_label() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FieldDescriptorProto::set_has_label() { + _has_bits_[0] |= 0x00000004u; +} +inline void FieldDescriptorProto::clear_has_label() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FieldDescriptorProto::clear_label() { + label_ = 1; + clear_has_label(); +} +inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label) + return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_); +} +inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) { + assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value)); + set_has_label(); + label_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label) +} + +// optional .google.protobuf.FieldDescriptorProto.Type type = 5; +inline bool FieldDescriptorProto::has_type() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FieldDescriptorProto::set_has_type() { + _has_bits_[0] |= 0x00000008u; +} +inline void FieldDescriptorProto::clear_has_type() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FieldDescriptorProto::clear_type() { + type_ = 1; + clear_has_type(); +} +inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type) + return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_); +} +inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) { + assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value)); + set_has_type(); + type_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type) +} + +// optional string type_name = 6; +inline bool FieldDescriptorProto::has_type_name() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FieldDescriptorProto::set_has_type_name() { + _has_bits_[0] |= 0x00000010u; +} +inline void FieldDescriptorProto::clear_has_type_name() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FieldDescriptorProto::clear_type_name() { + type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_type_name(); +} +inline const ::std::string& FieldDescriptorProto::type_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name) + return type_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_type_name(const ::std::string& value) { + set_has_type_name(); + type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name) +} +inline void FieldDescriptorProto::set_type_name(const char* value) { + set_has_type_name(); + type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name) +} +inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) { + set_has_type_name(); + type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name) +} +inline ::std::string* FieldDescriptorProto::mutable_type_name() { + set_has_type_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name) + return type_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FieldDescriptorProto::release_type_name() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name) + clear_has_type_name(); + return type_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) { + if (type_name != NULL) { + set_has_type_name(); + } else { + clear_has_type_name(); + } + type_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name) +} + +// optional string extendee = 2; +inline bool FieldDescriptorProto::has_extendee() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FieldDescriptorProto::set_has_extendee() { + _has_bits_[0] |= 0x00000020u; +} +inline void FieldDescriptorProto::clear_has_extendee() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FieldDescriptorProto::clear_extendee() { + extendee_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_extendee(); +} +inline const ::std::string& FieldDescriptorProto::extendee() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee) + return extendee_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_extendee(const ::std::string& value) { + set_has_extendee(); + extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee) +} +inline void FieldDescriptorProto::set_extendee(const char* value) { + set_has_extendee(); + extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee) +} +inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) { + set_has_extendee(); + extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee) +} +inline ::std::string* FieldDescriptorProto::mutable_extendee() { + set_has_extendee(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee) + return extendee_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FieldDescriptorProto::release_extendee() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee) + clear_has_extendee(); + return extendee_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) { + if (extendee != NULL) { + set_has_extendee(); + } else { + clear_has_extendee(); + } + extendee_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), extendee); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee) +} + +// optional string default_value = 7; +inline bool FieldDescriptorProto::has_default_value() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FieldDescriptorProto::set_has_default_value() { + _has_bits_[0] |= 0x00000040u; +} +inline void FieldDescriptorProto::clear_has_default_value() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FieldDescriptorProto::clear_default_value() { + default_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_default_value(); +} +inline const ::std::string& FieldDescriptorProto::default_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value) + return default_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_default_value(const ::std::string& value) { + set_has_default_value(); + default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value) +} +inline void FieldDescriptorProto::set_default_value(const char* value) { + set_has_default_value(); + default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value) +} +inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) { + set_has_default_value(); + default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value) +} +inline ::std::string* FieldDescriptorProto::mutable_default_value() { + set_has_default_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value) + return default_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FieldDescriptorProto::release_default_value() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value) + clear_has_default_value(); + return default_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) { + if (default_value != NULL) { + set_has_default_value(); + } else { + clear_has_default_value(); + } + default_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), default_value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value) +} + +// optional int32 oneof_index = 9; +inline bool FieldDescriptorProto::has_oneof_index() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FieldDescriptorProto::set_has_oneof_index() { + _has_bits_[0] |= 0x00000080u; +} +inline void FieldDescriptorProto::clear_has_oneof_index() { + _has_bits_[0] &= ~0x00000080u; +} +inline void FieldDescriptorProto::clear_oneof_index() { + oneof_index_ = 0; + clear_has_oneof_index(); +} +inline ::google::protobuf::int32 FieldDescriptorProto::oneof_index() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index) + return oneof_index_; +} +inline void FieldDescriptorProto::set_oneof_index(::google::protobuf::int32 value) { + set_has_oneof_index(); + oneof_index_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index) +} + +// optional string json_name = 10; +inline bool FieldDescriptorProto::has_json_name() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void FieldDescriptorProto::set_has_json_name() { + _has_bits_[0] |= 0x00000100u; +} +inline void FieldDescriptorProto::clear_has_json_name() { + _has_bits_[0] &= ~0x00000100u; +} +inline void FieldDescriptorProto::clear_json_name() { + json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_json_name(); +} +inline const ::std::string& FieldDescriptorProto::json_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.json_name) + return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_json_name(const ::std::string& value) { + set_has_json_name(); + json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.json_name) +} +inline void FieldDescriptorProto::set_json_name(const char* value) { + set_has_json_name(); + json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name) +} +inline void FieldDescriptorProto::set_json_name(const char* value, size_t size) { + set_has_json_name(); + json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.json_name) +} +inline ::std::string* FieldDescriptorProto::mutable_json_name() { + set_has_json_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.json_name) + return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FieldDescriptorProto::release_json_name() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name) + clear_has_json_name(); + return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldDescriptorProto::set_allocated_json_name(::std::string* json_name) { + if (json_name != NULL) { + set_has_json_name(); + } else { + clear_has_json_name(); + } + json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.json_name) +} + +// optional .google.protobuf.FieldOptions options = 8; +inline bool FieldDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void FieldDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000200u; +} +inline void FieldDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000200u; +} +inline void FieldDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::FieldOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options) + return options_; +} +inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.options) + clear_has_options(); + ::google::protobuf::FieldOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options) +} + +// ------------------------------------------------------------------- + +// OneofDescriptorProto + +// optional string name = 1; +inline bool OneofDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void OneofDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void OneofDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void OneofDescriptorProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& OneofDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void OneofDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name) +} +inline void OneofDescriptorProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name) +} +inline void OneofDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name) +} +inline ::std::string* OneofDescriptorProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* OneofDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void OneofDescriptorProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name) +} + +// optional .google.protobuf.OneofOptions options = 2; +inline bool OneofDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void OneofDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000002u; +} +inline void OneofDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000002u; +} +inline void OneofDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::OneofOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::OneofOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options) + return options_; +} +inline ::google::protobuf::OneofOptions* OneofDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options) + clear_has_options(); + ::google::protobuf::OneofOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void OneofDescriptorProto::set_allocated_options(::google::protobuf::OneofOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options) +} + +// ------------------------------------------------------------------- + +// EnumDescriptorProto + +// optional string name = 1; +inline bool EnumDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EnumDescriptorProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& EnumDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void EnumDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name) +} +inline void EnumDescriptorProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name) +} +inline void EnumDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name) +} +inline ::std::string* EnumDescriptorProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* EnumDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void EnumDescriptorProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name) +} + +// repeated .google.protobuf.EnumValueDescriptorProto value = 2; +inline int EnumDescriptorProto::value_size() const { + return value_.size(); +} +inline void EnumDescriptorProto::clear_value() { + value_.Clear(); +} +inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value) + return value_.Get(index); +} +inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value) + return value_.Mutable(index); +} +inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() { + // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value) + return value_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* +EnumDescriptorProto::mutable_value() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value) + return &value_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& +EnumDescriptorProto::value() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value) + return value_; +} + +// optional .google.protobuf.EnumOptions options = 3; +inline bool EnumDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void EnumDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void EnumDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; +} +inline void EnumDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::EnumOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options) + return options_; +} +inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.options) + clear_has_options(); + ::google::protobuf::EnumOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options) +} + +// ------------------------------------------------------------------- + +// EnumValueDescriptorProto + +// optional string name = 1; +inline bool EnumValueDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumValueDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumValueDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EnumValueDescriptorProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& EnumValueDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void EnumValueDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name) +} +inline void EnumValueDescriptorProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name) +} +inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name) +} +inline ::std::string* EnumValueDescriptorProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* EnumValueDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void EnumValueDescriptorProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name) +} + +// optional int32 number = 2; +inline bool EnumValueDescriptorProto::has_number() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void EnumValueDescriptorProto::set_has_number() { + _has_bits_[0] |= 0x00000002u; +} +inline void EnumValueDescriptorProto::clear_has_number() { + _has_bits_[0] &= ~0x00000002u; +} +inline void EnumValueDescriptorProto::clear_number() { + number_ = 0; + clear_has_number(); +} +inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number) + return number_; +} +inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) { + set_has_number(); + number_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number) +} + +// optional .google.protobuf.EnumValueOptions options = 3; +inline bool EnumValueDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void EnumValueDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void EnumValueDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; +} +inline void EnumValueDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::EnumValueOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options) + return options_; +} +inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.options) + clear_has_options(); + ::google::protobuf::EnumValueOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options) +} + +// ------------------------------------------------------------------- + +// ServiceDescriptorProto + +// optional string name = 1; +inline bool ServiceDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ServiceDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void ServiceDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ServiceDescriptorProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& ServiceDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void ServiceDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name) +} +inline void ServiceDescriptorProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name) +} +inline void ServiceDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name) +} +inline ::std::string* ServiceDescriptorProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* ServiceDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void ServiceDescriptorProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name) +} + +// repeated .google.protobuf.MethodDescriptorProto method = 2; +inline int ServiceDescriptorProto::method_size() const { + return method_.size(); +} +inline void ServiceDescriptorProto::clear_method() { + method_.Clear(); +} +inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method) + return method_.Get(index); +} +inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method) + return method_.Mutable(index); +} +inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() { + // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method) + return method_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* +ServiceDescriptorProto::mutable_method() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method) + return &method_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& +ServiceDescriptorProto::method() const { + // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method) + return method_; +} + +// optional .google.protobuf.ServiceOptions options = 3; +inline bool ServiceDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ServiceDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void ServiceDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ServiceDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::ServiceOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options) + return options_; +} +inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.options) + clear_has_options(); + ::google::protobuf::ServiceOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options) +} + +// ------------------------------------------------------------------- + +// MethodDescriptorProto + +// optional string name = 1; +inline bool MethodDescriptorProto::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MethodDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void MethodDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MethodDescriptorProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& MethodDescriptorProto::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MethodDescriptorProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name) +} +inline void MethodDescriptorProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name) +} +inline void MethodDescriptorProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name) +} +inline ::std::string* MethodDescriptorProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* MethodDescriptorProto::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MethodDescriptorProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name) +} + +// optional string input_type = 2; +inline bool MethodDescriptorProto::has_input_type() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MethodDescriptorProto::set_has_input_type() { + _has_bits_[0] |= 0x00000002u; +} +inline void MethodDescriptorProto::clear_has_input_type() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MethodDescriptorProto::clear_input_type() { + input_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_input_type(); +} +inline const ::std::string& MethodDescriptorProto::input_type() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type) + return input_type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MethodDescriptorProto::set_input_type(const ::std::string& value) { + set_has_input_type(); + input_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type) +} +inline void MethodDescriptorProto::set_input_type(const char* value) { + set_has_input_type(); + input_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type) +} +inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) { + set_has_input_type(); + input_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type) +} +inline ::std::string* MethodDescriptorProto::mutable_input_type() { + set_has_input_type(); + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type) + return input_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* MethodDescriptorProto::release_input_type() { + // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type) + clear_has_input_type(); + return input_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) { + if (input_type != NULL) { + set_has_input_type(); + } else { + clear_has_input_type(); + } + input_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), input_type); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type) +} + +// optional string output_type = 3; +inline bool MethodDescriptorProto::has_output_type() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MethodDescriptorProto::set_has_output_type() { + _has_bits_[0] |= 0x00000004u; +} +inline void MethodDescriptorProto::clear_has_output_type() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MethodDescriptorProto::clear_output_type() { + output_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_output_type(); +} +inline const ::std::string& MethodDescriptorProto::output_type() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type) + return output_type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MethodDescriptorProto::set_output_type(const ::std::string& value) { + set_has_output_type(); + output_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type) +} +inline void MethodDescriptorProto::set_output_type(const char* value) { + set_has_output_type(); + output_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type) +} +inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) { + set_has_output_type(); + output_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type) +} +inline ::std::string* MethodDescriptorProto::mutable_output_type() { + set_has_output_type(); + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type) + return output_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* MethodDescriptorProto::release_output_type() { + // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type) + clear_has_output_type(); + return output_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) { + if (output_type != NULL) { + set_has_output_type(); + } else { + clear_has_output_type(); + } + output_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), output_type); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type) +} + +// optional .google.protobuf.MethodOptions options = 4; +inline bool MethodDescriptorProto::has_options() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MethodDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000008u; +} +inline void MethodDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MethodDescriptorProto::clear_options() { + if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options) + return options_ != NULL ? *options_ : *default_instance_->options_; +} +inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::MethodOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options) + return options_; +} +inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.options) + clear_has_options(); + ::google::protobuf::MethodOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options) +} + +// optional bool client_streaming = 5 [default = false]; +inline bool MethodDescriptorProto::has_client_streaming() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MethodDescriptorProto::set_has_client_streaming() { + _has_bits_[0] |= 0x00000010u; +} +inline void MethodDescriptorProto::clear_has_client_streaming() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MethodDescriptorProto::clear_client_streaming() { + client_streaming_ = false; + clear_has_client_streaming(); +} +inline bool MethodDescriptorProto::client_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.client_streaming) + return client_streaming_; +} +inline void MethodDescriptorProto::set_client_streaming(bool value) { + set_has_client_streaming(); + client_streaming_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming) +} + +// optional bool server_streaming = 6 [default = false]; +inline bool MethodDescriptorProto::has_server_streaming() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void MethodDescriptorProto::set_has_server_streaming() { + _has_bits_[0] |= 0x00000020u; +} +inline void MethodDescriptorProto::clear_has_server_streaming() { + _has_bits_[0] &= ~0x00000020u; +} +inline void MethodDescriptorProto::clear_server_streaming() { + server_streaming_ = false; + clear_has_server_streaming(); +} +inline bool MethodDescriptorProto::server_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.server_streaming) + return server_streaming_; +} +inline void MethodDescriptorProto::set_server_streaming(bool value) { + set_has_server_streaming(); + server_streaming_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.server_streaming) +} + +// ------------------------------------------------------------------- + +// FileOptions + +// optional string java_package = 1; +inline bool FileOptions::has_java_package() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileOptions::set_has_java_package() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileOptions::clear_has_java_package() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FileOptions::clear_java_package() { + java_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_java_package(); +} +inline const ::std::string& FileOptions::java_package() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package) + return java_package_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_java_package(const ::std::string& value) { + set_has_java_package(); + java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package) +} +inline void FileOptions::set_java_package(const char* value) { + set_has_java_package(); + java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package) +} +inline void FileOptions::set_java_package(const char* value, size_t size) { + set_has_java_package(); + java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package) +} +inline ::std::string* FileOptions::mutable_java_package() { + set_has_java_package(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package) + return java_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileOptions::release_java_package() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package) + clear_has_java_package(); + return java_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_allocated_java_package(::std::string* java_package) { + if (java_package != NULL) { + set_has_java_package(); + } else { + clear_has_java_package(); + } + java_package_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), java_package); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package) +} + +// optional string java_outer_classname = 8; +inline bool FileOptions::has_java_outer_classname() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FileOptions::set_has_java_outer_classname() { + _has_bits_[0] |= 0x00000002u; +} +inline void FileOptions::clear_has_java_outer_classname() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FileOptions::clear_java_outer_classname() { + java_outer_classname_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_java_outer_classname(); +} +inline const ::std::string& FileOptions::java_outer_classname() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname) + return java_outer_classname_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_java_outer_classname(const ::std::string& value) { + set_has_java_outer_classname(); + java_outer_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname) +} +inline void FileOptions::set_java_outer_classname(const char* value) { + set_has_java_outer_classname(); + java_outer_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname) +} +inline void FileOptions::set_java_outer_classname(const char* value, size_t size) { + set_has_java_outer_classname(); + java_outer_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname) +} +inline ::std::string* FileOptions::mutable_java_outer_classname() { + set_has_java_outer_classname(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname) + return java_outer_classname_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileOptions::release_java_outer_classname() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname) + clear_has_java_outer_classname(); + return java_outer_classname_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) { + if (java_outer_classname != NULL) { + set_has_java_outer_classname(); + } else { + clear_has_java_outer_classname(); + } + java_outer_classname_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), java_outer_classname); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname) +} + +// optional bool java_multiple_files = 10 [default = false]; +inline bool FileOptions::has_java_multiple_files() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FileOptions::set_has_java_multiple_files() { + _has_bits_[0] |= 0x00000004u; +} +inline void FileOptions::clear_has_java_multiple_files() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FileOptions::clear_java_multiple_files() { + java_multiple_files_ = false; + clear_has_java_multiple_files(); +} +inline bool FileOptions::java_multiple_files() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files) + return java_multiple_files_; +} +inline void FileOptions::set_java_multiple_files(bool value) { + set_has_java_multiple_files(); + java_multiple_files_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files) +} + +// optional bool java_generate_equals_and_hash = 20 [default = false]; +inline bool FileOptions::has_java_generate_equals_and_hash() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FileOptions::set_has_java_generate_equals_and_hash() { + _has_bits_[0] |= 0x00000008u; +} +inline void FileOptions::clear_has_java_generate_equals_and_hash() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FileOptions::clear_java_generate_equals_and_hash() { + java_generate_equals_and_hash_ = false; + clear_has_java_generate_equals_and_hash(); +} +inline bool FileOptions::java_generate_equals_and_hash() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash) + return java_generate_equals_and_hash_; +} +inline void FileOptions::set_java_generate_equals_and_hash(bool value) { + set_has_java_generate_equals_and_hash(); + java_generate_equals_and_hash_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash) +} + +// optional bool java_string_check_utf8 = 27 [default = false]; +inline bool FileOptions::has_java_string_check_utf8() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FileOptions::set_has_java_string_check_utf8() { + _has_bits_[0] |= 0x00000010u; +} +inline void FileOptions::clear_has_java_string_check_utf8() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FileOptions::clear_java_string_check_utf8() { + java_string_check_utf8_ = false; + clear_has_java_string_check_utf8(); +} +inline bool FileOptions::java_string_check_utf8() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8) + return java_string_check_utf8_; +} +inline void FileOptions::set_java_string_check_utf8(bool value) { + set_has_java_string_check_utf8(); + java_string_check_utf8_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8) +} + +// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; +inline bool FileOptions::has_optimize_for() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FileOptions::set_has_optimize_for() { + _has_bits_[0] |= 0x00000020u; +} +inline void FileOptions::clear_has_optimize_for() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FileOptions::clear_optimize_for() { + optimize_for_ = 1; + clear_has_optimize_for(); +} +inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for) + return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_); +} +inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) { + assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value)); + set_has_optimize_for(); + optimize_for_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for) +} + +// optional string go_package = 11; +inline bool FileOptions::has_go_package() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FileOptions::set_has_go_package() { + _has_bits_[0] |= 0x00000040u; +} +inline void FileOptions::clear_has_go_package() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FileOptions::clear_go_package() { + go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_go_package(); +} +inline const ::std::string& FileOptions::go_package() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package) + return go_package_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_go_package(const ::std::string& value) { + set_has_go_package(); + go_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package) +} +inline void FileOptions::set_go_package(const char* value) { + set_has_go_package(); + go_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package) +} +inline void FileOptions::set_go_package(const char* value, size_t size) { + set_has_go_package(); + go_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package) +} +inline ::std::string* FileOptions::mutable_go_package() { + set_has_go_package(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package) + return go_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileOptions::release_go_package() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package) + clear_has_go_package(); + return go_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_allocated_go_package(::std::string* go_package) { + if (go_package != NULL) { + set_has_go_package(); + } else { + clear_has_go_package(); + } + go_package_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), go_package); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package) +} + +// optional bool cc_generic_services = 16 [default = false]; +inline bool FileOptions::has_cc_generic_services() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FileOptions::set_has_cc_generic_services() { + _has_bits_[0] |= 0x00000080u; +} +inline void FileOptions::clear_has_cc_generic_services() { + _has_bits_[0] &= ~0x00000080u; +} +inline void FileOptions::clear_cc_generic_services() { + cc_generic_services_ = false; + clear_has_cc_generic_services(); +} +inline bool FileOptions::cc_generic_services() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services) + return cc_generic_services_; +} +inline void FileOptions::set_cc_generic_services(bool value) { + set_has_cc_generic_services(); + cc_generic_services_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services) +} + +// optional bool java_generic_services = 17 [default = false]; +inline bool FileOptions::has_java_generic_services() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void FileOptions::set_has_java_generic_services() { + _has_bits_[0] |= 0x00000100u; +} +inline void FileOptions::clear_has_java_generic_services() { + _has_bits_[0] &= ~0x00000100u; +} +inline void FileOptions::clear_java_generic_services() { + java_generic_services_ = false; + clear_has_java_generic_services(); +} +inline bool FileOptions::java_generic_services() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services) + return java_generic_services_; +} +inline void FileOptions::set_java_generic_services(bool value) { + set_has_java_generic_services(); + java_generic_services_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services) +} + +// optional bool py_generic_services = 18 [default = false]; +inline bool FileOptions::has_py_generic_services() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void FileOptions::set_has_py_generic_services() { + _has_bits_[0] |= 0x00000200u; +} +inline void FileOptions::clear_has_py_generic_services() { + _has_bits_[0] &= ~0x00000200u; +} +inline void FileOptions::clear_py_generic_services() { + py_generic_services_ = false; + clear_has_py_generic_services(); +} +inline bool FileOptions::py_generic_services() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services) + return py_generic_services_; +} +inline void FileOptions::set_py_generic_services(bool value) { + set_has_py_generic_services(); + py_generic_services_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services) +} + +// optional bool deprecated = 23 [default = false]; +inline bool FileOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void FileOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000400u; +} +inline void FileOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000400u; +} +inline void FileOptions::clear_deprecated() { + deprecated_ = false; + clear_has_deprecated(); +} +inline bool FileOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated) + return deprecated_; +} +inline void FileOptions::set_deprecated(bool value) { + set_has_deprecated(); + deprecated_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated) +} + +// optional bool cc_enable_arenas = 31 [default = false]; +inline bool FileOptions::has_cc_enable_arenas() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void FileOptions::set_has_cc_enable_arenas() { + _has_bits_[0] |= 0x00000800u; +} +inline void FileOptions::clear_has_cc_enable_arenas() { + _has_bits_[0] &= ~0x00000800u; +} +inline void FileOptions::clear_cc_enable_arenas() { + cc_enable_arenas_ = false; + clear_has_cc_enable_arenas(); +} +inline bool FileOptions::cc_enable_arenas() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_enable_arenas) + return cc_enable_arenas_; +} +inline void FileOptions::set_cc_enable_arenas(bool value) { + set_has_cc_enable_arenas(); + cc_enable_arenas_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas) +} + +// optional string objc_class_prefix = 36; +inline bool FileOptions::has_objc_class_prefix() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void FileOptions::set_has_objc_class_prefix() { + _has_bits_[0] |= 0x00001000u; +} +inline void FileOptions::clear_has_objc_class_prefix() { + _has_bits_[0] &= ~0x00001000u; +} +inline void FileOptions::clear_objc_class_prefix() { + objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_objc_class_prefix(); +} +inline const ::std::string& FileOptions::objc_class_prefix() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.objc_class_prefix) + return objc_class_prefix_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_objc_class_prefix(const ::std::string& value) { + set_has_objc_class_prefix(); + objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix) +} +inline void FileOptions::set_objc_class_prefix(const char* value) { + set_has_objc_class_prefix(); + objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix) +} +inline void FileOptions::set_objc_class_prefix(const char* value, size_t size) { + set_has_objc_class_prefix(); + objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.objc_class_prefix) +} +inline ::std::string* FileOptions::mutable_objc_class_prefix() { + set_has_objc_class_prefix(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.objc_class_prefix) + return objc_class_prefix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileOptions::release_objc_class_prefix() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix) + clear_has_objc_class_prefix(); + return objc_class_prefix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_allocated_objc_class_prefix(::std::string* objc_class_prefix) { + if (objc_class_prefix != NULL) { + set_has_objc_class_prefix(); + } else { + clear_has_objc_class_prefix(); + } + objc_class_prefix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), objc_class_prefix); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix) +} + +// optional string csharp_namespace = 37; +inline bool FileOptions::has_csharp_namespace() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void FileOptions::set_has_csharp_namespace() { + _has_bits_[0] |= 0x00002000u; +} +inline void FileOptions::clear_has_csharp_namespace() { + _has_bits_[0] &= ~0x00002000u; +} +inline void FileOptions::clear_csharp_namespace() { + csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_csharp_namespace(); +} +inline const ::std::string& FileOptions::csharp_namespace() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace) + return csharp_namespace_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_csharp_namespace(const ::std::string& value) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace) +} +inline void FileOptions::set_csharp_namespace(const char* value) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace) +} +inline void FileOptions::set_csharp_namespace(const char* value, size_t size) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace) +} +inline ::std::string* FileOptions::mutable_csharp_namespace() { + set_has_csharp_namespace(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace) + return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileOptions::release_csharp_namespace() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace) + clear_has_csharp_namespace(); + return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_namespace) { + if (csharp_namespace != NULL) { + set_has_csharp_namespace(); + } else { + clear_has_csharp_namespace(); + } + csharp_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_namespace); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int FileOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void FileOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +FileOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +FileOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// MessageOptions + +// optional bool message_set_wire_format = 1 [default = false]; +inline bool MessageOptions::has_message_set_wire_format() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MessageOptions::set_has_message_set_wire_format() { + _has_bits_[0] |= 0x00000001u; +} +inline void MessageOptions::clear_has_message_set_wire_format() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MessageOptions::clear_message_set_wire_format() { + message_set_wire_format_ = false; + clear_has_message_set_wire_format(); +} +inline bool MessageOptions::message_set_wire_format() const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format) + return message_set_wire_format_; +} +inline void MessageOptions::set_message_set_wire_format(bool value) { + set_has_message_set_wire_format(); + message_set_wire_format_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format) +} + +// optional bool no_standard_descriptor_accessor = 2 [default = false]; +inline bool MessageOptions::has_no_standard_descriptor_accessor() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MessageOptions::set_has_no_standard_descriptor_accessor() { + _has_bits_[0] |= 0x00000002u; +} +inline void MessageOptions::clear_has_no_standard_descriptor_accessor() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MessageOptions::clear_no_standard_descriptor_accessor() { + no_standard_descriptor_accessor_ = false; + clear_has_no_standard_descriptor_accessor(); +} +inline bool MessageOptions::no_standard_descriptor_accessor() const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor) + return no_standard_descriptor_accessor_; +} +inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) { + set_has_no_standard_descriptor_accessor(); + no_standard_descriptor_accessor_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor) +} + +// optional bool deprecated = 3 [default = false]; +inline bool MessageOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MessageOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000004u; +} +inline void MessageOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MessageOptions::clear_deprecated() { + deprecated_ = false; + clear_has_deprecated(); +} +inline bool MessageOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated) + return deprecated_; +} +inline void MessageOptions::set_deprecated(bool value) { + set_has_deprecated(); + deprecated_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated) +} + +// optional bool map_entry = 7; +inline bool MessageOptions::has_map_entry() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MessageOptions::set_has_map_entry() { + _has_bits_[0] |= 0x00000008u; +} +inline void MessageOptions::clear_has_map_entry() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MessageOptions::clear_map_entry() { + map_entry_ = false; + clear_has_map_entry(); +} +inline bool MessageOptions::map_entry() const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.map_entry) + return map_entry_; +} +inline void MessageOptions::set_map_entry(bool value) { + set_has_map_entry(); + map_entry_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.map_entry) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int MessageOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void MessageOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +MessageOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +MessageOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// FieldOptions + +// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; +inline bool FieldOptions::has_ctype() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FieldOptions::set_has_ctype() { + _has_bits_[0] |= 0x00000001u; +} +inline void FieldOptions::clear_has_ctype() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FieldOptions::clear_ctype() { + ctype_ = 0; + clear_has_ctype(); +} +inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype) + return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_); +} +inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) { + assert(::google::protobuf::FieldOptions_CType_IsValid(value)); + set_has_ctype(); + ctype_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype) +} + +// optional bool packed = 2; +inline bool FieldOptions::has_packed() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FieldOptions::set_has_packed() { + _has_bits_[0] |= 0x00000002u; +} +inline void FieldOptions::clear_has_packed() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FieldOptions::clear_packed() { + packed_ = false; + clear_has_packed(); +} +inline bool FieldOptions::packed() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed) + return packed_; +} +inline void FieldOptions::set_packed(bool value) { + set_has_packed(); + packed_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed) +} + +// optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; +inline bool FieldOptions::has_jstype() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FieldOptions::set_has_jstype() { + _has_bits_[0] |= 0x00000004u; +} +inline void FieldOptions::clear_has_jstype() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FieldOptions::clear_jstype() { + jstype_ = 0; + clear_has_jstype(); +} +inline ::google::protobuf::FieldOptions_JSType FieldOptions::jstype() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype) + return static_cast< ::google::protobuf::FieldOptions_JSType >(jstype_); +} +inline void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType value) { + assert(::google::protobuf::FieldOptions_JSType_IsValid(value)); + set_has_jstype(); + jstype_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype) +} + +// optional bool lazy = 5 [default = false]; +inline bool FieldOptions::has_lazy() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FieldOptions::set_has_lazy() { + _has_bits_[0] |= 0x00000008u; +} +inline void FieldOptions::clear_has_lazy() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FieldOptions::clear_lazy() { + lazy_ = false; + clear_has_lazy(); +} +inline bool FieldOptions::lazy() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy) + return lazy_; +} +inline void FieldOptions::set_lazy(bool value) { + set_has_lazy(); + lazy_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy) +} + +// optional bool deprecated = 3 [default = false]; +inline bool FieldOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FieldOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000010u; +} +inline void FieldOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FieldOptions::clear_deprecated() { + deprecated_ = false; + clear_has_deprecated(); +} +inline bool FieldOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated) + return deprecated_; +} +inline void FieldOptions::set_deprecated(bool value) { + set_has_deprecated(); + deprecated_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated) +} + +// optional bool weak = 10 [default = false]; +inline bool FieldOptions::has_weak() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FieldOptions::set_has_weak() { + _has_bits_[0] |= 0x00000020u; +} +inline void FieldOptions::clear_has_weak() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FieldOptions::clear_weak() { + weak_ = false; + clear_has_weak(); +} +inline bool FieldOptions::weak() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak) + return weak_; +} +inline void FieldOptions::set_weak(bool value) { + set_has_weak(); + weak_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int FieldOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void FieldOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +FieldOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +FieldOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// OneofOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int OneofOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void OneofOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& OneofOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* OneofOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* OneofOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +OneofOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.OneofOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +OneofOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.OneofOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// EnumOptions + +// optional bool allow_alias = 2; +inline bool EnumOptions::has_allow_alias() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumOptions::set_has_allow_alias() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumOptions::clear_has_allow_alias() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EnumOptions::clear_allow_alias() { + allow_alias_ = false; + clear_has_allow_alias(); +} +inline bool EnumOptions::allow_alias() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias) + return allow_alias_; +} +inline void EnumOptions::set_allow_alias(bool value) { + set_has_allow_alias(); + allow_alias_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias) +} + +// optional bool deprecated = 3 [default = false]; +inline bool EnumOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void EnumOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000002u; +} +inline void EnumOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000002u; +} +inline void EnumOptions::clear_deprecated() { + deprecated_ = false; + clear_has_deprecated(); +} +inline bool EnumOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated) + return deprecated_; +} +inline void EnumOptions::set_deprecated(bool value) { + set_has_deprecated(); + deprecated_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int EnumOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void EnumOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +EnumOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +EnumOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// EnumValueOptions + +// optional bool deprecated = 1 [default = false]; +inline bool EnumValueOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumValueOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumValueOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EnumValueOptions::clear_deprecated() { + deprecated_ = false; + clear_has_deprecated(); +} +inline bool EnumValueOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated) + return deprecated_; +} +inline void EnumValueOptions::set_deprecated(bool value) { + set_has_deprecated(); + deprecated_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int EnumValueOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void EnumValueOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +EnumValueOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +EnumValueOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// ServiceOptions + +// optional bool deprecated = 33 [default = false]; +inline bool ServiceOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ServiceOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000001u; +} +inline void ServiceOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ServiceOptions::clear_deprecated() { + deprecated_ = false; + clear_has_deprecated(); +} +inline bool ServiceOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated) + return deprecated_; +} +inline void ServiceOptions::set_deprecated(bool value) { + set_has_deprecated(); + deprecated_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int ServiceOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void ServiceOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +ServiceOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +ServiceOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// MethodOptions + +// optional bool deprecated = 33 [default = false]; +inline bool MethodOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MethodOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000001u; +} +inline void MethodOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MethodOptions::clear_deprecated() { + deprecated_ = false; + clear_has_deprecated(); +} +inline bool MethodOptions::deprecated() const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated) + return deprecated_; +} +inline void MethodOptions::set_deprecated(bool value) { + set_has_deprecated(); + deprecated_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated) +} + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int MethodOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void MethodOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +MethodOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +MethodOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + +// UninterpretedOption_NamePart + +// required string name_part = 1; +inline bool UninterpretedOption_NamePart::has_name_part() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void UninterpretedOption_NamePart::set_has_name_part() { + _has_bits_[0] |= 0x00000001u; +} +inline void UninterpretedOption_NamePart::clear_has_name_part() { + _has_bits_[0] &= ~0x00000001u; +} +inline void UninterpretedOption_NamePart::clear_name_part() { + name_part_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name_part(); +} +inline const ::std::string& UninterpretedOption_NamePart::name_part() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part) + return name_part_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) { + set_has_name_part(); + name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part) +} +inline void UninterpretedOption_NamePart::set_name_part(const char* value) { + set_has_name_part(); + name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part) +} +inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) { + set_has_name_part(); + name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part) +} +inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() { + set_has_name_part(); + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part) + return name_part_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* UninterpretedOption_NamePart::release_name_part() { + // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part) + clear_has_name_part(); + return name_part_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) { + if (name_part != NULL) { + set_has_name_part(); + } else { + clear_has_name_part(); + } + name_part_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name_part); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part) +} + +// required bool is_extension = 2; +inline bool UninterpretedOption_NamePart::has_is_extension() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void UninterpretedOption_NamePart::set_has_is_extension() { + _has_bits_[0] |= 0x00000002u; +} +inline void UninterpretedOption_NamePart::clear_has_is_extension() { + _has_bits_[0] &= ~0x00000002u; +} +inline void UninterpretedOption_NamePart::clear_is_extension() { + is_extension_ = false; + clear_has_is_extension(); +} +inline bool UninterpretedOption_NamePart::is_extension() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension) + return is_extension_; +} +inline void UninterpretedOption_NamePart::set_is_extension(bool value) { + set_has_is_extension(); + is_extension_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension) +} + +// ------------------------------------------------------------------- + +// UninterpretedOption + +// repeated .google.protobuf.UninterpretedOption.NamePart name = 2; +inline int UninterpretedOption::name_size() const { + return name_.size(); +} +inline void UninterpretedOption::clear_name() { + name_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name) + return name_.Get(index); +} +inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name) + return name_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() { + // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name) + return name_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* +UninterpretedOption::mutable_name() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name) + return &name_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& +UninterpretedOption::name() const { + // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name) + return name_; +} + +// optional string identifier_value = 3; +inline bool UninterpretedOption::has_identifier_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void UninterpretedOption::set_has_identifier_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void UninterpretedOption::clear_has_identifier_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void UninterpretedOption::clear_identifier_value() { + identifier_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_identifier_value(); +} +inline const ::std::string& UninterpretedOption::identifier_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value) + return identifier_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void UninterpretedOption::set_identifier_value(const ::std::string& value) { + set_has_identifier_value(); + identifier_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value) +} +inline void UninterpretedOption::set_identifier_value(const char* value) { + set_has_identifier_value(); + identifier_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value) +} +inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) { + set_has_identifier_value(); + identifier_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value) +} +inline ::std::string* UninterpretedOption::mutable_identifier_value() { + set_has_identifier_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value) + return identifier_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* UninterpretedOption::release_identifier_value() { + // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value) + clear_has_identifier_value(); + return identifier_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) { + if (identifier_value != NULL) { + set_has_identifier_value(); + } else { + clear_has_identifier_value(); + } + identifier_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), identifier_value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value) +} + +// optional uint64 positive_int_value = 4; +inline bool UninterpretedOption::has_positive_int_value() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void UninterpretedOption::set_has_positive_int_value() { + _has_bits_[0] |= 0x00000004u; +} +inline void UninterpretedOption::clear_has_positive_int_value() { + _has_bits_[0] &= ~0x00000004u; +} +inline void UninterpretedOption::clear_positive_int_value() { + positive_int_value_ = GOOGLE_ULONGLONG(0); + clear_has_positive_int_value(); +} +inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value) + return positive_int_value_; +} +inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) { + set_has_positive_int_value(); + positive_int_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value) +} + +// optional int64 negative_int_value = 5; +inline bool UninterpretedOption::has_negative_int_value() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void UninterpretedOption::set_has_negative_int_value() { + _has_bits_[0] |= 0x00000008u; +} +inline void UninterpretedOption::clear_has_negative_int_value() { + _has_bits_[0] &= ~0x00000008u; +} +inline void UninterpretedOption::clear_negative_int_value() { + negative_int_value_ = GOOGLE_LONGLONG(0); + clear_has_negative_int_value(); +} +inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value) + return negative_int_value_; +} +inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) { + set_has_negative_int_value(); + negative_int_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value) +} + +// optional double double_value = 6; +inline bool UninterpretedOption::has_double_value() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void UninterpretedOption::set_has_double_value() { + _has_bits_[0] |= 0x00000010u; +} +inline void UninterpretedOption::clear_has_double_value() { + _has_bits_[0] &= ~0x00000010u; +} +inline void UninterpretedOption::clear_double_value() { + double_value_ = 0; + clear_has_double_value(); +} +inline double UninterpretedOption::double_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value) + return double_value_; +} +inline void UninterpretedOption::set_double_value(double value) { + set_has_double_value(); + double_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value) +} + +// optional bytes string_value = 7; +inline bool UninterpretedOption::has_string_value() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void UninterpretedOption::set_has_string_value() { + _has_bits_[0] |= 0x00000020u; +} +inline void UninterpretedOption::clear_has_string_value() { + _has_bits_[0] &= ~0x00000020u; +} +inline void UninterpretedOption::clear_string_value() { + string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_string_value(); +} +inline const ::std::string& UninterpretedOption::string_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value) + return string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void UninterpretedOption::set_string_value(const ::std::string& value) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value) +} +inline void UninterpretedOption::set_string_value(const char* value) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value) +} +inline void UninterpretedOption::set_string_value(const void* value, size_t size) { + set_has_string_value(); + string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value) +} +inline ::std::string* UninterpretedOption::mutable_string_value() { + set_has_string_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value) + return string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* UninterpretedOption::release_string_value() { + // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value) + clear_has_string_value(); + return string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void UninterpretedOption::set_allocated_string_value(::std::string* string_value) { + if (string_value != NULL) { + set_has_string_value(); + } else { + clear_has_string_value(); + } + string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value) +} + +// optional string aggregate_value = 8; +inline bool UninterpretedOption::has_aggregate_value() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void UninterpretedOption::set_has_aggregate_value() { + _has_bits_[0] |= 0x00000040u; +} +inline void UninterpretedOption::clear_has_aggregate_value() { + _has_bits_[0] &= ~0x00000040u; +} +inline void UninterpretedOption::clear_aggregate_value() { + aggregate_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_aggregate_value(); +} +inline const ::std::string& UninterpretedOption::aggregate_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value) + return aggregate_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) { + set_has_aggregate_value(); + aggregate_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value) +} +inline void UninterpretedOption::set_aggregate_value(const char* value) { + set_has_aggregate_value(); + aggregate_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value) +} +inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) { + set_has_aggregate_value(); + aggregate_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value) +} +inline ::std::string* UninterpretedOption::mutable_aggregate_value() { + set_has_aggregate_value(); + // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value) + return aggregate_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* UninterpretedOption::release_aggregate_value() { + // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value) + clear_has_aggregate_value(); + return aggregate_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) { + if (aggregate_value != NULL) { + set_has_aggregate_value(); + } else { + clear_has_aggregate_value(); + } + aggregate_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), aggregate_value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value) +} + +// ------------------------------------------------------------------- + +// SourceCodeInfo_Location + +// repeated int32 path = 1 [packed = true]; +inline int SourceCodeInfo_Location::path_size() const { + return path_.size(); +} +inline void SourceCodeInfo_Location::clear_path() { + path_.Clear(); +} +inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.path) + return path_.Get(index); +} +inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) { + path_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path) +} +inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) { + path_.Add(value); + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SourceCodeInfo_Location::path() const { + // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path) + return path_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SourceCodeInfo_Location::mutable_path() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.path) + return &path_; +} + +// repeated int32 span = 2 [packed = true]; +inline int SourceCodeInfo_Location::span_size() const { + return span_.size(); +} +inline void SourceCodeInfo_Location::clear_span() { + span_.Clear(); +} +inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.span) + return span_.Get(index); +} +inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) { + span_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span) +} +inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) { + span_.Add(value); + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SourceCodeInfo_Location::span() const { + // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span) + return span_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SourceCodeInfo_Location::mutable_span() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.span) + return &span_; +} + +// optional string leading_comments = 3; +inline bool SourceCodeInfo_Location::has_leading_comments() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void SourceCodeInfo_Location::set_has_leading_comments() { + _has_bits_[0] |= 0x00000004u; +} +inline void SourceCodeInfo_Location::clear_has_leading_comments() { + _has_bits_[0] &= ~0x00000004u; +} +inline void SourceCodeInfo_Location::clear_leading_comments() { + leading_comments_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_leading_comments(); +} +inline const ::std::string& SourceCodeInfo_Location::leading_comments() const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments) + return leading_comments_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SourceCodeInfo_Location::set_leading_comments(const ::std::string& value) { + set_has_leading_comments(); + leading_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments) +} +inline void SourceCodeInfo_Location::set_leading_comments(const char* value) { + set_has_leading_comments(); + leading_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments) +} +inline void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) { + set_has_leading_comments(); + leading_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments) +} +inline ::std::string* SourceCodeInfo_Location::mutable_leading_comments() { + set_has_leading_comments(); + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments) + return leading_comments_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* SourceCodeInfo_Location::release_leading_comments() { + // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments) + clear_has_leading_comments(); + return leading_comments_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SourceCodeInfo_Location::set_allocated_leading_comments(::std::string* leading_comments) { + if (leading_comments != NULL) { + set_has_leading_comments(); + } else { + clear_has_leading_comments(); + } + leading_comments_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), leading_comments); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments) +} + +// optional string trailing_comments = 4; +inline bool SourceCodeInfo_Location::has_trailing_comments() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void SourceCodeInfo_Location::set_has_trailing_comments() { + _has_bits_[0] |= 0x00000008u; +} +inline void SourceCodeInfo_Location::clear_has_trailing_comments() { + _has_bits_[0] &= ~0x00000008u; +} +inline void SourceCodeInfo_Location::clear_trailing_comments() { + trailing_comments_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_trailing_comments(); +} +inline const ::std::string& SourceCodeInfo_Location::trailing_comments() const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments) + return trailing_comments_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SourceCodeInfo_Location::set_trailing_comments(const ::std::string& value) { + set_has_trailing_comments(); + trailing_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments) +} +inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) { + set_has_trailing_comments(); + trailing_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments) +} +inline void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) { + set_has_trailing_comments(); + trailing_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments) +} +inline ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() { + set_has_trailing_comments(); + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments) + return trailing_comments_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* SourceCodeInfo_Location::release_trailing_comments() { + // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments) + clear_has_trailing_comments(); + return trailing_comments_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::string* trailing_comments) { + if (trailing_comments != NULL) { + set_has_trailing_comments(); + } else { + clear_has_trailing_comments(); + } + trailing_comments_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), trailing_comments); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments) +} + +// repeated string leading_detached_comments = 6; +inline int SourceCodeInfo_Location::leading_detached_comments_size() const { + return leading_detached_comments_.size(); +} +inline void SourceCodeInfo_Location::clear_leading_detached_comments() { + leading_detached_comments_.Clear(); +} +inline const ::std::string& SourceCodeInfo_Location::leading_detached_comments(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return leading_detached_comments_.Get(index); +} +inline ::std::string* SourceCodeInfo_Location::mutable_leading_detached_comments(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return leading_detached_comments_.Mutable(index); +} +inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + leading_detached_comments_.Mutable(index)->assign(value); +} +inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) { + leading_detached_comments_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value, size_t size) { + leading_detached_comments_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline ::std::string* SourceCodeInfo_Location::add_leading_detached_comments() { + // @@protoc_insertion_point(field_add_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return leading_detached_comments_.Add(); +} +inline void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::string& value) { + leading_detached_comments_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) { + leading_detached_comments_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value, size_t size) { + leading_detached_comments_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +SourceCodeInfo_Location::leading_detached_comments() const { + // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return leading_detached_comments_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +SourceCodeInfo_Location::mutable_leading_detached_comments() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) + return &leading_detached_comments_; +} + +// ------------------------------------------------------------------- + +// SourceCodeInfo + +// repeated .google.protobuf.SourceCodeInfo.Location location = 1; +inline int SourceCodeInfo::location_size() const { + return location_.size(); +} +inline void SourceCodeInfo::clear_location() { + location_.Clear(); +} +inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location) + return location_.Get(index); +} +inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location) + return location_.Mutable(index); +} +inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() { + // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location) + return location_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >* +SourceCodeInfo::mutable_location() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location) + return &location_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >& +SourceCodeInfo::location() const { + // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location) + return location_; +} + +// ------------------------------------------------------------------- + +// GeneratedCodeInfo_Annotation + +// repeated int32 path = 1 [packed = true]; +inline int GeneratedCodeInfo_Annotation::path_size() const { + return path_.size(); +} +inline void GeneratedCodeInfo_Annotation::clear_path() { + path_.Clear(); +} +inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::path(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.path) + return path_.Get(index); +} +inline void GeneratedCodeInfo_Annotation::set_path(int index, ::google::protobuf::int32 value) { + path_.Set(index, value); + // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.path) +} +inline void GeneratedCodeInfo_Annotation::add_path(::google::protobuf::int32 value) { + path_.Add(value); + // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.Annotation.path) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +GeneratedCodeInfo_Annotation::path() const { + // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.Annotation.path) + return path_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +GeneratedCodeInfo_Annotation::mutable_path() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.Annotation.path) + return &path_; +} + +// optional string source_file = 2; +inline bool GeneratedCodeInfo_Annotation::has_source_file() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void GeneratedCodeInfo_Annotation::set_has_source_file() { + _has_bits_[0] |= 0x00000002u; +} +inline void GeneratedCodeInfo_Annotation::clear_has_source_file() { + _has_bits_[0] &= ~0x00000002u; +} +inline void GeneratedCodeInfo_Annotation::clear_source_file() { + source_file_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_source_file(); +} +inline const ::std::string& GeneratedCodeInfo_Annotation::source_file() const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.source_file) + return source_file_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void GeneratedCodeInfo_Annotation::set_source_file(const ::std::string& value) { + set_has_source_file(); + source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file) +} +inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value) { + set_has_source_file(); + source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file) +} +inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value, size_t size) { + set_has_source_file(); + source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.GeneratedCodeInfo.Annotation.source_file) +} +inline ::std::string* GeneratedCodeInfo_Annotation::mutable_source_file() { + set_has_source_file(); + // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.Annotation.source_file) + return source_file_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* GeneratedCodeInfo_Annotation::release_source_file() { + // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file) + clear_has_source_file(); + return source_file_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(::std::string* source_file) { + if (source_file != NULL) { + set_has_source_file(); + } else { + clear_has_source_file(); + } + source_file_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), source_file); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file) +} + +// optional int32 begin = 3; +inline bool GeneratedCodeInfo_Annotation::has_begin() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void GeneratedCodeInfo_Annotation::set_has_begin() { + _has_bits_[0] |= 0x00000004u; +} +inline void GeneratedCodeInfo_Annotation::clear_has_begin() { + _has_bits_[0] &= ~0x00000004u; +} +inline void GeneratedCodeInfo_Annotation::clear_begin() { + begin_ = 0; + clear_has_begin(); +} +inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::begin() const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.begin) + return begin_; +} +inline void GeneratedCodeInfo_Annotation::set_begin(::google::protobuf::int32 value) { + set_has_begin(); + begin_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin) +} + +// optional int32 end = 4; +inline bool GeneratedCodeInfo_Annotation::has_end() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void GeneratedCodeInfo_Annotation::set_has_end() { + _has_bits_[0] |= 0x00000008u; +} +inline void GeneratedCodeInfo_Annotation::clear_has_end() { + _has_bits_[0] &= ~0x00000008u; +} +inline void GeneratedCodeInfo_Annotation::clear_end() { + end_ = 0; + clear_has_end(); +} +inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.end) + return end_; +} +inline void GeneratedCodeInfo_Annotation::set_end(::google::protobuf::int32 value) { + set_has_end(); + end_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end) +} + +// ------------------------------------------------------------------- + +// GeneratedCodeInfo + +// repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; +inline int GeneratedCodeInfo::annotation_size() const { + return annotation_.size(); +} +inline void GeneratedCodeInfo::clear_annotation() { + annotation_.Clear(); +} +inline const ::google::protobuf::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::annotation(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.annotation) + return annotation_.Get(index); +} +inline ::google::protobuf::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::mutable_annotation(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.annotation) + return annotation_.Mutable(index); +} +inline ::google::protobuf::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::add_annotation() { + // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.annotation) + return annotation_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >* +GeneratedCodeInfo::mutable_annotation() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.annotation) + return &annotation_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >& +GeneratedCodeInfo::annotation() const { + // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.annotation) + return annotation_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Type> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() { + return ::google::protobuf::FieldDescriptorProto_Type_descriptor(); +} +template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Label> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() { + return ::google::protobuf::FieldDescriptorProto_Label_descriptor(); +} +template <> struct is_proto_enum< ::google::protobuf::FileOptions_OptimizeMode> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() { + return ::google::protobuf::FileOptions_OptimizeMode_descriptor(); +} +template <> struct is_proto_enum< ::google::protobuf::FieldOptions_CType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() { + return ::google::protobuf::FieldOptions_CType_descriptor(); +} +template <> struct is_proto_enum< ::google::protobuf::FieldOptions_JSType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_JSType>() { + return ::google::protobuf::FieldOptions_JSType_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/descriptor.proto b/thirdparty/linux/include/google/protobuf/descriptor.proto new file mode 100644 index 0000000..28410d4 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/descriptor.proto @@ -0,0 +1,813 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; +option go_package = "descriptor"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option java_generate_equals_and_hash = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; + optional int32 end = 2; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + TYPE_GROUP = 10; // Tag-delimited aggregate. + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + }; + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + // TODO(sanjay): Should we add LABEL_MAP? + }; + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default=false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default=false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + optional string java_outer_classname = 8; + + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default=false]; + + // If set true, then the Java code generator will generate equals() and + // hashCode() methods for all messages defined in the .proto file. + // This increases generated code size, potentially substantially for large + // protos, which may harm a memory-constrained application. + // - In the full runtime this is a speed optimization, as the + // AbstractMessage base class includes reflection-based implementations of + // these methods. + // - In the lite runtime, setting this option changes the semantics of + // equals() and hashCode() to more closely match those of the full runtime; + // the generated methods compute their results based on field values rather + // than object identity. (Implementations should not assume that hashcodes + // will be consistent across runtimes or versions of the protocol compiler.) + optional bool java_generate_equals_and_hash = 20 [default=false]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default=false]; + + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default=SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default=false]; + optional bool java_generic_services = 17 [default=false]; + optional bool py_generic_services = 18 [default=false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default=false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default=false]; + + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default=false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default=false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default=false]; + + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + optional bool map_entry = 7; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + optional bool packed = 2; + + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). By default these types are + // represented as JavaScript strings. This avoids loss of precision that can + // happen when a large value is converted to a floating point JavaScript + // numbers. Specifying JS_NUMBER for the jstype causes the generated + // JavaScript code to use the JavaScript "number" type instead of strings. + // This option is an enum to permit additional types to be added, + // e.g. goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outher message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + optional bool lazy = 5 [default=false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default=false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default=false]; + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message OneofOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents + // "foo.(bar.baz).qux". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed=true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed=true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed=true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + } +} diff --git a/thirdparty/linux/include/google/protobuf/descriptor_database.h b/thirdparty/linux/include/google/protobuf/descriptor_database.h new file mode 100644 index 0000000..86002d5 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/descriptor_database.h @@ -0,0 +1,369 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Interface for manipulating databases of descriptors. + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ +#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ + +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + +// Defined in this file. +class DescriptorDatabase; +class SimpleDescriptorDatabase; +class EncodedDescriptorDatabase; +class DescriptorPoolDatabase; +class MergedDescriptorDatabase; + +// Abstract interface for a database of descriptors. +// +// This is useful if you want to create a DescriptorPool which loads +// descriptors on-demand from some sort of large database. If the database +// is large, it may be inefficient to enumerate every .proto file inside it +// calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool +// can be created which wraps a DescriptorDatabase and only builds particular +// descriptors when they are needed. +class LIBPROTOBUF_EXPORT DescriptorDatabase { + public: + inline DescriptorDatabase() {} + virtual ~DescriptorDatabase(); + + // Find a file by file name. Fills in in *output and returns true if found. + // Otherwise, returns false, leaving the contents of *output undefined. + virtual bool FindFileByName(const string& filename, + FileDescriptorProto* output) = 0; + + // Find the file that declares the given fully-qualified symbol name. + // If found, fills in *output and returns true, otherwise returns false + // and leaves *output undefined. + virtual bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output) = 0; + + // Find the file which defines an extension extending the given message type + // with the given field number. If found, fills in *output and returns true, + // otherwise returns false and leaves *output undefined. containing_type + // must be a fully-qualified type name. + virtual bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output) = 0; + + // Finds the tag numbers used by all known extensions of + // extendee_type, and appends them to output in an undefined + // order. This method is best-effort: it's not guaranteed that the + // database will find all extensions, and it's not guaranteed that + // FindFileContainingExtension will return true on all of the found + // numbers. Returns true if the search was successful, otherwise + // returns false and leaves output unchanged. + // + // This method has a default implementation that always returns + // false. + virtual bool FindAllExtensionNumbers(const string& /* extendee_type */, + vector* /* output */) { + return false; + } + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase); +}; + +// A DescriptorDatabase into which you can insert files manually. +// +// FindFileContainingSymbol() is fully-implemented. When you add a file, its +// symbols will be indexed for this purpose. Note that the implementation +// may return false positives, but only if it isn't possible for the symbol +// to be defined in any other file. In particular, if a file defines a symbol +// "Foo", then searching for "Foo.[anything]" will match that file. This way, +// the database does not need to aggressively index all children of a symbol. +// +// FindFileContainingExtension() is mostly-implemented. It works if and only +// if the original FieldDescriptorProto defining the extension has a +// fully-qualified type name in its "extendee" field (i.e. starts with a '.'). +// If the extendee is a relative name, SimpleDescriptorDatabase will not +// attempt to resolve the type, so it will not know what type the extension is +// extending. Therefore, calling FindFileContainingExtension() with the +// extension's containing type will never actually find that extension. Note +// that this is an unlikely problem, as all FileDescriptorProtos created by the +// protocol compiler (as well as ones created by calling +// FileDescriptor::CopyTo()) will always use fully-qualified names for all +// types. You only need to worry if you are constructing FileDescriptorProtos +// yourself, or are calling compiler::Parser directly. +class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { + public: + SimpleDescriptorDatabase(); + ~SimpleDescriptorDatabase(); + + // Adds the FileDescriptorProto to the database, making a copy. The object + // can be deleted after Add() returns. Returns false if the file conflicted + // with a file already in the database, in which case an error will have + // been written to GOOGLE_LOG(ERROR). + bool Add(const FileDescriptorProto& file); + + // Adds the FileDescriptorProto to the database and takes ownership of it. + bool AddAndOwn(const FileDescriptorProto* file); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + bool FindAllExtensionNumbers(const string& extendee_type, + vector* output); + + private: + // So that it can use DescriptorIndex. + friend class EncodedDescriptorDatabase; + + // An index mapping file names, symbol names, and extension numbers to + // some sort of values. + template + class DescriptorIndex { + public: + // Helpers to recursively add particular descriptors and all their contents + // to the index. + bool AddFile(const FileDescriptorProto& file, + Value value); + bool AddSymbol(const string& name, Value value); + bool AddNestedExtensions(const DescriptorProto& message_type, + Value value); + bool AddExtension(const FieldDescriptorProto& field, + Value value); + + Value FindFile(const string& filename); + Value FindSymbol(const string& name); + Value FindExtension(const string& containing_type, int field_number); + bool FindAllExtensionNumbers(const string& containing_type, + vector* output); + + private: + map by_name_; + map by_symbol_; + map, Value> by_extension_; + + // Invariant: The by_symbol_ map does not contain any symbols which are + // prefixes of other symbols in the map. For example, "foo.bar" is a + // prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz"). + // + // This invariant is important because it means that given a symbol name, + // we can find a key in the map which is a prefix of the symbol in O(lg n) + // time, and we know that there is at most one such key. + // + // The prefix lookup algorithm works like so: + // 1) Find the last key in the map which is less than or equal to the + // search key. + // 2) If the found key is a prefix of the search key, then return it. + // Otherwise, there is no match. + // + // I am sure this algorithm has been described elsewhere, but since I + // wasn't able to find it quickly I will instead prove that it works + // myself. The key to the algorithm is that if a match exists, step (1) + // will find it. Proof: + // 1) Define the "search key" to be the key we are looking for, the "found + // key" to be the key found in step (1), and the "match key" to be the + // key which actually matches the serach key (i.e. the key we're trying + // to find). + // 2) The found key must be less than or equal to the search key by + // definition. + // 3) The match key must also be less than or equal to the search key + // (because it is a prefix). + // 4) The match key cannot be greater than the found key, because if it + // were, then step (1) of the algorithm would have returned the match + // key instead (since it finds the *greatest* key which is less than or + // equal to the search key). + // 5) Therefore, the found key must be between the match key and the search + // key, inclusive. + // 6) Since the search key must be a sub-symbol of the match key, if it is + // not equal to the match key, then search_key[match_key.size()] must + // be '.'. + // 7) Since '.' sorts before any other character that is valid in a symbol + // name, then if the found key is not equal to the match key, then + // found_key[match_key.size()] must also be '.', because any other value + // would make it sort after the search key. + // 8) Therefore, if the found key is not equal to the match key, then the + // found key must be a sub-symbol of the match key. However, this would + // contradict our map invariant which says that no symbol in the map is + // a sub-symbol of any other. + // 9) Therefore, the found key must match the match key. + // + // The above proof assumes the match key exists. In the case that the + // match key does not exist, then step (1) will return some other symbol. + // That symbol cannot be a super-symbol of the search key since if it were, + // then it would be a match, and we're assuming the match key doesn't exist. + // Therefore, step 2 will correctly return no match. + + // Find the last entry in the by_symbol_ map whose key is less than or + // equal to the given name. + typename map::iterator FindLastLessOrEqual( + const string& name); + + // True if either the arguments are equal or super_symbol identifies a + // parent symbol of sub_symbol (e.g. "foo.bar" is a parent of + // "foo.bar.baz", but not a parent of "foo.barbaz"). + bool IsSubSymbol(const string& sub_symbol, const string& super_symbol); + + // Returns true if and only if all characters in the name are alphanumerics, + // underscores, or periods. + bool ValidateSymbolName(const string& name); + }; + + + DescriptorIndex index_; + vector files_to_delete_; + + // If file is non-NULL, copy it into *output and return true, otherwise + // return false. + bool MaybeCopy(const FileDescriptorProto* file, + FileDescriptorProto* output); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase); +}; + +// Very similar to SimpleDescriptorDatabase, but stores all the descriptors +// as raw bytes and generally tries to use as little memory as possible. +// +// The same caveats regarding FindFileContainingExtension() apply as with +// SimpleDescriptorDatabase. +class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { + public: + EncodedDescriptorDatabase(); + ~EncodedDescriptorDatabase(); + + // Adds the FileDescriptorProto to the database. The descriptor is provided + // in encoded form. The database does not make a copy of the bytes, nor + // does it take ownership; it's up to the caller to make sure the bytes + // remain valid for the life of the database. Returns false and logs an error + // if the bytes are not a valid FileDescriptorProto or if the file conflicted + // with a file already in the database. + bool Add(const void* encoded_file_descriptor, int size); + + // Like Add(), but makes a copy of the data, so that the caller does not + // need to keep it around. + bool AddCopy(const void* encoded_file_descriptor, int size); + + // Like FindFileContainingSymbol but returns only the name of the file. + bool FindNameOfFileContainingSymbol(const string& symbol_name, + string* output); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + bool FindAllExtensionNumbers(const string& extendee_type, + vector* output); + + private: + SimpleDescriptorDatabase::DescriptorIndex > index_; + vector files_to_delete_; + + // If encoded_file.first is non-NULL, parse the data into *output and return + // true, otherwise return false. + bool MaybeParse(pair encoded_file, + FileDescriptorProto* output); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase); +}; + +// A DescriptorDatabase that fetches files from a given pool. +class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase { + public: + explicit DescriptorPoolDatabase(const DescriptorPool& pool); + ~DescriptorPoolDatabase(); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + bool FindAllExtensionNumbers(const string& extendee_type, + vector* output); + + private: + const DescriptorPool& pool_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase); +}; + +// A DescriptorDatabase that wraps two or more others. It first searches the +// first database and, if that fails, tries the second, and so on. +class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { + public: + // Merge just two databases. The sources remain property of the caller. + MergedDescriptorDatabase(DescriptorDatabase* source1, + DescriptorDatabase* source2); + // Merge more than two databases. The sources remain property of the caller. + // The vector may be deleted after the constructor returns but the + // DescriptorDatabases need to stick around. + explicit MergedDescriptorDatabase(const vector& sources); + ~MergedDescriptorDatabase(); + + // implements DescriptorDatabase ----------------------------------- + bool FindFileByName(const string& filename, + FileDescriptorProto* output); + bool FindFileContainingSymbol(const string& symbol_name, + FileDescriptorProto* output); + bool FindFileContainingExtension(const string& containing_type, + int field_number, + FileDescriptorProto* output); + // Merges the results of calling all databases. Returns true iff any + // of the databases returned true. + bool FindAllExtensionNumbers(const string& extendee_type, + vector* output); + + + private: + vector sources_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ diff --git a/thirdparty/linux/include/google/protobuf/duration.pb.h b/thirdparty/linux/include/google/protobuf/duration.pb.h new file mode 100644 index 0000000..ad47963 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/duration.pb.h @@ -0,0 +1,176 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/duration.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fduration_2eproto(); + +class Duration; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ { + public: + Duration(); + virtual ~Duration(); + + Duration(const Duration& from); + + inline Duration& operator=(const Duration& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Duration& default_instance(); + + void Swap(Duration* other); + + // implements Message ---------------------------------------------- + + inline Duration* New() const { return New(NULL); } + + Duration* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Duration& from); + void MergeFrom(const Duration& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Duration* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 seconds = 1; + void clear_seconds(); + static const int kSecondsFieldNumber = 1; + ::google::protobuf::int64 seconds() const; + void set_seconds(::google::protobuf::int64 value); + + // optional int32 nanos = 2; + void clear_nanos(); + static const int kNanosFieldNumber = 2; + ::google::protobuf::int32 nanos() const; + void set_nanos(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Duration) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int64 seconds_; + ::google::protobuf::int32 nanos_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fduration_2eproto(); + + void InitAsDefaultInstance(); + static Duration* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Duration + +// optional int64 seconds = 1; +inline void Duration::clear_seconds() { + seconds_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 Duration::seconds() const { + // @@protoc_insertion_point(field_get:google.protobuf.Duration.seconds) + return seconds_; +} +inline void Duration::set_seconds(::google::protobuf::int64 value) { + + seconds_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Duration.seconds) +} + +// optional int32 nanos = 2; +inline void Duration::clear_nanos() { + nanos_ = 0; +} +inline ::google::protobuf::int32 Duration::nanos() const { + // @@protoc_insertion_point(field_get:google.protobuf.Duration.nanos) + return nanos_; +} +inline void Duration::set_nanos(::google::protobuf::int32 value) { + + nanos_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Duration.nanos) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/duration.proto b/thirdparty/linux/include/google/protobuf/duration.proto new file mode 100644 index 0000000..96c1796 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/duration.proto @@ -0,0 +1,98 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/duration"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DurationProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (durations.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// +message Duration { + + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} diff --git a/thirdparty/linux/include/google/protobuf/dynamic_message.h b/thirdparty/linux/include/google/protobuf/dynamic_message.h new file mode 100644 index 0000000..f74cd7d --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/dynamic_message.h @@ -0,0 +1,152 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines an implementation of Message which can emulate types which are not +// known at compile-time. + +#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ +#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ + +#include +#ifndef _SHARED_PTR_H +#include +#endif + +#include +#include +#include + +namespace google { +namespace protobuf { + +// Defined in other files. +class Descriptor; // descriptor.h +class DescriptorPool; // descriptor.h + +// Constructs implementations of Message which can emulate types which are not +// known at compile-time. +// +// Sometimes you want to be able to manipulate protocol types that you don't +// know about at compile time. It would be nice to be able to construct +// a Message object which implements the message type given by any arbitrary +// Descriptor. DynamicMessage provides this. +// +// As it turns out, a DynamicMessage needs to construct extra +// information about its type in order to operate. Most of this information +// can be shared between all DynamicMessages of the same type. But, caching +// this information in some sort of global map would be a bad idea, since +// the cached information for a particular descriptor could outlive the +// descriptor itself. To avoid this problem, DynamicMessageFactory +// encapsulates this "cache". All DynamicMessages of the same type created +// from the same factory will share the same support data. Any Descriptors +// used with a particular factory must outlive the factory. +class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { + public: + // Construct a DynamicMessageFactory that will search for extensions in + // the DescriptorPool in which the extendee is defined. + DynamicMessageFactory(); + + // Construct a DynamicMessageFactory that will search for extensions in + // the given DescriptorPool. + // + // DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the + // parser to look for extensions in an alternate pool. However, note that + // this is almost never what you want to do. Almost all users should use + // the zero-arg constructor. + DynamicMessageFactory(const DescriptorPool* pool); + + ~DynamicMessageFactory(); + + // Call this to tell the DynamicMessageFactory that if it is given a + // Descriptor d for which: + // d->file()->pool() == DescriptorPool::generated_pool(), + // then it should delegate to MessageFactory::generated_factory() instead + // of constructing a dynamic implementation of the message. In theory there + // is no down side to doing this, so it may become the default in the future. + void SetDelegateToGeneratedFactory(bool enable) { + delegate_to_generated_factory_ = enable; + } + + // implements MessageFactory --------------------------------------- + + // Given a Descriptor, constructs the default (prototype) Message of that + // type. You can then call that message's New() method to construct a + // mutable message of that type. + // + // Calling this method twice with the same Descriptor returns the same + // object. The returned object remains property of the factory and will + // be destroyed when the factory is destroyed. Also, any objects created + // by calling the prototype's New() method share some data with the + // prototype, so these must be destroyed before the DynamicMessageFactory + // is destroyed. + // + // The given descriptor must outlive the returned message, and hence must + // outlive the DynamicMessageFactory. + // + // The method is thread-safe. + const Message* GetPrototype(const Descriptor* type); + + private: + const DescriptorPool* pool_; + bool delegate_to_generated_factory_; + + // This struct just contains a hash_map. We can't #include from + // this header due to hacks needed for hash_map portability in the open source + // release. Namely, stubs/hash.h, which defines hash_map portably, is not a + // public header (for good reason), but dynamic_message.h is, and public + // headers may only #include other public headers. + struct PrototypeMap; + google::protobuf::scoped_ptr prototypes_; + mutable Mutex prototypes_mutex_; + + friend class DynamicMessage; + const Message* GetPrototypeNoLock(const Descriptor* type); + + // Construct default oneof instance for reflection usage if oneof + // is defined. + static void ConstructDefaultOneofInstance(const Descriptor* type, + const int offsets[], + void* default_oneof_instance); + // Delete default oneof instance. Called by ~DynamicMessageFactory. + static void DeleteDefaultOneofInstance(const Descriptor* type, + const int offsets[], + void* default_oneof_instance); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ diff --git a/thirdparty/linux/include/google/protobuf/empty.pb.h b/thirdparty/linux/include/google/protobuf/empty.pb.h new file mode 100644 index 0000000..8e78733 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/empty.pb.h @@ -0,0 +1,147 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/empty.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto(); + +class Empty; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { + public: + Empty(); + virtual ~Empty(); + + Empty(const Empty& from); + + inline Empty& operator=(const Empty& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const Empty& default_instance(); + + void UnsafeArenaSwap(Empty* other); + void Swap(Empty* other); + + // implements Message ---------------------------------------------- + + inline Empty* New() const { return New(NULL); } + + Empty* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Empty& from); + void MergeFrom(const Empty& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Empty* other); + protected: + explicit Empty(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:google.protobuf.Empty) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto(); + + void InitAsDefaultInstance(); + static Empty* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Empty + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/empty.proto b/thirdparty/linux/include/google/protobuf/empty.proto new file mode 100644 index 0000000..37f4cd1 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/empty.proto @@ -0,0 +1,53 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/empty"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "EmptyProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// A generic empty message that you can re-use to avoid defining duplicated +// empty messages in your APIs. A typical example is to use it as the request +// or the response type of an API method. For instance: +// +// service Foo { +// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +// } +// +// The JSON representation for `Empty` is empty JSON object `{}`. +message Empty {} diff --git a/thirdparty/linux/include/google/protobuf/extension_set.h b/thirdparty/linux/include/google/protobuf/extension_set.h new file mode 100644 index 0000000..3e1d1ef --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/extension_set.h @@ -0,0 +1,1318 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__ +#define GOOGLE_PROTOBUF_EXTENSION_SET_H__ + +#include +#include +#include +#include + + +#include +#include +#include + +#include + +namespace google { + +namespace protobuf { + class Arena; + class Descriptor; // descriptor.h + class FieldDescriptor; // descriptor.h + class DescriptorPool; // descriptor.h + class MessageLite; // message_lite.h + class Message; // message.h + class MessageFactory; // message.h + class UnknownFieldSet; // unknown_field_set.h + namespace io { + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h + } + namespace internal { + class FieldSkipper; // wire_format_lite.h + } +} + +namespace protobuf { +namespace internal { + +// Used to store values of type WireFormatLite::FieldType without having to +// #include wire_format_lite.h. Also, ensures that we use only one byte to +// store these values, which is important to keep the layout of +// ExtensionSet::Extension small. +typedef uint8 FieldType; + +// A function which, given an integer value, returns true if the number +// matches one of the defined values for the corresponding enum type. This +// is used with RegisterEnumExtension, below. +typedef bool EnumValidityFunc(int number); + +// Version of the above which takes an argument. This is needed to deal with +// extensions that are not compiled in. +typedef bool EnumValidityFuncWithArg(const void* arg, int number); + +// Information about a registered extension. +struct ExtensionInfo { + inline ExtensionInfo() {} + inline ExtensionInfo(FieldType type_param, bool isrepeated, bool ispacked) + : type(type_param), is_repeated(isrepeated), is_packed(ispacked), + descriptor(NULL) {} + + FieldType type; + bool is_repeated; + bool is_packed; + + struct EnumValidityCheck { + EnumValidityFuncWithArg* func; + const void* arg; + }; + + union { + EnumValidityCheck enum_validity_check; + const MessageLite* message_prototype; + }; + + // The descriptor for this extension, if one exists and is known. May be + // NULL. Must not be NULL if the descriptor for the extension does not + // live in the same pool as the descriptor for the containing type. + const FieldDescriptor* descriptor; +}; + +// Abstract interface for an object which looks up extension definitions. Used +// when parsing. +class LIBPROTOBUF_EXPORT ExtensionFinder { + public: + virtual ~ExtensionFinder(); + + // Find the extension with the given containing type and number. + virtual bool Find(int number, ExtensionInfo* output) = 0; +}; + +// Implementation of ExtensionFinder which finds extensions defined in .proto +// files which have been compiled into the binary. +class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder { + public: + GeneratedExtensionFinder(const MessageLite* containing_type) + : containing_type_(containing_type) {} + virtual ~GeneratedExtensionFinder() {} + + // Returns true and fills in *output if found, otherwise returns false. + virtual bool Find(int number, ExtensionInfo* output); + + private: + const MessageLite* containing_type_; +}; + +// A FieldSkipper used for parsing MessageSet. +class MessageSetFieldSkipper; + +// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for +// finding extensions from a DescriptorPool. + +// This is an internal helper class intended for use within the protocol buffer +// library and generated classes. Clients should not use it directly. Instead, +// use the generated accessors such as GetExtension() of the class being +// extended. +// +// This class manages extensions for a protocol message object. The +// message's HasExtension(), GetExtension(), MutableExtension(), and +// ClearExtension() methods are just thin wrappers around the embedded +// ExtensionSet. When parsing, if a tag number is encountered which is +// inside one of the message type's extension ranges, the tag is passed +// off to the ExtensionSet for parsing. Etc. +class LIBPROTOBUF_EXPORT ExtensionSet { + public: + ExtensionSet(); + explicit ExtensionSet(::google::protobuf::Arena* arena); + ~ExtensionSet(); + + // These are called at startup by protocol-compiler-generated code to + // register known extensions. The registrations are used by ParseField() + // to look up extensions for parsed field numbers. Note that dynamic parsing + // does not use ParseField(); only protocol-compiler-generated parsing + // methods do. + static void RegisterExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed); + static void RegisterEnumExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed, + EnumValidityFunc* is_valid); + static void RegisterMessageExtension(const MessageLite* containing_type, + int number, FieldType type, + bool is_repeated, bool is_packed, + const MessageLite* prototype); + + // ================================================================= + + // Add all fields which are currently present to the given vector. This + // is useful to implement Reflection::ListFields(). + void AppendToList(const Descriptor* containing_type, + const DescriptorPool* pool, + std::vector* output) const; + + // ================================================================= + // Accessors + // + // Generated message classes include type-safe templated wrappers around + // these methods. Generally you should use those rather than call these + // directly, unless you are doing low-level memory management. + // + // When calling any of these accessors, the extension number requested + // MUST exist in the DescriptorPool provided to the constructor. Otherwise, + // the method will fail an assert. Normally, though, you would not call + // these directly; you would either call the generated accessors of your + // message class (e.g. GetExtension()) or you would call the accessors + // of the reflection interface. In both cases, it is impossible to + // trigger this assert failure: the generated accessors only accept + // linked-in extension types as parameters, while the Reflection interface + // requires you to provide the FieldDescriptor describing the extension. + // + // When calling any of these accessors, a protocol-compiler-generated + // implementation of the extension corresponding to the number MUST + // be linked in, and the FieldDescriptor used to refer to it MUST be + // the one generated by that linked-in code. Otherwise, the method will + // die on an assert failure. The message objects returned by the message + // accessors are guaranteed to be of the correct linked-in type. + // + // These methods pretty much match Reflection except that: + // - They're not virtual. + // - They identify fields by number rather than FieldDescriptors. + // - They identify enum values using integers rather than descriptors. + // - Strings provide Mutable() in addition to Set() accessors. + + bool Has(int number) const; + int ExtensionSize(int number) const; // Size of a repeated extension. + int NumExtensions() const; // The number of extensions + FieldType ExtensionType(int number) const; + void ClearExtension(int number); + + // singular fields ------------------------------------------------- + + int32 GetInt32 (int number, int32 default_value) const; + int64 GetInt64 (int number, int64 default_value) const; + uint32 GetUInt32(int number, uint32 default_value) const; + uint64 GetUInt64(int number, uint64 default_value) const; + float GetFloat (int number, float default_value) const; + double GetDouble(int number, double default_value) const; + bool GetBool (int number, bool default_value) const; + int GetEnum (int number, int default_value) const; + const string & GetString (int number, const string& default_value) const; + const MessageLite& GetMessage(int number, + const MessageLite& default_value) const; + const MessageLite& GetMessage(int number, const Descriptor* message_type, + MessageFactory* factory) const; + + // |descriptor| may be NULL so long as it is known that the descriptor for + // the extension lives in the same pool as the descriptor for the containing + // type. +#define desc const FieldDescriptor* descriptor // avoid line wrapping + void SetInt32 (int number, FieldType type, int32 value, desc); + void SetInt64 (int number, FieldType type, int64 value, desc); + void SetUInt32(int number, FieldType type, uint32 value, desc); + void SetUInt64(int number, FieldType type, uint64 value, desc); + void SetFloat (int number, FieldType type, float value, desc); + void SetDouble(int number, FieldType type, double value, desc); + void SetBool (int number, FieldType type, bool value, desc); + void SetEnum (int number, FieldType type, int value, desc); + void SetString(int number, FieldType type, const string& value, desc); + string * MutableString (int number, FieldType type, desc); + MessageLite* MutableMessage(int number, FieldType type, + const MessageLite& prototype, desc); + MessageLite* MutableMessage(const FieldDescriptor* decsriptor, + MessageFactory* factory); + // Adds the given message to the ExtensionSet, taking ownership of the + // message object. Existing message with the same number will be deleted. + // If "message" is NULL, this is equivalent to "ClearExtension(number)". + void SetAllocatedMessage(int number, FieldType type, + const FieldDescriptor* descriptor, + MessageLite* message); + void UnsafeArenaSetAllocatedMessage(int number, FieldType type, + const FieldDescriptor* descriptor, + MessageLite* message); + MessageLite* ReleaseMessage(int number, const MessageLite& prototype); + MessageLite* UnsafeArenaReleaseMessage( + int number, const MessageLite& prototype); + + MessageLite* ReleaseMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); + MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); +#undef desc + ::google::protobuf::Arena* GetArenaNoVirtual() const { return arena_; } + + // repeated fields ------------------------------------------------- + + // Fetches a RepeatedField extension by number; returns |default_value| + // if no such extension exists. User should not touch this directly; it is + // used by the GetRepeatedExtension() method. + const void* GetRawRepeatedField(int number, const void* default_value) const; + // Fetches a mutable version of a RepeatedField extension by number, + // instantiating one if none exists. Similar to above, user should not use + // this directly; it underlies MutableRepeatedExtension(). + void* MutableRawRepeatedField(int number, FieldType field_type, + bool packed, const FieldDescriptor* desc); + + // This is an overload of MutableRawRepeatedField to maintain compatibility + // with old code using a previous API. This version of + // MutableRawRepeatedField() will GOOGLE_CHECK-fail on a missing extension. + // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.) + void* MutableRawRepeatedField(int number); + + int32 GetRepeatedInt32 (int number, int index) const; + int64 GetRepeatedInt64 (int number, int index) const; + uint32 GetRepeatedUInt32(int number, int index) const; + uint64 GetRepeatedUInt64(int number, int index) const; + float GetRepeatedFloat (int number, int index) const; + double GetRepeatedDouble(int number, int index) const; + bool GetRepeatedBool (int number, int index) const; + int GetRepeatedEnum (int number, int index) const; + const string & GetRepeatedString (int number, int index) const; + const MessageLite& GetRepeatedMessage(int number, int index) const; + + void SetRepeatedInt32 (int number, int index, int32 value); + void SetRepeatedInt64 (int number, int index, int64 value); + void SetRepeatedUInt32(int number, int index, uint32 value); + void SetRepeatedUInt64(int number, int index, uint64 value); + void SetRepeatedFloat (int number, int index, float value); + void SetRepeatedDouble(int number, int index, double value); + void SetRepeatedBool (int number, int index, bool value); + void SetRepeatedEnum (int number, int index, int value); + void SetRepeatedString(int number, int index, const string& value); + string * MutableRepeatedString (int number, int index); + MessageLite* MutableRepeatedMessage(int number, int index); + +#define desc const FieldDescriptor* descriptor // avoid line wrapping + void AddInt32 (int number, FieldType type, bool packed, int32 value, desc); + void AddInt64 (int number, FieldType type, bool packed, int64 value, desc); + void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc); + void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc); + void AddFloat (int number, FieldType type, bool packed, float value, desc); + void AddDouble(int number, FieldType type, bool packed, double value, desc); + void AddBool (int number, FieldType type, bool packed, bool value, desc); + void AddEnum (int number, FieldType type, bool packed, int value, desc); + void AddString(int number, FieldType type, const string& value, desc); + string * AddString (int number, FieldType type, desc); + MessageLite* AddMessage(int number, FieldType type, + const MessageLite& prototype, desc); + MessageLite* AddMessage(const FieldDescriptor* descriptor, + MessageFactory* factory); + void AddAllocatedMessage(const FieldDescriptor* descriptor, + MessageLite* new_entry); +#undef desc + + void RemoveLast(int number); + MessageLite* ReleaseLast(int number); + void SwapElements(int number, int index1, int index2); + + // ----------------------------------------------------------------- + // TODO(kenton): Hardcore memory management accessors + + // ================================================================= + // convenience methods for implementing methods of Message + // + // These could all be implemented in terms of the other methods of this + // class, but providing them here helps keep the generated code size down. + + void Clear(); + void MergeFrom(const ExtensionSet& other); + void Swap(ExtensionSet* other); + void SwapExtension(ExtensionSet* other, int number); + bool IsInitialized() const; + + // Parses a single extension from the input. The input should start out + // positioned immediately after the tag. + bool ParseField(uint32 tag, io::CodedInputStream* input, + ExtensionFinder* extension_finder, + FieldSkipper* field_skipper); + + // Specific versions for lite or full messages (constructs the appropriate + // FieldSkipper automatically). |containing_type| is the default + // instance for the containing message; it is used only to look up the + // extension by number. See RegisterExtension(), above. Unlike the other + // methods of ExtensionSet, this only works for generated message types -- + // it looks up extensions registered using RegisterExtension(). + bool ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type); + bool ParseField(uint32 tag, io::CodedInputStream* input, + const Message* containing_type, + UnknownFieldSet* unknown_fields); + bool ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type, + io::CodedOutputStream* unknown_fields); + + // Parse an entire message in MessageSet format. Such messages have no + // fields, only extensions. + bool ParseMessageSet(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + MessageSetFieldSkipper* field_skipper); + + // Specific versions for lite or full messages (constructs the appropriate + // FieldSkipper automatically). + bool ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type); + bool ParseMessageSet(io::CodedInputStream* input, + const Message* containing_type, + UnknownFieldSet* unknown_fields); + + // Write all extension fields with field numbers in the range + // [start_field_number, end_field_number) + // to the output stream, using the cached sizes computed when ByteSize() was + // last called. Note that the range bounds are inclusive-exclusive. + void SerializeWithCachedSizes(int start_field_number, + int end_field_number, + io::CodedOutputStream* output) const; + + // Same as SerializeWithCachedSizes, but without any bounds checking. + // The caller must ensure that target has sufficient capacity for the + // serialized extensions. + // + // Returns a pointer past the last written byte. + uint8* InternalSerializeWithCachedSizesToArray(int start_field_number, + int end_field_number, + bool deterministic, + uint8* target) const; + + // Like above but serializes in MessageSet format. + void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const; + uint8* InternalSerializeMessageSetWithCachedSizesToArray(bool deterministic, + uint8* target) const; + + // For backward-compatibility, versions of two of the above methods that + // are never forced to serialize deterministically. + uint8* SerializeWithCachedSizesToArray(int start_field_number, + int end_field_number, + uint8* target) const; + uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const; + + // Returns the total serialized size of all the extensions. + int ByteSize() const; + + // Like ByteSize() but uses MessageSet format. + int MessageSetByteSize() const; + + // Returns (an estimate of) the total number of bytes used for storing the + // extensions in memory, excluding sizeof(*this). If the ExtensionSet is + // for a lite message (and thus possibly contains lite messages), the results + // are undefined (might work, might crash, might corrupt data, might not even + // be linked in). It's up to the protocol compiler to avoid calling this on + // such ExtensionSets (easy enough since lite messages don't implement + // SpaceUsed()). + int SpaceUsedExcludingSelf() const; + + private: + + // Interface of a lazily parsed singular message extension. + class LIBPROTOBUF_EXPORT LazyMessageExtension { + public: + LazyMessageExtension() {} + virtual ~LazyMessageExtension() {} + + virtual LazyMessageExtension* New(::google::protobuf::Arena* arena) const = 0; + virtual const MessageLite& GetMessage( + const MessageLite& prototype) const = 0; + virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0; + virtual void SetAllocatedMessage(MessageLite *message) = 0; + virtual void UnsafeArenaSetAllocatedMessage(MessageLite *message) = 0; + virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0; + virtual MessageLite* UnsafeArenaReleaseMessage( + const MessageLite& prototype) = 0; + + virtual bool IsInitialized() const = 0; + virtual int ByteSize() const = 0; + virtual int SpaceUsed() const = 0; + + virtual void MergeFrom(const LazyMessageExtension& other) = 0; + virtual void Clear() = 0; + + virtual bool ReadMessage(const MessageLite& prototype, + io::CodedInputStream* input) = 0; + virtual void WriteMessage(int number, + io::CodedOutputStream* output) const = 0; + virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0; + virtual uint8* InternalWriteMessageToArray(int number, bool, + uint8* target) const { + // TODO(gpike): make this pure virtual. This is a placeholder because we + // need to update third_party/upb, for example. + return WriteMessageToArray(number, target); + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension); + }; + struct Extension { + // The order of these fields packs Extension into 24 bytes when using 8 + // byte alignment. Consider this when adding or removing fields here. + union { + int32 int32_value; + int64 int64_value; + uint32 uint32_value; + uint64 uint64_value; + float float_value; + double double_value; + bool bool_value; + int enum_value; + string* string_value; + MessageLite* message_value; + LazyMessageExtension* lazymessage_value; + + RepeatedField * repeated_int32_value; + RepeatedField * repeated_int64_value; + RepeatedField * repeated_uint32_value; + RepeatedField * repeated_uint64_value; + RepeatedField * repeated_float_value; + RepeatedField * repeated_double_value; + RepeatedField * repeated_bool_value; + RepeatedField * repeated_enum_value; + RepeatedPtrField* repeated_string_value; + RepeatedPtrField* repeated_message_value; + }; + + FieldType type; + bool is_repeated; + + // For singular types, indicates if the extension is "cleared". This + // happens when an extension is set and then later cleared by the caller. + // We want to keep the Extension object around for reuse, so instead of + // removing it from the map, we just set is_cleared = true. This has no + // meaning for repeated types; for those, the size of the RepeatedField + // simply becomes zero when cleared. + bool is_cleared : 4; + + // For singular message types, indicates whether lazy parsing is enabled + // for this extension. This field is only valid when type == TYPE_MESSAGE + // and !is_repeated because we only support lazy parsing for singular + // message types currently. If is_lazy = true, the extension is stored in + // lazymessage_value. Otherwise, the extension will be message_value. + bool is_lazy : 4; + + // For repeated types, this indicates if the [packed=true] option is set. + bool is_packed; + + // For packed fields, the size of the packed data is recorded here when + // ByteSize() is called then used during serialization. + // TODO(kenton): Use atomic when C++ supports it. + mutable int cached_size; + + // The descriptor for this extension, if one exists and is known. May be + // NULL. Must not be NULL if the descriptor for the extension does not + // live in the same pool as the descriptor for the containing type. + const FieldDescriptor* descriptor; + + // Some helper methods for operations on a single Extension. + void SerializeFieldWithCachedSizes( + int number, + io::CodedOutputStream* output) const; + uint8* InternalSerializeFieldWithCachedSizesToArray( + int number, + bool deterministic, + uint8* target) const; + void SerializeMessageSetItemWithCachedSizes( + int number, + io::CodedOutputStream* output) const; + uint8* InternalSerializeMessageSetItemWithCachedSizesToArray( + int number, + bool deterministic, + uint8* target) const; + int ByteSize(int number) const; + int MessageSetItemByteSize(int number) const; + void Clear(); + int GetSize() const; + void Free(); + int SpaceUsedExcludingSelf() const; + }; + typedef std::map ExtensionMap; + + + // Merges existing Extension from other_extension + void InternalExtensionMergeFrom(int number, const Extension& other_extension); + + // Returns true and fills field_number and extension if extension is found. + // Note to support packed repeated field compatibility, it also fills whether + // the tag on wire is packed, which can be different from + // extension->is_packed (whether packed=true is specified). + bool FindExtensionInfoFromTag(uint32 tag, ExtensionFinder* extension_finder, + int* field_number, ExtensionInfo* extension, + bool* was_packed_on_wire); + + // Returns true and fills extension if extension is found. + // Note to support packed repeated field compatibility, it also fills whether + // the tag on wire is packed, which can be different from + // extension->is_packed (whether packed=true is specified). + bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number, + ExtensionFinder* extension_finder, + ExtensionInfo* extension, + bool* was_packed_on_wire); + + // Parses a single extension from the input. The input should start out + // positioned immediately after the wire tag. This method is called in + // ParseField() after field number and was_packed_on_wire is extracted from + // the wire tag and ExtensionInfo is found by the field number. + bool ParseFieldWithExtensionInfo(int field_number, + bool was_packed_on_wire, + const ExtensionInfo& extension, + io::CodedInputStream* input, + FieldSkipper* field_skipper); + + // Like ParseField(), but this method may parse singular message extensions + // lazily depending on the value of FLAGS_eagerly_parse_message_sets. + bool ParseFieldMaybeLazily(int wire_type, int field_number, + io::CodedInputStream* input, + ExtensionFinder* extension_finder, + MessageSetFieldSkipper* field_skipper); + + // Gets the extension with the given number, creating it if it does not + // already exist. Returns true if the extension did not already exist. + bool MaybeNewExtension(int number, const FieldDescriptor* descriptor, + Extension** result); + + // Gets the repeated extension for the given descriptor, creating it if + // it does not exist. + Extension* MaybeNewRepeatedExtension(const FieldDescriptor* descriptor); + + // Parse a single MessageSet item -- called just after the item group start + // tag has been read. + bool ParseMessageSetItem(io::CodedInputStream* input, + ExtensionFinder* extension_finder, + MessageSetFieldSkipper* field_skipper); + + // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This + // friendship should automatically extend to ExtensionSet::Extension, but + // unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this + // correctly. So, we must provide helpers for calling methods of that + // class. + + // Defined in extension_set_heavy.cc. + static inline int RepeatedMessage_SpaceUsedExcludingSelf( + RepeatedPtrFieldBase* field); + + // The Extension struct is small enough to be passed by value, so we use it + // directly as the value type in the map rather than use pointers. We use + // a map rather than hash_map here because we expect most ExtensionSets will + // only contain a small number of extensions whereas hash_map is optimized + // for 100 elements or more. Also, we want AppendToList() to order fields + // by field number. + ExtensionMap extensions_; + ::google::protobuf::Arena* arena_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); +}; + +// These are just for convenience... +inline void ExtensionSet::SetString(int number, FieldType type, + const string& value, + const FieldDescriptor* descriptor) { + MutableString(number, type, descriptor)->assign(value); +} +inline void ExtensionSet::SetRepeatedString(int number, int index, + const string& value) { + MutableRepeatedString(number, index)->assign(value); +} +inline void ExtensionSet::AddString(int number, FieldType type, + const string& value, + const FieldDescriptor* descriptor) { + AddString(number, type, descriptor)->assign(value); +} + +// =================================================================== +// Glue for generated extension accessors + +// ------------------------------------------------------------------- +// Template magic + +// First we have a set of classes representing "type traits" for different +// field types. A type traits class knows how to implement basic accessors +// for extensions of a particular type given an ExtensionSet. The signature +// for a type traits class looks like this: +// +// class TypeTraits { +// public: +// typedef ? ConstType; +// typedef ? MutableType; +// // TypeTraits for singular fields and repeated fields will define the +// // symbol "Singular" or "Repeated" respectively. These two symbols will +// // be used in extension accessors to distinguish between singular +// // extensions and repeated extensions. If the TypeTraits for the passed +// // in extension doesn't have the expected symbol defined, it means the +// // user is passing a repeated extension to a singular accessor, or the +// // opposite. In that case the C++ compiler will generate an error +// // message "no matching member function" to inform the user. +// typedef ? Singular +// typedef ? Repeated +// +// static inline ConstType Get(int number, const ExtensionSet& set); +// static inline void Set(int number, ConstType value, ExtensionSet* set); +// static inline MutableType Mutable(int number, ExtensionSet* set); +// +// // Variants for repeated fields. +// static inline ConstType Get(int number, const ExtensionSet& set, +// int index); +// static inline void Set(int number, int index, +// ConstType value, ExtensionSet* set); +// static inline MutableType Mutable(int number, int index, +// ExtensionSet* set); +// static inline void Add(int number, ConstType value, ExtensionSet* set); +// static inline MutableType Add(int number, ExtensionSet* set); +// }; +// +// Not all of these methods make sense for all field types. For example, the +// "Mutable" methods only make sense for strings and messages, and the +// repeated methods only make sense for repeated types. So, each type +// traits class implements only the set of methods from this signature that it +// actually supports. This will cause a compiler error if the user tries to +// access an extension using a method that doesn't make sense for its type. +// For example, if "foo" is an extension of type "optional int32", then if you +// try to write code like: +// my_message.MutableExtension(foo) +// you will get a compile error because PrimitiveTypeTraits does not +// have a "Mutable()" method. + +// ------------------------------------------------------------------- +// PrimitiveTypeTraits + +// Since the ExtensionSet has different methods for each primitive type, +// we must explicitly define the methods of the type traits class for each +// known type. +template +class PrimitiveTypeTraits { + public: + typedef Type ConstType; + typedef Type MutableType; + typedef PrimitiveTypeTraits Singular; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value); + static inline void Set(int number, FieldType field_type, + ConstType value, ExtensionSet* set); +}; + +template +class RepeatedPrimitiveTypeTraits { + public: + typedef Type ConstType; + typedef Type MutableType; + typedef RepeatedPrimitiveTypeTraits Repeated; + + typedef RepeatedField RepeatedFieldType; + + static inline Type Get(int number, const ExtensionSet& set, int index); + static inline void Set(int number, int index, Type value, ExtensionSet* set); + static inline void Add(int number, FieldType field_type, + bool is_packed, Type value, ExtensionSet* set); + + static inline const RepeatedField& + GetRepeated(int number, const ExtensionSet& set); + static inline RepeatedField* + MutableRepeated(int number, FieldType field_type, + bool is_packed, ExtensionSet* set); + + static const RepeatedFieldType* GetDefaultRepeatedField(); +}; + +LIBPROTOBUF_EXPORT extern ProtobufOnceType repeated_primitive_generic_type_traits_once_init_; + +class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits { + private: + template friend class RepeatedPrimitiveTypeTraits; + static void InitializeDefaultRepeatedFields(); + static void DestroyDefaultRepeatedFields(); + static const RepeatedField* default_repeated_field_int32_; + static const RepeatedField* default_repeated_field_int64_; + static const RepeatedField* default_repeated_field_uint32_; + static const RepeatedField* default_repeated_field_uint64_; + static const RepeatedField* default_repeated_field_double_; + static const RepeatedField* default_repeated_field_float_; + static const RepeatedField* default_repeated_field_bool_; +}; + +#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \ +template<> inline TYPE PrimitiveTypeTraits::Get( \ + int number, const ExtensionSet& set, TYPE default_value) { \ + return set.Get##METHOD(number, default_value); \ +} \ +template<> inline void PrimitiveTypeTraits::Set( \ + int number, FieldType field_type, TYPE value, ExtensionSet* set) { \ + set->Set##METHOD(number, field_type, value, NULL); \ +} \ + \ +template<> inline TYPE RepeatedPrimitiveTypeTraits::Get( \ + int number, const ExtensionSet& set, int index) { \ + return set.GetRepeated##METHOD(number, index); \ +} \ +template<> inline void RepeatedPrimitiveTypeTraits::Set( \ + int number, int index, TYPE value, ExtensionSet* set) { \ + set->SetRepeated##METHOD(number, index, value); \ +} \ +template<> inline void RepeatedPrimitiveTypeTraits::Add( \ + int number, FieldType field_type, bool is_packed, \ + TYPE value, ExtensionSet* set) { \ + set->Add##METHOD(number, field_type, is_packed, value, NULL); \ +} \ +template<> inline const RepeatedField* \ + RepeatedPrimitiveTypeTraits::GetDefaultRepeatedField() { \ + ::google::protobuf::GoogleOnceInit( \ + &repeated_primitive_generic_type_traits_once_init_, \ + &RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields); \ + return RepeatedPrimitiveGenericTypeTraits:: \ + default_repeated_field_##TYPE##_; \ +} \ +template<> inline const RepeatedField& \ + RepeatedPrimitiveTypeTraits::GetRepeated(int number, \ + const ExtensionSet& set) { \ + return *reinterpret_cast*>( \ + set.GetRawRepeatedField( \ + number, GetDefaultRepeatedField())); \ +} \ +template<> inline RepeatedField* \ + RepeatedPrimitiveTypeTraits::MutableRepeated(int number, \ + FieldType field_type, \ + bool is_packed, \ + ExtensionSet* set) { \ + return reinterpret_cast*>( \ + set->MutableRawRepeatedField(number, field_type, is_packed, NULL)); \ +} + +PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32) +PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64, Int64) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64) +PROTOBUF_DEFINE_PRIMITIVE_TYPE( float, Float) +PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double) +PROTOBUF_DEFINE_PRIMITIVE_TYPE( bool, Bool) + +#undef PROTOBUF_DEFINE_PRIMITIVE_TYPE + +// ------------------------------------------------------------------- +// StringTypeTraits + +// Strings support both Set() and Mutable(). +class LIBPROTOBUF_EXPORT StringTypeTraits { + public: + typedef const string& ConstType; + typedef string* MutableType; + typedef StringTypeTraits Singular; + + static inline const string& Get(int number, const ExtensionSet& set, + ConstType default_value) { + return set.GetString(number, default_value); + } + static inline void Set(int number, FieldType field_type, + const string& value, ExtensionSet* set) { + set->SetString(number, field_type, value, NULL); + } + static inline string* Mutable(int number, FieldType field_type, + ExtensionSet* set) { + return set->MutableString(number, field_type, NULL); + } +}; + +LIBPROTOBUF_EXPORT extern ProtobufOnceType repeated_string_type_traits_once_init_; + +class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { + public: + typedef const string& ConstType; + typedef string* MutableType; + typedef RepeatedStringTypeTraits Repeated; + + typedef RepeatedPtrField RepeatedFieldType; + + static inline const string& Get(int number, const ExtensionSet& set, + int index) { + return set.GetRepeatedString(number, index); + } + static inline void Set(int number, int index, + const string& value, ExtensionSet* set) { + set->SetRepeatedString(number, index, value); + } + static inline string* Mutable(int number, int index, ExtensionSet* set) { + return set->MutableRepeatedString(number, index); + } + static inline void Add(int number, FieldType field_type, + bool /*is_packed*/, const string& value, + ExtensionSet* set) { + set->AddString(number, field_type, value, NULL); + } + static inline string* Add(int number, FieldType field_type, + ExtensionSet* set) { + return set->AddString(number, field_type, NULL); + } + static inline const RepeatedPtrField& + GetRepeated(int number, const ExtensionSet& set) { + return *reinterpret_cast*>( + set.GetRawRepeatedField(number, GetDefaultRepeatedField())); + } + + static inline RepeatedPtrField* + MutableRepeated(int number, FieldType field_type, + bool is_packed, ExtensionSet* set) { + return reinterpret_cast*>( + set->MutableRawRepeatedField(number, field_type, + is_packed, NULL)); + } + + static const RepeatedFieldType* GetDefaultRepeatedField() { + ::google::protobuf::GoogleOnceInit(&repeated_string_type_traits_once_init_, + &InitializeDefaultRepeatedFields); + return default_repeated_field_; + } + + private: + static void InitializeDefaultRepeatedFields(); + static void DestroyDefaultRepeatedFields(); + static const RepeatedFieldType *default_repeated_field_; +}; + +// ------------------------------------------------------------------- +// EnumTypeTraits + +// ExtensionSet represents enums using integers internally, so we have to +// static_cast around. +template +class EnumTypeTraits { + public: + typedef Type ConstType; + typedef Type MutableType; + typedef EnumTypeTraits Singular; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value) { + return static_cast(set.GetEnum(number, default_value)); + } + static inline void Set(int number, FieldType field_type, + ConstType value, ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->SetEnum(number, field_type, value, NULL); + } +}; + +template +class RepeatedEnumTypeTraits { + public: + typedef Type ConstType; + typedef Type MutableType; + typedef RepeatedEnumTypeTraits Repeated; + + typedef RepeatedField RepeatedFieldType; + + static inline ConstType Get(int number, const ExtensionSet& set, int index) { + return static_cast(set.GetRepeatedEnum(number, index)); + } + static inline void Set(int number, int index, + ConstType value, ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->SetRepeatedEnum(number, index, value); + } + static inline void Add(int number, FieldType field_type, + bool is_packed, ConstType value, ExtensionSet* set) { + GOOGLE_DCHECK(IsValid(value)); + set->AddEnum(number, field_type, is_packed, value, NULL); + } + static inline const RepeatedField& GetRepeated(int number, + const ExtensionSet& + set) { + // Hack: the `Extension` struct stores a RepeatedField for enums. + // RepeatedField cannot implicitly convert to RepeatedField + // so we need to do some casting magic. See message.h for similar + // contortions for non-extension fields. + return *reinterpret_cast*>( + set.GetRawRepeatedField(number, GetDefaultRepeatedField())); + } + + static inline RepeatedField* MutableRepeated(int number, + FieldType field_type, + bool is_packed, + ExtensionSet* set) { + return reinterpret_cast*>( + set->MutableRawRepeatedField(number, field_type, is_packed, NULL)); + } + + static const RepeatedFieldType* GetDefaultRepeatedField() { + // Hack: as noted above, repeated enum fields are internally stored as a + // RepeatedField. We need to be able to instantiate global static + // objects to return as default (empty) repeated fields on non-existent + // extensions. We would not be able to know a-priori all of the enum types + // (values of |Type|) to instantiate all of these, so we just re-use int32's + // default repeated field object. + return reinterpret_cast*>( + RepeatedPrimitiveTypeTraits::GetDefaultRepeatedField()); + } +}; + +// ------------------------------------------------------------------- +// MessageTypeTraits + +// ExtensionSet guarantees that when manipulating extensions with message +// types, the implementation used will be the compiled-in class representing +// that type. So, we can static_cast down to the exact type we expect. +template +class MessageTypeTraits { + public: + typedef const Type& ConstType; + typedef Type* MutableType; + typedef MessageTypeTraits Singular; + + static inline ConstType Get(int number, const ExtensionSet& set, + ConstType default_value) { + return static_cast( + set.GetMessage(number, default_value)); + } + static inline MutableType Mutable(int number, FieldType field_type, + ExtensionSet* set) { + return static_cast( + set->MutableMessage(number, field_type, Type::default_instance(), NULL)); + } + static inline void SetAllocated(int number, FieldType field_type, + MutableType message, ExtensionSet* set) { + set->SetAllocatedMessage(number, field_type, NULL, message); + } + static inline void UnsafeArenaSetAllocated(int number, FieldType field_type, + MutableType message, + ExtensionSet* set) { + set->UnsafeArenaSetAllocatedMessage(number, field_type, NULL, message); + } + static inline MutableType Release(int number, FieldType /* field_type */, + ExtensionSet* set) { + return static_cast(set->ReleaseMessage( + number, Type::default_instance())); + } + static inline MutableType UnsafeArenaRelease(int number, + FieldType /* field_type */, + ExtensionSet* set) { + return static_cast(set->UnsafeArenaReleaseMessage( + number, Type::default_instance())); + } +}; + +// forward declaration +class RepeatedMessageGenericTypeTraits; + +template +class RepeatedMessageTypeTraits { + public: + typedef const Type& ConstType; + typedef Type* MutableType; + typedef RepeatedMessageTypeTraits Repeated; + + typedef RepeatedPtrField RepeatedFieldType; + + static inline ConstType Get(int number, const ExtensionSet& set, int index) { + return static_cast(set.GetRepeatedMessage(number, index)); + } + static inline MutableType Mutable(int number, int index, ExtensionSet* set) { + return static_cast(set->MutableRepeatedMessage(number, index)); + } + static inline MutableType Add(int number, FieldType field_type, + ExtensionSet* set) { + return static_cast( + set->AddMessage(number, field_type, Type::default_instance(), NULL)); + } + static inline const RepeatedPtrField& GetRepeated(int number, + const ExtensionSet& + set) { + // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same + // casting hack applies here, because a RepeatedPtrField + // cannot naturally become a RepeatedPtrType even though Type is + // presumably a message. google::protobuf::Message goes through similar contortions + // with a reinterpret_cast<>. + return *reinterpret_cast*>( + set.GetRawRepeatedField(number, GetDefaultRepeatedField())); + } + static inline RepeatedPtrField* MutableRepeated(int number, + FieldType field_type, + bool is_packed, + ExtensionSet* set) { + return reinterpret_cast*>( + set->MutableRawRepeatedField(number, field_type, is_packed, NULL)); + } + + static const RepeatedFieldType* GetDefaultRepeatedField(); +}; + +LIBPROTOBUF_EXPORT extern ProtobufOnceType repeated_message_generic_type_traits_once_init_; + +// This class exists only to hold a generic default empty repeated field for all +// message-type repeated field extensions. +class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits { + public: + typedef RepeatedPtrField< ::google::protobuf::MessageLite*> RepeatedFieldType; + private: + template friend class RepeatedMessageTypeTraits; + static void InitializeDefaultRepeatedFields(); + static void DestroyDefaultRepeatedFields(); + static const RepeatedFieldType* default_repeated_field_; +}; + +template inline + const typename RepeatedMessageTypeTraits::RepeatedFieldType* + RepeatedMessageTypeTraits::GetDefaultRepeatedField() { + ::google::protobuf::GoogleOnceInit( + &repeated_message_generic_type_traits_once_init_, + &RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields); + return reinterpret_cast( + RepeatedMessageGenericTypeTraits::default_repeated_field_); +} + +// ------------------------------------------------------------------- +// ExtensionIdentifier + +// This is the type of actual extension objects. E.g. if you have: +// extends Foo with optional int32 bar = 1234; +// then "bar" will be defined in C++ as: +// ExtensionIdentifier, 1, false> bar(1234); +// +// Note that we could, in theory, supply the field number as a template +// parameter, and thus make an instance of ExtensionIdentifier have no +// actual contents. However, if we did that, then using at extension +// identifier would not necessarily cause the compiler to output any sort +// of reference to any simple defined in the extension's .pb.o file. Some +// linkers will actually drop object files that are not explicitly referenced, +// but that would be bad because it would cause this extension to not be +// registered at static initialization, and therefore using it would crash. + +template +class ExtensionIdentifier { + public: + typedef TypeTraitsType TypeTraits; + typedef ExtendeeType Extendee; + + ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value) + : number_(number), default_value_(default_value) {} + inline int number() const { return number_; } + typename TypeTraits::ConstType default_value() const { + return default_value_; + } + + private: + const int number_; + typename TypeTraits::ConstType default_value_; +}; + +// ------------------------------------------------------------------- +// Generated accessors + +// This macro should be expanded in the context of a generated type which +// has extensions. +// +// We use "_proto_TypeTraits" as a type name below because "TypeTraits" +// causes problems if the class has a nested message or enum type with that +// name and "_TypeTraits" is technically reserved for the C++ library since +// it starts with an underscore followed by a capital letter. +// +// For similar reason, we use "_field_type" and "_is_packed" as parameter names +// below, so that "field_type" and "is_packed" can be used as field names. +#define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME) \ + /* Has, Size, Clear */ \ + template \ + inline bool HasExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ + return _extensions_.Has(id.number()); \ + } \ + \ + template \ + inline void ClearExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + _extensions_.ClearExtension(id.number()); \ + } \ + \ + template \ + inline int ExtensionSize( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ + return _extensions_.ExtensionSize(id.number()); \ + } \ + \ + /* Singular accessors */ \ + template \ + inline typename _proto_TypeTraits::Singular::ConstType GetExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \ + return _proto_TypeTraits::Get(id.number(), _extensions_, \ + id.default_value()); \ + } \ + \ + template \ + inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + return _proto_TypeTraits::Mutable(id.number(), _field_type, \ + &_extensions_); \ + } \ + \ + template \ + inline void SetExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + typename _proto_TypeTraits::Singular::ConstType value) { \ + _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); \ + } \ + \ + template \ + inline void SetAllocatedExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + typename _proto_TypeTraits::Singular::MutableType value) { \ + _proto_TypeTraits::SetAllocated(id.number(), _field_type, \ + value, &_extensions_); \ + } \ + template \ + inline void UnsafeArenaSetAllocatedExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + typename _proto_TypeTraits::Singular::MutableType value) { \ + _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, \ + value, &_extensions_); \ + } \ + template \ + inline typename _proto_TypeTraits::Singular::MutableType ReleaseExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + return _proto_TypeTraits::Release(id.number(), _field_type, \ + &_extensions_); \ + } \ + template \ + inline typename _proto_TypeTraits::Singular::MutableType \ + UnsafeArenaReleaseExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, \ + &_extensions_); \ + } \ + \ + /* Repeated accessors */ \ + template \ + inline typename _proto_TypeTraits::Repeated::ConstType GetExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + int index) const { \ + return _proto_TypeTraits::Get(id.number(), _extensions_, index); \ + } \ + \ + template \ + inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + int index) { \ + return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); \ + } \ + \ + template \ + inline void SetExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + int index, typename _proto_TypeTraits::Repeated::ConstType value) { \ + _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); \ + } \ + \ + template \ + inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \ + return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); \ + } \ + \ + template \ + inline void AddExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \ + typename _proto_TypeTraits::Repeated::ConstType value) { \ + _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, \ + value, &_extensions_); \ + } \ + \ + template \ + inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType& \ + GetRepeatedExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, \ + _is_packed>& id) const { \ + return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); \ + } \ + \ + template \ + inline typename _proto_TypeTraits::Repeated::RepeatedFieldType* \ + MutableRepeatedExtension( \ + const ::google::protobuf::internal::ExtensionIdentifier< \ + CLASSNAME, _proto_TypeTraits, _field_type, \ + _is_packed>& id) { \ + return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, \ + _is_packed, &_extensions_); \ + } + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__ diff --git a/thirdparty/linux/include/google/protobuf/field_mask.pb.h b/thirdparty/linux/include/google/protobuf/field_mask.pb.h new file mode 100644 index 0000000..7a19c4a --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/field_mask.pb.h @@ -0,0 +1,206 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/field_mask.proto + +#ifndef PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto(); + +class FieldMask; + +// =================================================================== + +class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ { + public: + FieldMask(); + virtual ~FieldMask(); + + FieldMask(const FieldMask& from); + + inline FieldMask& operator=(const FieldMask& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FieldMask& default_instance(); + + void Swap(FieldMask* other); + + // implements Message ---------------------------------------------- + + inline FieldMask* New() const { return New(NULL); } + + FieldMask* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FieldMask& from); + void MergeFrom(const FieldMask& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FieldMask* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string paths = 1; + int paths_size() const; + void clear_paths(); + static const int kPathsFieldNumber = 1; + const ::std::string& paths(int index) const; + ::std::string* mutable_paths(int index); + void set_paths(int index, const ::std::string& value); + void set_paths(int index, const char* value); + void set_paths(int index, const char* value, size_t size); + ::std::string* add_paths(); + void add_paths(const ::std::string& value); + void add_paths(const char* value); + void add_paths(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& paths() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_paths(); + + // @@protoc_insertion_point(class_scope:google.protobuf.FieldMask) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::RepeatedPtrField< ::std::string> paths_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto(); + + void InitAsDefaultInstance(); + static FieldMask* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// FieldMask + +// repeated string paths = 1; +inline int FieldMask::paths_size() const { + return paths_.size(); +} +inline void FieldMask::clear_paths() { + paths_.Clear(); +} +inline const ::std::string& FieldMask::paths(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldMask.paths) + return paths_.Get(index); +} +inline ::std::string* FieldMask::mutable_paths(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldMask.paths) + return paths_.Mutable(index); +} +inline void FieldMask::set_paths(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths) + paths_.Mutable(index)->assign(value); +} +inline void FieldMask::set_paths(int index, const char* value) { + paths_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths) +} +inline void FieldMask::set_paths(int index, const char* value, size_t size) { + paths_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldMask.paths) +} +inline ::std::string* FieldMask::add_paths() { + // @@protoc_insertion_point(field_add_mutable:google.protobuf.FieldMask.paths) + return paths_.Add(); +} +inline void FieldMask::add_paths(const ::std::string& value) { + paths_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths) +} +inline void FieldMask::add_paths(const char* value) { + paths_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths) +} +inline void FieldMask::add_paths(const char* value, size_t size) { + paths_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.FieldMask.paths) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +FieldMask::paths() const { + // @@protoc_insertion_point(field_list:google.protobuf.FieldMask.paths) + return paths_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +FieldMask::mutable_paths() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldMask.paths) + return &paths_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/field_mask.proto b/thirdparty/linux/include/google/protobuf/field_mask.proto new file mode 100644 index 0000000..c51de09 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/field_mask.proto @@ -0,0 +1,246 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "FieldMaskProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option java_generate_equals_and_hash = true; + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// field mask. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, the existing +// repeated values in the target resource will be overwritten by the new values. +// Note that a repeated field is only allowed in the last position of a field +// mask. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then the existing sub-message in the target resource is +// overwritten. Given the target message: +// +// f { +// b { +// d : 1 +// x : 2 +// } +// c : 1 +// } +// +// And an update message: +// +// f { +// b { +// d : 10 +// } +// } +// +// then if the field mask is: +// +// paths: "f.b" +// +// then the result will be: +// +// f { +// b { +// d : 10 +// } +// c : 1 +// } +// +// However, if the update mask was: +// +// paths: "f.b.d" +// +// then the result would be: +// +// f { +// b { +// d : 10 +// x : 2 +// } +// c : 1 +// } +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// Photo photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/thirdparty/linux/include/google/protobuf/generated_enum_reflection.h b/thirdparty/linux/include/google/protobuf/generated_enum_reflection.h new file mode 100644 index 0000000..fdcdc27 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/generated_enum_reflection.h @@ -0,0 +1,88 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jasonh@google.com (Jason Hsueh) +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. +// It provides reflection support for generated enums, and is included in +// generated .pb.h files and should have minimal dependencies. The methods are +// implemented in generated_message_reflection.cc. + +#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ +#define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ + +#include + +#include +#include + +namespace google { +namespace protobuf { + class EnumDescriptor; +} // namespace protobuf + +namespace protobuf { + +// Returns the EnumDescriptor for enum type E, which must be a +// proto-declared enum type. Code generated by the protocol compiler +// will include specializations of this template for each enum type declared. +template +const EnumDescriptor* GetEnumDescriptor(); + +namespace internal { + +// Helper for EnumType_Parse functions: try to parse the string 'name' as an +// enum name of the given type, returning true and filling in value on success, +// or returning false and leaving value unchanged on failure. +LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor, + const string& name, + int* value); + +template +bool ParseNamedEnum(const EnumDescriptor* descriptor, + const string& name, + EnumType* value) { + int tmp; + if (!ParseNamedEnum(descriptor, name, &tmp)) return false; + *value = static_cast(tmp); + return true; +} + +// Just a wrapper around printing the name of a value. The main point of this +// function is not to be inlined, so that you can do this without including +// descriptor.h. +LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value); + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ diff --git a/thirdparty/linux/include/google/protobuf/generated_enum_util.h b/thirdparty/linux/include/google/protobuf/generated_enum_util.h new file mode 100644 index 0000000..e424205 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/generated_enum_util.h @@ -0,0 +1,46 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ +#define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ + +#include + +namespace google { +namespace protobuf { + +// This type trait can be used to cause templates to only match proto2 enum +// types. +template struct is_proto_enum : ::google::protobuf::internal::false_type {}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ diff --git a/thirdparty/linux/include/google/protobuf/generated_message_reflection.h b/thirdparty/linux/include/google/protobuf/generated_message_reflection.h new file mode 100644 index 0000000..15fc802 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/generated_message_reflection.h @@ -0,0 +1,683 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ + +#include +#include +#include +#include +// TODO(jasonh): Remove this once the compiler change to directly include this +// is released to components. +#include +#include +#include +#include + + +namespace google { +namespace upb { +namespace google_opensource { +class GMR_Handlers; +} // namespace google_opensource +} // namespace upb + +namespace protobuf { +class DescriptorPool; +class MapKey; +class MapValueRef; +} + +namespace protobuf { +namespace internal { +class DefaultEmptyOneof; + +// Defined in this file. +class GeneratedMessageReflection; + +// Defined in other files. +class ExtensionSet; // extension_set.h + +// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use +// by generated code. This class is just a big hack that reduces code +// size. +// +// A GeneratedMessageReflection is an implementation of Reflection +// which expects all fields to be backed by simple variables located in +// memory. The locations are given using a base pointer and a set of +// offsets. +// +// It is required that the user represents fields of each type in a standard +// way, so that GeneratedMessageReflection can cast the void* pointer to +// the appropriate type. For primitive fields and string fields, each field +// should be represented using the obvious C++ primitive type. Enums and +// Messages are different: +// - Singular Message fields are stored as a pointer to a Message. These +// should start out NULL, except for in the default instance where they +// should start out pointing to other default instances. +// - Enum fields are stored as an int. This int must always contain +// a valid value, such that EnumDescriptor::FindValueByNumber() would +// not return NULL. +// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields +// of whatever type the individual field would be. Strings and +// Messages use RepeatedPtrFields while everything else uses +// RepeatedFields. +class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { + public: + // Constructs a GeneratedMessageReflection. + // Parameters: + // descriptor: The descriptor for the message type being implemented. + // default_instance: The default instance of the message. This is only + // used to obtain pointers to default instances of embedded + // messages, which GetMessage() will return if the particular + // sub-message has not been initialized yet. (Thus, all + // embedded message fields *must* have non-NULL pointers + // in the default instance.) + // offsets: An array of ints giving the byte offsets, relative to + // the start of the message object, of each field. These can + // be computed at compile time using the + // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined + // below. + // has_bits_offset: Offset in the message of an array of uint32s of size + // descriptor->field_count()/32, rounded up. This is a + // bitfield where each bit indicates whether or not the + // corresponding field of the message has been initialized. + // The bit for field index i is obtained by the expression: + // has_bits[i / 32] & (1 << (i % 32)) + // unknown_fields_offset: Offset in the message of the UnknownFieldSet for + // the message. + // extensions_offset: Offset in the message of the ExtensionSet for the + // message, or -1 if the message type has no extension + // ranges. + // pool: DescriptorPool to search for extension definitions. Only + // used by FindKnownExtensionByName() and + // FindKnownExtensionByNumber(). + // factory: MessageFactory to use to construct extension messages. + // object_size: The size of a message object of this type, as measured + // by sizeof(). + GeneratedMessageReflection(const Descriptor* descriptor, + const Message* default_instance, + const int offsets[], + int has_bits_offset, + int unknown_fields_offset, + int extensions_offset, + const DescriptorPool* pool, + MessageFactory* factory, + int object_size, + int arena_offset, + int is_default_instance_offset = -1); + + // Similar with the construction above. Call this construction if the + // message has oneof definition. + // Parameters: + // offsets: An array of ints giving the byte offsets. + // For each oneof field, the offset is relative to the + // default_oneof_instance. These can be computed at compile + // time using the + // PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro. + // For each none oneof field, the offset is related to + // the start of the message object. These can be computed + // at compile time using the + // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro. + // Besides offsets for all fields, this array also contains + // offsets for oneof unions. The offset of the i-th oneof + // union is offsets[descriptor->field_count() + i]. + // default_oneof_instance: The default instance of the oneofs. It is a + // struct holding the default value of all oneof fields + // for this message. It is only used to obtain pointers + // to default instances of oneof fields, which Get + // methods will return if the field is not set. + // oneof_case_offset: Offset in the message of an array of uint32s of + // size descriptor->oneof_decl_count(). Each uint32 + // indicates what field is set for each oneof. + // other parameters are the same with the construction above. + GeneratedMessageReflection(const Descriptor* descriptor, + const Message* default_instance, + const int offsets[], + int has_bits_offset, + int unknown_fields_offset, + int extensions_offset, + const void* default_oneof_instance, + int oneof_case_offset, + const DescriptorPool* pool, + MessageFactory* factory, + int object_size, + int arena_offset, + int is_default_instance_offset = -1); + ~GeneratedMessageReflection(); + + // Shorter-to-call helpers for the above two constructions that work if the + // pool and factory are the usual, namely, DescriptorPool::generated_pool() + // and MessageFactory::generated_factory(). + + static GeneratedMessageReflection* NewGeneratedMessageReflection( + const Descriptor* descriptor, + const Message* default_instance, + const int offsets[], + int has_bits_offset, + int unknown_fields_offset, + int extensions_offset, + const void* default_oneof_instance, + int oneof_case_offset, + int object_size, + int arena_offset, + int is_default_instance_offset = -1); + + static GeneratedMessageReflection* NewGeneratedMessageReflection( + const Descriptor* descriptor, + const Message* default_instance, + const int offsets[], + int has_bits_offset, + int unknown_fields_offset, + int extensions_offset, + int object_size, + int arena_offset, + int is_default_instance_offset = -1); + + // implements Reflection ------------------------------------------- + + const UnknownFieldSet& GetUnknownFields(const Message& message) const; + UnknownFieldSet* MutableUnknownFields(Message* message) const; + + int SpaceUsed(const Message& message) const; + + bool HasField(const Message& message, const FieldDescriptor* field) const; + int FieldSize(const Message& message, const FieldDescriptor* field) const; + void ClearField(Message* message, const FieldDescriptor* field) const; + bool HasOneof(const Message& message, + const OneofDescriptor* oneof_descriptor) const; + void ClearOneof(Message* message, const OneofDescriptor* field) const; + void RemoveLast(Message* message, const FieldDescriptor* field) const; + Message* ReleaseLast(Message* message, const FieldDescriptor* field) const; + void Swap(Message* message1, Message* message2) const; + void SwapFields(Message* message1, Message* message2, + const vector& fields) const; + void SwapElements(Message* message, const FieldDescriptor* field, + int index1, int index2) const; + void ListFields(const Message& message, + vector* output) const; + + int32 GetInt32 (const Message& message, + const FieldDescriptor* field) const; + int64 GetInt64 (const Message& message, + const FieldDescriptor* field) const; + uint32 GetUInt32(const Message& message, + const FieldDescriptor* field) const; + uint64 GetUInt64(const Message& message, + const FieldDescriptor* field) const; + float GetFloat (const Message& message, + const FieldDescriptor* field) const; + double GetDouble(const Message& message, + const FieldDescriptor* field) const; + bool GetBool (const Message& message, + const FieldDescriptor* field) const; + string GetString(const Message& message, + const FieldDescriptor* field) const; + const string& GetStringReference(const Message& message, + const FieldDescriptor* field, + string* scratch) const; + const EnumValueDescriptor* GetEnum(const Message& message, + const FieldDescriptor* field) const; + int GetEnumValue(const Message& message, + const FieldDescriptor* field) const; + const Message& GetMessage(const Message& message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + + const FieldDescriptor* GetOneofFieldDescriptor( + const Message& message, + const OneofDescriptor* oneof_descriptor) const; + + private: + bool ContainsMapKey(const Message& message, + const FieldDescriptor* field, + const MapKey& key) const; + bool InsertOrLookupMapValue(Message* message, + const FieldDescriptor* field, + const MapKey& key, + MapValueRef* val) const; + bool DeleteMapValue(Message* message, + const FieldDescriptor* field, + const MapKey& key) const; + MapIterator MapBegin( + Message* message, + const FieldDescriptor* field) const; + MapIterator MapEnd( + Message* message, + const FieldDescriptor* field) const; + int MapSize(const Message& message, const FieldDescriptor* field) const; + + public: + void SetInt32 (Message* message, + const FieldDescriptor* field, int32 value) const; + void SetInt64 (Message* message, + const FieldDescriptor* field, int64 value) const; + void SetUInt32(Message* message, + const FieldDescriptor* field, uint32 value) const; + void SetUInt64(Message* message, + const FieldDescriptor* field, uint64 value) const; + void SetFloat (Message* message, + const FieldDescriptor* field, float value) const; + void SetDouble(Message* message, + const FieldDescriptor* field, double value) const; + void SetBool (Message* message, + const FieldDescriptor* field, bool value) const; + void SetString(Message* message, + const FieldDescriptor* field, + const string& value) const; + void SetEnum (Message* message, const FieldDescriptor* field, + const EnumValueDescriptor* value) const; + void SetEnumValue(Message* message, const FieldDescriptor* field, + int value) const; + Message* MutableMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + void SetAllocatedMessage(Message* message, + Message* sub_message, + const FieldDescriptor* field) const; + Message* ReleaseMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + + int32 GetRepeatedInt32 (const Message& message, + const FieldDescriptor* field, int index) const; + int64 GetRepeatedInt64 (const Message& message, + const FieldDescriptor* field, int index) const; + uint32 GetRepeatedUInt32(const Message& message, + const FieldDescriptor* field, int index) const; + uint64 GetRepeatedUInt64(const Message& message, + const FieldDescriptor* field, int index) const; + float GetRepeatedFloat (const Message& message, + const FieldDescriptor* field, int index) const; + double GetRepeatedDouble(const Message& message, + const FieldDescriptor* field, int index) const; + bool GetRepeatedBool (const Message& message, + const FieldDescriptor* field, int index) const; + string GetRepeatedString(const Message& message, + const FieldDescriptor* field, int index) const; + const string& GetRepeatedStringReference(const Message& message, + const FieldDescriptor* field, + int index, string* scratch) const; + const EnumValueDescriptor* GetRepeatedEnum(const Message& message, + const FieldDescriptor* field, + int index) const; + int GetRepeatedEnumValue(const Message& message, + const FieldDescriptor* field, + int index) const; + const Message& GetRepeatedMessage(const Message& message, + const FieldDescriptor* field, + int index) const; + + // Set the value of a field. + void SetRepeatedInt32 (Message* message, + const FieldDescriptor* field, int index, int32 value) const; + void SetRepeatedInt64 (Message* message, + const FieldDescriptor* field, int index, int64 value) const; + void SetRepeatedUInt32(Message* message, + const FieldDescriptor* field, int index, uint32 value) const; + void SetRepeatedUInt64(Message* message, + const FieldDescriptor* field, int index, uint64 value) const; + void SetRepeatedFloat (Message* message, + const FieldDescriptor* field, int index, float value) const; + void SetRepeatedDouble(Message* message, + const FieldDescriptor* field, int index, double value) const; + void SetRepeatedBool (Message* message, + const FieldDescriptor* field, int index, bool value) const; + void SetRepeatedString(Message* message, + const FieldDescriptor* field, int index, + const string& value) const; + void SetRepeatedEnum(Message* message, const FieldDescriptor* field, + int index, const EnumValueDescriptor* value) const; + void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field, + int index, int value) const; + // Get a mutable pointer to a field with a message type. + Message* MutableRepeatedMessage(Message* message, + const FieldDescriptor* field, + int index) const; + + void AddInt32 (Message* message, + const FieldDescriptor* field, int32 value) const; + void AddInt64 (Message* message, + const FieldDescriptor* field, int64 value) const; + void AddUInt32(Message* message, + const FieldDescriptor* field, uint32 value) const; + void AddUInt64(Message* message, + const FieldDescriptor* field, uint64 value) const; + void AddFloat (Message* message, + const FieldDescriptor* field, float value) const; + void AddDouble(Message* message, + const FieldDescriptor* field, double value) const; + void AddBool (Message* message, + const FieldDescriptor* field, bool value) const; + void AddString(Message* message, + const FieldDescriptor* field, const string& value) const; + void AddEnum(Message* message, + const FieldDescriptor* field, + const EnumValueDescriptor* value) const; + void AddEnumValue(Message* message, + const FieldDescriptor* field, + int value) const; + Message* AddMessage(Message* message, const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + void AddAllocatedMessage( + Message* message, const FieldDescriptor* field, + Message* new_entry) const; + + const FieldDescriptor* FindKnownExtensionByName(const string& name) const; + const FieldDescriptor* FindKnownExtensionByNumber(int number) const; + + bool SupportsUnknownEnumValues() const; + + // This value for arena_offset_ indicates that there is no arena pointer in + // this message (e.g., old generated code). + static const int kNoArenaPointer = -1; + + // This value for unknown_field_offset_ indicates that there is no + // UnknownFieldSet in this message, and that instead, we are using the + // Zero-Overhead Arena Pointer trick. When this is the case, arena_offset_ + // actually indexes to an InternalMetadataWithArena instance, which can return + // either an arena pointer or an UnknownFieldSet or both. It is never the case + // that unknown_field_offset_ == kUnknownFieldSetInMetadata && arena_offset_ + // == kNoArenaPointer. + static const int kUnknownFieldSetInMetadata = -1; + + protected: + void* MutableRawRepeatedField( + Message* message, const FieldDescriptor* field, FieldDescriptor::CppType, + int ctype, const Descriptor* desc) const; + + const void* GetRawRepeatedField( + const Message& message, const FieldDescriptor* field, + FieldDescriptor::CppType, int ctype, + const Descriptor* desc) const; + + virtual MessageFactory* GetMessageFactory() const; + + virtual void* RepeatedFieldData( + Message* message, const FieldDescriptor* field, + FieldDescriptor::CppType cpp_type, + const Descriptor* message_type) const; + + private: + friend class GeneratedMessage; + + // To parse directly into a proto2 generated class, the class GMR_Handlers + // needs access to member offsets and hasbits. + friend class upb::google_opensource::GMR_Handlers; + + const Descriptor* descriptor_; + const Message* default_instance_; + const void* default_oneof_instance_; + const int* offsets_; + + int has_bits_offset_; + int oneof_case_offset_; + int unknown_fields_offset_; + int extensions_offset_; + int arena_offset_; + int is_default_instance_offset_; + int object_size_; + + static const int kHasNoDefaultInstanceField = -1; + + const DescriptorPool* descriptor_pool_; + MessageFactory* message_factory_; + + template + inline const Type& GetRaw(const Message& message, + const FieldDescriptor* field) const; + template + inline Type* MutableRaw(Message* message, + const FieldDescriptor* field) const; + template + inline const Type& DefaultRaw(const FieldDescriptor* field) const; + template + inline const Type& DefaultOneofRaw(const FieldDescriptor* field) const; + + inline const uint32* GetHasBits(const Message& message) const; + inline uint32* MutableHasBits(Message* message) const; + inline uint32 GetOneofCase( + const Message& message, + const OneofDescriptor* oneof_descriptor) const; + inline uint32* MutableOneofCase( + Message* message, + const OneofDescriptor* oneof_descriptor) const; + inline const ExtensionSet& GetExtensionSet(const Message& message) const; + inline ExtensionSet* MutableExtensionSet(Message* message) const; + inline Arena* GetArena(Message* message) const; + inline const internal::InternalMetadataWithArena& + GetInternalMetadataWithArena(const Message& message) const; + inline internal::InternalMetadataWithArena* + MutableInternalMetadataWithArena(Message* message) const; + + inline bool GetIsDefaultInstance(const Message& message) const; + + inline bool HasBit(const Message& message, + const FieldDescriptor* field) const; + inline void SetBit(Message* message, + const FieldDescriptor* field) const; + inline void ClearBit(Message* message, + const FieldDescriptor* field) const; + inline void SwapBit(Message* message1, + Message* message2, + const FieldDescriptor* field) const; + + // This function only swaps the field. Should swap corresponding has_bit + // before or after using this function. + void SwapField(Message* message1, + Message* message2, + const FieldDescriptor* field) const; + + void SwapOneofField(Message* message1, + Message* message2, + const OneofDescriptor* oneof_descriptor) const; + + inline bool HasOneofField(const Message& message, + const FieldDescriptor* field) const; + inline void SetOneofCase(Message* message, + const FieldDescriptor* field) const; + inline void ClearOneofField(Message* message, + const FieldDescriptor* field) const; + + template + inline const Type& GetField(const Message& message, + const FieldDescriptor* field) const; + template + inline void SetField(Message* message, + const FieldDescriptor* field, const Type& value) const; + template + inline Type* MutableField(Message* message, + const FieldDescriptor* field) const; + template + inline const Type& GetRepeatedField(const Message& message, + const FieldDescriptor* field, + int index) const; + template + inline const Type& GetRepeatedPtrField(const Message& message, + const FieldDescriptor* field, + int index) const; + template + inline void SetRepeatedField(Message* message, + const FieldDescriptor* field, int index, + Type value) const; + template + inline Type* MutableRepeatedField(Message* message, + const FieldDescriptor* field, + int index) const; + template + inline void AddField(Message* message, + const FieldDescriptor* field, const Type& value) const; + template + inline Type* AddField(Message* message, + const FieldDescriptor* field) const; + + int GetExtensionNumberOrDie(const Descriptor* type) const; + + // Internal versions of EnumValue API perform no checking. Called after checks + // by public methods. + void SetEnumValueInternal(Message* message, + const FieldDescriptor* field, + int value) const; + void SetRepeatedEnumValueInternal(Message* message, + const FieldDescriptor* field, + int index, + int value) const; + void AddEnumValueInternal(Message* message, + const FieldDescriptor* field, + int value) const; + + + Message* UnsafeArenaReleaseMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const; + + void UnsafeArenaSetAllocatedMessage(Message* message, + Message* sub_message, + const FieldDescriptor* field) const; + + internal::MapFieldBase* MapData( + Message* message, const FieldDescriptor* field) const; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); +}; + +// Returns the offset of the given field within the given aggregate type. +// This is equivalent to the ANSI C offsetof() macro. However, according +// to the C++ standard, offsetof() only works on POD types, and GCC +// enforces this requirement with a warning. In practice, this rule is +// unnecessarily strict; there is probably no compiler or platform on +// which the offsets of the direct fields of a class are non-constant. +// Fields inherited from superclasses *can* have non-constant offsets, +// but that's not what this macro will be used for. +#if defined(__clang__) +// For Clang we use __builtin_offsetof() and suppress the warning, +// to avoid Control Flow Integrity and UBSan vptr sanitizers from +// crashing while trying to validate the invalid reinterpet_casts. +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \ + __builtin_offsetof(TYPE, FIELD) \ + _Pragma("clang diagnostic pop") +#else +// Note that we calculate relative to the pointer value 16 here since if we +// just use zero, GCC complains about dereferencing a NULL pointer. We +// choose 16 rather than some other number just in case the compiler would +// be confused by an unaligned pointer. +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ + static_cast( \ + reinterpret_cast( \ + &reinterpret_cast(16)->FIELD) - \ + reinterpret_cast(16)) +#endif + +#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \ + static_cast( \ + reinterpret_cast(&(ONEOF->FIELD)) \ + - reinterpret_cast(ONEOF)) + +// There are some places in proto2 where dynamic_cast would be useful as an +// optimization. For example, take Message::MergeFrom(const Message& other). +// For a given generated message FooMessage, we generate these two methods: +// void MergeFrom(const FooMessage& other); +// void MergeFrom(const Message& other); +// The former method can be implemented directly in terms of FooMessage's +// inline accessors, but the latter method must work with the reflection +// interface. However, if the parameter to the latter method is actually of +// type FooMessage, then we'd like to be able to just call the other method +// as an optimization. So, we use dynamic_cast to check this. +// +// That said, dynamic_cast requires RTTI, which many people like to disable +// for performance and code size reasons. When RTTI is not available, we +// still need to produce correct results. So, in this case we have to fall +// back to using reflection, which is what we would have done anyway if the +// objects were not of the exact same class. +// +// dynamic_cast_if_available() implements this logic. If RTTI is +// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns +// NULL. +// +// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI. +// On MSVC, this should be detected automatically. +template +inline To dynamic_cast_if_available(From from) { +#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI)) + return NULL; +#else + return dynamic_cast(from); +#endif +} + +// Tries to downcast this message to a generated message type. +// Returns NULL if this class is not an instance of T. +// +// This is like dynamic_cast_if_available, except it works even when +// dynamic_cast is not available by using Reflection. However it only works +// with Message objects. +// +// TODO(haberman): can we remove dynamic_cast_if_available in favor of this? +template +T* DynamicCastToGenerated(const Message* from) { + // Compile-time assert that T is a generated type that has a + // default_instance() accessor, but avoid actually calling it. + const T&(*get_default_instance)() = &T::default_instance; + (void)get_default_instance; + + // Compile-time assert that T is a subclass of google::protobuf::Message. + const Message* unused = static_cast(NULL); + (void)unused; + +#if defined(GOOGLE_PROTOBUF_NO_RTTI) || \ + (defined(_MSC_VER) && !defined(_CPPRTTI)) + bool ok = &T::default_instance() == + from->GetReflection()->GetMessageFactory()->GetPrototype( + from->GetDescriptor()); + return ok ? down_cast(from) : NULL; +#else + return dynamic_cast(from); +#endif +} + +template +T* DynamicCastToGenerated(Message* from) { + const Message* message_const = from; + return const_cast(DynamicCastToGenerated(message_const)); +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ diff --git a/thirdparty/linux/include/google/protobuf/generated_message_util.h b/thirdparty/linux/include/google/protobuf/generated_message_util.h new file mode 100644 index 0000000..8967726 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/generated_message_util.h @@ -0,0 +1,127 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains miscellaneous helper code used by generated code -- +// including lite types -- but which should not be used directly by users. + +#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ + +#include +#include + +#include +#include + +namespace google { + +namespace protobuf { + +class Arena; +namespace io { class CodedInputStream; } + +namespace internal { + + +// Annotation for the compiler to emit a deprecation message if a field marked +// with option 'deprecated=true' is used in the code, or for other things in +// generated code which are deprecated. +// +// For internal use in the pb.cc files, deprecation warnings are suppressed +// there. +#undef DEPRECATED_PROTOBUF_FIELD +#define PROTOBUF_DEPRECATED + +#define GOOGLE_PROTOBUF_DEPRECATED_ATTR + + +// Constants for special floating point values. +LIBPROTOBUF_EXPORT double Infinity(); +LIBPROTOBUF_EXPORT double NaN(); + +// TODO(jieluo): Change to template. We have tried to use template, +// but it causes net/rpc/python:rpcutil_test fail (the empty string will +// init twice). It may related to swig. Change to template after we +// found the solution. + +// Default empty string object. Don't use the pointer directly. Instead, call +// GetEmptyString() to get the reference. +LIBPROTOBUF_EXPORT extern const ::std::string* empty_string_; +LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_; +LIBPROTOBUF_EXPORT void InitEmptyString(); + + +LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() { + assert(empty_string_ != NULL); + return *empty_string_; +} +LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() { + ::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString); + return GetEmptyStringAlreadyInited(); +} + +LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); + + +// True if IsInitialized() is true for all elements of t. Type is expected +// to be a RepeatedPtrField. It's useful to have this +// helper here to keep the protobuf compiler from ever having to emit loops in +// IsInitialized() methods. We want the C++ compiler to inline this or not +// as it sees fit. +template bool AllAreInitialized(const Type& t) { + for (int i = t.size(); --i >= 0; ) { + if (!t.Get(i).IsInitialized()) return false; + } + return true; +} + +class ArenaString; + +// Read a length (varint32), followed by a string, from *input. Return a +// pointer to a copy of the string that resides in *arena. Requires both +// args to be non-NULL. If something goes wrong while reading the data +// then NULL is returned (e.g., input does not start with a valid varint). +LIBPROTOBUF_EXPORT ArenaString* ReadArenaString( + ::google::protobuf::io::CodedInputStream* input, + ::google::protobuf::Arena* arena); + +// Helper function to crash on merge failure. +// Moved out of generated code to reduce binary size. +LIBPROTOBUF_EXPORT void MergeFromFail(const char* file, int line) GOOGLE_ATTRIBUTE_NORETURN; + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ diff --git a/thirdparty/linux/include/google/protobuf/io/coded_stream.h b/thirdparty/linux/include/google/protobuf/io/coded_stream.h new file mode 100644 index 0000000..316da76 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/io/coded_stream.h @@ -0,0 +1,1367 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains the CodedInputStream and CodedOutputStream classes, +// which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, +// and allow you to read or write individual pieces of data in various +// formats. In particular, these implement the varint encoding for +// integers, a simple variable-length encoding in which smaller numbers +// take fewer bytes. +// +// Typically these classes will only be used internally by the protocol +// buffer library in order to encode and decode protocol buffers. Clients +// of the library only need to know about this class if they wish to write +// custom message parsing or serialization procedures. +// +// CodedOutputStream example: +// // Write some data to "myfile". First we write a 4-byte "magic number" +// // to identify the file type, then write a length-delimited string. The +// // string is composed of a varint giving the length followed by the raw +// // bytes. +// int fd = open("myfile", O_CREAT | O_WRONLY); +// ZeroCopyOutputStream* raw_output = new FileOutputStream(fd); +// CodedOutputStream* coded_output = new CodedOutputStream(raw_output); +// +// int magic_number = 1234; +// char text[] = "Hello world!"; +// coded_output->WriteLittleEndian32(magic_number); +// coded_output->WriteVarint32(strlen(text)); +// coded_output->WriteRaw(text, strlen(text)); +// +// delete coded_output; +// delete raw_output; +// close(fd); +// +// CodedInputStream example: +// // Read a file created by the above code. +// int fd = open("myfile", O_RDONLY); +// ZeroCopyInputStream* raw_input = new FileInputStream(fd); +// CodedInputStream coded_input = new CodedInputStream(raw_input); +// +// coded_input->ReadLittleEndian32(&magic_number); +// if (magic_number != 1234) { +// cerr << "File not in expected format." << endl; +// return; +// } +// +// uint32 size; +// coded_input->ReadVarint32(&size); +// +// char* text = new char[size + 1]; +// coded_input->ReadRaw(buffer, size); +// text[size] = '\0'; +// +// delete coded_input; +// delete raw_input; +// close(fd); +// +// cout << "Text is: " << text << endl; +// delete [] text; +// +// For those who are interested, varint encoding is defined as follows: +// +// The encoding operates on unsigned integers of up to 64 bits in length. +// Each byte of the encoded value has the format: +// * bits 0-6: Seven bits of the number being encoded. +// * bit 7: Zero if this is the last byte in the encoding (in which +// case all remaining bits of the number are zero) or 1 if +// more bytes follow. +// The first byte contains the least-significant 7 bits of the number, the +// second byte (if present) contains the next-least-significant 7 bits, +// and so on. So, the binary number 1011000101011 would be encoded in two +// bytes as "10101011 00101100". +// +// In theory, varint could be used to encode integers of any length. +// However, for practicality we set a limit at 64 bits. The maximum encoded +// length of a number is thus 10 bytes. + +#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ + +#include +#include +#include +#ifdef _MSC_VER + // Assuming windows is always little-endian. + #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif + #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) + // If MSVC has "/RTCc" set, it will complain about truncating casts at + // runtime. This file contains some intentional truncating casts. + #pragma runtime_checks("c", off) + #endif +#else + #include // __BYTE_ORDER + #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ + (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \ + !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif +#endif +#include + +namespace google { + +namespace protobuf { + +class DescriptorPool; +class MessageFactory; + +namespace io { + +// Defined in this file. +class CodedInputStream; +class CodedOutputStream; + +// Defined in other files. +class ZeroCopyInputStream; // zero_copy_stream.h +class ZeroCopyOutputStream; // zero_copy_stream.h + +// Class which reads and decodes binary data which is composed of varint- +// encoded integers and fixed-width pieces. Wraps a ZeroCopyInputStream. +// Most users will not need to deal with CodedInputStream. +// +// Most methods of CodedInputStream that return a bool return false if an +// underlying I/O error occurs or if the data is malformed. Once such a +// failure occurs, the CodedInputStream is broken and is no longer useful. +class LIBPROTOBUF_EXPORT CodedInputStream { + public: + // Create a CodedInputStream that reads from the given ZeroCopyInputStream. + explicit CodedInputStream(ZeroCopyInputStream* input); + + // Create a CodedInputStream that reads from the given flat array. This is + // faster than using an ArrayInputStream. PushLimit(size) is implied by + // this constructor. + explicit CodedInputStream(const uint8* buffer, int size); + + // Destroy the CodedInputStream and position the underlying + // ZeroCopyInputStream at the first unread byte. If an error occurred while + // reading (causing a method to return false), then the exact position of + // the input stream may be anywhere between the last value that was read + // successfully and the stream's byte limit. + ~CodedInputStream(); + + // Return true if this CodedInputStream reads from a flat array instead of + // a ZeroCopyInputStream. + inline bool IsFlat() const; + + // Skips a number of bytes. Returns false if an underlying read error + // occurs. + bool Skip(int count); + + // Sets *data to point directly at the unread part of the CodedInputStream's + // underlying buffer, and *size to the size of that buffer, but does not + // advance the stream's current position. This will always either produce + // a non-empty buffer or return false. If the caller consumes any of + // this data, it should then call Skip() to skip over the consumed bytes. + // This may be useful for implementing external fast parsing routines for + // types of data not covered by the CodedInputStream interface. + bool GetDirectBufferPointer(const void** data, int* size); + + // Like GetDirectBufferPointer, but this method is inlined, and does not + // attempt to Refresh() if the buffer is currently empty. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void GetDirectBufferPointerInline(const void** data, + int* size); + + // Read raw bytes, copying them into the given buffer. + bool ReadRaw(void* buffer, int size); + + // Like the above, with inlined optimizations. This should only be used + // by the protobuf implementation. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InternalReadRawInline(void* buffer, int size); + + // Like ReadRaw, but reads into a string. + // + // Implementation Note: ReadString() grows the string gradually as it + // reads in the data, rather than allocating the entire requested size + // upfront. This prevents denial-of-service attacks in which a client + // could claim that a string is going to be MAX_INT bytes long in order to + // crash the server because it can't allocate this much space at once. + bool ReadString(string* buffer, int size); + // Like the above, with inlined optimizations. This should only be used + // by the protobuf implementation. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InternalReadStringInline(string* buffer, + int size); + + + // Read a 32-bit little-endian integer. + bool ReadLittleEndian32(uint32* value); + // Read a 64-bit little-endian integer. + bool ReadLittleEndian64(uint64* value); + + // These methods read from an externally provided buffer. The caller is + // responsible for ensuring that the buffer has sufficient space. + // Read a 32-bit little-endian integer. + static const uint8* ReadLittleEndian32FromArray(const uint8* buffer, + uint32* value); + // Read a 64-bit little-endian integer. + static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, + uint64* value); + + // Read an unsigned integer with Varint encoding, truncating to 32 bits. + // Reading a 32-bit value is equivalent to reading a 64-bit one and casting + // it to uint32, but may be more efficient. + bool ReadVarint32(uint32* value); + // Read an unsigned integer with Varint encoding. + bool ReadVarint64(uint64* value); + + // Reads a varint off the wire into an "int". This should be used for reading + // sizes off the wire (sizes of strings, submessages, bytes fields, etc). + // + // The value from the wire is interpreted as unsigned. If its value exceeds + // the representable value of an integer on this platform, instead of + // truncating we return false. Truncating (as performed by ReadVarint32() + // above) is an acceptable approach for fields representing an integer, but + // when we are parsing a size from the wire, truncating the value would result + // in us misparsing the payload. + bool ReadVarintSizeAsInt(int* value); + + // Read a tag. This calls ReadVarint32() and returns the result, or returns + // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates + // the last tag value, which can be checked with LastTagWas(). + // Always inline because this is only called in one place per parse loop + // but it is called for every iteration of said loop, so it should be fast. + // GCC doesn't want to inline this by default. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag(); + + // This usually a faster alternative to ReadTag() when cutoff is a manifest + // constant. It does particularly well for cutoff >= 127. The first part + // of the return value is the tag that was read, though it can also be 0 in + // the cases where ReadTag() would return 0. If the second part is true + // then the tag is known to be in [0, cutoff]. If not, the tag either is + // above cutoff or is 0. (There's intentional wiggle room when tag is 0, + // because that can arise in several ways, and for best performance we want + // to avoid an extra "is tag == 0?" check here.) + GOOGLE_ATTRIBUTE_ALWAYS_INLINE std::pair ReadTagWithCutoff( + uint32 cutoff); + + // Usually returns true if calling ReadVarint32() now would produce the given + // value. Will always return false if ReadVarint32() would not return the + // given value. If ExpectTag() returns true, it also advances past + // the varint. For best performance, use a compile-time constant as the + // parameter. + // Always inline because this collapses to a small number of instructions + // when given a constant parameter, but GCC doesn't want to inline by default. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool ExpectTag(uint32 expected); + + // Like above, except this reads from the specified buffer. The caller is + // responsible for ensuring that the buffer is large enough to read a varint + // of the expected size. For best performance, use a compile-time constant as + // the expected tag parameter. + // + // Returns a pointer beyond the expected tag if it was found, or NULL if it + // was not. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static const uint8* ExpectTagFromArray( + const uint8* buffer, + uint32 expected); + + // Usually returns true if no more bytes can be read. Always returns false + // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent + // call to LastTagWas() will act as if ReadTag() had been called and returned + // zero, and ConsumedEntireMessage() will return true. + bool ExpectAtEnd(); + + // If the last call to ReadTag() or ReadTagWithCutoff() returned the + // given value, returns true. Otherwise, returns false; + // + // This is needed because parsers for some types of embedded messages + // (with field type TYPE_GROUP) don't actually know that they've reached the + // end of a message until they see an ENDGROUP tag, which was actually part + // of the enclosing message. The enclosing message would like to check that + // tag to make sure it had the right number, so it calls LastTagWas() on + // return from the embedded parser to check. + bool LastTagWas(uint32 expected); + + // When parsing message (but NOT a group), this method must be called + // immediately after MergeFromCodedStream() returns (if it returns true) + // to further verify that the message ended in a legitimate way. For + // example, this verifies that parsing did not end on an end-group tag. + // It also checks for some cases where, due to optimizations, + // MergeFromCodedStream() can incorrectly return true. + bool ConsumedEntireMessage(); + + // Limits ---------------------------------------------------------- + // Limits are used when parsing length-delimited embedded messages. + // After the message's length is read, PushLimit() is used to prevent + // the CodedInputStream from reading beyond that length. Once the + // embedded message has been parsed, PopLimit() is called to undo the + // limit. + + // Opaque type used with PushLimit() and PopLimit(). Do not modify + // values of this type yourself. The only reason that this isn't a + // struct with private internals is for efficiency. + typedef int Limit; + + // Places a limit on the number of bytes that the stream may read, + // starting from the current position. Once the stream hits this limit, + // it will act like the end of the input has been reached until PopLimit() + // is called. + // + // As the names imply, the stream conceptually has a stack of limits. The + // shortest limit on the stack is always enforced, even if it is not the + // top limit. + // + // The value returned by PushLimit() is opaque to the caller, and must + // be passed unchanged to the corresponding call to PopLimit(). + Limit PushLimit(int byte_limit); + + // Pops the last limit pushed by PushLimit(). The input must be the value + // returned by that call to PushLimit(). + void PopLimit(Limit limit); + + // Returns the number of bytes left until the nearest limit on the + // stack is hit, or -1 if no limits are in place. + int BytesUntilLimit() const; + + // Returns current position relative to the beginning of the input stream. + int CurrentPosition() const; + + // Total Bytes Limit ----------------------------------------------- + // To prevent malicious users from sending excessively large messages + // and causing integer overflows or memory exhaustion, CodedInputStream + // imposes a hard limit on the total number of bytes it will read. + + // Sets the maximum number of bytes that this CodedInputStream will read + // before refusing to continue. To prevent integer overflows in the + // protocol buffers implementation, as well as to prevent servers from + // allocating enormous amounts of memory to hold parsed messages, the + // maximum message length should be limited to the shortest length that + // will not harm usability. The theoretical shortest message that could + // cause integer overflows is 512MB. The default limit is 64MB. Apps + // should set shorter limits if possible. If warning_threshold is not -1, + // a warning will be printed to stderr after warning_threshold bytes are + // read. For backwards compatibility all negative values get squashed to -1, + // as other negative values might have special internal meanings. + // An error will always be printed to stderr if the limit is reached. + // + // This is unrelated to PushLimit()/PopLimit(). + // + // Hint: If you are reading this because your program is printing a + // warning about dangerously large protocol messages, you may be + // confused about what to do next. The best option is to change your + // design such that excessively large messages are not necessary. + // For example, try to design file formats to consist of many small + // messages rather than a single large one. If this is infeasible, + // you will need to increase the limit. Chances are, though, that + // your code never constructs a CodedInputStream on which the limit + // can be set. You probably parse messages by calling things like + // Message::ParseFromString(). In this case, you will need to change + // your code to instead construct some sort of ZeroCopyInputStream + // (e.g. an ArrayInputStream), construct a CodedInputStream around + // that, then call Message::ParseFromCodedStream() instead. Then + // you can adjust the limit. Yes, it's more work, but you're doing + // something unusual. + void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold); + + // The Total Bytes Limit minus the Current Position, or -1 if there + // is no Total Bytes Limit. + int BytesUntilTotalBytesLimit() const; + + // Recursion Limit ------------------------------------------------- + // To prevent corrupt or malicious messages from causing stack overflows, + // we must keep track of the depth of recursion when parsing embedded + // messages and groups. CodedInputStream keeps track of this because it + // is the only object that is passed down the stack during parsing. + + // Sets the maximum recursion depth. The default is 100. + void SetRecursionLimit(int limit); + + + // Increments the current recursion depth. Returns true if the depth is + // under the limit, false if it has gone over. + bool IncrementRecursionDepth(); + + // Decrements the recursion depth if possible. + void DecrementRecursionDepth(); + + // Decrements the recursion depth blindly. This is faster than + // DecrementRecursionDepth(). It should be used only if all previous + // increments to recursion depth were successful. + void UnsafeDecrementRecursionDepth(); + + // Shorthand for make_pair(PushLimit(byte_limit), --recursion_budget_). + // Using this can reduce code size and complexity in some cases. The caller + // is expected to check that the second part of the result is non-negative (to + // bail out if the depth of recursion is too high) and, if all is well, to + // later pass the first part of the result to PopLimit() or similar. + std::pair IncrementRecursionDepthAndPushLimit( + int byte_limit); + + // Shorthand for PushLimit(ReadVarint32(&length) ? length : 0). + Limit ReadLengthAndPushLimit(); + + // Helper that is equivalent to: { + // bool result = ConsumedEntireMessage(); + // PopLimit(limit); + // UnsafeDecrementRecursionDepth(); + // return result; } + // Using this can reduce code size and complexity in some cases. + // Do not use unless the current recursion depth is greater than zero. + bool DecrementRecursionDepthAndPopLimit(Limit limit); + + // Helper that is equivalent to: { + // bool result = ConsumedEntireMessage(); + // PopLimit(limit); + // return result; } + // Using this can reduce code size and complexity in some cases. + bool CheckEntireMessageConsumedAndPopLimit(Limit limit); + + // Extension Registry ---------------------------------------------- + // ADVANCED USAGE: 99.9% of people can ignore this section. + // + // By default, when parsing extensions, the parser looks for extension + // definitions in the pool which owns the outer message's Descriptor. + // However, you may call SetExtensionRegistry() to provide an alternative + // pool instead. This makes it possible, for example, to parse a message + // using a generated class, but represent some extensions using + // DynamicMessage. + + // Set the pool used to look up extensions. Most users do not need to call + // this as the correct pool will be chosen automatically. + // + // WARNING: It is very easy to misuse this. Carefully read the requirements + // below. Do not use this unless you are sure you need it. Almost no one + // does. + // + // Let's say you are parsing a message into message object m, and you want + // to take advantage of SetExtensionRegistry(). You must follow these + // requirements: + // + // The given DescriptorPool must contain m->GetDescriptor(). It is not + // sufficient for it to simply contain a descriptor that has the same name + // and content -- it must be the *exact object*. In other words: + // assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) == + // m->GetDescriptor()); + // There are two ways to satisfy this requirement: + // 1) Use m->GetDescriptor()->pool() as the pool. This is generally useless + // because this is the pool that would be used anyway if you didn't call + // SetExtensionRegistry() at all. + // 2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an + // "underlay". Read the documentation for DescriptorPool for more + // information about underlays. + // + // You must also provide a MessageFactory. This factory will be used to + // construct Message objects representing extensions. The factory's + // GetPrototype() MUST return non-NULL for any Descriptor which can be found + // through the provided pool. + // + // If the provided factory might return instances of protocol-compiler- + // generated (i.e. compiled-in) types, or if the outer message object m is + // a generated type, then the given factory MUST have this property: If + // GetPrototype() is given a Descriptor which resides in + // DescriptorPool::generated_pool(), the factory MUST return the same + // prototype which MessageFactory::generated_factory() would return. That + // is, given a descriptor for a generated type, the factory must return an + // instance of the generated class (NOT DynamicMessage). However, when + // given a descriptor for a type that is NOT in generated_pool, the factory + // is free to return any implementation. + // + // The reason for this requirement is that generated sub-objects may be + // accessed via the standard (non-reflection) extension accessor methods, + // and these methods will down-cast the object to the generated class type. + // If the object is not actually of that type, the results would be undefined. + // On the other hand, if an extension is not compiled in, then there is no + // way the code could end up accessing it via the standard accessors -- the + // only way to access the extension is via reflection. When using reflection, + // DynamicMessage and generated messages are indistinguishable, so it's fine + // if these objects are represented using DynamicMessage. + // + // Using DynamicMessageFactory on which you have called + // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the + // above requirement. + // + // If either pool or factory is NULL, both must be NULL. + // + // Note that this feature is ignored when parsing "lite" messages as they do + // not have descriptors. + void SetExtensionRegistry(const DescriptorPool* pool, + MessageFactory* factory); + + // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool + // has been provided. + const DescriptorPool* GetExtensionPool(); + + // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no + // factory has been provided. + MessageFactory* GetExtensionFactory(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); + + const uint8* buffer_; + const uint8* buffer_end_; // pointer to the end of the buffer. + ZeroCopyInputStream* input_; + int total_bytes_read_; // total bytes read from input_, including + // the current buffer + + // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here + // so that we can BackUp() on destruction. + int overflow_bytes_; + + // LastTagWas() stuff. + uint32 last_tag_; // result of last ReadTag() or ReadTagWithCutoff(). + + // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly + // at EOF, or by ExpectAtEnd() when it returns true. This happens when we + // reach the end of a message and attempt to read another tag. + bool legitimate_message_end_; + + // See EnableAliasing(). + bool aliasing_enabled_; + + // Limits + Limit current_limit_; // if position = -1, no limit is applied + + // For simplicity, if the current buffer crosses a limit (either a normal + // limit created by PushLimit() or the total bytes limit), buffer_size_ + // only tracks the number of bytes before that limit. This field + // contains the number of bytes after it. Note that this implies that if + // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've + // hit a limit. However, if both are zero, it doesn't necessarily mean + // we aren't at a limit -- the buffer may have ended exactly at the limit. + int buffer_size_after_limit_; + + // Maximum number of bytes to read, period. This is unrelated to + // current_limit_. Set using SetTotalBytesLimit(). + int total_bytes_limit_; + + // If positive/0: Limit for bytes read after which a warning due to size + // should be logged. + // If -1: Printing of warning disabled. Can be set by client. + // If -2: Internal: Limit has been reached, print full size when destructing. + int total_bytes_warning_threshold_; + + // Current recursion budget, controlled by IncrementRecursionDepth() and + // similar. Starts at recursion_limit_ and goes down: if this reaches + // -1 we are over budget. + int recursion_budget_; + // Recursion depth limit, set by SetRecursionLimit(). + int recursion_limit_; + + // See SetExtensionRegistry(). + const DescriptorPool* extension_pool_; + MessageFactory* extension_factory_; + + // Private member functions. + + // Advance the buffer by a given number of bytes. + void Advance(int amount); + + // Back up input_ to the current buffer position. + void BackUpInputToCurrentPosition(); + + // Recomputes the value of buffer_size_after_limit_. Must be called after + // current_limit_ or total_bytes_limit_ changes. + void RecomputeBufferLimits(); + + // Writes an error message saying that we hit total_bytes_limit_. + void PrintTotalBytesLimitError(); + + // Called when the buffer runs out to request more data. Implies an + // Advance(BufferSize()). + bool Refresh(); + + // When parsing varints, we optimize for the common case of small values, and + // then optimize for the case when the varint fits within the current buffer + // piece. The Fallback method is used when we can't use the one-byte + // optimization. The Slow method is yet another fallback when the buffer is + // not large enough. Making the slow path out-of-line speeds up the common + // case by 10-15%. The slow path is fairly uncommon: it only triggers when a + // message crosses multiple buffers. Note: ReadVarint32Fallback() and + // ReadVarint64Fallback() are called frequently and generally not inlined, so + // they have been optimized to avoid "out" parameters. The former returns -1 + // if it fails and the uint32 it read otherwise. The latter has a bool + // indicating success or failure as part of its return type. + int64 ReadVarint32Fallback(uint32 first_byte_or_zero); + int ReadVarintSizeAsIntFallback(); + std::pair ReadVarint64Fallback(); + bool ReadVarint32Slow(uint32* value); + bool ReadVarint64Slow(uint64* value); + int ReadVarintSizeAsIntSlow(); + bool ReadLittleEndian32Fallback(uint32* value); + bool ReadLittleEndian64Fallback(uint64* value); + // Fallback/slow methods for reading tags. These do not update last_tag_, + // but will set legitimate_message_end_ if we are at the end of the input + // stream. + uint32 ReadTagFallback(uint32 first_byte_or_zero); + uint32 ReadTagSlow(); + bool ReadStringFallback(string* buffer, int size); + + // Return the size of the buffer. + int BufferSize() const; + + static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB + + static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB + + static int default_recursion_limit_; // 100 by default. +}; + +// Class which encodes and writes binary data which is composed of varint- +// encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. +// Most users will not need to deal with CodedOutputStream. +// +// Most methods of CodedOutputStream which return a bool return false if an +// underlying I/O error occurs. Once such a failure occurs, the +// CodedOutputStream is broken and is no longer useful. The Write* methods do +// not return the stream status, but will invalidate the stream if an error +// occurs. The client can probe HadError() to determine the status. +// +// Note that every method of CodedOutputStream which writes some data has +// a corresponding static "ToArray" version. These versions write directly +// to the provided buffer, returning a pointer past the last written byte. +// They require that the buffer has sufficient capacity for the encoded data. +// This allows an optimization where we check if an output stream has enough +// space for an entire message before we start writing and, if there is, we +// call only the ToArray methods to avoid doing bound checks for each +// individual value. +// i.e., in the example above: +// +// CodedOutputStream coded_output = new CodedOutputStream(raw_output); +// int magic_number = 1234; +// char text[] = "Hello world!"; +// +// int coded_size = sizeof(magic_number) + +// CodedOutputStream::VarintSize32(strlen(text)) + +// strlen(text); +// +// uint8* buffer = +// coded_output->GetDirectBufferForNBytesAndAdvance(coded_size); +// if (buffer != NULL) { +// // The output stream has enough space in the buffer: write directly to +// // the array. +// buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number, +// buffer); +// buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer); +// buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer); +// } else { +// // Make bound-checked writes, which will ask the underlying stream for +// // more space as needed. +// coded_output->WriteLittleEndian32(magic_number); +// coded_output->WriteVarint32(strlen(text)); +// coded_output->WriteRaw(text, strlen(text)); +// } +// +// delete coded_output; +class LIBPROTOBUF_EXPORT CodedOutputStream { + public: + // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream. + explicit CodedOutputStream(ZeroCopyOutputStream* output); + CodedOutputStream(ZeroCopyOutputStream* output, bool do_eager_refresh); + + // Destroy the CodedOutputStream and position the underlying + // ZeroCopyOutputStream immediately after the last byte written. + ~CodedOutputStream(); + + // Trims any unused space in the underlying buffer so that its size matches + // the number of bytes written by this stream. The underlying buffer will + // automatically be trimmed when this stream is destroyed; this call is only + // necessary if the underlying buffer is accessed *before* the stream is + // destroyed. + void Trim(); + + // Skips a number of bytes, leaving the bytes unmodified in the underlying + // buffer. Returns false if an underlying write error occurs. This is + // mainly useful with GetDirectBufferPointer(). + bool Skip(int count); + + // Sets *data to point directly at the unwritten part of the + // CodedOutputStream's underlying buffer, and *size to the size of that + // buffer, but does not advance the stream's current position. This will + // always either produce a non-empty buffer or return false. If the caller + // writes any data to this buffer, it should then call Skip() to skip over + // the consumed bytes. This may be useful for implementing external fast + // serialization routines for types of data not covered by the + // CodedOutputStream interface. + bool GetDirectBufferPointer(void** data, int* size); + + // If there are at least "size" bytes available in the current buffer, + // returns a pointer directly into the buffer and advances over these bytes. + // The caller may then write directly into this buffer (e.g. using the + // *ToArray static methods) rather than go through CodedOutputStream. If + // there are not enough bytes available, returns NULL. The return pointer is + // invalidated as soon as any other non-const method of CodedOutputStream + // is called. + inline uint8* GetDirectBufferForNBytesAndAdvance(int size); + + // Write raw bytes, copying them from the given buffer. + void WriteRaw(const void* buffer, int size); + // Like WriteRaw() but will try to write aliased data if aliasing is + // turned on. + void WriteRawMaybeAliased(const void* data, int size); + // Like WriteRaw() but writing directly to the target array. + // This is _not_ inlined, as the compiler often optimizes memcpy into inline + // copy loops. Since this gets called by every field with string or bytes + // type, inlining may lead to a significant amount of code bloat, with only a + // minor performance gain. + static uint8* WriteRawToArray(const void* buffer, int size, uint8* target); + + // Equivalent to WriteRaw(str.data(), str.size()). + void WriteString(const string& str); + // Like WriteString() but writing directly to the target array. + static uint8* WriteStringToArray(const string& str, uint8* target); + // Write the varint-encoded size of str followed by str. + static uint8* WriteStringWithSizeToArray(const string& str, uint8* target); + + + // Instructs the CodedOutputStream to allow the underlying + // ZeroCopyOutputStream to hold pointers to the original structure instead of + // copying, if it supports it (i.e. output->AllowsAliasing() is true). If the + // underlying stream does not support aliasing, then enabling it has no + // affect. For now, this only affects the behavior of + // WriteRawMaybeAliased(). + // + // NOTE: It is caller's responsibility to ensure that the chunk of memory + // remains live until all of the data has been consumed from the stream. + void EnableAliasing(bool enabled); + + // Write a 32-bit little-endian integer. + void WriteLittleEndian32(uint32 value); + // Like WriteLittleEndian32() but writing directly to the target array. + static uint8* WriteLittleEndian32ToArray(uint32 value, uint8* target); + // Write a 64-bit little-endian integer. + void WriteLittleEndian64(uint64 value); + // Like WriteLittleEndian64() but writing directly to the target array. + static uint8* WriteLittleEndian64ToArray(uint64 value, uint8* target); + + // Write an unsigned integer with Varint encoding. Writing a 32-bit value + // is equivalent to casting it to uint64 and writing it as a 64-bit value, + // but may be more efficient. + void WriteVarint32(uint32 value); + // Like WriteVarint32() but writing directly to the target array. + static uint8* WriteVarint32ToArray(uint32 value, uint8* target); + // Write an unsigned integer with Varint encoding. + void WriteVarint64(uint64 value); + // Like WriteVarint64() but writing directly to the target array. + static uint8* WriteVarint64ToArray(uint64 value, uint8* target); + + // Equivalent to WriteVarint32() except when the value is negative, + // in which case it must be sign-extended to a full 10 bytes. + void WriteVarint32SignExtended(int32 value); + // Like WriteVarint32SignExtended() but writing directly to the target array. + static uint8* WriteVarint32SignExtendedToArray(int32 value, uint8* target); + + // This is identical to WriteVarint32(), but optimized for writing tags. + // In particular, if the input is a compile-time constant, this method + // compiles down to a couple instructions. + // Always inline because otherwise the aformentioned optimization can't work, + // but GCC by default doesn't want to inline this. + void WriteTag(uint32 value); + // Like WriteTag() but writing directly to the target array. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteTagToArray(uint32 value, + uint8* target); + + // Returns the number of bytes needed to encode the given value as a varint. + static int VarintSize32(uint32 value); + // Returns the number of bytes needed to encode the given value as a varint. + static int VarintSize64(uint64 value); + + // If negative, 10 bytes. Otheriwse, same as VarintSize32(). + static int VarintSize32SignExtended(int32 value); + + // Compile-time equivalent of VarintSize32(). + template + struct StaticVarintSize32 { + static const int value = + (Value < (1 << 7)) + ? 1 + : (Value < (1 << 14)) + ? 2 + : (Value < (1 << 21)) + ? 3 + : (Value < (1 << 28)) + ? 4 + : 5; + }; + + // Returns the total number of bytes written since this object was created. + inline int ByteCount() const; + + // Returns true if there was an underlying I/O error since this object was + // created. + bool HadError() const { return had_error_; } + + // Deterministic serialization, if requested, guarantees that for a given + // binary, equal messages will always be serialized to the same bytes. This + // implies: + // . repeated serialization of a message will return the same bytes + // . different processes of the same binary (which may be executing on + // different machines) will serialize equal messages to the same bytes. + // + // Note the deterministic serialization is NOT canonical across languages; it + // is also unstable across different builds with schema changes due to unknown + // fields. Users who need canonical serialization, e.g., persistent storage in + // a canonical form, fingerprinting, etc., should define their own + // canonicalization specification and implement the serializer using + // reflection APIs rather than relying on this API. + // + // If determinisitc serialization is requested, the serializer will + // sort map entries by keys in lexicographical order or numerical order. + // (This is an implementation detail and may subject to change.) + // + // There are two ways to determine whether serialization should be + // deterministic for this CodedOutputStream. If SetSerializationDeterministic + // has not yet been called, then the default comes from the global default, + // which is false, until SetDefaultSerializationDeterministic has been called. + // Otherwise, SetSerializationDeterministic has been called, and the last + // value passed to it is all that matters. + void SetSerializationDeterministic(bool value) { + serialization_deterministic_is_overridden_ = true; + serialization_deterministic_override_ = value; + } + // See above. Also, note that users of this CodedOutputStream may need to + // call IsSerializationDeterminstic() to serialize in the intended way. This + // CodedOutputStream cannot enforce a desire for deterministic serialization + // by itself. + bool IsSerializationDeterminstic() const { + return serialization_deterministic_is_overridden_ ? + serialization_deterministic_override_ : + default_serialization_deterministic_; + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); + + ZeroCopyOutputStream* output_; + uint8* buffer_; + int buffer_size_; + int total_bytes_; // Sum of sizes of all buffers seen so far. + bool had_error_; // Whether an error occurred during output. + bool aliasing_enabled_; // See EnableAliasing(). + // See SetSerializationDeterministic() regarding these three fields. + bool serialization_deterministic_is_overridden_; + bool serialization_deterministic_override_; + static bool default_serialization_deterministic_; + + // Advance the buffer by a given number of bytes. + void Advance(int amount); + + // Called when the buffer runs out to request more data. Implies an + // Advance(buffer_size_). + bool Refresh(); + + // Like WriteRaw() but may avoid copying if the underlying + // ZeroCopyOutputStream supports it. + void WriteAliasedRaw(const void* buffer, int size); + + // If this write might cross the end of the buffer, we compose the bytes first + // then use WriteRaw(). + void WriteVarint32SlowPath(uint32 value); + + // Always-inlined versions of WriteVarint* functions so that code can be + // reused, while still controlling size. For instance, WriteVarint32ToArray() + // should not directly call this: since it is inlined itself, doing so + // would greatly increase the size of generated code. Instead, it should call + // WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already + // out-of-line, so it should just invoke this directly to avoid any extra + // function call overhead. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteVarint64ToArrayInline( + uint64 value, uint8* target); + + static int VarintSize32Fallback(uint32 value); + + // See above. Other projects may use "friend" to allow them to call this. + static void SetDefaultSerializationDeterministic() { + default_serialization_deterministic_ = true; + } +}; + +// inline methods ==================================================== +// The vast majority of varints are only one byte. These inline +// methods optimize for that case. + +inline bool CodedInputStream::ReadVarint32(uint32* value) { + uint32 v = 0; + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { + v = *buffer_; + if (v < 0x80) { + *value = v; + Advance(1); + return true; + } + } + int64 result = ReadVarint32Fallback(v); + *value = static_cast(result); + return result >= 0; +} + +inline bool CodedInputStream::ReadVarint64(uint64* value) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { + *value = *buffer_; + Advance(1); + return true; + } + std::pair p = ReadVarint64Fallback(); + *value = p.first; + return p.second; +} + +inline bool CodedInputStream::ReadVarintSizeAsInt(int* value) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { + int v = *buffer_; + if (v < 0x80) { + *value = v; + Advance(1); + return true; + } + } + *value = ReadVarintSizeAsIntFallback(); + return *value >= 0; +} + +// static +inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( + const uint8* buffer, + uint32* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(value, buffer, sizeof(*value)); + return buffer + sizeof(*value); +#else + *value = (static_cast(buffer[0]) ) | + (static_cast(buffer[1]) << 8) | + (static_cast(buffer[2]) << 16) | + (static_cast(buffer[3]) << 24); + return buffer + sizeof(*value); +#endif +} +// static +inline const uint8* CodedInputStream::ReadLittleEndian64FromArray( + const uint8* buffer, + uint64* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(value, buffer, sizeof(*value)); + return buffer + sizeof(*value); +#else + uint32 part0 = (static_cast(buffer[0]) ) | + (static_cast(buffer[1]) << 8) | + (static_cast(buffer[2]) << 16) | + (static_cast(buffer[3]) << 24); + uint32 part1 = (static_cast(buffer[4]) ) | + (static_cast(buffer[5]) << 8) | + (static_cast(buffer[6]) << 16) | + (static_cast(buffer[7]) << 24); + *value = static_cast(part0) | + (static_cast(part1) << 32); + return buffer + sizeof(*value); +#endif +} + +inline bool CodedInputStream::ReadLittleEndian32(uint32* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast(sizeof(*value)))) { + memcpy(value, buffer_, sizeof(*value)); + Advance(sizeof(*value)); + return true; + } else { + return ReadLittleEndian32Fallback(value); + } +#else + return ReadLittleEndian32Fallback(value); +#endif +} + +inline bool CodedInputStream::ReadLittleEndian64(uint64* value) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast(sizeof(*value)))) { + memcpy(value, buffer_, sizeof(*value)); + Advance(sizeof(*value)); + return true; + } else { + return ReadLittleEndian64Fallback(value); + } +#else + return ReadLittleEndian64Fallback(value); +#endif +} + +inline uint32 CodedInputStream::ReadTag() { + uint32 v = 0; + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { + v = *buffer_; + if (v < 0x80) { + last_tag_ = v; + Advance(1); + return v; + } + } + last_tag_ = ReadTagFallback(v); + return last_tag_; +} + +inline std::pair CodedInputStream::ReadTagWithCutoff( + uint32 cutoff) { + // In performance-sensitive code we can expect cutoff to be a compile-time + // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at + // compile time. + uint32 first_byte_or_zero = 0; + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { + // Hot case: buffer_ non_empty, buffer_[0] in [1, 128). + // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields + // is large enough then is it better to check for the two-byte case first? + first_byte_or_zero = buffer_[0]; + if (static_cast(buffer_[0]) > 0) { + const uint32 kMax1ByteVarint = 0x7f; + uint32 tag = last_tag_ = buffer_[0]; + Advance(1); + return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); + } + // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available, + // and tag is two bytes. The latter is tested by bitwise-and-not of the + // first byte and the second byte. + if (cutoff >= 0x80 && + GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) && + GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) { + const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f; + uint32 tag = last_tag_ = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80); + Advance(2); + // It might make sense to test for tag == 0 now, but it is so rare that + // that we don't bother. A varint-encoded 0 should be one byte unless + // the encoder lost its mind. The second part of the return value of + // this function is allowed to be either true or false if the tag is 0, + // so we don't have to check for tag == 0. We may need to check whether + // it exceeds cutoff. + bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff; + return std::make_pair(tag, at_or_below_cutoff); + } + } + // Slow path + last_tag_ = ReadTagFallback(first_byte_or_zero); + return std::make_pair(last_tag_, static_cast(last_tag_ - 1) < cutoff); +} + +inline bool CodedInputStream::LastTagWas(uint32 expected) { + return last_tag_ == expected; +} + +inline bool CodedInputStream::ConsumedEntireMessage() { + return legitimate_message_end_; +} + +inline bool CodedInputStream::ExpectTag(uint32 expected) { + if (expected < (1 << 7)) { + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) { + Advance(1); + return true; + } else { + return false; + } + } else if (expected < (1 << 14)) { + if (GOOGLE_PREDICT_TRUE(BufferSize() >= 2) && + buffer_[0] == static_cast(expected | 0x80) && + buffer_[1] == static_cast(expected >> 7)) { + Advance(2); + return true; + } else { + return false; + } + } else { + // Don't bother optimizing for larger values. + return false; + } +} + +inline const uint8* CodedInputStream::ExpectTagFromArray( + const uint8* buffer, uint32 expected) { + if (expected < (1 << 7)) { + if (buffer[0] == expected) { + return buffer + 1; + } + } else if (expected < (1 << 14)) { + if (buffer[0] == static_cast(expected | 0x80) && + buffer[1] == static_cast(expected >> 7)) { + return buffer + 2; + } + } + return NULL; +} + +inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, + int* size) { + *data = buffer_; + *size = static_cast(buffer_end_ - buffer_); +} + +inline bool CodedInputStream::ExpectAtEnd() { + // If we are at a limit we know no more bytes can be read. Otherwise, it's + // hard to say without calling Refresh(), and we'd rather not do that. + + if (buffer_ == buffer_end_ && + ((buffer_size_after_limit_ != 0) || + (total_bytes_read_ == current_limit_))) { + last_tag_ = 0; // Pretend we called ReadTag()... + legitimate_message_end_ = true; // ... and it hit EOF. + return true; + } else { + return false; + } +} + +inline int CodedInputStream::CurrentPosition() const { + return total_bytes_read_ - (BufferSize() + buffer_size_after_limit_); +} + +inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) { + if (buffer_size_ < size) { + return NULL; + } else { + uint8* result = buffer_; + Advance(size); + return result; + } +} + +inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value, + uint8* target) { + while (value >= 0x80) { + *target = static_cast(value | 0x80); + value >>= 7; + ++target; + } + *target = static_cast(value); + return target + 1; +} + +inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { + if (value < 0) { + WriteVarint64(static_cast(value)); + } else { + WriteVarint32(static_cast(value)); + } +} + +inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray( + int32 value, uint8* target) { + if (value < 0) { + return WriteVarint64ToArray(static_cast(value), target); + } else { + return WriteVarint32ToArray(static_cast(value), target); + } +} + +inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, + uint8* target) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(target, &value, sizeof(value)); +#else + target[0] = static_cast(value); + target[1] = static_cast(value >> 8); + target[2] = static_cast(value >> 16); + target[3] = static_cast(value >> 24); +#endif + return target + sizeof(value); +} + +inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value, + uint8* target) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + memcpy(target, &value, sizeof(value)); +#else + uint32 part0 = static_cast(value); + uint32 part1 = static_cast(value >> 32); + + target[0] = static_cast(part0); + target[1] = static_cast(part0 >> 8); + target[2] = static_cast(part0 >> 16); + target[3] = static_cast(part0 >> 24); + target[4] = static_cast(part1); + target[5] = static_cast(part1 >> 8); + target[6] = static_cast(part1 >> 16); + target[7] = static_cast(part1 >> 24); +#endif + return target + sizeof(value); +} + +inline void CodedOutputStream::WriteVarint32(uint32 value) { + if (buffer_size_ >= 5) { + // Fast path: We have enough bytes left in the buffer to guarantee that + // this write won't cross the end, so we can skip the checks. + uint8* target = buffer_; + uint8* end = WriteVarint32ToArray(value, target); + int size = static_cast(end - target); + Advance(size); + } else { + WriteVarint32SlowPath(value); + } +} + +inline void CodedOutputStream::WriteTag(uint32 value) { + WriteVarint32(value); +} + +inline uint8* CodedOutputStream::WriteTagToArray( + uint32 value, uint8* target) { + return WriteVarint32ToArray(value, target); +} + +inline int CodedOutputStream::VarintSize32(uint32 value) { + if (value < (1 << 7)) { + return 1; + } else { + return VarintSize32Fallback(value); + } +} + +inline int CodedOutputStream::VarintSize32SignExtended(int32 value) { + if (value < 0) { + return 10; // TODO(kenton): Make this a symbolic constant. + } else { + return VarintSize32(static_cast(value)); + } +} + +inline void CodedOutputStream::WriteString(const string& str) { + WriteRaw(str.data(), static_cast(str.size())); +} + +inline void CodedOutputStream::WriteRawMaybeAliased( + const void* data, int size) { + if (aliasing_enabled_) { + WriteAliasedRaw(data, size); + } else { + WriteRaw(data, size); + } +} + +inline uint8* CodedOutputStream::WriteStringToArray( + const string& str, uint8* target) { + return WriteRawToArray(str.data(), static_cast(str.size()), target); +} + +inline int CodedOutputStream::ByteCount() const { + return total_bytes_ - buffer_size_; +} + +inline void CodedInputStream::Advance(int amount) { + buffer_ += amount; +} + +inline void CodedOutputStream::Advance(int amount) { + buffer_ += amount; + buffer_size_ -= amount; +} + +inline void CodedInputStream::SetRecursionLimit(int limit) { + recursion_budget_ += limit - recursion_limit_; + recursion_limit_ = limit; +} + +inline bool CodedInputStream::IncrementRecursionDepth() { + --recursion_budget_; + return recursion_budget_ >= 0; +} + +inline void CodedInputStream::DecrementRecursionDepth() { + if (recursion_budget_ < recursion_limit_) ++recursion_budget_; +} + +inline void CodedInputStream::UnsafeDecrementRecursionDepth() { + assert(recursion_budget_ < recursion_limit_); + ++recursion_budget_; +} + +inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool, + MessageFactory* factory) { + extension_pool_ = pool; + extension_factory_ = factory; +} + +inline const DescriptorPool* CodedInputStream::GetExtensionPool() { + return extension_pool_; +} + +inline MessageFactory* CodedInputStream::GetExtensionFactory() { + return extension_factory_; +} + +inline int CodedInputStream::BufferSize() const { + return static_cast(buffer_end_ - buffer_); +} + +inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) + : buffer_(NULL), + buffer_end_(NULL), + input_(input), + total_bytes_read_(0), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(kint32max), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), + recursion_budget_(default_recursion_limit_), + recursion_limit_(default_recursion_limit_), + extension_pool_(NULL), + extension_factory_(NULL) { + // Eagerly Refresh() so buffer space is immediately available. + Refresh(); +} + +inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) + : buffer_(buffer), + buffer_end_(buffer + size), + input_(NULL), + total_bytes_read_(size), + overflow_bytes_(0), + last_tag_(0), + legitimate_message_end_(false), + aliasing_enabled_(false), + current_limit_(size), + buffer_size_after_limit_(0), + total_bytes_limit_(kDefaultTotalBytesLimit), + total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), + recursion_budget_(default_recursion_limit_), + recursion_limit_(default_recursion_limit_), + extension_pool_(NULL), + extension_factory_(NULL) { + // Note that setting current_limit_ == size is important to prevent some + // code paths from trying to access input_ and segfaulting. +} + +inline bool CodedInputStream::IsFlat() const { + return input_ == NULL; +} + +} // namespace io +} // namespace protobuf + + +#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) + #pragma runtime_checks("c", restore) +#endif // _MSC_VER && !defined(__INTEL_COMPILER) + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ diff --git a/thirdparty/linux/include/google/protobuf/io/gzip_stream.h b/thirdparty/linux/include/google/protobuf/io/gzip_stream.h new file mode 100644 index 0000000..15b02fe --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/io/gzip_stream.h @@ -0,0 +1,209 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: brianolson@google.com (Brian Olson) +// +// This file contains the definition for classes GzipInputStream and +// GzipOutputStream. +// +// GzipInputStream decompresses data from an underlying +// ZeroCopyInputStream and provides the decompressed data as a +// ZeroCopyInputStream. +// +// GzipOutputStream is an ZeroCopyOutputStream that compresses data to +// an underlying ZeroCopyOutputStream. + +#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +// A ZeroCopyInputStream that reads compressed data through zlib +class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream { + public: + // Format key for constructor + enum Format { + // zlib will autodetect gzip header or deflate stream + AUTO = 0, + + // GZIP streams have some extra header data for file attributes. + GZIP = 1, + + // Simpler zlib stream format. + ZLIB = 2, + }; + + // buffer_size and format may be -1 for default of 64kB and GZIP format + explicit GzipInputStream( + ZeroCopyInputStream* sub_stream, + Format format = AUTO, + int buffer_size = -1); + virtual ~GzipInputStream(); + + // Return last error message or NULL if no error. + inline const char* ZlibErrorMessage() const { + return zcontext_.msg; + } + inline int ZlibErrorCode() const { + return zerror_; + } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + Format format_; + + ZeroCopyInputStream* sub_stream_; + + z_stream zcontext_; + int zerror_; + + void* output_buffer_; + void* output_position_; + size_t output_buffer_length_; + int64 byte_count_; + + int Inflate(int flush); + void DoNextOutput(const void** data, int* size); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream); +}; + + +class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream { + public: + // Format key for constructor + enum Format { + // GZIP streams have some extra header data for file attributes. + GZIP = 1, + + // Simpler zlib stream format. + ZLIB = 2, + }; + + struct Options { + // Defaults to GZIP. + Format format; + + // What size buffer to use internally. Defaults to 64kB. + int buffer_size; + + // A number between 0 and 9, where 0 is no compression and 9 is best + // compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h). + int compression_level; + + // Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED, + // Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in + // zlib.h for definitions of these constants. + int compression_strategy; + + Options(); // Initializes with default values. + }; + + // Create a GzipOutputStream with default options. + explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream); + + // Create a GzipOutputStream with the given options. + GzipOutputStream( + ZeroCopyOutputStream* sub_stream, + const Options& options); + + virtual ~GzipOutputStream(); + + // Return last error message or NULL if no error. + inline const char* ZlibErrorMessage() const { + return zcontext_.msg; + } + inline int ZlibErrorCode() const { + return zerror_; + } + + // Flushes data written so far to zipped data in the underlying stream. + // It is the caller's responsibility to flush the underlying stream if + // necessary. + // Compression may be less efficient stopping and starting around flushes. + // Returns true if no error. + // + // Please ensure that block size is > 6. Here is an excerpt from the zlib + // doc that explains why: + // + // In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out + // is greater than six to avoid repeated flush markers due to + // avail_out == 0 on return. + bool Flush(); + + // Writes out all data and closes the gzip stream. + // It is the caller's responsibility to close the underlying stream if + // necessary. + // Returns true if no error. + bool Close(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + ZeroCopyOutputStream* sub_stream_; + // Result from calling Next() on sub_stream_ + void* sub_data_; + int sub_data_size_; + + z_stream zcontext_; + int zerror_; + void* input_buffer_; + size_t input_buffer_length_; + + // Shared constructor code. + void Init(ZeroCopyOutputStream* sub_stream, const Options& options); + + // Do some compression. + // Takes zlib flush mode. + // Returns zlib error code. + int Deflate(int flush); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream); +}; + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__ diff --git a/thirdparty/linux/include/google/protobuf/io/printer.h b/thirdparty/linux/include/google/protobuf/io/printer.h new file mode 100644 index 0000000..e78e2ef --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/io/printer.h @@ -0,0 +1,353 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Utility class for writing text to a ZeroCopyOutputStream. + +#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__ +#define GOOGLE_PROTOBUF_IO_PRINTER_H__ + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +class ZeroCopyOutputStream; // zero_copy_stream.h + +// Records annotations about a Printer's output. +class LIBPROTOBUF_EXPORT AnnotationCollector { + public: + // Records that the bytes in file_path beginning with begin_offset and ending + // before end_offset are associated with the SourceCodeInfo-style path. + virtual void AddAnnotation(size_t begin_offset, size_t end_offset, + const string& file_path, + const vector& path) = 0; + + virtual ~AnnotationCollector() {} +}; + +// Records annotations about a Printer's output to the given protocol buffer, +// assuming that the buffer has an ::Annotation message exposing path, +// source_file, begin and end fields. +template +class AnnotationProtoCollector : public AnnotationCollector { + public: + // annotation_proto is the protocol buffer to which new Annotations should be + // added. It is not owned by the AnnotationProtoCollector. + explicit AnnotationProtoCollector(AnnotationProto* annotation_proto) + : annotation_proto_(annotation_proto) {} + + // Override for AnnotationCollector::AddAnnotation. + virtual void AddAnnotation(size_t begin_offset, size_t end_offset, + const string& file_path, const vector& path) { + typename AnnotationProto::Annotation* annotation = + annotation_proto_->add_annotation(); + for (int i = 0; i < path.size(); ++i) { + annotation->add_path(path[i]); + } + annotation->set_source_file(file_path); + annotation->set_begin(begin_offset); + annotation->set_end(end_offset); + } + + private: + // The protocol buffer to which new annotations should be added. + AnnotationProto* const annotation_proto_; +}; + +// This simple utility class assists in code generation. It basically +// allows the caller to define a set of variables and then output some +// text with variable substitutions. Example usage: +// +// Printer printer(output, '$'); +// map vars; +// vars["name"] = "Bob"; +// printer.Print(vars, "My name is $name$."); +// +// The above writes "My name is Bob." to the output stream. +// +// Printer aggressively enforces correct usage, crashing (with assert failures) +// in the case of undefined variables in debug builds. This helps greatly in +// debugging code which uses it. +// +// If a Printer is constructed with an AnnotationCollector, it will provide it +// with annotations that connect the Printer's output to paths that can identify +// various descriptors. In the above example, if person_ is a descriptor that +// identifies Bob, we can associate the output string "My name is Bob." with +// a source path pointing to that descriptor with: +// +// printer.Annotate("name", person_); +// +// The AnnotationCollector will be sent an annotation linking the output range +// covering "Bob" to the logical path provided by person_. Tools may use +// this association to (for example) link "Bob" in the output back to the +// source file that defined the person_ descriptor identifying Bob. +// +// Annotate can only examine variables substituted during the last call to +// Print. It is invalid to refer to a variable that was used multiple times +// in a single Print call. +// +// In full generality, one may specify a range of output text using a beginning +// substitution variable and an ending variable. The resulting annotation will +// span from the first character of the substituted value for the beginning +// variable to the last character of the substituted value for the ending +// variable. For example, the Annotate call above is equivalent to this one: +// +// printer.Annotate("name", "name", person_); +// +// This is useful if multiple variables combine to form a single span of output +// that should be annotated with the same source path. For example: +// +// Printer printer(output, '$'); +// map vars; +// vars["first"] = "Alice"; +// vars["last"] = "Smith"; +// printer.Print(vars, "My name is $first$ $last$."); +// printer.Annotate("first", "last", person_); +// +// This code would associate the span covering "Alice Smith" in the output with +// the person_ descriptor. +// +// Note that the beginning variable must come before (or overlap with, in the +// case of zero-sized substitution values) the ending variable. +// +// It is also sometimes useful to use variables with zero-sized values as +// markers. This avoids issues with multiple references to the same variable +// and also allows annotation ranges to span literal text from the Print +// templates: +// +// Printer printer(output, '$'); +// map vars; +// vars["foo"] = "bar"; +// vars["function"] = "call"; +// vars["mark"] = ""; +// printer.Print(vars, "$function$($foo$,$foo$)$mark$"); +// printer.Annotate("function", "rmark", call_); +// +// This code associates the span covering "call(bar,bar)" in the output with the +// call_ descriptor. + +class LIBPROTOBUF_EXPORT Printer { + public: + // Create a printer that writes text to the given output stream. Use the + // given character as the delimiter for variables. + Printer(ZeroCopyOutputStream* output, char variable_delimiter); + + // Create a printer that writes text to the given output stream. Use the + // given character as the delimiter for variables. If annotation_collector + // is not null, Printer will provide it with annotations about code written + // to the stream. annotation_collector is not owned by Printer. + Printer(ZeroCopyOutputStream* output, char variable_delimiter, + AnnotationCollector* annotation_collector); + + ~Printer(); + + // Link a subsitution variable emitted by the last call to Print to the object + // described by descriptor. + template + void Annotate(const char* varname, const SomeDescriptor* descriptor) { + Annotate(varname, varname, descriptor); + } + + // Link the output range defined by the substitution variables as emitted by + // the last call to Print to the object described by descriptor. The range + // begins at begin_varname's value and ends after the last character of the + // value substituted for end_varname. + template + void Annotate(const char* begin_varname, const char* end_varname, + const SomeDescriptor* descriptor) { + if (annotation_collector_ == NULL) { + // Annotations aren't turned on for this Printer, so don't pay the cost + // of building the location path. + return; + } + vector path; + descriptor->GetLocationPath(&path); + Annotate(begin_varname, end_varname, descriptor->file()->name(), path); + } + + // Link a subsitution variable emitted by the last call to Print to the file + // with path file_name. + void Annotate(const char* varname, const string& file_name) { + Annotate(varname, varname, file_name); + } + + // Link the output range defined by the substitution variables as emitted by + // the last call to Print to the file with path file_name. The range begins + // at begin_varname's value and ends after the last character of the value + // substituted for end_varname. + void Annotate(const char* begin_varname, const char* end_varname, + const string& file_name) { + if (annotation_collector_ == NULL) { + // Annotations aren't turned on for this Printer. + return; + } + vector empty_path; + Annotate(begin_varname, end_varname, file_name, empty_path); + } + + // Print some text after applying variable substitutions. If a particular + // variable in the text is not defined, this will crash. Variables to be + // substituted are identified by their names surrounded by delimiter + // characters (as given to the constructor). The variable bindings are + // defined by the given map. + void Print(const map& variables, const char* text); + + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable, const string& value); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6, + const char* variable7, const string& value7); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6, + const char* variable7, const string& value7, + const char* variable8, const string& value8); + + // Indent text by two spaces. After calling Indent(), two spaces will be + // inserted at the beginning of each line of text. Indent() may be called + // multiple times to produce deeper indents. + void Indent(); + + // Reduces the current indent level by two spaces, or crashes if the indent + // level is zero. + void Outdent(); + + // Write a string to the output buffer. + // This method does not look for newlines to add indentation. + void PrintRaw(const string& data); + + // Write a zero-delimited string to output buffer. + // This method does not look for newlines to add indentation. + void PrintRaw(const char* data); + + // Write some bytes to the output buffer. + // This method does not look for newlines to add indentation. + void WriteRaw(const char* data, int size); + + // True if any write to the underlying stream failed. (We don't just + // crash in this case because this is an I/O failure, not a programming + // error.) + bool failed() const { return failed_; } + + private: + // Link the output range defined by the substitution variables as emitted by + // the last call to Print to the object found at the SourceCodeInfo-style path + // in a file with path file_path. The range begins at the start of + // begin_varname's value and ends after the last character of the value + // substituted for end_varname. Note that begin_varname and end_varname + // may refer to the same variable. + void Annotate(const char* begin_varname, const char* end_varname, + const string& file_path, const vector& path); + + const char variable_delimiter_; + + ZeroCopyOutputStream* const output_; + char* buffer_; + int buffer_size_; + // The current position, in bytes, in the output stream. This is equivalent + // to the total number of bytes that have been written so far. This value is + // used to calculate annotation ranges in the substitutions_ map below. + size_t offset_; + + string indent_; + bool at_start_of_line_; + bool failed_; + + // A map from variable name to [start, end) offsets in the output buffer. + // These refer to the offsets used for a variable after the last call to + // Print. If a variable was used more than once, the entry used in + // this map is set to a negative-length span. For singly-used variables, the + // start offset is the beginning of the substitution; the end offset is the + // last byte of the substitution plus one (such that (end - start) is the + // length of the substituted string). + map > substitutions_; + + // Returns true and sets range to the substitution range in the output for + // varname if varname was used once in the last call to Print. If varname + // was not used, or if it was used multiple times, returns false (and + // fails a debug assertion). + bool GetSubstitutionRange(const char* varname, pair* range); + + // If non-null, annotation_collector_ is used to store annotations about + // generated code. + AnnotationCollector* const annotation_collector_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer); +}; + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__ diff --git a/thirdparty/linux/include/google/protobuf/io/strtod.h b/thirdparty/linux/include/google/protobuf/io/strtod.h new file mode 100644 index 0000000..f56e41c --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/io/strtod.h @@ -0,0 +1,55 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A locale-independent version of strtod(), used to parse floating +// point default values in .proto files, where the decimal separator +// is always a dot. + +#ifndef GOOGLE_PROTOBUF_IO_STRTOD_H__ +#define GOOGLE_PROTOBUF_IO_STRTOD_H__ + +namespace google { +namespace protobuf { +namespace io { + +// A locale-independent version of the standard strtod(), which always +// uses a dot as the decimal separator. +double NoLocaleStrtod(const char* str, char** endptr); + +// Casts a double value to a float value. If the value is outside of the +// representable range of float, it will be converted to positive or negative +// infinity. +float SafeDoubleToFloat(double value); + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_STRTOD_H__ diff --git a/thirdparty/linux/include/google/protobuf/io/tokenizer.h b/thirdparty/linux/include/google/protobuf/io/tokenizer.h new file mode 100644 index 0000000..77a873b --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/io/tokenizer.h @@ -0,0 +1,411 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Class for parsing tokenized text from a ZeroCopyInputStream. + +#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__ +#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__ + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { + +class ZeroCopyInputStream; // zero_copy_stream.h + +// Defined in this file. +class ErrorCollector; +class Tokenizer; + +// By "column number", the proto compiler refers to a count of the number +// of bytes before a given byte, except that a tab character advances to +// the next multiple of 8 bytes. Note in particular that column numbers +// are zero-based, while many user interfaces use one-based column numbers. +typedef int ColumnNumber; + +// Abstract interface for an object which collects the errors that occur +// during parsing. A typical implementation might simply print the errors +// to stdout. +class LIBPROTOBUF_EXPORT ErrorCollector { + public: + inline ErrorCollector() {} + virtual ~ErrorCollector(); + + // Indicates that there was an error in the input at the given line and + // column numbers. The numbers are zero-based, so you may want to add + // 1 to each before printing them. + virtual void AddError(int line, ColumnNumber column, + const string& message) = 0; + + // Indicates that there was a warning in the input at the given line and + // column numbers. The numbers are zero-based, so you may want to add + // 1 to each before printing them. + virtual void AddWarning(int line, ColumnNumber column, + const string& message) { } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); +}; + +// This class converts a stream of raw text into a stream of tokens for +// the protocol definition parser to parse. The tokens recognized are +// similar to those that make up the C language; see the TokenType enum for +// precise descriptions. Whitespace and comments are skipped. By default, +// C- and C++-style comments are recognized, but other styles can be used by +// calling set_comment_style(). +class LIBPROTOBUF_EXPORT Tokenizer { + public: + // Construct a Tokenizer that reads and tokenizes text from the given + // input stream and writes errors to the given error_collector. + // The caller keeps ownership of input and error_collector. + Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector); + ~Tokenizer(); + + enum TokenType { + TYPE_START, // Next() has not yet been called. + TYPE_END, // End of input reached. "text" is empty. + + TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not + // starting with a digit. It is an error for a number + // to be followed by an identifier with no space in + // between. + TYPE_INTEGER, // A sequence of digits representing an integer. Normally + // the digits are decimal, but a prefix of "0x" indicates + // a hex number and a leading zero indicates octal, just + // like with C numeric literals. A leading negative sign + // is NOT included in the token; it's up to the parser to + // interpret the unary minus operator on its own. + TYPE_FLOAT, // A floating point literal, with a fractional part and/or + // an exponent. Always in decimal. Again, never + // negative. + TYPE_STRING, // A quoted sequence of escaped characters. Either single + // or double quotes can be used, but they must match. + // A string literal cannot cross a line break. + TYPE_SYMBOL, // Any other printable character, like '!' or '+'. + // Symbols are always a single character, so "!+$%" is + // four tokens. + }; + + // Structure representing a token read from the token stream. + struct Token { + TokenType type; + string text; // The exact text of the token as it appeared in + // the input. e.g. tokens of TYPE_STRING will still + // be escaped and in quotes. + + // "line" and "column" specify the position of the first character of + // the token within the input stream. They are zero-based. + int line; + ColumnNumber column; + ColumnNumber end_column; + }; + + // Get the current token. This is updated when Next() is called. Before + // the first call to Next(), current() has type TYPE_START and no contents. + const Token& current(); + + // Return the previous token -- i.e. what current() returned before the + // previous call to Next(). + const Token& previous(); + + // Advance to the next token. Returns false if the end of the input is + // reached. + bool Next(); + + // Like Next(), but also collects comments which appear between the previous + // and next tokens. + // + // Comments which appear to be attached to the previous token are stored + // in *prev_tailing_comments. Comments which appear to be attached to the + // next token are stored in *next_leading_comments. Comments appearing in + // between which do not appear to be attached to either will be added to + // detached_comments. Any of these parameters can be NULL to simply discard + // the comments. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // Only the comment content is returned; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk will + // be stripped from the beginning of each line other than the first. Newlines + // are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment. This is not attached to qux or corge + // // because there are blank lines separating it from both. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + bool NextWithComments(string* prev_trailing_comments, + vector* detached_comments, + string* next_leading_comments); + + // Parse helpers --------------------------------------------------- + + // Parses a TYPE_FLOAT token. This never fails, so long as the text actually + // comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the + // result is undefined (possibly an assert failure). + static double ParseFloat(const string& text); + + // Parses a TYPE_STRING token. This never fails, so long as the text actually + // comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the + // result is undefined (possibly an assert failure). + static void ParseString(const string& text, string* output); + + // Identical to ParseString, but appends to output. + static void ParseStringAppend(const string& text, string* output); + + // Parses a TYPE_INTEGER token. Returns false if the result would be + // greater than max_value. Otherwise, returns true and sets *output to the + // result. If the text is not from a Token of type TYPE_INTEGER originally + // parsed by a Tokenizer, the result is undefined (possibly an assert + // failure). + static bool ParseInteger(const string& text, uint64 max_value, + uint64* output); + + // Options --------------------------------------------------------- + + // Set true to allow floats to be suffixed with the letter 'f'. Tokens + // which would otherwise be integers but which have the 'f' suffix will be + // forced to be interpreted as floats. For all other purposes, the 'f' is + // ignored. + void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; } + + // Valid values for set_comment_style(). + enum CommentStyle { + // Line comments begin with "//", block comments are delimited by "/*" and + // "*/". + CPP_COMMENT_STYLE, + // Line comments begin with "#". No way to write block comments. + SH_COMMENT_STYLE + }; + + // Sets the comment style. + void set_comment_style(CommentStyle style) { comment_style_ = style; } + + // Whether to require whitespace between a number and a field name. + // Default is true. Do not use this; for Google-internal cleanup only. + void set_require_space_after_number(bool require) { + require_space_after_number_ = require; + } + + // Whether to allow string literals to span multiple lines. Default is false. + // Do not use this; for Google-internal cleanup only. + void set_allow_multiline_strings(bool allow) { + allow_multiline_strings_ = allow; + } + + // External helper: validate an identifier. + static bool IsIdentifier(const string& text); + + // ----------------------------------------------------------------- + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer); + + Token current_; // Returned by current(). + Token previous_; // Returned by previous(). + + ZeroCopyInputStream* input_; + ErrorCollector* error_collector_; + + char current_char_; // == buffer_[buffer_pos_], updated by NextChar(). + const char* buffer_; // Current buffer returned from input_. + int buffer_size_; // Size of buffer_. + int buffer_pos_; // Current position within the buffer. + bool read_error_; // Did we previously encounter a read error? + + // Line and column number of current_char_ within the whole input stream. + int line_; + ColumnNumber column_; + + // String to which text should be appended as we advance through it. + // Call RecordTo(&str) to start recording and StopRecording() to stop. + // E.g. StartToken() calls RecordTo(¤t_.text). record_start_ is the + // position within the current buffer where recording started. + string* record_target_; + int record_start_; + + // Options. + bool allow_f_after_float_; + CommentStyle comment_style_; + bool require_space_after_number_; + bool allow_multiline_strings_; + + // Since we count columns we need to interpret tabs somehow. We'll take + // the standard 8-character definition for lack of any way to do better. + // This must match the documentation of ColumnNumber. + static const int kTabWidth = 8; + + // ----------------------------------------------------------------- + // Helper methods. + + // Consume this character and advance to the next one. + void NextChar(); + + // Read a new buffer from the input. + void Refresh(); + + inline void RecordTo(string* target); + inline void StopRecording(); + + // Called when the current character is the first character of a new + // token (not including whitespace or comments). + inline void StartToken(); + // Called when the current character is the first character after the + // end of the last token. After this returns, current_.text will + // contain all text consumed since StartToken() was called. + inline void EndToken(); + + // Convenience method to add an error at the current line and column. + void AddError(const string& message) { + error_collector_->AddError(line_, column_, message); + } + + // ----------------------------------------------------------------- + // The following four methods are used to consume tokens of specific + // types. They are actually used to consume all characters *after* + // the first, since the calling function consumes the first character + // in order to decide what kind of token is being read. + + // Read and consume a string, ending when the given delimiter is + // consumed. + void ConsumeString(char delimiter); + + // Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER + // depending on what was read. This needs to know if the first + // character was a zero in order to correctly recognize hex and octal + // numbers. + // It also needs to know if the first character was a . to parse floating + // point correctly. + TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot); + + // Consume the rest of a line. + void ConsumeLineComment(string* content); + // Consume until "*/". + void ConsumeBlockComment(string* content); + + enum NextCommentStatus { + // Started a line comment. + LINE_COMMENT, + + // Started a block comment. + BLOCK_COMMENT, + + // Consumed a slash, then realized it wasn't a comment. current_ has + // been filled in with a slash token. The caller should return it. + SLASH_NOT_COMMENT, + + // We do not appear to be starting a comment here. + NO_COMMENT + }; + + // If we're at the start of a new comment, consume it and return what kind + // of comment it is. + NextCommentStatus TryConsumeCommentStart(); + + // ----------------------------------------------------------------- + // These helper methods make the parsing code more readable. The + // "character classes" referred to are defined at the top of the .cc file. + // Basically it is a C++ class with one method: + // static bool InClass(char c); + // The method returns true if c is a member of this "class", like "Letter" + // or "Digit". + + // Returns true if the current character is of the given character + // class, but does not consume anything. + template + inline bool LookingAt(); + + // If the current character is in the given class, consume it and return + // true. Otherwise return false. + // e.g. TryConsumeOne() + template + inline bool TryConsumeOne(); + + // Like above, but try to consume the specific character indicated. + inline bool TryConsume(char c); + + // Consume zero or more of the given character class. + template + inline void ConsumeZeroOrMore(); + + // Consume one or more of the given character class or log the given + // error message. + // e.g. ConsumeOneOrMore("Expected digits."); + template + inline void ConsumeOneOrMore(const char* error); +}; + +// inline methods ==================================================== +inline const Tokenizer::Token& Tokenizer::current() { + return current_; +} + +inline const Tokenizer::Token& Tokenizer::previous() { + return previous_; +} + +inline void Tokenizer::ParseString(const string& text, string* output) { + output->clear(); + ParseStringAppend(text, output); +} + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__ diff --git a/thirdparty/linux/include/google/protobuf/io/zero_copy_stream.h b/thirdparty/linux/include/google/protobuf/io/zero_copy_stream.h new file mode 100644 index 0000000..52650fc --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/io/zero_copy_stream.h @@ -0,0 +1,248 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream +// interfaces, which represent abstract I/O streams to and from which +// protocol buffers can be read and written. For a few simple +// implementations of these interfaces, see zero_copy_stream_impl.h. +// +// These interfaces are different from classic I/O streams in that they +// try to minimize the amount of data copying that needs to be done. +// To accomplish this, responsibility for allocating buffers is moved to +// the stream object, rather than being the responsibility of the caller. +// So, the stream can return a buffer which actually points directly into +// the final data structure where the bytes are to be stored, and the caller +// can interact directly with that buffer, eliminating an intermediate copy +// operation. +// +// As an example, consider the common case in which you are reading bytes +// from an array that is already in memory (or perhaps an mmap()ed file). +// With classic I/O streams, you would do something like: +// char buffer[BUFFER_SIZE]; +// input->Read(buffer, BUFFER_SIZE); +// DoSomething(buffer, BUFFER_SIZE); +// Then, the stream basically just calls memcpy() to copy the data from +// the array into your buffer. With a ZeroCopyInputStream, you would do +// this instead: +// const void* buffer; +// int size; +// input->Next(&buffer, &size); +// DoSomething(buffer, size); +// Here, no copy is performed. The input stream returns a pointer directly +// into the backing array, and the caller ends up reading directly from it. +// +// If you want to be able to read the old-fashion way, you can create +// a CodedInputStream or CodedOutputStream wrapping these objects and use +// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy +// step, but Coded*Stream will handle buffering so at least it will be +// reasonably efficient. +// +// ZeroCopyInputStream example: +// // Read in a file and print its contents to stdout. +// int fd = open("myfile", O_RDONLY); +// ZeroCopyInputStream* input = new FileInputStream(fd); +// +// const void* buffer; +// int size; +// while (input->Next(&buffer, &size)) { +// cout.write(buffer, size); +// } +// +// delete input; +// close(fd); +// +// ZeroCopyOutputStream example: +// // Copy the contents of "infile" to "outfile", using plain read() for +// // "infile" but a ZeroCopyOutputStream for "outfile". +// int infd = open("infile", O_RDONLY); +// int outfd = open("outfile", O_WRONLY); +// ZeroCopyOutputStream* output = new FileOutputStream(outfd); +// +// void* buffer; +// int size; +// while (output->Next(&buffer, &size)) { +// int bytes = read(infd, buffer, size); +// if (bytes < size) { +// // Reached EOF. +// output->BackUp(size - bytes); +// break; +// } +// } +// +// delete output; +// close(infd); +// close(outfd); + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ + +#include +#include + +namespace google { + +namespace protobuf { +namespace io { + +// Defined in this file. +class ZeroCopyInputStream; +class ZeroCopyOutputStream; + +// Abstract interface similar to an input stream but designed to minimize +// copying. +class LIBPROTOBUF_EXPORT ZeroCopyInputStream { + public: + inline ZeroCopyInputStream() {} + virtual ~ZeroCopyInputStream(); + + // Obtains a chunk of data from the stream. + // + // Preconditions: + // * "size" and "data" are not NULL. + // + // Postconditions: + // * If the returned value is false, there is no more data to return or + // an error occurred. All errors are permanent. + // * Otherwise, "size" points to the actual number of bytes read and "data" + // points to a pointer to a buffer containing these bytes. + // * Ownership of this buffer remains with the stream, and the buffer + // remains valid only until some other method of the stream is called + // or the stream is destroyed. + // * It is legal for the returned buffer to have zero size, as long + // as repeatedly calling Next() eventually yields a buffer with non-zero + // size. + virtual bool Next(const void** data, int* size) = 0; + + // Backs up a number of bytes, so that the next call to Next() returns + // data again that was already returned by the last call to Next(). This + // is useful when writing procedures that are only supposed to read up + // to a certain point in the input, then return. If Next() returns a + // buffer that goes beyond what you wanted to read, you can use BackUp() + // to return to the point where you intended to finish. + // + // Preconditions: + // * The last method called must have been Next(). + // * count must be less than or equal to the size of the last buffer + // returned by Next(). + // + // Postconditions: + // * The last "count" bytes of the last buffer returned by Next() will be + // pushed back into the stream. Subsequent calls to Next() will return + // the same data again before producing new data. + virtual void BackUp(int count) = 0; + + // Skips a number of bytes. Returns false if the end of the stream is + // reached or some input error occurred. In the end-of-stream case, the + // stream is advanced to the end of the stream (so ByteCount() will return + // the total size of the stream). + virtual bool Skip(int count) = 0; + + // Returns the total number of bytes read since this object was created. + virtual int64 ByteCount() const = 0; + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream); +}; + +// Abstract interface similar to an output stream but designed to minimize +// copying. +class LIBPROTOBUF_EXPORT ZeroCopyOutputStream { + public: + inline ZeroCopyOutputStream() {} + virtual ~ZeroCopyOutputStream(); + + // Obtains a buffer into which data can be written. Any data written + // into this buffer will eventually (maybe instantly, maybe later on) + // be written to the output. + // + // Preconditions: + // * "size" and "data" are not NULL. + // + // Postconditions: + // * If the returned value is false, an error occurred. All errors are + // permanent. + // * Otherwise, "size" points to the actual number of bytes in the buffer + // and "data" points to the buffer. + // * Ownership of this buffer remains with the stream, and the buffer + // remains valid only until some other method of the stream is called + // or the stream is destroyed. + // * Any data which the caller stores in this buffer will eventually be + // written to the output (unless BackUp() is called). + // * It is legal for the returned buffer to have zero size, as long + // as repeatedly calling Next() eventually yields a buffer with non-zero + // size. + virtual bool Next(void** data, int* size) = 0; + + // Backs up a number of bytes, so that the end of the last buffer returned + // by Next() is not actually written. This is needed when you finish + // writing all the data you want to write, but the last buffer was bigger + // than you needed. You don't want to write a bunch of garbage after the + // end of your data, so you use BackUp() to back up. + // + // Preconditions: + // * The last method called must have been Next(). + // * count must be less than or equal to the size of the last buffer + // returned by Next(). + // * The caller must not have written anything to the last "count" bytes + // of that buffer. + // + // Postconditions: + // * The last "count" bytes of the last buffer returned by Next() will be + // ignored. + virtual void BackUp(int count) = 0; + + // Returns the total number of bytes written since this object was created. + virtual int64 ByteCount() const = 0; + + // Write a given chunk of data to the output. Some output streams may + // implement this in a way that avoids copying. Check AllowsAliasing() before + // calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is + // called on a stream that does not allow aliasing. + // + // NOTE: It is caller's responsibility to ensure that the chunk of memory + // remains live until all of the data has been consumed from the stream. + virtual bool WriteAliasedRaw(const void* data, int size); + virtual bool AllowsAliasing() const { return false; } + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream); +}; + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ diff --git a/thirdparty/linux/include/google/protobuf/io/zero_copy_stream_impl.h b/thirdparty/linux/include/google/protobuf/io/zero_copy_stream_impl.h new file mode 100644 index 0000000..0746fa6 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/io/zero_copy_stream_impl.h @@ -0,0 +1,358 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains common implementations of the interfaces defined in +// zero_copy_stream.h which are only included in the full (non-lite) +// protobuf library. These implementations include Unix file descriptors +// and C++ iostreams. See also: zero_copy_stream_impl_lite.h + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ + +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace io { + + +// =================================================================== + +// A ZeroCopyInputStream which reads from a file descriptor. +// +// FileInputStream is preferred over using an ifstream with IstreamInputStream. +// The latter will introduce an extra layer of buffering, harming performance. +// Also, it's conceivable that FileInputStream could someday be enhanced +// to use zero-copy file descriptors on OSs which support them. +class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given Unix file descriptor. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. + explicit FileInputStream(int file_descriptor, int block_size = -1); + ~FileInputStream(); + + // Flushes any buffers and closes the underlying file. Returns false if + // an error occurs during the process; use GetErrno() to examine the error. + // Even if an error occurs, the file descriptor is closed when this returns. + bool Close(); + + // By default, the file descriptor is not closed when the stream is + // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: + // This leaves no way for the caller to detect if close() fails. If + // detecting close() errors is important to you, you should arrange + // to close the descriptor yourself. + void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); } + + // If an I/O error has occurred on this file descriptor, this is the + // errno from that error. Otherwise, this is zero. Once an error + // occurs, the stream is broken and all subsequent operations will + // fail. + int GetErrno() { return copying_input_.GetErrno(); } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream { + public: + CopyingFileInputStream(int file_descriptor); + ~CopyingFileInputStream(); + + bool Close(); + void SetCloseOnDelete(bool value) { close_on_delete_ = value; } + int GetErrno() { return errno_; } + + // implements CopyingInputStream --------------------------------- + int Read(void* buffer, int size); + int Skip(int count); + + private: + // The file descriptor. + const int file_; + bool close_on_delete_; + bool is_closed_; + + // The errno of the I/O error, if one has occurred. Otherwise, zero. + int errno_; + + // Did we try to seek once and fail? If so, we assume this file descriptor + // doesn't support seeking and won't try again. + bool previous_seek_failed_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream); + }; + + CopyingFileInputStream copying_input_; + CopyingInputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which writes to a file descriptor. +// +// FileOutputStream is preferred over using an ofstream with +// OstreamOutputStream. The latter will introduce an extra layer of buffering, +// harming performance. Also, it's conceivable that FileOutputStream could +// someday be enhanced to use zero-copy file descriptors on OSs which +// support them. +class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given Unix file descriptor. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit FileOutputStream(int file_descriptor, int block_size = -1); + ~FileOutputStream(); + + // Flushes any buffers and closes the underlying file. Returns false if + // an error occurs during the process; use GetErrno() to examine the error. + // Even if an error occurs, the file descriptor is closed when this returns. + bool Close(); + + // Flushes FileOutputStream's buffers but does not close the + // underlying file. No special measures are taken to ensure that + // underlying operating system file object is synchronized to disk. + bool Flush(); + + // By default, the file descriptor is not closed when the stream is + // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: + // This leaves no way for the caller to detect if close() fails. If + // detecting close() errors is important to you, you should arrange + // to close the descriptor yourself. + void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); } + + // If an I/O error has occurred on this file descriptor, this is the + // errno from that error. Otherwise, this is zero. Once an error + // occurs, the stream is broken and all subsequent operations will + // fail. + int GetErrno() { return copying_output_.GetErrno(); } + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { + public: + CopyingFileOutputStream(int file_descriptor); + ~CopyingFileOutputStream(); + + bool Close(); + void SetCloseOnDelete(bool value) { close_on_delete_ = value; } + int GetErrno() { return errno_; } + + // implements CopyingOutputStream -------------------------------- + bool Write(const void* buffer, int size); + + private: + // The file descriptor. + const int file_; + bool close_on_delete_; + bool is_closed_; + + // The errno of the I/O error, if one has occurred. Otherwise, zero. + int errno_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream); + }; + + CopyingFileOutputStream copying_output_; + CopyingOutputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream); +}; + +// =================================================================== + +// A ZeroCopyInputStream which reads from a C++ istream. +// +// Note that for reading files (or anything represented by a file descriptor), +// FileInputStream is more efficient. +class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given C++ istream. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. + explicit IstreamInputStream(istream* stream, int block_size = -1); + ~IstreamInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream { + public: + CopyingIstreamInputStream(istream* input); + ~CopyingIstreamInputStream(); + + // implements CopyingInputStream --------------------------------- + int Read(void* buffer, int size); + // (We use the default implementation of Skip().) + + private: + // The stream. + istream* input_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream); + }; + + CopyingIstreamInputStream copying_input_; + CopyingInputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which writes to a C++ ostream. +// +// Note that for writing files (or anything represented by a file descriptor), +// FileOutputStream is more efficient. +class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given C++ ostream. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit OstreamOutputStream(ostream* stream, int block_size = -1); + ~OstreamOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream { + public: + CopyingOstreamOutputStream(ostream* output); + ~CopyingOstreamOutputStream(); + + // implements CopyingOutputStream -------------------------------- + bool Write(const void* buffer, int size); + + private: + // The stream. + ostream* output_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream); + }; + + CopyingOstreamOutputStream copying_output_; + CopyingOutputStreamAdaptor impl_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream); +}; + +// =================================================================== + +// A ZeroCopyInputStream which reads from several other streams in sequence. +// ConcatenatingInputStream is unable to distinguish between end-of-stream +// and read errors in the underlying streams, so it assumes any errors mean +// end-of-stream. So, if the underlying streams fail for any other reason, +// ConcatenatingInputStream may do odd things. It is suggested that you do +// not use ConcatenatingInputStream on streams that might produce read errors +// other than end-of-stream. +class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { + public: + // All streams passed in as well as the array itself must remain valid + // until the ConcatenatingInputStream is destroyed. + ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count); + ~ConcatenatingInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + + private: + // As streams are retired, streams_ is incremented and count_ is + // decremented. + ZeroCopyInputStream* const* streams_; + int stream_count_; + int64 bytes_retired_; // Bytes read from previous streams. + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream); +}; + +// =================================================================== + +// A ZeroCopyInputStream which wraps some other stream and limits it to +// a particular byte count. +class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream { + public: + LimitingInputStream(ZeroCopyInputStream* input, int64 limit); + ~LimitingInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + + private: + ZeroCopyInputStream* input_; + int64 limit_; // Decreases as we go, becomes negative if we overshoot. + int64 prior_bytes_read_; // Bytes read on underlying stream at construction + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream); +}; + +// =================================================================== + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ diff --git a/thirdparty/linux/include/google/protobuf/io/zero_copy_stream_impl_lite.h b/thirdparty/linux/include/google/protobuf/io/zero_copy_stream_impl_lite.h new file mode 100644 index 0000000..e4d6a02 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -0,0 +1,410 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file contains common implementations of the interfaces defined in +// zero_copy_stream.h which are included in the "lite" protobuf library. +// These implementations cover I/O on raw arrays and strings, as well as +// adaptors which make it easy to implement streams based on traditional +// streams. Of course, many users will probably want to write their own +// implementations of these interfaces specific to the particular I/O +// abstractions they prefer to use, but these should cover the most common +// cases. + +#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ +#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ + +#include +#ifndef _SHARED_PTR_H +#include +#endif +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace io { + +// =================================================================== + +// A ZeroCopyInputStream backed by an in-memory array of bytes. +class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { + public: + // Create an InputStream that returns the bytes pointed to by "data". + // "data" remains the property of the caller but must remain valid until + // the stream is destroyed. If a block_size is given, calls to Next() + // will return data blocks no larger than the given size. Otherwise, the + // first call to Next() returns the entire array. block_size is mainly + // useful for testing; in production you would probably never want to set + // it. + ArrayInputStream(const void* data, int size, int block_size = -1); + ~ArrayInputStream(); + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + + private: + const uint8* const data_; // The byte array. + const int size_; // Total size of the array. + const int block_size_; // How many bytes to return at a time. + + int position_; + int last_returned_size_; // How many bytes we returned last time Next() + // was called (used for error checking only). + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream backed by an in-memory array of bytes. +class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { + public: + // Create an OutputStream that writes to the bytes pointed to by "data". + // "data" remains the property of the caller but must remain valid until + // the stream is destroyed. If a block_size is given, calls to Next() + // will return data blocks no larger than the given size. Otherwise, the + // first call to Next() returns the entire array. block_size is mainly + // useful for testing; in production you would probably never want to set + // it. + ArrayOutputStream(void* data, int size, int block_size = -1); + ~ArrayOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + uint8* const data_; // The byte array. + const int size_; // Total size of the array. + const int block_size_; // How many bytes to return at a time. + + int position_; + int last_returned_size_; // How many bytes we returned last time Next() + // was called (used for error checking only). + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream); +}; + +// =================================================================== + +// A ZeroCopyOutputStream which appends bytes to a string. +class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { + public: + // Create a StringOutputStream which appends bytes to the given string. + // The string remains property of the caller, but it is mutated in arbitrary + // ways and MUST NOT be accessed in any way until you're done with the + // stream. Either be sure there's no further usage, or (safest) destroy the + // stream before using the contents. + // + // Hint: If you call target->reserve(n) before creating the stream, + // the first call to Next() will return at least n bytes of buffer + // space. + explicit StringOutputStream(string* target); + ~StringOutputStream(); + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + protected: + void SetString(string* target); + + private: + static const int kMinimumSize = 16; + + string* target_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream); +}; + +// LazyStringOutputStream is a StringOutputStream with lazy acquisition of +// the output string from a callback. The string is owned externally, and not +// deleted in the stream destructor. +class LIBPROTOBUF_EXPORT LazyStringOutputStream : public StringOutputStream { + public: + // Callback should be permanent (non-self-deleting). Ownership is transferred + // to the LazyStringOutputStream. + explicit LazyStringOutputStream(ResultCallback* callback); + ~LazyStringOutputStream(); + + // implements ZeroCopyOutputStream, overriding StringOutputStream ----------- + bool Next(void** data, int* size); + int64 ByteCount() const; + + private: + const google::protobuf::scoped_ptr > callback_; + bool string_is_set_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyStringOutputStream); +}; + +// Note: There is no StringInputStream. Instead, just create an +// ArrayInputStream as follows: +// ArrayInputStream input(str.data(), str.size()); + +// =================================================================== + +// A generic traditional input stream interface. +// +// Lots of traditional input streams (e.g. file descriptors, C stdio +// streams, and C++ iostreams) expose an interface where every read +// involves copying bytes into a buffer. If you want to take such an +// interface and make a ZeroCopyInputStream based on it, simply implement +// CopyingInputStream and then use CopyingInputStreamAdaptor. +// +// CopyingInputStream implementations should avoid buffering if possible. +// CopyingInputStreamAdaptor does its own buffering and will read data +// in large blocks. +class LIBPROTOBUF_EXPORT CopyingInputStream { + public: + virtual ~CopyingInputStream(); + + // Reads up to "size" bytes into the given buffer. Returns the number of + // bytes read. Read() waits until at least one byte is available, or + // returns zero if no bytes will ever become available (EOF), or -1 if a + // permanent read error occurred. + virtual int Read(void* buffer, int size) = 0; + + // Skips the next "count" bytes of input. Returns the number of bytes + // actually skipped. This will always be exactly equal to "count" unless + // EOF was reached or a permanent read error occurred. + // + // The default implementation just repeatedly calls Read() into a scratch + // buffer. + virtual int Skip(int count); +}; + +// A ZeroCopyInputStream which reads from a CopyingInputStream. This is +// useful for implementing ZeroCopyInputStreams that read from traditional +// streams. Note that this class is not really zero-copy. +// +// If you want to read from file descriptors or C++ istreams, this is +// already implemented for you: use FileInputStream or IstreamInputStream +// respectively. +class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream { + public: + // Creates a stream that reads from the given CopyingInputStream. + // If a block_size is given, it specifies the number of bytes that + // should be read and returned with each call to Next(). Otherwise, + // a reasonable default is used. The caller retains ownership of + // copying_stream unless SetOwnsCopyingStream(true) is called. + explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream, + int block_size = -1); + ~CopyingInputStreamAdaptor(); + + // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to + // delete the underlying CopyingInputStream when it is destroyed. + void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } + + // implements ZeroCopyInputStream ---------------------------------- + bool Next(const void** data, int* size); + void BackUp(int count); + bool Skip(int count); + int64 ByteCount() const; + + private: + // Insures that buffer_ is not NULL. + void AllocateBufferIfNeeded(); + // Frees the buffer and resets buffer_used_. + void FreeBuffer(); + + // The underlying copying stream. + CopyingInputStream* copying_stream_; + bool owns_copying_stream_; + + // True if we have seen a permenant error from the underlying stream. + bool failed_; + + // The current position of copying_stream_, relative to the point where + // we started reading. + int64 position_; + + // Data is read into this buffer. It may be NULL if no buffer is currently + // in use. Otherwise, it points to an array of size buffer_size_. + google::protobuf::scoped_array buffer_; + const int buffer_size_; + + // Number of valid bytes currently in the buffer (i.e. the size last + // returned by Next()). 0 <= buffer_used_ <= buffer_size_. + int buffer_used_; + + // Number of bytes in the buffer which were backed up over by a call to + // BackUp(). These need to be returned again. + // 0 <= backup_bytes_ <= buffer_used_ + int backup_bytes_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor); +}; + +// =================================================================== + +// A generic traditional output stream interface. +// +// Lots of traditional output streams (e.g. file descriptors, C stdio +// streams, and C++ iostreams) expose an interface where every write +// involves copying bytes from a buffer. If you want to take such an +// interface and make a ZeroCopyOutputStream based on it, simply implement +// CopyingOutputStream and then use CopyingOutputStreamAdaptor. +// +// CopyingOutputStream implementations should avoid buffering if possible. +// CopyingOutputStreamAdaptor does its own buffering and will write data +// in large blocks. +class LIBPROTOBUF_EXPORT CopyingOutputStream { + public: + virtual ~CopyingOutputStream(); + + // Writes "size" bytes from the given buffer to the output. Returns true + // if successful, false on a write error. + virtual bool Write(const void* buffer, int size) = 0; +}; + +// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is +// useful for implementing ZeroCopyOutputStreams that write to traditional +// streams. Note that this class is not really zero-copy. +// +// If you want to write to file descriptors or C++ ostreams, this is +// already implemented for you: use FileOutputStream or OstreamOutputStream +// respectively. +class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { + public: + // Creates a stream that writes to the given Unix file descriptor. + // If a block_size is given, it specifies the size of the buffers + // that should be returned by Next(). Otherwise, a reasonable default + // is used. + explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream, + int block_size = -1); + ~CopyingOutputStreamAdaptor(); + + // Writes all pending data to the underlying stream. Returns false if a + // write error occurred on the underlying stream. (The underlying + // stream itself is not necessarily flushed.) + bool Flush(); + + // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to + // delete the underlying CopyingOutputStream when it is destroyed. + void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } + + // implements ZeroCopyOutputStream --------------------------------- + bool Next(void** data, int* size); + void BackUp(int count); + int64 ByteCount() const; + + private: + // Write the current buffer, if it is present. + bool WriteBuffer(); + // Insures that buffer_ is not NULL. + void AllocateBufferIfNeeded(); + // Frees the buffer. + void FreeBuffer(); + + // The underlying copying stream. + CopyingOutputStream* copying_stream_; + bool owns_copying_stream_; + + // True if we have seen a permenant error from the underlying stream. + bool failed_; + + // The current position of copying_stream_, relative to the point where + // we started writing. + int64 position_; + + // Data is written from this buffer. It may be NULL if no buffer is + // currently in use. Otherwise, it points to an array of size buffer_size_. + google::protobuf::scoped_array buffer_; + const int buffer_size_; + + // Number of valid bytes currently in the buffer (i.e. the size last + // returned by Next()). When BackUp() is called, we just reduce this. + // 0 <= buffer_used_ <= buffer_size_. + int buffer_used_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor); +}; + +// =================================================================== + +// mutable_string_data() and as_string_data() are workarounds to improve +// the performance of writing new data to an existing string. Unfortunately +// the methods provided by the string class are suboptimal, and using memcpy() +// is mildly annoying because it requires its pointer args to be non-NULL even +// if we ask it to copy 0 bytes. Furthermore, string_as_array() has the +// property that it always returns NULL if its arg is the empty string, exactly +// what we want to avoid if we're using it in conjunction with memcpy()! +// With C++11, the desired memcpy() boils down to memcpy(..., &(*s)[0], size), +// where s is a string*. Without C++11, &(*s)[0] is not guaranteed to be safe, +// so we use string_as_array(), and live with the extra logic that tests whether +// *s is empty. + +// Return a pointer to mutable characters underlying the given string. The +// return value is valid until the next time the string is resized. We +// trust the caller to treat the return value as an array of length s->size(). +inline char* mutable_string_data(string* s) { +#ifdef LANG_CXX11 + // This should be simpler & faster than string_as_array() because the latter + // is guaranteed to return NULL when *s is empty, so it has to check for that. + return &(*s)[0]; +#else + return string_as_array(s); +#endif +} + +// as_string_data(s) is equivalent to +// ({ char* p = mutable_string_data(s); make_pair(p, p != NULL); }) +// Sometimes it's faster: in some scenarios p cannot be NULL, and then the +// code can avoid that check. +inline std::pair as_string_data(string* s) { + char *p = mutable_string_data(s); +#ifdef LANG_CXX11 + return std::make_pair(p, true); +#else + return make_pair(p, p != NULL); +#endif +} + +} // namespace io +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__ diff --git a/thirdparty/linux/include/google/protobuf/map.h b/thirdparty/linux/include/google/protobuf/map.h new file mode 100644 index 0000000..1b9aa70 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/map.h @@ -0,0 +1,1742 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_MAP_H__ +#define GOOGLE_PROTOBUF_MAP_H__ + +#include +#include +#include // To support Visual Studio 2008 +#include +#include + +#include +#include +#include +#include +#include +#include +#if __cpp_exceptions && LANG_CXX11 +#include +#endif + +namespace google { +namespace protobuf { + +// The Map and MapIterator types are provided by this header file. +// Please avoid using other types defined here, unless they are public +// types within Map or MapIterator, such as Map::value_type. +template +class Map; + +class MapIterator; + +template struct is_proto_enum; + +namespace internal { +template +class MapFieldLite; + +template +class MapField; + +template +class TypeDefinedMapFieldBase; + +class DynamicMapField; + +class GeneratedMessageReflection; +} // namespace internal + +#define TYPE_CHECK(EXPECTEDTYPE, METHOD) \ + if (type() != EXPECTEDTYPE) { \ + GOOGLE_LOG(FATAL) \ + << "Protocol Buffer map usage error:\n" \ + << METHOD << " type does not match\n" \ + << " Expected : " \ + << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \ + << " Actual : " \ + << FieldDescriptor::CppTypeName(type()); \ + } + +// MapKey is an union type for representing any possible +// map key. +class LIBPROTOBUF_EXPORT MapKey { + public: + MapKey() : type_(0) { + } + MapKey(const MapKey& other) : type_(0) { + CopyFrom(other); + } + + ~MapKey() { + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + delete val_.string_value_; + } + } + + FieldDescriptor::CppType type() const { + if (type_ == 0) { + GOOGLE_LOG(FATAL) + << "Protocol Buffer map usage error:\n" + << "MapKey::type MapKey is not initialized. " + << "Call set methods to initialize MapKey."; + } + return (FieldDescriptor::CppType)type_; + } + + void SetInt64Value(int64 value) { + SetType(FieldDescriptor::CPPTYPE_INT64); + val_.int64_value_ = value; + } + void SetUInt64Value(uint64 value) { + SetType(FieldDescriptor::CPPTYPE_UINT64); + val_.uint64_value_ = value; + } + void SetInt32Value(int32 value) { + SetType(FieldDescriptor::CPPTYPE_INT32); + val_.int32_value_ = value; + } + void SetUInt32Value(uint32 value) { + SetType(FieldDescriptor::CPPTYPE_UINT32); + val_.uint32_value_ = value; + } + void SetBoolValue(bool value) { + SetType(FieldDescriptor::CPPTYPE_BOOL); + val_.bool_value_ = value; + } + void SetStringValue(const string& val) { + SetType(FieldDescriptor::CPPTYPE_STRING); + *val_.string_value_ = val; + } + + int64 GetInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, + "MapKey::GetInt64Value"); + return val_.int64_value_; + } + uint64 GetUInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, + "MapKey::GetUInt64Value"); + return val_.uint64_value_; + } + int32 GetInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, + "MapKey::GetInt32Value"); + return val_.int32_value_; + } + uint32 GetUInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, + "MapKey::GetUInt32Value"); + return val_.uint32_value_; + } + bool GetBoolValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, + "MapKey::GetBoolValue"); + return val_.bool_value_; + } + const string& GetStringValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, + "MapKey::GetStringValue"); + return *val_.string_value_; + } + + bool operator<(const MapKey& other) const { + if (type_ != other.type_) { + // We could define a total order that handles this case, but + // there currently no need. So, for now, fail. + GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; + } + switch (type()) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + return false; + case FieldDescriptor::CPPTYPE_STRING: + return *val_.string_value_ < *other.val_.string_value_; + case FieldDescriptor::CPPTYPE_INT64: + return val_.int64_value_ < other.val_.int64_value_; + case FieldDescriptor::CPPTYPE_INT32: + return val_.int32_value_ < other.val_.int32_value_; + case FieldDescriptor::CPPTYPE_UINT64: + return val_.uint64_value_ < other.val_.uint64_value_; + case FieldDescriptor::CPPTYPE_UINT32: + return val_.uint32_value_ < other.val_.uint32_value_; + case FieldDescriptor::CPPTYPE_BOOL: + return val_.bool_value_ < other.val_.bool_value_; + } + return false; + } + + bool operator==(const MapKey& other) const { + if (type_ != other.type_) { + // To be consistent with operator<, we don't allow this either. + GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; + } + switch (type()) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case FieldDescriptor::CPPTYPE_STRING: + return *val_.string_value_ == *other.val_.string_value_; + case FieldDescriptor::CPPTYPE_INT64: + return val_.int64_value_ == other.val_.int64_value_; + case FieldDescriptor::CPPTYPE_INT32: + return val_.int32_value_ == other.val_.int32_value_; + case FieldDescriptor::CPPTYPE_UINT64: + return val_.uint64_value_ == other.val_.uint64_value_; + case FieldDescriptor::CPPTYPE_UINT32: + return val_.uint32_value_ == other.val_.uint32_value_; + case FieldDescriptor::CPPTYPE_BOOL: + return val_.bool_value_ == other.val_.bool_value_; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; + } + + void CopyFrom(const MapKey& other) { + SetType(other.type()); + switch (type_) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case FieldDescriptor::CPPTYPE_STRING: + *val_.string_value_ = *other.val_.string_value_; + break; + case FieldDescriptor::CPPTYPE_INT64: + val_.int64_value_ = other.val_.int64_value_; + break; + case FieldDescriptor::CPPTYPE_INT32: + val_.int32_value_ = other.val_.int32_value_; + break; + case FieldDescriptor::CPPTYPE_UINT64: + val_.uint64_value_ = other.val_.uint64_value_; + break; + case FieldDescriptor::CPPTYPE_UINT32: + val_.uint32_value_ = other.val_.uint32_value_; + break; + case FieldDescriptor::CPPTYPE_BOOL: + val_.bool_value_ = other.val_.bool_value_; + break; + } + } + + private: + template + friend class internal::TypeDefinedMapFieldBase; + friend class MapIterator; + friend class internal::DynamicMapField; + + union KeyValue { + KeyValue() {} + string* string_value_; + int64 int64_value_; + int32 int32_value_; + uint64 uint64_value_; + uint32 uint32_value_; + bool bool_value_; + } val_; + + void SetType(FieldDescriptor::CppType type) { + if (type_ == type) return; + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + delete val_.string_value_; + } + type_ = type; + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + val_.string_value_ = new string; + } + } + + // type_ is 0 or a valid FieldDescriptor::CppType. + int type_; +}; + +// MapValueRef points to a map value. +class LIBPROTOBUF_EXPORT MapValueRef { + public: + MapValueRef() : data_(NULL), type_(0) {} + + void SetInt64Value(int64 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, + "MapValueRef::SetInt64Value"); + *reinterpret_cast(data_) = value; + } + void SetUInt64Value(uint64 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, + "MapValueRef::SetUInt64Value"); + *reinterpret_cast(data_) = value; + } + void SetInt32Value(int32 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, + "MapValueRef::SetInt32Value"); + *reinterpret_cast(data_) = value; + } + void SetUInt32Value(uint32 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, + "MapValueRef::SetUInt32Value"); + *reinterpret_cast(data_) = value; + } + void SetBoolValue(bool value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, + "MapValueRef::SetBoolValue"); + *reinterpret_cast(data_) = value; + } + // TODO(jieluo) - Checks that enum is member. + void SetEnumValue(int value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, + "MapValueRef::SetEnumValue"); + *reinterpret_cast(data_) = value; + } + void SetStringValue(const string& value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, + "MapValueRef::SetStringValue"); + *reinterpret_cast(data_) = value; + } + void SetFloatValue(float value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, + "MapValueRef::SetFloatValue"); + *reinterpret_cast(data_) = value; + } + void SetDoubleValue(double value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, + "MapValueRef::SetDoubleValue"); + *reinterpret_cast(data_) = value; + } + + int64 GetInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, + "MapValueRef::GetInt64Value"); + return *reinterpret_cast(data_); + } + uint64 GetUInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, + "MapValueRef::GetUInt64Value"); + return *reinterpret_cast(data_); + } + int32 GetInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, + "MapValueRef::GetInt32Value"); + return *reinterpret_cast(data_); + } + uint32 GetUInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, + "MapValueRef::GetUInt32Value"); + return *reinterpret_cast(data_); + } + bool GetBoolValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, + "MapValueRef::GetBoolValue"); + return *reinterpret_cast(data_); + } + int GetEnumValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, + "MapValueRef::GetEnumValue"); + return *reinterpret_cast(data_); + } + const string& GetStringValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, + "MapValueRef::GetStringValue"); + return *reinterpret_cast(data_); + } + float GetFloatValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, + "MapValueRef::GetFloatValue"); + return *reinterpret_cast(data_); + } + double GetDoubleValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, + "MapValueRef::GetDoubleValue"); + return *reinterpret_cast(data_); + } + + const Message& GetMessageValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, + "MapValueRef::GetMessageValue"); + return *reinterpret_cast(data_); + } + + Message* MutableMessageValue() { + TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, + "MapValueRef::MutableMessageValue"); + return reinterpret_cast(data_); + } + + private: + template + friend class internal::MapField; + template + friend class internal::TypeDefinedMapFieldBase; + friend class MapIterator; + friend class internal::GeneratedMessageReflection; + friend class internal::DynamicMapField; + + void SetType(FieldDescriptor::CppType type) { + type_ = type; + } + + FieldDescriptor::CppType type() const { + if (type_ == 0 || data_ == NULL) { + GOOGLE_LOG(FATAL) + << "Protocol Buffer map usage error:\n" + << "MapValueRef::type MapValueRef is not initialized."; + } + return (FieldDescriptor::CppType)type_; + } + void SetValue(const void* val) { + data_ = const_cast(val); + } + void CopyFrom(const MapValueRef& other) { + type_ = other.type_; + data_ = other.data_; + } + // Only used in DynamicMapField + void DeleteData() { + switch (type_) { +#define HANDLE_TYPE(CPPTYPE, TYPE) \ + case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \ + delete reinterpret_cast(data_); \ + break; \ + } + HANDLE_TYPE(INT32, int32); + HANDLE_TYPE(INT64, int64); + HANDLE_TYPE(UINT32, uint32); + HANDLE_TYPE(UINT64, uint64); + HANDLE_TYPE(DOUBLE, double); + HANDLE_TYPE(FLOAT, float); + HANDLE_TYPE(BOOL, bool); + HANDLE_TYPE(STRING, string); + HANDLE_TYPE(ENUM, int32); + HANDLE_TYPE(MESSAGE, Message); +#undef HANDLE_TYPE + } + } + // data_ point to a map value. MapValueRef does not + // own this value. + void* data_; + // type_ is 0 or a valid FieldDescriptor::CppType. + int type_; +}; + +#undef TYPE_CHECK + +// This is the class for google::protobuf::Map's internal value_type. Instead of using +// std::pair as value_type, we use this class which provides us more control of +// its process of construction and destruction. +template +class MapPair { + public: + typedef const Key first_type; + typedef T second_type; + + MapPair(const Key& other_first, const T& other_second) + : first(other_first), second(other_second) {} + explicit MapPair(const Key& other_first) : first(other_first), second() {} + MapPair(const MapPair& other) + : first(other.first), second(other.second) {} + + ~MapPair() {} + + // Implicitly convertible to std::pair of compatible types. + template + operator std::pair() const { + return std::pair(first, second); + } + + const Key first; + T second; + + private: + friend class ::google::protobuf::Arena; + friend class Map; +}; + +// google::protobuf::Map is an associative container type used to store protobuf map +// fields. Each Map instance may or may not use a different hash function, a +// different iteration order, and so on. E.g., please don't examine +// implementation details to decide if the following would work: +// Map m0, m1; +// m0[0] = m1[0] = m0[1] = m1[1] = 0; +// assert(m0.begin()->first == m1.begin()->first); // Bug! +// +// Map's interface is similar to std::unordered_map, except that Map is not +// designed to play well with exceptions. +template +class Map { + public: + typedef Key key_type; + typedef T mapped_type; + typedef MapPair value_type; + + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + typedef size_t size_type; + typedef hash hasher; + + explicit Map(bool old_style = true) + : arena_(NULL), + default_enum_value_(0), + old_style_(old_style) { + Init(); + } + explicit Map(Arena* arena, bool old_style = true) + : arena_(arena), + default_enum_value_(0), + old_style_(old_style) { + Init(); + } + Map(const Map& other) + : arena_(NULL), + default_enum_value_(other.default_enum_value_), + old_style_(other.old_style_) { + Init(); + insert(other.begin(), other.end()); + } + template + Map(const InputIt& first, const InputIt& last, bool old_style = true) + : arena_(NULL), + default_enum_value_(0), + old_style_(old_style) { + Init(); + insert(first, last); + } + + ~Map() { + clear(); + if (arena_ == NULL) { + if (old_style_) + delete deprecated_elements_; + else + delete elements_; + } + } + + private: + void Init() { + if (old_style_) + deprecated_elements_ = Arena::Create( + arena_, 0, hasher(), equal_to(), + MapAllocator*> >(arena_)); + else + elements_ = + Arena::Create(arena_, 0, hasher(), Allocator(arena_)); + } + + // re-implement std::allocator to use arena allocator for memory allocation. + // Used for google::protobuf::Map implementation. Users should not use this class + // directly. + template + class MapAllocator { + public: + typedef U value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + MapAllocator() : arena_(NULL) {} + explicit MapAllocator(Arena* arena) : arena_(arena) {} + template + MapAllocator(const MapAllocator& allocator) + : arena_(allocator.arena()) {} + + pointer allocate(size_type n, const_pointer hint = 0) { + // If arena is not given, malloc needs to be called which doesn't + // construct element object. + if (arena_ == NULL) { + return reinterpret_cast(malloc(n * sizeof(value_type))); + } else { + return reinterpret_cast( + Arena::CreateArray(arena_, n * sizeof(value_type))); + } + } + + void deallocate(pointer p, size_type n) { + if (arena_ == NULL) { + free(p); + } + } + +#if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE) && \ + !defined(GOOGLE_PROTOBUF_OS_NACL) && \ + !defined(GOOGLE_PROTOBUF_OS_ANDROID) && \ + !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN) + template + void construct(NodeType* p, Args&&... args) { + // Clang 3.6 doesn't compile static casting to void* directly. (Issue + // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall + // not cast away constness". So first the maybe const pointer is casted to + // const void* and after the const void* is const casted. + new (const_cast(static_cast(p))) + NodeType(std::forward(args)...); + } + + template + void destroy(NodeType* p) { + p->~NodeType(); + } +#else + void construct(pointer p, const_reference t) { new (p) value_type(t); } + + void destroy(pointer p) { p->~value_type(); } +#endif + + template + struct rebind { + typedef MapAllocator other; + }; + + template + bool operator==(const MapAllocator& other) const { + return arena_ == other.arena_; + } + + template + bool operator!=(const MapAllocator& other) const { + return arena_ != other.arena_; + } + + // To support Visual Studio 2008 + size_type max_size() const { + return std::numeric_limits::max(); + } + + // To support gcc-4.4, which does not properly + // support templated friend classes + Arena* arena() const { + return arena_; + } + + private: + typedef void DestructorSkippable_; + Arena* const arena_; + }; + + // InnerMap's key type is Key and its value type is value_type*. We use a + // custom class here and for Node, below, to ensure that k_ is at offset 0, + // allowing safe conversion from pointer to Node to pointer to Key, and vice + // versa when appropriate. + class KeyValuePair { + public: + KeyValuePair(const Key& k, value_type* v) : k_(k), v_(v) {} + + const Key& key() const { return k_; } + Key& key() { return k_; } + value_type* const value() const { return v_; } + value_type*& value() { return v_; } + + private: + Key k_; + value_type* v_; + }; + + typedef MapAllocator Allocator; + + // InnerMap is a generic hash-based map. It doesn't contain any + // protocol-buffer-specific logic. It is a chaining hash map with the + // additional feature that some buckets can be converted to use an ordered + // container. This ensures O(lg n) bounds on find, insert, and erase, while + // avoiding the overheads of ordered containers most of the time. + // + // The implementation doesn't need the full generality of unordered_map, + // and it doesn't have it. More bells and whistles can be added as needed. + // Some implementation details: + // 1. The hash function has type hasher and the equality function + // equal_to. We inherit from hasher to save space + // (empty-base-class optimization). + // 2. The number of buckets is a power of two. + // 3. Buckets are converted to trees in pairs: if we convert bucket b then + // buckets b and b^1 will share a tree. Invariant: buckets b and b^1 have + // the same non-NULL value iff they are sharing a tree. (An alternative + // implementation strategy would be to have a tag bit per bucket.) + // 4. As is typical for hash_map and such, the Keys and Values are always + // stored in linked list nodes. Pointers to elements are never invalidated + // until the element is deleted. + // 5. The trees' payload type is pointer to linked-list node. Tree-converting + // a bucket doesn't copy Key-Value pairs. + // 6. Once we've tree-converted a bucket, it is never converted back. However, + // the items a tree contains may wind up assigned to trees or lists upon a + // rehash. + // 7. The code requires no C++ features from C++11 or later. + // 8. Mutations to a map do not invalidate the map's iterators, pointers to + // elements, or references to elements. + // 9. Except for erase(iterator), any non-const method can reorder iterators. + class InnerMap : private hasher { + public: + typedef value_type* Value; + + InnerMap(size_type n, hasher h, Allocator alloc) + : hasher(h), + num_elements_(0), + seed_(Seed()), + table_(NULL), + alloc_(alloc) { + n = TableSize(n); + table_ = CreateEmptyTable(n); + num_buckets_ = index_of_first_non_null_ = n; + } + + ~InnerMap() { + if (table_ != NULL) { + clear(); + Dealloc(table_, num_buckets_); + } + } + + private: + enum { kMinTableSize = 8 }; + + // Linked-list nodes, as one would expect for a chaining hash table. + struct Node { + KeyValuePair kv; + Node* next; + }; + + // This is safe only if the given pointer is known to point to a Key that is + // part of a Node. + static Node* NodePtrFromKeyPtr(Key* k) { + return reinterpret_cast(k); + } + + static Key* KeyPtrFromNodePtr(Node* node) { return &node->kv.key(); } + + // Trees. The payload type is pointer to Key, so that we can query the tree + // with Keys that are not in any particular data structure. When we insert, + // though, the pointer is always pointing to a Key that is inside a Node. + struct KeyCompare { + bool operator()(const Key* n0, const Key* n1) const { return *n0 < *n1; } + }; + typedef typename Allocator::template rebind::other KeyPtrAllocator; + typedef std::set Tree; + + // iterator and const_iterator are instantiations of iterator_base. + template + class iterator_base { + public: + typedef KeyValueType& reference; + typedef KeyValueType* pointer; + typedef typename Tree::iterator TreeIterator; + + // Invariants: + // node_ is always correct. This is handy because the most common + // operations are operator* and operator-> and they only use node_. + // When node_ is set to a non-NULL value, all the other non-const fields + // are updated to be correct also, but those fields can become stale + // if the underlying map is modified. When those fields are needed they + // are rechecked, and updated if necessary. + iterator_base() : node_(NULL) {} + + explicit iterator_base(const InnerMap* m) : m_(m) { + SearchFrom(m->index_of_first_non_null_); + } + + // Any iterator_base can convert to any other. This is overkill, and we + // rely on the enclosing class to use it wisely. The standard "iterator + // can convert to const_iterator" is OK but the reverse direction is not. + template + explicit iterator_base(const iterator_base& it) + : node_(it.node_), + m_(it.m_), + bucket_index_(it.bucket_index_), + tree_it_(it.tree_it_) {} + + iterator_base(Node* n, const InnerMap* m, size_type index) + : node_(n), + m_(m), + bucket_index_(index) {} + + iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index) + : node_(NodePtrFromKeyPtr(*tree_it)), + m_(m), + bucket_index_(index), + tree_it_(tree_it) { + // Invariant: iterators that use tree_it_ have an even bucket_index_. + GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0); + } + + // Advance through buckets, looking for the first that isn't empty. + // If nothing non-empty is found then leave node_ == NULL. + void SearchFrom(size_type start_bucket) { + GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ || + m_->table_[m_->index_of_first_non_null_] != NULL); + node_ = NULL; + for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_; + bucket_index_++) { + if (m_->TableEntryIsNonEmptyList(bucket_index_)) { + node_ = static_cast(m_->table_[bucket_index_]); + break; + } else if (m_->TableEntryIsTree(bucket_index_)) { + Tree* tree = static_cast(m_->table_[bucket_index_]); + GOOGLE_DCHECK(!tree->empty()); + tree_it_ = tree->begin(); + node_ = NodePtrFromKeyPtr(*tree_it_); + break; + } + } + } + + reference operator*() const { return node_->kv; } + pointer operator->() const { return &(operator*()); } + + friend bool operator==(const iterator_base& a, const iterator_base& b) { + return a.node_ == b.node_; + } + friend bool operator!=(const iterator_base& a, const iterator_base& b) { + return a.node_ != b.node_; + } + + iterator_base& operator++() { + if (node_->next == NULL) { + const bool is_list = revalidate_if_necessary(); + if (is_list) { + SearchFrom(bucket_index_ + 1); + } else { + GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0); + Tree* tree = static_cast(m_->table_[bucket_index_]); + if (++tree_it_ == tree->end()) { + SearchFrom(bucket_index_ + 2); + } else { + node_ = NodePtrFromKeyPtr(*tree_it_); + } + } + } else { + node_ = node_->next; + } + return *this; + } + + iterator_base operator++(int /* unused */) { + iterator_base tmp = *this; + ++*this; + return tmp; + } + + // Assumes node_ and m_ are correct and non-NULL, but other fields may be + // stale. Fix them as needed. Then return true iff node_ points to a + // Node in a list. + bool revalidate_if_necessary() { + GOOGLE_DCHECK(node_ != NULL && m_ != NULL); + // Force bucket_index_ to be in range. + bucket_index_ &= (m_->num_buckets_ - 1); + // Common case: the bucket we think is relevant points to node_. + if (m_->table_[bucket_index_] == static_cast(node_)) + return true; + // Less common: the bucket is a linked list with node_ somewhere in it, + // but not at the head. + if (m_->TableEntryIsNonEmptyList(bucket_index_)) { + Node* l = static_cast(m_->table_[bucket_index_]); + while ((l = l->next) != NULL) { + if (l == node_) { + return true; + } + } + } + // Well, bucket_index_ still might be correct, but probably + // not. Revalidate just to be sure. This case is rare enough that we + // don't worry about potential optimizations, such as having a custom + // find-like method that compares Node* instead of const Key&. + iterator_base i(m_->find(*KeyPtrFromNodePtr(node_))); + bucket_index_ = i.bucket_index_; + tree_it_ = i.tree_it_; + return m_->TableEntryIsList(bucket_index_); + } + + Node* node_; + const InnerMap* m_; + size_type bucket_index_; + TreeIterator tree_it_; + }; + + public: + typedef iterator_base iterator; + typedef iterator_base const_iterator; + + iterator begin() { return iterator(this); } + iterator end() { return iterator(); } + const_iterator begin() const { return const_iterator(this); } + const_iterator end() const { return const_iterator(); } + + void clear() { + for (size_type b = 0; b < num_buckets_; b++) { + if (TableEntryIsNonEmptyList(b)) { + Node* node = static_cast(table_[b]); + table_[b] = NULL; + do { + Node* next = node->next; + DestroyNode(node); + node = next; + } while (node != NULL); + } else if (TableEntryIsTree(b)) { + Tree* tree = static_cast(table_[b]); + GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0); + table_[b] = table_[b + 1] = NULL; + typename Tree::iterator tree_it = tree->begin(); + do { + Node* node = NodePtrFromKeyPtr(*tree_it); + typename Tree::iterator next = tree_it; + ++next; + tree->erase(tree_it); + DestroyNode(node); + tree_it = next; + } while (tree_it != tree->end()); + DestroyTree(tree); + b++; + } + } + num_elements_ = 0; + index_of_first_non_null_ = num_buckets_; + } + + const hasher& hash_function() const { return *this; } + + static size_type max_size() { + return static_cast(1) << (sizeof(void**) >= 8 ? 60 : 28); + } + size_type size() const { return num_elements_; } + bool empty() const { return size() == 0; } + + iterator find(const Key& k) { return iterator(FindHelper(k).first); } + const_iterator find(const Key& k) const { return FindHelper(k).first; } + + // In traditional C++ style, this performs "insert if not present." + std::pair insert(const KeyValuePair& kv) { + std::pair p = FindHelper(kv.key()); + // Case 1: key was already present. + if (p.first.node_ != NULL) + return std::make_pair(iterator(p.first), false); + // Case 2: insert. + if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) { + p = FindHelper(kv.key()); + } + const size_type b = p.second; // bucket number + Node* node = Alloc(1); + alloc_.construct(&node->kv, kv); + iterator result = InsertUnique(b, node); + ++num_elements_; + return std::make_pair(result, true); + } + + // The same, but if an insertion is necessary then the value portion of the + // inserted key-value pair is left uninitialized. + std::pair insert(const Key& k) { + std::pair p = FindHelper(k); + // Case 1: key was already present. + if (p.first.node_ != NULL) + return std::make_pair(iterator(p.first), false); + // Case 2: insert. + if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) { + p = FindHelper(k); + } + const size_type b = p.second; // bucket number + Node* node = Alloc(1); + typedef typename Allocator::template rebind::other KeyAllocator; + KeyAllocator(alloc_).construct(&node->kv.key(), k); + iterator result = InsertUnique(b, node); + ++num_elements_; + return std::make_pair(result, true); + } + + Value& operator[](const Key& k) { + KeyValuePair kv(k, Value()); + return insert(kv).first->value(); + } + + void erase(iterator it) { + GOOGLE_DCHECK_EQ(it.m_, this); + const bool is_list = it.revalidate_if_necessary(); + size_type b = it.bucket_index_; + Node* const item = it.node_; + if (is_list) { + GOOGLE_DCHECK(TableEntryIsNonEmptyList(b)); + Node* head = static_cast(table_[b]); + head = EraseFromLinkedList(item, head); + table_[b] = static_cast(head); + } else { + GOOGLE_DCHECK(TableEntryIsTree(b)); + Tree* tree = static_cast(table_[b]); + tree->erase(it.tree_it_); + if (tree->empty()) { + // Force b to be the minimum of b and b ^ 1. This is important + // only because we want index_of_first_non_null_ to be correct. + b &= ~static_cast(1); + DestroyTree(tree); + table_[b] = table_[b + 1] = NULL; + } + } + DestroyNode(item); + --num_elements_; + if (GOOGLE_PREDICT_FALSE(b == index_of_first_non_null_)) { + while (index_of_first_non_null_ < num_buckets_ && + table_[index_of_first_non_null_] == NULL) { + ++index_of_first_non_null_; + } + } + } + + private: + std::pair FindHelper(const Key& k) const { + size_type b = BucketNumber(k); + if (TableEntryIsNonEmptyList(b)) { + Node* node = static_cast(table_[b]); + do { + if (IsMatch(*KeyPtrFromNodePtr(node), k)) { + return std::make_pair(const_iterator(node, this, b), b); + } else { + node = node->next; + } + } while (node != NULL); + } else if (TableEntryIsTree(b)) { + GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]); + b &= ~static_cast(1); + Tree* tree = static_cast(table_[b]); + Key* key = const_cast(&k); + typename Tree::iterator tree_it = tree->find(key); + if (tree_it != tree->end()) { + return std::make_pair(const_iterator(tree_it, this, b), b); + } + } + return std::make_pair(end(), b); + } + + // Insert the given Node in bucket b. If that would make bucket b too big, + // and bucket b is not a tree, create a tree for buckets b and b^1 to share. + // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct + // bucket. num_elements_ is not modified. + iterator InsertUnique(size_type b, Node* node) { + GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ || + table_[index_of_first_non_null_] != NULL); + // In practice, the code that led to this point may have already + // determined whether we are inserting into an empty list, a short list, + // or whatever. But it's probably cheap enough to recompute that here; + // it's likely that we're inserting into an empty or short list. + iterator result; + GOOGLE_DCHECK(find(*KeyPtrFromNodePtr(node)) == end()); + if (TableEntryIsEmpty(b)) { + result = InsertUniqueInList(b, node); + } else if (TableEntryIsNonEmptyList(b)) { + if (GOOGLE_PREDICT_FALSE(TableEntryIsTooLong(b))) { + TreeConvert(b); + result = InsertUniqueInTree(b, node); + GOOGLE_DCHECK_EQ(result.bucket_index_, b & ~static_cast(1)); + } else { + // Insert into a pre-existing list. This case cannot modify + // index_of_first_non_null_, so we skip the code to update it. + return InsertUniqueInList(b, node); + } + } else { + // Insert into a pre-existing tree. This case cannot modify + // index_of_first_non_null_, so we skip the code to update it. + return InsertUniqueInTree(b, node); + } + index_of_first_non_null_ = + std::min(index_of_first_non_null_, result.bucket_index_); + return result; + } + + // Helper for InsertUnique. Handles the case where bucket b is a + // not-too-long linked list. + iterator InsertUniqueInList(size_type b, Node* node) { + node->next = static_cast(table_[b]); + table_[b] = static_cast(node); + return iterator(node, this, b); + } + + // Helper for InsertUnique. Handles the case where bucket b points to a + // Tree. + iterator InsertUniqueInTree(size_type b, Node* node) { + GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]); + // Maintain the invariant that node->next is NULL for all Nodes in Trees. + node->next = NULL; + return iterator(static_cast(table_[b]) + ->insert(KeyPtrFromNodePtr(node)) + .first, + this, b & ~static_cast(1)); + } + + // Returns whether it did resize. Currently this is only used when + // num_elements_ increases, though it could be used in other situations. + // It checks for load too low as well as load too high: because any number + // of erases can occur between inserts, the load could be as low as 0 here. + // Resizing to a lower size is not always helpful, but failing to do so can + // destroy the expected big-O bounds for some operations. By having the + // policy that sometimes we resize down as well as up, clients can easily + // keep O(size()) = O(number of buckets) if they want that. + bool ResizeIfLoadIsOutOfRange(size_type new_size) { + const size_type kMaxMapLoadTimes16 = 12; // controls RAM vs CPU tradeoff + const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16; + const size_type lo_cutoff = hi_cutoff / 4; + // We don't care how many elements are in trees. If a lot are, + // we may resize even though there are many empty buckets. In + // practice, this seems fine. + if (GOOGLE_PREDICT_FALSE(new_size >= hi_cutoff)) { + if (num_buckets_ <= max_size() / 2) { + Resize(num_buckets_ * 2); + return true; + } + } else if (GOOGLE_PREDICT_FALSE(new_size <= lo_cutoff && + num_buckets_ > kMinTableSize)) { + size_type lg2_of_size_reduction_factor = 1; + // It's possible we want to shrink a lot here... size() could even be 0. + // So, estimate how much to shrink by making sure we don't shrink so + // much that we would need to grow the table after a few inserts. + const size_type hypothetical_size = new_size * 5 / 4 + 1; + while ((hypothetical_size << lg2_of_size_reduction_factor) < + hi_cutoff) { + ++lg2_of_size_reduction_factor; + } + size_type new_num_buckets = std::max( + kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor); + if (new_num_buckets != num_buckets_) { + Resize(new_num_buckets); + return true; + } + } + return false; + } + + // Resize to the given number of buckets. + void Resize(size_t new_num_buckets) { + GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize); + void** const old_table = table_; + const size_type old_table_size = num_buckets_; + num_buckets_ = new_num_buckets; + table_ = CreateEmptyTable(num_buckets_); + const size_type start = index_of_first_non_null_; + index_of_first_non_null_ = num_buckets_; + for (size_type i = start; i < old_table_size; i++) { + if (TableEntryIsNonEmptyList(old_table, i)) { + TransferList(old_table, i); + } else if (TableEntryIsTree(old_table, i)) { + TransferTree(old_table, i++); + } + } + Dealloc(old_table, old_table_size); + } + + void TransferList(void* const* table, size_type index) { + Node* node = static_cast(table[index]); + do { + Node* next = node->next; + InsertUnique(BucketNumber(*KeyPtrFromNodePtr(node)), node); + node = next; + } while (node != NULL); + } + + void TransferTree(void* const* table, size_type index) { + Tree* tree = static_cast(table[index]); + typename Tree::iterator tree_it = tree->begin(); + do { + Node* node = NodePtrFromKeyPtr(*tree_it); + InsertUnique(BucketNumber(**tree_it), node); + } while (++tree_it != tree->end()); + DestroyTree(tree); + } + + Node* EraseFromLinkedList(Node* item, Node* head) { + if (head == item) { + return head->next; + } else { + head->next = EraseFromLinkedList(item, head->next); + return head; + } + } + + bool TableEntryIsEmpty(size_type b) const { + return TableEntryIsEmpty(table_, b); + } + bool TableEntryIsNonEmptyList(size_type b) const { + return TableEntryIsNonEmptyList(table_, b); + } + bool TableEntryIsTree(size_type b) const { + return TableEntryIsTree(table_, b); + } + bool TableEntryIsList(size_type b) const { + return TableEntryIsList(table_, b); + } + static bool TableEntryIsEmpty(void* const* table, size_type b) { + return table[b] == NULL; + } + static bool TableEntryIsNonEmptyList(void* const* table, size_type b) { + return table[b] != NULL && table[b] != table[b ^ 1]; + } + static bool TableEntryIsTree(void* const* table, size_type b) { + return !TableEntryIsEmpty(table, b) && + !TableEntryIsNonEmptyList(table, b); + } + static bool TableEntryIsList(void* const* table, size_type b) { + return !TableEntryIsTree(table, b); + } + + void TreeConvert(size_type b) { + GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1)); + typename Allocator::template rebind::other tree_allocator(alloc_); + Tree* tree = tree_allocator.allocate(1); + // We want to use the three-arg form of construct, if it exists, but we + // create a temporary and use the two-arg construct that's known to exist. + // It's clunky, but the compiler should be able to generate more-or-less + // the same code. + tree_allocator.construct(tree, + Tree(KeyCompare(), KeyPtrAllocator(alloc_))); + // Now the tree is ready to use. + size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree); + GOOGLE_DCHECK_EQ(count, tree->size()); + table_[b] = table_[b ^ 1] = static_cast(tree); + } + + // Copy a linked list in the given bucket to a tree. + // Returns the number of things it copied. + size_type CopyListToTree(size_type b, Tree* tree) { + size_type count = 0; + Node* node = static_cast(table_[b]); + while (node != NULL) { + tree->insert(KeyPtrFromNodePtr(node)); + ++count; + Node* next = node->next; + node->next = NULL; + node = next; + } + return count; + } + + // Return whether table_[b] is a linked list that seems awfully long. + // Requires table_[b] to point to a non-empty linked list. + bool TableEntryIsTooLong(size_type b) { + const size_type kMaxLength = 8; + size_type count = 0; + Node* node = static_cast(table_[b]); + do { + ++count; + node = node->next; + } while (node != NULL); + // Invariant: no linked list ever is more than kMaxLength in length. + GOOGLE_DCHECK_LE(count, kMaxLength); + return count >= kMaxLength; + } + + size_type BucketNumber(const Key& k) const { + // We inherit from hasher, so one-arg operator() provides a hash function. + size_type h = (*const_cast(this))(k); + // To help prevent people from making assumptions about the hash function, + // we use the seed differently depending on NDEBUG. The default hash + // function, the seeding, etc., are all likely to change in the future. +#ifndef NDEBUG + return (h * (seed_ | 1)) & (num_buckets_ - 1); +#else + return (h + seed_) & (num_buckets_ - 1); +#endif + } + + bool IsMatch(const Key& k0, const Key& k1) const { + return std::equal_to()(k0, k1); + } + + // Return a power of two no less than max(kMinTableSize, n). + // Assumes either n < kMinTableSize or n is a power of two. + size_type TableSize(size_type n) { + return n < kMinTableSize ? kMinTableSize : n; + } + + // Use alloc_ to allocate an array of n objects of type U. + template + U* Alloc(size_type n) { + typedef typename Allocator::template rebind::other alloc_type; + return alloc_type(alloc_).allocate(n); + } + + // Use alloc_ to deallocate an array of n objects of type U. + template + void Dealloc(U* t, size_type n) { + typedef typename Allocator::template rebind::other alloc_type; + alloc_type(alloc_).deallocate(t, n); + } + + void DestroyNode(Node* node) { + alloc_.destroy(&node->kv); + Dealloc(node, 1); + } + + void DestroyTree(Tree* tree) { + typename Allocator::template rebind::other tree_allocator(alloc_); + tree_allocator.destroy(tree); + tree_allocator.deallocate(tree, 1); + } + + void** CreateEmptyTable(size_type n) { + GOOGLE_DCHECK(n >= kMinTableSize); + GOOGLE_DCHECK_EQ(n & (n - 1), 0); + void** result = Alloc(n); + memset(result, 0, n * sizeof(result[0])); + return result; + } + + // Return a randomish value. + size_type Seed() const { + // random_device can throw, so avoid it unless we are compiling with + // exceptions enabled. +#if __cpp_exceptions && LANG_CXX11 + try { + std::random_device rd; + std::knuth_b knuth(rd()); + std::uniform_int_distribution u; + return u(knuth); + } catch (...) { } +#endif + size_type s = static_cast(reinterpret_cast(this)); +#if defined(__x86_64__) && defined(__GNUC__) + uint32 hi, lo; + asm("rdtsc" : "=a" (lo), "=d" (hi)); + s += ((static_cast(hi) << 32) | lo); +#endif + return s; + } + + size_type num_elements_; + size_type num_buckets_; + size_type seed_; + size_type index_of_first_non_null_; + void** table_; // an array with num_buckets_ entries + Allocator alloc_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap); + }; // end of class InnerMap + + typedef hash_map, equal_to, + MapAllocator*> > > + DeprecatedInnerMap; + + public: + // Iterators + class iterator_base { + public: + // We support "old style" and "new style" iterators for now. This is + // temporary. Also, for "iterator()" we have an unknown category. + // TODO(gpike): get rid of this. + enum IteratorStyle { kUnknown, kOld, kNew }; + explicit iterator_base(IteratorStyle style) : iterator_style_(style) {} + + bool OldStyle() const { + GOOGLE_DCHECK_NE(iterator_style_, kUnknown); + return iterator_style_ == kOld; + } + bool UnknownStyle() const { + return iterator_style_ == kUnknown; + } + bool SameStyle(const iterator_base& other) const { + return iterator_style_ == other.iterator_style_; + } + + private: + IteratorStyle iterator_style_; + }; + + class const_iterator + : private iterator_base, + public std::iterator { + typedef typename InnerMap::const_iterator InnerIt; + typedef typename DeprecatedInnerMap::const_iterator DeprecatedInnerIt; + + public: + const_iterator() : iterator_base(iterator_base::kUnknown) {} + explicit const_iterator(const DeprecatedInnerIt& dit) + : iterator_base(iterator_base::kOld), dit_(dit) {} + explicit const_iterator(const InnerIt& it) + : iterator_base(iterator_base::kNew), it_(it) {} + + const_iterator(const const_iterator& other) + : iterator_base(other), it_(other.it_), dit_(other.dit_) {} + + const_reference operator*() const { + return this->OldStyle() ? *dit_->second : *it_->value(); + } + const_pointer operator->() const { return &(operator*()); } + + const_iterator& operator++() { + if (this->OldStyle()) + ++dit_; + else + ++it_; + return *this; + } + const_iterator operator++(int) { + return this->OldStyle() ? const_iterator(dit_++) : const_iterator(it_++); + } + + friend bool operator==(const const_iterator& a, const const_iterator& b) { + if (!a.SameStyle(b)) return false; + if (a.UnknownStyle()) return true; + return a.OldStyle() ? (a.dit_ == b.dit_) : (a.it_ == b.it_); + } + friend bool operator!=(const const_iterator& a, const const_iterator& b) { + return !(a == b); + } + + private: + InnerIt it_; + DeprecatedInnerIt dit_; + }; + + class iterator : private iterator_base, + public std::iterator { + typedef typename InnerMap::iterator InnerIt; + typedef typename DeprecatedInnerMap::iterator DeprecatedInnerIt; + + public: + iterator() : iterator_base(iterator_base::kUnknown) {} + explicit iterator(const DeprecatedInnerIt& dit) + : iterator_base(iterator_base::kOld), dit_(dit) {} + explicit iterator(const InnerIt& it) + : iterator_base(iterator_base::kNew), it_(it) {} + + reference operator*() const { + return this->OldStyle() ? *dit_->second : *it_->value(); + } + pointer operator->() const { return &(operator*()); } + + iterator& operator++() { + if (this->OldStyle()) + ++dit_; + else + ++it_; + return *this; + } + iterator operator++(int) { + return this->OldStyle() ? iterator(dit_++) : iterator(it_++); + } + + // Allow implicit conversion to const_iterator. + operator const_iterator() const { + return this->OldStyle() ? + const_iterator(typename DeprecatedInnerMap::const_iterator(dit_)) : + const_iterator(typename InnerMap::const_iterator(it_)); + } + + friend bool operator==(const iterator& a, const iterator& b) { + if (!a.SameStyle(b)) return false; + if (a.UnknownStyle()) return true; + return a.OldStyle() ? a.dit_ == b.dit_ : a.it_ == b.it_; + } + friend bool operator!=(const iterator& a, const iterator& b) { + return !(a == b); + } + + private: + friend class Map; + + InnerIt it_; + DeprecatedInnerIt dit_; + }; + + iterator begin() { + return old_style_ ? iterator(deprecated_elements_->begin()) + : iterator(elements_->begin()); + } + iterator end() { + return old_style_ ? iterator(deprecated_elements_->end()) + : iterator(elements_->end()); + } + const_iterator begin() const { + return old_style_ ? const_iterator(deprecated_elements_->begin()) + : const_iterator(iterator(elements_->begin())); + } + const_iterator end() const { + return old_style_ ? const_iterator(deprecated_elements_->end()) + : const_iterator(iterator(elements_->end())); + } + const_iterator cbegin() const { return begin(); } + const_iterator cend() const { return end(); } + + // Capacity + size_type size() const { + return old_style_ ? deprecated_elements_->size() : elements_->size(); + } + bool empty() const { return size() == 0; } + + // Element access + T& operator[](const key_type& key) { + value_type** value = + old_style_ ? &(*deprecated_elements_)[key] : &(*elements_)[key]; + if (*value == NULL) { + *value = CreateValueTypeInternal(key); + internal::MapValueInitializer::value, + T>::Initialize((*value)->second, + default_enum_value_); + } + return (*value)->second; + } + const T& at(const key_type& key) const { + const_iterator it = find(key); + GOOGLE_CHECK(it != end()); + return it->second; + } + T& at(const key_type& key) { + iterator it = find(key); + GOOGLE_CHECK(it != end()); + return it->second; + } + + // Lookup + size_type count(const key_type& key) const { + if (find(key) != end()) assert(key == find(key)->first); + return find(key) == end() ? 0 : 1; + } + const_iterator find(const key_type& key) const { + return old_style_ ? const_iterator(deprecated_elements_->find(key)) + : const_iterator(iterator(elements_->find(key))); + } + iterator find(const key_type& key) { + return old_style_ ? iterator(deprecated_elements_->find(key)) + : iterator(elements_->find(key)); + } + std::pair equal_range( + const key_type& key) const { + const_iterator it = find(key); + if (it == end()) { + return std::pair(it, it); + } else { + const_iterator begin = it++; + return std::pair(begin, it); + } + } + std::pair equal_range(const key_type& key) { + iterator it = find(key); + if (it == end()) { + return std::pair(it, it); + } else { + iterator begin = it++; + return std::pair(begin, it); + } + } + + // insert + std::pair insert(const value_type& value) { + if (old_style_) { + iterator it = find(value.first); + if (it != end()) { + return std::pair(it, false); + } else { + return std::pair( + iterator(deprecated_elements_->insert(std::pair( + value.first, CreateValueTypeInternal(value))).first), true); + } + } else { + std::pair p = + elements_->insert(value.first); + if (p.second) { + p.first->value() = CreateValueTypeInternal(value); + } + return std::pair(iterator(p.first), p.second); + } + } + template + void insert(InputIt first, InputIt last) { + for (InputIt it = first; it != last; ++it) { + iterator exist_it = find(it->first); + if (exist_it == end()) { + operator[](it->first) = it->second; + } + } + } + + // Erase and clear + size_type erase(const key_type& key) { + iterator it = find(key); + if (it == end()) { + return 0; + } else { + erase(it); + return 1; + } + } + iterator erase(iterator pos) { + if (arena_ == NULL) delete pos.operator->(); + iterator i = pos++; + if (old_style_) + deprecated_elements_->erase(i.dit_); + else + elements_->erase(i.it_); + return pos; + } + void erase(iterator first, iterator last) { + while (first != last) { + first = erase(first); + } + } + void clear() { erase(begin(), end()); } + + // Assign + Map& operator=(const Map& other) { + if (this != &other) { + clear(); + insert(other.begin(), other.end()); + } + return *this; + } + + void swap(Map& other) { + if (arena_ == other.arena_ && old_style_ == other.old_style_) { + std::swap(default_enum_value_, other.default_enum_value_); + if (old_style_) { + std::swap(deprecated_elements_, other.deprecated_elements_); + } else { + std::swap(elements_, other.elements_); + } + } else { + // TODO(zuguang): optimize this. The temporary copy can be allocated + // in the same arena as the other message, and the "other = copy" can + // be replaced with the fast-path swap above. + Map copy = *this; + *this = other; + other = copy; + } + } + + // Access to hasher. Currently this returns a copy, but it may + // be modified to return a const reference in the future. + hasher hash_function() const { + return old_style_ ? deprecated_elements_->hash_function() + : elements_->hash_function(); + } + + private: + // Set default enum value only for proto2 map field whose value is enum type. + void SetDefaultEnumValue(int default_enum_value) { + default_enum_value_ = default_enum_value; + } + + value_type* CreateValueTypeInternal(const Key& key) { + if (arena_ == NULL) { + return new value_type(key); + } else { + value_type* value = reinterpret_cast( + Arena::CreateArray(arena_, sizeof(value_type))); + Arena::CreateInArenaStorage(const_cast(&value->first), arena_); + Arena::CreateInArenaStorage(&value->second, arena_); + const_cast(value->first) = key; + return value; + } + } + + value_type* CreateValueTypeInternal(const value_type& value) { + if (arena_ == NULL) { + return new value_type(value); + } else { + value_type* p = reinterpret_cast( + Arena::CreateArray(arena_, sizeof(value_type))); + Arena::CreateInArenaStorage(const_cast(&p->first), arena_); + Arena::CreateInArenaStorage(&p->second, arena_); + const_cast(p->first) = value.first; + p->second = value.second; + return p; + } + } + + Arena* arena_; + int default_enum_value_; + // The following is a tagged union because we support two map styles + // for now. + // TODO(gpike): get rid of the old style. + const bool old_style_; + union { + InnerMap* elements_; + DeprecatedInnerMap* deprecated_elements_; + }; + + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + template + friend class internal::MapFieldLite; +}; + +} // namespace protobuf +} // namespace google + +GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START +template<> +struct hash { + size_t + operator()(const google::protobuf::MapKey& map_key) const { + switch (map_key.type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: + return hash()(map_key.GetStringValue()); + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: + return hash< ::google::protobuf::int64>()(map_key.GetInt64Value()); + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: + return hash< ::google::protobuf::int32>()(map_key.GetInt32Value()); + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: + return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value()); + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: + return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value()); + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: + return hash()(map_key.GetBoolValue()); + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; + } + bool + operator()(const google::protobuf::MapKey& map_key1, + const google::protobuf::MapKey& map_key2) const { + return map_key1 < map_key2; + } +}; +GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END + +#endif // GOOGLE_PROTOBUF_MAP_H__ diff --git a/thirdparty/linux/include/google/protobuf/map_entry.h b/thirdparty/linux/include/google/protobuf/map_entry.h new file mode 100644 index 0000000..e87eda6 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/map_entry.h @@ -0,0 +1,310 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_MAP_ENTRY_H__ +#define GOOGLE_PROTOBUF_MAP_ENTRY_H__ + +#include +#include +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { +class Arena; +namespace internal { +template +class MapField; +} +} + +namespace protobuf { +namespace internal { + +// Register all MapEntry default instances so we can delete them in +// ShutdownProtobufLibrary(). +void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance( + MessageLite* default_instance); + +// This is the common base class for MapEntry. It is used by MapFieldBase in +// reflection api, in which the static type of key and value is unknown. +class LIBPROTOBUF_EXPORT MapEntryBase : public Message { + public: + ::google::protobuf::Metadata GetMetadata() const { + ::google::protobuf::Metadata metadata; + metadata.descriptor = descriptor_; + metadata.reflection = reflection_; + return metadata; + } + + protected: + MapEntryBase() : descriptor_(NULL), reflection_(NULL) { } + virtual ~MapEntryBase() {} + + const Descriptor* descriptor_; + const Reflection* reflection_; +}; + +// MapEntry is the returned google::protobuf::Message when calling AddMessage of +// google::protobuf::Reflection. In order to let it work with generated message +// reflection, its in-memory type is the same as generated message with the same +// fields. However, in order to decide the in-memory type of key/value, we need +// to know both their cpp type in generated api and proto type. In +// implementation, all in-memory types have related wire format functions to +// support except ArenaStringPtr. Therefore, we need to define another type with +// supporting wire format functions. Since this type is only used as return type +// of MapEntry accessors, it's named MapEntry accessor type. +// +// cpp type: the type visible to users in public API. +// proto type: WireFormatLite::FieldType of the field. +// in-memory type: type of the data member used to stored this field. +// MapEntry accessor type: type used in MapEntry getters/mutators to access the +// field. +// +// cpp type | proto type | in-memory type | MapEntry accessor type +// int32 TYPE_INT32 int32 int32 +// int32 TYPE_FIXED32 int32 int32 +// string TYPE_STRING ArenaStringPtr string +// FooEnum TYPE_ENUM int int +// FooMessage TYPE_MESSAGE FooMessage* FooMessage +// +// The in-memory types of primitive types can be inferred from its proto type, +// while we need to explicitly specify the cpp type if proto type is +// TYPE_MESSAGE to infer the in-memory type. Moreover, default_enum_value is +// used to initialize enum field in proto2. +template +class MapEntry : public MapEntryBase { + // Provide utilities to parse/serialize key/value. Provide utilities to + // manipulate internal stored type. + typedef MapTypeHandler KeyTypeHandler; + typedef MapTypeHandler ValueTypeHandler; + + // Enum type cannot be used for MapTypeHandler::Read. Define a type + // which will replace Enum with int. + typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType; + typedef typename ValueTypeHandler::MapEntryAccessorType + ValueMapEntryAccessorType; + + // Abbreviation for MapEntry + typedef typename google::protobuf::internal::MapEntry< + Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> EntryType; + + // Abbreviation for MapEntryLite + typedef typename google::protobuf::internal::MapEntryLite< + Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> + EntryLiteType; + + public: + ~MapEntry() { + if (this == default_instance_) { + delete reflection_; + } + } + + // accessors ====================================================== + + virtual inline const KeyMapEntryAccessorType& key() const { + return entry_lite_.key(); + } + inline KeyMapEntryAccessorType* mutable_key() { + return entry_lite_.mutable_key(); + } + virtual inline const ValueMapEntryAccessorType& value() const { + return entry_lite_.value(); + } + inline ValueMapEntryAccessorType* mutable_value() { + return entry_lite_.mutable_value(); + } + + // implements Message ============================================= + + bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) { + return entry_lite_.MergePartialFromCodedStream(input); + } + + int ByteSize() const { + return entry_lite_.ByteSize(); + } + + void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const { + entry_lite_.SerializeWithCachedSizes(output); + } + + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic, + ::google::protobuf::uint8* output) const { + return entry_lite_.InternalSerializeWithCachedSizesToArray(deterministic, + output); + } + + int GetCachedSize() const { + return entry_lite_.GetCachedSize(); + } + + bool IsInitialized() const { + return entry_lite_.IsInitialized(); + } + + Message* New() const { + MapEntry* entry = new MapEntry; + entry->descriptor_ = descriptor_; + entry->reflection_ = reflection_; + entry->set_default_instance(default_instance_); + return entry; + } + + Message* New(Arena* arena) const { + MapEntry* entry = Arena::CreateMessage(arena); + entry->descriptor_ = descriptor_; + entry->reflection_ = reflection_; + entry->set_default_instance(default_instance_); + return entry; + } + + int SpaceUsed() const { + int size = sizeof(MapEntry); + size += entry_lite_.SpaceUsed(); + return size; + } + + void CopyFrom(const ::google::protobuf::Message& from) { + Clear(); + MergeFrom(from); + } + + void MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const MapEntry* source = dynamic_cast_if_available(&from); + if (source == NULL) { + ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } + } + + void CopyFrom(const MapEntry& from) { + Clear(); + MergeFrom(from); + } + + void MergeFrom(const MapEntry& from) { + entry_lite_.MergeFrom(from.entry_lite_); + } + + void Clear() { + entry_lite_.Clear(); + } + + void InitAsDefaultInstance() { + entry_lite_.InitAsDefaultInstance(); + } + + Arena* GetArena() const { + return entry_lite_.GetArena(); + } + + // Create default MapEntry instance for given descriptor. Descriptor has to be + // given when creating default MapEntry instance because different map field + // may have the same type and MapEntry class. The given descriptor is needed + // to distinguish instances of the same MapEntry class. + static MapEntry* CreateDefaultInstance(const Descriptor* descriptor) { + MapEntry* entry = new MapEntry; + const Reflection* reflection = new GeneratedMessageReflection( + descriptor, entry, offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _unknown_fields_), -1, + DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(MapEntry), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _internal_metadata_)); + entry->descriptor_ = descriptor; + entry->reflection_ = reflection; + entry->set_default_instance(entry); + entry->InitAsDefaultInstance(); + RegisterMapEntryDefaultInstance(entry); + return entry; + } + + private: + MapEntry() + : _internal_metadata_(NULL), default_instance_(NULL), entry_lite_() {} + + explicit MapEntry(Arena* arena) + : _internal_metadata_(arena), + default_instance_(NULL), + entry_lite_(arena) {} + + inline Arena* GetArenaNoVirtual() const { + return entry_lite_.GetArenaNoVirtual(); + } + + void set_default_instance(MapEntry* default_instance) { + default_instance_ = default_instance; + entry_lite_.set_default_instance(&default_instance->entry_lite_); + } + + static int offsets_[2]; + UnknownFieldSet _unknown_fields_; + InternalMetadataWithArena _internal_metadata_; + MapEntry* default_instance_; + EntryLiteType entry_lite_; + + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + template + friend class internal::MapField; + friend class internal::GeneratedMessageReflection; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry); +}; + +template +int MapEntry::offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.key_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.value_), +}; + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__ diff --git a/thirdparty/linux/include/google/protobuf/map_entry_lite.h b/thirdparty/linux/include/google/protobuf/map_entry_lite.h new file mode 100644 index 0000000..4dedfd5 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/map_entry_lite.h @@ -0,0 +1,568 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ +#define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +class Arena; +namespace internal { +template +class MapEntry; +template +class MapFieldLite; +} // namespace internal +} // namespace protobuf + +namespace protobuf { +namespace internal { + +// MoveHelper::Move is used to set *dest. It copies *src, or moves it (in +// the C++11 sense), or swaps it. *src is left in a sane state for +// subsequent destruction, but shouldn't be used for anything. +template +struct MoveHelper { // primitives + static void Move(T* src, T* dest) { *dest = *src; } +}; + +template +struct MoveHelper { // enums + static void Move(T* src, T* dest) { *dest = *src; } + // T is an enum here, so allow conversions to and from int. + static void Move(T* src, int* dest) { *dest = static_cast(*src); } + static void Move(int* src, T* dest) { *dest = static_cast(*src); } +}; + +template +struct MoveHelper { // messages + static void Move(T* src, T* dest) { dest->Swap(src); } +}; + +template +struct MoveHelper { // strings and similar + static void Move(T* src, T* dest) { +#if __cplusplus >= 201103L + *dest = std::move(*src); +#else + dest->swap(*src); +#endif + } +}; + +// MapEntryLite is used to implement parsing and serialization of map for lite +// runtime. +template +class MapEntryLite : public MessageLite { + // Provide utilities to parse/serialize key/value. Provide utilities to + // manipulate internal stored type. + typedef MapTypeHandler KeyTypeHandler; + typedef MapTypeHandler ValueTypeHandler; + + // Define internal memory layout. Strings and messages are stored as + // pointers, while other types are stored as values. + typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory; + typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory; + + // Enum type cannot be used for MapTypeHandler::Read. Define a type + // which will replace Enum with int. + typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType; + typedef typename ValueTypeHandler::MapEntryAccessorType + ValueMapEntryAccessorType; + + // Constants for field number. + static const int kKeyFieldNumber = 1; + static const int kValueFieldNumber = 2; + + // Constants for field tag. + static const uint8 kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( + kKeyFieldNumber, KeyTypeHandler::kWireType); + static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( + kValueFieldNumber, ValueTypeHandler::kWireType); + static const int kTagSize = 1; + + public: + ~MapEntryLite() { + if (this != default_instance_) { + if (GetArenaNoVirtual() != NULL) return; + KeyTypeHandler::DeleteNoArena(key_); + ValueTypeHandler::DeleteNoArena(value_); + } + } + + // accessors ====================================================== + + virtual inline const KeyMapEntryAccessorType& key() const { + return KeyTypeHandler::GetExternalReference(key_); + } + virtual inline const ValueMapEntryAccessorType& value() const { + GOOGLE_CHECK(default_instance_ != NULL); + return ValueTypeHandler::DefaultIfNotInitialized(value_, + default_instance_->value_); + } + inline KeyMapEntryAccessorType* mutable_key() { + set_has_key(); + return KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual()); + } + inline ValueMapEntryAccessorType* mutable_value() { + set_has_value(); + return ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual()); + } + + // implements MessageLite ========================================= + + // MapEntryLite is for implementation only and this function isn't called + // anywhere. Just provide a fake implementation here for MessageLite. + string GetTypeName() const { return ""; } + + void CheckTypeAndMergeFrom(const MessageLite& other) { + MergeFrom(*::google::protobuf::down_cast(&other)); + } + + bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) { + uint32 tag; + + for (;;) { + // 1) corrupted data: return false; + // 2) unknown field: skip without putting into unknown field set; + // 3) unknown enum value: keep it in parsing. In proto2, caller should + // check the value and put this entry into containing message's unknown + // field set if the value is an unknown enum. In proto3, caller doesn't + // need to care whether the value is unknown enum; + // 4) missing key/value: missed key/value will have default value. caller + // should take this entry as if key/value is set to default value. + tag = input->ReadTag(); + switch (tag) { + case kKeyTag: + if (!KeyTypeHandler::Read(input, mutable_key())) { + return false; + } + set_has_key(); + if (!input->ExpectTag(kValueTag)) break; + GOOGLE_FALLTHROUGH_INTENDED; + + case kValueTag: + if (!ValueTypeHandler::Read(input, mutable_value())) { + return false; + } + set_has_value(); + if (input->ExpectAtEnd()) return true; + break; + + default: + if (tag == 0 || + WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + if (!WireFormatLite::SkipField(input, tag)) return false; + break; + } + } + } + + int ByteSize() const { + int size = 0; + size += has_key() ? kTagSize + KeyTypeHandler::ByteSize(key()) : 0; + size += has_value() ? kTagSize + ValueTypeHandler::ByteSize(value()) : 0; + return size; + } + + void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const { + KeyTypeHandler::Write(kKeyFieldNumber, key(), output); + ValueTypeHandler::Write(kValueFieldNumber, value(), output); + } + + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic, + ::google::protobuf::uint8* output) const { + output = KeyTypeHandler::InternalWriteToArray(kKeyFieldNumber, key(), + deterministic, output); + output = ValueTypeHandler::InternalWriteToArray(kValueFieldNumber, value(), + deterministic, output); + return output; + } + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + + int GetCachedSize() const { + int size = 0; + size += has_key() + ? kTagSize + KeyTypeHandler::GetCachedSize(key()) + : 0; + size += has_value() + ? kTagSize + ValueTypeHandler::GetCachedSize( + value()) + : 0; + return size; + } + + bool IsInitialized() const { return ValueTypeHandler::IsInitialized(value_); } + + MessageLite* New() const { + MapEntryLite* entry = new MapEntryLite; + entry->default_instance_ = default_instance_; + return entry; + } + + MessageLite* New(Arena* arena) const { + MapEntryLite* entry = Arena::CreateMessage(arena); + entry->default_instance_ = default_instance_; + return entry; + } + + int SpaceUsed() const { + int size = sizeof(MapEntryLite); + size += KeyTypeHandler::SpaceUsedInMapEntry(key_); + size += ValueTypeHandler::SpaceUsedInMapEntry(value_); + return size; + } + + void MergeFrom(const MapEntryLite& from) { + if (from._has_bits_[0]) { + if (from.has_key()) { + KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual()); + KeyTypeHandler::Merge(from.key(), &key_, GetArenaNoVirtual()); + set_has_key(); + } + if (from.has_value()) { + ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual()); + ValueTypeHandler::Merge(from.value(), &value_, GetArenaNoVirtual()); + set_has_value(); + } + } + } + + void Clear() { + KeyTypeHandler::Clear(&key_, GetArenaNoVirtual()); + ValueTypeHandler::ClearMaybeByDefaultEnum( + &value_, GetArenaNoVirtual(), default_enum_value); + clear_has_key(); + clear_has_value(); + } + + void InitAsDefaultInstance() { + KeyTypeHandler::AssignDefaultValue(&key_); + ValueTypeHandler::AssignDefaultValue(&value_); + } + + Arena* GetArena() const { + return GetArenaNoVirtual(); + } + + // Create a MapEntryLite for given key and value from google::protobuf::Map in + // serialization. This function is only called when value is enum. Enum is + // treated differently because its type in MapEntry is int and its type in + // google::protobuf::Map is enum. We cannot create a reference to int from an enum. + static MapEntryLite* EnumWrap(const Key& key, const Value value, + Arena* arena) { + return Arena::CreateMessage >( + arena, key, value); + } + + // Like above, but for all the other types. This avoids value copy to create + // MapEntryLite from google::protobuf::Map in serialization. + static MapEntryLite* Wrap(const Key& key, const Value& value, Arena* arena) { + return Arena::CreateMessage >( + arena, key, value); + } + + // Parsing using MergePartialFromCodedStream, above, is not as + // efficient as it could be. This helper class provides a speedier way. + template + class Parser { + public: + explicit Parser(MapField* mf) : mf_(mf), map_(mf->MutableMap()) {} + + // This does what the typical MergePartialFromCodedStream() is expected to + // do, with the additional side-effect that if successful (i.e., if true is + // going to be its return value) it inserts the key-value pair into map_. + bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) { + // Look for the expected thing: a key and then a value. If it fails, + // invoke the enclosing class's MergePartialFromCodedStream, or return + // false if that would be pointless. + if (input->ExpectTag(kKeyTag)) { + if (!KeyTypeHandler::Read(input, &key_)) { + return false; + } + // Peek at the next byte to see if it is kValueTag. If not, bail out. + const void* data; + int size; + input->GetDirectBufferPointerInline(&data, &size); + // We could use memcmp here, but we don't bother. The tag is one byte. + assert(kTagSize == 1); + if (size > 0 && *reinterpret_cast(data) == kValueTag) { + typename Map::size_type size = map_->size(); + value_ptr_ = &(*map_)[key_]; + if (GOOGLE_PREDICT_TRUE(size != map_->size())) { + // We created a new key-value pair. Fill in the value. + typedef + typename MapIf::type T; + input->Skip(kTagSize); // Skip kValueTag. + if (!ValueTypeHandler::Read(input, + reinterpret_cast(value_ptr_))) { + map_->erase(key_); // Failure! Undo insertion. + return false; + } + if (input->ExpectAtEnd()) return true; + return ReadBeyondKeyValuePair(input); + } + } + } else { + key_ = Key(); + } + + entry_.reset(mf_->NewEntry()); + *entry_->mutable_key() = key_; + if (!entry_->MergePartialFromCodedStream(input)) return false; + return UseKeyAndValueFromEntry(); + } + + const Key& key() const { return key_; } + const Value& value() const { return *value_ptr_; } + + private: + bool UseKeyAndValueFromEntry() GOOGLE_ATTRIBUTE_COLD { + // Update key_ in case we need it later (because key() is called). + // This is potentially inefficient, especially if the key is + // expensive to copy (e.g., a long string), but this is a cold + // path, so it's not a big deal. + key_ = entry_->key(); + value_ptr_ = &(*map_)[key_]; + MoveHelper::Move(entry_->mutable_value(), value_ptr_); + if (entry_->GetArena() != NULL) entry_.release(); + return true; + } + + // After reading a key and value successfully, and inserting that data + // into map_, we are not at the end of the input. This is unusual, but + // allowed by the spec. + bool ReadBeyondKeyValuePair(::google::protobuf::io::CodedInputStream* input) + GOOGLE_ATTRIBUTE_COLD { + typedef MoveHelper KeyMover; + typedef MoveHelper ValueMover; + entry_.reset(mf_->NewEntry()); + ValueMover::Move(value_ptr_, entry_->mutable_value()); + map_->erase(key_); + KeyMover::Move(&key_, entry_->mutable_key()); + if (!entry_->MergePartialFromCodedStream(input)) return false; + return UseKeyAndValueFromEntry(); + } + + MapField* const mf_; + Map* const map_; + Key key_; + Value* value_ptr_; + // On the fast path entry_ is not used. + google::protobuf::scoped_ptr entry_; + }; + + protected: + void set_has_key() { _has_bits_[0] |= 0x00000001u; } + bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; } + void clear_has_key() { _has_bits_[0] &= ~0x00000001u; } + void set_has_value() { _has_bits_[0] |= 0x00000002u; } + bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; } + void clear_has_value() { _has_bits_[0] &= ~0x00000002u; } + + private: + // Serializing a generated message containing map field involves serializing + // key-value pairs from google::protobuf::Map. The wire format of each key-value pair + // after serialization should be the same as that of a MapEntry message + // containing the same key and value inside it. However, google::protobuf::Map doesn't + // store key and value as MapEntry message, which disables us to use existing + // code to serialize message. In order to use existing code to serialize + // message, we need to construct a MapEntry from key-value pair. But it + // involves copy of key and value to construct a MapEntry. In order to avoid + // this copy in constructing a MapEntry, we need the following class which + // only takes references of given key and value. + template + class MapEntryWrapper + : public MapEntryLite { + typedef MapEntryLite Base; + typedef typename Base::KeyMapEntryAccessorType KeyMapEntryAccessorType; + typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType; + + public: + MapEntryWrapper(Arena* arena, const K& key, const V& value) + : MapEntryLite(arena), + key_(key), + value_(value) { + Base::set_has_key(); + Base::set_has_value(); + } + inline const KeyMapEntryAccessorType& key() const { return key_; } + inline const ValueMapEntryAccessorType& value() const { return value_; } + + private: + const Key& key_; + const Value& value_; + + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + }; + + // Like above, but for enum value only, which stores value instead of + // reference of value field inside. This is needed because the type of value + // field in constructor is an enum, while we need to store it as an int. If we + // initialize a reference to int with a reference to enum, compiler will + // generate a temporary int from enum and initialize the reference to int with + // the temporary. + template + class MapEnumEntryWrapper + : public MapEntryLite { + typedef MapEntryLite Base; + typedef typename Base::KeyMapEntryAccessorType KeyMapEntryAccessorType; + typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType; + + public: + MapEnumEntryWrapper(Arena* arena, const K& key, const V& value) + : MapEntryLite(arena), + key_(key), + value_(value) { + Base::set_has_key(); + Base::set_has_value(); + } + inline const KeyMapEntryAccessorType& key() const { return key_; } + inline const ValueMapEntryAccessorType& value() const { return value_; } + + private: + const KeyMapEntryAccessorType& key_; + const ValueMapEntryAccessorType value_; + + friend class google::protobuf::Arena; + typedef void DestructorSkippable_; + }; + + MapEntryLite() : default_instance_(NULL), arena_(NULL) { + KeyTypeHandler::Initialize(&key_, NULL); + ValueTypeHandler::InitializeMaybeByDefaultEnum( + &value_, default_enum_value, NULL); + _has_bits_[0] = 0; + } + + explicit MapEntryLite(Arena* arena) + : default_instance_(NULL), arena_(arena) { + KeyTypeHandler::Initialize(&key_, arena); + ValueTypeHandler::InitializeMaybeByDefaultEnum( + &value_, default_enum_value, arena); + _has_bits_[0] = 0; + } + + inline Arena* GetArenaNoVirtual() const { + return arena_; + } + + void set_default_instance(MapEntryLite* default_instance) { + default_instance_ = default_instance; + } + + MapEntryLite* default_instance_; + + KeyOnMemory key_; + ValueOnMemory value_; + Arena* arena_; + uint32 _has_bits_[1]; + + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + template + friend class internal::MapEntry; + template + friend class internal::MapFieldLite; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite); +}; + +// Helpers for deterministic serialization ============================= + +// This struct can be used with any generic sorting algorithm. If the Key +// type is relatively small and easy to copy then copying Keys into an +// array of SortItems can be beneficial. Then all the data the sorting +// algorithm needs to touch is in that one array. +template struct SortItem { + SortItem() {} + explicit SortItem(PtrToKeyValuePair p) : first(p->first), second(p) {} + + Key first; + PtrToKeyValuePair second; +}; + +template struct CompareByFirstField { + bool operator()(const T& a, const T& b) const { + return a.first < b.first; + } +}; + +template struct CompareByDerefFirst { + bool operator()(const T& a, const T& b) const { + return a->first < b->first; + } +}; + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ diff --git a/thirdparty/linux/include/google/protobuf/map_field.h b/thirdparty/linux/include/google/protobuf/map_field.h new file mode 100644 index 0000000..d6af853 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/map_field.h @@ -0,0 +1,397 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_MAP_FIELD_H__ +#define GOOGLE_PROTOBUF_MAP_FIELD_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +class DynamicMessage; +class MapKey; +namespace internal { + +class ContendedMapCleanTest; +class GeneratedMessageReflection; +class MapFieldAccessor; + +// This class provides access to map field using reflection, which is the same +// as those provided for RepeatedPtrField. It is used for internal +// reflection implentation only. Users should never use this directly. +class LIBPROTOBUF_EXPORT MapFieldBase { + public: + MapFieldBase() + : arena_(NULL), + repeated_field_(NULL), + entry_descriptor_(NULL), + assign_descriptor_callback_(NULL), + state_(STATE_MODIFIED_MAP) {} + explicit MapFieldBase(Arena* arena) + : arena_(arena), + repeated_field_(NULL), + entry_descriptor_(NULL), + assign_descriptor_callback_(NULL), + state_(STATE_MODIFIED_MAP) { + // Mutex's destructor needs to be called explicitly to release resources + // acquired in its constructor. + arena->OwnDestructor(&mutex_); + } + virtual ~MapFieldBase(); + + // Returns reference to internal repeated field. Data written using + // google::protobuf::Map's api prior to calling this function is guarantted to be + // included in repeated field. + const RepeatedPtrFieldBase& GetRepeatedField() const; + + // Like above. Returns mutable pointer to the internal repeated field. + RepeatedPtrFieldBase* MutableRepeatedField(); + + // Pure virtual map APIs for Map Reflection. + virtual bool ContainsMapKey(const MapKey& map_key) const = 0; + virtual bool InsertOrLookupMapValue( + const MapKey& map_key, MapValueRef* val) = 0; + virtual bool DeleteMapValue(const MapKey& map_key) = 0; + virtual bool EqualIterator(const MapIterator& a, + const MapIterator& b) const = 0; + virtual void MapBegin(MapIterator* map_iter) const = 0; + virtual void MapEnd(MapIterator* map_iter) const = 0; + // Sync Map with repeated field and returns the size of map. + virtual int size() const = 0; + + // Returns the number of bytes used by the repeated field, excluding + // sizeof(*this) + int SpaceUsedExcludingSelf() const; + + protected: + // Gets the size of space used by map field. + virtual int SpaceUsedExcludingSelfNoLock() const; + + // Synchronizes the content in Map to RepeatedPtrField if there is any change + // to Map after last synchronization. + void SyncRepeatedFieldWithMap() const; + virtual void SyncRepeatedFieldWithMapNoLock() const; + + // Synchronizes the content in RepeatedPtrField to Map if there is any change + // to RepeatedPtrField after last synchronization. + void SyncMapWithRepeatedField() const; + virtual void SyncMapWithRepeatedFieldNoLock() const {} + + // Tells MapFieldBase that there is new change to Map. + void SetMapDirty(); + + // Tells MapFieldBase that there is new change to RepeatedPTrField. + void SetRepeatedDirty(); + + // Provides derived class the access to repeated field. + void* MutableRepeatedPtrField() const; + + // Creates descriptor for only one time. + void InitMetadataOnce() const; + + enum State { + STATE_MODIFIED_MAP = 0, // map has newly added data that has not been + // synchronized to repeated field + STATE_MODIFIED_REPEATED = 1, // repeated field has newly added data that + // has not been synchronized to map + CLEAN = 2, // data in map and repeated field are same + }; + + Arena* arena_; + mutable RepeatedPtrField* repeated_field_; + // MapEntry can only be created from MapField. To create MapEntry, MapField + // needs to know its descriptor, because MapEntry is not generated class which + // cannot initialize its own descriptor by calling generated + // descriptor-assign-function. Thus, we need to register a callback to + // initialize MapEntry's descriptor. + const Descriptor** entry_descriptor_; + void (*assign_descriptor_callback_)(); + + mutable Mutex mutex_; // The thread to synchronize map and repeated field + // needs to get lock first; + mutable volatile Atomic32 state_; // 0: STATE_MODIFIED_MAP + // 1: STATE_MODIFIED_REPEATED + // 2: CLEAN + + private: + friend class ContendedMapCleanTest; + friend class GeneratedMessageReflection; + friend class MapFieldAccessor; + friend class ::google::protobuf::DynamicMessage; + + // Virtual helper methods for MapIterator. MapIterator doesn't have the + // type helper for key and value. Call these help methods to deal with + // different types. Real helper methods are implemented in + // TypeDefinedMapFieldBase. + friend class ::google::protobuf::MapIterator; + // Allocate map<...>::iterator for MapIterator. + virtual void InitializeIterator(MapIterator* map_iter) const = 0; + + // DeleteIterator() is called by the destructor of MapIterator only. + // It deletes map<...>::iterator for MapIterator. + virtual void DeleteIterator(MapIterator* map_iter) const = 0; + + // Copy the map<...>::iterator from other_iterator to + // this_iterator. + virtual void CopyIterator(MapIterator* this_iterator, + const MapIterator& other_iterator) const = 0; + + // IncreaseIterator() is called by operator++() of MapIterator only. + // It implements the ++ operator of MapIterator. + virtual void IncreaseIterator(MapIterator* map_iter) const = 0; +}; + +// This class provides common Map Reflection implementations for generated +// message and dynamic message. +template +class TypeDefinedMapFieldBase : public MapFieldBase { + public: + TypeDefinedMapFieldBase() {} + explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {} + ~TypeDefinedMapFieldBase() {} + void MapBegin(MapIterator* map_iter) const; + void MapEnd(MapIterator* map_iter) const; + bool EqualIterator(const MapIterator& a, const MapIterator& b) const; + + virtual const Map& GetMap() const = 0; + virtual Map* MutableMap() = 0; + + protected: + typename Map::const_iterator& InternalGetIterator( + const MapIterator* map_iter) const; + + private: + void InitializeIterator(MapIterator* map_iter) const; + void DeleteIterator(MapIterator* map_iter) const; + void CopyIterator(MapIterator* this_iteratorm, + const MapIterator& that_iterator) const; + void IncreaseIterator(MapIterator* map_iter) const; + + virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0; +}; + +// This class provides access to map field using generated api. It is used for +// internal generated message implentation only. Users should never use this +// directly. +template +class MapField : public TypeDefinedMapFieldBase, + public MapFieldLite { + // Provide utilities to parse/serialize key/value. Provide utilities to + // manipulate internal stored type. + typedef MapTypeHandler KeyTypeHandler; + typedef MapTypeHandler ValueTypeHandler; + + // Define message type for internal repeated field. + typedef MapEntry + EntryType; + typedef MapEntryLite EntryLiteType; + + // Define abbreviation for parent MapFieldLite + typedef MapFieldLite MapFieldLiteType; + + // Enum needs to be handled differently from other types because it has + // different exposed type in google::protobuf::Map's api and repeated field's api. For + // details see the comment in the implementation of + // SyncMapWithRepeatedFieldNoLock. + static const bool kIsValueEnum = ValueTypeHandler::kIsEnum; + typedef typename MapIf::type CastValueType; + + public: + MapField(); + explicit MapField(Arena* arena); + // MapField doesn't own the default_entry, which means default_entry must + // outlive the lifetime of MapField. + MapField(const Message* default_entry); + // For tests only. + MapField(Arena* arena, const Message* default_entry); + ~MapField(); + + // Implement MapFieldBase + bool ContainsMapKey(const MapKey& map_key) const; + bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val); + bool DeleteMapValue(const MapKey& map_key); + + // Accessors + const Map& GetMap() const; + Map* MutableMap(); + + // Convenient methods for generated message implementation. + int size() const; + void Clear(); + void MergeFrom(const MapFieldLiteType& other); + void Swap(MapFieldLiteType* other); + + // Allocates metadata only if this MapField is part of a generated message. + void SetEntryDescriptor(const Descriptor** descriptor); + void SetAssignDescriptorCallback(void (*callback)()); + + private: + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + + // MapField needs MapEntry's default instance to create new MapEntry. + void InitDefaultEntryOnce() const; + + // Manually set default entry instance. For test only. + void SetDefaultEntryOnce(const EntryType* default_entry) const; + + // Convenient methods to get internal google::protobuf::Map + const Map& GetInternalMap() const; + Map* MutableInternalMap(); + + // Implements MapFieldBase + void SyncRepeatedFieldWithMapNoLock() const; + void SyncMapWithRepeatedFieldNoLock() const; + int SpaceUsedExcludingSelfNoLock() const; + + void SetMapIteratorValue(MapIterator* map_iter) const; + + mutable const EntryType* default_entry_; + + friend class ::google::protobuf::Arena; +}; + +class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase { + public: + explicit DynamicMapField(const Message* default_entry); + DynamicMapField(const Message* default_entry, Arena* arena); + ~DynamicMapField(); + + // Implement MapFieldBase + bool ContainsMapKey(const MapKey& map_key) const; + bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val); + bool DeleteMapValue(const MapKey& map_key); + + const Map& GetMap() const; + Map* MutableMap(); + + int size() const; + + private: + Map map_; + const Message* default_entry_; + + // Implements MapFieldBase + void SyncRepeatedFieldWithMapNoLock() const; + void SyncMapWithRepeatedFieldNoLock() const; + int SpaceUsedExcludingSelfNoLock() const; + void SetMapIteratorValue(MapIterator* map_iter) const; +}; + +} // namespace internal + +class LIBPROTOBUF_EXPORT MapIterator { + public: + MapIterator(Message* message, const FieldDescriptor* field) { + const Reflection* reflection = message->GetReflection(); + map_ = reflection->MapData(message, field); + key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type()); + value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type()); + map_->InitializeIterator(this); + } + MapIterator(const MapIterator& other) { + map_ = other.map_; + map_->InitializeIterator(this); + map_->CopyIterator(this, other); + } + ~MapIterator() { + map_->DeleteIterator(this); + } + friend bool operator==(const MapIterator& a, const MapIterator& b) { + return a.map_->EqualIterator(a, b); + } + friend bool operator!=(const MapIterator& a, const MapIterator& b) { + return !a.map_->EqualIterator(a, b); + } + MapIterator& operator++() { + map_->IncreaseIterator(this); + return *this; + } + MapIterator operator++(int) { + // iter_ is copied from Map<...>::iterator, no need to + // copy from its self again. Use the same implementation + // with operator++() + map_->IncreaseIterator(this); + return *this; + } + const MapKey& GetKey() { + return key_; + } + const MapValueRef& GetValueRef() { + return value_; + } + MapValueRef* MutableValueRef() { + map_->SetMapDirty(); + return &value_; + } + + private: + template + friend class internal::TypeDefinedMapFieldBase; + friend class internal::DynamicMapField; + template + friend class internal::MapField; + + // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns + // the iterator. It is allocated by MapField<...>::InitializeIterator() called + // in constructor and deleted by MapField<...>::DeleteIterator() called in + // destructor. + void* iter_; + // Point to a MapField to call helper methods implemented in MapField. + // MapIterator does not own this object. + internal::MapFieldBase* map_; + MapKey key_; + MapValueRef value_; +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MAP_FIELD_H__ diff --git a/thirdparty/linux/include/google/protobuf/map_field_inl.h b/thirdparty/linux/include/google/protobuf/map_field_inl.h new file mode 100644 index 0000000..01c9b89 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/map_field_inl.h @@ -0,0 +1,489 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_MAP_FIELD_INL_H__ +#define GOOGLE_PROTOBUF_MAP_FIELD_INL_H__ + +#include +#ifndef _SHARED_PTR_H +#include +#endif + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { +// UnwrapMapKey template +template +T UnwrapMapKey(const MapKey& map_key); +template<> +inline int32 UnwrapMapKey(const MapKey& map_key) { + return map_key.GetInt32Value(); +} +template<> +inline uint32 UnwrapMapKey(const MapKey& map_key) { + return map_key.GetUInt32Value(); +} +template<> +inline int64 UnwrapMapKey(const MapKey& map_key) { + return map_key.GetInt64Value(); +} +template<> +inline uint64 UnwrapMapKey(const MapKey& map_key) { + return map_key.GetUInt64Value(); +} +template<> +inline bool UnwrapMapKey(const MapKey& map_key) { + return map_key.GetBoolValue(); +} +template<> +inline string UnwrapMapKey(const MapKey& map_key) { + return map_key.GetStringValue(); +} + +// SetMapKey template +template +inline void SetMapKey(MapKey* map_key, const T& value); +template<> +inline void SetMapKey(MapKey* map_key, const int32& value) { + map_key->SetInt32Value(value); +} +template<> +inline void SetMapKey(MapKey* map_key, const uint32& value) { + map_key->SetUInt32Value(value); +} +template<> +inline void SetMapKey(MapKey* map_key, const int64& value) { + map_key->SetInt64Value(value); +} +template<> +inline void SetMapKey(MapKey* map_key, const uint64& value) { + map_key->SetUInt64Value(value); +} +template<> +inline void SetMapKey(MapKey* map_key, const bool& value) { + map_key->SetBoolValue(value); +} +template<> +inline void SetMapKey(MapKey* map_key, const string& value) { + map_key->SetStringValue(value); +} + +// ------------------------TypeDefinedMapFieldBase--------------- +template +typename Map::const_iterator& +TypeDefinedMapFieldBase::InternalGetIterator( + const MapIterator* map_iter) const { + return *reinterpret_cast::const_iterator *>( + map_iter->iter_); +} + +template +void TypeDefinedMapFieldBase::MapBegin(MapIterator* map_iter) const { + InternalGetIterator(map_iter) = GetMap().begin(); + SetMapIteratorValue(map_iter); +} + +template +void TypeDefinedMapFieldBase::MapEnd(MapIterator* map_iter) const { + InternalGetIterator(map_iter) = GetMap().end(); +} + +template +bool TypeDefinedMapFieldBase::EqualIterator(const MapIterator& a, + const MapIterator& b) + const { + return InternalGetIterator(&a) == InternalGetIterator(&b); +} + +template +void TypeDefinedMapFieldBase::IncreaseIterator(MapIterator* map_iter) + const { + ++InternalGetIterator(map_iter); + SetMapIteratorValue(map_iter); +} + +template +void TypeDefinedMapFieldBase::InitializeIterator( + MapIterator* map_iter) const { + map_iter->iter_ = new typename Map::const_iterator; + GOOGLE_CHECK(map_iter->iter_ != NULL); +} + +template +void TypeDefinedMapFieldBase::DeleteIterator(MapIterator* map_iter) + const { + delete reinterpret_cast::const_iterator *>( + map_iter->iter_); +} + +template +void TypeDefinedMapFieldBase::CopyIterator( + MapIterator* this_iter, + const MapIterator& that_iter) const { + InternalGetIterator(this_iter) = InternalGetIterator(&that_iter); + this_iter->key_.SetType(that_iter.key_.type()); + // MapValueRef::type() fails when containing data is null. However, if + // this_iter points to MapEnd, data can be null. + this_iter->value_.SetType( + static_cast(that_iter.value_.type_)); + SetMapIteratorValue(this_iter); +} + +// ---------------------------------------------------------------------- + +template +MapField::MapField() + : default_entry_(NULL) {} + +template +MapField::MapField( + Arena* arena) + : TypeDefinedMapFieldBase(arena), + MapFieldLite( + arena), + default_entry_(NULL) {} + +template +MapField::MapField( + const Message* default_entry) + : default_entry_(down_cast(default_entry)) {} + +template +MapField::MapField( + Arena* arena, const Message* default_entry) + : TypeDefinedMapFieldBase(arena), + MapFieldLite( + arena), + default_entry_(down_cast(default_entry)) {} + +template +MapField::~MapField() {} + +template +int +MapField::size() const { + MapFieldBase::SyncMapWithRepeatedField(); + return MapFieldLiteType::GetInternalMap().size(); +} + +template +void +MapField::Clear() { + MapFieldBase::SyncMapWithRepeatedField(); + MapFieldLiteType::MutableInternalMap()->clear(); + MapFieldBase::SetMapDirty(); +} + +template +void MapField::SetMapIteratorValue( + MapIterator* map_iter) const { + const Map& map = GetMap(); + typename Map::const_iterator iter = + TypeDefinedMapFieldBase::InternalGetIterator(map_iter); + if (iter == map.end()) return; + SetMapKey(&map_iter->key_, iter->first); + map_iter->value_.SetValue(&iter->second); +} + +template +bool MapField::ContainsMapKey( + const MapKey& map_key) const { + const Map& map = GetMap(); + const Key& key = UnwrapMapKey(map_key); + typename Map::const_iterator iter = map.find(key); + return iter != map.end(); +} + +template +bool MapField::InsertOrLookupMapValue( + const MapKey& map_key, + MapValueRef* val) { + // Always use mutable map because users may change the map value by + // MapValueRef. + Map* map = MutableMap(); + const Key& key = UnwrapMapKey(map_key); + typename Map::iterator iter = map->find(key); + if (map->end() == iter) { + val->SetValue(&((*map)[key])); + return true; + } + // Key is already in the map. Make sure (*map)[key] is not called. + // [] may reorder the map and iterators. + val->SetValue(&(iter->second)); + return false; +} + +template +bool MapField::DeleteMapValue( + const MapKey& map_key) { + const Key& key = UnwrapMapKey(map_key); + return MutableMap()->erase(key); +} + +template +const Map& +MapField::GetMap() const { + MapFieldBase::SyncMapWithRepeatedField(); + return MapFieldLiteType::GetInternalMap(); +} + +template +Map* +MapField::MutableMap() { + MapFieldBase::SyncMapWithRepeatedField(); + Map* result = MapFieldLiteType::MutableInternalMap(); + MapFieldBase::SetMapDirty(); + return result; +} + +template +void +MapField::MergeFrom( + const MapFieldLiteType& other) { + const MapField& down_other = down_cast(other); + MapFieldBase::SyncMapWithRepeatedField(); + down_other.SyncMapWithRepeatedField(); + MapFieldLiteType::MergeFrom(other); + MapFieldBase::SetMapDirty(); +} + +template +void +MapField::Swap( + MapFieldLiteType* other) { + MapField* down_other = down_cast(other); + std::swap(MapFieldBase::repeated_field_, down_other->repeated_field_); + MapFieldLiteType::Swap(other); + std::swap(MapFieldBase::state_, down_other->state_); +} + +template +void +MapField::SetEntryDescriptor( + const Descriptor** descriptor) { + MapFieldBase::entry_descriptor_ = descriptor; +} + +template +void +MapField::SetAssignDescriptorCallback(void (*callback)()) { + MapFieldBase::assign_descriptor_callback_ = callback; +} + +template +const Map& +MapField::GetInternalMap() const { + return MapFieldLiteType::GetInternalMap(); +} + +template +Map* +MapField::MutableInternalMap() { + return MapFieldLiteType::MutableInternalMap(); +} + +template +void +MapField::SyncRepeatedFieldWithMapNoLock() const { + if (MapFieldBase::repeated_field_ == NULL) { + if (MapFieldBase::arena_ == NULL) { + MapFieldBase::repeated_field_ = new RepeatedPtrField(); + } else { + MapFieldBase::repeated_field_ = + Arena::CreateMessage >( + MapFieldBase::arena_); + } + } + const Map& map = GetInternalMap(); + RepeatedPtrField* repeated_field = + reinterpret_cast*>( + MapFieldBase::repeated_field_); + + repeated_field->Clear(); + + for (typename Map::const_iterator it = map.begin(); + it != map.end(); ++it) { + InitDefaultEntryOnce(); + GOOGLE_CHECK(default_entry_ != NULL); + EntryType* new_entry = + down_cast(default_entry_->New(MapFieldBase::arena_)); + repeated_field->AddAllocated(new_entry); + (*new_entry->mutable_key()) = it->first; + (*new_entry->mutable_value()) = it->second; + } +} + +template +void +MapField::SyncMapWithRepeatedFieldNoLock() const { + Map* map = const_cast(this)->MutableInternalMap(); + RepeatedPtrField* repeated_field = + reinterpret_cast*>( + MapFieldBase::repeated_field_); + GOOGLE_CHECK(MapFieldBase::repeated_field_ != NULL); + map->clear(); + for (typename RepeatedPtrField::iterator it = + repeated_field->begin(); it != repeated_field->end(); ++it) { + // Cast is needed because Map's api and internal storage is different when + // value is enum. For enum, we cannot cast an int to enum. Thus, we have to + // copy value. For other types, they have same exposed api type and internal + // stored type. We should not introduce value copy for them. We achieve this + // by casting to value for enum while casting to reference for other types. + (*map)[it->key()] = static_cast(it->value()); + } +} + +template +int +MapField::SpaceUsedExcludingSelfNoLock() const { + int size = 0; + if (MapFieldBase::repeated_field_ != NULL) { + size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelf(); + } + Map* map = const_cast(this)->MutableInternalMap(); + size += sizeof(*map); + for (typename Map::iterator it = map->begin(); + it != map->end(); ++it) { + size += KeyTypeHandler::SpaceUsedInMap(it->first); + size += ValueTypeHandler::SpaceUsedInMap(it->second); + } + return size; +} + +template +void +MapField::InitDefaultEntryOnce() + const { + if (default_entry_ == NULL) { + MapFieldBase::InitMetadataOnce(); + GOOGLE_CHECK(*MapFieldBase::entry_descriptor_ != NULL); + default_entry_ = down_cast( + MessageFactory::generated_factory()->GetPrototype( + *MapFieldBase::entry_descriptor_)); + } +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MAP_FIELD_INL_H__ diff --git a/thirdparty/linux/include/google/protobuf/map_field_lite.h b/thirdparty/linux/include/google/protobuf/map_field_lite.h new file mode 100644 index 0000000..a9f30f5 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/map_field_lite.h @@ -0,0 +1,278 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +// This class provides access to map field using generated api. It is used for +// internal generated message implentation only. Users should never use this +// directly. +template +class MapFieldLite { + // Define message type for internal repeated field. + typedef MapEntryLite EntryType; + + public: + MapFieldLite(); + explicit MapFieldLite(Arena* arena); + virtual ~MapFieldLite(); + + // Accessors + virtual const Map& GetMap() const; + virtual Map* MutableMap(); + + // Convenient methods for generated message implementation. + virtual int size() const; + virtual void Clear(); + virtual void MergeFrom(const MapFieldLite& other); + virtual void Swap(MapFieldLite* other); + + // Set default enum value only for proto2 map field whose value is enum type. + void SetDefaultEnumValue(); + + // Used in the implementation of parsing. Caller should take the ownership. + EntryType* NewEntry() const; + // Used in the implementation of serializing enum value type. Caller should + // take the ownership. + EntryType* NewEnumEntryWrapper(const Key& key, const T t) const; + // Used in the implementation of serializing other value types. Caller should + // take the ownership. + EntryType* NewEntryWrapper(const Key& key, const T& t) const; + + protected: + // Convenient methods to get internal google::protobuf::Map + virtual const Map& GetInternalMap() const; + virtual Map* MutableInternalMap(); + + private: + typedef void DestructorSkippable_; + + Arena* arena_; + Map* map_; + + friend class ::google::protobuf::Arena; +}; + +template +MapFieldLite::MapFieldLite() + : arena_(NULL) { + map_ = new Map; + SetDefaultEnumValue(); +} + +template +MapFieldLite::MapFieldLite(Arena* arena) + : arena_(arena) { + map_ = Arena::CreateMessage >(arena); + SetDefaultEnumValue(); +} + +template +MapFieldLite::~MapFieldLite() { + delete map_; +} + +template +const Map& +MapFieldLite::GetMap() const { + return *map_; +} + +template +Map* +MapFieldLite::MutableMap() { + return map_; +} + +template +int +MapFieldLite::size() const { + return map_->size(); +} + +template +void +MapFieldLite::Clear() { + map_->clear(); +} + +template +void +MapFieldLite::MergeFrom( + const MapFieldLite& other) { + for (typename Map::const_iterator it = other.map_->begin(); + it != other.map_->end(); ++it) { + (*map_)[it->first] = it->second; + } +} + +template +void +MapFieldLite::Swap( + MapFieldLite* other) { + std::swap(map_, other->map_); +} + +template +void +MapFieldLite::SetDefaultEnumValue() { + MutableInternalMap()->SetDefaultEnumValue(default_enum_value); +} + +template +const Map& +MapFieldLite::GetInternalMap() const { + return *map_; +} + +template +Map* +MapFieldLite::MutableInternalMap() { + return map_; +} + +#define EntryType \ + MapEntryLite + +template +EntryType* +MapFieldLite::NewEntry() const { + if (arena_ == NULL) { + return new EntryType(); + } else { + return Arena::CreateMessage(arena_); + } +} + +template +EntryType* +MapFieldLite::NewEnumEntryWrapper(const Key& key, + const T t) const { + return EntryType::EnumWrap(key, t, arena_); +} + +template +EntryType* +MapFieldLite::NewEntryWrapper(const Key& key, + const T& t) const { + return EntryType::Wrap(key, t, arena_); +} + +#undef EntryType + +// True if IsInitialized() is true for value field in all elements of t. T is +// expected to be message. It's useful to have this helper here to keep the +// protobuf compiler from ever having to emit loops in IsInitialized() methods. +// We want the C++ compiler to inline this or not as it sees fit. +template +bool AllAreInitialized(const Map& t) { + for (typename Map::const_iterator it = t.begin(); it != t.end(); + ++it) { + if (!it->second.IsInitialized()) return false; + } + return true; +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__ diff --git a/thirdparty/linux/include/google/protobuf/map_type_handler.h b/thirdparty/linux/include/google/protobuf/map_type_handler.h new file mode 100644 index 0000000..685a770 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/map_type_handler.h @@ -0,0 +1,743 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_TYPE_HANDLER_H__ +#define GOOGLE_PROTOBUF_TYPE_HANDLER_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +// Used for compile time type selection. MapIf::type will be TrueType if Flag is +// true and FalseType otherwise. +template +struct MapIf; + +template +struct MapIf { + typedef TrueType type; +}; + +template +struct MapIf { + typedef FalseType type; +}; + +// In proto2 Map, enum needs to be initialized to given default value, while +// other types' default value can be inferred from the type. +template +class MapValueInitializer { + public: + static inline void Initialize(Type& type, int default_enum_value); +}; + +template +class MapValueInitializer { + public: + static inline void Initialize(Type& value, int default_enum_value) { + value = static_cast(default_enum_value); + } +}; + +template +class MapValueInitializer { + public: + static inline void Initialize(Type& value, int default_enum_value) {} +}; + +template +class MapArenaMessageCreator { + public: + // Use arena to create message if Type is arena constructable. Otherwise, + // create the message on heap. + static inline Type* CreateMessage(Arena* arena); +}; +template +class MapArenaMessageCreator { + public: + static inline Type* CreateMessage(Arena* arena) { + return Arena::CreateMessage(arena); + } +}; +template +class MapArenaMessageCreator { + public: + static inline Type* CreateMessage(Arena* arena) { + return Arena::Create(arena); + } +}; + +// Define constants for given wire field type +template +class MapWireFieldTypeTraits {}; + +#define TYPE_TRAITS(FieldType, CType, WireFormatType, IsMessage, IsEnum) \ + template \ + class MapWireFieldTypeTraits { \ + public: \ + static const bool kIsMessage = IsMessage; \ + static const bool kIsEnum = IsEnum; \ + typedef typename MapIf::type TypeOnMemory; \ + typedef typename MapIf::type MapEntryAccessorType; \ + static const WireFormatLite::WireType kWireType = \ + WireFormatLite::WIRETYPE_##WireFormatType; \ + }; + +TYPE_TRAITS(MESSAGE , Type, LENGTH_DELIMITED, true, false) +TYPE_TRAITS(STRING , ArenaStringPtr, LENGTH_DELIMITED, false, false) +TYPE_TRAITS(BYTES , ArenaStringPtr , LENGTH_DELIMITED, false, false) +TYPE_TRAITS(INT64 , int64 , VARINT , false, false) +TYPE_TRAITS(UINT64 , uint64 , VARINT , false, false) +TYPE_TRAITS(INT32 , int32 , VARINT , false, false) +TYPE_TRAITS(UINT32 , uint32 , VARINT , false, false) +TYPE_TRAITS(SINT64 , int64 , VARINT , false, false) +TYPE_TRAITS(SINT32 , int32 , VARINT , false, false) +TYPE_TRAITS(ENUM , int , VARINT , false, true ) +TYPE_TRAITS(DOUBLE , double , FIXED64, false, false) +TYPE_TRAITS(FLOAT , float , FIXED32, false, false) +TYPE_TRAITS(FIXED64 , uint64 , FIXED64, false, false) +TYPE_TRAITS(FIXED32 , uint32 , FIXED32, false, false) +TYPE_TRAITS(SFIXED64, int64 , FIXED64, false, false) +TYPE_TRAITS(SFIXED32, int32 , FIXED32, false, false) +TYPE_TRAITS(BOOL , bool , VARINT , false, false) + +#undef TYPE_TRAITS + +template +class MapTypeHandler {}; + +template +class MapTypeHandler { + public: + // Enum type cannot be used for MapTypeHandler::Read. Define a type which will + // replace Enum with int. + typedef typename MapWireFieldTypeTraits::MapEntryAccessorType MapEntryAccessorType; + // Internal stored type in MapEntryLite for given wire field type. + typedef typename MapWireFieldTypeTraits::TypeOnMemory TypeOnMemory; + // Corresponding wire type for field type. + static const WireFormatLite::WireType kWireType = + MapWireFieldTypeTraits::kWireType; + // Whether wire type is for message. + static const bool kIsMessage = + MapWireFieldTypeTraits::kIsMessage; + // Whether wire type is for enum. + static const bool kIsEnum = + MapWireFieldTypeTraits::kIsEnum; + + // Functions used in parsing and serialization. =================== + static inline int ByteSize(const MapEntryAccessorType& value); + static inline int GetCachedSize(const MapEntryAccessorType& value); + static inline bool Read(io::CodedInputStream* input, + MapEntryAccessorType* value); + static inline void Write(int field, const MapEntryAccessorType& value, + io::CodedOutputStream* output); + static inline uint8* InternalWriteToArray(int field, + const MapEntryAccessorType& value, + bool deterministic, uint8* target); + static inline uint8* WriteToArray(int field, + const MapEntryAccessorType& value, + uint8* target); + + // Functions to manipulate data on memory. ======================== + static inline const Type& GetExternalReference(const Type* value); + static inline void DeleteNoArena(const Type* x); + static inline void Merge(const Type& from, Type** to, Arena* arena); + static inline void Clear(Type** value, Arena* arena); + static inline void ClearMaybeByDefaultEnum(Type** value, Arena* arena, + int default_enum_value); + static inline void Initialize(Type** x, Arena* arena); + + static inline void InitializeMaybeByDefaultEnum(Type** x, + int default_enum_value, + Arena* arena); + static inline Type* EnsureMutable(Type** value, Arena* arena); + // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding + // those already calculate in sizeof(MapField). + static inline int SpaceUsedInMapEntry(const Type* value); + // Return bytes used by value in Map. + static inline int SpaceUsedInMap(const Type& value); + // Assign default value to given instance. + static inline void AssignDefaultValue(Type** value); + // Return default instance if value is not initialized when calling const + // reference accessor. + static inline const Type& DefaultIfNotInitialized( + const Type* value, const Type* default_value); + // Check if all required fields have values set. + static inline bool IsInitialized(Type* value); +}; + +#define MAP_HANDLER(FieldType) \ + template \ + class MapTypeHandler { \ + public: \ + typedef typename MapWireFieldTypeTraits::MapEntryAccessorType \ + MapEntryAccessorType; \ + typedef typename MapWireFieldTypeTraits::TypeOnMemory TypeOnMemory; \ + static const WireFormatLite::WireType kWireType = \ + MapWireFieldTypeTraits::kWireType; \ + static const bool kIsMessage = \ + MapWireFieldTypeTraits::kIsMessage; \ + static const bool kIsEnum = \ + MapWireFieldTypeTraits::kIsEnum; \ + static inline int ByteSize(const MapEntryAccessorType& value); \ + static inline int GetCachedSize(const MapEntryAccessorType& value); \ + static inline bool Read(io::CodedInputStream* input, \ + MapEntryAccessorType* value); \ + static inline void Write(int field, const MapEntryAccessorType& value, \ + io::CodedOutputStream* output); \ + static inline uint8* InternalWriteToArray( \ + int field, \ + const MapEntryAccessorType& value, \ + bool deterministic, \ + uint8* target); \ + static inline uint8* WriteToArray(int field, \ + const MapEntryAccessorType& value, \ + uint8* target) { \ + return InternalWriteToArray(field, value, false, target); \ + } \ + static inline const MapEntryAccessorType& GetExternalReference( \ + const TypeOnMemory& value); \ + static inline void DeleteNoArena(const TypeOnMemory& x); \ + static inline void Merge(const MapEntryAccessorType& from, \ + TypeOnMemory* to, Arena* arena); \ + static inline void Clear(TypeOnMemory* value, Arena* arena); \ + static inline void ClearMaybeByDefaultEnum(TypeOnMemory* value, \ + Arena* arena, \ + int default_enum); \ + static inline int SpaceUsedInMapEntry(const TypeOnMemory& value); \ + static inline int SpaceUsedInMap(const TypeOnMemory& value); \ + static inline int SpaceUsedInMap(const string& value); \ + static inline void AssignDefaultValue(TypeOnMemory* value); \ + static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ + const TypeOnMemory& value, const TypeOnMemory& default_value); \ + static inline bool IsInitialized(const TypeOnMemory& value); \ + static void DeleteNoArena(TypeOnMemory& value); \ + static inline void Initialize(TypeOnMemory* value, Arena* arena); \ + static inline void InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ + int default_enum_value, \ + Arena* arena); \ + static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ + Arena* arena); \ + }; +MAP_HANDLER(STRING) +MAP_HANDLER(BYTES) +MAP_HANDLER(INT64) +MAP_HANDLER(UINT64) +MAP_HANDLER(INT32) +MAP_HANDLER(UINT32) +MAP_HANDLER(SINT64) +MAP_HANDLER(SINT32) +MAP_HANDLER(ENUM) +MAP_HANDLER(DOUBLE) +MAP_HANDLER(FLOAT) +MAP_HANDLER(FIXED64) +MAP_HANDLER(FIXED32) +MAP_HANDLER(SFIXED64) +MAP_HANDLER(SFIXED32) +MAP_HANDLER(BOOL) +#undef MAP_HANDLER + +template +inline int +MapTypeHandler::ByteSize( + const MapEntryAccessorType& value) { + return WireFormatLite::MessageSizeNoVirtual(value); +} + +#define GOOGLE_PROTOBUF_BYTE_SIZE(FieldType, DeclaredType) \ + template \ + inline int MapTypeHandler::ByteSize( \ + const MapEntryAccessorType& value) { \ + return WireFormatLite::DeclaredType##Size(value); \ + } + +GOOGLE_PROTOBUF_BYTE_SIZE(STRING, String) +GOOGLE_PROTOBUF_BYTE_SIZE(BYTES , Bytes) +GOOGLE_PROTOBUF_BYTE_SIZE(INT64 , Int64) +GOOGLE_PROTOBUF_BYTE_SIZE(UINT64, UInt64) +GOOGLE_PROTOBUF_BYTE_SIZE(INT32 , Int32) +GOOGLE_PROTOBUF_BYTE_SIZE(UINT32, UInt32) +GOOGLE_PROTOBUF_BYTE_SIZE(SINT64, SInt64) +GOOGLE_PROTOBUF_BYTE_SIZE(SINT32, SInt32) +GOOGLE_PROTOBUF_BYTE_SIZE(ENUM , Enum) + +#undef GOOGLE_PROTOBUF_BYTE_SIZE + +#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \ + template \ + inline int MapTypeHandler::ByteSize( \ + const MapEntryAccessorType& value) { \ + return WireFormatLite::k##DeclaredType##Size; \ + } + +FIXED_BYTE_SIZE(DOUBLE , Double) +FIXED_BYTE_SIZE(FLOAT , Float) +FIXED_BYTE_SIZE(FIXED64 , Fixed64) +FIXED_BYTE_SIZE(FIXED32 , Fixed32) +FIXED_BYTE_SIZE(SFIXED64, SFixed64) +FIXED_BYTE_SIZE(SFIXED32, SFixed32) +FIXED_BYTE_SIZE(BOOL , Bool) + +#undef FIXED_BYTE_SIZE + +template +inline int +MapTypeHandler::GetCachedSize( + const MapEntryAccessorType& value) { + return WireFormatLite::LengthDelimitedSize(value.GetCachedSize()); +} + +#define GET_CACHED_SIZE(FieldType, DeclaredType) \ + template \ + inline int \ + MapTypeHandler::GetCachedSize( \ + const MapEntryAccessorType& value) { \ + return WireFormatLite::DeclaredType##Size(value); \ + } + +GET_CACHED_SIZE(STRING, String) +GET_CACHED_SIZE(BYTES , Bytes) +GET_CACHED_SIZE(INT64 , Int64) +GET_CACHED_SIZE(UINT64, UInt64) +GET_CACHED_SIZE(INT32 , Int32) +GET_CACHED_SIZE(UINT32, UInt32) +GET_CACHED_SIZE(SINT64, SInt64) +GET_CACHED_SIZE(SINT32, SInt32) +GET_CACHED_SIZE(ENUM , Enum) + +#undef GET_CACHED_SIZE + +#define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType) \ + template \ + inline int \ + MapTypeHandler::GetCachedSize( \ + const MapEntryAccessorType& value) { \ + return WireFormatLite::k##DeclaredType##Size; \ + } + +GET_FIXED_CACHED_SIZE(DOUBLE , Double) +GET_FIXED_CACHED_SIZE(FLOAT , Float) +GET_FIXED_CACHED_SIZE(FIXED64 , Fixed64) +GET_FIXED_CACHED_SIZE(FIXED32 , Fixed32) +GET_FIXED_CACHED_SIZE(SFIXED64, SFixed64) +GET_FIXED_CACHED_SIZE(SFIXED32, SFixed32) +GET_FIXED_CACHED_SIZE(BOOL , Bool) + +#undef GET_FIXED_CACHED_SIZE + +template +inline void MapTypeHandler::Write( + int field, const MapEntryAccessorType& value, + io::CodedOutputStream* output) { + WireFormatLite::WriteMessageMaybeToArray(field, value, output); +} + +template +inline uint8* +MapTypeHandler::InternalWriteToArray( + int field, const MapEntryAccessorType& value, bool deterministic, + uint8* target) { + return WireFormatLite::InternalWriteMessageToArray(field, value, + deterministic, target); +} + +#define WRITE_METHOD(FieldType, DeclaredType) \ + template \ + inline void MapTypeHandler::Write( \ + int field, const MapEntryAccessorType& value, \ + io::CodedOutputStream* output) { \ + return WireFormatLite::Write##DeclaredType(field, value, output); \ + } \ + template \ + inline uint8* \ + MapTypeHandler::InternalWriteToArray( \ + int field, const MapEntryAccessorType& value, bool, uint8* target) { \ + return WireFormatLite::Write##DeclaredType##ToArray(field, value, target); \ + } + +WRITE_METHOD(STRING , String) +WRITE_METHOD(BYTES , Bytes) +WRITE_METHOD(INT64 , Int64) +WRITE_METHOD(UINT64 , UInt64) +WRITE_METHOD(INT32 , Int32) +WRITE_METHOD(UINT32 , UInt32) +WRITE_METHOD(SINT64 , SInt64) +WRITE_METHOD(SINT32 , SInt32) +WRITE_METHOD(ENUM , Enum) +WRITE_METHOD(DOUBLE , Double) +WRITE_METHOD(FLOAT , Float) +WRITE_METHOD(FIXED64 , Fixed64) +WRITE_METHOD(FIXED32 , Fixed32) +WRITE_METHOD(SFIXED64, SFixed64) +WRITE_METHOD(SFIXED32, SFixed32) +WRITE_METHOD(BOOL , Bool) + +#undef WRITE_METHOD + +template +inline bool MapTypeHandler::Read( + io::CodedInputStream* input, MapEntryAccessorType* value) { + return WireFormatLite::ReadMessageNoVirtual(input, value); +} + +template +inline bool MapTypeHandler::Read( + io::CodedInputStream* input, MapEntryAccessorType* value) { + return WireFormatLite::ReadString(input, value); +} + +template +inline bool MapTypeHandler::Read( + io::CodedInputStream* input, MapEntryAccessorType* value) { + return WireFormatLite::ReadBytes(input, value); +} + +#define READ_METHOD(FieldType) \ + template \ + inline bool MapTypeHandler::Read( \ + io::CodedInputStream* input, MapEntryAccessorType* value) { \ + return WireFormatLite::ReadPrimitive( \ + input, value); \ + } + +READ_METHOD(INT64) +READ_METHOD(UINT64) +READ_METHOD(INT32) +READ_METHOD(UINT32) +READ_METHOD(SINT64) +READ_METHOD(SINT32) +READ_METHOD(ENUM) +READ_METHOD(DOUBLE) +READ_METHOD(FLOAT) +READ_METHOD(FIXED64) +READ_METHOD(FIXED32) +READ_METHOD(SFIXED64) +READ_METHOD(SFIXED32) +READ_METHOD(BOOL) + +#undef READ_METHOD + +// Definition for message handler + +template +inline const Type& +MapTypeHandler::GetExternalReference(const Type* value) { + return *value; +} + +template +inline int +MapTypeHandler::SpaceUsedInMapEntry(const Type* value) { + return value->SpaceUsed(); +} + +template +int MapTypeHandler::SpaceUsedInMap( + const Type& value) { + return value.SpaceUsed(); +} + +template +inline void MapTypeHandler::Clear( + Type** value, Arena* arena) { + if (*value != NULL) (*value)->Clear(); +} +template +inline void +MapTypeHandler::ClearMaybeByDefaultEnum(Type** value, + Arena* arena, + int default_enum_value) { + if (*value != NULL) (*value)->Clear(); +} +template +inline void MapTypeHandler::Merge( + const Type& from, Type** to, Arena* arena) { + (*to)->MergeFrom(from); +} + +template +void MapTypeHandler::DeleteNoArena( + const Type* ptr) { + delete ptr; +} + +template +inline void MapTypeHandler::AssignDefaultValue(Type** value) { + *value = const_cast(&Type::default_instance()); +} + +template +inline void MapTypeHandler::Initialize(Type** x, + Arena* arena) { + *x = NULL; +} + +template +inline void MapTypeHandler:: + InitializeMaybeByDefaultEnum(Type** x, int default_enum_value, + Arena* arena) { + *x = NULL; +} + +template +inline Type* MapTypeHandler::EnsureMutable(Type** value, + Arena* arena) { + if (*value == NULL) { + *value = + MapArenaMessageCreator:: + type::value>::CreateMessage(arena); + } + return *value; +} + +template +inline const Type& MapTypeHandler:: + DefaultIfNotInitialized(const Type* value, const Type* default_value) { + return value != NULL ? *value : *default_value; +} + +template +inline bool MapTypeHandler::IsInitialized(Type* value) { + return value->IsInitialized(); +} + +// Definition for string/bytes handler + +#define STRING_OR_BYTES_HANDLER_FUNCTIONS(FieldType) \ + template \ + inline const typename MapTypeHandler::MapEntryAccessorType& \ + MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ + return value.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \ + } \ + template \ + inline int \ + MapTypeHandler::SpaceUsedInMapEntry( \ + const TypeOnMemory& value) { \ + return sizeof(value); \ + } \ + template \ + inline int MapTypeHandler::SpaceUsedInMap(const TypeOnMemory& value) { \ + return sizeof(value); \ + } \ + template \ + inline int MapTypeHandler::SpaceUsedInMap(const string& value) { \ + return sizeof(value); \ + } \ + template \ + inline void MapTypeHandler::Clear( \ + TypeOnMemory* value, Arena* arena) { \ + value->ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), \ + arena); \ + } \ + template \ + inline void \ + MapTypeHandler::ClearMaybeByDefaultEnum(TypeOnMemory* value, \ + Arena* arena, \ + int default_enum) { \ + Clear(value, arena); \ + } \ + template \ + inline void MapTypeHandler::Merge( \ + const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \ + to->Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from, arena); \ + } \ + template \ + void MapTypeHandler::DeleteNoArena( \ + TypeOnMemory& value) { \ + value.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \ + } \ + template \ + inline void MapTypeHandler::AssignDefaultValue(TypeOnMemory* value) {} \ + template \ + inline void \ + MapTypeHandler::Initialize( \ + TypeOnMemory* value, Arena* arena) { \ + value->UnsafeSetDefault( \ + &::google::protobuf::internal::GetEmptyStringAlreadyInited()); \ + } \ + template \ + inline void \ + MapTypeHandler::InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ + int default_enum_value, \ + Arena* arena) { \ + Initialize(value, arena); \ + } \ + template \ + inline typename MapTypeHandler::MapEntryAccessorType* \ + MapTypeHandler::EnsureMutable( \ + TypeOnMemory* value, Arena* arena) { \ + return value->Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), \ + arena); \ + } \ + template \ + inline const typename MapTypeHandler::MapEntryAccessorType& \ + MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value, \ + const TypeOnMemory& \ + default_value) { \ + return value.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \ + } \ + template \ + inline bool MapTypeHandler::IsInitialized(const TypeOnMemory& value) { \ + return true; \ + } +STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING) +STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) +#undef STRING_OR_BYTES_HANDLER_FUNCTIONS + +#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \ + template \ + inline const typename MapTypeHandler::MapEntryAccessorType& \ + MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ + return value; \ + } \ + template \ + inline int \ + MapTypeHandler::SpaceUsedInMapEntry( \ + const TypeOnMemory& value) { \ + return 0; \ + } \ + template \ + inline int MapTypeHandler::SpaceUsedInMap(const TypeOnMemory& value) { \ + return sizeof(Type); \ + } \ + template \ + inline void MapTypeHandler::Clear( \ + TypeOnMemory* value, Arena* arena) { \ + *value = 0; \ + } \ + template \ + inline void \ + MapTypeHandler::ClearMaybeByDefaultEnum(TypeOnMemory* value, \ + Arena* arena, \ + int default_enum_value) { \ + *value = static_cast(default_enum_value); \ + } \ + template \ + inline void MapTypeHandler::Merge( \ + const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \ + *to = from; \ + } \ + template \ + inline void MapTypeHandler::DeleteNoArena(TypeOnMemory& x) {} \ + template \ + inline void MapTypeHandler::AssignDefaultValue(TypeOnMemory* value) {} \ + template \ + inline void \ + MapTypeHandler::Initialize( \ + TypeOnMemory* value, Arena* arena) { \ + *value = 0; \ + } \ + template \ + inline void \ + MapTypeHandler::InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ + int default_enum_value, \ + Arena* arena) { \ + *value = static_cast(default_enum_value); \ + } \ + template \ + inline typename MapTypeHandler::MapEntryAccessorType* \ + MapTypeHandler::EnsureMutable( \ + TypeOnMemory* value, Arena* arena) { \ + return value; \ + } \ + template \ + inline const typename MapTypeHandler::MapEntryAccessorType& \ + MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value, \ + const TypeOnMemory& \ + default_value) { \ + return value; \ + } \ + template \ + inline bool MapTypeHandler::IsInitialized(const TypeOnMemory& value) { \ + return true; \ + } +PRIMITIVE_HANDLER_FUNCTIONS(INT64) +PRIMITIVE_HANDLER_FUNCTIONS(UINT64) +PRIMITIVE_HANDLER_FUNCTIONS(INT32) +PRIMITIVE_HANDLER_FUNCTIONS(UINT32) +PRIMITIVE_HANDLER_FUNCTIONS(SINT64) +PRIMITIVE_HANDLER_FUNCTIONS(SINT32) +PRIMITIVE_HANDLER_FUNCTIONS(ENUM) +PRIMITIVE_HANDLER_FUNCTIONS(DOUBLE) +PRIMITIVE_HANDLER_FUNCTIONS(FLOAT) +PRIMITIVE_HANDLER_FUNCTIONS(FIXED64) +PRIMITIVE_HANDLER_FUNCTIONS(FIXED32) +PRIMITIVE_HANDLER_FUNCTIONS(SFIXED64) +PRIMITIVE_HANDLER_FUNCTIONS(SFIXED32) +PRIMITIVE_HANDLER_FUNCTIONS(BOOL) +#undef PRIMITIVE_HANDLER_FUNCTIONS + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_TYPE_HANDLER_H__ diff --git a/thirdparty/linux/include/google/protobuf/message.h b/thirdparty/linux/include/google/protobuf/message.h new file mode 100644 index 0000000..9705e97 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/message.h @@ -0,0 +1,1150 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines Message, the abstract interface implemented by non-lite +// protocol message objects. Although it's possible to implement this +// interface manually, most users will use the protocol compiler to +// generate implementations. +// +// Example usage: +// +// Say you have a message defined as: +// +// message Foo { +// optional string text = 1; +// repeated int32 numbers = 2; +// } +// +// Then, if you used the protocol compiler to generate a class from the above +// definition, you could use it like so: +// +// string data; // Will store a serialized version of the message. +// +// { +// // Create a message and serialize it. +// Foo foo; +// foo.set_text("Hello World!"); +// foo.add_numbers(1); +// foo.add_numbers(5); +// foo.add_numbers(42); +// +// foo.SerializeToString(&data); +// } +// +// { +// // Parse the serialized message and check that it contains the +// // correct data. +// Foo foo; +// foo.ParseFromString(data); +// +// assert(foo.text() == "Hello World!"); +// assert(foo.numbers_size() == 3); +// assert(foo.numbers(0) == 1); +// assert(foo.numbers(1) == 5); +// assert(foo.numbers(2) == 42); +// } +// +// { +// // Same as the last block, but do it dynamically via the Message +// // reflection interface. +// Message* foo = new Foo; +// const Descriptor* descriptor = foo->GetDescriptor(); +// +// // Get the descriptors for the fields we're interested in and verify +// // their types. +// const FieldDescriptor* text_field = descriptor->FindFieldByName("text"); +// assert(text_field != NULL); +// assert(text_field->type() == FieldDescriptor::TYPE_STRING); +// assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL); +// const FieldDescriptor* numbers_field = descriptor-> +// FindFieldByName("numbers"); +// assert(numbers_field != NULL); +// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32); +// assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED); +// +// // Parse the message. +// foo->ParseFromString(data); +// +// // Use the reflection interface to examine the contents. +// const Reflection* reflection = foo->GetReflection(); +// assert(reflection->GetString(*foo, text_field) == "Hello World!"); +// assert(reflection->FieldSize(*foo, numbers_field) == 3); +// assert(reflection->GetRepeatedInt32(*foo, numbers_field, 0) == 1); +// assert(reflection->GetRepeatedInt32(*foo, numbers_field, 1) == 5); +// assert(reflection->GetRepeatedInt32(*foo, numbers_field, 2) == 42); +// +// delete foo; +// } + +#ifndef GOOGLE_PROTOBUF_MESSAGE_H__ +#define GOOGLE_PROTOBUF_MESSAGE_H__ + +#include +#include +#include +#include + +#include +#include + +#include +#include + + +#define GOOGLE_PROTOBUF_HAS_ONEOF +#define GOOGLE_PROTOBUF_HAS_ARENAS + +namespace google { +namespace protobuf { + +// Defined in this file. +class Message; +class Reflection; +class MessageFactory; + +// Defined in other files. +class MapKey; +class MapValueRef; +class MapIterator; +class MapReflectionTester; + +namespace internal { +class MapFieldBase; +} +class UnknownFieldSet; // unknown_field_set.h +namespace io { +class ZeroCopyInputStream; // zero_copy_stream.h +class ZeroCopyOutputStream; // zero_copy_stream.h +class CodedInputStream; // coded_stream.h +class CodedOutputStream; // coded_stream.h +} +namespace python { +class MapReflectionFriend; // scalar_map_container.h +} + + +template +class RepeatedField; // repeated_field.h + +template +class RepeatedPtrField; // repeated_field.h + +// A container to hold message metadata. +struct Metadata { + const Descriptor* descriptor; + const Reflection* reflection; +}; + +// Abstract interface for protocol messages. +// +// See also MessageLite, which contains most every-day operations. Message +// adds descriptors and reflection on top of that. +// +// The methods of this class that are virtual but not pure-virtual have +// default implementations based on reflection. Message classes which are +// optimized for speed will want to override these with faster implementations, +// but classes optimized for code size may be happy with keeping them. See +// the optimize_for option in descriptor.proto. +class LIBPROTOBUF_EXPORT Message : public MessageLite { + public: + inline Message() {} + virtual ~Message() {} + + // Basic Operations ------------------------------------------------ + + // Construct a new instance of the same type. Ownership is passed to the + // caller. (This is also defined in MessageLite, but is defined again here + // for return-type covariance.) + virtual Message* New() const = 0; + + // Construct a new instance on the arena. Ownership is passed to the caller + // if arena is a NULL. Default implementation allows for API compatibility + // during the Arena transition. + virtual Message* New(::google::protobuf::Arena* arena) const { + Message* message = New(); + if (arena != NULL) { + arena->Own(message); + } + return message; + } + + // Make this message into a copy of the given message. The given message + // must have the same descriptor, but need not necessarily be the same class. + // By default this is just implemented as "Clear(); MergeFrom(from);". + virtual void CopyFrom(const Message& from); + + // Merge the fields from the given message into this message. Singular + // fields will be overwritten, if specified in from, except for embedded + // messages which will be merged. Repeated fields will be concatenated. + // The given message must be of the same type as this message (i.e. the + // exact same class). + virtual void MergeFrom(const Message& from); + + // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with + // a nice error message. + void CheckInitialized() const; + + // Slowly build a list of all required fields that are not set. + // This is much, much slower than IsInitialized() as it is implemented + // purely via reflection. Generally, you should not call this unless you + // have already determined that an error exists by calling IsInitialized(). + void FindInitializationErrors(std::vector* errors) const; + + // Like FindInitializationErrors, but joins all the strings, delimited by + // commas, and returns them. + string InitializationErrorString() const; + + // Clears all unknown fields from this message and all embedded messages. + // Normally, if unknown tag numbers are encountered when parsing a message, + // the tag and value are stored in the message's UnknownFieldSet and + // then written back out when the message is serialized. This allows servers + // which simply route messages to other servers to pass through messages + // that have new field definitions which they don't yet know about. However, + // this behavior can have security implications. To avoid it, call this + // method after parsing. + // + // See Reflection::GetUnknownFields() for more on unknown fields. + virtual void DiscardUnknownFields(); + + // Computes (an estimate of) the total number of bytes currently used for + // storing the message in memory. The default implementation calls the + // Reflection object's SpaceUsed() method. + // + // SpaceUsed() is noticeably slower than ByteSize(), as it is implemented + // using reflection (rather than the generated code implementation for + // ByteSize()). Like ByteSize(), its CPU time is linear in the number of + // fields defined for the proto. + virtual int SpaceUsed() const; + + // Debugging & Testing---------------------------------------------- + + // Generates a human readable form of this message, useful for debugging + // and other purposes. + string DebugString() const; + // Like DebugString(), but with less whitespace. + string ShortDebugString() const; + // Like DebugString(), but do not escape UTF-8 byte sequences. + string Utf8DebugString() const; + // Convenience function useful in GDB. Prints DebugString() to stdout. + void PrintDebugString() const; + + // Heavy I/O ------------------------------------------------------- + // Additional parsing and serialization methods not implemented by + // MessageLite because they are not supported by the lite library. + + // Parse a protocol buffer from a file descriptor. If successful, the entire + // input will be consumed. + bool ParseFromFileDescriptor(int file_descriptor); + // Like ParseFromFileDescriptor(), but accepts messages that are missing + // required fields. + bool ParsePartialFromFileDescriptor(int file_descriptor); + // Parse a protocol buffer from a C++ istream. If successful, the entire + // input will be consumed. + bool ParseFromIstream(istream* input); + // Like ParseFromIstream(), but accepts messages that are missing + // required fields. + bool ParsePartialFromIstream(istream* input); + + // Serialize the message and write it to the given file descriptor. All + // required fields must be set. + bool SerializeToFileDescriptor(int file_descriptor) const; + // Like SerializeToFileDescriptor(), but allows missing required fields. + bool SerializePartialToFileDescriptor(int file_descriptor) const; + // Serialize the message and write it to the given C++ ostream. All + // required fields must be set. + bool SerializeToOstream(ostream* output) const; + // Like SerializeToOstream(), but allows missing required fields. + bool SerializePartialToOstream(ostream* output) const; + + + // Reflection-based methods ---------------------------------------- + // These methods are pure-virtual in MessageLite, but Message provides + // reflection-based default implementations. + + virtual string GetTypeName() const; + virtual void Clear(); + virtual bool IsInitialized() const; + virtual void CheckTypeAndMergeFrom(const MessageLite& other); + virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); + virtual int ByteSize() const; + virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const; + + private: + // This is called only by the default implementation of ByteSize(), to + // update the cached size. If you override ByteSize(), you do not need + // to override this. If you do not override ByteSize(), you MUST override + // this; the default implementation will crash. + // + // The method is private because subclasses should never call it; only + // override it. Yes, C++ lets you do that. Crazy, huh? + virtual void SetCachedSize(int size) const; + + public: + + // Introspection --------------------------------------------------- + + // Typedef for backwards-compatibility. + typedef google::protobuf::Reflection Reflection; + + // Get a Descriptor for this message's type. This describes what + // fields the message contains, the types of those fields, etc. + const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; } + + // Get the Reflection interface for this Message, which can be used to + // read and modify the fields of the Message dynamically (in other words, + // without knowing the message type at compile time). This object remains + // property of the Message. + // + // This method remains virtual in case a subclass does not implement + // reflection and wants to override the default behavior. + virtual const Reflection* GetReflection() const { + return GetMetadata().reflection; + } + + protected: + // Get a struct containing the metadata for the Message. Most subclasses only + // need to implement this method, rather than the GetDescriptor() and + // GetReflection() wrappers. + virtual Metadata GetMetadata() const = 0; + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); +}; + +namespace internal { +// Forward-declare interfaces used to implement RepeatedFieldRef. +// These are protobuf internals that users shouldn't care about. +class RepeatedFieldAccessor; +} // namespace internal + +// Forward-declare RepeatedFieldRef templates. The second type parameter is +// used for SFINAE tricks. Users should ignore it. +template +class RepeatedFieldRef; + +template +class MutableRepeatedFieldRef; + +// This interface contains methods that can be used to dynamically access +// and modify the fields of a protocol message. Their semantics are +// similar to the accessors the protocol compiler generates. +// +// To get the Reflection for a given Message, call Message::GetReflection(). +// +// This interface is separate from Message only for efficiency reasons; +// the vast majority of implementations of Message will share the same +// implementation of Reflection (GeneratedMessageReflection, +// defined in generated_message.h), and all Messages of a particular class +// should share the same Reflection object (though you should not rely on +// the latter fact). +// +// There are several ways that these methods can be used incorrectly. For +// example, any of the following conditions will lead to undefined +// results (probably assertion failures): +// - The FieldDescriptor is not a field of this message type. +// - The method called is not appropriate for the field's type. For +// each field type in FieldDescriptor::TYPE_*, there is only one +// Get*() method, one Set*() method, and one Add*() method that is +// valid for that type. It should be obvious which (except maybe +// for TYPE_BYTES, which are represented using strings in C++). +// - A Get*() or Set*() method for singular fields is called on a repeated +// field. +// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated +// field. +// - The Message object passed to any method is not of the right type for +// this Reflection object (i.e. message.GetReflection() != reflection). +// +// You might wonder why there is not any abstract representation for a field +// of arbitrary type. E.g., why isn't there just a "GetField()" method that +// returns "const Field&", where "Field" is some class with accessors like +// "GetInt32Value()". The problem is that someone would have to deal with +// allocating these Field objects. For generated message classes, having to +// allocate space for an additional object to wrap every field would at least +// double the message's memory footprint, probably worse. Allocating the +// objects on-demand, on the other hand, would be expensive and prone to +// memory leaks. So, instead we ended up with this flat interface. +// +// TODO(kenton): Create a utility class which callers can use to read and +// write fields from a Reflection without paying attention to the type. +class LIBPROTOBUF_EXPORT Reflection { + public: + inline Reflection() {} + virtual ~Reflection(); + + // Get the UnknownFieldSet for the message. This contains fields which + // were seen when the Message was parsed but were not recognized according + // to the Message's definition. For proto3 protos, this method will always + // return an empty UnknownFieldSet. + virtual const UnknownFieldSet& GetUnknownFields( + const Message& message) const = 0; + // Get a mutable pointer to the UnknownFieldSet for the message. This + // contains fields which were seen when the Message was parsed but were not + // recognized according to the Message's definition. For proto3 protos, this + // method will return a valid mutable UnknownFieldSet pointer but modifying + // it won't affect the serialized bytes of the message. + virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0; + + // Estimate the amount of memory used by the message object. + virtual int SpaceUsed(const Message& message) const = 0; + + // Check if the given non-repeated field is set. + virtual bool HasField(const Message& message, + const FieldDescriptor* field) const = 0; + + // Get the number of elements of a repeated field. + virtual int FieldSize(const Message& message, + const FieldDescriptor* field) const = 0; + + // Clear the value of a field, so that HasField() returns false or + // FieldSize() returns zero. + virtual void ClearField(Message* message, + const FieldDescriptor* field) const = 0; + + // Check if the oneof is set. Returns true if any field in oneof + // is set, false otherwise. + // TODO(jieluo) - make it pure virtual after updating all + // the subclasses. + virtual bool HasOneof(const Message& /*message*/, + const OneofDescriptor* /*oneof_descriptor*/) const { + return false; + } + + virtual void ClearOneof(Message* /*message*/, + const OneofDescriptor* /*oneof_descriptor*/) const {} + + // Returns the field descriptor if the oneof is set. NULL otherwise. + // TODO(jieluo) - make it pure virtual. + virtual const FieldDescriptor* GetOneofFieldDescriptor( + const Message& /*message*/, + const OneofDescriptor* /*oneof_descriptor*/) const { + return NULL; + } + + // Removes the last element of a repeated field. + // We don't provide a way to remove any element other than the last + // because it invites inefficient use, such as O(n^2) filtering loops + // that should have been O(n). If you want to remove an element other + // than the last, the best way to do it is to re-arrange the elements + // (using Swap()) so that the one you want removed is at the end, then + // call RemoveLast(). + virtual void RemoveLast(Message* message, + const FieldDescriptor* field) const = 0; + // Removes the last element of a repeated message field, and returns the + // pointer to the caller. Caller takes ownership of the returned pointer. + virtual Message* ReleaseLast(Message* message, + const FieldDescriptor* field) const = 0; + + // Swap the complete contents of two messages. + virtual void Swap(Message* message1, Message* message2) const = 0; + + // Swap fields listed in fields vector of two messages. + virtual void SwapFields(Message* message1, + Message* message2, + const std::vector& fields) + const = 0; + + // Swap two elements of a repeated field. + virtual void SwapElements(Message* message, + const FieldDescriptor* field, + int index1, + int index2) const = 0; + + // List all fields of the message which are currently set. This includes + // extensions. Singular fields will only be listed if HasField(field) would + // return true and repeated fields will only be listed if FieldSize(field) + // would return non-zero. Fields (both normal fields and extension fields) + // will be listed ordered by field number. + virtual void ListFields( + const Message& message, + std::vector* output) const = 0; + + // Singular field getters ------------------------------------------ + // These get the value of a non-repeated field. They return the default + // value for fields that aren't set. + + virtual int32 GetInt32 (const Message& message, + const FieldDescriptor* field) const = 0; + virtual int64 GetInt64 (const Message& message, + const FieldDescriptor* field) const = 0; + virtual uint32 GetUInt32(const Message& message, + const FieldDescriptor* field) const = 0; + virtual uint64 GetUInt64(const Message& message, + const FieldDescriptor* field) const = 0; + virtual float GetFloat (const Message& message, + const FieldDescriptor* field) const = 0; + virtual double GetDouble(const Message& message, + const FieldDescriptor* field) const = 0; + virtual bool GetBool (const Message& message, + const FieldDescriptor* field) const = 0; + virtual string GetString(const Message& message, + const FieldDescriptor* field) const = 0; + virtual const EnumValueDescriptor* GetEnum( + const Message& message, const FieldDescriptor* field) const = 0; + + // GetEnumValue() returns an enum field's value as an integer rather than + // an EnumValueDescriptor*. If the integer value does not correspond to a + // known value descriptor, a new value descriptor is created. (Such a value + // will only be present when the new unknown-enum-value semantics are enabled + // for a message.) + virtual int GetEnumValue( + const Message& message, const FieldDescriptor* field) const; + + // See MutableMessage() for the meaning of the "factory" parameter. + virtual const Message& GetMessage(const Message& message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; + + // Get a string value without copying, if possible. + // + // GetString() necessarily returns a copy of the string. This can be + // inefficient when the string is already stored in a string object in the + // underlying message. GetStringReference() will return a reference to the + // underlying string in this case. Otherwise, it will copy the string into + // *scratch and return that. + // + // Note: It is perfectly reasonable and useful to write code like: + // str = reflection->GetStringReference(field, &str); + // This line would ensure that only one copy of the string is made + // regardless of the field's underlying representation. When initializing + // a newly-constructed string, though, it's just as fast and more readable + // to use code like: + // string str = reflection->GetString(message, field); + virtual const string& GetStringReference(const Message& message, + const FieldDescriptor* field, + string* scratch) const = 0; + + + // Singular field mutators ----------------------------------------- + // These mutate the value of a non-repeated field. + + virtual void SetInt32 (Message* message, + const FieldDescriptor* field, int32 value) const = 0; + virtual void SetInt64 (Message* message, + const FieldDescriptor* field, int64 value) const = 0; + virtual void SetUInt32(Message* message, + const FieldDescriptor* field, uint32 value) const = 0; + virtual void SetUInt64(Message* message, + const FieldDescriptor* field, uint64 value) const = 0; + virtual void SetFloat (Message* message, + const FieldDescriptor* field, float value) const = 0; + virtual void SetDouble(Message* message, + const FieldDescriptor* field, double value) const = 0; + virtual void SetBool (Message* message, + const FieldDescriptor* field, bool value) const = 0; + virtual void SetString(Message* message, + const FieldDescriptor* field, + const string& value) const = 0; + virtual void SetEnum (Message* message, + const FieldDescriptor* field, + const EnumValueDescriptor* value) const = 0; + // Set an enum field's value with an integer rather than EnumValueDescriptor. + // If the value does not correspond to a known enum value, either behavior is + // undefined (for proto2 messages), or the value is accepted silently for + // messages with new unknown-enum-value semantics. + virtual void SetEnumValue(Message* message, + const FieldDescriptor* field, + int value) const; + + // Get a mutable pointer to a field with a message type. If a MessageFactory + // is provided, it will be used to construct instances of the sub-message; + // otherwise, the default factory is used. If the field is an extension that + // does not live in the same pool as the containing message's descriptor (e.g. + // it lives in an overlay pool), then a MessageFactory must be provided. + // If you have no idea what that meant, then you probably don't need to worry + // about it (don't provide a MessageFactory). WARNING: If the + // FieldDescriptor is for a compiled-in extension, then + // factory->GetPrototype(field->message_type()) MUST return an instance of + // the compiled-in class for this type, NOT DynamicMessage. + virtual Message* MutableMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; + // Replaces the message specified by 'field' with the already-allocated object + // sub_message, passing ownership to the message. If the field contained a + // message, that message is deleted. If sub_message is NULL, the field is + // cleared. + virtual void SetAllocatedMessage(Message* message, + Message* sub_message, + const FieldDescriptor* field) const = 0; + // Releases the message specified by 'field' and returns the pointer, + // ReleaseMessage() will return the message the message object if it exists. + // Otherwise, it may or may not return NULL. In any case, if the return value + // is non-NULL, the caller takes ownership of the pointer. + // If the field existed (HasField() is true), then the returned pointer will + // be the same as the pointer returned by MutableMessage(). + // This function has the same effect as ClearField(). + virtual Message* ReleaseMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; + + + // Repeated field getters ------------------------------------------ + // These get the value of one element of a repeated field. + + virtual int32 GetRepeatedInt32 (const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual int64 GetRepeatedInt64 (const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual uint32 GetRepeatedUInt32(const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual uint64 GetRepeatedUInt64(const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual float GetRepeatedFloat (const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual double GetRepeatedDouble(const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual bool GetRepeatedBool (const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual string GetRepeatedString(const Message& message, + const FieldDescriptor* field, + int index) const = 0; + virtual const EnumValueDescriptor* GetRepeatedEnum( + const Message& message, + const FieldDescriptor* field, int index) const = 0; + // GetRepeatedEnumValue() returns an enum field's value as an integer rather + // than an EnumValueDescriptor*. If the integer value does not correspond to a + // known value descriptor, a new value descriptor is created. (Such a value + // will only be present when the new unknown-enum-value semantics are enabled + // for a message.) + virtual int GetRepeatedEnumValue( + const Message& message, + const FieldDescriptor* field, int index) const; + virtual const Message& GetRepeatedMessage( + const Message& message, + const FieldDescriptor* field, int index) const = 0; + + // See GetStringReference(), above. + virtual const string& GetRepeatedStringReference( + const Message& message, const FieldDescriptor* field, + int index, string* scratch) const = 0; + + + // Repeated field mutators ----------------------------------------- + // These mutate the value of one element of a repeated field. + + virtual void SetRepeatedInt32 (Message* message, + const FieldDescriptor* field, + int index, int32 value) const = 0; + virtual void SetRepeatedInt64 (Message* message, + const FieldDescriptor* field, + int index, int64 value) const = 0; + virtual void SetRepeatedUInt32(Message* message, + const FieldDescriptor* field, + int index, uint32 value) const = 0; + virtual void SetRepeatedUInt64(Message* message, + const FieldDescriptor* field, + int index, uint64 value) const = 0; + virtual void SetRepeatedFloat (Message* message, + const FieldDescriptor* field, + int index, float value) const = 0; + virtual void SetRepeatedDouble(Message* message, + const FieldDescriptor* field, + int index, double value) const = 0; + virtual void SetRepeatedBool (Message* message, + const FieldDescriptor* field, + int index, bool value) const = 0; + virtual void SetRepeatedString(Message* message, + const FieldDescriptor* field, + int index, const string& value) const = 0; + virtual void SetRepeatedEnum(Message* message, + const FieldDescriptor* field, int index, + const EnumValueDescriptor* value) const = 0; + // Set an enum field's value with an integer rather than EnumValueDescriptor. + // If the value does not correspond to a known enum value, either behavior is + // undefined (for proto2 messages), or the value is accepted silently for + // messages with new unknown-enum-value semantics. + virtual void SetRepeatedEnumValue(Message* message, + const FieldDescriptor* field, int index, + int value) const; + // Get a mutable pointer to an element of a repeated field with a message + // type. + virtual Message* MutableRepeatedMessage( + Message* message, const FieldDescriptor* field, int index) const = 0; + + + // Repeated field adders ------------------------------------------- + // These add an element to a repeated field. + + virtual void AddInt32 (Message* message, + const FieldDescriptor* field, int32 value) const = 0; + virtual void AddInt64 (Message* message, + const FieldDescriptor* field, int64 value) const = 0; + virtual void AddUInt32(Message* message, + const FieldDescriptor* field, uint32 value) const = 0; + virtual void AddUInt64(Message* message, + const FieldDescriptor* field, uint64 value) const = 0; + virtual void AddFloat (Message* message, + const FieldDescriptor* field, float value) const = 0; + virtual void AddDouble(Message* message, + const FieldDescriptor* field, double value) const = 0; + virtual void AddBool (Message* message, + const FieldDescriptor* field, bool value) const = 0; + virtual void AddString(Message* message, + const FieldDescriptor* field, + const string& value) const = 0; + virtual void AddEnum (Message* message, + const FieldDescriptor* field, + const EnumValueDescriptor* value) const = 0; + // Set an enum field's value with an integer rather than EnumValueDescriptor. + // If the value does not correspond to a known enum value, either behavior is + // undefined (for proto2 messages), or the value is accepted silently for + // messages with new unknown-enum-value semantics. + virtual void AddEnumValue(Message* message, + const FieldDescriptor* field, + int value) const; + // See MutableMessage() for comments on the "factory" parameter. + virtual Message* AddMessage(Message* message, + const FieldDescriptor* field, + MessageFactory* factory = NULL) const = 0; + + // Appends an already-allocated object 'new_entry' to the repeated field + // specifyed by 'field' passing ownership to the message. + // TODO(tmarek): Make virtual after all subclasses have been + // updated. + virtual void AddAllocatedMessage(Message* /* message */, + const FieldDescriptor* /*field */, + Message* /* new_entry */) const {} + + + // Get a RepeatedFieldRef object that can be used to read the underlying + // repeated field. The type parameter T must be set according to the + // field's cpp type. The following table shows the mapping from cpp type + // to acceptable T. + // + // field->cpp_type() T + // CPPTYPE_INT32 int32 + // CPPTYPE_UINT32 uint32 + // CPPTYPE_INT64 int64 + // CPPTYPE_UINT64 uint64 + // CPPTYPE_DOUBLE double + // CPPTYPE_FLOAT float + // CPPTYPE_BOOL bool + // CPPTYPE_ENUM generated enum type or int32 + // CPPTYPE_STRING string + // CPPTYPE_MESSAGE generated message type or google::protobuf::Message + // + // A RepeatedFieldRef object can be copied and the resulted object will point + // to the same repeated field in the same message. The object can be used as + // long as the message is not destroyed. + // + // Note that to use this method users need to include the header file + // "google/protobuf/reflection.h" (which defines the RepeatedFieldRef + // class templates). + template + RepeatedFieldRef GetRepeatedFieldRef( + const Message& message, const FieldDescriptor* field) const; + + // Like GetRepeatedFieldRef() but return an object that can also be used + // manipulate the underlying repeated field. + template + MutableRepeatedFieldRef GetMutableRepeatedFieldRef( + Message* message, const FieldDescriptor* field) const; + + // DEPRECATED. Please use Get(Mutable)RepeatedFieldRef() for repeated field + // access. The following repeated field accesors will be removed in the + // future. + // + // Repeated field accessors ------------------------------------------------- + // The methods above, e.g. GetRepeatedInt32(msg, fd, index), provide singular + // access to the data in a RepeatedField. The methods below provide aggregate + // access by exposing the RepeatedField object itself with the Message. + // Applying these templates to inappropriate types will lead to an undefined + // reference at link time (e.g. GetRepeatedField<***double>), or possibly a + // template matching error at compile time (e.g. GetRepeatedPtrField). + // + // Usage example: my_doubs = refl->GetRepeatedField(msg, fd); + + // DEPRECATED. Please use GetRepeatedFieldRef(). + // + // for T = Cord and all protobuf scalar types except enums. + template + const RepeatedField& GetRepeatedField( + const Message&, const FieldDescriptor*) const; + + // DEPRECATED. Please use GetMutableRepeatedFieldRef(). + // + // for T = Cord and all protobuf scalar types except enums. + template + RepeatedField* MutableRepeatedField( + Message*, const FieldDescriptor*) const; + + // DEPRECATED. Please use GetRepeatedFieldRef(). + // + // for T = string, google::protobuf::internal::StringPieceField + // google::protobuf::Message & descendants. + template + const RepeatedPtrField& GetRepeatedPtrField( + const Message&, const FieldDescriptor*) const; + + // DEPRECATED. Please use GetMutableRepeatedFieldRef(). + // + // for T = string, google::protobuf::internal::StringPieceField + // google::protobuf::Message & descendants. + template + RepeatedPtrField* MutableRepeatedPtrField( + Message*, const FieldDescriptor*) const; + + // Extensions ---------------------------------------------------------------- + + // Try to find an extension of this message type by fully-qualified field + // name. Returns NULL if no extension is known for this name or number. + virtual const FieldDescriptor* FindKnownExtensionByName( + const string& name) const = 0; + + // Try to find an extension of this message type by field number. + // Returns NULL if no extension is known for this name or number. + virtual const FieldDescriptor* FindKnownExtensionByNumber( + int number) const = 0; + + // Feature Flags ------------------------------------------------------------- + + // Does this message support storing arbitrary integer values in enum fields? + // If |true|, GetEnumValue/SetEnumValue and associated repeated-field versions + // take arbitrary integer values, and the legacy GetEnum() getter will + // dynamically create an EnumValueDescriptor for any integer value without + // one. If |false|, setting an unknown enum value via the integer-based + // setters results in undefined behavior (in practice, GOOGLE_DCHECK-fails). + // + // Generic code that uses reflection to handle messages with enum fields + // should check this flag before using the integer-based setter, and either + // downgrade to a compatible value or use the UnknownFieldSet if not. For + // example: + // + // int new_value = GetValueFromApplicationLogic(); + // if (reflection->SupportsUnknownEnumValues()) { + // reflection->SetEnumValue(message, field, new_value); + // } else { + // if (field_descriptor->enum_type()-> + // FindValueByNumver(new_value) != NULL) { + // reflection->SetEnumValue(message, field, new_value); + // } else if (emit_unknown_enum_values) { + // reflection->MutableUnknownFields(message)->AddVarint( + // field->number(), + // new_value); + // } else { + // // convert value to a compatible/default value. + // new_value = CompatibleDowngrade(new_value); + // reflection->SetEnumValue(message, field, new_value); + // } + // } + virtual bool SupportsUnknownEnumValues() const { return false; } + + // Returns the MessageFactory associated with this message. This can be + // useful for determining if a message is a generated message or not, for + // example: + // + // if (message->GetReflection()->GetMessageFactory() == + // google::protobuf::MessageFactory::generated_factory()) { + // // This is a generated message. + // } + // + // It can also be used to create more messages of this type, though + // Message::New() is an easier way to accomplish this. + virtual MessageFactory* GetMessageFactory() const; + + // --------------------------------------------------------------------------- + + protected: + // Obtain a pointer to a Repeated Field Structure and do some type checking: + // on field->cpp_type(), + // on field->field_option().ctype() (if ctype >= 0) + // of field->message_type() (if message_type != NULL). + // We use 2 routine rather than 4 (const vs mutable) x (scalar vs pointer). + virtual void* MutableRawRepeatedField( + Message* message, const FieldDescriptor* field, FieldDescriptor::CppType, + int ctype, const Descriptor* message_type) const = 0; + + // TODO(jieluo) - make it pure virtual after updating all the subclasses. + virtual const void* GetRawRepeatedField( + const Message& message, const FieldDescriptor* field, + FieldDescriptor::CppType cpptype, int ctype, + const Descriptor* message_type) const { + return MutableRawRepeatedField( + const_cast(&message), field, cpptype, ctype, message_type); + } + + // The following methods are used to implement (Mutable)RepeatedFieldRef. + // A Ref object will store a raw pointer to the repeated field data (obtained + // from RepeatedFieldData()) and a pointer to a Accessor (obtained from + // RepeatedFieldAccessor) which will be used to access the raw data. + // + // TODO(xiaofeng): Make these methods pure-virtual. + + // Returns a raw pointer to the repeated field + // + // "cpp_type" and "message_type" are decuded from the type parameter T passed + // to Get(Mutable)RepeatedFieldRef. If T is a generated message type, + // "message_type" should be set to its descriptor. Otherwise "message_type" + // should be set to NULL. Implementations of this method should check whether + // "cpp_type"/"message_type" is consistent with the actual type of the field. + // We use 1 routine rather than 2 (const vs mutable) because it is protected + // and it doesn't change the message. + virtual void* RepeatedFieldData( + Message* message, const FieldDescriptor* field, + FieldDescriptor::CppType cpp_type, + const Descriptor* message_type) const; + + // The returned pointer should point to a singleton instance which implements + // the RepeatedFieldAccessor interface. + virtual const internal::RepeatedFieldAccessor* RepeatedFieldAccessor( + const FieldDescriptor* field) const; + + private: + template + friend class RepeatedFieldRef; + template + friend class MutableRepeatedFieldRef; + friend class ::google::protobuf::python::MapReflectionFriend; + + // Special version for specialized implementations of string. We can't call + // MutableRawRepeatedField directly here because we don't have access to + // FieldOptions::* which are defined in descriptor.pb.h. Including that + // file here is not possible because it would cause a circular include cycle. + // We use 1 routine rather than 2 (const vs mutable) because it is private + // and mutable a repeated string field doesn't change the message. + void* MutableRawRepeatedString( + Message* message, const FieldDescriptor* field, bool is_string) const; + + friend class MapReflectionTester; + // TODO(jieluo) - make the map APIs pure virtual after updating + // all the subclasses. + // Returns true if key is in map. Returns false if key is not in map field. + virtual bool ContainsMapKey(const Message& /* message*/, + const FieldDescriptor* /* field */, + const MapKey& /* key */) const { + return false; + } + + // If key is in map field: Saves the value pointer to val and returns + // false. If key in not in map field: Insert the key into map, saves + // value pointer to val and retuns true. + virtual bool InsertOrLookupMapValue(Message* /* message */, + const FieldDescriptor* /* field */, + const MapKey& /* key */, + MapValueRef* /* val */) const { + return false; + } + + // Delete and returns true if key is in the map field. Returns false + // otherwise. + virtual bool DeleteMapValue(Message* /* mesage */, + const FieldDescriptor* /* field */, + const MapKey& /* key */) const { + return false; + } + + // Returns a MapIterator referring to the first element in the map field. + // If the map field is empty, this function returns the same as + // reflection::MapEnd. Mutation to the field may invalidate the iterator. + virtual MapIterator MapBegin( + Message* message, + const FieldDescriptor* field) const; + + // Returns a MapIterator referring to the theoretical element that would + // follow the last element in the map field. It does not point to any + // real element. Mutation to the field may invalidate the iterator. + virtual MapIterator MapEnd( + Message* message, + const FieldDescriptor* field) const; + + // Get the number of pair of a map field. The result may be + // different from FieldSize which can have duplicate keys. + virtual int MapSize(const Message& /* message */, + const FieldDescriptor* /* field */) const { + return 0; + } + + // Help method for MapIterator. + friend class MapIterator; + virtual internal::MapFieldBase* MapData( + Message* /* message */, const FieldDescriptor* /* field */) const { + return NULL; + } + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection); +}; + +// Abstract interface for a factory for message objects. +class LIBPROTOBUF_EXPORT MessageFactory { + public: + inline MessageFactory() {} + virtual ~MessageFactory(); + + // Given a Descriptor, gets or constructs the default (prototype) Message + // of that type. You can then call that message's New() method to construct + // a mutable message of that type. + // + // Calling this method twice with the same Descriptor returns the same + // object. The returned object remains property of the factory. Also, any + // objects created by calling the prototype's New() method share some data + // with the prototype, so these must be destroyed before the MessageFactory + // is destroyed. + // + // The given descriptor must outlive the returned message, and hence must + // outlive the MessageFactory. + // + // Some implementations do not support all types. GetPrototype() will + // return NULL if the descriptor passed in is not supported. + // + // This method may or may not be thread-safe depending on the implementation. + // Each implementation should document its own degree thread-safety. + virtual const Message* GetPrototype(const Descriptor* type) = 0; + + // Gets a MessageFactory which supports all generated, compiled-in messages. + // In other words, for any compiled-in type FooMessage, the following is true: + // MessageFactory::generated_factory()->GetPrototype( + // FooMessage::descriptor()) == FooMessage::default_instance() + // This factory supports all types which are found in + // DescriptorPool::generated_pool(). If given a descriptor from any other + // pool, GetPrototype() will return NULL. (You can also check if a + // descriptor is for a generated message by checking if + // descriptor->file()->pool() == DescriptorPool::generated_pool().) + // + // This factory is 100% thread-safe; calling GetPrototype() does not modify + // any shared data. + // + // This factory is a singleton. The caller must not delete the object. + static MessageFactory* generated_factory(); + + // For internal use only: Registers a .proto file at static initialization + // time, to be placed in generated_factory. The first time GetPrototype() + // is called with a descriptor from this file, |register_messages| will be + // called, with the file name as the parameter. It must call + // InternalRegisterGeneratedMessage() (below) to register each message type + // in the file. This strange mechanism is necessary because descriptors are + // built lazily, so we can't register types by their descriptor until we + // know that the descriptor exists. |filename| must be a permanent string. + static void InternalRegisterGeneratedFile( + const char* filename, void (*register_messages)(const string&)); + + // For internal use only: Registers a message type. Called only by the + // functions which are registered with InternalRegisterGeneratedFile(), + // above. + static void InternalRegisterGeneratedMessage(const Descriptor* descriptor, + const Message* prototype); + + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory); +}; + +#define DECLARE_GET_REPEATED_FIELD(TYPE) \ +template<> \ +LIBPROTOBUF_EXPORT \ +const RepeatedField& Reflection::GetRepeatedField( \ + const Message& message, const FieldDescriptor* field) const; \ + \ +template<> \ +LIBPROTOBUF_EXPORT \ +RepeatedField* Reflection::MutableRepeatedField( \ + Message* message, const FieldDescriptor* field) const; + +DECLARE_GET_REPEATED_FIELD(int32) +DECLARE_GET_REPEATED_FIELD(int64) +DECLARE_GET_REPEATED_FIELD(uint32) +DECLARE_GET_REPEATED_FIELD(uint64) +DECLARE_GET_REPEATED_FIELD(float) +DECLARE_GET_REPEATED_FIELD(double) +DECLARE_GET_REPEATED_FIELD(bool) + +#undef DECLARE_GET_REPEATED_FIELD + +// ============================================================================= +// Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide +// specializations for , and and handle +// everything else with the default template which will match any type having +// a method with signature "static const google::protobuf::Descriptor* descriptor()". +// Such a type presumably is a descendant of google::protobuf::Message. + +template<> +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField( + const Message& message, const FieldDescriptor* field) const { + return *static_cast* >( + MutableRawRepeatedString(const_cast(&message), field, true)); +} + +template<> +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField( + Message* message, const FieldDescriptor* field) const { + return static_cast* >( + MutableRawRepeatedString(message, field, true)); +} + + +// ----- + +template<> +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField( + const Message& message, const FieldDescriptor* field) const { + return *static_cast* >( + GetRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE, + -1, NULL)); +} + +template<> +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField( + Message* message, const FieldDescriptor* field) const { + return static_cast* >( + MutableRawRepeatedField(message, field, + FieldDescriptor::CPPTYPE_MESSAGE, -1, + NULL)); +} + +template +inline const RepeatedPtrField& Reflection::GetRepeatedPtrField( + const Message& message, const FieldDescriptor* field) const { + return *static_cast* >( + GetRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE, + -1, PB::default_instance().GetDescriptor())); +} + +template +inline RepeatedPtrField* Reflection::MutableRepeatedPtrField( + Message* message, const FieldDescriptor* field) const { + return static_cast* >( + MutableRawRepeatedField(message, field, + FieldDescriptor::CPPTYPE_MESSAGE, -1, + PB::default_instance().GetDescriptor())); +} +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MESSAGE_H__ diff --git a/thirdparty/linux/include/google/protobuf/message_lite.h b/thirdparty/linux/include/google/protobuf/message_lite.h new file mode 100644 index 0000000..2bdfe49 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/message_lite.h @@ -0,0 +1,296 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Authors: wink@google.com (Wink Saville), +// kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Defines MessageLite, the abstract interface implemented by all (lite +// and non-lite) protocol message objects. + +#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__ +#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__ + +#include + + +namespace google { +namespace protobuf { + class Arena; +namespace io { + class CodedInputStream; + class CodedOutputStream; + class ZeroCopyInputStream; + class ZeroCopyOutputStream; +} +namespace internal { + class WireFormatLite; +} + +// Interface to light weight protocol messages. +// +// This interface is implemented by all protocol message objects. Non-lite +// messages additionally implement the Message interface, which is a +// subclass of MessageLite. Use MessageLite instead when you only need +// the subset of features which it supports -- namely, nothing that uses +// descriptors or reflection. You can instruct the protocol compiler +// to generate classes which implement only MessageLite, not the full +// Message interface, by adding the following line to the .proto file: +// +// option optimize_for = LITE_RUNTIME; +// +// This is particularly useful on resource-constrained systems where +// the full protocol buffers runtime library is too big. +// +// Note that on non-constrained systems (e.g. servers) when you need +// to link in lots of protocol definitions, a better way to reduce +// total code footprint is to use optimize_for = CODE_SIZE. This +// will make the generated code smaller while still supporting all the +// same features (at the expense of speed). optimize_for = LITE_RUNTIME +// is best when you only have a small number of message types linked +// into your binary, in which case the size of the protocol buffers +// runtime itself is the biggest problem. +class LIBPROTOBUF_EXPORT MessageLite { + public: + inline MessageLite() {} + virtual ~MessageLite() {} + + // Basic Operations ------------------------------------------------ + + // Get the name of this message type, e.g. "foo.bar.BazProto". + virtual string GetTypeName() const = 0; + + // Construct a new instance of the same type. Ownership is passed to the + // caller. + virtual MessageLite* New() const = 0; + + // Construct a new instance on the arena. Ownership is passed to the caller + // if arena is a NULL. Default implementation for backwards compatibility. + virtual MessageLite* New(::google::protobuf::Arena* arena) const; + + // Get the arena, if any, associated with this message. Virtual method + // required for generic operations but most arena-related operations should + // use the GetArenaNoVirtual() generated-code method. Default implementation + // to reduce code size by avoiding the need for per-type implementations when + // types do not implement arena support. + virtual ::google::protobuf::Arena* GetArena() const { return NULL; } + + // Get a pointer that may be equal to this message's arena, or may not be. If + // the value returned by this method is equal to some arena pointer, then this + // message is on that arena; however, if this message is on some arena, this + // method may or may not return that arena's pointer. As a tradeoff, this + // method may be more efficient than GetArena(). The intent is to allow + // underlying representations that use e.g. tagged pointers to sometimes store + // the arena pointer directly, and sometimes in a more indirect way, and allow + // a fastpath comparison against the arena pointer when it's easy to obtain. + virtual void* GetMaybeArenaPointer() const { return GetArena(); } + + // Clear all fields of the message and set them to their default values. + // Clear() avoids freeing memory, assuming that any memory allocated + // to hold parts of the message will be needed again to hold the next + // message. If you actually want to free the memory used by a Message, + // you must delete it. + virtual void Clear() = 0; + + // Quickly check if all required fields have values set. + virtual bool IsInitialized() const = 0; + + // This is not implemented for Lite messages -- it just returns "(cannot + // determine missing fields for lite message)". However, it is implemented + // for full messages. See message.h. + virtual string InitializationErrorString() const; + + // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, + // results are undefined (probably crash). + virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0; + + // Parsing --------------------------------------------------------- + // Methods for parsing in protocol buffer format. Most of these are + // just simple wrappers around MergeFromCodedStream(). Clear() will be called + // before merging the input. + + // Fill the message with a protocol buffer parsed from the given input stream. + // Returns false on a read error or if the input is in the wrong format. A + // successful return does not indicate the entire input is consumed, ensure + // you call ConsumedEntireMessage() to check that if applicable. + bool ParseFromCodedStream(io::CodedInputStream* input); + // Like ParseFromCodedStream(), but accepts messages that are missing + // required fields. + bool ParsePartialFromCodedStream(io::CodedInputStream* input); + // Read a protocol buffer from the given zero-copy input stream. If + // successful, the entire input will be consumed. + bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); + // Like ParseFromZeroCopyStream(), but accepts messages that are missing + // required fields. + bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); + // Read a protocol buffer from the given zero-copy input stream, expecting + // the message to be exactly "size" bytes long. If successful, exactly + // this many bytes will have been consumed from the input. + bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); + // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are + // missing required fields. + bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, + int size); + // Parses a protocol buffer contained in a string. Returns true on success. + // This function takes a string in the (non-human-readable) binary wire + // format, matching the encoding output by MessageLite::SerializeToString(). + // If you'd like to convert a human-readable string into a protocol buffer + // object, see google::protobuf::TextFormat::ParseFromString(). + bool ParseFromString(const string& data); + // Like ParseFromString(), but accepts messages that are missing + // required fields. + bool ParsePartialFromString(const string& data); + // Parse a protocol buffer contained in an array of bytes. + bool ParseFromArray(const void* data, int size); + // Like ParseFromArray(), but accepts messages that are missing + // required fields. + bool ParsePartialFromArray(const void* data, int size); + + + // Reads a protocol buffer from the stream and merges it into this + // Message. Singular fields read from the input overwrite what is + // already in the Message and repeated fields are appended to those + // already present. + // + // It is the responsibility of the caller to call input->LastTagWas() + // (for groups) or input->ConsumedEntireMessage() (for non-groups) after + // this returns to verify that the message's end was delimited correctly. + // + // ParsefromCodedStream() is implemented as Clear() followed by + // MergeFromCodedStream(). + bool MergeFromCodedStream(io::CodedInputStream* input); + + // Like MergeFromCodedStream(), but succeeds even if required fields are + // missing in the input. + // + // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() + // followed by IsInitialized(). + virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0; + + + // Serialization --------------------------------------------------- + // Methods for serializing in protocol buffer format. Most of these + // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). + + // Write a protocol buffer of this message to the given output. Returns + // false on a write error. If the message is missing required fields, + // this may GOOGLE_CHECK-fail. + bool SerializeToCodedStream(io::CodedOutputStream* output) const; + // Like SerializeToCodedStream(), but allows missing required fields. + bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; + // Write the message to the given zero-copy output stream. All required + // fields must be set. + bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; + // Like SerializeToZeroCopyStream(), but allows missing required fields. + bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; + // Serialize the message and store it in the given string. All required + // fields must be set. + bool SerializeToString(string* output) const; + // Like SerializeToString(), but allows missing required fields. + bool SerializePartialToString(string* output) const; + // Serialize the message and store it in the given byte array. All required + // fields must be set. + bool SerializeToArray(void* data, int size) const; + // Like SerializeToArray(), but allows missing required fields. + bool SerializePartialToArray(void* data, int size) const; + + // Make a string encoding the message. Is equivalent to calling + // SerializeToString() on a string and using that. Returns the empty + // string if SerializeToString() would have returned an error. + // Note: If you intend to generate many such strings, you may + // reduce heap fragmentation by instead re-using the same string + // object with calls to SerializeToString(). + string SerializeAsString() const; + // Like SerializeAsString(), but allows missing required fields. + string SerializePartialAsString() const; + + // Like SerializeToString(), but appends to the data to the string's existing + // contents. All required fields must be set. + bool AppendToString(string* output) const; + // Like AppendToString(), but allows missing required fields. + bool AppendPartialToString(string* output) const; + + // Computes the serialized size of the message. This recursively calls + // ByteSize() on all embedded messages. If a subclass does not override + // this, it MUST override SetCachedSize(). + // + // ByteSize() is generally linear in the number of fields defined for the + // proto. + virtual int ByteSize() const = 0; + + // Serializes the message without recomputing the size. The message must + // not have changed since the last call to ByteSize(); if it has, the results + // are undefined. + virtual void SerializeWithCachedSizes( + io::CodedOutputStream* output) const = 0; + + // A version of SerializeWithCachedSizesToArray, below, that does + // not guarantee deterministic serialization. + virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const { + return InternalSerializeWithCachedSizesToArray(false, target); + } + + // Returns the result of the last call to ByteSize(). An embedded message's + // size is needed both to serialize it (because embedded messages are + // length-delimited) and to compute the outer message's size. Caching + // the size avoids computing it multiple times. + // + // ByteSize() does not automatically use the cached size when available + // because this would require invalidating it every time the message was + // modified, which would be too hard and expensive. (E.g. if a deeply-nested + // sub-message is changed, all of its parents' cached sizes would need to be + // invalidated, which is too much work for an otherwise inlined setter + // method.) + virtual int GetCachedSize() const = 0; + + // Functions below here are not part of the public interface. It isn't + // enforced, but they should be treated as private, and will be private + // at some future time. Unfortunately the implementation of the "friend" + // keyword in GCC is broken at the moment, but we expect it will be fixed. + + // Like SerializeWithCachedSizes, but writes directly to *target, returning + // a pointer to the byte immediately after the last byte written. "target" + // must point at a byte array of at least ByteSize() bytes. If deterministic + // is true then we use deterministic serialization, e.g., map keys are sorted. + // FOR INTERNAL USE ONLY! + virtual uint8* InternalSerializeWithCachedSizesToArray(bool deterministic, + uint8* target) const; + + private: + friend class internal::WireFormatLite; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__ diff --git a/thirdparty/linux/include/google/protobuf/metadata.h b/thirdparty/linux/include/google/protobuf/metadata.h new file mode 100644 index 0000000..fdee150 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/metadata.h @@ -0,0 +1,163 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This header file defines an internal class that encapsulates internal message +// metadata (Unknown-field set, Arena pointer, ...) and allows its +// representation to be made more space-efficient via various optimizations. +// +// Note that this is distinct from google::protobuf::Metadata, which encapsulates +// Descriptor and Reflection pointers. + +#ifndef GOOGLE_PROTOBUF_METADATA_H__ +#define GOOGLE_PROTOBUF_METADATA_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +// This is the representation for messages that support arena allocation. It +// uses a tagged pointer to either store the Arena pointer, if there are no +// unknown fields, or a pointer to a block of memory with both the Arena pointer +// and the UnknownFieldSet, if there are unknown fields. This optimization +// allows for "zero-overhead" storage of the Arena pointer, relative to the +// above baseline implementation. +// +// The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to +// indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container +// pointer. +class LIBPROTOBUF_EXPORT InternalMetadataWithArena { + public: + InternalMetadataWithArena() : ptr_(NULL) {} + explicit InternalMetadataWithArena(Arena* arena) + : ptr_ (arena) {} + + ~InternalMetadataWithArena() { + if (have_unknown_fields() && arena() == NULL) { + delete PtrValue(); + } + ptr_ = NULL; + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE const UnknownFieldSet& unknown_fields() const { + if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { + return PtrValue()->unknown_fields_; + } else { + return *UnknownFieldSet::default_instance(); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE UnknownFieldSet* mutable_unknown_fields() { + if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) { + return &PtrValue()->unknown_fields_; + } else { + return mutable_unknown_fields_slow(); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const { + if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { + return PtrValue()->arena_; + } else { + return PtrValue(); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const { + return PtrTag() == kTagContainer; + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(InternalMetadataWithArena* other) { + // Semantics here are that we swap only the unknown fields, not the arena + // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to + // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in + // different states (direct arena pointer vs. container with UFS) so we + // cannot simply swap ptr_ and then restore the arena pointers. We reuse + // UFS's swap implementation instead. + if (have_unknown_fields() || other->have_unknown_fields()) { + mutable_unknown_fields()->Swap(other->mutable_unknown_fields()); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const { + return ptr_; + } + + private: + void* ptr_; + + // Tagged pointer implementation. + enum { + // ptr_ is an Arena*. + kTagArena = 0, + // ptr_ is a Container*. + kTagContainer = 1, + }; + static const intptr_t kPtrTagMask = 1; + static const intptr_t kPtrValueMask = ~kPtrTagMask; + + // Accessors for pointer tag and pointer value. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const { + return reinterpret_cast(ptr_) & kPtrTagMask; + } + + template T* PtrValue() const { + return reinterpret_cast( + reinterpret_cast(ptr_) & kPtrValueMask); + } + + // If ptr_'s tag is kTagContainer, it points to an instance of this struct. + struct Container { + UnknownFieldSet unknown_fields_; + Arena* arena_; + }; + + GOOGLE_ATTRIBUTE_NOINLINE UnknownFieldSet* mutable_unknown_fields_slow() { + Arena* my_arena = arena(); + Container* container = Arena::Create(my_arena); + ptr_ = reinterpret_cast( + reinterpret_cast(container) | kTagContainer); + container->arena_ = my_arena; + return &(container->unknown_fields_); + } +}; + +// Temporary compatibility typedef. Remove once this is released in components +// and upb CL is submitted. +typedef InternalMetadataWithArena InternalMetadata; + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_METADATA_H__ diff --git a/thirdparty/linux/include/google/protobuf/reflection.h b/thirdparty/linux/include/google/protobuf/reflection.h new file mode 100644 index 0000000..2391f45 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/reflection.h @@ -0,0 +1,600 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This header defines the RepeatedFieldRef class template used to access +// repeated fields with protobuf reflection API. +#ifndef GOOGLE_PROTOBUF_REFLECTION_H__ +#define GOOGLE_PROTOBUF_REFLECTION_H__ + +#include +#ifndef _SHARED_PTR_H +#include +#endif + +#include +#include + +namespace google { +namespace protobuf { +namespace internal { +template +struct RefTypeTraits; +} // namespace internal + +template +RepeatedFieldRef Reflection::GetRepeatedFieldRef( + const Message& message, const FieldDescriptor* field) const { + return RepeatedFieldRef(message, field); +} + +template +MutableRepeatedFieldRef Reflection::GetMutableRepeatedFieldRef( + Message* message, const FieldDescriptor* field) const { + return MutableRepeatedFieldRef(message, field); +} + +// RepeatedFieldRef definition for non-message types. +template +class RepeatedFieldRef< + T, typename internal::enable_if::value>::type> { + typedef typename internal::RefTypeTraits::iterator IteratorType; + typedef typename internal::RefTypeTraits::AccessorType AccessorType; + + public: + bool empty() const { + return accessor_->IsEmpty(data_); + } + int size() const { + return accessor_->Size(data_); + } + T Get(int index) const { + return accessor_->template Get(data_, index); + } + + typedef IteratorType iterator; + typedef IteratorType const_iterator; + iterator begin() const { + return iterator(data_, accessor_, true); + } + iterator end() const { + return iterator(data_, accessor_, false); + } + + private: + friend class Reflection; + RepeatedFieldRef( + const Message& message, + const FieldDescriptor* field) { + const Reflection* reflection = message.GetReflection(); + data_ = reflection->RepeatedFieldData( + const_cast(&message), field, + internal::RefTypeTraits::cpp_type, NULL); + accessor_ = reflection->RepeatedFieldAccessor(field); + } + + const void* data_; + const AccessorType* accessor_; +}; + +// MutableRepeatedFieldRef definition for non-message types. +template +class MutableRepeatedFieldRef< + T, typename internal::enable_if::value>::type> { + typedef typename internal::RefTypeTraits::AccessorType AccessorType; + + public: + bool empty() const { + return accessor_->IsEmpty(data_); + } + int size() const { + return accessor_->Size(data_); + } + T Get(int index) const { + return accessor_->template Get(data_, index); + } + + void Set(int index, const T& value) const { + accessor_->template Set(data_, index, value); + } + void Add(const T& value) const { + accessor_->template Add(data_, value); + } + void RemoveLast() const { + accessor_->RemoveLast(data_); + } + void SwapElements(int index1, int index2) const { + accessor_->SwapElements(data_, index1, index2); + } + void Clear() const { + accessor_->Clear(data_); + } + + void Swap(const MutableRepeatedFieldRef& other) const { + accessor_->Swap(data_, other.accessor_, other.data_); + } + + template + void MergeFrom(const Container& container) const { + typedef typename Container::const_iterator Iterator; + for (Iterator it = container.begin(); it != container.end(); ++it) { + Add(*it); + } + } + template + void CopyFrom(const Container& container) const { + Clear(); + MergeFrom(container); + } + + private: + friend class Reflection; + MutableRepeatedFieldRef( + Message* message, + const FieldDescriptor* field) { + const Reflection* reflection = message->GetReflection(); + data_ = reflection->RepeatedFieldData( + message, field, internal::RefTypeTraits::cpp_type, NULL); + accessor_ = reflection->RepeatedFieldAccessor(field); + } + + void* data_; + const AccessorType* accessor_; +}; + +// RepeatedFieldRef definition for message types. +template +class RepeatedFieldRef< + T, typename internal::enable_if::value>::type> { + typedef typename internal::RefTypeTraits::iterator IteratorType; + typedef typename internal::RefTypeTraits::AccessorType AccessorType; + + public: + bool empty() const { + return accessor_->IsEmpty(data_); + } + int size() const { + return accessor_->Size(data_); + } + // This method returns a reference to the underlying message object if it + // exists. If a message object doesn't exist (e.g., data stored in serialized + // form), scratch_space will be filled with the data and a reference to it + // will be returned. + // + // Example: + // RepeatedFieldRef h = ... + // unique_ptr scratch_space(h.NewMessage()); + // const Message& item = h.Get(index, scratch_space.get()); + const T& Get(int index, T* scratch_space) const { + return *static_cast(accessor_->Get(data_, index, scratch_space)); + } + // Create a new message of the same type as the messages stored in this + // repeated field. Caller takes ownership of the returned object. + T* NewMessage() const { + return static_cast(default_instance_->New()); + } + + typedef IteratorType iterator; + typedef IteratorType const_iterator; + iterator begin() const { + return iterator(data_, accessor_, true, NewMessage()); + } + iterator end() const { + return iterator(data_, accessor_, false, NewMessage()); + } + + private: + friend class Reflection; + RepeatedFieldRef( + const Message& message, + const FieldDescriptor* field) { + const Reflection* reflection = message.GetReflection(); + data_ = reflection->RepeatedFieldData( + const_cast(&message), field, + internal::RefTypeTraits::cpp_type, + internal::RefTypeTraits::GetMessageFieldDescriptor()); + accessor_ = reflection->RepeatedFieldAccessor(field); + default_instance_ = + reflection->GetMessageFactory()->GetPrototype(field->message_type()); + } + + const void* data_; + const AccessorType* accessor_; + const Message* default_instance_; +}; + +// MutableRepeatedFieldRef definition for message types. +template +class MutableRepeatedFieldRef< + T, typename internal::enable_if::value>::type> { + typedef typename internal::RefTypeTraits::AccessorType AccessorType; + + public: + bool empty() const { + return accessor_->IsEmpty(data_); + } + int size() const { + return accessor_->Size(data_); + } + // See comments for RepeatedFieldRef::Get() + const T& Get(int index, T* scratch_space) const { + return *static_cast(accessor_->Get(data_, index, scratch_space)); + } + // Create a new message of the same type as the messages stored in this + // repeated field. Caller takes ownership of the returned object. + T* NewMessage() const { + return static_cast(default_instance_->New()); + } + + void Set(int index, const T& value) const { + accessor_->Set(data_, index, &value); + } + void Add(const T& value) const { + accessor_->Add(data_, &value); + } + void RemoveLast() const { + accessor_->RemoveLast(data_); + } + void SwapElements(int index1, int index2) const { + accessor_->SwapElements(data_, index1, index2); + } + void Clear() const { + accessor_->Clear(data_); + } + + void Swap(const MutableRepeatedFieldRef& other) const { + accessor_->Swap(data_, other.accessor_, other.data_); + } + + template + void MergeFrom(const Container& container) const { + typedef typename Container::const_iterator Iterator; + for (Iterator it = container.begin(); it != container.end(); ++it) { + Add(*it); + } + } + template + void CopyFrom(const Container& container) const { + Clear(); + MergeFrom(container); + } + + private: + friend class Reflection; + MutableRepeatedFieldRef( + Message* message, + const FieldDescriptor* field) { + const Reflection* reflection = message->GetReflection(); + data_ = reflection->RepeatedFieldData( + message, field, internal::RefTypeTraits::cpp_type, + internal::RefTypeTraits::GetMessageFieldDescriptor()); + accessor_ = reflection->RepeatedFieldAccessor(field); + default_instance_ = + reflection->GetMessageFactory()->GetPrototype(field->message_type()); + } + + void* data_; + const AccessorType* accessor_; + const Message* default_instance_; +}; + +namespace internal { +// Interfaces used to implement reflection RepeatedFieldRef API. +// Reflection::GetRepeatedAccessor() should return a pointer to an singleton +// object that implements the below interface. +// +// This interface passes/returns values using void pointers. The actual type +// of the value depends on the field's cpp_type. Following is a mapping from +// cpp_type to the type that should be used in this interface: +// +// field->cpp_type() T Actual type of void* +// CPPTYPE_INT32 int32 int32 +// CPPTYPE_UINT32 uint32 uint32 +// CPPTYPE_INT64 int64 int64 +// CPPTYPE_UINT64 uint64 uint64 +// CPPTYPE_DOUBLE double double +// CPPTYPE_FLOAT float float +// CPPTYPE_BOOL bool bool +// CPPTYPE_ENUM generated enum type int32 +// CPPTYPE_STRING string string +// CPPTYPE_MESSAGE generated message type google::protobuf::Message +// or google::protobuf::Message +// +// Note that for enums we use int32 in the interface. +// +// You can map from T to the actual type using RefTypeTraits: +// typedef RefTypeTraits::AccessorValueType ActualType; +class LIBPROTOBUF_EXPORT RepeatedFieldAccessor { + public: + // Typedefs for clarity. + typedef void Field; + typedef void Value; + typedef void Iterator; + + virtual ~RepeatedFieldAccessor(); + virtual bool IsEmpty(const Field* data) const = 0; + virtual int Size(const Field* data) const = 0; + // Depends on the underlying representation of the repeated field, this + // method can return a pointer to the underlying object if such an object + // exists, or fill the data into scratch_space and return scratch_space. + // Callers of this method must ensure scratch_space is a valid pointer + // to a mutable object of the correct type. + virtual const Value* Get( + const Field* data, int index, Value* scratch_space) const = 0; + + virtual void Clear(Field* data) const = 0; + virtual void Set(Field* data, int index, const Value* value) const = 0; + virtual void Add(Field* data, const Value* value) const = 0; + virtual void RemoveLast(Field* data) const = 0; + virtual void SwapElements(Field* data, int index1, int index2) const = 0; + virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator, + Field* other_data) const = 0; + + // Create an iterator that points at the beginning of the repeated field. + virtual Iterator* BeginIterator(const Field* data) const = 0; + // Create an iterator that points at the end of the repeated field. + virtual Iterator* EndIterator(const Field* data) const = 0; + // Make a copy of an iterator and return the new copy. + virtual Iterator* CopyIterator(const Field* data, + const Iterator* iterator) const = 0; + // Move an iterator to point to the next element. + virtual Iterator* AdvanceIterator(const Field* data, + Iterator* iterator) const = 0; + // Compare whether two iterators point to the same element. + virtual bool EqualsIterator(const Field* data, const Iterator* a, + const Iterator* b) const = 0; + // Delete an iterator created by BeginIterator(), EndIterator() and + // CopyIterator(). + virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0; + // Like Get() but for iterators. + virtual const Value* GetIteratorValue(const Field* data, + const Iterator* iterator, + Value* scratch_space) const = 0; + + // Templated methods that make using this interface easier for non-message + // types. + template + T Get(const Field* data, int index) const { + typedef typename RefTypeTraits::AccessorValueType ActualType; + ActualType scratch_space; + return static_cast( + *reinterpret_cast( + Get(data, index, static_cast(&scratch_space)))); + } + + template + void Set(Field* data, int index, const ValueType& value) const { + typedef typename RefTypeTraits::AccessorValueType ActualType; + // In this RepeatedFieldAccessor interface we pass/return data using + // raw pointers. Type of the data these raw pointers point to should + // be ActualType. Here we have a ValueType object and want a ActualType + // pointer. We can't cast a ValueType pointer to an ActualType pointer + // directly because their type might be different (for enums ValueType + // may be a generated enum type while ActualType is int32). To be safe + // we make a copy to get a temporary ActualType object and use it. + ActualType tmp = static_cast(value); + Set(data, index, static_cast(&tmp)); + } + + template + void Add(Field* data, const ValueType& value) const { + typedef typename RefTypeTraits::AccessorValueType ActualType; + // In this RepeatedFieldAccessor interface we pass/return data using + // raw pointers. Type of the data these raw pointers point to should + // be ActualType. Here we have a ValueType object and want a ActualType + // pointer. We can't cast a ValueType pointer to an ActualType pointer + // directly because their type might be different (for enums ValueType + // may be a generated enum type while ActualType is int32). To be safe + // we make a copy to get a temporary ActualType object and use it. + ActualType tmp = static_cast(value); + Add(data, static_cast(&tmp)); + } +}; + +// Implement (Mutable)RepeatedFieldRef::iterator +template +class RepeatedFieldRefIterator + : public std::iterator { + typedef typename RefTypeTraits::AccessorValueType AccessorValueType; + typedef typename RefTypeTraits::IteratorValueType IteratorValueType; + typedef typename RefTypeTraits::IteratorPointerType IteratorPointerType; + + public: + // Constructor for non-message fields. + RepeatedFieldRefIterator(const void* data, + const RepeatedFieldAccessor* accessor, + bool begin) + : data_(data), accessor_(accessor), + iterator_(begin ? accessor->BeginIterator(data) : + accessor->EndIterator(data)), + scratch_space_(new AccessorValueType) { + } + // Constructor for message fields. + RepeatedFieldRefIterator(const void* data, + const RepeatedFieldAccessor* accessor, + bool begin, + AccessorValueType* scratch_space) + : data_(data), accessor_(accessor), + iterator_(begin ? accessor->BeginIterator(data) : + accessor->EndIterator(data)), + scratch_space_(scratch_space) { + } + ~RepeatedFieldRefIterator() { + accessor_->DeleteIterator(data_, iterator_); + } + RepeatedFieldRefIterator operator++(int) { + RepeatedFieldRefIterator tmp(*this); + iterator_ = accessor_->AdvanceIterator(data_, iterator_); + return tmp; + } + RepeatedFieldRefIterator& operator++() { + iterator_ = accessor_->AdvanceIterator(data_, iterator_); + return *this; + } + IteratorValueType operator*() const { + return static_cast( + *static_cast( + accessor_->GetIteratorValue( + data_, iterator_, scratch_space_.get()))); + } + IteratorPointerType operator->() const { + return static_cast( + accessor_->GetIteratorValue( + data_, iterator_, scratch_space_.get())); + } + bool operator!=(const RepeatedFieldRefIterator& other) const { + assert(data_ == other.data_); + assert(accessor_ == other.accessor_); + return !accessor_->EqualsIterator(data_, iterator_, other.iterator_); + } + bool operator==(const RepeatedFieldRefIterator& other) const { + return !this->operator!=(other); + } + + RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other) + : data_(other.data_), accessor_(other.accessor_), + iterator_(accessor_->CopyIterator(data_, other.iterator_)) { + } + RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) { + if (this != &other) { + accessor_->DeleteIterator(data_, iterator_); + data_ = other.data_; + accessor_ = other.accessor_; + iterator_ = accessor_->CopyIterator(data_, other.iterator_); + } + return *this; + } + + protected: + const void* data_; + const RepeatedFieldAccessor* accessor_; + void* iterator_; + google::protobuf::scoped_ptr scratch_space_; +}; + +// TypeTraits that maps the type parameter T of RepeatedFieldRef or +// MutableRepeatedFieldRef to corresponding iterator type, +// RepeatedFieldAccessor type, etc. +template +struct PrimitiveTraits { + static const bool is_primitive = false; +}; +#define DEFINE_PRIMITIVE(TYPE, type) \ + template<> struct PrimitiveTraits { \ + static const bool is_primitive = true; \ + static const FieldDescriptor::CppType cpp_type = \ + FieldDescriptor::CPPTYPE_ ## TYPE; \ + }; +DEFINE_PRIMITIVE(INT32, int32) +DEFINE_PRIMITIVE(UINT32, uint32) +DEFINE_PRIMITIVE(INT64, int64) +DEFINE_PRIMITIVE(UINT64, uint64) +DEFINE_PRIMITIVE(FLOAT, float) +DEFINE_PRIMITIVE(DOUBLE, double) +DEFINE_PRIMITIVE(BOOL, bool) +#undef DEFINE_PRIMITIVE + +template +struct RefTypeTraits< + T, typename internal::enable_if::is_primitive>::type> { + typedef RepeatedFieldRefIterator iterator; + typedef RepeatedFieldAccessor AccessorType; + typedef T AccessorValueType; + typedef T IteratorValueType; + typedef T* IteratorPointerType; + static const FieldDescriptor::CppType cpp_type = + PrimitiveTraits::cpp_type; + static const Descriptor* GetMessageFieldDescriptor() { + return NULL; + } +}; + +template +struct RefTypeTraits< + T, typename internal::enable_if::value>::type> { + typedef RepeatedFieldRefIterator iterator; + typedef RepeatedFieldAccessor AccessorType; + // We use int32 for repeated enums in RepeatedFieldAccessor. + typedef int32 AccessorValueType; + typedef T IteratorValueType; + typedef int32* IteratorPointerType; + static const FieldDescriptor::CppType cpp_type = + FieldDescriptor::CPPTYPE_ENUM; + static const Descriptor* GetMessageFieldDescriptor() { + return NULL; + } +}; + +template +struct RefTypeTraits< + T, typename internal::enable_if< ::google::protobuf::internal::is_same::value>::type> { + typedef RepeatedFieldRefIterator iterator; + typedef RepeatedFieldAccessor AccessorType; + typedef string AccessorValueType; + typedef string IteratorValueType; + typedef string* IteratorPointerType; + static const FieldDescriptor::CppType cpp_type = + FieldDescriptor::CPPTYPE_STRING; + static const Descriptor* GetMessageFieldDescriptor() { + return NULL; + } +}; + +template +struct MessageDescriptorGetter { + static const Descriptor* get() { + return T::default_instance().GetDescriptor(); + } +}; +template<> +struct MessageDescriptorGetter { + static const Descriptor* get() { + return NULL; + } +}; + +template +struct RefTypeTraits< + T, typename internal::enable_if::value>::type> { + typedef RepeatedFieldRefIterator iterator; + typedef RepeatedFieldAccessor AccessorType; + typedef Message AccessorValueType; + typedef const T& IteratorValueType; + typedef const T* IteratorPointerType; + static const FieldDescriptor::CppType cpp_type = + FieldDescriptor::CPPTYPE_MESSAGE; + static const Descriptor* GetMessageFieldDescriptor() { + return MessageDescriptorGetter::get(); + } +}; +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_REFLECTION_H__ diff --git a/thirdparty/linux/include/google/protobuf/reflection_ops.h b/thirdparty/linux/include/google/protobuf/reflection_ops.h new file mode 100644 index 0000000..4775911 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/reflection_ops.h @@ -0,0 +1,81 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__ +#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +// Basic operations that can be performed using reflection. +// These can be used as a cheap way to implement the corresponding +// methods of the Message interface, though they are likely to be +// slower than implementations tailored for the specific message type. +// +// This class should stay limited to operations needed to implement +// the Message interface. +// +// This class is really a namespace that contains only static methods. +class LIBPROTOBUF_EXPORT ReflectionOps { + public: + static void Copy(const Message& from, Message* to); + static void Merge(const Message& from, Message* to); + static void Clear(Message* message); + static bool IsInitialized(const Message& message); + static void DiscardUnknownFields(Message* message); + + // Finds all unset required fields in the message and adds their full + // paths (e.g. "foo.bar[5].baz") to *names. "prefix" will be attached to + // the front of each name. + static void FindInitializationErrors(const Message& message, + const string& prefix, + vector* errors); + + private: + // All methods are static. No need to construct. + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps); +}; + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__ diff --git a/thirdparty/linux/include/google/protobuf/repeated_field.h b/thirdparty/linux/include/google/protobuf/repeated_field.h new file mode 100644 index 0000000..bc56755 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/repeated_field.h @@ -0,0 +1,2481 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// RepeatedField and RepeatedPtrField are used by generated protocol message +// classes to manipulate repeated fields. These classes are very similar to +// STL's vector, but include a number of optimizations found to be useful +// specifically in the case of Protocol Buffers. RepeatedPtrField is +// particularly different from STL vector as it manages ownership of the +// pointers that it contains. +// +// Typically, clients should not need to access RepeatedField objects directly, +// but should instead use the accessor functions generated automatically by the +// protocol compiler. + +#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__ +#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__ + +#ifdef _MSC_VER +// This is required for min/max on VS2013 only. +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace google { + +namespace upb { +namespace google_opensource { +class GMR_Handlers; +} // namespace google_opensource +} // namespace upb + +namespace protobuf { + +class Message; + +namespace internal { + +static const int kMinRepeatedFieldAllocationSize = 4; + +// A utility function for logging that doesn't need any template types. +void LogIndexOutOfBounds(int index, int size); + +template +inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) { + return std::distance(begin, end); +} + +template +inline int CalculateReserve(Iter /*begin*/, Iter /*end*/, + std::input_iterator_tag /*unused*/) { + return -1; +} + +template +inline int CalculateReserve(Iter begin, Iter end) { + typedef typename std::iterator_traits::iterator_category Category; + return CalculateReserve(begin, end, Category()); +} +} // namespace internal + + +// RepeatedField is used to represent repeated fields of a primitive type (in +// other words, everything except strings and nested Messages). Most users will +// not ever use a RepeatedField directly; they will use the get-by-index, +// set-by-index, and add accessors that are generated for all repeated fields. +template +class RepeatedField { + public: + RepeatedField(); + explicit RepeatedField(Arena* arena); + RepeatedField(const RepeatedField& other); + template + RepeatedField(Iter begin, const Iter& end); + ~RepeatedField(); + + RepeatedField& operator=(const RepeatedField& other); + + bool empty() const; + int size() const; + + const Element& Get(int index) const; + Element* Mutable(int index); + void Set(int index, const Element& value); + void Add(const Element& value); + Element* Add(); + // Remove the last element in the array. + void RemoveLast(); + + // Extract elements with indices in "[start .. start+num-1]". + // Copy them into "elements[0 .. num-1]" if "elements" is not NULL. + // Caution: implementation also moves elements with indices [start+num ..]. + // Calling this routine inside a loop can cause quadratic behavior. + void ExtractSubrange(int start, int num, Element* elements); + + void Clear(); + void MergeFrom(const RepeatedField& other); + void CopyFrom(const RepeatedField& other); + + // Reserve space to expand the field to at least the given size. If the + // array is grown, it will always be at least doubled in size. + void Reserve(int new_size); + + // Resize the RepeatedField to a new, smaller size. This is O(1). + void Truncate(int new_size); + + void AddAlreadyReserved(const Element& value); + Element* AddAlreadyReserved(); + int Capacity() const; + + // Like STL resize. Uses value to fill appended elements. + // Like Truncate() if new_size <= size(), otherwise this is + // O(new_size - size()). + void Resize(int new_size, const Element& value); + + // Gets the underlying array. This pointer is possibly invalidated by + // any add or remove operation. + Element* mutable_data(); + const Element* data() const; + + // Swap entire contents with "other". If they are separate arenas then, copies + // data between each other. + void Swap(RepeatedField* other); + + // Swap entire contents with "other". Should be called only if the caller can + // guarantee that both repeated fields are on the same arena or are on the + // heap. Swapping between different arenas is disallowed and caught by a + // GOOGLE_DCHECK (see API docs for details). + void UnsafeArenaSwap(RepeatedField* other); + + // Swap two elements. + void SwapElements(int index1, int index2); + + // STL-like iterator support + typedef Element* iterator; + typedef const Element* const_iterator; + typedef Element value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef int size_type; + typedef ptrdiff_t difference_type; + + iterator begin(); + const_iterator begin() const; + const_iterator cbegin() const; + iterator end(); + const_iterator end() const; + const_iterator cend() const; + + // Reverse iterator support + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + reverse_iterator rbegin() { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // Returns the number of bytes used by the repeated field, excluding + // sizeof(*this) + int SpaceUsedExcludingSelf() const; + + // Removes the element referenced by position. + // + // Returns an iterator to the element immediately following the removed + // element. + // + // Invalidates all iterators at or after the removed element, including end(). + iterator erase(const_iterator position); + + // Removes the elements in the range [first, last). + // + // Returns an iterator to the element immediately following the removed range. + // + // Invalidates all iterators at or after the removed range, including end(). + iterator erase(const_iterator first, const_iterator last); + + // Get the Arena on which this RepeatedField stores its elements. + ::google::protobuf::Arena* GetArena() const { + return GetArenaNoVirtual(); + } + + private: + static const int kInitialSize = 0; + // A note on the representation here (see also comment below for + // RepeatedPtrFieldBase's struct Rep): + // + // We maintain the same sizeof(RepeatedField) as before we added arena support + // so that we do not degrade performance by bloating memory usage. Directly + // adding an arena_ element to RepeatedField is quite costly. By using + // indirection in this way, we keep the same size when the RepeatedField is + // empty (common case), and add only an 8-byte header to the elements array + // when non-empty. We make sure to place the size fields directly in the + // RepeatedField class to avoid costly cache misses due to the indirection. + int current_size_; + int total_size_; + struct Rep { + Arena* arena; + Element elements[1]; + }; + // We can not use sizeof(Rep) - sizeof(Element) due to the trailing padding on + // the struct. We can not use sizeof(Arena*) as well because there might be + // a "gap" after the field arena and before the field elements (e.g., when + // Element is double and pointer is 32bit). + static const size_t kRepHeaderSize; + // Contains arena ptr and the elements array. We also keep the invariant that + // if rep_ is NULL, then arena is NULL. + Rep* rep_; + + friend class Arena; + typedef void InternalArenaConstructable_; + + // Move the contents of |from| into |to|, possibly clobbering |from| in the + // process. For primitive types this is just a memcpy(), but it could be + // specialized for non-primitive types to, say, swap each element instead. + void MoveArray(Element* to, Element* from, int size); + + // Copy the elements of |from| into |to|. + void CopyArray(Element* to, const Element* from, int size); + + inline void InternalSwap(RepeatedField* other); + + // Internal helper expected by Arena methods. + inline Arena* GetArenaNoVirtual() const { + return (rep_ == NULL) ? NULL : rep_->arena; + } + + // Internal helper to delete all elements and deallocate the storage. + // If Element has a trivial destructor (for example, if it's a fundamental + // type, like int32), the loop will be removed by the optimizer. + void InternalDeallocate(Rep* rep, int size) { + if (rep != NULL) { + Element* e = &rep->elements[0]; + Element* limit = &rep->elements[size]; + for (; e < limit; e++) { + e->Element::~Element(); + } + if (rep->arena == NULL) { + delete[] reinterpret_cast(rep); + } + } + } +}; + +template +const size_t RepeatedField::kRepHeaderSize = + reinterpret_cast(&reinterpret_cast(16)->elements[0]) - 16; + +namespace internal { +template class RepeatedPtrIterator; +template class RepeatedPtrOverPtrsIterator; +} // namespace internal + +namespace internal { + +// This is a helper template to copy an array of elements effeciently when they +// have a trivial copy constructor, and correctly otherwise. This really +// shouldn't be necessary, but our compiler doesn't optimize std::copy very +// effectively. +template ::value> +struct ElementCopier { + void operator()(Element* to, const Element* from, int array_size); +}; + +} // namespace internal + +namespace internal { + +// type-traits helper for RepeatedPtrFieldBase: we only want to invoke +// arena-related "copy if on different arena" behavior if the necessary methods +// exist on the contained type. In particular, we rely on MergeFrom() existing +// as a general proxy for the fact that a copy will work, and we also provide a +// specific override for string*. +template +struct TypeImplementsMergeBehavior { + typedef char HasMerge; + typedef long HasNoMerge; + + // We accept either of: + // - void MergeFrom(const T& other) + // - bool MergeFrom(const T& other) + // + // We mangle these names a bit to avoid compatibility issues in 'unclean' + // include environments that may have, e.g., "#define test ..." (yes, this + // exists). + template + struct CheckType; + template static HasMerge Check( + CheckType*); + template static HasMerge Check( + CheckType*); + template static HasNoMerge Check(...); + + // Resovles to either google::protobuf::internal::true_type or google::protobuf::internal::false_type. + typedef google::protobuf::internal::integral_constant(0)) == sizeof(HasMerge))> type; +}; + +template<> +struct TypeImplementsMergeBehavior< ::std::string > { + typedef google::protobuf::internal::true_type type; +}; + +// This is the common base class for RepeatedPtrFields. It deals only in void* +// pointers. Users should not use this interface directly. +// +// The methods of this interface correspond to the methods of RepeatedPtrField, +// but may have a template argument called TypeHandler. Its signature is: +// class TypeHandler { +// public: +// typedef MyType Type; +// static Type* New(); +// static void Delete(Type*); +// static void Clear(Type*); +// static void Merge(const Type& from, Type* to); +// +// // Only needs to be implemented if SpaceUsedExcludingSelf() is called. +// static int SpaceUsed(const Type&); +// }; +class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { + protected: + // The reflection implementation needs to call protected methods directly, + // reinterpreting pointers as being to Message instead of a specific Message + // subclass. + friend class GeneratedMessageReflection; + + // ExtensionSet stores repeated message extensions as + // RepeatedPtrField, but non-lite ExtensionSets need to + // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf() + // reinterpreting MessageLite as Message. ExtensionSet also needs to make + // use of AddFromCleared(), which is not part of the public interface. + friend class ExtensionSet; + + // The MapFieldBase implementation needs to call protected methods directly, + // reinterpreting pointers as being to Message instead of a specific Message + // subclass. + friend class MapFieldBase; + + // To parse directly into a proto2 generated class, the upb class GMR_Handlers + // needs to be able to modify a RepeatedPtrFieldBase directly. + friend class upb::google_opensource::GMR_Handlers; + + RepeatedPtrFieldBase(); + explicit RepeatedPtrFieldBase(::google::protobuf::Arena* arena); + ~RepeatedPtrFieldBase() {} + + // Must be called from destructor. + template + void Destroy(); + + bool empty() const; + int size() const; + + template + const typename TypeHandler::Type& Get(int index) const; + template + typename TypeHandler::Type* Mutable(int index); + template + void Delete(int index); + template + typename TypeHandler::Type* Add(typename TypeHandler::Type* prototype = NULL); + + template + void RemoveLast(); + template + void Clear(); + template + void MergeFrom(const RepeatedPtrFieldBase& other); + template + void CopyFrom(const RepeatedPtrFieldBase& other); + + void CloseGap(int start, int num); + + void Reserve(int new_size); + + int Capacity() const; + + // Used for constructing iterators. + void* const* raw_data() const; + void** raw_mutable_data() const; + + template + typename TypeHandler::Type** mutable_data(); + template + const typename TypeHandler::Type* const* data() const; + + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(RepeatedPtrFieldBase* other); + + void SwapElements(int index1, int index2); + + template + int SpaceUsedExcludingSelf() const; + + + // Advanced memory management -------------------------------------- + + // Like Add(), but if there are no cleared objects to use, returns NULL. + template + typename TypeHandler::Type* AddFromCleared(); + + template + void AddAllocated(typename TypeHandler::Type* value) { + typename TypeImplementsMergeBehavior::type t; + AddAllocatedInternal(value, t); + } + + template + void UnsafeArenaAddAllocated(typename TypeHandler::Type* value); + + template + typename TypeHandler::Type* ReleaseLast() { + typename TypeImplementsMergeBehavior::type t; + return ReleaseLastInternal(t); + } + + // Releases last element and returns it, but does not do out-of-arena copy. + // And just returns the raw pointer to the contained element in the arena. + template + typename TypeHandler::Type* UnsafeArenaReleaseLast(); + + int ClearedCount() const; + template + void AddCleared(typename TypeHandler::Type* value); + template + typename TypeHandler::Type* ReleaseCleared(); + + protected: + inline void InternalSwap(RepeatedPtrFieldBase* other); + + template + void AddAllocatedInternal(typename TypeHandler::Type* value, + google::protobuf::internal::true_type); + template + void AddAllocatedInternal(typename TypeHandler::Type* value, + google::protobuf::internal::false_type); + + template GOOGLE_ATTRIBUTE_NOINLINE + void AddAllocatedSlowWithCopy(typename TypeHandler::Type* value, + Arena* value_arena, + Arena* my_arena); + template GOOGLE_ATTRIBUTE_NOINLINE + void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value); + + template + typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::true_type); + template + typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::false_type); + + template GOOGLE_ATTRIBUTE_NOINLINE + void SwapFallback(RepeatedPtrFieldBase* other); + + inline Arena* GetArenaNoVirtual() const { + return arena_; + } + + private: + static const int kInitialSize = 0; + // A few notes on internal representation: + // + // We use an indirected approach, with struct Rep, to keep + // sizeof(RepeatedPtrFieldBase) equivalent to what it was before arena support + // was added, namely, 3 8-byte machine words on x86-64. An instance of Rep is + // allocated only when the repeated field is non-empty, and it is a + // dynamically-sized struct (the header is directly followed by elements[]). + // We place arena_ and current_size_ directly in the object to avoid cache + // misses due to the indirection, because these fields are checked frequently. + // Placing all fields directly in the RepeatedPtrFieldBase instance costs + // significant performance for memory-sensitive workloads. + Arena* arena_; + int current_size_; + int total_size_; + struct Rep { + int allocated_size; + void* elements[1]; + }; + static const size_t kRepHeaderSize = sizeof(Rep) - sizeof(void*); + // Contains arena ptr and the elements array. We also keep the invariant that + // if rep_ is NULL, then arena is NULL. + Rep* rep_; + + template + static inline typename TypeHandler::Type* cast(void* element) { + return reinterpret_cast(element); + } + template + static inline const typename TypeHandler::Type* cast(const void* element) { + return reinterpret_cast(element); + } + + // Non-templated inner function to avoid code duplication. Takes a function + // pointer to the type-specific (templated) inner allocate/merge loop. + void MergeFromInternal( + const RepeatedPtrFieldBase& other, + void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int)); + + template + void MergeFromInnerLoop( + void** our_elems, void** other_elems, int length, int already_allocated); + + // Internal helper: extend array space if necessary to contain |extend_amount| + // more elements, and return a pointer to the element immediately following + // the old list of elements. This interface factors out common behavior from + // Reserve() and MergeFrom() to reduce code size. |extend_amount| must be > 0. + void** InternalExtend(int extend_amount); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase); +}; + +template +class GenericTypeHandler { + public: + typedef GenericType Type; + static inline GenericType* New(Arena* arena) { + return ::google::protobuf::Arena::CreateMaybeMessage( + arena, static_cast(0)); + } + // We force NewFromPrototype() to be non-inline to reduce code size: + // else, several other methods get inlined copies of message types' + // constructors. + GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype( + const GenericType* prototype, ::google::protobuf::Arena* arena = NULL); + static inline void Delete(GenericType* value, Arena* arena) { + if (arena == NULL) { + delete value; + } + } + static inline ::google::protobuf::Arena* GetArena(GenericType* value) { + return ::google::protobuf::Arena::GetArena(value); + } + static inline void* GetMaybeArenaPointer(GenericType* value) { + return ::google::protobuf::Arena::GetArena(value); + } + + static inline void Clear(GenericType* value) { value->Clear(); } + GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from, + GenericType* to); + static inline int SpaceUsed(const GenericType& value) { + return value.SpaceUsed(); + } + static inline const Type& default_instance() { + return Type::default_instance(); + } +}; + +template +GenericType* GenericTypeHandler::NewFromPrototype( + const GenericType* /* prototype */, ::google::protobuf::Arena* arena) { + return New(arena); +} +template +void GenericTypeHandler::Merge(const GenericType& from, + GenericType* to) { + to->MergeFrom(from); +} + +// NewFromPrototype() and Merge() cannot be defined here; if they're declared +// inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLINE +// above, and if not, compilation will result in multiple definitions. These +// are therefore declared as specializations here and defined in +// message_lite.cc. +template<> +MessageLite* GenericTypeHandler::NewFromPrototype( + const MessageLite* prototype, google::protobuf::Arena* arena); +template<> +inline google::protobuf::Arena* GenericTypeHandler::GetArena( + MessageLite* value) { + return value->GetArena(); +} +template<> +inline void* GenericTypeHandler::GetMaybeArenaPointer( + MessageLite* value) { + return value->GetMaybeArenaPointer(); +} +template <> +void GenericTypeHandler::Merge(const MessageLite& from, + MessageLite* to); +template<> +inline void GenericTypeHandler::Clear(string* value) { + value->clear(); +} +template<> +void GenericTypeHandler::Merge(const string& from, + string* to); + +// Declarations of the specialization as we cannot define them here, as the +// header that defines ProtocolMessage depends on types defined in this header. +#define DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(TypeName) \ + template<> \ + TypeName* GenericTypeHandler::NewFromPrototype( \ + const TypeName* prototype, google::protobuf::Arena* arena); \ + template<> \ + google::protobuf::Arena* GenericTypeHandler::GetArena( \ + TypeName* value); \ + template<> \ + void* GenericTypeHandler::GetMaybeArenaPointer( \ + TypeName* value); + +// Message specialization bodies defined in message.cc. This split is necessary +// to allow proto2-lite (which includes this header) to be independent of +// Message. +DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(Message) + + +#undef DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES + +template <> +inline const MessageLite& GenericTypeHandler::default_instance() { + // Yes, the behavior of the code is undefined, but this function is only + // called when we're already deep into the world of undefined, because the + // caller called Get(index) out of bounds. + MessageLite* null = NULL; + return *null; +} + +template <> +inline const Message& GenericTypeHandler::default_instance() { + // Yes, the behavior of the code is undefined, but this function is only + // called when we're already deep into the world of undefined, because the + // caller called Get(index) out of bounds. + Message* null = NULL; + return *null; +} + + +// HACK: If a class is declared as DLL-exported in MSVC, it insists on +// generating copies of all its methods -- even inline ones -- to include +// in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which +// isn't in the lite library, therefore the lite library cannot link if +// StringTypeHandler is exported. So, we factor out StringTypeHandlerBase, +// export that, then make StringTypeHandler be a subclass which is NOT +// exported. +// TODO(kenton): Now that StringSpaceUsedExcludingSelf() is in the lite +// library, this can be cleaned up. +class LIBPROTOBUF_EXPORT StringTypeHandlerBase { + public: + typedef string Type; + + static inline string* New(Arena* arena) { + return Arena::Create(arena); + } + static inline string* NewFromPrototype(const string*, + ::google::protobuf::Arena* arena) { + return New(arena); + } + static inline ::google::protobuf::Arena* GetArena(string*) { + return NULL; + } + static inline void* GetMaybeArenaPointer(string* /* value */) { + return NULL; + } + static inline void Delete(string* value, Arena* arena) { + if (arena == NULL) { + delete value; + } + } + static inline void Clear(string* value) { value->clear(); } + static inline void Merge(const string& from, string* to) { *to = from; } + static inline const Type& default_instance() { + return ::google::protobuf::internal::GetEmptyString(); + } +}; + +class StringTypeHandler : public StringTypeHandlerBase { + public: + static int SpaceUsed(const string& value) { + return static_cast(sizeof(value)) + StringSpaceUsedExcludingSelf(value); + } +}; + + +} // namespace internal + +// RepeatedPtrField is like RepeatedField, but used for repeated strings or +// Messages. +template +class RepeatedPtrField : public internal::RepeatedPtrFieldBase { + public: + RepeatedPtrField(); + explicit RepeatedPtrField(::google::protobuf::Arena* arena); + + RepeatedPtrField(const RepeatedPtrField& other); + template + RepeatedPtrField(Iter begin, const Iter& end); + ~RepeatedPtrField(); + + RepeatedPtrField& operator=(const RepeatedPtrField& other); + + bool empty() const; + int size() const; + + const Element& Get(int index) const; + Element* Mutable(int index); + Element* Add(); + + // Remove the last element in the array. + // Ownership of the element is retained by the array. + void RemoveLast(); + + // Delete elements with indices in the range [start .. start+num-1]. + // Caution: implementation moves all elements with indices [start+num .. ]. + // Calling this routine inside a loop can cause quadratic behavior. + void DeleteSubrange(int start, int num); + + void Clear(); + void MergeFrom(const RepeatedPtrField& other); + void CopyFrom(const RepeatedPtrField& other); + + // Reserve space to expand the field to at least the given size. This only + // resizes the pointer array; it doesn't allocate any objects. If the + // array is grown, it will always be at least doubled in size. + void Reserve(int new_size); + + int Capacity() const; + + // Gets the underlying array. This pointer is possibly invalidated by + // any add or remove operation. + Element** mutable_data(); + const Element* const* data() const; + + // Swap entire contents with "other". If they are on separate arenas, then + // copies data. + void Swap(RepeatedPtrField* other); + + // Swap entire contents with "other". Caller should guarantee that either both + // fields are on the same arena or both are on the heap. Swapping between + // different arenas with this function is disallowed and is caught via + // GOOGLE_DCHECK. + void UnsafeArenaSwap(RepeatedPtrField* other); + + // Swap two elements. + void SwapElements(int index1, int index2); + + // STL-like iterator support + typedef internal::RepeatedPtrIterator iterator; + typedef internal::RepeatedPtrIterator const_iterator; + typedef Element value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef int size_type; + typedef ptrdiff_t difference_type; + + iterator begin(); + const_iterator begin() const; + const_iterator cbegin() const; + iterator end(); + const_iterator end() const; + const_iterator cend() const; + + // Reverse iterator support + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + reverse_iterator rbegin() { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // Custom STL-like iterator that iterates over and returns the underlying + // pointers to Element rather than Element itself. + typedef internal::RepeatedPtrOverPtrsIterator + pointer_iterator; + typedef internal::RepeatedPtrOverPtrsIterator + const_pointer_iterator; + pointer_iterator pointer_begin(); + const_pointer_iterator pointer_begin() const; + pointer_iterator pointer_end(); + const_pointer_iterator pointer_end() const; + + // Returns (an estimate of) the number of bytes used by the repeated field, + // excluding sizeof(*this). + int SpaceUsedExcludingSelf() const; + + // Advanced memory management -------------------------------------- + // When hardcore memory management becomes necessary -- as it sometimes + // does here at Google -- the following methods may be useful. + + // Add an already-allocated object, passing ownership to the + // RepeatedPtrField. + // + // Note that some special behavior occurs with respect to arenas: + // + // (i) if this field holds submessages, the new submessage will be copied if + // the original is in an arena and this RepeatedPtrField is either in a + // different arena, or on the heap. + // (ii) if this field holds strings, the passed-in string *must* be + // heap-allocated, not arena-allocated. There is no way to dynamically check + // this at runtime, so User Beware. + void AddAllocated(Element* value); + + // Remove the last element and return it, passing ownership to the caller. + // Requires: size() > 0 + // + // If this RepeatedPtrField is on an arena, an object copy is required to pass + // ownership back to the user (for compatible semantics). Use + // UnsafeArenaReleaseLast() if this behavior is undesired. + Element* ReleaseLast(); + + // Add an already-allocated object, skipping arena-ownership checks. The user + // must guarantee that the given object is in the same arena as this + // RepeatedPtrField. + // It is also useful in legacy code that uses temporary ownership to avoid + // copies. Example: + // RepeatedPtrField temp_field; + // temp_field.AddAllocated(new T); + // ... // Do something with temp_field + // temp_field.ExtractSubrange(0, temp_field.size(), NULL); + // If you put temp_field on the arena this fails, because the ownership + // transfers to the arena at the "AddAllocated" call and is not released + // anymore causing a double delete. UnsafeArenaAddAllocated prevents this. + void UnsafeArenaAddAllocated(Element* value); + + // Remove the last element and return it. Works only when operating on an + // arena. The returned pointer is to the original object in the arena, hence + // has the arena's lifetime. + // Requires: current_size_ > 0 + Element* UnsafeArenaReleaseLast(); + + // Extract elements with indices in the range "[start .. start+num-1]". + // The caller assumes ownership of the extracted elements and is responsible + // for deleting them when they are no longer needed. + // If "elements" is non-NULL, then pointers to the extracted elements + // are stored in "elements[0 .. num-1]" for the convenience of the caller. + // If "elements" is NULL, then the caller must use some other mechanism + // to perform any further operations (like deletion) on these elements. + // Caution: implementation also moves elements with indices [start+num ..]. + // Calling this routine inside a loop can cause quadratic behavior. + // + // Memory copying behavior is identical to ReleaseLast(), described above: if + // this RepeatedPtrField is on an arena, an object copy is performed for each + // returned element, so that all returned element pointers are to + // heap-allocated copies. If this copy is not desired, the user should call + // UnsafeArenaExtractSubrange(). + void ExtractSubrange(int start, int num, Element** elements); + + // Identical to ExtractSubrange() described above, except that when this + // repeated field is on an arena, no object copies are performed. Instead, the + // raw object pointers are returned. Thus, if on an arena, the returned + // objects must not be freed, because they will not be heap-allocated objects. + void UnsafeArenaExtractSubrange(int start, int num, Element** elements); + + // When elements are removed by calls to RemoveLast() or Clear(), they + // are not actually freed. Instead, they are cleared and kept so that + // they can be reused later. This can save lots of CPU time when + // repeatedly reusing a protocol message for similar purposes. + // + // Hardcore programs may choose to manipulate these cleared objects + // to better optimize memory management using the following routines. + + // Get the number of cleared objects that are currently being kept + // around for reuse. + int ClearedCount() const; + // Add an element to the pool of cleared objects, passing ownership to + // the RepeatedPtrField. The element must be cleared prior to calling + // this method. + // + // This method cannot be called when the repeated field is on an arena or when + // |value| is; both cases will trigger a GOOGLE_DCHECK-failure. + void AddCleared(Element* value); + // Remove a single element from the cleared pool and return it, passing + // ownership to the caller. The element is guaranteed to be cleared. + // Requires: ClearedCount() > 0 + // + // + // This method cannot be called when the repeated field is on an arena; doing + // so will trigger a GOOGLE_DCHECK-failure. + Element* ReleaseCleared(); + + // Removes the element referenced by position. + // + // Returns an iterator to the element immediately following the removed + // element. + // + // Invalidates all iterators at or after the removed element, including end(). + iterator erase(const_iterator position); + + // Removes the elements in the range [first, last). + // + // Returns an iterator to the element immediately following the removed range. + // + // Invalidates all iterators at or after the removed range, including end(). + iterator erase(const_iterator first, const_iterator last); + + // Gets the arena on which this RepeatedPtrField stores its elements. + ::google::protobuf::Arena* GetArena() const { + return GetArenaNoVirtual(); + } + + protected: + // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only + // subclass it in one place as a hack for compatibility with proto1. The + // subclass needs to know about TypeHandler in order to call protected + // methods on RepeatedPtrFieldBase. + class TypeHandler; + + // Internal arena accessor expected by helpers in Arena. + inline Arena* GetArenaNoVirtual() const; + + private: + // Implementations for ExtractSubrange(). The copying behavior must be + // included only if the type supports the necessary operations (e.g., + // MergeFrom()), so we must resolve this at compile time. ExtractSubrange() + // uses SFINAE to choose one of the below implementations. + void ExtractSubrangeInternal(int start, int num, Element** elements, + google::protobuf::internal::true_type); + void ExtractSubrangeInternal(int start, int num, Element** elements, + google::protobuf::internal::false_type); + + friend class Arena; + typedef void InternalArenaConstructable_; + +}; + +// implementation ==================================================== + +template +inline RepeatedField::RepeatedField() + : current_size_(0), + total_size_(0), + rep_(NULL) { +} + +template +inline RepeatedField::RepeatedField(Arena* arena) + : current_size_(0), + total_size_(0), + rep_(NULL) { + // In case arena is NULL, then we do not create rep_, as code has an invariant + // `rep_ == NULL then arena == NULL`. + if (arena != NULL) { + rep_ = reinterpret_cast( + ::google::protobuf::Arena::CreateArray(arena, kRepHeaderSize)); + rep_->arena = arena; + } +} + +template +inline RepeatedField::RepeatedField(const RepeatedField& other) + : current_size_(0), + total_size_(0), + rep_(NULL) { + CopyFrom(other); +} + +template +template +RepeatedField::RepeatedField(Iter begin, const Iter& end) + : current_size_(0), + total_size_(0), + rep_(NULL) { + int reserve = internal::CalculateReserve(begin, end); + if (reserve != -1) { + Reserve(reserve); + for (; begin != end; ++begin) { + AddAlreadyReserved(*begin); + } + } else { + for (; begin != end; ++begin) { + Add(*begin); + } + } +} + +template +RepeatedField::~RepeatedField() { + // See explanation in Reserve(): we need to invoke destructors here for the + // case that Element has a non-trivial destructor. + InternalDeallocate(rep_, total_size_); +} + +template +inline RepeatedField& +RepeatedField::operator=(const RepeatedField& other) { + if (this != &other) + CopyFrom(other); + return *this; +} + +template +inline bool RepeatedField::empty() const { + return current_size_ == 0; +} + +template +inline int RepeatedField::size() const { + return current_size_; +} + +template +inline int RepeatedField::Capacity() const { + return total_size_; +} + +template +inline void RepeatedField::AddAlreadyReserved(const Element& value) { + GOOGLE_DCHECK_LT(current_size_, total_size_); + rep_->elements[current_size_++] = value; +} + +template +inline Element* RepeatedField::AddAlreadyReserved() { + GOOGLE_DCHECK_LT(current_size_, total_size_); + return &rep_->elements[current_size_++]; +} + +template +inline void RepeatedField::Resize(int new_size, const Element& value) { + GOOGLE_DCHECK_GE(new_size, 0); + if (new_size > current_size_) { + Reserve(new_size); + std::fill(&rep_->elements[current_size_], + &rep_->elements[new_size], value); + } + current_size_ = new_size; +} + +template +inline const Element& RepeatedField::Get(int index) const { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + return rep_->elements[index]; +} + +template +inline Element* RepeatedField::Mutable(int index) { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + return &rep_->elements[index]; +} + +template +inline void RepeatedField::Set(int index, const Element& value) { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + rep_->elements[index] = value; +} + +template +inline void RepeatedField::Add(const Element& value) { + if (current_size_ == total_size_) Reserve(total_size_ + 1); + rep_->elements[current_size_++] = value; +} + +template +inline Element* RepeatedField::Add() { + if (current_size_ == total_size_) Reserve(total_size_ + 1); + return &rep_->elements[current_size_++]; +} + +template +inline void RepeatedField::RemoveLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + current_size_--; +} + +template +void RepeatedField::ExtractSubrange( + int start, int num, Element* elements) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, this->current_size_); + + // Save the values of the removed elements if requested. + if (elements != NULL) { + for (int i = 0; i < num; ++i) + elements[i] = this->Get(i + start); + } + + // Slide remaining elements down to fill the gap. + if (num > 0) { + for (int i = start + num; i < this->current_size_; ++i) + this->Set(i - num, this->Get(i)); + this->Truncate(this->current_size_ - num); + } +} + +template +inline void RepeatedField::Clear() { + current_size_ = 0; +} + +template +inline void RepeatedField::MergeFrom(const RepeatedField& other) { + GOOGLE_CHECK_NE(&other, this); + if (other.current_size_ != 0) { + Reserve(current_size_ + other.current_size_); + CopyArray(rep_->elements + current_size_, + other.rep_->elements, other.current_size_); + current_size_ += other.current_size_; + } +} + +template +inline void RepeatedField::CopyFrom(const RepeatedField& other) { + if (&other == this) return; + Clear(); + MergeFrom(other); +} + +template +inline typename RepeatedField::iterator RepeatedField::erase( + const_iterator position) { + return erase(position, position + 1); +} + +template +inline typename RepeatedField::iterator RepeatedField::erase( + const_iterator first, const_iterator last) { + size_type first_offset = first - cbegin(); + if (first != last) { + Truncate(std::copy(last, cend(), begin() + first_offset) - cbegin()); + } + return begin() + first_offset; +} + +template +inline Element* RepeatedField::mutable_data() { + return rep_ ? rep_->elements : NULL; +} + +template +inline const Element* RepeatedField::data() const { + return rep_ ? rep_->elements : NULL; +} + + +template +inline void RepeatedField::InternalSwap(RepeatedField* other) { + std::swap(rep_, other->rep_); + std::swap(current_size_, other->current_size_); + std::swap(total_size_, other->total_size_); +} + +template +void RepeatedField::Swap(RepeatedField* other) { + if (this == other) return; + if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + InternalSwap(other); + } else { + RepeatedField temp(other->GetArenaNoVirtual()); + temp.MergeFrom(*this); + CopyFrom(*other); + other->UnsafeArenaSwap(&temp); + } +} + +template +void RepeatedField::UnsafeArenaSwap(RepeatedField* other) { + if (this == other) return; + GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + InternalSwap(other); +} + +template +void RepeatedField::SwapElements(int index1, int index2) { + using std::swap; // enable ADL with fallback + swap(rep_->elements[index1], rep_->elements[index2]); +} + +template +inline typename RepeatedField::iterator +RepeatedField::begin() { + return rep_ ? rep_->elements : NULL; +} +template +inline typename RepeatedField::const_iterator +RepeatedField::begin() const { + return rep_ ? rep_->elements : NULL; +} +template +inline typename RepeatedField::const_iterator +RepeatedField::cbegin() const { + return rep_ ? rep_->elements : NULL; +} +template +inline typename RepeatedField::iterator +RepeatedField::end() { + return rep_ ? rep_->elements + current_size_ : NULL; +} +template +inline typename RepeatedField::const_iterator +RepeatedField::end() const { + return rep_ ? rep_->elements + current_size_ : NULL; +} +template +inline typename RepeatedField::const_iterator +RepeatedField::cend() const { + return rep_ ? rep_->elements + current_size_ : NULL; +} + +template +inline int RepeatedField::SpaceUsedExcludingSelf() const { + return rep_ ? + (total_size_ * sizeof(Element) + kRepHeaderSize) : 0; +} + +// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant +// amount of code bloat. +template +void RepeatedField::Reserve(int new_size) { + if (total_size_ >= new_size) return; + Rep* old_rep = rep_; + Arena* arena = GetArenaNoVirtual(); + new_size = std::max(google::protobuf::internal::kMinRepeatedFieldAllocationSize, + std::max(total_size_ * 2, new_size)); + GOOGLE_CHECK_LE(static_cast(new_size), + (std::numeric_limits::max() - kRepHeaderSize) / + sizeof(Element)) + << "Requested size is too large to fit into size_t."; + if (arena == NULL) { + rep_ = reinterpret_cast( + new char[kRepHeaderSize + sizeof(Element) * new_size]); + } else { + rep_ = reinterpret_cast( + ::google::protobuf::Arena::CreateArray(arena, + kRepHeaderSize + sizeof(Element) * new_size)); + } + rep_->arena = arena; + int old_total_size = total_size_; + total_size_ = new_size; + // Invoke placement-new on newly allocated elements. We shouldn't have to do + // this, since Element is supposed to be POD, but a previous version of this + // code allocated storage with "new Element[size]" and some code uses + // RepeatedField with non-POD types, relying on constructor invocation. If + // Element has a trivial constructor (e.g., int32), gcc (tested with -O2) + // completely removes this loop because the loop body is empty, so this has no + // effect unless its side-effects are required for correctness. + // Note that we do this before MoveArray() below because Element's copy + // assignment implementation will want an initialized instance first. + Element* e = &rep_->elements[0]; + Element* limit = &rep_->elements[total_size_]; + for (; e < limit; e++) { + new (e) Element(); + } + if (current_size_ > 0) { + MoveArray(rep_->elements, old_rep->elements, current_size_); + } + + // Likewise, we need to invoke destructors on the old array. + InternalDeallocate(old_rep, old_total_size); + +} + +template +inline void RepeatedField::Truncate(int new_size) { + GOOGLE_DCHECK_LE(new_size, current_size_); + if (current_size_ > 0) { + current_size_ = new_size; + } +} + +template +inline void RepeatedField::MoveArray( + Element* to, Element* from, int array_size) { + CopyArray(to, from, array_size); +} + +template +inline void RepeatedField::CopyArray( + Element* to, const Element* from, int array_size) { + internal::ElementCopier()(to, from, array_size); +} + +namespace internal { + +template +void ElementCopier::operator()( + Element* to, const Element* from, int array_size) { + std::copy(from, from + array_size, to); +} + +template +struct ElementCopier { + void operator()(Element* to, const Element* from, int array_size) { + memcpy(to, from, array_size * sizeof(Element)); + } +}; + +} // namespace internal + + +// ------------------------------------------------------------------- + +namespace internal { + +inline RepeatedPtrFieldBase::RepeatedPtrFieldBase() + : arena_(NULL), + current_size_(0), + total_size_(0), + rep_(NULL) { +} + +inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* arena) + : arena_(arena), + current_size_(0), + total_size_(0), + rep_(NULL) { +} + +template +void RepeatedPtrFieldBase::Destroy() { + if (rep_ != NULL && arena_ == NULL) { + int n = rep_->allocated_size; + void* const* elements = rep_->elements; + for (int i = 0; i < n; i++) { + TypeHandler::Delete(cast(elements[i]), NULL); + } + delete[] reinterpret_cast(rep_); + } + rep_ = NULL; +} + +template +inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { + if (other->GetArenaNoVirtual() == GetArenaNoVirtual()) { + InternalSwap(other); + } else { + SwapFallback(other); + } +} + +template +void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) { + GOOGLE_DCHECK(other->GetArenaNoVirtual() != GetArenaNoVirtual()); + + // Copy semantics in this case. We try to improve efficiency by placing the + // temporary on |other|'s arena so that messages are copied cross-arena only + // once, not twice. + RepeatedPtrFieldBase temp(other->GetArenaNoVirtual()); + temp.MergeFrom(*this); + this->Clear(); + this->MergeFrom(*other); + other->Clear(); + other->InternalSwap(&temp); + temp.Destroy(); // Frees rep_ if `other` had no arena. +} + +inline bool RepeatedPtrFieldBase::empty() const { + return current_size_ == 0; +} + +inline int RepeatedPtrFieldBase::size() const { + return current_size_; +} + +template +inline const typename TypeHandler::Type& +RepeatedPtrFieldBase::Get(int index) const { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + return *cast(rep_->elements[index]); +} + + +template +inline typename TypeHandler::Type* +RepeatedPtrFieldBase::Mutable(int index) { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + return cast(rep_->elements[index]); +} + +template +inline void RepeatedPtrFieldBase::Delete(int index) { + GOOGLE_DCHECK_GE(index, 0); + GOOGLE_DCHECK_LT(index, current_size_); + TypeHandler::Delete(cast(rep_->elements[index]), arena_); +} + +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add( + typename TypeHandler::Type* prototype) { + if (rep_ != NULL && current_size_ < rep_->allocated_size) { + return cast(rep_->elements[current_size_++]); + } + if (!rep_ || rep_->allocated_size == total_size_) { + Reserve(total_size_ + 1); + } + ++rep_->allocated_size; + typename TypeHandler::Type* result = + TypeHandler::NewFromPrototype(prototype, arena_); + rep_->elements[current_size_++] = result; + return result; +} + +template +inline void RepeatedPtrFieldBase::RemoveLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + TypeHandler::Clear(cast(rep_->elements[--current_size_])); +} + +template +void RepeatedPtrFieldBase::Clear() { + const int n = current_size_; + GOOGLE_DCHECK_GE(n, 0); + if (n > 0) { + void* const* elements = rep_->elements; + int i = 0; + do { + TypeHandler::Clear(cast(elements[i++])); + } while (i < n); + current_size_ = 0; + } +} + +// To avoid unnecessary code duplication and reduce binary size, we use a +// layered approach to implementing MergeFrom(). The toplevel method is +// templated, so we get a small thunk per concrete message type in the binary. +// This calls a shared implementation with most of the logic, passing a function +// pointer to another type-specific piece of code that calls the object-allocate +// and merge handlers. +template +inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) { + GOOGLE_DCHECK_NE(&other, this); + if (other.current_size_ == 0) return; + MergeFromInternal( + other, &RepeatedPtrFieldBase::MergeFromInnerLoop); +} + +inline void RepeatedPtrFieldBase::MergeFromInternal( + const RepeatedPtrFieldBase& other, + void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int)) { + // Note: wrapper has already guaranteed that other.rep_ != NULL here. + int other_size = other.current_size_; + void** other_elements = other.rep_->elements; + void** new_elements = InternalExtend(other_size); + int allocated_elems = rep_->allocated_size - current_size_; + (this->*inner_loop)(new_elements, other_elements, + other_size, allocated_elems); + current_size_ += other_size; + if (rep_->allocated_size < current_size_) { + rep_->allocated_size = current_size_; + } +} + +// Merges other_elems to our_elems. +template +void RepeatedPtrFieldBase::MergeFromInnerLoop( + void** our_elems, void** other_elems, int length, int already_allocated) { + // Split into two loops, over ranges [0, allocated) and [allocated, length), + // to avoid a branch within the loop. + for (int i = 0; i < already_allocated && i < length; i++) { + // Already allocated: use existing element. + typename TypeHandler::Type* other_elem = + reinterpret_cast(other_elems[i]); + typename TypeHandler::Type* new_elem = + reinterpret_cast(our_elems[i]); + TypeHandler::Merge(*other_elem, new_elem); + } + Arena* arena = GetArenaNoVirtual(); + for (int i = already_allocated; i < length; i++) { + // Not allocated: alloc a new element first, then merge it. + typename TypeHandler::Type* other_elem = + reinterpret_cast(other_elems[i]); + typename TypeHandler::Type* new_elem = + TypeHandler::NewFromPrototype(other_elem, arena); + TypeHandler::Merge(*other_elem, new_elem); + our_elems[i] = new_elem; + } +} + +template +inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) { + if (&other == this) return; + RepeatedPtrFieldBase::Clear(); + RepeatedPtrFieldBase::MergeFrom(other); +} + +inline int RepeatedPtrFieldBase::Capacity() const { + return total_size_; +} + +inline void* const* RepeatedPtrFieldBase::raw_data() const { + return rep_ ? rep_->elements : NULL; +} + +inline void** RepeatedPtrFieldBase::raw_mutable_data() const { + return rep_ ? const_cast(rep_->elements) : NULL; +} + +template +inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() { + // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this + // method entirely. + return reinterpret_cast(raw_mutable_data()); +} + +template +inline const typename TypeHandler::Type* const* +RepeatedPtrFieldBase::data() const { + // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this + // method entirely. + return reinterpret_cast(raw_data()); +} + +inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) { + using std::swap; // enable ADL with fallback + swap(rep_->elements[index1], rep_->elements[index2]); +} + +template +inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const { + int allocated_bytes = total_size_ * sizeof(void*); + if (rep_ != NULL) { + for (int i = 0; i < rep_->allocated_size; ++i) { + allocated_bytes += TypeHandler::SpaceUsed( + *cast(rep_->elements[i])); + } + allocated_bytes += kRepHeaderSize; + } + return allocated_bytes; +} + +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() { + if (rep_ != NULL && current_size_ < rep_->allocated_size) { + return cast(rep_->elements[current_size_++]); + } else { + return NULL; + } +} + +// AddAllocated version that implements arena-safe copying behavior. +template +void RepeatedPtrFieldBase::AddAllocatedInternal( + typename TypeHandler::Type* value, + google::protobuf::internal::true_type) { + Arena* element_arena = reinterpret_cast( + TypeHandler::GetMaybeArenaPointer(value)); + Arena* arena = GetArenaNoVirtual(); + if (arena == element_arena && rep_ && + rep_->allocated_size < total_size_) { + // Fast path: underlying arena representation (tagged pointer) is equal to + // our arena pointer, and we can add to array without resizing it (at least + // one slot that is not allocated). + void** elems = rep_->elements; + if (current_size_ < rep_->allocated_size) { + // Make space at [current] by moving first allocated element to end of + // allocated list. + elems[rep_->allocated_size] = elems[current_size_]; + } + elems[current_size_] = value; + current_size_ = current_size_ + 1; + rep_->allocated_size = rep_->allocated_size + 1; + return; + } else { + AddAllocatedSlowWithCopy( + value, TypeHandler::GetArena(value), arena); + } +} + +// Slowpath handles all cases, copying if necessary. +template +void RepeatedPtrFieldBase::AddAllocatedSlowWithCopy( + // Pass value_arena and my_arena to avoid duplicate virtual call (value) or + // load (mine). + typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena) { + // Ensure that either the value is in the same arena, or if not, we do the + // appropriate thing: Own() it (if it's on heap and we're in an arena) or copy + // it to our arena/heap (otherwise). + if (my_arena != NULL && value_arena == NULL) { + my_arena->Own(value); + } else if (my_arena != value_arena) { + typename TypeHandler::Type* new_value = + TypeHandler::NewFromPrototype(value, my_arena); + TypeHandler::Merge(*value, new_value); + TypeHandler::Delete(value, value_arena); + value = new_value; + } + + UnsafeArenaAddAllocated(value); +} + +// AddAllocated version that does not implement arena-safe copying behavior. +template +void RepeatedPtrFieldBase::AddAllocatedInternal( + typename TypeHandler::Type* value, + google::protobuf::internal::false_type) { + if (rep_ && rep_->allocated_size < total_size_) { + // Fast path: underlying arena representation (tagged pointer) is equal to + // our arena pointer, and we can add to array without resizing it (at least + // one slot that is not allocated). + void** elems = rep_->elements; + if (current_size_ < rep_->allocated_size) { + // Make space at [current] by moving first allocated element to end of + // allocated list. + elems[rep_->allocated_size] = elems[current_size_]; + } + elems[current_size_] = value; + current_size_ = current_size_ + 1; + ++rep_->allocated_size; + return; + } else { + UnsafeArenaAddAllocated(value); + } +} + +template +void RepeatedPtrFieldBase::UnsafeArenaAddAllocated( + typename TypeHandler::Type* value) { + // Make room for the new pointer. + if (!rep_ || current_size_ == total_size_) { + // The array is completely full with no cleared objects, so grow it. + Reserve(total_size_ + 1); + ++rep_->allocated_size; + } else if (rep_->allocated_size == total_size_) { + // There is no more space in the pointer array because it contains some + // cleared objects awaiting reuse. We don't want to grow the array in this + // case because otherwise a loop calling AddAllocated() followed by Clear() + // would leak memory. + TypeHandler::Delete( + cast(rep_->elements[current_size_]), arena_); + } else if (current_size_ < rep_->allocated_size) { + // We have some cleared objects. We don't care about their order, so we + // can just move the first one to the end to make space. + rep_->elements[rep_->allocated_size] = rep_->elements[current_size_]; + ++rep_->allocated_size; + } else { + // There are no cleared objects. + ++rep_->allocated_size; + } + + rep_->elements[current_size_++] = value; +} + +// ReleaseLast() for types that implement merge/copy behavior. +template +inline typename TypeHandler::Type* +RepeatedPtrFieldBase::ReleaseLastInternal(google::protobuf::internal::true_type) { + // First, release an element. + typename TypeHandler::Type* result = UnsafeArenaReleaseLast(); + // Now perform a copy if we're on an arena. + Arena* arena = GetArenaNoVirtual(); + if (arena == NULL) { + return result; + } else { + typename TypeHandler::Type* new_result = + TypeHandler::NewFromPrototype(result, NULL); + TypeHandler::Merge(*result, new_result); + return new_result; + } +} + +// ReleaseLast() for types that *do not* implement merge/copy behavior -- this +// is the same as UnsafeArenaReleaseLast(). Note that we GOOGLE_DCHECK-fail if we're on +// an arena, since the user really should implement the copy operation in this +// case. +template +inline typename TypeHandler::Type* +RepeatedPtrFieldBase::ReleaseLastInternal(google::protobuf::internal::false_type) { + GOOGLE_DCHECK(GetArenaNoVirtual() == NULL) + << "ReleaseLast() called on a RepeatedPtrField that is on an arena, " + << "with a type that does not implement MergeFrom. This is unsafe; " + << "please implement MergeFrom for your type."; + return UnsafeArenaReleaseLast(); +} + +template +inline typename TypeHandler::Type* + RepeatedPtrFieldBase::UnsafeArenaReleaseLast() { + GOOGLE_DCHECK_GT(current_size_, 0); + typename TypeHandler::Type* result = + cast(rep_->elements[--current_size_]); + --rep_->allocated_size; + if (current_size_ < rep_->allocated_size) { + // There are cleared elements on the end; replace the removed element + // with the last allocated element. + rep_->elements[current_size_] = rep_->elements[rep_->allocated_size]; + } + return result; +} + +inline int RepeatedPtrFieldBase::ClearedCount() const { + return rep_ ? (rep_->allocated_size - current_size_) : 0; +} + +template +inline void RepeatedPtrFieldBase::AddCleared( + typename TypeHandler::Type* value) { + GOOGLE_DCHECK(GetArenaNoVirtual() == NULL) + << "AddCleared() can only be used on a RepeatedPtrField not on an arena."; + GOOGLE_DCHECK(TypeHandler::GetArena(value) == NULL) + << "AddCleared() can only accept values not on an arena."; + if (!rep_ || rep_->allocated_size == total_size_) { + Reserve(total_size_ + 1); + } + rep_->elements[rep_->allocated_size++] = value; +} + +template +inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() { + GOOGLE_DCHECK(GetArenaNoVirtual() == NULL) + << "ReleaseCleared() can only be used on a RepeatedPtrField not on " + << "an arena."; + GOOGLE_DCHECK(GetArenaNoVirtual() == NULL); + GOOGLE_DCHECK(rep_ != NULL); + GOOGLE_DCHECK_GT(rep_->allocated_size, current_size_); + return cast(rep_->elements[--rep_->allocated_size]); +} + +} // namespace internal + +// ------------------------------------------------------------------- + +template +class RepeatedPtrField::TypeHandler + : public internal::GenericTypeHandler { +}; + +template <> +class RepeatedPtrField::TypeHandler + : public internal::StringTypeHandler { +}; + + +template +inline RepeatedPtrField::RepeatedPtrField() + : RepeatedPtrFieldBase() {} + +template +inline RepeatedPtrField::RepeatedPtrField(::google::protobuf::Arena* arena) : + RepeatedPtrFieldBase(arena) {} + +template +inline RepeatedPtrField::RepeatedPtrField( + const RepeatedPtrField& other) + : RepeatedPtrFieldBase() { + CopyFrom(other); +} + +template +template +inline RepeatedPtrField::RepeatedPtrField( + Iter begin, const Iter& end) { + int reserve = internal::CalculateReserve(begin, end); + if (reserve != -1) { + Reserve(reserve); + } + for (; begin != end; ++begin) { + *Add() = *begin; + } +} + +template +RepeatedPtrField::~RepeatedPtrField() { + Destroy(); +} + +template +inline RepeatedPtrField& RepeatedPtrField::operator=( + const RepeatedPtrField& other) { + if (this != &other) + CopyFrom(other); + return *this; +} + +template +inline bool RepeatedPtrField::empty() const { + return RepeatedPtrFieldBase::empty(); +} + +template +inline int RepeatedPtrField::size() const { + return RepeatedPtrFieldBase::size(); +} + +template +inline const Element& RepeatedPtrField::Get(int index) const { + return RepeatedPtrFieldBase::Get(index); +} + + +template +inline Element* RepeatedPtrField::Mutable(int index) { + return RepeatedPtrFieldBase::Mutable(index); +} + +template +inline Element* RepeatedPtrField::Add() { + return RepeatedPtrFieldBase::Add(); +} + +template +inline void RepeatedPtrField::RemoveLast() { + RepeatedPtrFieldBase::RemoveLast(); +} + +template +inline void RepeatedPtrField::DeleteSubrange(int start, int num) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, size()); + for (int i = 0; i < num; ++i) { + RepeatedPtrFieldBase::Delete(start + i); + } + ExtractSubrange(start, num, NULL); +} + +template +inline void RepeatedPtrField::ExtractSubrange( + int start, int num, Element** elements) { + typename internal::TypeImplementsMergeBehavior< + typename TypeHandler::Type>::type t; + ExtractSubrangeInternal(start, num, elements, t); +} + +// ExtractSubrange() implementation for types that implement merge/copy +// behavior. +template +inline void RepeatedPtrField::ExtractSubrangeInternal( + int start, int num, Element** elements, google::protobuf::internal::true_type) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, size()); + + if (num > 0) { + // Save the values of the removed elements if requested. + if (elements != NULL) { + if (GetArenaNoVirtual() != NULL) { + // If we're on an arena, we perform a copy for each element so that the + // returned elements are heap-allocated. + for (int i = 0; i < num; ++i) { + Element* element = RepeatedPtrFieldBase:: + Mutable(i + start); + typename TypeHandler::Type* new_value = + TypeHandler::NewFromPrototype(element, NULL); + TypeHandler::Merge(*element, new_value); + elements[i] = new_value; + } + } else { + for (int i = 0; i < num; ++i) { + elements[i] = RepeatedPtrFieldBase::Mutable(i + start); + } + } + } + CloseGap(start, num); + } +} + +// ExtractSubrange() implementation for types that do not implement merge/copy +// behavior. +template +inline void RepeatedPtrField::ExtractSubrangeInternal( + int start, int num, Element** elements, google::protobuf::internal::false_type) { + // This case is identical to UnsafeArenaExtractSubrange(). However, since + // ExtractSubrange() must return heap-allocated objects by contract, and we + // cannot fulfill this contract if we are an on arena, we must GOOGLE_DCHECK() that + // we are not on an arena. + GOOGLE_DCHECK(GetArenaNoVirtual() == NULL) + << "ExtractSubrange() when arena is non-NULL is only supported when " + << "the Element type supplies a MergeFrom() operation to make copies."; + UnsafeArenaExtractSubrange(start, num, elements); +} + +template +inline void RepeatedPtrField::UnsafeArenaExtractSubrange( + int start, int num, Element** elements) { + GOOGLE_DCHECK_GE(start, 0); + GOOGLE_DCHECK_GE(num, 0); + GOOGLE_DCHECK_LE(start + num, size()); + + if (num > 0) { + // Save the values of the removed elements if requested. + if (elements != NULL) { + for (int i = 0; i < num; ++i) { + elements[i] = RepeatedPtrFieldBase::Mutable(i + start); + } + } + CloseGap(start, num); + } +} + +template +inline void RepeatedPtrField::Clear() { + RepeatedPtrFieldBase::Clear(); +} + +template +inline void RepeatedPtrField::MergeFrom( + const RepeatedPtrField& other) { + RepeatedPtrFieldBase::MergeFrom(other); +} + +template +inline void RepeatedPtrField::CopyFrom( + const RepeatedPtrField& other) { + RepeatedPtrFieldBase::CopyFrom(other); +} + +template +inline typename RepeatedPtrField::iterator +RepeatedPtrField::erase(const_iterator position) { + return erase(position, position + 1); +} + +template +inline typename RepeatedPtrField::iterator +RepeatedPtrField::erase(const_iterator first, const_iterator last) { + size_type pos_offset = std::distance(cbegin(), first); + size_type last_offset = std::distance(cbegin(), last); + DeleteSubrange(pos_offset, last_offset - pos_offset); + return begin() + pos_offset; +} + +template +inline Element** RepeatedPtrField::mutable_data() { + return RepeatedPtrFieldBase::mutable_data(); +} + +template +inline const Element* const* RepeatedPtrField::data() const { + return RepeatedPtrFieldBase::data(); +} + +template +inline void RepeatedPtrField::Swap(RepeatedPtrField* other) { + if (this == other) + return; + RepeatedPtrFieldBase::Swap(other); +} + +template +inline void RepeatedPtrField::UnsafeArenaSwap( + RepeatedPtrField* other) { + GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + if (this == other) + return; + RepeatedPtrFieldBase::InternalSwap(other); +} + +template +inline void RepeatedPtrField::SwapElements(int index1, int index2) { + RepeatedPtrFieldBase::SwapElements(index1, index2); +} + +template +inline Arena* RepeatedPtrField::GetArenaNoVirtual() const { + return RepeatedPtrFieldBase::GetArenaNoVirtual(); +} + +template +inline int RepeatedPtrField::SpaceUsedExcludingSelf() const { + return RepeatedPtrFieldBase::SpaceUsedExcludingSelf(); +} + +template +inline void RepeatedPtrField::AddAllocated(Element* value) { + RepeatedPtrFieldBase::AddAllocated(value); +} + +template +inline void RepeatedPtrField::UnsafeArenaAddAllocated(Element* value) { + RepeatedPtrFieldBase::UnsafeArenaAddAllocated(value); +} + +template +inline Element* RepeatedPtrField::ReleaseLast() { + return RepeatedPtrFieldBase::ReleaseLast(); +} + +template +inline Element* RepeatedPtrField::UnsafeArenaReleaseLast() { + return RepeatedPtrFieldBase::UnsafeArenaReleaseLast(); +} + +template +inline int RepeatedPtrField::ClearedCount() const { + return RepeatedPtrFieldBase::ClearedCount(); +} + +template +inline void RepeatedPtrField::AddCleared(Element* value) { + return RepeatedPtrFieldBase::AddCleared(value); +} + +template +inline Element* RepeatedPtrField::ReleaseCleared() { + return RepeatedPtrFieldBase::ReleaseCleared(); +} + +template +inline void RepeatedPtrField::Reserve(int new_size) { + return RepeatedPtrFieldBase::Reserve(new_size); +} + +template +inline int RepeatedPtrField::Capacity() const { + return RepeatedPtrFieldBase::Capacity(); +} + +// ------------------------------------------------------------------- + +namespace internal { + +// STL-like iterator implementation for RepeatedPtrField. You should not +// refer to this class directly; use RepeatedPtrField::iterator instead. +// +// The iterator for RepeatedPtrField, RepeatedPtrIterator, is +// very similar to iterator_ptr in util/gtl/iterator_adaptors.h, +// but adds random-access operators and is modified to wrap a void** base +// iterator (since RepeatedPtrField stores its array as a void* array and +// casting void** to T** would violate C++ aliasing rules). +// +// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin +// (jyasskin@google.com). +template +class RepeatedPtrIterator + : public std::iterator< + std::random_access_iterator_tag, Element> { + public: + typedef RepeatedPtrIterator iterator; + typedef std::iterator< + std::random_access_iterator_tag, Element> superclass; + + // Shadow the value_type in std::iterator<> because const_iterator::value_type + // needs to be T, not const T. + typedef typename remove_const::type value_type; + + // Let the compiler know that these are type names, so we don't have to + // write "typename" in front of them everywhere. + typedef typename superclass::reference reference; + typedef typename superclass::pointer pointer; + typedef typename superclass::difference_type difference_type; + + RepeatedPtrIterator() : it_(NULL) {} + explicit RepeatedPtrIterator(void* const* it) : it_(it) {} + + // Allow "upcasting" from RepeatedPtrIterator to + // RepeatedPtrIterator. + template + RepeatedPtrIterator(const RepeatedPtrIterator& other) + : it_(other.it_) { + // Force a compiler error if the other type is not convertible to ours. + if (false) { + implicit_cast(0); + } + } + + // dereferenceable + reference operator*() const { return *reinterpret_cast(*it_); } + pointer operator->() const { return &(operator*()); } + + // {inc,dec}rementable + iterator& operator++() { ++it_; return *this; } + iterator operator++(int) { return iterator(it_++); } + iterator& operator--() { --it_; return *this; } + iterator operator--(int) { return iterator(it_--); } + + // equality_comparable + bool operator==(const iterator& x) const { return it_ == x.it_; } + bool operator!=(const iterator& x) const { return it_ != x.it_; } + + // less_than_comparable + bool operator<(const iterator& x) const { return it_ < x.it_; } + bool operator<=(const iterator& x) const { return it_ <= x.it_; } + bool operator>(const iterator& x) const { return it_ > x.it_; } + bool operator>=(const iterator& x) const { return it_ >= x.it_; } + + // addable, subtractable + iterator& operator+=(difference_type d) { + it_ += d; + return *this; + } + friend iterator operator+(iterator it, const difference_type d) { + it += d; + return it; + } + friend iterator operator+(const difference_type d, iterator it) { + it += d; + return it; + } + iterator& operator-=(difference_type d) { + it_ -= d; + return *this; + } + friend iterator operator-(iterator it, difference_type d) { + it -= d; + return it; + } + + // indexable + reference operator[](difference_type d) const { return *(*this + d); } + + // random access iterator + difference_type operator-(const iterator& x) const { return it_ - x.it_; } + + private: + template + friend class RepeatedPtrIterator; + + // The internal iterator. + void* const* it_; +}; + +// Provide an iterator that operates on pointers to the underlying objects +// rather than the objects themselves as RepeatedPtrIterator does. +// Consider using this when working with stl algorithms that change +// the array. +// The VoidPtr template parameter holds the type-agnostic pointer value +// referenced by the iterator. It should either be "void *" for a mutable +// iterator, or "const void *" for a constant iterator. +template +class RepeatedPtrOverPtrsIterator + : public std::iterator { + public: + typedef RepeatedPtrOverPtrsIterator iterator; + typedef std::iterator< + std::random_access_iterator_tag, Element*> superclass; + + // Shadow the value_type in std::iterator<> because const_iterator::value_type + // needs to be T, not const T. + typedef typename remove_const::type value_type; + + // Let the compiler know that these are type names, so we don't have to + // write "typename" in front of them everywhere. + typedef typename superclass::reference reference; + typedef typename superclass::pointer pointer; + typedef typename superclass::difference_type difference_type; + + RepeatedPtrOverPtrsIterator() : it_(NULL) {} + explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {} + + // dereferenceable + reference operator*() const { return *reinterpret_cast(it_); } + pointer operator->() const { return &(operator*()); } + + // {inc,dec}rementable + iterator& operator++() { ++it_; return *this; } + iterator operator++(int) { return iterator(it_++); } + iterator& operator--() { --it_; return *this; } + iterator operator--(int) { return iterator(it_--); } + + // equality_comparable + bool operator==(const iterator& x) const { return it_ == x.it_; } + bool operator!=(const iterator& x) const { return it_ != x.it_; } + + // less_than_comparable + bool operator<(const iterator& x) const { return it_ < x.it_; } + bool operator<=(const iterator& x) const { return it_ <= x.it_; } + bool operator>(const iterator& x) const { return it_ > x.it_; } + bool operator>=(const iterator& x) const { return it_ >= x.it_; } + + // addable, subtractable + iterator& operator+=(difference_type d) { + it_ += d; + return *this; + } + friend iterator operator+(iterator it, difference_type d) { + it += d; + return it; + } + friend iterator operator+(difference_type d, iterator it) { + it += d; + return it; + } + iterator& operator-=(difference_type d) { + it_ -= d; + return *this; + } + friend iterator operator-(iterator it, difference_type d) { + it -= d; + return it; + } + + // indexable + reference operator[](difference_type d) const { return *(*this + d); } + + // random access iterator + difference_type operator-(const iterator& x) const { return it_ - x.it_; } + + private: + template + friend class RepeatedPtrIterator; + + // The internal iterator. + VoidPtr* it_; +}; + +void RepeatedPtrFieldBase::InternalSwap(RepeatedPtrFieldBase* other) { + std::swap(rep_, other->rep_); + std::swap(current_size_, other->current_size_); + std::swap(total_size_, other->total_size_); +} + +} // namespace internal + +template +inline typename RepeatedPtrField::iterator +RepeatedPtrField::begin() { + return iterator(raw_data()); +} +template +inline typename RepeatedPtrField::const_iterator +RepeatedPtrField::begin() const { + return iterator(raw_data()); +} +template +inline typename RepeatedPtrField::const_iterator +RepeatedPtrField::cbegin() const { + return begin(); +} +template +inline typename RepeatedPtrField::iterator +RepeatedPtrField::end() { + return iterator(raw_data() + size()); +} +template +inline typename RepeatedPtrField::const_iterator +RepeatedPtrField::end() const { + return iterator(raw_data() + size()); +} +template +inline typename RepeatedPtrField::const_iterator +RepeatedPtrField::cend() const { + return end(); +} + +template +inline typename RepeatedPtrField::pointer_iterator +RepeatedPtrField::pointer_begin() { + return pointer_iterator(raw_mutable_data()); +} +template +inline typename RepeatedPtrField::const_pointer_iterator +RepeatedPtrField::pointer_begin() const { + return const_pointer_iterator(const_cast(raw_mutable_data())); +} +template +inline typename RepeatedPtrField::pointer_iterator +RepeatedPtrField::pointer_end() { + return pointer_iterator(raw_mutable_data() + size()); +} +template +inline typename RepeatedPtrField::const_pointer_iterator +RepeatedPtrField::pointer_end() const { + return const_pointer_iterator( + const_cast(raw_mutable_data() + size())); +} + + +// Iterators and helper functions that follow the spirit of the STL +// std::back_insert_iterator and std::back_inserter but are tailor-made +// for RepeatedField and RepeatedPtrField. Typical usage would be: +// +// std::copy(some_sequence.begin(), some_sequence.end(), +// google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence())); +// +// Ported by johannes from util/gtl/proto-array-iterators.h + +namespace internal { +// A back inserter for RepeatedField objects. +template class RepeatedFieldBackInsertIterator + : public std::iterator { + public: + explicit RepeatedFieldBackInsertIterator( + RepeatedField* const mutable_field) + : field_(mutable_field) { + } + RepeatedFieldBackInsertIterator& operator=(const T& value) { + field_->Add(value); + return *this; + } + RepeatedFieldBackInsertIterator& operator*() { + return *this; + } + RepeatedFieldBackInsertIterator& operator++() { + return *this; + } + RepeatedFieldBackInsertIterator& operator++(int /* unused */) { + return *this; + } + + private: + RepeatedField* field_; +}; + +// A back inserter for RepeatedPtrField objects. +template class RepeatedPtrFieldBackInsertIterator + : public std::iterator { + public: + RepeatedPtrFieldBackInsertIterator( + RepeatedPtrField* const mutable_field) + : field_(mutable_field) { + } + RepeatedPtrFieldBackInsertIterator& operator=(const T& value) { + *field_->Add() = value; + return *this; + } + RepeatedPtrFieldBackInsertIterator& operator=( + const T* const ptr_to_value) { + *field_->Add() = *ptr_to_value; + return *this; + } + RepeatedPtrFieldBackInsertIterator& operator*() { + return *this; + } + RepeatedPtrFieldBackInsertIterator& operator++() { + return *this; + } + RepeatedPtrFieldBackInsertIterator& operator++(int /* unused */) { + return *this; + } + + private: + RepeatedPtrField* field_; +}; + +// A back inserter for RepeatedPtrFields that inserts by transferring ownership +// of a pointer. +template class AllocatedRepeatedPtrFieldBackInsertIterator + : public std::iterator { + public: + explicit AllocatedRepeatedPtrFieldBackInsertIterator( + RepeatedPtrField* const mutable_field) + : field_(mutable_field) { + } + AllocatedRepeatedPtrFieldBackInsertIterator& operator=( + T* const ptr_to_value) { + field_->AddAllocated(ptr_to_value); + return *this; + } + AllocatedRepeatedPtrFieldBackInsertIterator& operator*() { + return *this; + } + AllocatedRepeatedPtrFieldBackInsertIterator& operator++() { + return *this; + } + AllocatedRepeatedPtrFieldBackInsertIterator& operator++( + int /* unused */) { + return *this; + } + + private: + RepeatedPtrField* field_; +}; + +// Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one +// uses the UnsafeArenaAddAllocated instead. +template +class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator + : public std::iterator { + public: + explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator( + ::google::protobuf::RepeatedPtrField* const mutable_field) + : field_(mutable_field) { + } + UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator& operator=( + T const* const ptr_to_value) { + field_->UnsafeArenaAddAllocated(const_cast(ptr_to_value)); + return *this; + } + UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator& operator*() { + return *this; + } + UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator& operator++() { + return *this; + } + UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator& operator++( + int /* unused */) { + return *this; + } + + private: + ::google::protobuf::RepeatedPtrField* field_; +}; + +} // namespace internal + +// Provides a back insert iterator for RepeatedField instances, +// similar to std::back_inserter(). +template internal::RepeatedFieldBackInsertIterator +RepeatedFieldBackInserter(RepeatedField* const mutable_field) { + return internal::RepeatedFieldBackInsertIterator(mutable_field); +} + +// Provides a back insert iterator for RepeatedPtrField instances, +// similar to std::back_inserter(). +template internal::RepeatedPtrFieldBackInsertIterator +RepeatedPtrFieldBackInserter(RepeatedPtrField* const mutable_field) { + return internal::RepeatedPtrFieldBackInsertIterator(mutable_field); +} + +// Special back insert iterator for RepeatedPtrField instances, just in +// case someone wants to write generic template code that can access both +// RepeatedFields and RepeatedPtrFields using a common name. +template internal::RepeatedPtrFieldBackInsertIterator +RepeatedFieldBackInserter(RepeatedPtrField* const mutable_field) { + return internal::RepeatedPtrFieldBackInsertIterator(mutable_field); +} + +// Provides a back insert iterator for RepeatedPtrField instances +// similar to std::back_inserter() which transfers the ownership while +// copying elements. +template internal::AllocatedRepeatedPtrFieldBackInsertIterator +AllocatedRepeatedPtrFieldBackInserter( + RepeatedPtrField* const mutable_field) { + return internal::AllocatedRepeatedPtrFieldBackInsertIterator( + mutable_field); +} + +// Similar to AllocatedRepeatedPtrFieldBackInserter, using +// UnsafeArenaAddAllocated instead of AddAllocated. +// This is slightly faster if that matters. It is also useful in legacy code +// that uses temporary ownership to avoid copies. Example: +// RepeatedPtrField temp_field; +// temp_field.AddAllocated(new T); +// ... // Do something with temp_field +// temp_field.ExtractSubrange(0, temp_field.size(), NULL); +// If you put temp_field on the arena this fails, because the ownership +// transfers to the arena at the "AddAllocated" call and is not released anymore +// causing a double delete. Using UnsafeArenaAddAllocated prevents this. +template +internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator +UnsafeArenaAllocatedRepeatedPtrFieldBackInserter( + ::google::protobuf::RepeatedPtrField* const mutable_field) { + return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator( + mutable_field); +} + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__ diff --git a/thirdparty/linux/include/google/protobuf/service.h b/thirdparty/linux/include/google/protobuf/service.h new file mode 100644 index 0000000..ad6f968 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/service.h @@ -0,0 +1,292 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// DEPRECATED: This module declares the abstract interfaces underlying proto2 +// RPC services. These are intented to be independent of any particular RPC +// implementation, so that proto2 services can be used on top of a variety +// of implementations. Starting with version 2.3.0, RPC implementations should +// not try to build on these, but should instead provide code generator plugins +// which generate code specific to the particular RPC implementation. This way +// the generated code can be more appropriate for the implementation in use +// and can avoid unnecessary layers of indirection. +// +// +// When you use the protocol compiler to compile a service definition, it +// generates two classes: An abstract interface for the service (with +// methods matching the service definition) and a "stub" implementation. +// A stub is just a type-safe wrapper around an RpcChannel which emulates a +// local implementation of the service. +// +// For example, the service definition: +// service MyService { +// rpc Foo(MyRequest) returns(MyResponse); +// } +// will generate abstract interface "MyService" and class "MyService::Stub". +// You could implement a MyService as follows: +// class MyServiceImpl : public MyService { +// public: +// MyServiceImpl() {} +// ~MyServiceImpl() {} +// +// // implements MyService --------------------------------------- +// +// void Foo(google::protobuf::RpcController* controller, +// const MyRequest* request, +// MyResponse* response, +// Closure* done) { +// // ... read request and fill in response ... +// done->Run(); +// } +// }; +// You would then register an instance of MyServiceImpl with your RPC server +// implementation. (How to do that depends on the implementation.) +// +// To call a remote MyServiceImpl, first you need an RpcChannel connected to it. +// How to construct a channel depends, again, on your RPC implementation. +// Here we use a hypothetical "MyRpcChannel" as an example: +// MyRpcChannel channel("rpc:hostname:1234/myservice"); +// MyRpcController controller; +// MyServiceImpl::Stub stub(&channel); +// FooRequest request; +// FooResponse response; +// +// // ... fill in request ... +// +// stub.Foo(&controller, request, &response, NewCallback(HandleResponse)); +// +// On Thread-Safety: +// +// Different RPC implementations may make different guarantees about what +// threads they may run callbacks on, and what threads the application is +// allowed to use to call the RPC system. Portable software should be ready +// for callbacks to be called on any thread, but should not try to call the +// RPC system from any thread except for the ones on which it received the +// callbacks. Realistically, though, simple software will probably want to +// use a single-threaded RPC system while high-end software will want to +// use multiple threads. RPC implementations should provide multiple +// choices. + +#ifndef GOOGLE_PROTOBUF_SERVICE_H__ +#define GOOGLE_PROTOBUF_SERVICE_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + +// Defined in this file. +class Service; +class RpcController; +class RpcChannel; + +// Defined in other files. +class Descriptor; // descriptor.h +class ServiceDescriptor; // descriptor.h +class MethodDescriptor; // descriptor.h +class Message; // message.h + +// Abstract base interface for protocol-buffer-based RPC services. Services +// themselves are abstract interfaces (implemented either by servers or as +// stubs), but they subclass this base interface. The methods of this +// interface can be used to call the methods of the Service without knowing +// its exact type at compile time (analogous to Reflection). +class LIBPROTOBUF_EXPORT Service { + public: + inline Service() {} + virtual ~Service(); + + // When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second + // parameter to the constructor to tell it to delete its RpcChannel when + // destroyed. + enum ChannelOwnership { + STUB_OWNS_CHANNEL, + STUB_DOESNT_OWN_CHANNEL + }; + + // Get the ServiceDescriptor describing this service and its methods. + virtual const ServiceDescriptor* GetDescriptor() = 0; + + // Call a method of the service specified by MethodDescriptor. This is + // normally implemented as a simple switch() that calls the standard + // definitions of the service's methods. + // + // Preconditions: + // * method->service() == GetDescriptor() + // * request and response are of the exact same classes as the objects + // returned by GetRequestPrototype(method) and + // GetResponsePrototype(method). + // * After the call has started, the request must not be modified and the + // response must not be accessed at all until "done" is called. + // * "controller" is of the correct type for the RPC implementation being + // used by this Service. For stubs, the "correct type" depends on the + // RpcChannel which the stub is using. Server-side Service + // implementations are expected to accept whatever type of RpcController + // the server-side RPC implementation uses. + // + // Postconditions: + // * "done" will be called when the method is complete. This may be + // before CallMethod() returns or it may be at some point in the future. + // * If the RPC succeeded, "response" contains the response returned by + // the server. + // * If the RPC failed, "response"'s contents are undefined. The + // RpcController can be queried to determine if an error occurred and + // possibly to get more information about the error. + virtual void CallMethod(const MethodDescriptor* method, + RpcController* controller, + const Message* request, + Message* response, + Closure* done) = 0; + + // CallMethod() requires that the request and response passed in are of a + // particular subclass of Message. GetRequestPrototype() and + // GetResponsePrototype() get the default instances of these required types. + // You can then call Message::New() on these instances to construct mutable + // objects which you can then pass to CallMethod(). + // + // Example: + // const MethodDescriptor* method = + // service->GetDescriptor()->FindMethodByName("Foo"); + // Message* request = stub->GetRequestPrototype (method)->New(); + // Message* response = stub->GetResponsePrototype(method)->New(); + // request->ParseFromString(input); + // service->CallMethod(method, *request, response, callback); + virtual const Message& GetRequestPrototype( + const MethodDescriptor* method) const = 0; + virtual const Message& GetResponsePrototype( + const MethodDescriptor* method) const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service); +}; + +// An RpcController mediates a single method call. The primary purpose of +// the controller is to provide a way to manipulate settings specific to the +// RPC implementation and to find out about RPC-level errors. +// +// The methods provided by the RpcController interface are intended to be a +// "least common denominator" set of features which we expect all +// implementations to support. Specific implementations may provide more +// advanced features (e.g. deadline propagation). +class LIBPROTOBUF_EXPORT RpcController { + public: + inline RpcController() {} + virtual ~RpcController(); + + // Client-side methods --------------------------------------------- + // These calls may be made from the client side only. Their results + // are undefined on the server side (may crash). + + // Resets the RpcController to its initial state so that it may be reused in + // a new call. Must not be called while an RPC is in progress. + virtual void Reset() = 0; + + // After a call has finished, returns true if the call failed. The possible + // reasons for failure depend on the RPC implementation. Failed() must not + // be called before a call has finished. If Failed() returns true, the + // contents of the response message are undefined. + virtual bool Failed() const = 0; + + // If Failed() is true, returns a human-readable description of the error. + virtual string ErrorText() const = 0; + + // Advises the RPC system that the caller desires that the RPC call be + // canceled. The RPC system may cancel it immediately, may wait awhile and + // then cancel it, or may not even cancel the call at all. If the call is + // canceled, the "done" callback will still be called and the RpcController + // will indicate that the call failed at that time. + virtual void StartCancel() = 0; + + // Server-side methods --------------------------------------------- + // These calls may be made from the server side only. Their results + // are undefined on the client side (may crash). + + // Causes Failed() to return true on the client side. "reason" will be + // incorporated into the message returned by ErrorText(). If you find + // you need to return machine-readable information about failures, you + // should incorporate it into your response protocol buffer and should + // NOT call SetFailed(). + virtual void SetFailed(const string& reason) = 0; + + // If true, indicates that the client canceled the RPC, so the server may + // as well give up on replying to it. The server should still call the + // final "done" callback. + virtual bool IsCanceled() const = 0; + + // Asks that the given callback be called when the RPC is canceled. The + // callback will always be called exactly once. If the RPC completes without + // being canceled, the callback will be called after completion. If the RPC + // has already been canceled when NotifyOnCancel() is called, the callback + // will be called immediately. + // + // NotifyOnCancel() must be called no more than once per request. + virtual void NotifyOnCancel(Closure* callback) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController); +}; + +// Abstract interface for an RPC channel. An RpcChannel represents a +// communication line to a Service which can be used to call that Service's +// methods. The Service may be running on another machine. Normally, you +// should not call an RpcChannel directly, but instead construct a stub Service +// wrapping it. Example: +// RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234"); +// MyService* service = new MyService::Stub(channel); +// service->MyMethod(request, &response, callback); +class LIBPROTOBUF_EXPORT RpcChannel { + public: + inline RpcChannel() {} + virtual ~RpcChannel(); + + // Call the given method of the remote service. The signature of this + // procedure looks the same as Service::CallMethod(), but the requirements + // are less strict in one important way: the request and response objects + // need not be of any specific class as long as their descriptors are + // method->input_type() and method->output_type(). + virtual void CallMethod(const MethodDescriptor* method, + RpcController* controller, + const Message* request, + Message* response, + Closure* done) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel); +}; + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_SERVICE_H__ diff --git a/thirdparty/linux/include/google/protobuf/source_context.pb.h b/thirdparty/linux/include/google/protobuf/source_context.pb.h new file mode 100644 index 0000000..341a453 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/source_context.pb.h @@ -0,0 +1,190 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/source_context.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fsource_5fcontext_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fsource_5fcontext_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto(); + +class SourceContext; + +// =================================================================== + +class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceContext) */ { + public: + SourceContext(); + virtual ~SourceContext(); + + SourceContext(const SourceContext& from); + + inline SourceContext& operator=(const SourceContext& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SourceContext& default_instance(); + + void Swap(SourceContext* other); + + // implements Message ---------------------------------------------- + + inline SourceContext* New() const { return New(NULL); } + + SourceContext* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SourceContext& from); + void MergeFrom(const SourceContext& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(SourceContext* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string file_name = 1; + void clear_file_name(); + static const int kFileNameFieldNumber = 1; + const ::std::string& file_name() const; + void set_file_name(const ::std::string& value); + void set_file_name(const char* value); + void set_file_name(const char* value, size_t size); + ::std::string* mutable_file_name(); + ::std::string* release_file_name(); + void set_allocated_file_name(::std::string* file_name); + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceContext) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr file_name_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto(); + + void InitAsDefaultInstance(); + static SourceContext* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// SourceContext + +// optional string file_name = 1; +inline void SourceContext::clear_file_name() { + file_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& SourceContext::file_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceContext.file_name) + return file_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SourceContext::set_file_name(const ::std::string& value) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceContext.file_name) +} +inline void SourceContext::set_file_name(const char* value) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name) +} +inline void SourceContext::set_file_name(const char* value, size_t size) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceContext.file_name) +} +inline ::std::string* SourceContext::mutable_file_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceContext.file_name) + return file_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* SourceContext::release_file_name() { + // @@protoc_insertion_point(field_release:google.protobuf.SourceContext.file_name) + + return file_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SourceContext::set_allocated_file_name(::std::string* file_name) { + if (file_name != NULL) { + + } else { + + } + file_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), file_name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceContext.file_name) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fsource_5fcontext_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/source_context.proto b/thirdparty/linux/include/google/protobuf/source_context.proto new file mode 100644 index 0000000..a2c08e2 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/source_context.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "SourceContextProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; + +// `SourceContext` represents information about the source of a +// protobuf element, like the file in which it is defined. +message SourceContext { + // The path-qualified name of the .proto file that contained the associated + // protobuf element. For example: `"google/protobuf/source_context.proto"`. + string file_name = 1; +} diff --git a/thirdparty/linux/include/google/protobuf/struct.pb.h b/thirdparty/linux/include/google/protobuf/struct.pb.h new file mode 100644 index 0000000..b085b84 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/struct.pb.h @@ -0,0 +1,781 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/struct.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fstruct_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fstruct_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto(); + +class ListValue; +class Struct; +class Value; + +enum NullValue { + NULL_VALUE = 0, + NullValue_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + NullValue_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +LIBPROTOBUF_EXPORT bool NullValue_IsValid(int value); +const NullValue NullValue_MIN = NULL_VALUE; +const NullValue NullValue_MAX = NULL_VALUE; +const int NullValue_ARRAYSIZE = NullValue_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* NullValue_descriptor(); +inline const ::std::string& NullValue_Name(NullValue value) { + return ::google::protobuf::internal::NameOfEnum( + NullValue_descriptor(), value); +} +inline bool NullValue_Parse( + const ::std::string& name, NullValue* value) { + return ::google::protobuf::internal::ParseNamedEnum( + NullValue_descriptor(), name, value); +} +// =================================================================== + +class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ { + public: + Struct(); + virtual ~Struct(); + + Struct(const Struct& from); + + inline Struct& operator=(const Struct& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Struct& default_instance(); + + void Swap(Struct* other); + + // implements Message ---------------------------------------------- + + inline Struct* New() const { return New(NULL); } + + Struct* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Struct& from); + void MergeFrom(const Struct& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Struct* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + + // accessors ------------------------------------------------------- + + // map fields = 1; + int fields_size() const; + void clear_fields(); + static const int kFieldsFieldNumber = 1; + const ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >& + fields() const; + ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >* + mutable_fields(); + + // @@protoc_insertion_point(class_scope:google.protobuf.Struct) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + typedef ::google::protobuf::internal::MapEntryLite< + ::std::string, ::google::protobuf::Value, + ::google::protobuf::internal::WireFormatLite::TYPE_STRING, + ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, + 0 > + Struct_FieldsEntry; + ::google::protobuf::internal::MapField< + ::std::string, ::google::protobuf::Value, + ::google::protobuf::internal::WireFormatLite::TYPE_STRING, + ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, + 0 > fields_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto(); + + void InitAsDefaultInstance(); + static Struct* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ { + public: + Value(); + virtual ~Value(); + + Value(const Value& from); + + inline Value& operator=(const Value& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Value& default_instance(); + + enum KindCase { + kNullValue = 1, + kNumberValue = 2, + kStringValue = 3, + kBoolValue = 4, + kStructValue = 5, + kListValue = 6, + KIND_NOT_SET = 0, + }; + + void Swap(Value* other); + + // implements Message ---------------------------------------------- + + inline Value* New() const { return New(NULL); } + + Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Value& from); + void MergeFrom(const Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Value* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .google.protobuf.NullValue null_value = 1; + private: + bool has_null_value() const; + public: + void clear_null_value(); + static const int kNullValueFieldNumber = 1; + ::google::protobuf::NullValue null_value() const; + void set_null_value(::google::protobuf::NullValue value); + + // optional double number_value = 2; + private: + bool has_number_value() const; + public: + void clear_number_value(); + static const int kNumberValueFieldNumber = 2; + double number_value() const; + void set_number_value(double value); + + // optional string string_value = 3; + private: + bool has_string_value() const; + public: + void clear_string_value(); + static const int kStringValueFieldNumber = 3; + const ::std::string& string_value() const; + void set_string_value(const ::std::string& value); + void set_string_value(const char* value); + void set_string_value(const char* value, size_t size); + ::std::string* mutable_string_value(); + ::std::string* release_string_value(); + void set_allocated_string_value(::std::string* string_value); + + // optional bool bool_value = 4; + private: + bool has_bool_value() const; + public: + void clear_bool_value(); + static const int kBoolValueFieldNumber = 4; + bool bool_value() const; + void set_bool_value(bool value); + + // optional .google.protobuf.Struct struct_value = 5; + bool has_struct_value() const; + void clear_struct_value(); + static const int kStructValueFieldNumber = 5; + const ::google::protobuf::Struct& struct_value() const; + ::google::protobuf::Struct* mutable_struct_value(); + ::google::protobuf::Struct* release_struct_value(); + void set_allocated_struct_value(::google::protobuf::Struct* struct_value); + + // optional .google.protobuf.ListValue list_value = 6; + bool has_list_value() const; + void clear_list_value(); + static const int kListValueFieldNumber = 6; + const ::google::protobuf::ListValue& list_value() const; + ::google::protobuf::ListValue* mutable_list_value(); + ::google::protobuf::ListValue* release_list_value(); + void set_allocated_list_value(::google::protobuf::ListValue* list_value); + + KindCase kind_case() const; + // @@protoc_insertion_point(class_scope:google.protobuf.Value) + private: + inline void set_has_null_value(); + inline void set_has_number_value(); + inline void set_has_string_value(); + inline void set_has_bool_value(); + inline void set_has_struct_value(); + inline void set_has_list_value(); + + inline bool has_kind() const; + void clear_kind(); + inline void clear_has_kind(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + union KindUnion { + KindUnion() {} + int null_value_; + double number_value_; + ::google::protobuf::internal::ArenaStringPtr string_value_; + bool bool_value_; + ::google::protobuf::Struct* struct_value_; + ::google::protobuf::ListValue* list_value_; + } kind_; + mutable int _cached_size_; + ::google::protobuf::uint32 _oneof_case_[1]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto(); + + void InitAsDefaultInstance(); + static Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ { + public: + ListValue(); + virtual ~ListValue(); + + ListValue(const ListValue& from); + + inline ListValue& operator=(const ListValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ListValue& default_instance(); + + void Swap(ListValue* other); + + // implements Message ---------------------------------------------- + + inline ListValue* New() const { return New(NULL); } + + ListValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ListValue& from); + void MergeFrom(const ListValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(ListValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.Value values = 1; + int values_size() const; + void clear_values(); + static const int kValuesFieldNumber = 1; + const ::google::protobuf::Value& values(int index) const; + ::google::protobuf::Value* mutable_values(int index); + ::google::protobuf::Value* add_values(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >* + mutable_values(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >& + values() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.ListValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value > values_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto(); + + void InitAsDefaultInstance(); + static ListValue* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Struct + +// map fields = 1; +inline int Struct::fields_size() const { + return fields_.size(); +} +inline void Struct::clear_fields() { + fields_.Clear(); +} +inline const ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >& +Struct::fields() const { + // @@protoc_insertion_point(field_map:google.protobuf.Struct.fields) + return fields_.GetMap(); +} +inline ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >* +Struct::mutable_fields() { + // @@protoc_insertion_point(field_mutable_map:google.protobuf.Struct.fields) + return fields_.MutableMap(); +} + +// ------------------------------------------------------------------- + +// Value + +// optional .google.protobuf.NullValue null_value = 1; +inline bool Value::has_null_value() const { + return kind_case() == kNullValue; +} +inline void Value::set_has_null_value() { + _oneof_case_[0] = kNullValue; +} +inline void Value::clear_null_value() { + if (has_null_value()) { + kind_.null_value_ = 0; + clear_has_kind(); + } +} +inline ::google::protobuf::NullValue Value::null_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.null_value) + if (has_null_value()) { + return static_cast< ::google::protobuf::NullValue >(kind_.null_value_); + } + return static_cast< ::google::protobuf::NullValue >(0); +} +inline void Value::set_null_value(::google::protobuf::NullValue value) { + if (!has_null_value()) { + clear_kind(); + set_has_null_value(); + } + kind_.null_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.null_value) +} + +// optional double number_value = 2; +inline bool Value::has_number_value() const { + return kind_case() == kNumberValue; +} +inline void Value::set_has_number_value() { + _oneof_case_[0] = kNumberValue; +} +inline void Value::clear_number_value() { + if (has_number_value()) { + kind_.number_value_ = 0; + clear_has_kind(); + } +} +inline double Value::number_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.number_value) + if (has_number_value()) { + return kind_.number_value_; + } + return 0; +} +inline void Value::set_number_value(double value) { + if (!has_number_value()) { + clear_kind(); + set_has_number_value(); + } + kind_.number_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.number_value) +} + +// optional string string_value = 3; +inline bool Value::has_string_value() const { + return kind_case() == kStringValue; +} +inline void Value::set_has_string_value() { + _oneof_case_[0] = kStringValue; +} +inline void Value::clear_string_value() { + if (has_string_value()) { + kind_.string_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_kind(); + } +} +inline const ::std::string& Value::string_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.string_value) + if (has_string_value()) { + return kind_.string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + return *&::google::protobuf::internal::GetEmptyStringAlreadyInited(); +} +inline void Value::set_string_value(const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) +} +inline void Value::set_string_value(const char* value) { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Value.string_value) +} +inline void Value::set_string_value(const char* value, size_t size) { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string( + reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Value.string_value) +} +inline ::std::string* Value::mutable_string_value() { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.string_value) + return kind_.string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Value::release_string_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value) + if (has_string_value()) { + clear_has_kind(); + return kind_.string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } else { + return NULL; + } +} +inline void Value::set_allocated_string_value(::std::string* string_value) { + if (!has_string_value()) { + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + clear_kind(); + if (string_value != NULL) { + set_has_string_value(); + kind_.string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + string_value); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value) +} + +// optional bool bool_value = 4; +inline bool Value::has_bool_value() const { + return kind_case() == kBoolValue; +} +inline void Value::set_has_bool_value() { + _oneof_case_[0] = kBoolValue; +} +inline void Value::clear_bool_value() { + if (has_bool_value()) { + kind_.bool_value_ = false; + clear_has_kind(); + } +} +inline bool Value::bool_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.bool_value) + if (has_bool_value()) { + return kind_.bool_value_; + } + return false; +} +inline void Value::set_bool_value(bool value) { + if (!has_bool_value()) { + clear_kind(); + set_has_bool_value(); + } + kind_.bool_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.bool_value) +} + +// optional .google.protobuf.Struct struct_value = 5; +inline bool Value::has_struct_value() const { + return kind_case() == kStructValue; +} +inline void Value::set_has_struct_value() { + _oneof_case_[0] = kStructValue; +} +inline void Value::clear_struct_value() { + if (has_struct_value()) { + delete kind_.struct_value_; + clear_has_kind(); + } +} +inline const ::google::protobuf::Struct& Value::struct_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value) + return has_struct_value() + ? *kind_.struct_value_ + : ::google::protobuf::Struct::default_instance(); +} +inline ::google::protobuf::Struct* Value::mutable_struct_value() { + if (!has_struct_value()) { + clear_kind(); + set_has_struct_value(); + kind_.struct_value_ = new ::google::protobuf::Struct; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.struct_value) + return kind_.struct_value_; +} +inline ::google::protobuf::Struct* Value::release_struct_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Value.struct_value) + if (has_struct_value()) { + clear_has_kind(); + ::google::protobuf::Struct* temp = kind_.struct_value_; + kind_.struct_value_ = NULL; + return temp; + } else { + return NULL; + } +} +inline void Value::set_allocated_struct_value(::google::protobuf::Struct* struct_value) { + clear_kind(); + if (struct_value) { + set_has_struct_value(); + kind_.struct_value_ = struct_value; + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.struct_value) +} + +// optional .google.protobuf.ListValue list_value = 6; +inline bool Value::has_list_value() const { + return kind_case() == kListValue; +} +inline void Value::set_has_list_value() { + _oneof_case_[0] = kListValue; +} +inline void Value::clear_list_value() { + if (has_list_value()) { + delete kind_.list_value_; + clear_has_kind(); + } +} +inline const ::google::protobuf::ListValue& Value::list_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value) + return has_list_value() + ? *kind_.list_value_ + : ::google::protobuf::ListValue::default_instance(); +} +inline ::google::protobuf::ListValue* Value::mutable_list_value() { + if (!has_list_value()) { + clear_kind(); + set_has_list_value(); + kind_.list_value_ = new ::google::protobuf::ListValue; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.list_value) + return kind_.list_value_; +} +inline ::google::protobuf::ListValue* Value::release_list_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Value.list_value) + if (has_list_value()) { + clear_has_kind(); + ::google::protobuf::ListValue* temp = kind_.list_value_; + kind_.list_value_ = NULL; + return temp; + } else { + return NULL; + } +} +inline void Value::set_allocated_list_value(::google::protobuf::ListValue* list_value) { + clear_kind(); + if (list_value) { + set_has_list_value(); + kind_.list_value_ = list_value; + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value) +} + +inline bool Value::has_kind() const { + return kind_case() != KIND_NOT_SET; +} +inline void Value::clear_has_kind() { + _oneof_case_[0] = KIND_NOT_SET; +} +inline Value::KindCase Value::kind_case() const { + return Value::KindCase(_oneof_case_[0]); +} +// ------------------------------------------------------------------- + +// ListValue + +// repeated .google.protobuf.Value values = 1; +inline int ListValue::values_size() const { + return values_.size(); +} +inline void ListValue::clear_values() { + values_.Clear(); +} +inline const ::google::protobuf::Value& ListValue::values(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ListValue.values) + return values_.Get(index); +} +inline ::google::protobuf::Value* ListValue::mutable_values(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values) + return values_.Mutable(index); +} +inline ::google::protobuf::Value* ListValue::add_values() { + // @@protoc_insertion_point(field_add:google.protobuf.ListValue.values) + return values_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >* +ListValue::mutable_values() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ListValue.values) + return &values_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >& +ListValue::values() const { + // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values) + return values_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::google::protobuf::NullValue> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::NullValue>() { + return ::google::protobuf::NullValue_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fstruct_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/struct.proto b/thirdparty/linux/include/google/protobuf/struct.proto new file mode 100644 index 0000000..beeba81 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/struct.proto @@ -0,0 +1,96 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/struct;structpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "StructProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; + + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +message Struct { + // Unordered map of dynamically typed values. + map fields = 1; +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of that +// variants, absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +message Value { + // The kind of value. + oneof kind { + // Represents a null value. + NullValue null_value = 1; + // Represents a double value. + double number_value = 2; + // Represents a string value. + string string_value = 3; + // Represents a boolean value. + bool bool_value = 4; + // Represents a structured value. + Struct struct_value = 5; + // Represents a repeated `Value`. + ListValue list_value = 6; + } +} + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +enum NullValue { + // Null value. + NULL_VALUE = 0; +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +message ListValue { + // Repeated field of dynamically typed values. + repeated Value values = 1; +} diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomic_sequence_num.h b/thirdparty/linux/include/google/protobuf/stubs/atomic_sequence_num.h new file mode 100644 index 0000000..bb20942 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomic_sequence_num.h @@ -0,0 +1,54 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_ +#define GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_ + +#include + +namespace google { +namespace protobuf { +namespace internal { + +class SequenceNumber { + public: + SequenceNumber() : word_(0) {} + + AtomicWord GetNext() { + return NoBarrier_AtomicIncrement(&word_, 1) - 1; + } + private: + AtomicWord word_; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops.h new file mode 100644 index 0000000..9b3d1e6 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops.h @@ -0,0 +1,246 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// The routines exported by this module are subtle. If you use them, even if +// you get the code right, it will depend on careful reasoning about atomicity +// and memory ordering; it will be less readable, and harder to maintain. If +// you plan to use these routines, you should have a good reason, such as solid +// evidence that performance would otherwise suffer, or there being no +// alternative. You should assume only properties explicitly guaranteed by the +// specifications in this file. You are almost certainly _not_ writing code +// just for the x86; if you assume x86 semantics, x86 hardware bugs and +// implementations on other archtectures will cause your code to break. If you +// do not know what you are doing, avoid these routines, and use a Mutex. +// +// It is incorrect to make direct assignments to/from an atomic variable. +// You should use one of the Load or Store routines. The NoBarrier +// versions are provided when no barriers are needed: +// NoBarrier_Store() +// NoBarrier_Load() +// Although there are currently no compiler enforcement, you are encouraged +// to use these. + +// This header and the implementations for each platform (located in +// atomicops_internals_*) must be kept in sync with the upstream code (V8). + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_H_ + +// Don't include this file for people not concerned about thread safety. +#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +#if defined(GOOGLE_PROTOBUF_ARCH_POWER) +#if defined(_LP64) || defined(__LP64__) +typedef int32 Atomic32; +typedef intptr_t Atomic64; +#else +typedef intptr_t Atomic32; +typedef int64 Atomic64; +#endif +#else +typedef int32 Atomic32; +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT +// We need to be able to go between Atomic64 and AtomicWord implicitly. This +// means Atomic64 and AtomicWord should be the same type on 64-bit. +#if defined(__ILP32__) || defined(GOOGLE_PROTOBUF_OS_NACL) +// NaCl's intptr_t is not actually 64-bits on 64-bit! +// http://code.google.com/p/nativeclient/issues/detail?id=1162 +// sparcv9's pointer type is 32bits +typedef int64 Atomic64; +#else +typedef intptr_t Atomic64; +#endif +#endif +#endif + +// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or +// Atomic64 routines below, depending on your architecture. +typedef intptr_t AtomicWord; + +// Atomically execute: +// result = *ptr; +// if (*ptr == old_value) +// *ptr = new_value; +// return result; +// +// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". +// Always return the old value of "*ptr" +// +// This routine implies no memory barriers. +Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value); + +// Atomically store new_value into *ptr, returning the previous value held in +// *ptr. This routine implies no memory barriers. +Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value); + +// Atomically increment *ptr by "increment". Returns the new value of +// *ptr with the increment applied. This routine implies no memory barriers. +Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); + +Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment); + +// These following lower-level operations are typically useful only to people +// implementing higher-level synchronization operations like spinlocks, +// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or +// a store with appropriate memory-ordering instructions. "Acquire" operations +// ensure that no later memory access can be reordered ahead of the operation. +// "Release" operations ensure that no previous memory access can be reordered +// after the operation. "Barrier" operations have both "Acquire" and "Release" +// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory +// access. +Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value); +Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value); + +#if defined(__MINGW32__) && defined(MemoryBarrier) +#undef MemoryBarrier +#endif +void MemoryBarrier(); +void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value); +void Acquire_Store(volatile Atomic32* ptr, Atomic32 value); +void Release_Store(volatile Atomic32* ptr, Atomic32 value); + +Atomic32 NoBarrier_Load(volatile const Atomic32* ptr); +Atomic32 Acquire_Load(volatile const Atomic32* ptr); +Atomic32 Release_Load(volatile const Atomic32* ptr); + +// 64-bit atomic operations (only available on 64-bit processors). +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT +Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value); +Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value); +Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); +Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); + +Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value); +Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value); +void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value); +void Acquire_Store(volatile Atomic64* ptr, Atomic64 value); +void Release_Store(volatile Atomic64* ptr, Atomic64 value); +Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); +Atomic64 Acquire_Load(volatile const Atomic64* ptr); +Atomic64 Release_Load(volatile const Atomic64* ptr); +#endif // GOOGLE_PROTOBUF_ARCH_64_BIT + +} // namespace internal +} // namespace protobuf +} // namespace google + +// Include our platform specific implementation. +#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \ +"Atomic operations are not supported on your platform" + +// ThreadSanitizer, http://clang.llvm.org/docs/ThreadSanitizer.html. +#if defined(THREAD_SANITIZER) +#include +// MSVC. +#elif defined(_MSC_VER) +#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64) +#include +#else +#error GOOGLE_PROTOBUF_ATOMICOPS_ERROR +#endif + +// Solaris +#elif defined(GOOGLE_PROTOBUF_OS_SOLARIS) +#include + +// AIX +#elif defined(GOOGLE_PROTOBUF_OS_AIX) +#include + +// Apple. +#elif defined(GOOGLE_PROTOBUF_OS_APPLE) +#include + +// GCC. +#elif defined(__GNUC__) +#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_ARM) && defined(__linux__) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_AARCH64) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS) || defined(GOOGLE_PROTOBUF_ARCH_MIPS64) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_POWER) +#include +#elif defined(__native_client__) +#include +#elif defined(GOOGLE_PROTOBUF_ARCH_PPC) +#include +#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)) +#include +#elif defined(__clang__) +#if __has_extension(c_atomic) +#include +#else +#error GOOGLE_PROTOBUF_ATOMICOPS_ERROR +#endif +#else +#error GOOGLE_PROTOBUF_ATOMICOPS_ERROR +#endif + +// Unknown. +#else +#error GOOGLE_PROTOBUF_ATOMICOPS_ERROR +#endif + +// On some platforms we need additional declarations to make AtomicWord +// compatible with our other Atomic* types. +#if defined(GOOGLE_PROTOBUF_OS_APPLE) +#include +#endif + +#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR + +#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm64_gcc.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm64_gcc.h new file mode 100644 index 0000000..0a2d2b8 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm64_gcc.h @@ -0,0 +1,325 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_ + +namespace google { +namespace protobuf { +namespace internal { + +inline void MemoryBarrier() { + __asm__ __volatile__ ("dmb ish" ::: "memory"); // NOLINT +} + +// NoBarrier versions of the operation include "memory" in the clobber list. +// This is not required for direct usage of the NoBarrier versions of the +// operations. However this is required for correctness when they are used as +// part of the Acquire or Release versions, to ensure that nothing from outside +// the call is reordered between the operation and the memory barrier. This does +// not change the code generated, so has no or minimal impact on the +// NoBarrier operations. + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev; + int32_t temp; + + __asm__ __volatile__ ( // NOLINT + "0: \n\t" + "ldxr %w[prev], %[ptr] \n\t" // Load the previous value. + "cmp %w[prev], %w[old_value] \n\t" + "bne 1f \n\t" + "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value. + "cbnz %w[temp], 0b \n\t" // Retry if it did not work. + "1: \n\t" + : [prev]"=&r" (prev), + [temp]"=&r" (temp), + [ptr]"+Q" (*ptr) + : [old_value]"IJr" (old_value), + [new_value]"r" (new_value) + : "cc", "memory" + ); // NOLINT + + return prev; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 result; + int32_t temp; + + __asm__ __volatile__ ( // NOLINT + "0: \n\t" + "ldxr %w[result], %[ptr] \n\t" // Load the previous value. + "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value. + "cbnz %w[temp], 0b \n\t" // Retry if it did not work. + : [result]"=&r" (result), + [temp]"=&r" (temp), + [ptr]"+Q" (*ptr) + : [new_value]"r" (new_value) + : "memory" + ); // NOLINT + + return result; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 result; + int32_t temp; + + __asm__ __volatile__ ( // NOLINT + "0: \n\t" + "ldxr %w[result], %[ptr] \n\t" // Load the previous value. + "add %w[result], %w[result], %w[increment]\n\t" + "stxr %w[temp], %w[result], %[ptr] \n\t" // Try to store the result. + "cbnz %w[temp], 0b \n\t" // Retry on failure. + : [result]"=&r" (result), + [temp]"=&r" (temp), + [ptr]"+Q" (*ptr) + : [increment]"IJr" (increment) + : "memory" + ); // NOLINT + + return result; +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + MemoryBarrier(); + Atomic32 result = NoBarrier_AtomicIncrement(ptr, increment); + MemoryBarrier(); + + return result; +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); + + return prev; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + MemoryBarrier(); + Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + + return prev; +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + __asm__ __volatile__ ( // NOLINT + "stlr %w[value], %[ptr] \n\t" + : [ptr]"=Q" (*ptr) + : [value]"r" (value) + : "memory" + ); // NOLINT +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value; + + __asm__ __volatile__ ( // NOLINT + "ldar %w[value], %[ptr] \n\t" + : [value]"=r" (value) + : [ptr]"Q" (*ptr) + : "memory" + ); // NOLINT + + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +// 64-bit versions of the operations. +// See the 32-bit versions for comments. + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev; + int32_t temp; + + __asm__ __volatile__ ( // NOLINT + "0: \n\t" + "ldxr %[prev], %[ptr] \n\t" + "cmp %[prev], %[old_value] \n\t" + "bne 1f \n\t" + "stxr %w[temp], %[new_value], %[ptr] \n\t" + "cbnz %w[temp], 0b \n\t" + "1: \n\t" + : [prev]"=&r" (prev), + [temp]"=&r" (temp), + [ptr]"+Q" (*ptr) + : [old_value]"IJr" (old_value), + [new_value]"r" (new_value) + : "cc", "memory" + ); // NOLINT + + return prev; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + Atomic64 result; + int32_t temp; + + __asm__ __volatile__ ( // NOLINT + "0: \n\t" + "ldxr %[result], %[ptr] \n\t" + "stxr %w[temp], %[new_value], %[ptr] \n\t" + "cbnz %w[temp], 0b \n\t" + : [result]"=&r" (result), + [temp]"=&r" (temp), + [ptr]"+Q" (*ptr) + : [new_value]"r" (new_value) + : "memory" + ); // NOLINT + + return result; +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + Atomic64 result; + int32_t temp; + + __asm__ __volatile__ ( // NOLINT + "0: \n\t" + "ldxr %[result], %[ptr] \n\t" + "add %[result], %[result], %[increment] \n\t" + "stxr %w[temp], %[result], %[ptr] \n\t" + "cbnz %w[temp], 0b \n\t" + : [result]"=&r" (result), + [temp]"=&r" (temp), + [ptr]"+Q" (*ptr) + : [increment]"IJr" (increment) + : "memory" + ); // NOLINT + + return result; +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + MemoryBarrier(); + Atomic64 result = NoBarrier_AtomicIncrement(ptr, increment); + MemoryBarrier(); + + return result; +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); + + return prev; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + MemoryBarrier(); + Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + + return prev; +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + __asm__ __volatile__ ( // NOLINT + "stlr %x[value], %[ptr] \n\t" + : [ptr]"=Q" (*ptr) + : [value]"r" (value) + : "memory" + ); // NOLINT +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 value; + + __asm__ __volatile__ ( // NOLINT + "ldar %x[value], %[ptr] \n\t" + : [value]"=r" (value) + : [ptr]"Q" (*ptr) + : "memory" + ); // NOLINT + + return value; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return *ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm_gcc.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm_gcc.h new file mode 100644 index 0000000..90e727b --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm_gcc.h @@ -0,0 +1,151 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. +// +// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_ + +namespace google { +namespace protobuf { +namespace internal { + +// 0xffff0fc0 is the hard coded address of a function provided by +// the kernel which implements an atomic compare-exchange. On older +// ARM architecture revisions (pre-v6) this may be implemented using +// a syscall. This address is stable, and in active use (hard coded) +// by at least glibc-2.7 and the Android C library. +typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value, + Atomic32 new_value, + volatile Atomic32* ptr); +LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) = + (LinuxKernelCmpxchgFunc) 0xffff0fc0; + +typedef void (*LinuxKernelMemoryBarrierFunc)(void); +LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) = + (LinuxKernelMemoryBarrierFunc) 0xffff0fa0; + + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev_value = *ptr; + do { + if (!pLinuxKernelCmpxchg(old_value, new_value, + const_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 old_value; + do { + old_value = *ptr; + } while (pLinuxKernelCmpxchg(old_value, new_value, + const_cast(ptr))); + return old_value; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return Barrier_AtomicIncrement(ptr, increment); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + for (;;) { + // Atomic exchange the old value with an incremented one. + Atomic32 old_value = *ptr; + Atomic32 new_value = old_value + increment; + if (pLinuxKernelCmpxchg(old_value, new_value, + const_cast(ptr)) == 0) { + // The exchange took place as expected. + return new_value; + } + // Otherwise, *ptr changed mid-loop and we need to retry. + } +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void MemoryBarrier() { + pLinuxKernelMemoryBarrier(); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm_qnx.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm_qnx.h new file mode 100644 index 0000000..17dfaa5 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_arm_qnx.h @@ -0,0 +1,146 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_ + +// For _smp_cmpxchg() +#include + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 QNXCmpxchg(Atomic32 old_value, + Atomic32 new_value, + volatile Atomic32* ptr) { + return static_cast( + _smp_cmpxchg((volatile unsigned *)ptr, + (unsigned)old_value, + (unsigned)new_value)); +} + + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev_value = *ptr; + do { + if (!QNXCmpxchg(old_value, new_value, + const_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 old_value; + do { + old_value = *ptr; + } while (QNXCmpxchg(old_value, new_value, + const_cast(ptr))); + return old_value; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return Barrier_AtomicIncrement(ptr, increment); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + for (;;) { + // Atomic exchange the old value with an incremented one. + Atomic32 old_value = *ptr; + Atomic32 new_value = old_value + increment; + if (QNXCmpxchg(old_value, new_value, + const_cast(ptr)) == 0) { + // The exchange took place as expected. + return new_value; + } + // Otherwise, *ptr changed mid-loop and we need to retry. + } +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void MemoryBarrier() { + __sync_synchronize(); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_atomicword_compat.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_atomicword_compat.h new file mode 100644 index 0000000..eb198ff --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_atomicword_compat.h @@ -0,0 +1,122 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ + +// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32, +// which in turn means int. On some LP32 platforms, intptr_t is an int, but +// on others, it's a long. When AtomicWord and Atomic32 are based on different +// fundamental types, their pointers are incompatible. +// +// This file defines function overloads to allow both AtomicWord and Atomic32 +// data to be used with this interface. +// +// On LP64 platforms, AtomicWord and Atomic64 are both always long, +// so this problem doesn't occur. + +#if !defined(GOOGLE_PROTOBUF_ARCH_64_BIT) + +namespace google { +namespace protobuf { +namespace internal { + +inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return NoBarrier_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr, + AtomicWord new_value) { + return NoBarrier_AtomicExchange( + reinterpret_cast(ptr), new_value); +} + +inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr, + AtomicWord increment) { + return NoBarrier_AtomicIncrement( + reinterpret_cast(ptr), increment); +} + +inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr, + AtomicWord increment) { + return Barrier_AtomicIncrement( + reinterpret_cast(ptr), increment); +} + +inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return Acquire_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr, + AtomicWord old_value, + AtomicWord new_value) { + return Release_CompareAndSwap( + reinterpret_cast(ptr), old_value, new_value); +} + +inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) { + NoBarrier_Store(reinterpret_cast(ptr), value); +} + +inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) { + return Acquire_Store(reinterpret_cast(ptr), value); +} + +inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) { + return Release_Store(reinterpret_cast(ptr), value); +} + +inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) { + return NoBarrier_Load(reinterpret_cast(ptr)); +} + +inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) { + return Acquire_Load(reinterpret_cast(ptr)); +} + +inline AtomicWord Release_Load(volatile const AtomicWord* ptr) { + return Release_Load(reinterpret_cast(ptr)); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // !defined(GOOGLE_PROTOBUF_ARCH_64_BIT) + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_generic_gcc.h new file mode 100644 index 0000000..7314ee4 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_generic_gcc.h @@ -0,0 +1,155 @@ +// Copyright 2013 Red Hat Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Red Hat Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_ + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __ATOMIC_RELAXED, __ATOMIC_RELAXED); + return old_value; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED); +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return __atomic_add_fetch(ptr, increment, __ATOMIC_SEQ_CST); +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); + return old_value; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __ATOMIC_RELEASE, __ATOMIC_ACQUIRE); + return old_value; +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + __atomic_store_n(ptr, value, __ATOMIC_RELAXED); +} + +inline void MemoryBarrier() { + __sync_synchronize(); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + __atomic_store_n(ptr, value, __ATOMIC_RELEASE); +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return __atomic_load_n(ptr, __ATOMIC_RELAXED); +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + return __atomic_load_n(ptr, __ATOMIC_ACQUIRE); +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + return __atomic_load_n(ptr, __ATOMIC_SEQ_CST); +} + +#ifdef __LP64__ + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + __atomic_store_n(ptr, value, __ATOMIC_RELEASE); +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + return __atomic_load_n(ptr, __ATOMIC_ACQUIRE); +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); + return old_value; +} + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + __atomic_compare_exchange_n(ptr, &old_value, new_value, true, + __ATOMIC_RELAXED, __ATOMIC_RELAXED); + return old_value; +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED); +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + __atomic_store_n(ptr, value, __ATOMIC_RELAXED); +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED); +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return __atomic_load_n(ptr, __ATOMIC_RELAXED); +} + +#endif // defined(__LP64__) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_macosx.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_macosx.h new file mode 100644 index 0000000..7963324 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_macosx.h @@ -0,0 +1,225 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ + +#include + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev_value; + do { + if (OSAtomicCompareAndSwap32(old_value, new_value, + const_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 old_value; + do { + old_value = *ptr; + } while (!OSAtomicCompareAndSwap32(old_value, new_value, + const_cast(ptr))); + return old_value; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return OSAtomicAdd32(increment, const_cast(ptr)); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return OSAtomicAdd32Barrier(increment, const_cast(ptr)); +} + +inline void MemoryBarrier() { + OSMemoryBarrier(); +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev_value; + do { + if (OSAtomicCompareAndSwap32Barrier(old_value, new_value, + const_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return Acquire_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +#ifdef __LP64__ + +// 64-bit implementation on 64-bit platform + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev_value; + do { + if (OSAtomicCompareAndSwap64(old_value, new_value, + reinterpret_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + Atomic64 old_value; + do { + old_value = *ptr; + } while (!OSAtomicCompareAndSwap64(old_value, new_value, + reinterpret_cast(ptr))); + return old_value; +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return OSAtomicAdd64(increment, reinterpret_cast(ptr)); +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return OSAtomicAdd64Barrier(increment, + reinterpret_cast(ptr)); +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev_value; + do { + if (OSAtomicCompareAndSwap64Barrier( + old_value, new_value, reinterpret_cast(ptr))) { + return old_value; + } + prev_value = *ptr; + } while (prev_value == old_value); + return prev_value; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + // The lib kern interface does not distinguish between + // Acquire and Release memory barriers; they are equivalent. + return Acquire_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return *ptr; +} + +#endif // defined(__LP64__) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_mips_gcc.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_mips_gcc.h new file mode 100644 index 0000000..f5837c9 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_mips_gcc.h @@ -0,0 +1,313 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_ + +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory") + +namespace google { +namespace protobuf { +namespace internal { + +// Atomically execute: +// result = *ptr; +// if (*ptr == old_value) +// *ptr = new_value; +// return result; +// +// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". +// Always return the old value of "*ptr" +// +// This routine implies no memory barriers. +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev, tmp; + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "ll %0, %5\n" // prev = *ptr + "bne %0, %3, 2f\n" // if (prev != old_value) goto 2 + "move %2, %4\n" // tmp = new_value + "sc %2, %1\n" // *ptr = tmp (with atomic check) + "beqz %2, 1b\n" // start again on atomic error + "nop\n" // delay slot nop + "2:\n" + ".set pop\n" + : "=&r" (prev), "=m" (*ptr), "=&r" (tmp) + : "r" (old_value), "r" (new_value), "m" (*ptr) + : "memory"); + return prev; +} + +// Atomically store new_value into *ptr, returning the previous value held in +// *ptr. This routine implies no memory barriers. +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 temp, old; + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "ll %1, %4\n" // old = *ptr + "move %0, %3\n" // temp = new_value + "sc %0, %2\n" // *ptr = temp (with atomic check) + "beqz %0, 1b\n" // start again on atomic error + "nop\n" // delay slot nop + ".set pop\n" + : "=&r" (temp), "=&r" (old), "=m" (*ptr) + : "r" (new_value), "m" (*ptr) + : "memory"); + + return old; +} + +// Atomically increment *ptr by "increment". Returns the new value of +// *ptr with the increment applied. This routine implies no memory barriers. +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 temp, temp2; + + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "ll %0, %4\n" // temp = *ptr + "addu %1, %0, %3\n" // temp2 = temp + increment + "sc %1, %2\n" // *ptr = temp2 (with atomic check) + "beqz %1, 1b\n" // start again on atomic error + "addu %1, %0, %3\n" // temp2 = temp + increment + ".set pop\n" + : "=&r" (temp), "=&r" (temp2), "=m" (*ptr) + : "Ir" (increment), "m" (*ptr) + : "memory"); + // temp2 now holds the final value. + return temp2; +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + ATOMICOPS_COMPILER_BARRIER(); + Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment); + ATOMICOPS_COMPILER_BARRIER(); + return res; +} + +// "Acquire" operations +// ensure that no later memory access can be reordered ahead of the operation. +// "Release" operations ensure that no previous memory access can be reordered +// after the operation. "Barrier" operations have both "Acquire" and "Release" +// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory +// access. +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + ATOMICOPS_COMPILER_BARRIER(); + Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + ATOMICOPS_COMPILER_BARRIER(); + return res; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + ATOMICOPS_COMPILER_BARRIER(); + Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + ATOMICOPS_COMPILER_BARRIER(); + return res; +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void MemoryBarrier() { + __asm__ __volatile__("sync" : : : "memory"); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +#if defined(__LP64__) +// 64-bit versions of the atomic ops. + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev, tmp; + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "lld %0, %5\n" // prev = *ptr + "bne %0, %3, 2f\n" // if (prev != old_value) goto 2 + "move %2, %4\n" // tmp = new_value + "scd %2, %1\n" // *ptr = tmp (with atomic check) + "beqz %2, 1b\n" // start again on atomic error + "nop\n" // delay slot nop + "2:\n" + ".set pop\n" + : "=&r" (prev), "=m" (*ptr), "=&r" (tmp) + : "r" (old_value), "r" (new_value), "m" (*ptr) + : "memory"); + return prev; +} + +// Atomically store new_value into *ptr, returning the previous value held in +// *ptr. This routine implies no memory barriers. +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + Atomic64 temp, old; + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "lld %1, %4\n" // old = *ptr + "move %0, %3\n" // temp = new_value + "scd %0, %2\n" // *ptr = temp (with atomic check) + "beqz %0, 1b\n" // start again on atomic error + "nop\n" // delay slot nop + ".set pop\n" + : "=&r" (temp), "=&r" (old), "=m" (*ptr) + : "r" (new_value), "m" (*ptr) + : "memory"); + + return old; +} + +// Atomically increment *ptr by "increment". Returns the new value of +// *ptr with the increment applied. This routine implies no memory barriers. +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + Atomic64 temp, temp2; + + __asm__ __volatile__(".set push\n" + ".set noreorder\n" + "1:\n" + "lld %0, %4\n" // temp = *ptr + "daddu %1, %0, %3\n" // temp2 = temp + increment + "scd %1, %2\n" // *ptr = temp2 (with atomic check) + "beqz %1, 1b\n" // start again on atomic error + "daddu %1, %0, %3\n" // temp2 = temp + increment + ".set pop\n" + : "=&r" (temp), "=&r" (temp2), "=m" (*ptr) + : "Ir" (increment), "m" (*ptr) + : "memory"); + // temp2 now holds the final value. + return temp2; +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + MemoryBarrier(); + Atomic64 res = NoBarrier_AtomicIncrement(ptr, increment); + MemoryBarrier(); + return res; +} + +// "Acquire" operations +// ensure that no later memory access can be reordered ahead of the operation. +// "Release" operations ensure that no previous memory access can be reordered +// after the operation. "Barrier" operations have both "Acquire" and "Release" +// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory +// access. +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); + return res; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + MemoryBarrier(); + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return *ptr; +} +#endif + +} // namespace internal +} // namespace protobuf +} // namespace google + +#undef ATOMICOPS_COMPILER_BARRIER + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_pnacl.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_pnacl.h new file mode 100644 index 0000000..3b314fd --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_pnacl.h @@ -0,0 +1,231 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_ + +#include + +namespace google { +namespace protobuf { +namespace internal { + +// This implementation is transitional and maintains the original API for +// atomicops.h. This requires casting memory locations to the atomic types, and +// assumes that the API and the C++11 implementation are layout-compatible, +// which isn't true for all implementations or hardware platforms. The static +// assertion should detect this issue, were it to fire then this header +// shouldn't be used. +// +// TODO(jfb) If this header manages to stay committed then the API should be +// modified, and all call sites updated. +typedef volatile std::atomic* AtomicLocation32; +static_assert(sizeof(*(AtomicLocation32) nullptr) == sizeof(Atomic32), + "incompatible 32-bit atomic layout"); + +inline void MemoryBarrier() { +#if defined(__GLIBCXX__) + // Work around libstdc++ bug 51038 where atomic_thread_fence was declared but + // not defined, leading to the linker complaining about undefined references. + __atomic_thread_fence(std::memory_order_seq_cst); +#else + std::atomic_thread_fence(std::memory_order_seq_cst); +#endif +} + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + ((AtomicLocation32)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_relaxed, + std::memory_order_relaxed); + return old_value; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + return ((AtomicLocation32)ptr) + ->exchange(new_value, std::memory_order_relaxed); +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return increment + + ((AtomicLocation32)ptr) + ->fetch_add(increment, std::memory_order_relaxed); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return increment + ((AtomicLocation32)ptr)->fetch_add(increment); +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + ((AtomicLocation32)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_acquire, + std::memory_order_acquire); + return old_value; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + ((AtomicLocation32)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_release, + std::memory_order_relaxed); + return old_value; +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + ((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + ((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed); + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + ((AtomicLocation32)ptr)->store(value, std::memory_order_release); +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed); +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + return ((AtomicLocation32)ptr)->load(std::memory_order_acquire); +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed); +} + +#if defined(GOOGLE_PROTOBUF_ARCH_64_BIT) + +typedef volatile std::atomic* AtomicLocation64; +static_assert(sizeof(*(AtomicLocation64) nullptr) == sizeof(Atomic64), + "incompatible 64-bit atomic layout"); + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + ((AtomicLocation64)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_relaxed, + std::memory_order_relaxed); + return old_value; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + return ((AtomicLocation64)ptr) + ->exchange(new_value, std::memory_order_relaxed); +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return increment + + ((AtomicLocation64)ptr) + ->fetch_add(increment, std::memory_order_relaxed); +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return increment + ((AtomicLocation64)ptr)->fetch_add(increment); +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + ((AtomicLocation64)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_acquire, + std::memory_order_acquire); + return old_value; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + ((AtomicLocation64)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_release, + std::memory_order_relaxed); + return old_value; +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + ((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed); +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + ((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed); + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + ((AtomicLocation64)ptr)->store(value, std::memory_order_release); +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed); +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + return ((AtomicLocation64)ptr)->load(std::memory_order_acquire); +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed); +} + +#endif // defined(GOOGLE_PROTOBUF_ARCH_64_BIT) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_power.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_power.h new file mode 100644 index 0000000..b8a42f2 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_power.h @@ -0,0 +1,440 @@ +// Copyright 2014 Bloomberg Finance LP. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Bloomberg Finance LP. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_AIX_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_AIX_H_ + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 result; + + asm volatile ( + "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve + " cmpw %[cmp], %[res] \n\t" // compare values + " bne- 2f \n\t" + " stwcx. %[val], %[zero], %[obj] \n\t" // store new value + " bne- 1b \n\t" + "2: \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [cmp] "b" (old_value), + [val] "b" (new_value), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + Atomic32 result; + + asm volatile ( + "1: lwarx %[res], %[zero], %[obj] \n\t" + " stwcx. %[val], %[zero], %[obj] \n\t" + " bne- 1b \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [val] "b" (new_value), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 result; + + asm volatile ( + "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve + " add %[res], %[val], %[res] \n\t" // add the operand + " stwcx. %[res], %[zero], %[obj] \n\t" // store old value + // if still reserved + " bne- 1b \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [val] "b" (increment), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline void MemoryBarrier(void) { + asm volatile ( + " lwsync \n\t" + " isync \n\t" + : + : + : "memory"); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 result; + + asm volatile ( + " lwsync \n\t" + + "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve + " add %[res], %[val], %[res] \n\t" // add the operand + " stwcx. %[res], %[zero], %[obj] \n\t" // store old value + // if still reserved + " bne- 1b \n\t" + " isync \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [val] "b" (increment), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 result; + + asm volatile ( + "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve + " cmpw %[cmp], %[res] \n\t" // compare values + " bne- 2f \n\t" + " stwcx. %[val], %[zero], %[obj] \n\t" // store new value + " bne- 1b \n\t" + + " isync \n\t" + "2: \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [cmp] "b" (old_value), + [val] "b" (new_value), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 result; + + asm volatile ( + " lwsync \n\t" + + "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve + " cmpw %[cmp], %[res] \n\t" // compare values + " bne- 2f \n\t" + " stwcx. %[val], %[zero], %[obj] \n\t" // store new value + " bne- 1b \n\t" + + "2: \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [cmp] "b" (old_value), + [val] "b" (new_value), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + asm volatile ( + " stw %[val], %[obj] \n\t" + " isync \n\t" + : [obj] "=m" (*ptr) + : [val] "b" (value)); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + asm volatile ( + " lwsync \n\t" + " stw %[val], %[obj] \n\t" + : [obj] "=m" (*ptr) + : [val] "b" (value)); +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 result; + + asm volatile ( + "1: lwz %[res], %[obj] \n\t" + " cmpw %[res], %[res] \n\t" // create data + // dependency for + // load/load ordering + " bne- 1b \n\t" // never taken + + " isync \n\t" + : [res] "=b" (result) + : [obj] "m" (*ptr), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + Atomic32 result; + + asm volatile ( + " lwsync \n\t" + + "1: lwz %[res], %[obj] \n\t" + " cmpw %[res], %[res] \n\t" // create data + // dependency for + // load/load ordering + " bne- 1b \n\t" // never taken + : [res] "=b" (result) + : [obj] "m" (*ptr), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 result; + + asm volatile ( + "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve + " cmpd %[cmp], %[res] \n\t" // compare values + " bne- 2f \n\t" + + " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value + " bne- 1b \n\t" + "2: \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [cmp] "b" (old_value), + [val] "b" (new_value), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + Atomic64 result; + + asm volatile ( + "1: ldarx %[res], %[zero], %[obj] \n\t" + " stdcx. %[val], %[zero], %[obj] \n\t" + " bne- 1b \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [val] "b" (new_value), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + Atomic64 result; + + asm volatile ( + "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve + " add %[res], %[res], %[val] \n\t" // add the operand + " stdcx. %[res], %[zero], %[obj] \n\t" // store old value if + // still reserved + + " bne- 1b \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [val] "b" (increment), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + + Atomic64 result; + + asm volatile ( + " lwsync \n\t" + + "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve + " add %[res], %[res], %[val] \n\t" // add the operand + " stdcx. %[res], %[zero], %[obj] \n\t" // store old value if + // still reserved + + " bne- 1b \n\t" + + " isync \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [val] "b" (increment), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 result; + + asm volatile ( + "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve + " cmpd %[cmp], %[res] \n\t" // compare values + " bne- 2f \n\t" + + " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value + " bne- 1b \n\t" + " isync \n\t" + "2: \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [cmp] "b" (old_value), + [val] "b" (new_value), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 result; + + asm volatile ( + " lwsync \n\t" + + "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve + " cmpd %[cmp], %[res] \n\t" // compare values + " bne- 2f \n\t" + + " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value + " bne- 1b \n\t" + "2: \n\t" + : [res] "=&b" (result) + : [obj] "b" (ptr), + [cmp] "b" (old_value), + [val] "b" (new_value), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + asm volatile ( + " std %[val], %[obj] \n\t" + " isync \n\t" + : [obj] "=m" (*ptr) + : [val] "b" (value)); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + asm volatile ( + " lwsync \n\t" + " std %[val], %[obj] \n\t" + : [obj] "=m" (*ptr) + : [val] "b" (value)); +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 result; + + asm volatile ( + "1: ld %[res], %[obj] \n\t" + " cmpd %[res], %[res] \n\t" // create data + // dependency for + // load/load ordering + " bne- 1b \n\t" // never taken + + " isync \n\t" + : [res] "=b" (result) + : [obj] "m" (*ptr), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + Atomic64 result; + + asm volatile ( + " lwsync \n\t" + + "1: ld %[res], %[obj] \n\t" + " cmpd %[res], %[res] \n\t" // create data + // dependency for + // load/load ordering + " bne- 1b \n\t" // never taken + : [res] "=b" (result) + : [obj] "m" (*ptr), + [zero] "i" (0) + : "cr0", "ctr"); + + return result; +} +#endif + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_ppc_gcc.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_ppc_gcc.h new file mode 100644 index 0000000..8231a57 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_ppc_gcc.h @@ -0,0 +1,155 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: ogabbay@advaoptical.com (Oded Gabbay) +// Cleaned up by: bsilver16384@gmail.com (Brian Silverman) +// +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_ + +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory") + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev; + + __asm__ __volatile__( + "0: \n\t" + "lwarx %[prev],0,%[ptr] \n\t" + "cmpw 0,%[prev],%[old_value] \n\t" + "bne- 1f \n\t" + "stwcx. %[new_value],0,%[ptr] \n\t" + "bne- 0b \n\t" + "1: \n\t" + : [prev] "=&r"(prev), "+m"(*ptr) + : [ptr] "r"(ptr), [old_value] "r"(old_value), [new_value] "r"(new_value) + : "cc", "memory"); + + return prev; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr, + Atomic32 new_value) { + Atomic32 old; + + __asm__ __volatile__( + "0: \n\t" + "lwarx %[old],0,%[ptr] \n\t" + "stwcx. %[new_value],0,%[ptr] \n\t" + "bne- 0b \n\t" + : [old] "=&r"(old), "+m"(*ptr) + : [ptr] "r"(ptr), [new_value] "r"(new_value) + : "cc", "memory"); + + return old; +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr, + Atomic32 increment) { + Atomic32 temp; + + __asm__ __volatile__( + "0: \n\t" + "lwarx %[temp],0,%[ptr] \n\t" + "add %[temp],%[increment],%[temp] \n\t" + "stwcx. %[temp],0,%[ptr] \n\t" + "bne- 0b \n\t" + : [temp] "=&r"(temp) + : [increment] "r"(increment), [ptr] "r"(ptr) + : "cc", "memory"); + + return temp; +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr, + Atomic32 increment) { + MemoryBarrier(); + Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment); + MemoryBarrier(); + return res; +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr, + Atomic32 old_value, Atomic32 new_value) { + Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); + return res; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr, + Atomic32 old_value, Atomic32 new_value) { + MemoryBarrier(); + Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + return res; +} + +inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) { + *ptr = value; +} + +inline void MemoryBarrier() { __asm__ __volatile__("sync" : : : "memory"); } + +inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) { + MemoryBarrier(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) { return *ptr; } + +inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) { + Atomic32 value = *ptr; + MemoryBarrier(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32 *ptr) { + MemoryBarrier(); + return *ptr; +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#undef ATOMICOPS_COMPILER_BARRIER + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_solaris.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_solaris.h new file mode 100644 index 0000000..d8057ec --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_solaris.h @@ -0,0 +1,188 @@ +// Copyright 2014 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_ + +#include + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return (Atomic32)atomic_cas_32((volatile uint32_t*)ptr, (uint32_t)old_value, (uint32_t)new_value); +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + return (Atomic32)atomic_swap_32((volatile uint32_t*)ptr, (uint32_t)new_value); +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return (Atomic32)atomic_add_32_nv((volatile uint32_t*)ptr, (uint32_t)increment); +} + +inline void MemoryBarrier(void) { + membar_producer(); + membar_consumer(); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + MemoryBarrier(); + Atomic32 ret = NoBarrier_AtomicIncrement(ptr, increment); + MemoryBarrier(); + + return ret; +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); + + return ret; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + MemoryBarrier(); + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + membar_producer(); +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + membar_consumer(); + *ptr = value; +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 val = *ptr; + membar_consumer(); + return val; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + membar_producer(); + return *ptr; +} + +#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + return atomic_cas_64((volatile uint64_t*)ptr, (uint64_t)old_value, (uint64_t)new_value); +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value) { + return atomic_swap_64((volatile uint64_t*)ptr, (uint64_t)new_value); +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) { + return atomic_add_64_nv((volatile uint64_t*)ptr, increment); +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) { + MemoryBarrier(); + Atomic64 ret = atomic_add_64_nv((volatile uint64_t*)ptr, increment); + MemoryBarrier(); + return ret; +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + MemoryBarrier(); + return ret; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + MemoryBarrier(); + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; + membar_producer(); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + membar_consumer(); + *ptr = value; +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 ret = *ptr; + membar_consumer(); + return ret; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + membar_producer(); + return *ptr; +} +#endif + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_ + diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_tsan.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_tsan.h new file mode 100644 index 0000000..0c90354 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_tsan.h @@ -0,0 +1,219 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2013 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation for compiler-based +// ThreadSanitizer (http://clang.llvm.org/docs/ThreadSanitizer.html). +// Use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_ + +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory") + +#include + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 cmp = old_value; + __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value, + __tsan_memory_order_relaxed, __tsan_memory_order_relaxed); + return cmp; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr, + Atomic32 new_value) { + return __tsan_atomic32_exchange(ptr, new_value, + __tsan_memory_order_relaxed); +} + +inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr, + Atomic32 new_value) { + return __tsan_atomic32_exchange(ptr, new_value, + __tsan_memory_order_acquire); +} + +inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr, + Atomic32 new_value) { + return __tsan_atomic32_exchange(ptr, new_value, + __tsan_memory_order_release); +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr, + Atomic32 increment) { + return increment + __tsan_atomic32_fetch_add(ptr, increment, + __tsan_memory_order_relaxed); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr, + Atomic32 increment) { + return increment + __tsan_atomic32_fetch_add(ptr, increment, + __tsan_memory_order_acq_rel); +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 cmp = old_value; + __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value, + __tsan_memory_order_acquire, __tsan_memory_order_acquire); + return cmp; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 cmp = old_value; + __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value, + __tsan_memory_order_release, __tsan_memory_order_relaxed); + return cmp; +} + +inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) { + __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed); +} + +inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) { + __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed); + __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); +} + +inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) { + __tsan_atomic32_store(ptr, value, __tsan_memory_order_release); +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) { + return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed); +} + +inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) { + return __tsan_atomic32_load(ptr, __tsan_memory_order_acquire); +} + +inline Atomic32 Release_Load(volatile const Atomic32 *ptr) { + __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); + return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed); +} + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 cmp = old_value; + __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value, + __tsan_memory_order_relaxed, __tsan_memory_order_relaxed); + return cmp; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr, + Atomic64 new_value) { + return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_relaxed); +} + +inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr, + Atomic64 new_value) { + return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_acquire); +} + +inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr, + Atomic64 new_value) { + return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_release); +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr, + Atomic64 increment) { + return increment + __tsan_atomic64_fetch_add(ptr, increment, + __tsan_memory_order_relaxed); +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr, + Atomic64 increment) { + return increment + __tsan_atomic64_fetch_add(ptr, increment, + __tsan_memory_order_acq_rel); +} + +inline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) { + __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed); +} + +inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) { + __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed); + __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); +} + +inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) { + __tsan_atomic64_store(ptr, value, __tsan_memory_order_release); +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) { + return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed); +} + +inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) { + return __tsan_atomic64_load(ptr, __tsan_memory_order_acquire); +} + +inline Atomic64 Release_Load(volatile const Atomic64 *ptr) { + __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); + return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed); +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 cmp = old_value; + __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value, + __tsan_memory_order_acquire, __tsan_memory_order_acquire); + return cmp; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 cmp = old_value; + __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value, + __tsan_memory_order_release, __tsan_memory_order_relaxed); + return cmp; +} + +inline void MemoryBarrier() { + __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#undef ATOMICOPS_COMPILER_BARRIER + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_x86_gcc.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_x86_gcc.h new file mode 100644 index 0000000..edccc59 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_x86_gcc.h @@ -0,0 +1,293 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_ + +namespace google { +namespace protobuf { +namespace internal { + +// This struct is not part of the public API of this module; clients may not +// use it. +// Features of this x86. Values may not be correct before main() is run, +// but are set conservatively. +struct AtomicOps_x86CPUFeatureStruct { + bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence + // after acquire compare-and-swap. + bool has_sse2; // Processor has SSE2. +}; +extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures; + +#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory") + +// 32-bit low-level operations on any platform. + +inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 prev; + __asm__ __volatile__("lock; cmpxchgl %1,%2" + : "=a" (prev) + : "q" (new_value), "m" (*ptr), "0" (old_value) + : "memory"); + return prev; +} + +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + __asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg. + : "=r" (new_value) + : "m" (*ptr), "0" (new_value) + : "memory"); + return new_value; // Now it's the previous value. +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 temp = increment; + __asm__ __volatile__("lock; xaddl %0,%1" + : "+r" (temp), "+m" (*ptr) + : : "memory"); + // temp now holds the old value of *ptr + return temp + increment; +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + Atomic32 temp = increment; + __asm__ __volatile__("lock; xaddl %0,%1" + : "+r" (temp), "+m" (*ptr) + : : "memory"); + // temp now holds the old value of *ptr + if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { + __asm__ __volatile__("lfence" : : : "memory"); + } + return temp + increment; +} + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { + __asm__ __volatile__("lfence" : : : "memory"); + } + return x; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +#if defined(__x86_64__) + +// 64-bit implementations of memory barrier can be simpler, because it +// "mfence" is guaranteed to exist. +inline void MemoryBarrier() { + __asm__ __volatile__("mfence" : : : "memory"); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; + MemoryBarrier(); +} + +#else + +inline void MemoryBarrier() { + if (AtomicOps_Internalx86CPUFeatures.has_sse2) { + __asm__ __volatile__("mfence" : : : "memory"); + } else { // mfence is faster but not present on PIII + Atomic32 x = 0; + NoBarrier_AtomicExchange(&x, 0); // acts as a barrier on PIII + } +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + if (AtomicOps_Internalx86CPUFeatures.has_sse2) { + *ptr = value; + __asm__ __volatile__("mfence" : : : "memory"); + } else { + NoBarrier_AtomicExchange(ptr, value); + // acts as a barrier on PIII + } +} +#endif + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + ATOMICOPS_COMPILER_BARRIER(); + *ptr = value; // An x86 store acts as a release barrier. + // See comments in Atomic64 version of Release_Store(), below. +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; // An x86 load acts as a acquire barrier. + // See comments in Atomic64 version of Release_Store(), below. + ATOMICOPS_COMPILER_BARRIER(); + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +#if defined(__x86_64__) + +// 64-bit low-level operations on 64-bit platform. + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 prev; + __asm__ __volatile__("lock; cmpxchgq %1,%2" + : "=a" (prev) + : "q" (new_value), "m" (*ptr), "0" (old_value) + : "memory"); + return prev; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + __asm__ __volatile__("xchgq %1,%0" // The lock prefix is implicit for xchg. + : "=r" (new_value) + : "m" (*ptr), "0" (new_value) + : "memory"); + return new_value; // Now it's the previous value. +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + Atomic64 temp = increment; + __asm__ __volatile__("lock; xaddq %0,%1" + : "+r" (temp), "+m" (*ptr) + : : "memory"); + // temp now contains the previous value of *ptr + return temp + increment; +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + Atomic64 temp = increment; + __asm__ __volatile__("lock; xaddq %0,%1" + : "+r" (temp), "+m" (*ptr) + : : "memory"); + // temp now contains the previous value of *ptr + if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { + __asm__ __volatile__("lfence" : : : "memory"); + } + return temp + increment; +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; + MemoryBarrier(); +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + ATOMICOPS_COMPILER_BARRIER(); + + *ptr = value; // An x86 store acts as a release barrier + // for current AMD/Intel chips as of Jan 2008. + // See also Acquire_Load(), below. + + // When new chips come out, check: + // IA-32 Intel Architecture Software Developer's Manual, Volume 3: + // System Programming Guide, Chatper 7: Multiple-processor management, + // Section 7.2, Memory Ordering. + // Last seen at: + // http://developer.intel.com/design/pentium4/manuals/index_new.htm + // + // x86 stores/loads fail to act as barriers for a few instructions (clflush + // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are + // not generated by the compiler, and are rare. Users of these instructions + // need to know about cache behaviour in any case since all of these involve + // either flushing cache lines or non-temporal cache hints. +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 value = *ptr; // An x86 load acts as a acquire barrier, + // for current AMD/Intel chips as of Jan 2008. + // See also Release_Store(), above. + ATOMICOPS_COMPILER_BARRIER(); + return value; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return *ptr; +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) { + __asm__ __volatile__("lfence" : : : "memory"); + } + return x; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +#endif // defined(__x86_64__) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#undef ATOMICOPS_COMPILER_BARRIER + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_x86_msvc.h b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_x86_msvc.h new file mode 100644 index 0000000..e53a641 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/atomicops_internals_x86_msvc.h @@ -0,0 +1,150 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is an internal atomic implementation, use atomicops.h instead. + +#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_ +#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_ + +namespace google { +namespace protobuf { +namespace internal { + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return Barrier_AtomicIncrement(ptr, increment); +} + +#if !(defined(_MSC_VER) && _MSC_VER >= 1400) +#error "We require at least vs2005 for MemoryBarrier" +#endif + +inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + NoBarrier_AtomicExchange(ptr, value); + // acts as a barrier in this implementation +} + +inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { + *ptr = value; // works w/o barrier for current Intel chips as of June 2005 + // See comments in Atomic64 version of Release_Store() below. +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return *ptr; +} + +inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { + Atomic32 value = *ptr; + return value; +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return *ptr; +} + +#if defined(_WIN64) + +// 64-bit low-level operations on 64-bit platform. + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return Barrier_AtomicIncrement(ptr, increment); +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + NoBarrier_AtomicExchange(ptr, value); + // acts as a barrier in this implementation +} + +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + *ptr = value; // works w/o barrier for current Intel chips as of June 2005 + + // When new chips come out, check: + // IA-32 Intel Architecture Software Developer's Manual, Volume 3: + // System Programming Guide, Chatper 7: Multiple-processor management, + // Section 7.2, Memory Ordering. + // Last seen at: + // http://developer.intel.com/design/pentium4/manuals/index_new.htm +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return *ptr; +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + Atomic64 value = *ptr; + return value; +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return *ptr; +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + return NoBarrier_CompareAndSwap(ptr, old_value, new_value); +} + +#endif // defined(_WIN64) + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/bytestream.h b/thirdparty/linux/include/google/protobuf/stubs/bytestream.h new file mode 100644 index 0000000..07604e1 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/bytestream.h @@ -0,0 +1,348 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file declares the ByteSink and ByteSource abstract interfaces. These +// interfaces represent objects that consume (ByteSink) or produce (ByteSource) +// a sequence of bytes. Using these abstract interfaces in your APIs can help +// make your code work with a variety of input and output types. +// +// This file also declares the following commonly used implementations of these +// interfaces. +// +// ByteSink: +// UncheckedArrayByteSink Writes to an array, without bounds checking +// CheckedArrayByteSink Writes to an array, with bounds checking +// GrowingArrayByteSink Allocates and writes to a growable buffer +// StringByteSink Writes to an STL string +// NullByteSink Consumes a never-ending stream of bytes +// +// ByteSource: +// ArrayByteSource Reads from an array or string/StringPiece +// LimitedByteSource Limits the number of bytes read from an + +#ifndef GOOGLE_PROTOBUF_STUBS_BYTESTREAM_H_ +#define GOOGLE_PROTOBUF_STUBS_BYTESTREAM_H_ + +#include +#include + +#include +#include + +class CordByteSink; +class MemBlock; + +namespace google { +namespace protobuf { +namespace strings { + +// An abstract interface for an object that consumes a sequence of bytes. This +// interface offers 3 different ways to append data, and a Flush() function. +// +// Example: +// +// string my_data; +// ... +// ByteSink* sink = ... +// sink->Append(my_data.data(), my_data.size()); +// sink->Flush(); +// +class LIBPROTOBUF_EXPORT ByteSink { + public: + ByteSink() {} + virtual ~ByteSink() {} + + // Appends the "n" bytes starting at "bytes". + virtual void Append(const char* bytes, size_t n) = 0; + + // Flushes internal buffers. The default implemenation does nothing. ByteSink + // subclasses may use internal buffers that require calling Flush() at the end + // of the stream. + virtual void Flush(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ByteSink); +}; + +// An abstract interface for an object that produces a fixed-size sequence of +// bytes. +// +// Example: +// +// ByteSource* source = ... +// while (source->Available() > 0) { +// StringPiece data = source->Peek(); +// ... do something with "data" ... +// source->Skip(data.length()); +// } +// +class LIBPROTOBUF_EXPORT ByteSource { + public: + ByteSource() {} + virtual ~ByteSource() {} + + // Returns the number of bytes left to read from the source. Available() + // should decrease by N each time Skip(N) is called. Available() may not + // increase. Available() returning 0 indicates that the ByteSource is + // exhausted. + // + // Note: Size() may have been a more appropriate name as it's more + // indicative of the fixed-size nature of a ByteSource. + virtual size_t Available() const = 0; + + // Returns a StringPiece of the next contiguous region of the source. Does not + // reposition the source. The returned region is empty iff Available() == 0. + // + // The returned region is valid until the next call to Skip() or until this + // object is destroyed, whichever occurs first. + // + // The length of the returned StringPiece will be <= Available(). + virtual StringPiece Peek() = 0; + + // Skips the next n bytes. Invalidates any StringPiece returned by a previous + // call to Peek(). + // + // REQUIRES: Available() >= n + virtual void Skip(size_t n) = 0; + + // Writes the next n bytes in this ByteSource to the given ByteSink, and + // advances this ByteSource past the copied bytes. The default implementation + // of this method just copies the bytes normally, but subclasses might + // override CopyTo to optimize certain cases. + // + // REQUIRES: Available() >= n + virtual void CopyTo(ByteSink* sink, size_t n); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ByteSource); +}; + +// +// Some commonly used implementations of ByteSink +// + +// Implementation of ByteSink that writes to an unsized byte array. No +// bounds-checking is performed--it is the caller's responsibility to ensure +// that the destination array is large enough. +// +// Example: +// +// char buf[10]; +// UncheckedArrayByteSink sink(buf); +// sink.Append("hi", 2); // OK +// sink.Append(data, 100); // WOOPS! Overflows buf[10]. +// +class LIBPROTOBUF_EXPORT UncheckedArrayByteSink : public ByteSink { + public: + explicit UncheckedArrayByteSink(char* dest) : dest_(dest) {} + virtual void Append(const char* data, size_t n); + + // Returns the current output pointer so that a caller can see how many bytes + // were produced. + // + // Note: this method is not part of the ByteSink interface. + char* CurrentDestination() const { return dest_; } + + private: + char* dest_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UncheckedArrayByteSink); +}; + +// Implementation of ByteSink that writes to a sized byte array. This sink will +// not write more than "capacity" bytes to outbuf. Once "capacity" bytes are +// appended, subsequent bytes will be ignored and Overflowed() will return true. +// Overflowed() does not cause a runtime error (i.e., it does not CHECK fail). +// +// Example: +// +// char buf[10]; +// CheckedArrayByteSink sink(buf, 10); +// sink.Append("hi", 2); // OK +// sink.Append(data, 100); // Will only write 8 more bytes +// +class LIBPROTOBUF_EXPORT CheckedArrayByteSink : public ByteSink { + public: + CheckedArrayByteSink(char* outbuf, size_t capacity); + virtual void Append(const char* bytes, size_t n); + + // Returns the number of bytes actually written to the sink. + size_t NumberOfBytesWritten() const { return size_; } + + // Returns true if any bytes were discarded, i.e., if there was an + // attempt to write more than 'capacity' bytes. + bool Overflowed() const { return overflowed_; } + + private: + char* outbuf_; + const size_t capacity_; + size_t size_; + bool overflowed_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CheckedArrayByteSink); +}; + +// Implementation of ByteSink that allocates an internal buffer (a char array) +// and expands it as needed to accommodate appended data (similar to a string), +// and allows the caller to take ownership of the internal buffer via the +// GetBuffer() method. The buffer returned from GetBuffer() must be deleted by +// the caller with delete[]. GetBuffer() also sets the internal buffer to be +// empty, and subsequent appends to the sink will create a new buffer. The +// destructor will free the internal buffer if GetBuffer() was not called. +// +// Example: +// +// GrowingArrayByteSink sink(10); +// sink.Append("hi", 2); +// sink.Append(data, n); +// const char* buf = sink.GetBuffer(); // Ownership transferred +// delete[] buf; +// +class LIBPROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink { + public: + explicit GrowingArrayByteSink(size_t estimated_size); + virtual ~GrowingArrayByteSink(); + virtual void Append(const char* bytes, size_t n); + + // Returns the allocated buffer, and sets nbytes to its size. The caller takes + // ownership of the buffer and must delete it with delete[]. + char* GetBuffer(size_t* nbytes); + + private: + void Expand(size_t amount); + void ShrinkToFit(); + + size_t capacity_; + char* buf_; + size_t size_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GrowingArrayByteSink); +}; + +// Implementation of ByteSink that appends to the given string. +// Existing contents of "dest" are not modified; new data is appended. +// +// Example: +// +// string dest = "Hello "; +// StringByteSink sink(&dest); +// sink.Append("World", 5); +// assert(dest == "Hello World"); +// +class LIBPROTOBUF_EXPORT StringByteSink : public ByteSink { + public: + explicit StringByteSink(string* dest) : dest_(dest) {} + virtual void Append(const char* data, size_t n); + + private: + string* dest_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringByteSink); +}; + +// Implementation of ByteSink that discards all data. +// +// Example: +// +// NullByteSink sink; +// sink.Append(data, data.size()); // All data ignored. +// +class LIBPROTOBUF_EXPORT NullByteSink : public ByteSink { + public: + NullByteSink() {} + virtual void Append(const char *data, size_t n) {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(NullByteSink); +}; + +// +// Some commonly used implementations of ByteSource +// + +// Implementation of ByteSource that reads from a StringPiece. +// +// Example: +// +// string data = "Hello"; +// ArrayByteSource source(data); +// assert(source.Available() == 5); +// assert(source.Peek() == "Hello"); +// +class LIBPROTOBUF_EXPORT ArrayByteSource : public ByteSource { + public: + explicit ArrayByteSource(StringPiece s) : input_(s) {} + + virtual size_t Available() const; + virtual StringPiece Peek(); + virtual void Skip(size_t n); + + private: + StringPiece input_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayByteSource); +}; + +// Implementation of ByteSource that wraps another ByteSource, limiting the +// number of bytes returned. +// +// The caller maintains ownership of the underlying source, and may not use the +// underlying source while using the LimitByteSource object. The underlying +// source's pointer is advanced by n bytes every time this LimitByteSource +// object is advanced by n. +// +// Example: +// +// string data = "Hello World"; +// ArrayByteSource abs(data); +// assert(abs.Available() == data.size()); +// +// LimitByteSource limit(abs, 5); +// assert(limit.Available() == 5); +// assert(limit.Peek() == "Hello"); +// +class LIBPROTOBUF_EXPORT LimitByteSource : public ByteSource { + public: + // Returns at most "limit" bytes from "source". + LimitByteSource(ByteSource* source, size_t limit); + + virtual size_t Available() const; + virtual StringPiece Peek(); + virtual void Skip(size_t n); + + // We override CopyTo so that we can forward to the underlying source, in + // case it has an efficient implementation of CopyTo. + virtual void CopyTo(ByteSink* sink, size_t n); + + private: + ByteSource* source_; + size_t limit_; +}; + +} // namespace strings +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_BYTESTREAM_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/callback.h b/thirdparty/linux/include/google/protobuf/stubs/callback.h new file mode 100644 index 0000000..87271c5 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/callback.h @@ -0,0 +1,546 @@ +#ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ +#define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ + +#include +#include + +// =================================================================== +// emulates google3/base/callback.h + +namespace google { +namespace protobuf { + +// Abstract interface for a callback. When calling an RPC, you must provide +// a Closure to call when the procedure completes. See the Service interface +// in service.h. +// +// To automatically construct a Closure which calls a particular function or +// method with a particular set of parameters, use the NewCallback() function. +// Example: +// void FooDone(const FooResponse* response) { +// ... +// } +// +// void CallFoo() { +// ... +// // When done, call FooDone() and pass it a pointer to the response. +// Closure* callback = NewCallback(&FooDone, response); +// // Make the call. +// service->Foo(controller, request, response, callback); +// } +// +// Example that calls a method: +// class Handler { +// public: +// ... +// +// void FooDone(const FooResponse* response) { +// ... +// } +// +// void CallFoo() { +// ... +// // When done, call FooDone() and pass it a pointer to the response. +// Closure* callback = NewCallback(this, &Handler::FooDone, response); +// // Make the call. +// service->Foo(controller, request, response, callback); +// } +// }; +// +// Currently NewCallback() supports binding zero, one, or two arguments. +// +// Callbacks created with NewCallback() automatically delete themselves when +// executed. They should be used when a callback is to be called exactly +// once (usually the case with RPC callbacks). If a callback may be called +// a different number of times (including zero), create it with +// NewPermanentCallback() instead. You are then responsible for deleting the +// callback (using the "delete" keyword as normal). +// +// Note that NewCallback() is a bit touchy regarding argument types. Generally, +// the values you provide for the parameter bindings must exactly match the +// types accepted by the callback function. For example: +// void Foo(string s); +// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string +// NewCallback(&Foo, string("foo")); // WORKS +// Also note that the arguments cannot be references: +// void Foo(const string& s); +// string my_str; +// NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes. +// However, correctly-typed pointers will work just fine. +class LIBPROTOBUF_EXPORT Closure { + public: + Closure() {} + virtual ~Closure(); + + virtual void Run() = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure); +}; + +template +class ResultCallback { + public: + ResultCallback() {} + virtual ~ResultCallback() {} + + virtual R Run() = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback); +}; + +template +class LIBPROTOBUF_EXPORT ResultCallback1 { + public: + ResultCallback1() {} + virtual ~ResultCallback1() {} + + virtual R Run(A1) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1); +}; + +template +class LIBPROTOBUF_EXPORT ResultCallback2 { + public: + ResultCallback2() {} + virtual ~ResultCallback2() {} + + virtual R Run(A1,A2) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback2); +}; + +namespace internal { + +class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure { + public: + typedef void (*FunctionType)(); + + FunctionClosure0(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionClosure0(); + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template +class MethodClosure0 : public Closure { + public: + typedef void (Class::*MethodType)(); + + MethodClosure0(Class* object, MethodType method, bool self_deleting) + : object_(object), method_(method), self_deleting_(self_deleting) {} + ~MethodClosure0() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; +}; + +template +class FunctionClosure1 : public Closure { + public: + typedef void (*FunctionType)(Arg1 arg1); + + FunctionClosure1(FunctionType function, bool self_deleting, + Arg1 arg1) + : function_(function), self_deleting_(self_deleting), + arg1_(arg1) {} + ~FunctionClosure1() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(arg1_); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; + Arg1 arg1_; +}; + +template +class MethodClosure1 : public Closure { + public: + typedef void (Class::*MethodType)(Arg1 arg1); + + MethodClosure1(Class* object, MethodType method, bool self_deleting, + Arg1 arg1) + : object_(object), method_(method), self_deleting_(self_deleting), + arg1_(arg1) {} + ~MethodClosure1() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(arg1_); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; + Arg1 arg1_; +}; + +template +class FunctionClosure2 : public Closure { + public: + typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2); + + FunctionClosure2(FunctionType function, bool self_deleting, + Arg1 arg1, Arg2 arg2) + : function_(function), self_deleting_(self_deleting), + arg1_(arg1), arg2_(arg2) {} + ~FunctionClosure2() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + function_(arg1_, arg2_); + if (needs_delete) delete this; + } + + private: + FunctionType function_; + bool self_deleting_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +class MethodClosure2 : public Closure { + public: + typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2); + + MethodClosure2(Class* object, MethodType method, bool self_deleting, + Arg1 arg1, Arg2 arg2) + : object_(object), method_(method), self_deleting_(self_deleting), + arg1_(arg1), arg2_(arg2) {} + ~MethodClosure2() {} + + void Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + (object_->*method_)(arg1_, arg2_); + if (needs_delete) delete this; + } + + private: + Class* object_; + MethodType method_; + bool self_deleting_; + Arg1 arg1_; + Arg2 arg2_; +}; + +template +class FunctionResultCallback_0_0 : public ResultCallback { + public: + typedef R (*FunctionType)(); + + FunctionResultCallback_0_0(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionResultCallback_0_0() {} + + R Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template +class FunctionResultCallback_1_0 : public ResultCallback { + public: + typedef R (*FunctionType)(P1); + + FunctionResultCallback_1_0(FunctionType function, bool self_deleting, + P1 p1) + : function_(function), self_deleting_(self_deleting), p1_(p1) {} + ~FunctionResultCallback_1_0() {} + + R Run() { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(p1_); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; + P1 p1_; +}; + +template +class FunctionResultCallback_0_1 : public ResultCallback1 { + public: + typedef R (*FunctionType)(Arg1 arg1); + + FunctionResultCallback_0_1(FunctionType function, bool self_deleting) + : function_(function), self_deleting_(self_deleting) {} + ~FunctionResultCallback_0_1() {} + + R Run(Arg1 a1) { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(a1); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; +}; + +template +class FunctionResultCallback_1_1 : public ResultCallback1 { + public: + typedef R (*FunctionType)(P1, A1); + + FunctionResultCallback_1_1(FunctionType function, bool self_deleting, + P1 p1) + : function_(function), self_deleting_(self_deleting), p1_(p1) {} + ~FunctionResultCallback_1_1() {} + + R Run(A1 a1) { + bool needs_delete = self_deleting_; // read in case callback deletes + R result = function_(p1_, a1); + if (needs_delete) delete this; + return result; + } + + private: + FunctionType function_; + bool self_deleting_; + P1 p1_; +}; + +template +struct InternalConstRef { + typedef typename remove_reference::type base_type; + typedef const base_type& type; +}; + +template +class MethodResultCallback_5_2 : public ResultCallback2 { + public: + typedef R (T::*MethodType)(P1, P2, P3, P4, P5, A1, A2); + MethodResultCallback_5_2(T* object, MethodType method, bool self_deleting, + P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) + : object_(object), + method_(method), + self_deleting_(self_deleting), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + ~MethodResultCallback_5_2() {} + + R Run(A1 a1, A2 a2) { + bool needs_delete = self_deleting_; + R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + if (needs_delete) delete this; + return result; + } + + private: + T* object_; + MethodType method_; + bool self_deleting_; + typename remove_reference::type p1_; + typename remove_reference::type p2_; + typename remove_reference::type p3_; + typename remove_reference::type p4_; + typename remove_reference::type p5_; +}; + +// See Closure. +inline Closure* NewCallback(void (*function)()) { + return new internal::FunctionClosure0(function, true); +} + +// See Closure. +inline Closure* NewPermanentCallback(void (*function)()) { + return new internal::FunctionClosure0(function, false); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)()) { + return new internal::MethodClosure0(object, method, true); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) { + return new internal::MethodClosure0(object, method, false); +} + +// See Closure. +template +inline Closure* NewCallback(void (*function)(Arg1), + Arg1 arg1) { + return new internal::FunctionClosure1(function, true, arg1); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(void (*function)(Arg1), + Arg1 arg1) { + return new internal::FunctionClosure1(function, false, arg1); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1), + Arg1 arg1) { + return new internal::MethodClosure1(object, method, true, arg1); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1), + Arg1 arg1) { + return new internal::MethodClosure1(object, method, false, arg1); +} + +// See Closure. +template +inline Closure* NewCallback(void (*function)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::FunctionClosure2( + function, true, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::FunctionClosure2( + function, false, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::MethodClosure2( + object, method, true, arg1, arg2); +} + +// See Closure. +template +inline Closure* NewPermanentCallback( + Class* object, void (Class::*method)(Arg1, Arg2), + Arg1 arg1, Arg2 arg2) { + return new internal::MethodClosure2( + object, method, false, arg1, arg2); +} + +// See ResultCallback +template +inline ResultCallback* NewCallback(R (*function)()) { + return new internal::FunctionResultCallback_0_0(function, true); +} + +// See ResultCallback +template +inline ResultCallback* NewPermanentCallback(R (*function)()) { + return new internal::FunctionResultCallback_0_0(function, false); +} + +// See ResultCallback +template +inline ResultCallback* NewCallback(R (*function)(P1), P1 p1) { + return new internal::FunctionResultCallback_1_0( + function, true, p1); +} + +// See ResultCallback +template +inline ResultCallback* NewPermanentCallback( + R (*function)(P1), P1 p1) { + return new internal::FunctionResultCallback_1_0( + function, false, p1); +} + +// See ResultCallback1 +template +inline ResultCallback1* NewCallback(R (*function)(A1)) { + return new internal::FunctionResultCallback_0_1(function, true); +} + +// See ResultCallback1 +template +inline ResultCallback1* NewPermanentCallback(R (*function)(A1)) { + return new internal::FunctionResultCallback_0_1(function, false); +} + +// See ResultCallback1 +template +inline ResultCallback1* NewCallback(R (*function)(P1, A1), P1 p1) { + return new internal::FunctionResultCallback_1_1( + function, true, p1); +} + +// See ResultCallback1 +template +inline ResultCallback1* NewPermanentCallback( + R (*function)(P1, A1), P1 p1) { + return new internal::FunctionResultCallback_1_1( + function, false, p1); +} + +// See MethodResultCallback_5_2 +template +inline ResultCallback2* NewPermanentCallback( + T* object, R (T::*function)(P1, P2, P3, P4, P5, A1, A2), + typename internal::InternalConstRef::type p1, + typename internal::InternalConstRef::type p2, + typename internal::InternalConstRef::type p3, + typename internal::InternalConstRef::type p4, + typename internal::InternalConstRef::type p5) { + return new internal::MethodResultCallback_5_2(object, function, false, p1, + p2, p3, p4, p5); +} + +} // namespace internal + +// A function which does nothing. Useful for creating no-op callbacks, e.g.: +// Closure* nothing = NewCallback(&DoNothing); +void LIBPROTOBUF_EXPORT DoNothing(); + + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/casts.h b/thirdparty/linux/include/google/protobuf/stubs/casts.h new file mode 100644 index 0000000..be65284 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/casts.h @@ -0,0 +1,133 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_CASTS_H__ +#define GOOGLE_PROTOBUF_CASTS_H__ + +#include +#include + +namespace google { +namespace protobuf { +namespace internal { +// Use implicit_cast as a safe version of static_cast or const_cast +// for upcasting in the type hierarchy (i.e. casting a pointer to Foo +// to a pointer to SuperclassOfFoo or casting a pointer to Foo to +// a const pointer to Foo). +// When you use implicit_cast, the compiler checks that the cast is safe. +// Such explicit implicit_casts are necessary in surprisingly many +// situations where C++ demands an exact type match instead of an +// argument type convertable to a target type. +// +// The From type can be inferred, so the preferred syntax for using +// implicit_cast is the same as for static_cast etc.: +// +// implicit_cast(expr) +// +// implicit_cast would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +template +inline To implicit_cast(From const &f) { + return f; +} + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. + +template // use like this: down_cast(foo); +inline To down_cast(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + implicit_cast(0); + } + +#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI) + assert(f == NULL || dynamic_cast(f) != NULL); // RTTI: debug mode only! +#endif + return static_cast(f); +} + +template // use like this: down_cast(foo); +inline To down_cast(From& f) { + typedef typename remove_reference::type* ToAsPointer; + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + implicit_cast(0); + } + +#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI) + // RTTI: debug mode only! + assert(dynamic_cast(&f) != NULL); +#endif + return *static_cast(&f); +} + +template +inline To bit_cast(const From& from) { + GOOGLE_COMPILE_ASSERT(sizeof(From) == sizeof(To), + bit_cast_with_different_sizes); + To dest; + memcpy(&dest, &from, sizeof(dest)); + return dest; +} + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::implicit_cast; +using internal::down_cast; +using internal::bit_cast; + +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_CASTS_H__ diff --git a/thirdparty/linux/include/google/protobuf/stubs/common.h b/thirdparty/linux/include/google/protobuf/stubs/common.h new file mode 100644 index 0000000..9c05cac --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/common.h @@ -0,0 +1,225 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) and others +// +// Contains basic types and utilities used by the rest of the library. + +#ifndef GOOGLE_PROTOBUF_COMMON_H__ +#define GOOGLE_PROTOBUF_COMMON_H__ + +#include + +#include +#include +#include + +// TODO(liujisi): Remove the following includes after the include clean-up. +#include +#include +#include +#include + +#ifndef PROTOBUF_USE_EXCEPTIONS +#if defined(_MSC_VER) && defined(_CPPUNWIND) + #define PROTOBUF_USE_EXCEPTIONS 1 +#elif defined(__EXCEPTIONS) + #define PROTOBUF_USE_EXCEPTIONS 1 +#else + #define PROTOBUF_USE_EXCEPTIONS 0 +#endif +#endif + +#if PROTOBUF_USE_EXCEPTIONS +#include +#endif +#if defined(__APPLE__) +#include // for TARGET_OS_IPHONE +#endif + +#if defined(__ANDROID__) || defined(GOOGLE_PROTOBUF_OS_ANDROID) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(GOOGLE_PROTOBUF_OS_IPHONE) +#include +#endif + +#if defined(_WIN32) && defined(GetMessage) +// Allow GetMessage to be used as a valid method name in protobuf classes. +// windows.h defines GetMessage() as a macro. Let's re-define it as an inline +// function. The inline function should be equivalent for C++ users. +inline BOOL GetMessage_Win32( + LPMSG lpMsg, HWND hWnd, + UINT wMsgFilterMin, UINT wMsgFilterMax) { + return GetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); +} +#undef GetMessage +inline BOOL GetMessage( + LPMSG lpMsg, HWND hWnd, + UINT wMsgFilterMin, UINT wMsgFilterMax) { + return GetMessage_Win32(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); +} +#endif + +namespace std {} + +namespace google { +namespace protobuf { +namespace internal { + +// Some of these constants are macros rather than const ints so that they can +// be used in #if directives. + +// The current version, represented as a single integer to make comparison +// easier: major * 10^6 + minor * 10^3 + micro +#define GOOGLE_PROTOBUF_VERSION 3000000 + +// The minimum library version which works with the current version of the +// headers. +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3000000 + +// The minimum header version which works with the current version of +// the library. This constant should only be used by protoc's C++ code +// generator. +static const int kMinHeaderVersionForLibrary = 3000000; + +// The minimum protoc version which works with the current version of the +// headers. +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3000000 + +// The minimum header version which works with the current version of +// protoc. This constant should only be used in VerifyVersion(). +static const int kMinHeaderVersionForProtoc = 3000000; + +// Verifies that the headers and libraries are compatible. Use the macro +// below to call this. +void LIBPROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion, + const char* filename); + +// Converts a numeric version number to a string. +std::string LIBPROTOBUF_EXPORT VersionString(int version); + +} // namespace internal + +// Place this macro in your main() function (or somewhere before you attempt +// to use the protobuf library) to verify that the version you link against +// matches the headers you compiled against. If a version mismatch is +// detected, the process will abort. +#define GOOGLE_PROTOBUF_VERIFY_VERSION \ + ::google::protobuf::internal::VerifyVersion( \ + GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION, \ + __FILE__) + + +// =================================================================== +// from google3/util/utf8/public/unilib.h + +class StringPiece; +namespace internal { + +// Checks if the buffer contains structurally-valid UTF-8. Implemented in +// structurally_valid.cc. +LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len); + +inline bool IsStructurallyValidUTF8(const std::string& str) { + return IsStructurallyValidUTF8(str.data(), static_cast(str.length())); +} + +// Returns initial number of bytes of structually valid UTF-8. +LIBPROTOBUF_EXPORT int UTF8SpnStructurallyValid(const StringPiece& str); + +// Coerce UTF-8 byte string in src_str to be +// a structurally-valid equal-length string by selectively +// overwriting illegal bytes with replace_char (typically ' ' or '?'). +// replace_char must be legal printable 7-bit Ascii 0x20..0x7e. +// src_str is read-only. +// +// Returns pointer to output buffer, src_str.data() if no changes were made, +// or idst if some bytes were changed. idst is allocated by the caller +// and must be at least as big as src_str +// +// Optimized for: all structurally valid and no byte copying is done. +// +LIBPROTOBUF_EXPORT char* UTF8CoerceToStructurallyValid( + const StringPiece& str, char* dst, char replace_char); + +} // namespace internal + + +// =================================================================== +// Shutdown support. + +// Shut down the entire protocol buffers library, deleting all static-duration +// objects allocated by the library or by generated .pb.cc files. +// +// There are two reasons you might want to call this: +// * You use a draconian definition of "memory leak" in which you expect +// every single malloc() to have a corresponding free(), even for objects +// which live until program exit. +// * You are writing a dynamically-loaded library which needs to clean up +// after itself when the library is unloaded. +// +// It is safe to call this multiple times. However, it is not safe to use +// any other part of the protocol buffers library after +// ShutdownProtobufLibrary() has been called. +LIBPROTOBUF_EXPORT void ShutdownProtobufLibrary(); + +namespace internal { + +// Register a function to be called when ShutdownProtocolBuffers() is called. +LIBPROTOBUF_EXPORT void OnShutdown(void (*func)()); + +} // namespace internal + +#if PROTOBUF_USE_EXCEPTIONS +class FatalException : public std::exception { + public: + FatalException(const char* filename, int line, const std::string& message) + : filename_(filename), line_(line), message_(message) {} + virtual ~FatalException() throw(); + + virtual const char* what() const throw(); + + const char* filename() const { return filename_; } + int line() const { return line_; } + const std::string& message() const { return message_; } + + private: + const char* filename_; + const int line_; + const std::string message_; +}; +#endif + +// This is at the end of the file instead of the beginning to work around a bug +// in some versions of MSVC. +using namespace std; // Don't do this at home, kids. + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMMON_H__ diff --git a/thirdparty/linux/include/google/protobuf/stubs/fastmem.h b/thirdparty/linux/include/google/protobuf/stubs/fastmem.h new file mode 100644 index 0000000..763a6e6 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/fastmem.h @@ -0,0 +1,152 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Fast memory copying and comparison routines. +// strings::fastmemcmp_inlined() replaces memcmp() +// strings::memcpy_inlined() replaces memcpy() +// strings::memeq(a, b, n) replaces memcmp(a, b, n) == 0 +// +// strings::*_inlined() routines are inline versions of the +// routines exported by this module. Sometimes using the inlined +// versions is faster. Measure before using the inlined versions. +// +// Performance measurement: +// strings::fastmemcmp_inlined +// Analysis: memcmp, fastmemcmp_inlined, fastmemcmp +// 2012-01-30 + +#ifndef GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ +#define GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ + +#include +#include +#include + +#include + +namespace google { +namespace protobuf { +namespace internal { + +// Return true if the n bytes at a equal the n bytes at b. +// The regions are allowed to overlap. +// +// The performance is similar to the performance memcmp(), but faster for +// moderately-sized inputs, or inputs that share a common prefix and differ +// somewhere in their last 8 bytes. Further optimizations can be added later +// if it makes sense to do so.:w +inline bool memeq(const char* a, const char* b, size_t n) { + size_t n_rounded_down = n & ~static_cast(7); + if (GOOGLE_PREDICT_FALSE(n_rounded_down == 0)) { // n <= 7 + return memcmp(a, b, n) == 0; + } + // n >= 8 + uint64 u = GOOGLE_UNALIGNED_LOAD64(a) ^ GOOGLE_UNALIGNED_LOAD64(b); + uint64 v = GOOGLE_UNALIGNED_LOAD64(a + n - 8) ^ GOOGLE_UNALIGNED_LOAD64(b + n - 8); + if ((u | v) != 0) { // The first or last 8 bytes differ. + return false; + } + a += 8; + b += 8; + n = n_rounded_down - 8; + if (n > 128) { + // As of 2012, memcmp on x86-64 uses a big unrolled loop with SSE2 + // instructions, and while we could try to do something faster, it + // doesn't seem worth pursuing. + return memcmp(a, b, n) == 0; + } + for (; n >= 16; n -= 16) { + uint64 x = GOOGLE_UNALIGNED_LOAD64(a) ^ GOOGLE_UNALIGNED_LOAD64(b); + uint64 y = GOOGLE_UNALIGNED_LOAD64(a + 8) ^ GOOGLE_UNALIGNED_LOAD64(b + 8); + if ((x | y) != 0) { + return false; + } + a += 16; + b += 16; + } + // n must be 0 or 8 now because it was a multiple of 8 at the top of the loop. + return n == 0 || GOOGLE_UNALIGNED_LOAD64(a) == GOOGLE_UNALIGNED_LOAD64(b); +} + +inline int fastmemcmp_inlined(const char *a, const char *b, size_t n) { + if (n >= 64) { + return memcmp(a, b, n); + } + const char* a_limit = a + n; + while (a + sizeof(uint64) <= a_limit && + GOOGLE_UNALIGNED_LOAD64(a) == GOOGLE_UNALIGNED_LOAD64(b)) { + a += sizeof(uint64); + b += sizeof(uint64); + } + if (a + sizeof(uint32) <= a_limit && + GOOGLE_UNALIGNED_LOAD32(a) == GOOGLE_UNALIGNED_LOAD32(b)) { + a += sizeof(uint32); + b += sizeof(uint32); + } + while (a < a_limit) { + int d = static_cast(*a++) - static_cast(*b++); + if (d) return d; + } + return 0; +} + +// The standard memcpy operation is slow for variable small sizes. +// This implementation inlines the optimal realization for sizes 1 to 16. +// To avoid code bloat don't use it in case of not performance-critical spots, +// nor when you don't expect very frequent values of size <= 16. +inline void memcpy_inlined(char *dst, const char *src, size_t size) { + // Compiler inlines code with minimal amount of data movement when third + // parameter of memcpy is a constant. + switch (size) { + case 1: memcpy(dst, src, 1); break; + case 2: memcpy(dst, src, 2); break; + case 3: memcpy(dst, src, 3); break; + case 4: memcpy(dst, src, 4); break; + case 5: memcpy(dst, src, 5); break; + case 6: memcpy(dst, src, 6); break; + case 7: memcpy(dst, src, 7); break; + case 8: memcpy(dst, src, 8); break; + case 9: memcpy(dst, src, 9); break; + case 10: memcpy(dst, src, 10); break; + case 11: memcpy(dst, src, 11); break; + case 12: memcpy(dst, src, 12); break; + case 13: memcpy(dst, src, 13); break; + case 14: memcpy(dst, src, 14); break; + case 15: memcpy(dst, src, 15); break; + case 16: memcpy(dst, src, 16); break; + default: memcpy(dst, src, size); break; + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/hash.h b/thirdparty/linux/include/google/protobuf/stubs/hash.h new file mode 100644 index 0000000..4eac7d5 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/hash.h @@ -0,0 +1,438 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// Deals with the fact that hash_map is not defined everywhere. + +#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__ +#define GOOGLE_PROTOBUF_STUBS_HASH_H__ + +#include +#include + +#define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1 +#define GOOGLE_PROTOBUF_HAVE_HASH_SET 1 + +// Android +#if defined(__ANDROID__) +# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP +# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP + +// Use C++11 unordered_{map|set} if available. +#elif ((_LIBCPP_STD_VER >= 11) || \ + (((__cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X)) && \ + (__GLIBCXX__ > 20090421))) +# define GOOGLE_PROTOBUF_HAS_CXX11_HASH + +// For XCode >= 4.6: the compiler is clang with libc++. +// For earlier XCode version: the compiler is gcc-4.2.1 with libstdc++. +// libc++ provides and friends even in non C++11 mode, +// and it does not provide the tr1 library. Therefore the following macro +// checks against this special case. +// Note that we should not test the __APPLE_CC__ version number or the +// __clang__ macro, since the new compiler can still use -stdlib=libstdc++, in +// which case is not compilable without -std=c++11 +#elif defined(__APPLE_CC__) +# if __GNUC__ >= 4 +# define GOOGLE_PROTOBUF_HAS_TR1 +# else +// Not tested for gcc < 4... These setting can compile under 4.2.1 though. +# define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set +# endif + +// Version checks for gcc. +#elif defined(__GNUC__) +// For GCC 4.x+, use tr1::unordered_map/set; otherwise, follow the +// instructions from: +// https://gcc.gnu.org/onlinedocs/libstdc++/manual/backwards.html +# if __GNUC__ >= 4 +# define GOOGLE_PROTOBUF_HAS_TR1 +# elif __GNUC__ >= 3 +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set +# if __GNUC__ == 3 && __GNUC_MINOR__ == 0 +# define GOOGLE_PROTOBUF_HASH_NAMESPACE std // GCC 3.0 +# else +# define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx // GCC 3.1 and later +# endif +# else +# define GOOGLE_PROTOBUF_HASH_NAMESPACE +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set +# endif + +// Version checks for MSC. +// Apparently Microsoft decided to move hash_map *back* to the std namespace in +// MSVC 2010: +// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx +// And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That +// said, use unordered_map for MSVC 2010 and beyond is our safest bet. +#elif defined(_MSC_VER) +# if _MSC_VER >= 1600 // Since Visual Studio 2010 +# define GOOGLE_PROTOBUF_HAS_CXX11_HASH +# define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare +# elif _MSC_VER >= 1500 // Since Visual Studio 2008 +# define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set +# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare +# define GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE +# elif _MSC_VER >= 1310 +# define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set +# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare +# else +# define GOOGLE_PROTOBUF_HASH_NAMESPACE std +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set +# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare +# endif + +// **ADD NEW COMPILERS SUPPORT HERE.** +// For other compilers, undefine the macro and fallback to use std::map, in +// google/protobuf/stubs/hash.h +#else +# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP +# undef GOOGLE_PROTOBUF_HAVE_HASH_SET +#endif + +#if defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH) +# define GOOGLE_PROTOBUF_HASH_NAMESPACE std +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set +#elif defined(GOOGLE_PROTOBUF_HAS_TR1) +# define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1 +# include +# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map +# include +# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set +#endif + +# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START \ + namespace google { \ + namespace protobuf { +# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }} + +#undef GOOGLE_PROTOBUF_HAS_CXX11_HASH +#undef GOOGLE_PROTOBUF_HAS_TR1 + +#if defined(GOOGLE_PROTOBUF_HAVE_HASH_MAP) && \ + defined(GOOGLE_PROTOBUF_HAVE_HASH_SET) +#else +#define GOOGLE_PROTOBUF_MISSING_HASH +#include +#include +#endif + +namespace google { +namespace protobuf { + +#ifdef GOOGLE_PROTOBUF_MISSING_HASH +#undef GOOGLE_PROTOBUF_MISSING_HASH + +// This system doesn't have hash_map or hash_set. Emulate them using map and +// set. + +// Make hash be the same as less. Note that everywhere where custom +// hash functions are defined in the protobuf code, they are also defined such +// that they can be used as "less" functions, which is required by MSVC anyway. +template +struct hash { + // Dummy, just to make derivative hash functions compile. + int operator()(const Key& key) { + GOOGLE_LOG(FATAL) << "Should never be called."; + return 0; + } + + inline bool operator()(const Key& a, const Key& b) const { + return a < b; + } +}; + +// Make sure char* is compared by value. +template <> +struct hash { + // Dummy, just to make derivative hash functions compile. + int operator()(const char* key) { + GOOGLE_LOG(FATAL) << "Should never be called."; + return 0; + } + + inline bool operator()(const char* a, const char* b) const { + return strcmp(a, b) < 0; + } +}; + +template , + typename EqualKey = std::equal_to, + typename Alloc = std::allocator< std::pair > > +class hash_map : public std::map { + typedef std::map BaseClass; + + public: + hash_map(int a = 0, const HashFcn& b = HashFcn(), + const EqualKey& c = EqualKey(), + const Alloc& d = Alloc()) : BaseClass(b, d) {} + + HashFcn hash_function() const { return HashFcn(); } +}; + +template , + typename EqualKey = std::equal_to > +class hash_set : public std::set { + public: + hash_set(int = 0) {} + + HashFcn hash_function() const { return HashFcn(); } +}; + +#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) + +template +struct hash : public GOOGLE_PROTOBUF_HASH_COMPARE { +}; + +// MSVC's hash_compare hashes based on the string contents but +// compares based on the string pointer. WTF? +class CstringLess { + public: + inline bool operator()(const char* a, const char* b) const { + return strcmp(a, b) < 0; + } +}; + +template <> +struct hash + : public GOOGLE_PROTOBUF_HASH_COMPARE {}; + +#ifdef GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE + +template +struct InternalHashCompare : public GOOGLE_PROTOBUF_HASH_COMPARE { + InternalHashCompare() {} + InternalHashCompare(HashFcn hashfcn, EqualKey equalkey) + : hashfcn_(hashfcn), equalkey_(equalkey) {} + size_t operator()(const Key& key) const { return hashfcn_(key); } + bool operator()(const Key& key1, const Key& key2) const { + return !equalkey_(key1, key2); + } + HashFcn hashfcn_; + EqualKey equalkey_; +}; + +template , + typename EqualKey = std::equal_to, + typename Alloc = std::allocator< std::pair > > +class hash_map + : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< + Key, Data, InternalHashCompare, Alloc> { + typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< + Key, Data, InternalHashCompare, Alloc> BaseClass; + + public: + hash_map(int a = 0, const HashFcn& b = HashFcn(), + const EqualKey& c = EqualKey(), const Alloc& d = Alloc()) + : BaseClass(InternalHashCompare(b, c), d) {} + + HashFcn hash_function() const { return HashFcn(); } +}; + +template , + typename EqualKey = std::equal_to > +class hash_set + : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS< + Key, InternalHashCompare > { + public: + hash_set(int = 0) {} + + HashFcn hash_function() const { return HashFcn(); } +}; + +#else // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE + +template , + typename EqualKey = std::equal_to, + typename Alloc = std::allocator< std::pair > > +class hash_map + : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< + Key, Data, HashFcn, EqualKey, Alloc> { + typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< + Key, Data, HashFcn, EqualKey, Alloc> BaseClass; + + public: + hash_map(int a = 0, const HashFcn& b = HashFcn(), + const EqualKey& c = EqualKey(), + const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {} + + HashFcn hash_function() const { return HashFcn(); } +}; + +template , + typename EqualKey = std::equal_to > +class hash_set + : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS< + Key, HashFcn, EqualKey> { + public: + hash_set(int = 0) {} + + HashFcn hash_function() const { return HashFcn(); } +}; +#endif // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE + +#else // defined(_MSC_VER) && !defined(_STLPORT_VERSION) + +template +struct hash : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash { +}; + +template +struct hash { + inline size_t operator()(const Key* key) const { + return reinterpret_cast(key); + } +}; + +// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So, +// we go ahead and provide our own implementation. +template <> +struct hash { + inline size_t operator()(const char* str) const { + size_t result = 0; + for (; *str != '\0'; str++) { + result = 5 * result + *str; + } + return result; + } +}; + +template<> +struct hash { + size_t operator()(bool x) const { + return static_cast(x); + } +}; + +template , + typename EqualKey = std::equal_to, + typename Alloc = std::allocator< std::pair > > +class hash_map + : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< + Key, Data, HashFcn, EqualKey, Alloc> { + typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< + Key, Data, HashFcn, EqualKey, Alloc> BaseClass; + + public: + hash_map(int a = 0, const HashFcn& b = HashFcn(), + const EqualKey& c = EqualKey(), + const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {} + + HashFcn hash_function() const { return HashFcn(); } +}; + +template , + typename EqualKey = std::equal_to > +class hash_set + : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS< + Key, HashFcn, EqualKey> { + public: + hash_set(int = 0) {} + + HashFcn hash_function() const { return HashFcn(); } +}; + +#endif // !GOOGLE_PROTOBUF_MISSING_HASH + +template <> +struct hash { + inline size_t operator()(const string& key) const { + return hash()(key.c_str()); + } + + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + inline bool operator()(const string& a, const string& b) const { + return a < b; + } +}; + +template +struct hash > { + inline size_t operator()(const pair& key) const { + size_t first_hash = hash()(key.first); + size_t second_hash = hash()(key.second); + + // FIXME(kenton): What is the best way to compute this hash? I have + // no idea! This seems a bit better than an XOR. + return first_hash * ((1 << 16) - 1) + second_hash; + } + + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + inline bool operator()(const pair& a, + const pair& b) const { + return a < b; + } +}; + +// Used by GCC/SGI STL only. (Why isn't this provided by the standard +// library? :( ) +struct streq { + inline bool operator()(const char* a, const char* b) const { + return strcmp(a, b) == 0; + } +}; + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__ diff --git a/thirdparty/linux/include/google/protobuf/stubs/logging.h b/thirdparty/linux/include/google/protobuf/stubs/logging.h new file mode 100644 index 0000000..f69605d --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/logging.h @@ -0,0 +1,237 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_STUBS_LOGGING_H_ +#define GOOGLE_PROTOBUF_STUBS_LOGGING_H_ + +#include +#include + +// =================================================================== +// emulates google3/base/logging.h + +namespace google { +namespace protobuf { + +enum LogLevel { + LOGLEVEL_INFO, // Informational. This is never actually used by + // libprotobuf. + LOGLEVEL_WARNING, // Warns about issues that, although not technically a + // problem now, could cause problems in the future. For + // example, a // warning will be printed when parsing a + // message that is near the message size limit. + LOGLEVEL_ERROR, // An error occurred which should never happen during + // normal use. + LOGLEVEL_FATAL, // An error occurred from which the library cannot + // recover. This usually indicates a programming error + // in the code which calls the library, especially when + // compiled in debug mode. + +#ifdef NDEBUG + LOGLEVEL_DFATAL = LOGLEVEL_ERROR +#else + LOGLEVEL_DFATAL = LOGLEVEL_FATAL +#endif +}; + +class StringPiece; +namespace util { +class Status; +} +class uint128; +namespace internal { + +class LogFinisher; + +class LIBPROTOBUF_EXPORT LogMessage { + public: + LogMessage(LogLevel level, const char* filename, int line); + ~LogMessage(); + + LogMessage& operator<<(const std::string& value); + LogMessage& operator<<(const char* value); + LogMessage& operator<<(char value); + LogMessage& operator<<(int value); + LogMessage& operator<<(uint value); + LogMessage& operator<<(long value); + LogMessage& operator<<(unsigned long value); + LogMessage& operator<<(long long value); + LogMessage& operator<<(unsigned long long value); + LogMessage& operator<<(double value); + LogMessage& operator<<(void* value); + LogMessage& operator<<(const StringPiece& value); + LogMessage& operator<<(const ::google::protobuf::util::Status& status); + LogMessage& operator<<(const uint128& value); + + private: + friend class LogFinisher; + void Finish(); + + LogLevel level_; + const char* filename_; + int line_; + std::string message_; +}; + +// Used to make the entire "LOG(BLAH) << etc." expression have a void return +// type and print a newline after each message. +class LIBPROTOBUF_EXPORT LogFinisher { + public: + void operator=(LogMessage& other); +}; + +template +bool IsOk(T status) { return status.ok(); } +template<> +inline bool IsOk(bool status) { return status; } + +} // namespace internal + +// Undef everything in case we're being mixed with some other Google library +// which already defined them itself. Presumably all Google libraries will +// support the same syntax for these so it should not be a big deal if they +// end up using our definitions instead. +#undef GOOGLE_LOG +#undef GOOGLE_LOG_IF + +#undef GOOGLE_CHECK +#undef GOOGLE_CHECK_OK +#undef GOOGLE_CHECK_EQ +#undef GOOGLE_CHECK_NE +#undef GOOGLE_CHECK_LT +#undef GOOGLE_CHECK_LE +#undef GOOGLE_CHECK_GT +#undef GOOGLE_CHECK_GE +#undef GOOGLE_CHECK_NOTNULL + +#undef GOOGLE_DLOG +#undef GOOGLE_DCHECK +#undef GOOGLE_DCHECK_OK +#undef GOOGLE_DCHECK_EQ +#undef GOOGLE_DCHECK_NE +#undef GOOGLE_DCHECK_LT +#undef GOOGLE_DCHECK_LE +#undef GOOGLE_DCHECK_GT +#undef GOOGLE_DCHECK_GE + +#define GOOGLE_LOG(LEVEL) \ + ::google::protobuf::internal::LogFinisher() = \ + ::google::protobuf::internal::LogMessage( \ + ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__) +#define GOOGLE_LOG_IF(LEVEL, CONDITION) \ + !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL) + +#define GOOGLE_CHECK(EXPRESSION) \ + GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " +#define GOOGLE_CHECK_OK(A) GOOGLE_CHECK(::google::protobuf::internal::IsOk(A)) +#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B)) +#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B)) +#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B)) +#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK((A) <= (B)) +#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B)) +#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B)) + +namespace internal { +template +T* CheckNotNull(const char* /* file */, int /* line */, + const char* name, T* val) { + if (val == NULL) { + GOOGLE_LOG(FATAL) << name; + } + return val; +} +} // namespace internal +#define GOOGLE_CHECK_NOTNULL(A) \ + ::google::protobuf::internal::CheckNotNull(\ + __FILE__, __LINE__, "'" #A "' must not be NULL", (A)) + +#ifdef NDEBUG + +#define GOOGLE_DLOG(LEVEL) GOOGLE_LOG_IF(LEVEL, false) + +#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION) +#define GOOGLE_DCHECK_OK(E) GOOGLE_DCHECK(::google::protobuf::internal::IsOk(E)) +#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK((A) == (B)) +#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK((A) != (B)) +#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK((A) < (B)) +#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK((A) <= (B)) +#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK((A) > (B)) +#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK((A) >= (B)) + +#else // NDEBUG + +#define GOOGLE_DLOG GOOGLE_LOG + +#define GOOGLE_DCHECK GOOGLE_CHECK +#define GOOGLE_DCHECK_OK GOOGLE_CHECK_OK +#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ +#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE +#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT +#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE +#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT +#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE + +#endif // !NDEBUG + +typedef void LogHandler(LogLevel level, const char* filename, int line, + const std::string& message); + +// The protobuf library sometimes writes warning and error messages to +// stderr. These messages are primarily useful for developers, but may +// also help end users figure out a problem. If you would prefer that +// these messages be sent somewhere other than stderr, call SetLogHandler() +// to set your own handler. This returns the old handler. Set the handler +// to NULL to ignore log messages (but see also LogSilencer, below). +// +// Obviously, SetLogHandler is not thread-safe. You should only call it +// at initialization time, and probably not from library code. If you +// simply want to suppress log messages temporarily (e.g. because you +// have some code that tends to trigger them frequently and you know +// the warnings are not important to you), use the LogSilencer class +// below. +LIBPROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func); + +// Create a LogSilencer if you want to temporarily suppress all log +// messages. As long as any LogSilencer objects exist, non-fatal +// log messages will be discarded (the current LogHandler will *not* +// be called). Constructing a LogSilencer is thread-safe. You may +// accidentally suppress log messages occurring in another thread, but +// since messages are generally for debugging purposes only, this isn't +// a big deal. If you want to intercept log messages, use SetLogHandler(). +class LIBPROTOBUF_EXPORT LogSilencer { + public: + LogSilencer(); + ~LogSilencer(); +}; + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_LOGGING_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/macros.h b/thirdparty/linux/include/google/protobuf/stubs/macros.h new file mode 100644 index 0000000..0e9a9ec --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/macros.h @@ -0,0 +1,168 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_MACROS_H__ +#define GOOGLE_PROTOBUF_MACROS_H__ + +#include + +namespace google { +namespace protobuf { + +#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS +#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +#undef GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS +#define GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName(); \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +// =================================================================== +// from google3/base/basictypes.h + +// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. +// +// GOOGLE_ARRAYSIZE catches a few type errors. If you see a compiler error +// +// "warning: division by zero in ..." +// +// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer. +// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays. +// +// The following comments are on the implementation details, and can +// be ignored by the users. +// +// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in +// the array) and sizeof(*(arr)) (the # of bytes in one array +// element). If the former is divisible by the latter, perhaps arr is +// indeed an array, in which case the division result is the # of +// elements in the array. Otherwise, arr cannot possibly be an array, +// and we generate a compiler error to prevent the code from +// compiling. +// +// Since the size of bool is implementation-defined, we need to cast +// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final +// result has type size_t. +// +// This macro is not perfect as it wrongfully accepts certain +// pointers, namely where the pointer size is divisible by the pointee +// size. Since all our code has to go through a 32-bit compiler, +// where a pointer is 4 bytes, this means all pointers to a type whose +// size is 3 or greater than 4 will be (righteously) rejected. +// +// Kudos to Jorg Brown for this simple and elegant implementation. + +#undef GOOGLE_ARRAYSIZE +#define GOOGLE_ARRAYSIZE(a) \ + ((sizeof(a) / sizeof(*(a))) / \ + static_cast(!(sizeof(a) % sizeof(*(a))))) + +// The COMPILE_ASSERT macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +namespace internal { + +template +struct CompileAssert { +}; + +} // namespace internal + +#undef GOOGLE_COMPILE_ASSERT +#if __cplusplus >= 201103L +#define GOOGLE_COMPILE_ASSERT(expr, msg) static_assert(expr, #msg) +#else +#define GOOGLE_COMPILE_ASSERT(expr, msg) \ + ::google::protobuf::internal::CompileAssert<(bool(expr))> \ + msg[bool(expr) ? 1 : -1]; \ + (void)msg +// Implementation details of COMPILE_ASSERT: +// +// - COMPILE_ASSERT works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// COMPILE_ASSERT(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. +#endif // __cplusplus >= 201103L + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_MACROS_H__ diff --git a/thirdparty/linux/include/google/protobuf/stubs/mutex.h b/thirdparty/linux/include/google/protobuf/stubs/mutex.h new file mode 100644 index 0000000..7ef1cb6 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/mutex.h @@ -0,0 +1,148 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_STUBS_MUTEX_H_ +#define GOOGLE_PROTOBUF_STUBS_MUTEX_H_ + +#ifdef GOOGLE_PROTOBUF_NO_THREADLOCAL +#include +#endif + +#include + +// =================================================================== +// emulates google3/base/mutex.h +namespace google { +namespace protobuf { +namespace internal { + +// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T +// may hold a mutex at a given time. If T attempts to Lock() the same Mutex +// while holding it, T will deadlock. +class LIBPROTOBUF_EXPORT Mutex { + public: + // Create a Mutex that is not held by anybody. + Mutex(); + + // Destructor + ~Mutex(); + + // Block if necessary until this Mutex is free, then acquire it exclusively. + void Lock(); + + // Release this Mutex. Caller must hold it exclusively. + void Unlock(); + + // Crash if this Mutex is not held exclusively by this thread. + // May fail to crash when it should; will never crash when it should not. + void AssertHeld(); + + private: + struct Internal; + Internal* mInternal; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); +}; + +// Undefine the macros to workaround the conflicts with Google internal +// MutexLock implementation. +// TODO(liujisi): Remove the undef once internal macros are removed. +#undef MutexLock +#undef ReaderMutexLock +#undef WriterMutexLock +#undef MutexLockMaybe + +// MutexLock(mu) acquires mu when constructed and releases it when destroyed. +class LIBPROTOBUF_EXPORT MutexLock { + public: + explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); } + ~MutexLock() { this->mu_->Unlock(); } + private: + Mutex *const mu_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock); +}; + +// TODO(kenton): Implement these? Hard to implement portably. +typedef MutexLock ReaderMutexLock; +typedef MutexLock WriterMutexLock; + +// MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL. +class LIBPROTOBUF_EXPORT MutexLockMaybe { + public: + explicit MutexLockMaybe(Mutex *mu) : + mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } } + ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } } + private: + Mutex *const mu_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); +}; + +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) +template +class ThreadLocalStorage { + public: + ThreadLocalStorage() { + pthread_key_create(&key_, &ThreadLocalStorage::Delete); + } + ~ThreadLocalStorage() { + pthread_key_delete(key_); + } + T* Get() { + T* result = static_cast(pthread_getspecific(key_)); + if (result == NULL) { + result = new T(); + pthread_setspecific(key_, result); + } + return result; + } + private: + static void Delete(void* value) { + delete static_cast(value); + } + pthread_key_t key_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage); +}; +#endif + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::Mutex; +using internal::MutexLock; +using internal::ReaderMutexLock; +using internal::WriterMutexLock; +using internal::MutexLockMaybe; + + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_MUTEX_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/once.h b/thirdparty/linux/include/google/protobuf/stubs/once.h new file mode 100644 index 0000000..1f082c3 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/once.h @@ -0,0 +1,167 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// emulates google3/base/once.h +// +// This header is intended to be included only by internal .cc files and +// generated .pb.cc files. Users should not use this directly. +// +// This is basically a portable version of pthread_once(). +// +// This header declares: +// * A type called ProtobufOnceType. +// * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type +// ProtobufOnceType. This is the only legal way to declare such a variable. +// The macro may only be used at the global scope (you cannot create local or +// class member variables of this type). +// * A function GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()). +// This function, when invoked multiple times given the same ProtobufOnceType +// object, will invoke init_func on the first call only, and will make sure +// none of the calls return before that first call to init_func has finished. +// * The user can provide a parameter which GoogleOnceInit() forwards to the +// user-provided function when it is called. Usage example: +// int a = 10; +// GoogleOnceInit(&my_once, &MyFunctionExpectingIntArgument, &a); +// * This implementation guarantees that ProtobufOnceType is a POD (i.e. no +// static initializer generated). +// +// This implements a way to perform lazy initialization. It's more efficient +// than using mutexes as no lock is needed if initialization has already +// happened. +// +// Example usage: +// void Init(); +// GOOGLE_PROTOBUF_DECLARE_ONCE(once_init); +// +// // Calls Init() exactly once. +// void InitOnce() { +// GoogleOnceInit(&once_init, &Init); +// } +// +// Note that if GoogleOnceInit() is called before main() has begun, it must +// only be called by the thread that will eventually call main() -- that is, +// the thread that performs dynamic initialization. In general this is a safe +// assumption since people don't usually construct threads before main() starts, +// but it is technically not guaranteed. Unfortunately, Win32 provides no way +// whatsoever to statically-initialize its synchronization primitives, so our +// only choice is to assume that dynamic initialization is single-threaded. + +#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__ +#define GOOGLE_PROTOBUF_STUBS_ONCE_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { + +#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +typedef bool ProtobufOnceType; + +#define GOOGLE_PROTOBUF_ONCE_INIT false + +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { + if (!*once) { + *once = true; + init_func(); + } +} + +template +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg), + Arg arg) { + if (!*once) { + *once = true; + init_func(arg); + } +} + +#else + +enum { + ONCE_STATE_UNINITIALIZED = 0, + ONCE_STATE_EXECUTING_CLOSURE = 1, + ONCE_STATE_DONE = 2 +}; + +typedef internal::AtomicWord ProtobufOnceType; + +#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED + +LIBPROTOBUF_EXPORT +void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure); + +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { + if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { + internal::FunctionClosure0 func(init_func, false); + GoogleOnceInitImpl(once, &func); + } +} + +template +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*), + Arg* arg) { + if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { + internal::FunctionClosure1 func(init_func, false, arg); + GoogleOnceInitImpl(once, &func); + } +} + +#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +class GoogleOnceDynamic { + public: + GoogleOnceDynamic() : state_(GOOGLE_PROTOBUF_ONCE_INIT) { } + + // If this->Init() has not been called before by any thread, + // execute (*func_with_arg)(arg) then return. + // Otherwise, wait until that prior invocation has finished + // executing its function, then return. + template + void Init(void (*func_with_arg)(T*), T* arg) { + GoogleOnceInit(&this->state_, + func_with_arg, + arg); + } + private: + ProtobufOnceType state_; +}; + +#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ + ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__ diff --git a/thirdparty/linux/include/google/protobuf/stubs/platform_macros.h b/thirdparty/linux/include/google/protobuf/stubs/platform_macros.h new file mode 100644 index 0000000..4ba4b34 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/platform_macros.h @@ -0,0 +1,125 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2012 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ +#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ + +#define GOOGLE_PROTOBUF_PLATFORM_ERROR \ +#error "Host platform was not detected as supported by protobuf" + +// Processor architecture detection. For more info on what's defined, see: +// http://msdn.microsoft.com/en-us/library/b0084kay.aspx +// http://www.agner.org/optimize/calling_conventions.pdf +// or with gcc, run: "echo | gcc -E -dM -" +#if defined(_M_X64) || defined(__x86_64__) +#define GOOGLE_PROTOBUF_ARCH_X64 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#elif defined(_M_IX86) || defined(__i386__) +#define GOOGLE_PROTOBUF_ARCH_IA32 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__QNX__) +#define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__ARMEL__) +#define GOOGLE_PROTOBUF_ARCH_ARM 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__aarch64__) +#define GOOGLE_PROTOBUF_ARCH_AARCH64 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#elif defined(__MIPSEL__) +#if defined(__LP64__) +#define GOOGLE_PROTOBUF_ARCH_MIPS64 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#else +#define GOOGLE_PROTOBUF_ARCH_MIPS 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#endif +#elif defined(__pnacl__) +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(sparc) +#define GOOGLE_PROTOBUF_ARCH_SPARC 1 +#if defined(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__) +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#else +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#endif +#elif defined(_POWER) || defined(__powerpc64__) || defined(__PPC64__) +#define GOOGLE_PROTOBUF_ARCH_POWER 1 +#define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +#elif defined(__PPC__) +#define GOOGLE_PROTOBUF_ARCH_PPC 1 +#define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +#elif defined(__GNUC__) +# if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)) +// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h +# elif defined(__clang__) +# if !__has_extension(c_atomic) +GOOGLE_PROTOBUF_PLATFORM_ERROR +# endif +// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h +# endif +# if __LP64__ +# define GOOGLE_PROTOBUF_ARCH_64_BIT 1 +# else +# define GOOGLE_PROTOBUF_ARCH_32_BIT 1 +# endif +#else +GOOGLE_PROTOBUF_PLATFORM_ERROR +#endif + +#if defined(__APPLE__) +#define GOOGLE_PROTOBUF_OS_APPLE +#include +#if TARGET_OS_IPHONE +#define GOOGLE_PROTOBUF_OS_IPHONE +#endif +#elif defined(__EMSCRIPTEN__) +#define GOOGLE_PROTOBUF_OS_EMSCRIPTEN +#elif defined(__native_client__) +#define GOOGLE_PROTOBUF_OS_NACL +#elif defined(sun) +#define GOOGLE_PROTOBUF_OS_SOLARIS +#elif defined(_AIX) +#define GOOGLE_PROTOBUF_OS_AIX +#elif defined(__ANDROID__) +#define GOOGLE_PROTOBUF_OS_ANDROID +#endif + +#undef GOOGLE_PROTOBUF_PLATFORM_ERROR + +#if defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE) +// Android ndk does not support the __thread keyword very well yet. Here +// we use pthread_key_create()/pthread_getspecific()/... methods for +// TLS support on android. +// iOS also does not support the __thread keyword. +#define GOOGLE_PROTOBUF_NO_THREADLOCAL +#endif + +#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/port.h b/thirdparty/linux/include/google/protobuf/stubs/port.h new file mode 100644 index 0000000..d7f93b4 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/port.h @@ -0,0 +1,393 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_STUBS_PORT_H_ +#define GOOGLE_PROTOBUF_STUBS_PORT_H_ + +#include +#include +#include +#include +#include +#if defined(__osf__) +// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of +// what stdint.h would define. +#include +#elif !defined(_MSC_VER) +#include +#endif + +#undef PROTOBUF_LITTLE_ENDIAN +#ifdef _WIN32 + // Assuming windows is always little-endian. + // TODO(xiaofeng): The PROTOBUF_LITTLE_ENDIAN is not only used for + // optimization but also for correctness. We should define an + // different macro to test the big-endian code path in coded_stream. + #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif + #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) + // If MSVC has "/RTCc" set, it will complain about truncating casts at + // runtime. This file contains some intentional truncating casts. + #pragma runtime_checks("c", off) + #endif +#else + #include // __BYTE_ORDER + #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ + (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \ + !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) + #define PROTOBUF_LITTLE_ENDIAN 1 + #endif +#endif +#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS) + #ifdef LIBPROTOBUF_EXPORTS + #define LIBPROTOBUF_EXPORT __declspec(dllexport) + #else + #define LIBPROTOBUF_EXPORT __declspec(dllimport) + #endif + #ifdef LIBPROTOC_EXPORTS + #define LIBPROTOC_EXPORT __declspec(dllexport) + #else + #define LIBPROTOC_EXPORT __declspec(dllimport) + #endif +#else + #define LIBPROTOBUF_EXPORT + #define LIBPROTOC_EXPORT +#endif + +// These #includes are for the byte swap functions declared later on. +#ifdef _MSC_VER +#include // NOLINT(build/include) +#elif defined(__APPLE__) +#include +#elif defined(__GLIBC__) || defined(__CYGWIN__) +#include // IWYU pragma: export +#endif + +// =================================================================== +// from google3/base/port.h +namespace google { +namespace protobuf { + +typedef unsigned int uint; + +#ifdef _MSC_VER +typedef signed __int8 int8; +typedef __int16 int16; +typedef __int32 int32; +typedef __int64 int64; + +typedef unsigned __int8 uint8; +typedef unsigned __int16 uint16; +typedef unsigned __int32 uint32; +typedef unsigned __int64 uint64; +#else +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; +#endif + +// long long macros to be used because gcc and vc++ use different suffixes, +// and different size specifiers in format strings +#undef GOOGLE_LONGLONG +#undef GOOGLE_ULONGLONG +#undef GOOGLE_LL_FORMAT + +#ifdef _MSC_VER +#define GOOGLE_LONGLONG(x) x##I64 +#define GOOGLE_ULONGLONG(x) x##UI64 +#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...) +#else +// By long long, we actually mean int64. +#define GOOGLE_LONGLONG(x) x##LL +#define GOOGLE_ULONGLONG(x) x##ULL +// Used to format real long long integers. +#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also. +#endif + +static const int32 kint32max = 0x7FFFFFFF; +static const int32 kint32min = -kint32max - 1; +static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF); +static const int64 kint64min = -kint64max - 1; +static const uint32 kuint32max = 0xFFFFFFFFu; +static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); + +// ------------------------------------------------------------------- +// Annotations: Some parts of the code have been annotated in ways that might +// be useful to some compilers or tools, but are not supported universally. +// You can #define these annotations yourself if the default implementation +// is not right for you. + +#ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE +#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +// For functions we want to force inline. +// Introduced in gcc 3.1. +#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) +#else +// Other compilers will have to figure it out for themselves. +#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE +#endif +#endif + +#ifndef GOOGLE_ATTRIBUTE_NOINLINE +#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +// For functions we want to force not inline. +// Introduced in gcc 3.1. +#define GOOGLE_ATTRIBUTE_NOINLINE __attribute__ ((noinline)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +// Seems to have been around since at least Visual Studio 2005 +#define GOOGLE_ATTRIBUTE_NOINLINE __declspec(noinline) +#else +// Other compilers will have to figure it out for themselves. +#define GOOGLE_ATTRIBUTE_NOINLINE +#endif +#endif + +#ifndef GOOGLE_ATTRIBUTE_NORETURN +#ifdef __GNUC__ +// Tell the compiler that a given function never returns. +#define GOOGLE_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#else +#define GOOGLE_ATTRIBUTE_NORETURN +#endif +#endif + +#ifndef GOOGLE_ATTRIBUTE_DEPRECATED +#ifdef __GNUC__ +// If the method/variable/type is used anywhere, produce a warning. +#define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated)) +#else +#define GOOGLE_ATTRIBUTE_DEPRECATED +#endif +#endif + +#ifndef GOOGLE_PREDICT_TRUE +#ifdef __GNUC__ +// Provided at least since GCC 3.0. +#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define GOOGLE_PREDICT_TRUE(x) (x) +#endif +#endif + +#ifndef GOOGLE_PREDICT_FALSE +#ifdef __GNUC__ +// Provided at least since GCC 3.0. +#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#else +#define GOOGLE_PREDICT_FALSE(x) (x) +#endif +#endif + +// Delimits a block of code which may write to memory which is simultaneously +// written by other threads, but which has been determined to be thread-safe +// (e.g. because it is an idempotent write). +#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN +#define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN() +#endif +#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END +#define GOOGLE_SAFE_CONCURRENT_WRITES_END() +#endif + +#if defined(__clang__) && defined(__has_cpp_attribute) \ + && !defined(GOOGLE_PROTOBUF_OS_APPLE) +# if defined(GOOGLE_PROTOBUF_OS_NACL) || defined(EMSCRIPTEN) || \ + __has_cpp_attribute(clang::fallthrough) +# define GOOGLE_FALLTHROUGH_INTENDED [[clang::fallthrough]] +# endif +#endif + +#ifndef GOOGLE_FALLTHROUGH_INTENDED +# define GOOGLE_FALLTHROUGH_INTENDED +#endif + +#define GOOGLE_GUARDED_BY(x) +#define GOOGLE_ATTRIBUTE_COLD + +// x86 and x86-64 can perform unaligned loads/stores directly. +#if defined(_M_X64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(__i386__) + +#define GOOGLE_UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) +#define GOOGLE_UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) +#define GOOGLE_UNALIGNED_LOAD64(_p) (*reinterpret_cast(_p)) + +#define GOOGLE_UNALIGNED_STORE16(_p, _val) (*reinterpret_cast(_p) = (_val)) +#define GOOGLE_UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) +#define GOOGLE_UNALIGNED_STORE64(_p, _val) (*reinterpret_cast(_p) = (_val)) + +#else +inline uint16 GOOGLE_UNALIGNED_LOAD16(const void *p) { + uint16 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint32 GOOGLE_UNALIGNED_LOAD32(const void *p) { + uint32 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64 GOOGLE_UNALIGNED_LOAD64(const void *p) { + uint64 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void GOOGLE_UNALIGNED_STORE16(void *p, uint16 v) { + memcpy(p, &v, sizeof v); +} + +inline void GOOGLE_UNALIGNED_STORE32(void *p, uint32 v) { + memcpy(p, &v, sizeof v); +} + +inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { + memcpy(p, &v, sizeof v); +} +#endif + +#if defined(_MSC_VER) +#define GOOGLE_THREAD_LOCAL __declspec(thread) +#else +#define GOOGLE_THREAD_LOCAL __thread +#endif + +// The following guarantees declaration of the byte swap functions. +#ifdef _MSC_VER +#define bswap_16(x) _byteswap_ushort(x) +#define bswap_32(x) _byteswap_ulong(x) +#define bswap_64(x) _byteswap_uint64(x) + +#elif defined(__APPLE__) +// Mac OS X / Darwin features +#define bswap_16(x) OSSwapInt16(x) +#define bswap_32(x) OSSwapInt32(x) +#define bswap_64(x) OSSwapInt64(x) + +#elif !defined(__GLIBC__) && !defined(__CYGWIN__) + +static inline uint16 bswap_16(uint16 x) { + return static_cast(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); +} +#define bswap_16(x) bswap_16(x) +static inline uint32 bswap_32(uint32 x) { + return (((x & 0xFF) << 24) | + ((x & 0xFF00) << 8) | + ((x & 0xFF0000) >> 8) | + ((x & 0xFF000000) >> 24)); +} +#define bswap_32(x) bswap_32(x) +static inline uint64 bswap_64(uint64 x) { + return (((x & GOOGLE_ULONGLONG(0xFF)) << 56) | + ((x & GOOGLE_ULONGLONG(0xFF00)) << 40) | + ((x & GOOGLE_ULONGLONG(0xFF0000)) << 24) | + ((x & GOOGLE_ULONGLONG(0xFF000000)) << 8) | + ((x & GOOGLE_ULONGLONG(0xFF00000000)) >> 8) | + ((x & GOOGLE_ULONGLONG(0xFF0000000000)) >> 24) | + ((x & GOOGLE_ULONGLONG(0xFF000000000000)) >> 40) | + ((x & GOOGLE_ULONGLONG(0xFF00000000000000)) >> 56)); +} +#define bswap_64(x) bswap_64(x) + +#endif + +// =================================================================== +// from google3/util/endian/endian.h +LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x); + +class BigEndian { + public: +#ifdef PROTOBUF_LITTLE_ENDIAN + + static uint16 FromHost16(uint16 x) { return bswap_16(x); } + static uint16 ToHost16(uint16 x) { return bswap_16(x); } + + static uint32 FromHost32(uint32 x) { return bswap_32(x); } + static uint32 ToHost32(uint32 x) { return bswap_32(x); } + + static uint64 FromHost64(uint64 x) { return bswap_64(x); } + static uint64 ToHost64(uint64 x) { return bswap_64(x); } + + static bool IsLittleEndian() { return true; } + +#else + + static uint16 FromHost16(uint16 x) { return x; } + static uint16 ToHost16(uint16 x) { return x; } + + static uint32 FromHost32(uint32 x) { return x; } + static uint32 ToHost32(uint32 x) { return x; } + + static uint64 FromHost64(uint64 x) { return x; } + static uint64 ToHost64(uint64 x) { return x; } + + static bool IsLittleEndian() { return false; } + +#endif /* ENDIAN */ + + // Functions to do unaligned loads and stores in big-endian order. + static uint16 Load16(const void *p) { + return ToHost16(GOOGLE_UNALIGNED_LOAD16(p)); + } + + static void Store16(void *p, uint16 v) { + GOOGLE_UNALIGNED_STORE16(p, FromHost16(v)); + } + + static uint32 Load32(const void *p) { + return ToHost32(GOOGLE_UNALIGNED_LOAD32(p)); + } + + static void Store32(void *p, uint32 v) { + GOOGLE_UNALIGNED_STORE32(p, FromHost32(v)); + } + + static uint64 Load64(const void *p) { + return ToHost64(GOOGLE_UNALIGNED_LOAD64(p)); + } + + static void Store64(void *p, uint64 v) { + GOOGLE_UNALIGNED_STORE64(p, FromHost64(v)); + } +}; + + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_PORT_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/scoped_ptr.h b/thirdparty/linux/include/google/protobuf/stubs/scoped_ptr.h new file mode 100644 index 0000000..4423c11 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/scoped_ptr.h @@ -0,0 +1,236 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_ +#define GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_ + +#include + +namespace google { +namespace protobuf { + +// =================================================================== +// from google3/base/scoped_ptr.h + +namespace internal { + +// This is an implementation designed to match the anticipated future TR2 +// implementation of the scoped_ptr class, and its closely-related brethren, +// scoped_array, scoped_ptr_malloc, and make_scoped_ptr. + +template class scoped_ptr; +template class scoped_array; + +// A scoped_ptr is like a T*, except that the destructor of scoped_ptr +// automatically deletes the pointer it holds (if any). +// That is, scoped_ptr owns the T object that it points to. +// Like a T*, a scoped_ptr may hold either NULL or a pointer to a T object. +// +// The size of a scoped_ptr is small: +// sizeof(scoped_ptr) == sizeof(C*) +template +class scoped_ptr { + public: + + // The element type + typedef C element_type; + + // Constructor. Defaults to initializing with NULL. + // There is no way to create an uninitialized scoped_ptr. + // The input parameter must be allocated with new. + explicit scoped_ptr(C* p = NULL) : ptr_(p) { } + + // Destructor. If there is a C object, delete it. + // We don't need to test ptr_ == NULL because C++ does that for us. + ~scoped_ptr() { + enum { type_must_be_complete = sizeof(C) }; + delete ptr_; + } + + // Reset. Deletes the current owned object, if any. + // Then takes ownership of a new object, if given. + // this->reset(this->get()) works. + void reset(C* p = NULL) { + if (p != ptr_) { + enum { type_must_be_complete = sizeof(C) }; + delete ptr_; + ptr_ = p; + } + } + + // Accessors to get the owned object. + // operator* and operator-> will assert() if there is no current object. + C& operator*() const { + assert(ptr_ != NULL); + return *ptr_; + } + C* operator->() const { + assert(ptr_ != NULL); + return ptr_; + } + C* get() const { return ptr_; } + + // Comparison operators. + // These return whether two scoped_ptr refer to the same object, not just to + // two different but equal objects. + bool operator==(C* p) const { return ptr_ == p; } + bool operator!=(C* p) const { return ptr_ != p; } + + // Swap two scoped pointers. + void swap(scoped_ptr& p2) { + C* tmp = ptr_; + ptr_ = p2.ptr_; + p2.ptr_ = tmp; + } + + // Release a pointer. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. + C* release() { + C* retVal = ptr_; + ptr_ = NULL; + return retVal; + } + + private: + C* ptr_; + + // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't + // make sense, and if C2 == C, it still doesn't make sense because you should + // never have the same object owned by two different scoped_ptrs. + template bool operator==(scoped_ptr const& p2) const; + template bool operator!=(scoped_ptr const& p2) const; + + // Disallow evil constructors + scoped_ptr(const scoped_ptr&); + void operator=(const scoped_ptr&); +}; + +// scoped_array is like scoped_ptr, except that the caller must allocate +// with new [] and the destructor deletes objects with delete []. +// +// As with scoped_ptr, a scoped_array either points to an object +// or is NULL. A scoped_array owns the object that it points to. +// +// Size: sizeof(scoped_array) == sizeof(C*) +template +class scoped_array { + public: + + // The element type + typedef C element_type; + + // Constructor. Defaults to initializing with NULL. + // There is no way to create an uninitialized scoped_array. + // The input parameter must be allocated with new []. + explicit scoped_array(C* p = NULL) : array_(p) { } + + // Destructor. If there is a C object, delete it. + // We don't need to test ptr_ == NULL because C++ does that for us. + ~scoped_array() { + enum { type_must_be_complete = sizeof(C) }; + delete[] array_; + } + + // Reset. Deletes the current owned object, if any. + // Then takes ownership of a new object, if given. + // this->reset(this->get()) works. + void reset(C* p = NULL) { + if (p != array_) { + enum { type_must_be_complete = sizeof(C) }; + delete[] array_; + array_ = p; + } + } + + // Get one element of the current object. + // Will assert() if there is no current object, or index i is negative. + C& operator[](std::ptrdiff_t i) const { + assert(i >= 0); + assert(array_ != NULL); + return array_[i]; + } + + // Get a pointer to the zeroth element of the current object. + // If there is no current object, return NULL. + C* get() const { + return array_; + } + + // Comparison operators. + // These return whether two scoped_array refer to the same object, not just to + // two different but equal objects. + bool operator==(C* p) const { return array_ == p; } + bool operator!=(C* p) const { return array_ != p; } + + // Swap two scoped arrays. + void swap(scoped_array& p2) { + C* tmp = array_; + array_ = p2.array_; + p2.array_ = tmp; + } + + // Release an array. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. + C* release() { + C* retVal = array_; + array_ = NULL; + return retVal; + } + + private: + C* array_; + + // Forbid comparison of different scoped_array types. + template bool operator==(scoped_array const& p2) const; + template bool operator!=(scoped_array const& p2) const; + + // Disallow evil constructors + scoped_array(const scoped_array&); + void operator=(const scoped_array&); +}; + +} // namespace internal + +// We made these internal so that they would show up as such in the docs, +// but we don't want to stick "internal::" in front of them everywhere. +using internal::scoped_ptr; +using internal::scoped_array; + + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/shared_ptr.h b/thirdparty/linux/include/google/protobuf/stubs/shared_ptr.h new file mode 100644 index 0000000..d250bf4 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/shared_ptr.h @@ -0,0 +1,470 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/util/gtl/shared_ptr.h + +#ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__ +#define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__ + +#include + +#include // for swap +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +// Alias to std::shared_ptr for any C++11 platform, +// and for any supported MSVC compiler. +#if !defined(UTIL_GTL_USE_STD_SHARED_PTR) && \ + (defined(COMPILER_MSVC) || defined(LANG_CXX11)) +#define UTIL_GTL_USE_STD_SHARED_PTR 1 +#endif + +#if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR + +// These are transitional. They will be going away soon. +// Please just #include and just type std::shared_ptr yourself, instead +// of relying on this file. +// +// Migration doc: http://go/std-shared-ptr-lsc +using std::enable_shared_from_this; +using std::shared_ptr; +using std::static_pointer_cast; +using std::weak_ptr; + +#else // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0. + +// For everything else there is the google3 implementation. +inline bool RefCountDec(volatile Atomic32 *ptr) { + return Barrier_AtomicIncrement(ptr, -1) != 0; +} + +inline void RefCountInc(volatile Atomic32 *ptr) { + NoBarrier_AtomicIncrement(ptr, 1); +} + +template class shared_ptr; +template class weak_ptr; + +// This class is an internal implementation detail for shared_ptr. If two +// shared_ptrs point to the same object, they also share a control block. +// An "empty" shared_pointer refers to NULL and also has a NULL control block. +// It contains all of the state that's needed for reference counting or any +// other kind of resource management. In this implementation the control block +// happens to consist of two atomic words, the reference count (the number +// of shared_ptrs that share ownership of the object) and the weak count +// (the number of weak_ptrs that observe the object, plus 1 if the +// refcount is nonzero). +// +// The "plus 1" is to prevent a race condition in the shared_ptr and +// weak_ptr destructors. We need to make sure the control block is +// only deleted once, so we need to make sure that at most one +// object sees the weak count decremented from 1 to 0. +class SharedPtrControlBlock { + template friend class shared_ptr; + template friend class weak_ptr; + private: + SharedPtrControlBlock() : refcount_(1), weak_count_(1) { } + Atomic32 refcount_; + Atomic32 weak_count_; +}; + +// Forward declaration. The class is defined below. +template class enable_shared_from_this; + +template +class shared_ptr { + template friend class weak_ptr; + public: + typedef T element_type; + + shared_ptr() : ptr_(NULL), control_block_(NULL) {} + + explicit shared_ptr(T* ptr) + : ptr_(ptr), + control_block_(ptr != NULL ? new SharedPtrControlBlock : NULL) { + // If p is non-null and T inherits from enable_shared_from_this, we + // set up the data that shared_from_this needs. + MaybeSetupWeakThis(ptr); + } + + // Copy constructor: makes this object a copy of ptr, and increments + // the reference count. + template + shared_ptr(const shared_ptr& ptr) + : ptr_(NULL), + control_block_(NULL) { + Initialize(ptr); + } + // Need non-templated version to prevent the compiler-generated default + shared_ptr(const shared_ptr& ptr) + : ptr_(NULL), + control_block_(NULL) { + Initialize(ptr); + } + + // Assignment operator. Replaces the existing shared_ptr with ptr. + // Increment ptr's reference count and decrement the one being replaced. + template + shared_ptr& operator=(const shared_ptr& ptr) { + if (ptr_ != ptr.ptr_) { + shared_ptr me(ptr); // will hold our previous state to be destroyed. + swap(me); + } + return *this; + } + + // Need non-templated version to prevent the compiler-generated default + shared_ptr& operator=(const shared_ptr& ptr) { + if (ptr_ != ptr.ptr_) { + shared_ptr me(ptr); // will hold our previous state to be destroyed. + swap(me); + } + return *this; + } + + // TODO(austern): Consider providing this constructor. The draft C++ standard + // (20.8.10.2.1) includes it. However, it says that this constructor throws + // a bad_weak_ptr exception when ptr is expired. Is it better to provide this + // constructor and make it do something else, like fail with a CHECK, or to + // leave this constructor out entirely? + // + // template + // shared_ptr(const weak_ptr& ptr); + + ~shared_ptr() { + if (ptr_ != NULL) { + if (!RefCountDec(&control_block_->refcount_)) { + delete ptr_; + + // weak_count_ is defined as the number of weak_ptrs that observe + // ptr_, plus 1 if refcount_ is nonzero. + if (!RefCountDec(&control_block_->weak_count_)) { + delete control_block_; + } + } + } + } + + // Replaces underlying raw pointer with the one passed in. The reference + // count is set to one (or zero if the pointer is NULL) for the pointer + // being passed in and decremented for the one being replaced. + // + // If you have a compilation error with this code, make sure you aren't + // passing NULL, nullptr, or 0 to this function. Call reset without an + // argument to reset to a null ptr. + template + void reset(Y* p) { + if (p != ptr_) { + shared_ptr tmp(p); + tmp.swap(*this); + } + } + + void reset() { + reset(static_cast(NULL)); + } + + // Exchanges the contents of this with the contents of r. This function + // supports more efficient swapping since it eliminates the need for a + // temporary shared_ptr object. + void swap(shared_ptr& r) { + using std::swap; // http://go/using-std-swap + swap(ptr_, r.ptr_); + swap(control_block_, r.control_block_); + } + + // The following function is useful for gaining access to the underlying + // pointer when a shared_ptr remains in scope so the reference-count is + // known to be > 0 (e.g. for parameter passing). + T* get() const { + return ptr_; + } + + T& operator*() const { + return *ptr_; + } + + T* operator->() const { + return ptr_; + } + + long use_count() const { + return control_block_ ? control_block_->refcount_ : 1; + } + + bool unique() const { + return use_count() == 1; + } + + private: + // If r is non-empty, initialize *this to share ownership with r, + // increasing the underlying reference count. + // If r is empty, *this remains empty. + // Requires: this is empty, namely this->ptr_ == NULL. + template + void Initialize(const shared_ptr& r) { + // This performs a static_cast on r.ptr_ to U*, which is a no-op since it + // is already a U*. So initialization here requires that r.ptr_ is + // implicitly convertible to T*. + InitializeWithStaticCast(r); + } + + // Initializes *this as described in Initialize, but additionally performs a + // static_cast from r.ptr_ (V*) to U*. + // NOTE(gfc): We'd need a more general form to support const_pointer_cast and + // dynamic_pointer_cast, but those operations are sufficiently discouraged + // that supporting static_pointer_cast is sufficient. + template + void InitializeWithStaticCast(const shared_ptr& r) { + if (r.control_block_ != NULL) { + RefCountInc(&r.control_block_->refcount_); + + ptr_ = static_cast(r.ptr_); + control_block_ = r.control_block_; + } + } + + // Helper function for the constructor that takes a raw pointer. If T + // doesn't inherit from enable_shared_from_this then we have nothing to + // do, so this function is trivial and inline. The other version is declared + // out of line, after the class definition of enable_shared_from_this. + void MaybeSetupWeakThis(enable_shared_from_this* ptr); + void MaybeSetupWeakThis(...) { } + + T* ptr_; + SharedPtrControlBlock* control_block_; + +#ifndef SWIG + template + friend class shared_ptr; + + template + friend shared_ptr static_pointer_cast(const shared_ptr& rhs); +#endif +}; + +// Matches the interface of std::swap as an aid to generic programming. +template void swap(shared_ptr& r, shared_ptr& s) { + r.swap(s); +} + +template +shared_ptr static_pointer_cast(const shared_ptr& rhs) { + shared_ptr lhs; + lhs.template InitializeWithStaticCast(rhs); + return lhs; +} + +// See comments at the top of the file for a description of why this +// class exists, and the draft C++ standard (as of July 2009 the +// latest draft is N2914) for the detailed specification. +template +class weak_ptr { + template friend class weak_ptr; + public: + typedef T element_type; + + // Create an empty (i.e. already expired) weak_ptr. + weak_ptr() : ptr_(NULL), control_block_(NULL) { } + + // Create a weak_ptr that observes the same object that ptr points + // to. Note that there is no race condition here: we know that the + // control block can't disappear while we're looking at it because + // it is owned by at least one shared_ptr, ptr. + template weak_ptr(const shared_ptr& ptr) { + CopyFrom(ptr.ptr_, ptr.control_block_); + } + + // Copy a weak_ptr. The object it points to might disappear, but we + // don't care: we're only working with the control block, and it can't + // disappear while we're looking at because it's owned by at least one + // weak_ptr, ptr. + template weak_ptr(const weak_ptr& ptr) { + CopyFrom(ptr.ptr_, ptr.control_block_); + } + + // Need non-templated version to prevent default copy constructor + weak_ptr(const weak_ptr& ptr) { + CopyFrom(ptr.ptr_, ptr.control_block_); + } + + // Destroy the weak_ptr. If no shared_ptr owns the control block, and if + // we are the last weak_ptr to own it, then it can be deleted. Note that + // weak_count_ is defined as the number of weak_ptrs sharing this control + // block, plus 1 if there are any shared_ptrs. We therefore know that it's + // safe to delete the control block when weak_count_ reaches 0, without + // having to perform any additional tests. + ~weak_ptr() { + if (control_block_ != NULL && + !RefCountDec(&control_block_->weak_count_)) { + delete control_block_; + } + } + + weak_ptr& operator=(const weak_ptr& ptr) { + if (&ptr != this) { + weak_ptr tmp(ptr); + tmp.swap(*this); + } + return *this; + } + template weak_ptr& operator=(const weak_ptr& ptr) { + weak_ptr tmp(ptr); + tmp.swap(*this); + return *this; + } + template weak_ptr& operator=(const shared_ptr& ptr) { + weak_ptr tmp(ptr); + tmp.swap(*this); + return *this; + } + + void swap(weak_ptr& ptr) { + using std::swap; // http://go/using-std-swap + swap(ptr_, ptr.ptr_); + swap(control_block_, ptr.control_block_); + } + + void reset() { + weak_ptr tmp; + tmp.swap(*this); + } + + // Return the number of shared_ptrs that own the object we are observing. + // Note that this number can be 0 (if this pointer has expired). + long use_count() const { + return control_block_ != NULL ? control_block_->refcount_ : 0; + } + + bool expired() const { return use_count() == 0; } + + // Return a shared_ptr that owns the object we are observing. If we + // have expired, the shared_ptr will be empty. We have to be careful + // about concurrency, though, since some other thread might be + // destroying the last owning shared_ptr while we're in this + // function. We want to increment the refcount only if it's nonzero + // and get the new value, and we want that whole operation to be + // atomic. + shared_ptr lock() const { + shared_ptr result; + if (control_block_ != NULL) { + Atomic32 old_refcount; + do { + old_refcount = control_block_->refcount_; + if (old_refcount == 0) + break; + } while (old_refcount != + NoBarrier_CompareAndSwap( + &control_block_->refcount_, old_refcount, + old_refcount + 1)); + if (old_refcount > 0) { + result.ptr_ = ptr_; + result.control_block_ = control_block_; + } + } + + return result; + } + + private: + void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) { + ptr_ = ptr; + control_block_ = control_block; + if (control_block_ != NULL) + RefCountInc(&control_block_->weak_count_); + } + + private: + element_type* ptr_; + SharedPtrControlBlock* control_block_; +}; + +template void swap(weak_ptr& r, weak_ptr& s) { + r.swap(s); +} + +// See comments at the top of the file for a description of why this class +// exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009 +// the latest draft is N2914) for the detailed specification. +template +class enable_shared_from_this { + friend class shared_ptr; + public: + // Precondition: there must be a shared_ptr that owns *this and that was + // created, directly or indirectly, from a raw pointer of type T*. (The + // latter part of the condition is technical but not quite redundant; it + // rules out some complicated uses involving inheritance hierarchies.) + shared_ptr shared_from_this() { + // Behavior is undefined if the precondition isn't satisfied; we choose + // to die with a CHECK failure. + CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; + return weak_this_.lock(); + } + shared_ptr shared_from_this() const { + CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; + return weak_this_.lock(); + } + + protected: + enable_shared_from_this() { } + enable_shared_from_this(const enable_shared_from_this& other) { } + enable_shared_from_this& operator=(const enable_shared_from_this& other) { + return *this; + } + ~enable_shared_from_this() { } + + private: + weak_ptr weak_this_; +}; + +// This is a helper function called by shared_ptr's constructor from a raw +// pointer. If T inherits from enable_shared_from_this, it sets up +// weak_this_ so that shared_from_this works correctly. If T does not inherit +// from weak_this we get a different overload, defined inline, which does +// nothing. +template +void shared_ptr::MaybeSetupWeakThis(enable_shared_from_this* ptr) { + if (ptr) { + CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr"; + ptr->weak_this_ = *this; + } +} + +#endif // UTIL_GTL_USE_STD_SHARED_PTR + +} // internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__ diff --git a/thirdparty/linux/include/google/protobuf/stubs/singleton.h b/thirdparty/linux/include/google/protobuf/stubs/singleton.h new file mode 100644 index 0000000..9301f54 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/singleton.h @@ -0,0 +1,68 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef GOOGLE_PROTOBUF_STUBS_SINGLETON_H__ +#define GOOGLE_PROTOBUF_STUBS_SINGLETON_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { +template +class Singleton { + public: + static T* get() { + GoogleOnceInit(&once_, &Singleton::Init); + return instance_; + } + static void ShutDown() { + delete instance_; + instance_ = NULL; + } + private: + static void Init() { + instance_ = new T(); + } + static ProtobufOnceType once_; + static T* instance_; +}; + +template +ProtobufOnceType Singleton::once_; + +template +T* Singleton::instance_ = NULL; +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_SINGLETON_H__ diff --git a/thirdparty/linux/include/google/protobuf/stubs/status.h b/thirdparty/linux/include/google/protobuf/stubs/status.h new file mode 100644 index 0000000..614ab99 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/status.h @@ -0,0 +1,116 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef GOOGLE_PROTOBUF_STUBS_STATUS_H_ +#define GOOGLE_PROTOBUF_STUBS_STATUS_H_ + +#include +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace util { +namespace error { +// These values must match error codes defined in google/rpc/code.proto. +enum Code { + OK = 0, + CANCELLED = 1, + UNKNOWN = 2, + INVALID_ARGUMENT = 3, + DEADLINE_EXCEEDED = 4, + NOT_FOUND = 5, + ALREADY_EXISTS = 6, + PERMISSION_DENIED = 7, + UNAUTHENTICATED = 16, + RESOURCE_EXHAUSTED = 8, + FAILED_PRECONDITION = 9, + ABORTED = 10, + OUT_OF_RANGE = 11, + UNIMPLEMENTED = 12, + INTERNAL = 13, + UNAVAILABLE = 14, + DATA_LOSS = 15, +}; +} // namespace error + +class LIBPROTOBUF_EXPORT Status { + public: + // Creates a "successful" status. + Status(); + + // Create a status in the canonical error space with the specified + // code, and error message. If "code == 0", error_message is + // ignored and a Status object identical to Status::OK is + // constructed. + Status(error::Code error_code, StringPiece error_message); + Status(const Status&); + Status& operator=(const Status& x); + ~Status() {} + + // Some pre-defined Status objects + static const Status OK; // Identical to 0-arg constructor + static const Status CANCELLED; + static const Status UNKNOWN; + + // Accessor + bool ok() const { + return error_code_ == error::OK; + } + int error_code() const { + return error_code_; + } + StringPiece error_message() const { + return error_message_; + } + + bool operator==(const Status& x) const; + bool operator!=(const Status& x) const { + return !operator==(x); + } + + // Return a combination of the error code name and message. + string ToString() const; + + private: + error::Code error_code_; + string error_message_; +}; + +// Prints a human-readable representation of 'x' to 'os'. +LIBPROTOBUF_EXPORT ostream& operator<<(ostream& os, const Status& x); + +#define EXPECT_OK(value) EXPECT_TRUE((value).ok()) + +} // namespace util +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_STUBS_STATUS_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/stl_util.h b/thirdparty/linux/include/google/protobuf/stubs/stl_util.h new file mode 100644 index 0000000..9e4c82a --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/stl_util.h @@ -0,0 +1,121 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// from google3/util/gtl/stl_util.h + +#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ +#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ + +#include + +namespace google { +namespace protobuf { + +// STLDeleteContainerPointers() +// For a range within a container of pointers, calls delete +// (non-array version) on these pointers. +// NOTE: for these three functions, we could just implement a DeleteObject +// functor and then call for_each() on the range and functor, but this +// requires us to pull in all of algorithm.h, which seems expensive. +// For hash_[multi]set, it is important that this deletes behind the iterator +// because the hash_set may call the hash function on the iterator when it is +// advanced, which could result in the hash function trying to deference a +// stale pointer. +template +void STLDeleteContainerPointers(ForwardIterator begin, + ForwardIterator end) { + while (begin != end) { + ForwardIterator temp = begin; + ++begin; + delete *temp; + } +} + +// Inside Google, this function implements a horrible, disgusting hack in which +// we reach into the string's private implementation and resize it without +// initializing the new bytes. In some cases doing this can significantly +// improve performance. However, since it's totally non-portable it has no +// place in open source code. Feel free to fill this function in with your +// own disgusting hack if you want the perf boost. +inline void STLStringResizeUninitialized(string* s, size_t new_size) { + s->resize(new_size); +} + +// Return a mutable char* pointing to a string's internal buffer, +// which may not be null-terminated. Writing through this pointer will +// modify the string. +// +// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the +// next call to a string method that invalidates iterators. +// +// As of 2006-04, there is no standard-blessed way of getting a +// mutable reference to a string's internal buffer. However, issue 530 +// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) +// proposes this as the method. According to Matt Austern, this should +// already work on all current implementations. +inline char* string_as_array(string* str) { + // DO NOT USE const_cast(str->data())! See the unittest for why. + return str->empty() ? NULL : &*str->begin(); +} + +// STLDeleteElements() deletes all the elements in an STL container and clears +// the container. This function is suitable for use with a vector, set, +// hash_set, or any other STL container which defines sensible begin(), end(), +// and clear() methods. +// +// If container is NULL, this function is a no-op. +// +// As an alternative to calling STLDeleteElements() directly, consider +// ElementDeleter (defined below), which ensures that your container's elements +// are deleted when the ElementDeleter goes out of scope. +template +void STLDeleteElements(T *container) { + if (!container) return; + STLDeleteContainerPointers(container->begin(), container->end()); + container->clear(); +} + +// Given an STL container consisting of (key, value) pairs, STLDeleteValues +// deletes all the "value" components and clears the container. Does nothing +// in the case it's given a NULL pointer. + +template +void STLDeleteValues(T *v) { + if (!v) return; + for (typename T::iterator i = v->begin(); i != v->end(); ++i) { + delete i->second; + } + v->clear(); +} + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__ diff --git a/thirdparty/linux/include/google/protobuf/stubs/stringpiece.h b/thirdparty/linux/include/google/protobuf/stubs/stringpiece.h new file mode 100644 index 0000000..8910688 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/stringpiece.h @@ -0,0 +1,483 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// A StringPiece points to part or all of a string, Cord, double-quoted string +// literal, or other string-like object. A StringPiece does *not* own the +// string to which it points. A StringPiece is not null-terminated. +// +// You can use StringPiece as a function or method parameter. A StringPiece +// parameter can receive a double-quoted string literal argument, a "const +// char*" argument, a string argument, or a StringPiece argument with no data +// copying. Systematic use of StringPiece for arguments reduces data +// copies and strlen() calls. +// +// Prefer passing StringPieces by value: +// void MyFunction(StringPiece arg); +// If circumstances require, you may also pass by const reference: +// void MyFunction(const StringPiece& arg); // not preferred +// Both of these have the same lifetime semantics. Passing by value +// generates slightly smaller code. For more discussion, see the thread +// go/stringpiecebyvalue on c-users. +// +// StringPiece is also suitable for local variables if you know that +// the lifetime of the underlying object is longer than the lifetime +// of your StringPiece variable. +// +// Beware of binding a StringPiece to a temporary: +// StringPiece sp = obj.MethodReturningString(); // BAD: lifetime problem +// +// This code is okay: +// string str = obj.MethodReturningString(); // str owns its contents +// StringPiece sp(str); // GOOD, because str outlives sp +// +// StringPiece is sometimes a poor choice for a return value and usually a poor +// choice for a data member. If you do use a StringPiece this way, it is your +// responsibility to ensure that the object pointed to by the StringPiece +// outlives the StringPiece. +// +// A StringPiece may represent just part of a string; thus the name "Piece". +// For example, when splitting a string, vector is a natural data +// type for the output. For another example, a Cord is a non-contiguous, +// potentially very long string-like object. The Cord class has an interface +// that iteratively provides StringPiece objects that point to the +// successive pieces of a Cord object. +// +// A StringPiece is not null-terminated. If you write code that scans a +// StringPiece, you must check its length before reading any characters. +// Common idioms that work on null-terminated strings do not work on +// StringPiece objects. +// +// There are several ways to create a null StringPiece: +// StringPiece() +// StringPiece(NULL) +// StringPiece(NULL, 0) +// For all of the above, sp.data() == NULL, sp.length() == 0, +// and sp.empty() == true. Also, if you create a StringPiece with +// a non-NULL pointer then sp.data() != NULL. Once created, +// sp.data() will stay either NULL or not-NULL, except if you call +// sp.clear() or sp.set(). +// +// Thus, you can use StringPiece(NULL) to signal an out-of-band value +// that is different from other StringPiece values. This is similar +// to the way that const char* p1 = NULL; is different from +// const char* p2 = "";. +// +// There are many ways to create an empty StringPiece: +// StringPiece() +// StringPiece(NULL) +// StringPiece(NULL, 0) +// StringPiece("") +// StringPiece("", 0) +// StringPiece("abcdef", 0) +// StringPiece("abcdef"+6, 0) +// For all of the above, sp.length() will be 0 and sp.empty() will be true. +// For some empty StringPiece values, sp.data() will be NULL. +// For some empty StringPiece values, sp.data() will not be NULL. +// +// Be careful not to confuse: null StringPiece and empty StringPiece. +// The set of empty StringPieces properly includes the set of null StringPieces. +// That is, every null StringPiece is an empty StringPiece, +// but some non-null StringPieces are empty Stringpieces too. +// +// All empty StringPiece values compare equal to each other. +// Even a null StringPieces compares equal to a non-null empty StringPiece: +// StringPiece() == StringPiece("", 0) +// StringPiece(NULL) == StringPiece("abc", 0) +// StringPiece(NULL, 0) == StringPiece("abcdef"+6, 0) +// +// Look carefully at this example: +// StringPiece("") == NULL +// True or false? TRUE, because StringPiece::operator== converts +// the right-hand side from NULL to StringPiece(NULL), +// and then compares two zero-length spans of characters. +// However, we are working to make this example produce a compile error. +// +// Suppose you want to write: +// bool TestWhat?(StringPiece sp) { return sp == NULL; } // BAD +// Do not do that. Write one of these instead: +// bool TestNull(StringPiece sp) { return sp.data() == NULL; } +// bool TestEmpty(StringPiece sp) { return sp.empty(); } +// The intent of TestWhat? is unclear. Did you mean TestNull or TestEmpty? +// Right now, TestWhat? behaves likes TestEmpty. +// We are working to make TestWhat? produce a compile error. +// TestNull is good to test for an out-of-band signal. +// TestEmpty is good to test for an empty StringPiece. +// +// Caveats (again): +// (1) The lifetime of the pointed-to string (or piece of a string) +// must be longer than the lifetime of the StringPiece. +// (2) There may or may not be a '\0' character after the end of +// StringPiece data. +// (3) A null StringPiece is empty. +// An empty StringPiece may or may not be a null StringPiece. + +#ifndef GOOGLE_PROTOBUF_STUBS_STRINGPIECE_H_ +#define GOOGLE_PROTOBUF_STUBS_STRINGPIECE_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace google { +namespace protobuf { +// StringPiece has *two* size types. +// StringPiece::size_type +// is unsigned +// is 32 bits in LP32, 64 bits in LP64, 64 bits in LLP64 +// no future changes intended +// stringpiece_ssize_type +// is signed +// is 32 bits in LP32, 64 bits in LP64, 64 bits in LLP64 +// future changes intended: http://go/64BitStringPiece +// +typedef string::difference_type stringpiece_ssize_type; + +// STRINGPIECE_CHECK_SIZE protects us from 32-bit overflows. +// TODO(mec): delete this after stringpiece_ssize_type goes 64 bit. +#if !defined(NDEBUG) +#define STRINGPIECE_CHECK_SIZE 1 +#elif defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 +#define STRINGPIECE_CHECK_SIZE 1 +#else +#define STRINGPIECE_CHECK_SIZE 0 +#endif + +class LIBPROTOBUF_EXPORT StringPiece { + private: + const char* ptr_; + stringpiece_ssize_type length_; + + // Prevent overflow in debug mode or fortified mode. + // sizeof(stringpiece_ssize_type) may be smaller than sizeof(size_t). + static stringpiece_ssize_type CheckedSsizeTFromSizeT(size_t size) { +#if STRINGPIECE_CHECK_SIZE > 0 +#ifdef max +#undef max +#endif + if (size > static_cast( + std::numeric_limits::max())) { + // Some people grep for this message in logs + // so take care if you ever change it. + LogFatalSizeTooBig(size, "size_t to int conversion"); + } +#endif + return static_cast(size); + } + + // Out-of-line error path. + static void LogFatalSizeTooBig(size_t size, const char* details); + + public: + // We provide non-explicit singleton constructors so users can pass + // in a "const char*" or a "string" wherever a "StringPiece" is + // expected. + // + // Style guide exception granted: + // http://goto/style-guide-exception-20978288 + StringPiece() : ptr_(NULL), length_(0) {} + + StringPiece(const char* str) // NOLINT(runtime/explicit) + : ptr_(str), length_(0) { + if (str != NULL) { + length_ = CheckedSsizeTFromSizeT(strlen(str)); + } + } + + template + StringPiece( // NOLINT(runtime/explicit) + const std::basic_string, Allocator>& str) + : ptr_(str.data()), length_(0) { + length_ = CheckedSsizeTFromSizeT(str.size()); + } + + StringPiece(const char* offset, stringpiece_ssize_type len) + : ptr_(offset), length_(len) { + assert(len >= 0); + } + + // Substring of another StringPiece. + // pos must be non-negative and <= x.length(). + StringPiece(StringPiece x, stringpiece_ssize_type pos); + // Substring of another StringPiece. + // pos must be non-negative and <= x.length(). + // len must be non-negative and will be pinned to at most x.length() - pos. + StringPiece(StringPiece x, + stringpiece_ssize_type pos, + stringpiece_ssize_type len); + + // data() may return a pointer to a buffer with embedded NULs, and the + // returned buffer may or may not be null terminated. Therefore it is + // typically a mistake to pass data() to a routine that expects a NUL + // terminated string. + const char* data() const { return ptr_; } + stringpiece_ssize_type size() const { return length_; } + stringpiece_ssize_type length() const { return length_; } + bool empty() const { return length_ == 0; } + + void clear() { + ptr_ = NULL; + length_ = 0; + } + + void set(const char* data, stringpiece_ssize_type len) { + assert(len >= 0); + ptr_ = data; + length_ = len; + } + + void set(const char* str) { + ptr_ = str; + if (str != NULL) + length_ = CheckedSsizeTFromSizeT(strlen(str)); + else + length_ = 0; + } + + void set(const void* data, stringpiece_ssize_type len) { + ptr_ = reinterpret_cast(data); + length_ = len; + } + + char operator[](stringpiece_ssize_type i) const { + assert(0 <= i); + assert(i < length_); + return ptr_[i]; + } + + void remove_prefix(stringpiece_ssize_type n) { + assert(length_ >= n); + ptr_ += n; + length_ -= n; + } + + void remove_suffix(stringpiece_ssize_type n) { + assert(length_ >= n); + length_ -= n; + } + + // returns {-1, 0, 1} + int compare(StringPiece x) const { + const stringpiece_ssize_type min_size = + length_ < x.length_ ? length_ : x.length_; + int r = memcmp(ptr_, x.ptr_, min_size); + if (r < 0) return -1; + if (r > 0) return 1; + if (length_ < x.length_) return -1; + if (length_ > x.length_) return 1; + return 0; + } + + string as_string() const { + return ToString(); + } + // We also define ToString() here, since many other string-like + // interfaces name the routine that converts to a C++ string + // "ToString", and it's confusing to have the method that does that + // for a StringPiece be called "as_string()". We also leave the + // "as_string()" method defined here for existing code. + string ToString() const { + if (ptr_ == NULL) return string(); + return string(data(), size()); + } + + operator string() const { + return ToString(); + } + + void CopyToString(string* target) const; + void AppendToString(string* target) const; + + bool starts_with(StringPiece x) const { + return (length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0); + } + + bool ends_with(StringPiece x) const { + return ((length_ >= x.length_) && + (memcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0)); + } + + // Checks whether StringPiece starts with x and if so advances the beginning + // of it to past the match. It's basically a shortcut for starts_with + // followed by remove_prefix. + bool Consume(StringPiece x); + // Like above but for the end of the string. + bool ConsumeFromEnd(StringPiece x); + + // standard STL container boilerplate + typedef char value_type; + typedef const char* pointer; + typedef const char& reference; + typedef const char& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static const size_type npos; + typedef const char* const_iterator; + typedef const char* iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + iterator begin() const { return ptr_; } + iterator end() const { return ptr_ + length_; } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(ptr_ + length_); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(ptr_); + } + stringpiece_ssize_type max_size() const { return length_; } + stringpiece_ssize_type capacity() const { return length_; } + + // cpplint.py emits a false positive [build/include_what_you_use] + stringpiece_ssize_type copy(char* buf, size_type n, size_type pos = 0) const; // NOLINT + + bool contains(StringPiece s) const; + + stringpiece_ssize_type find(StringPiece s, size_type pos = 0) const; + stringpiece_ssize_type find(char c, size_type pos = 0) const; + stringpiece_ssize_type rfind(StringPiece s, size_type pos = npos) const; + stringpiece_ssize_type rfind(char c, size_type pos = npos) const; + + stringpiece_ssize_type find_first_of(StringPiece s, size_type pos = 0) const; + stringpiece_ssize_type find_first_of(char c, size_type pos = 0) const { + return find(c, pos); + } + stringpiece_ssize_type find_first_not_of(StringPiece s, + size_type pos = 0) const; + stringpiece_ssize_type find_first_not_of(char c, size_type pos = 0) const; + stringpiece_ssize_type find_last_of(StringPiece s, + size_type pos = npos) const; + stringpiece_ssize_type find_last_of(char c, size_type pos = npos) const { + return rfind(c, pos); + } + stringpiece_ssize_type find_last_not_of(StringPiece s, + size_type pos = npos) const; + stringpiece_ssize_type find_last_not_of(char c, size_type pos = npos) const; + + StringPiece substr(size_type pos, size_type n = npos) const; +}; + +// This large function is defined inline so that in a fairly common case where +// one of the arguments is a literal, the compiler can elide a lot of the +// following comparisons. +inline bool operator==(StringPiece x, StringPiece y) { + stringpiece_ssize_type len = x.size(); + if (len != y.size()) { + return false; + } + + return x.data() == y.data() || len <= 0 || + memcmp(x.data(), y.data(), len) == 0; +} + +inline bool operator!=(StringPiece x, StringPiece y) { + return !(x == y); +} + +inline bool operator<(StringPiece x, StringPiece y) { + const stringpiece_ssize_type min_size = + x.size() < y.size() ? x.size() : y.size(); + const int r = memcmp(x.data(), y.data(), min_size); + return (r < 0) || (r == 0 && x.size() < y.size()); +} + +inline bool operator>(StringPiece x, StringPiece y) { + return y < x; +} + +inline bool operator<=(StringPiece x, StringPiece y) { + return !(x > y); +} + +inline bool operator>=(StringPiece x, StringPiece y) { + return !(x < y); +} + +// allow StringPiece to be logged +extern std::ostream& operator<<(std::ostream& o, StringPiece piece); + +namespace internal { +// StringPiece is not a POD and can not be used in an union (pre C++11). We +// need a POD version of it. +struct StringPiecePod { + // Create from a StringPiece. + static StringPiecePod CreateFromStringPiece(StringPiece str) { + StringPiecePod pod; + pod.data_ = str.data(); + pod.size_ = str.size(); + return pod; + } + + // Cast to StringPiece. + operator StringPiece() const { return StringPiece(data_, size_); } + + bool operator==(const char* value) const { + return StringPiece(data_, size_) == StringPiece(value); + } + + char operator[](stringpiece_ssize_type i) const { + assert(0 <= i); + assert(i < size_); + return data_[i]; + } + + const char* data() const { return data_; } + + stringpiece_ssize_type size() const { + return size_; + } + + std::string ToString() const { return std::string(data_, size_); } + private: + const char* data_; + stringpiece_ssize_type size_; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START +template<> struct hash { + size_t operator()(const StringPiece& s) const { + size_t result = 0; + for (const char *str = s.data(), *end = str + s.size(); str < end; str++) { + result = 5 * result + *str; + } + return result; + } +}; +GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END + +#endif // STRINGS_STRINGPIECE_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/template_util.h b/thirdparty/linux/include/google/protobuf/stubs/template_util.h new file mode 100644 index 0000000..feef904 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/template_util.h @@ -0,0 +1,138 @@ +// Copyright 2005 Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// ---- +// Author: lar@google.com (Laramie Leavitt) +// +// Template metaprogramming utility functions. +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. +// +// +// The names chosen here reflect those used in tr1 and the boost::mpl +// library, there are similar operations used in the Loki library as +// well. I prefer the boost names for 2 reasons: +// 1. I think that portions of the Boost libraries are more likely to +// be included in the c++ standard. +// 2. It is not impossible that some of the boost libraries will be +// included in our own build in the future. +// Both of these outcomes means that we may be able to directly replace +// some of these with boost equivalents. +// +#ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ +#define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ + +namespace google { +namespace protobuf { +namespace internal { + +// Types small_ and big_ are guaranteed such that sizeof(small_) < +// sizeof(big_) +typedef char small_; + +struct big_ { + char dummy[2]; +}; + +// Identity metafunction. +template +struct identity_ { + typedef T type; +}; + +// integral_constant, defined in tr1, is a wrapper for an integer +// value. We don't really need this generality; we could get away +// with hardcoding the integer type to bool. We use the fully +// general integer_constant for compatibility with tr1. + +template +struct integral_constant { + static const T value = v; + typedef T value_type; + typedef integral_constant type; +}; + +template const T integral_constant::value; + + +// Abbreviations: true_type and false_type are structs that represent boolean +// true and false values. Also define the boost::mpl versions of those names, +// true_ and false_. +typedef integral_constant true_type; +typedef integral_constant false_type; +typedef true_type true_; +typedef false_type false_; + +// if_ is a templatized conditional statement. +// if_ is a compile time evaluation of cond. +// if_<>::type contains A if cond is true, B otherwise. +template +struct if_{ + typedef A type; +}; + +template +struct if_ { + typedef B type; +}; + + +// type_equals_ is a template type comparator, similar to Loki IsSameType. +// type_equals_::value is true iff "A" is the same type as "B". +// +// New code should prefer base::is_same, defined in base/type_traits.h. +// It is functionally identical, but is_same is the standard spelling. +template +struct type_equals_ : public false_ { +}; + +template +struct type_equals_ : public true_ { +}; + +// and_ is a template && operator. +// and_::value evaluates "A::value && B::value". +template +struct and_ : public integral_constant { +}; + +// or_ is a template || operator. +// or_::value evaluates "A::value || B::value". +template +struct or_ : public integral_constant { +}; + + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ diff --git a/thirdparty/linux/include/google/protobuf/stubs/type_traits.h b/thirdparty/linux/include/google/protobuf/stubs/type_traits.h new file mode 100644 index 0000000..0d8127e --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/stubs/type_traits.h @@ -0,0 +1,364 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// ---- +// Author: Matt Austern +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. +// +// Define a small subset of tr1 type traits. The traits we define are: +// enable_if +// is_integral +// is_floating_point +// is_pointer +// is_enum +// is_reference +// is_pod +// has_trivial_constructor +// has_trivial_copy +// has_trivial_assign +// has_trivial_destructor +// remove_const +// remove_volatile +// remove_cv +// remove_reference +// add_reference +// remove_pointer +// is_same +// is_convertible +// We can add more type traits as required. + +#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_ +#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_ + +#include // for NULL +#include // For pair + +#include // For true_type and false_type + +namespace google { +namespace protobuf { +namespace internal { + +template +struct is_base_of { + typedef char (&yes)[1]; + typedef char (&no)[2]; + + // BEGIN GOOGLE LOCAL MODIFICATION -- check is a #define on Mac. + #undef check + // END GOOGLE LOCAL MODIFICATION + + static yes check(const B*); + static no check(const void*); + + enum { + value = sizeof(check(static_cast(NULL))) == sizeof(yes), + }; +}; + +template struct enable_if; +template struct is_integral; +template struct is_floating_point; +template struct is_pointer; +// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least) +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +// is_enum uses is_convertible, which is not available on MSVC. +template struct is_enum; +#endif +template struct is_reference; +template struct is_pod; +template struct has_trivial_constructor; +template struct has_trivial_copy; +template struct has_trivial_assign; +template struct has_trivial_destructor; +template struct remove_const; +template struct remove_volatile; +template struct remove_cv; +template struct remove_reference; +template struct add_reference; +template struct remove_pointer; +template struct is_same; +#if !(defined(__GNUC__) && __GNUC__ <= 3) +template struct is_convertible; +#endif + +// enable_if, equivalent semantics to c++11 std::enable_if, specifically: +// "If B is true, the member typedef type shall equal T; otherwise, there +// shall be no member typedef type." +// Specified by 20.9.7.6 [Other transformations] + +template struct enable_if { typedef T type; }; +template struct enable_if {}; +// is_integral is false except for the built-in integer types. A +// cv-qualified type is integral if and only if the underlying type is. +template struct is_integral : false_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +#if defined(_MSC_VER) +// wchar_t is not by default a distinct type from unsigned short in +// Microsoft C. +// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx +template<> struct is_integral<__wchar_t> : true_type { }; +#else +template<> struct is_integral : true_type { }; +#endif +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +#ifdef HAVE_LONG_LONG +template<> struct is_integral : true_type { }; +template<> struct is_integral : true_type { }; +#endif +template struct is_integral : is_integral { }; +template struct is_integral : is_integral { }; +template struct is_integral : is_integral { }; + +// is_floating_point is false except for the built-in floating-point types. +// A cv-qualified type is integral if and only if the underlying type is. +template struct is_floating_point : false_type { }; +template<> struct is_floating_point : true_type { }; +template<> struct is_floating_point : true_type { }; +template<> struct is_floating_point : true_type { }; +template struct is_floating_point + : is_floating_point { }; +template struct is_floating_point + : is_floating_point { }; +template struct is_floating_point + : is_floating_point { }; + +// is_pointer is false except for pointer types. A cv-qualified type (e.g. +// "int* const", as opposed to "int const*") is cv-qualified if and only if +// the underlying type is. +template struct is_pointer : false_type { }; +template struct is_pointer : true_type { }; +template struct is_pointer : is_pointer { }; +template struct is_pointer : is_pointer { }; +template struct is_pointer : is_pointer { }; + +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + +namespace type_traits_internal { + +template struct is_class_or_union { + template static small_ tester(void (U::*)()); + template static big_ tester(...); + static const bool value = sizeof(tester(0)) == sizeof(small_); +}; + +// is_convertible chokes if the first argument is an array. That's why +// we use add_reference here. +template struct is_enum_impl + : is_convertible::type, int> { }; + +template struct is_enum_impl : false_type { }; + +} // namespace type_traits_internal + +// Specified by TR1 [4.5.1] primary type categories. + +// Implementation note: +// +// Each type is either void, integral, floating point, array, pointer, +// reference, member object pointer, member function pointer, enum, +// union or class. Out of these, only integral, floating point, reference, +// class and enum types are potentially convertible to int. Therefore, +// if a type is not a reference, integral, floating point or class and +// is convertible to int, it's a enum. Adding cv-qualification to a type +// does not change whether it's an enum. +// +// Is-convertible-to-int check is done only if all other checks pass, +// because it can't be used with some types (e.g. void or classes with +// inaccessible conversion operators). +template struct is_enum + : type_traits_internal::is_enum_impl< + is_same::value || + is_integral::value || + is_floating_point::value || + is_reference::value || + type_traits_internal::is_class_or_union::value, + T> { }; + +template struct is_enum : is_enum { }; +template struct is_enum : is_enum { }; +template struct is_enum : is_enum { }; + +#endif + +// is_reference is false except for reference types. +template struct is_reference : false_type {}; +template struct is_reference : true_type {}; + + +// We can't get is_pod right without compiler help, so fail conservatively. +// We will assume it's false except for arithmetic types, enumerations, +// pointers and cv-qualified versions thereof. Note that std::pair +// is not a POD even if T and U are PODs. +template struct is_pod + : integral_constant::value || + is_floating_point::value || +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + // is_enum is not available on MSVC. + is_enum::value || +#endif + is_pointer::value)> { }; +template struct is_pod : is_pod { }; +template struct is_pod : is_pod { }; +template struct is_pod : is_pod { }; + + +// We can't get has_trivial_constructor right without compiler help, so +// fail conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial +// constructors. (3) array of a type with a trivial constructor. +// (4) const versions thereof. +template struct has_trivial_constructor : is_pod { }; +template struct has_trivial_constructor > + : integral_constant::value && + has_trivial_constructor::value)> { }; +template struct has_trivial_constructor + : has_trivial_constructor
    { }; +template struct has_trivial_constructor + : has_trivial_constructor { }; + +// We can't get has_trivial_copy right without compiler help, so fail +// conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial copy +// constructors. (3) array of a type with a trivial copy constructor. +// (4) const versions thereof. +template struct has_trivial_copy : is_pod { }; +template struct has_trivial_copy > + : integral_constant::value && + has_trivial_copy::value)> { }; +template struct has_trivial_copy + : has_trivial_copy { }; +template struct has_trivial_copy : has_trivial_copy { }; + +// We can't get has_trivial_assign right without compiler help, so fail +// conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial copy +// constructors. (3) array of a type with a trivial assign constructor. +template struct has_trivial_assign : is_pod { }; +template struct has_trivial_assign > + : integral_constant::value && + has_trivial_assign::value)> { }; +template struct has_trivial_assign + : has_trivial_assign { }; + +// We can't get has_trivial_destructor right without compiler help, so +// fail conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial +// destructors. (3) array of a type with a trivial destructor. +// (4) const versions thereof. +template struct has_trivial_destructor : is_pod { }; +template struct has_trivial_destructor > + : integral_constant::value && + has_trivial_destructor::value)> { }; +template struct has_trivial_destructor + : has_trivial_destructor { }; +template struct has_trivial_destructor + : has_trivial_destructor { }; + +// Specified by TR1 [4.7.1] +template struct remove_const { typedef T type; }; +template struct remove_const { typedef T type; }; +template struct remove_volatile { typedef T type; }; +template struct remove_volatile { typedef T type; }; +template struct remove_cv { + typedef typename remove_const::type>::type type; +}; + + +// Specified by TR1 [4.7.2] Reference modifications. +template struct remove_reference { typedef T type; }; +template struct remove_reference { typedef T type; }; + +template struct add_reference { typedef T& type; }; +template struct add_reference { typedef T& type; }; + +// Specified by TR1 [4.7.4] Pointer modifications. +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { + typedef T type; }; + +// Specified by TR1 [4.6] Relationships between types +template struct is_same : public false_type { }; +template struct is_same : public true_type { }; + +// Specified by TR1 [4.6] Relationships between types +#if !(defined(__GNUC__) && __GNUC__ <= 3) +namespace type_traits_internal { + +// This class is an implementation detail for is_convertible, and you +// don't need to know how it works to use is_convertible. For those +// who care: we declare two different functions, one whose argument is +// of type To and one with a variadic argument list. We give them +// return types of different size, so we can use sizeof to trick the +// compiler into telling us which function it would have chosen if we +// had called it with an argument of type From. See Alexandrescu's +// _Modern C++ Design_ for more details on this sort of trick. + +template +struct ConvertHelper { + static small_ Test(To); + static big_ Test(...); + static From Create(); + enum { + value = sizeof(Test(Create())) == sizeof(small_) + }; +}; +} // namespace type_traits_internal + +// Inherits from true_type if From is convertible to To, false_type otherwise. +template +struct is_convertible + : integral_constant::value> { +}; +#endif + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_TYPE_TRAITS_H_ diff --git a/thirdparty/linux/include/google/protobuf/text_format.h b/thirdparty/linux/include/google/protobuf/text_format.h new file mode 100644 index 0000000..ef3d4a8 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/text_format.h @@ -0,0 +1,517 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Utilities for printing and parsing protocol messages in a human-readable, +// text-based format. + +#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__ +#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__ + +#include +#include +#ifndef _SHARED_PTR_H +#include +#endif +#include +#include + +#include +#include +#include + +namespace google { +namespace protobuf { + +namespace io { + class ErrorCollector; // tokenizer.h +} + +// This class implements protocol buffer text format. Printing and parsing +// protocol messages in text format is useful for debugging and human editing +// of messages. +// +// This class is really a namespace that contains only static methods. +class LIBPROTOBUF_EXPORT TextFormat { + public: + // Outputs a textual representation of the given message to the given + // output stream. + static bool Print(const Message& message, io::ZeroCopyOutputStream* output); + + // Print the fields in an UnknownFieldSet. They are printed by tag number + // only. Embedded messages are heuristically identified by attempting to + // parse them. + static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output); + + // Like Print(), but outputs directly to a string. + static bool PrintToString(const Message& message, string* output); + + // Like PrintUnknownFields(), but outputs directly to a string. + static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, + string* output); + + // Outputs a textual representation of the value of the field supplied on + // the message supplied. For non-repeated fields, an index of -1 must + // be supplied. Note that this method will print the default value for a + // field if it is not set. + static void PrintFieldValueToString(const Message& message, + const FieldDescriptor* field, + int index, + string* output); + + // The default printer that converts scalar values from fields into + // their string representation. + // You can derive from this FieldValuePrinter if you want to have + // fields to be printed in a different way and register it at the + // Printer. + class LIBPROTOBUF_EXPORT FieldValuePrinter { + public: + FieldValuePrinter(); + virtual ~FieldValuePrinter(); + virtual string PrintBool(bool val) const; + virtual string PrintInt32(int32 val) const; + virtual string PrintUInt32(uint32 val) const; + virtual string PrintInt64(int64 val) const; + virtual string PrintUInt64(uint64 val) const; + virtual string PrintFloat(float val) const; + virtual string PrintDouble(double val) const; + virtual string PrintString(const string& val) const; + virtual string PrintBytes(const string& val) const; + virtual string PrintEnum(int32 val, const string& name) const; + virtual string PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field) const; + virtual string PrintMessageStart(const Message& message, + int field_index, + int field_count, + bool single_line_mode) const; + virtual string PrintMessageEnd(const Message& message, + int field_index, + int field_count, + bool single_line_mode) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter); + }; + + // Class for those users which require more fine-grained control over how + // a protobuffer message is printed out. + class LIBPROTOBUF_EXPORT Printer { + public: + Printer(); + ~Printer(); + + // Like TextFormat::Print + bool Print(const Message& message, io::ZeroCopyOutputStream* output) const; + // Like TextFormat::PrintUnknownFields + bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, + io::ZeroCopyOutputStream* output) const; + // Like TextFormat::PrintToString + bool PrintToString(const Message& message, string* output) const; + // Like TextFormat::PrintUnknownFieldsToString + bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, + string* output) const; + // Like TextFormat::PrintFieldValueToString + void PrintFieldValueToString(const Message& message, + const FieldDescriptor* field, + int index, + string* output) const; + + // Adjust the initial indent level of all output. Each indent level is + // equal to two spaces. + void SetInitialIndentLevel(int indent_level) { + initial_indent_level_ = indent_level; + } + + // If printing in single line mode, then the entire message will be output + // on a single line with no line breaks. + void SetSingleLineMode(bool single_line_mode) { + single_line_mode_ = single_line_mode; + } + + bool IsInSingleLineMode() { + return single_line_mode_; + } + + // If use_field_number is true, uses field number instead of field name. + void SetUseFieldNumber(bool use_field_number) { + use_field_number_ = use_field_number; + } + + // Set true to print repeated primitives in a format like: + // field_name: [1, 2, 3, 4] + // instead of printing each value on its own line. Short format applies + // only to primitive values -- i.e. everything except strings and + // sub-messages/groups. + void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) { + use_short_repeated_primitives_ = use_short_repeated_primitives; + } + + // Set true to output UTF-8 instead of ASCII. The only difference + // is that bytes >= 0x80 in string fields will not be escaped, + // because they are assumed to be part of UTF-8 multi-byte + // sequences. This will change the default FieldValuePrinter. + void SetUseUtf8StringEscaping(bool as_utf8); + + // Set the default FieldValuePrinter that is used for all fields that + // don't have a field-specific printer registered. + // Takes ownership of the printer. + void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer); + + // Sets whether we want to hide unknown fields or not. + // Usually unknown fields are printed in a generic way that includes the + // tag number of the field instead of field name. However, sometimes it + // is useful to be able to print the message without unknown fields (e.g. + // for the python protobuf version to maintain consistency between its pure + // python and c++ implementations). + void SetHideUnknownFields(bool hide) { + hide_unknown_fields_ = hide; + } + + // If print_message_fields_in_index_order is true, print fields of a proto + // message using the order defined in source code instead of the field + // number. By default, use the field number order. + void SetPrintMessageFieldsInIndexOrder( + bool print_message_fields_in_index_order) { + print_message_fields_in_index_order_ = + print_message_fields_in_index_order; + } + + // If expand==true, expand google.protobuf.Any payloads. The output + // will be of form + // [type_url] { } + // + // If expand==false, print Any using the default printer. The output will + // look like + // type_url: "" value: "serialized_content" + void SetExpandAny(bool expand) { + expand_any_ = expand; + } + + // If non-zero, we truncate all string fields that are longer than this + // threshold. This is useful when the proto message has very long strings, + // e.g., dump of encoded image file. + // + // NOTE(hfgong): Setting a non-zero value breaks round-trip safe + // property of TextFormat::Printer. That is, from the printed message, we + // cannot fully recover the original string field any more. + void SetTruncateStringFieldLongerThan( + const int64 truncate_string_field_longer_than) { + truncate_string_field_longer_than_ = truncate_string_field_longer_than; + } + + // Register a custom field-specific FieldValuePrinter for fields + // with a particular FieldDescriptor. + // Returns "true" if the registration succeeded, or "false", if there is + // already a printer for that FieldDescriptor. + // Takes ownership of the printer on successful registration. + bool RegisterFieldValuePrinter(const FieldDescriptor* field, + const FieldValuePrinter* printer); + + private: + // Forward declaration of an internal class used to print the text + // output to the OutputStream (see text_format.cc for implementation). + class TextGenerator; + + // Internal Print method, used for writing to the OutputStream via + // the TextGenerator class. + void Print(const Message& message, + TextGenerator& generator) const; + + // Print a single field. + void PrintField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const; + + // Print a repeated primitive field in short form. + void PrintShortRepeatedField(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const; + + // Print the name of a field -- i.e. everything that comes before the + // ':' for a single name/value pair. + void PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const; + + // Outputs a textual representation of the value of the field supplied on + // the message supplied or the default value if not set. + void PrintFieldValue(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + int index, + TextGenerator& generator) const; + + // Print the fields in an UnknownFieldSet. They are printed by tag number + // only. Embedded messages are heuristically identified by attempting to + // parse them. + void PrintUnknownFields(const UnknownFieldSet& unknown_fields, + TextGenerator& generator) const; + + bool PrintAny(const Message& message, TextGenerator& generator) const; + + int initial_indent_level_; + + bool single_line_mode_; + + bool use_field_number_; + + bool use_short_repeated_primitives_; + + bool hide_unknown_fields_; + + bool print_message_fields_in_index_order_; + + bool expand_any_; + + int64 truncate_string_field_longer_than_; + + google::protobuf::scoped_ptr default_field_value_printer_; + typedef map CustomPrinterMap; + CustomPrinterMap custom_printers_; + }; + + // Parses a text-format protocol message from the given input stream to + // the given message object. This function parses the human-readable format + // written by Print(). Returns true on success. The message is cleared first, + // even if the function fails -- See Merge() to avoid this behavior. + // + // Example input: "user {\n id: 123 extra { gender: MALE language: 'en' }\n}" + // + // One use for this function is parsing handwritten strings in test code. + // Another use is to parse the output from google::protobuf::Message::DebugString() + // (or ShortDebugString()), because these functions output using + // google::protobuf::TextFormat::Print(). + // + // If you would like to read a protocol buffer serialized in the + // (non-human-readable) binary wire format, see + // google::protobuf::MessageLite::ParseFromString(). + static bool Parse(io::ZeroCopyInputStream* input, Message* output); + // Like Parse(), but reads directly from a string. + static bool ParseFromString(const string& input, Message* output); + + // Like Parse(), but the data is merged into the given message, as if + // using Message::MergeFrom(). + static bool Merge(io::ZeroCopyInputStream* input, Message* output); + // Like Merge(), but reads directly from a string. + static bool MergeFromString(const string& input, Message* output); + + // Parse the given text as a single field value and store it into the + // given field of the given message. If the field is a repeated field, + // the new value will be added to the end + static bool ParseFieldValueFromString(const string& input, + const FieldDescriptor* field, + Message* message); + + // Interface that TextFormat::Parser can use to find extensions. + // This class may be extended in the future to find more information + // like fields, etc. + class LIBPROTOBUF_EXPORT Finder { + public: + virtual ~Finder(); + + // Try to find an extension of *message by fully-qualified field + // name. Returns NULL if no extension is known for this name or number. + virtual const FieldDescriptor* FindExtension( + Message* message, + const string& name) const = 0; + }; + + // A location in the parsed text. + struct ParseLocation { + int line; + int column; + + ParseLocation() : line(-1), column(-1) {} + ParseLocation(int line_param, int column_param) + : line(line_param), column(column_param) {} + }; + + // Data structure which is populated with the locations of each field + // value parsed from the text. + class LIBPROTOBUF_EXPORT ParseInfoTree { + public: + ParseInfoTree(); + ~ParseInfoTree(); + + // Returns the parse location for index-th value of the field in the parsed + // text. If none exists, returns a location with line = -1. Index should be + // -1 for not-repeated fields. + ParseLocation GetLocation(const FieldDescriptor* field, int index) const; + + // Returns the parse info tree for the given field, which must be a message + // type. The nested information tree is owned by the root tree and will be + // deleted when it is deleted. + ParseInfoTree* GetTreeForNested(const FieldDescriptor* field, + int index) const; + + private: + // Allow the text format parser to record information into the tree. + friend class TextFormat; + + // Records the starting location of a single value for a field. + void RecordLocation(const FieldDescriptor* field, ParseLocation location); + + // Create and records a nested tree for a nested message field. + ParseInfoTree* CreateNested(const FieldDescriptor* field); + + // Defines the map from the index-th field descriptor to its parse location. + typedef map > LocationMap; + + // Defines the map from the index-th field descriptor to the nested parse + // info tree. + typedef map > NestedMap; + + LocationMap locations_; + NestedMap nested_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree); + }; + + // For more control over parsing, use this class. + class LIBPROTOBUF_EXPORT Parser { + public: + Parser(); + ~Parser(); + + // Like TextFormat::Parse(). + bool Parse(io::ZeroCopyInputStream* input, Message* output); + // Like TextFormat::ParseFromString(). + bool ParseFromString(const string& input, Message* output); + // Like TextFormat::Merge(). + bool Merge(io::ZeroCopyInputStream* input, Message* output); + // Like TextFormat::MergeFromString(). + bool MergeFromString(const string& input, Message* output); + + // Set where to report parse errors. If NULL (the default), errors will + // be printed to stderr. + void RecordErrorsTo(io::ErrorCollector* error_collector) { + error_collector_ = error_collector; + } + + // Set how parser finds extensions. If NULL (the default), the + // parser will use the standard Reflection object associated with + // the message being parsed. + void SetFinder(Finder* finder) { + finder_ = finder; + } + + // Sets where location information about the parse will be written. If NULL + // (the default), then no location will be written. + void WriteLocationsTo(ParseInfoTree* tree) { + parse_info_tree_ = tree; + } + + // Normally parsing fails if, after parsing, output->IsInitialized() + // returns false. Call AllowPartialMessage(true) to skip this check. + void AllowPartialMessage(bool allow) { + allow_partial_ = allow; + } + + // Allow field names to be matched case-insensitively. + // This is not advisable if there are fields that only differ in case, or + // if you want to enforce writing in the canonical form. + // This is 'false' by default. + void AllowCaseInsensitiveField(bool allow) { + allow_case_insensitive_field_ = allow; + } + + // Like TextFormat::ParseFieldValueFromString + bool ParseFieldValueFromString(const string& input, + const FieldDescriptor* field, + Message* output); + + + void AllowFieldNumber(bool allow) { + allow_field_number_ = allow; + } + + private: + // Forward declaration of an internal class used to parse text + // representations (see text_format.cc for implementation). + class ParserImpl; + + // Like TextFormat::Merge(). The provided implementation is used + // to do the parsing. + bool MergeUsingImpl(io::ZeroCopyInputStream* input, + Message* output, + ParserImpl* parser_impl); + + io::ErrorCollector* error_collector_; + Finder* finder_; + ParseInfoTree* parse_info_tree_; + bool allow_partial_; + bool allow_case_insensitive_field_; + bool allow_unknown_field_; + bool allow_unknown_enum_; + bool allow_field_number_; + bool allow_relaxed_whitespace_; + bool allow_singular_overwrites_; + }; + + + private: + // Hack: ParseInfoTree declares TextFormat as a friend which should extend + // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some + // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide + // helpers for ParserImpl to call methods of ParseInfoTree. + static inline void RecordLocation(ParseInfoTree* info_tree, + const FieldDescriptor* field, + ParseLocation location); + static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree, + const FieldDescriptor* field); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat); +}; + +inline void TextFormat::RecordLocation(ParseInfoTree* info_tree, + const FieldDescriptor* field, + ParseLocation location) { + info_tree->RecordLocation(field, location); +} + + +inline TextFormat::ParseInfoTree* TextFormat::CreateNested( + ParseInfoTree* info_tree, const FieldDescriptor* field) { + return info_tree->CreateNested(field); +} + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__ diff --git a/thirdparty/linux/include/google/protobuf/timestamp.pb.h b/thirdparty/linux/include/google/protobuf/timestamp.pb.h new file mode 100644 index 0000000..19f4f86 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/timestamp.pb.h @@ -0,0 +1,189 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/timestamp.proto + +#ifndef PROTOBUF_google_2fprotobuf_2ftimestamp_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2ftimestamp_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2ftimestamp_2eproto(); + +class Timestamp; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Timestamp) */ { + public: + Timestamp(); + virtual ~Timestamp(); + + Timestamp(const Timestamp& from); + + inline Timestamp& operator=(const Timestamp& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const Timestamp& default_instance(); + + void UnsafeArenaSwap(Timestamp* other); + void Swap(Timestamp* other); + + // implements Message ---------------------------------------------- + + inline Timestamp* New() const { return New(NULL); } + + Timestamp* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Timestamp& from); + void MergeFrom(const Timestamp& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Timestamp* other); + protected: + explicit Timestamp(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 seconds = 1; + void clear_seconds(); + static const int kSecondsFieldNumber = 1; + ::google::protobuf::int64 seconds() const; + void set_seconds(::google::protobuf::int64 value); + + // optional int32 nanos = 2; + void clear_nanos(); + static const int kNanosFieldNumber = 2; + ::google::protobuf::int32 nanos() const; + void set_nanos(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Timestamp) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + ::google::protobuf::int64 seconds_; + ::google::protobuf::int32 nanos_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftimestamp_2eproto(); + + void InitAsDefaultInstance(); + static Timestamp* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Timestamp + +// optional int64 seconds = 1; +inline void Timestamp::clear_seconds() { + seconds_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 Timestamp::seconds() const { + // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.seconds) + return seconds_; +} +inline void Timestamp::set_seconds(::google::protobuf::int64 value) { + + seconds_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.seconds) +} + +// optional int32 nanos = 2; +inline void Timestamp::clear_nanos() { + nanos_ = 0; +} +inline ::google::protobuf::int32 Timestamp::nanos() const { + // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.nanos) + return nanos_; +} +inline void Timestamp::set_nanos(::google::protobuf::int32 value) { + + nanos_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.nanos) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2ftimestamp_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/timestamp.proto b/thirdparty/linux/include/google/protobuf/timestamp.proto new file mode 100644 index 0000000..7992a85 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/timestamp.proto @@ -0,0 +1,111 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/timestamp"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; + +// A Timestamp represents a point in time independent of any time zone +// or calendar, represented as seconds and fractions of seconds at +// nanosecond resolution in UTC Epoch time. It is encoded using the +// Proleptic Gregorian Calendar which extends the Gregorian calendar +// backwards to year one. It is encoded assuming all minutes are 60 +// seconds long, i.e. leap seconds are "smeared" so that no leap second +// table is needed for interpretation. Range is from +// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. +// By restricting to that range, we ensure that we can convert to +// and from RFC 3339 date strings. +// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// +// Example 5: Compute Timestamp from current time in Python. +// +// now = time.time() +// seconds = int(now) +// nanos = int((now - seconds) * 10**9) +// timestamp = Timestamp(seconds=seconds, nanos=nanos) +// +// +message Timestamp { + + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/thirdparty/linux/include/google/protobuf/type.pb.h b/thirdparty/linux/include/google/protobuf/type.pb.h new file mode 100644 index 0000000..ce29c28 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/type.pb.h @@ -0,0 +1,1751 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/type.proto + +#ifndef PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + +class Enum; +class EnumValue; +class Field; +class Option; +class Type; + +enum Field_Kind { + Field_Kind_TYPE_UNKNOWN = 0, + Field_Kind_TYPE_DOUBLE = 1, + Field_Kind_TYPE_FLOAT = 2, + Field_Kind_TYPE_INT64 = 3, + Field_Kind_TYPE_UINT64 = 4, + Field_Kind_TYPE_INT32 = 5, + Field_Kind_TYPE_FIXED64 = 6, + Field_Kind_TYPE_FIXED32 = 7, + Field_Kind_TYPE_BOOL = 8, + Field_Kind_TYPE_STRING = 9, + Field_Kind_TYPE_GROUP = 10, + Field_Kind_TYPE_MESSAGE = 11, + Field_Kind_TYPE_BYTES = 12, + Field_Kind_TYPE_UINT32 = 13, + Field_Kind_TYPE_ENUM = 14, + Field_Kind_TYPE_SFIXED32 = 15, + Field_Kind_TYPE_SFIXED64 = 16, + Field_Kind_TYPE_SINT32 = 17, + Field_Kind_TYPE_SINT64 = 18, + Field_Kind_Field_Kind_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +LIBPROTOBUF_EXPORT bool Field_Kind_IsValid(int value); +const Field_Kind Field_Kind_Kind_MIN = Field_Kind_TYPE_UNKNOWN; +const Field_Kind Field_Kind_Kind_MAX = Field_Kind_TYPE_SINT64; +const int Field_Kind_Kind_ARRAYSIZE = Field_Kind_Kind_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor(); +inline const ::std::string& Field_Kind_Name(Field_Kind value) { + return ::google::protobuf::internal::NameOfEnum( + Field_Kind_descriptor(), value); +} +inline bool Field_Kind_Parse( + const ::std::string& name, Field_Kind* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Field_Kind_descriptor(), name, value); +} +enum Field_Cardinality { + Field_Cardinality_CARDINALITY_UNKNOWN = 0, + Field_Cardinality_CARDINALITY_OPTIONAL = 1, + Field_Cardinality_CARDINALITY_REQUIRED = 2, + Field_Cardinality_CARDINALITY_REPEATED = 3, + Field_Cardinality_Field_Cardinality_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +LIBPROTOBUF_EXPORT bool Field_Cardinality_IsValid(int value); +const Field_Cardinality Field_Cardinality_Cardinality_MIN = Field_Cardinality_CARDINALITY_UNKNOWN; +const Field_Cardinality Field_Cardinality_Cardinality_MAX = Field_Cardinality_CARDINALITY_REPEATED; +const int Field_Cardinality_Cardinality_ARRAYSIZE = Field_Cardinality_Cardinality_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor(); +inline const ::std::string& Field_Cardinality_Name(Field_Cardinality value) { + return ::google::protobuf::internal::NameOfEnum( + Field_Cardinality_descriptor(), value); +} +inline bool Field_Cardinality_Parse( + const ::std::string& name, Field_Cardinality* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Field_Cardinality_descriptor(), name, value); +} +enum Syntax { + SYNTAX_PROTO2 = 0, + SYNTAX_PROTO3 = 1, + Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +LIBPROTOBUF_EXPORT bool Syntax_IsValid(int value); +const Syntax Syntax_MIN = SYNTAX_PROTO2; +const Syntax Syntax_MAX = SYNTAX_PROTO3; +const int Syntax_ARRAYSIZE = Syntax_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Syntax_descriptor(); +inline const ::std::string& Syntax_Name(Syntax value) { + return ::google::protobuf::internal::NameOfEnum( + Syntax_descriptor(), value); +} +inline bool Syntax_Parse( + const ::std::string& name, Syntax* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Syntax_descriptor(), name, value); +} +// =================================================================== + +class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ { + public: + Type(); + virtual ~Type(); + + Type(const Type& from); + + inline Type& operator=(const Type& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Type& default_instance(); + + void Swap(Type* other); + + // implements Message ---------------------------------------------- + + inline Type* New() const { return New(NULL); } + + Type* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Type& from); + void MergeFrom(const Type& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Type* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.Field fields = 2; + int fields_size() const; + void clear_fields(); + static const int kFieldsFieldNumber = 2; + const ::google::protobuf::Field& fields(int index) const; + ::google::protobuf::Field* mutable_fields(int index); + ::google::protobuf::Field* add_fields(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >* + mutable_fields(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >& + fields() const; + + // repeated string oneofs = 3; + int oneofs_size() const; + void clear_oneofs(); + static const int kOneofsFieldNumber = 3; + const ::std::string& oneofs(int index) const; + ::std::string* mutable_oneofs(int index); + void set_oneofs(int index, const ::std::string& value); + void set_oneofs(int index, const char* value); + void set_oneofs(int index, const char* value, size_t size); + ::std::string* add_oneofs(); + void add_oneofs(const ::std::string& value); + void add_oneofs(const char* value); + void add_oneofs(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& oneofs() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_oneofs(); + + // repeated .google.protobuf.Option options = 4; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 4; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + + // optional .google.protobuf.SourceContext source_context = 5; + bool has_source_context() const; + void clear_source_context(); + static const int kSourceContextFieldNumber = 5; + const ::google::protobuf::SourceContext& source_context() const; + ::google::protobuf::SourceContext* mutable_source_context(); + ::google::protobuf::SourceContext* release_source_context(); + void set_allocated_source_context(::google::protobuf::SourceContext* source_context); + + // optional .google.protobuf.Syntax syntax = 6; + void clear_syntax(); + static const int kSyntaxFieldNumber = 6; + ::google::protobuf::Syntax syntax() const; + void set_syntax(::google::protobuf::Syntax value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Type) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field > fields_; + ::google::protobuf::RepeatedPtrField< ::std::string> oneofs_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::SourceContext* source_context_; + int syntax_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static Type* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ { + public: + Field(); + virtual ~Field(); + + Field(const Field& from); + + inline Field& operator=(const Field& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Field& default_instance(); + + void Swap(Field* other); + + // implements Message ---------------------------------------------- + + inline Field* New() const { return New(NULL); } + + Field* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Field& from); + void MergeFrom(const Field& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Field* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef Field_Kind Kind; + static const Kind TYPE_UNKNOWN = + Field_Kind_TYPE_UNKNOWN; + static const Kind TYPE_DOUBLE = + Field_Kind_TYPE_DOUBLE; + static const Kind TYPE_FLOAT = + Field_Kind_TYPE_FLOAT; + static const Kind TYPE_INT64 = + Field_Kind_TYPE_INT64; + static const Kind TYPE_UINT64 = + Field_Kind_TYPE_UINT64; + static const Kind TYPE_INT32 = + Field_Kind_TYPE_INT32; + static const Kind TYPE_FIXED64 = + Field_Kind_TYPE_FIXED64; + static const Kind TYPE_FIXED32 = + Field_Kind_TYPE_FIXED32; + static const Kind TYPE_BOOL = + Field_Kind_TYPE_BOOL; + static const Kind TYPE_STRING = + Field_Kind_TYPE_STRING; + static const Kind TYPE_GROUP = + Field_Kind_TYPE_GROUP; + static const Kind TYPE_MESSAGE = + Field_Kind_TYPE_MESSAGE; + static const Kind TYPE_BYTES = + Field_Kind_TYPE_BYTES; + static const Kind TYPE_UINT32 = + Field_Kind_TYPE_UINT32; + static const Kind TYPE_ENUM = + Field_Kind_TYPE_ENUM; + static const Kind TYPE_SFIXED32 = + Field_Kind_TYPE_SFIXED32; + static const Kind TYPE_SFIXED64 = + Field_Kind_TYPE_SFIXED64; + static const Kind TYPE_SINT32 = + Field_Kind_TYPE_SINT32; + static const Kind TYPE_SINT64 = + Field_Kind_TYPE_SINT64; + static inline bool Kind_IsValid(int value) { + return Field_Kind_IsValid(value); + } + static const Kind Kind_MIN = + Field_Kind_Kind_MIN; + static const Kind Kind_MAX = + Field_Kind_Kind_MAX; + static const int Kind_ARRAYSIZE = + Field_Kind_Kind_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Kind_descriptor() { + return Field_Kind_descriptor(); + } + static inline const ::std::string& Kind_Name(Kind value) { + return Field_Kind_Name(value); + } + static inline bool Kind_Parse(const ::std::string& name, + Kind* value) { + return Field_Kind_Parse(name, value); + } + + typedef Field_Cardinality Cardinality; + static const Cardinality CARDINALITY_UNKNOWN = + Field_Cardinality_CARDINALITY_UNKNOWN; + static const Cardinality CARDINALITY_OPTIONAL = + Field_Cardinality_CARDINALITY_OPTIONAL; + static const Cardinality CARDINALITY_REQUIRED = + Field_Cardinality_CARDINALITY_REQUIRED; + static const Cardinality CARDINALITY_REPEATED = + Field_Cardinality_CARDINALITY_REPEATED; + static inline bool Cardinality_IsValid(int value) { + return Field_Cardinality_IsValid(value); + } + static const Cardinality Cardinality_MIN = + Field_Cardinality_Cardinality_MIN; + static const Cardinality Cardinality_MAX = + Field_Cardinality_Cardinality_MAX; + static const int Cardinality_ARRAYSIZE = + Field_Cardinality_Cardinality_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Cardinality_descriptor() { + return Field_Cardinality_descriptor(); + } + static inline const ::std::string& Cardinality_Name(Cardinality value) { + return Field_Cardinality_Name(value); + } + static inline bool Cardinality_Parse(const ::std::string& name, + Cardinality* value) { + return Field_Cardinality_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .google.protobuf.Field.Kind kind = 1; + void clear_kind(); + static const int kKindFieldNumber = 1; + ::google::protobuf::Field_Kind kind() const; + void set_kind(::google::protobuf::Field_Kind value); + + // optional .google.protobuf.Field.Cardinality cardinality = 2; + void clear_cardinality(); + static const int kCardinalityFieldNumber = 2; + ::google::protobuf::Field_Cardinality cardinality() const; + void set_cardinality(::google::protobuf::Field_Cardinality value); + + // optional int32 number = 3; + void clear_number(); + static const int kNumberFieldNumber = 3; + ::google::protobuf::int32 number() const; + void set_number(::google::protobuf::int32 value); + + // optional string name = 4; + void clear_name(); + static const int kNameFieldNumber = 4; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional string type_url = 6; + void clear_type_url(); + static const int kTypeUrlFieldNumber = 6; + const ::std::string& type_url() const; + void set_type_url(const ::std::string& value); + void set_type_url(const char* value); + void set_type_url(const char* value, size_t size); + ::std::string* mutable_type_url(); + ::std::string* release_type_url(); + void set_allocated_type_url(::std::string* type_url); + + // optional int32 oneof_index = 7; + void clear_oneof_index(); + static const int kOneofIndexFieldNumber = 7; + ::google::protobuf::int32 oneof_index() const; + void set_oneof_index(::google::protobuf::int32 value); + + // optional bool packed = 8; + void clear_packed(); + static const int kPackedFieldNumber = 8; + bool packed() const; + void set_packed(bool value); + + // repeated .google.protobuf.Option options = 9; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 9; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + + // optional string json_name = 10; + void clear_json_name(); + static const int kJsonNameFieldNumber = 10; + const ::std::string& json_name() const; + void set_json_name(const ::std::string& value); + void set_json_name(const char* value); + void set_json_name(const char* value, size_t size); + ::std::string* mutable_json_name(); + ::std::string* release_json_name(); + void set_allocated_json_name(::std::string* json_name); + + // optional string default_value = 11; + void clear_default_value(); + static const int kDefaultValueFieldNumber = 11; + const ::std::string& default_value() const; + void set_default_value(const ::std::string& value); + void set_default_value(const char* value); + void set_default_value(const char* value, size_t size); + ::std::string* mutable_default_value(); + ::std::string* release_default_value(); + void set_allocated_default_value(::std::string* default_value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Field) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + int kind_; + int cardinality_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::int32 number_; + ::google::protobuf::int32 oneof_index_; + ::google::protobuf::internal::ArenaStringPtr type_url_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::internal::ArenaStringPtr json_name_; + ::google::protobuf::internal::ArenaStringPtr default_value_; + bool packed_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static Field* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ { + public: + Enum(); + virtual ~Enum(); + + Enum(const Enum& from); + + inline Enum& operator=(const Enum& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Enum& default_instance(); + + void Swap(Enum* other); + + // implements Message ---------------------------------------------- + + inline Enum* New() const { return New(NULL); } + + Enum* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Enum& from); + void MergeFrom(const Enum& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Enum* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.EnumValue enumvalue = 2; + int enumvalue_size() const; + void clear_enumvalue(); + static const int kEnumvalueFieldNumber = 2; + const ::google::protobuf::EnumValue& enumvalue(int index) const; + ::google::protobuf::EnumValue* mutable_enumvalue(int index); + ::google::protobuf::EnumValue* add_enumvalue(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >* + mutable_enumvalue(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >& + enumvalue() const; + + // repeated .google.protobuf.Option options = 3; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + + // optional .google.protobuf.SourceContext source_context = 4; + bool has_source_context() const; + void clear_source_context(); + static const int kSourceContextFieldNumber = 4; + const ::google::protobuf::SourceContext& source_context() const; + ::google::protobuf::SourceContext* mutable_source_context(); + ::google::protobuf::SourceContext* release_source_context(); + void set_allocated_source_context(::google::protobuf::SourceContext* source_context); + + // optional .google.protobuf.Syntax syntax = 5; + void clear_syntax(); + static const int kSyntaxFieldNumber = 5; + ::google::protobuf::Syntax syntax() const; + void set_syntax(::google::protobuf::Syntax value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Enum) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue > enumvalue_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::SourceContext* source_context_; + int syntax_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static Enum* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ { + public: + EnumValue(); + virtual ~EnumValue(); + + EnumValue(const EnumValue& from); + + inline EnumValue& operator=(const EnumValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumValue& default_instance(); + + void Swap(EnumValue* other); + + // implements Message ---------------------------------------------- + + inline EnumValue* New() const { return New(NULL); } + + EnumValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumValue& from); + void MergeFrom(const EnumValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(EnumValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional int32 number = 2; + void clear_number(); + static const int kNumberFieldNumber = 2; + ::google::protobuf::int32 number() const; + void set_number(::google::protobuf::int32 value); + + // repeated .google.protobuf.Option options = 3; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::int32 number_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static EnumValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ { + public: + Option(); + virtual ~Option(); + + Option(const Option& from); + + inline Option& operator=(const Option& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Option& default_instance(); + + void Swap(Option* other); + + // implements Message ---------------------------------------------- + + inline Option* New() const { return New(NULL); } + + Option* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Option& from); + void MergeFrom(const Option& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Option* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional .google.protobuf.Any value = 2; + bool has_value() const; + void clear_value(); + static const int kValueFieldNumber = 2; + const ::google::protobuf::Any& value() const; + ::google::protobuf::Any* mutable_value(); + ::google::protobuf::Any* release_value(); + void set_allocated_value(::google::protobuf::Any* value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Option) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::Any* value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static Option* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Type + +// optional string name = 1; +inline void Type::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Type::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Type::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Type.name) +} +inline void Type::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Type.name) +} +inline void Type::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.name) +} +inline ::std::string* Type::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Type::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Type.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Type::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.name) +} + +// repeated .google.protobuf.Field fields = 2; +inline int Type::fields_size() const { + return fields_.size(); +} +inline void Type::clear_fields() { + fields_.Clear(); +} +inline const ::google::protobuf::Field& Type::fields(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.fields) + return fields_.Get(index); +} +inline ::google::protobuf::Field* Type::mutable_fields(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields) + return fields_.Mutable(index); +} +inline ::google::protobuf::Field* Type::add_fields() { + // @@protoc_insertion_point(field_add:google.protobuf.Type.fields) + return fields_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >* +Type::mutable_fields() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.fields) + return &fields_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >& +Type::fields() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.fields) + return fields_; +} + +// repeated string oneofs = 3; +inline int Type::oneofs_size() const { + return oneofs_.size(); +} +inline void Type::clear_oneofs() { + oneofs_.Clear(); +} +inline const ::std::string& Type::oneofs(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.oneofs) + return oneofs_.Get(index); +} +inline ::std::string* Type::mutable_oneofs(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.oneofs) + return oneofs_.Mutable(index); +} +inline void Type::set_oneofs(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs) + oneofs_.Mutable(index)->assign(value); +} +inline void Type::set_oneofs(int index, const char* value) { + oneofs_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs) +} +inline void Type::set_oneofs(int index, const char* value, size_t size) { + oneofs_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.oneofs) +} +inline ::std::string* Type::add_oneofs() { + // @@protoc_insertion_point(field_add_mutable:google.protobuf.Type.oneofs) + return oneofs_.Add(); +} +inline void Type::add_oneofs(const ::std::string& value) { + oneofs_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs) +} +inline void Type::add_oneofs(const char* value) { + oneofs_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs) +} +inline void Type::add_oneofs(const char* value, size_t size) { + oneofs_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.Type.oneofs) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +Type::oneofs() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.oneofs) + return oneofs_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +Type::mutable_oneofs() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.oneofs) + return &oneofs_; +} + +// repeated .google.protobuf.Option options = 4; +inline int Type::options_size() const { + return options_.size(); +} +inline void Type::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Type::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Type::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Type::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Type.options) + return options_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Type::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.options) + return &options_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Type::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.options) + return options_; +} + +// optional .google.protobuf.SourceContext source_context = 5; +inline bool Type::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +inline void Type::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} +inline const ::google::protobuf::SourceContext& Type::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} +inline ::google::protobuf::SourceContext* Type::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context) + return source_context_; +} +inline ::google::protobuf::SourceContext* Type::release_source_context() { + // @@protoc_insertion_point(field_release:google.protobuf.Type.source_context) + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} +inline void Type::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context) +} + +// optional .google.protobuf.Syntax syntax = 6; +inline void Type::clear_syntax() { + syntax_ = 0; +} +inline ::google::protobuf::Syntax Type::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.syntax) + return static_cast< ::google::protobuf::Syntax >(syntax_); +} +inline void Type::set_syntax(::google::protobuf::Syntax value) { + + syntax_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Type.syntax) +} + +// ------------------------------------------------------------------- + +// Field + +// optional .google.protobuf.Field.Kind kind = 1; +inline void Field::clear_kind() { + kind_ = 0; +} +inline ::google::protobuf::Field_Kind Field::kind() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.kind) + return static_cast< ::google::protobuf::Field_Kind >(kind_); +} +inline void Field::set_kind(::google::protobuf::Field_Kind value) { + + kind_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.kind) +} + +// optional .google.protobuf.Field.Cardinality cardinality = 2; +inline void Field::clear_cardinality() { + cardinality_ = 0; +} +inline ::google::protobuf::Field_Cardinality Field::cardinality() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.cardinality) + return static_cast< ::google::protobuf::Field_Cardinality >(cardinality_); +} +inline void Field::set_cardinality(::google::protobuf::Field_Cardinality value) { + + cardinality_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.cardinality) +} + +// optional int32 number = 3; +inline void Field::clear_number() { + number_ = 0; +} +inline ::google::protobuf::int32 Field::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.number) + return number_; +} +inline void Field::set_number(::google::protobuf::int32 value) { + + number_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.number) +} + +// optional string name = 4; +inline void Field::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Field::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.name) +} +inline void Field::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Field.name) +} +inline void Field::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.name) +} +inline ::std::string* Field::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Field::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Field.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name) +} + +// optional string type_url = 6; +inline void Field::clear_type_url() { + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Field::type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url) + return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_type_url(const ::std::string& value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url) +} +inline void Field::set_type_url(const char* value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Field.type_url) +} +inline void Field::set_type_url(const char* value, size_t size) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.type_url) +} +inline ::std::string* Field::mutable_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.type_url) + return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Field::release_type_url() { + // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url) + + return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_allocated_type_url(::std::string* type_url) { + if (type_url != NULL) { + + } else { + + } + type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url) +} + +// optional int32 oneof_index = 7; +inline void Field::clear_oneof_index() { + oneof_index_ = 0; +} +inline ::google::protobuf::int32 Field::oneof_index() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.oneof_index) + return oneof_index_; +} +inline void Field::set_oneof_index(::google::protobuf::int32 value) { + + oneof_index_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.oneof_index) +} + +// optional bool packed = 8; +inline void Field::clear_packed() { + packed_ = false; +} +inline bool Field::packed() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.packed) + return packed_; +} +inline void Field::set_packed(bool value) { + + packed_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.packed) +} + +// repeated .google.protobuf.Option options = 9; +inline int Field::options_size() const { + return options_.size(); +} +inline void Field::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Field::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Field::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Field::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Field.options) + return options_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Field::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options) + return &options_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Field::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Field.options) + return options_; +} + +// optional string json_name = 10; +inline void Field::clear_json_name() { + json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Field::json_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name) + return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_json_name(const ::std::string& value) { + + json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name) +} +inline void Field::set_json_name(const char* value) { + + json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name) +} +inline void Field::set_json_name(const char* value, size_t size) { + + json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name) +} +inline ::std::string* Field::mutable_json_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name) + return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Field::release_json_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name) + + return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_allocated_json_name(::std::string* json_name) { + if (json_name != NULL) { + + } else { + + } + json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name) +} + +// optional string default_value = 11; +inline void Field::clear_default_value() { + default_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Field::default_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value) + return default_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_default_value(const ::std::string& value) { + + default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value) +} +inline void Field::set_default_value(const char* value) { + + default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Field.default_value) +} +inline void Field::set_default_value(const char* value, size_t size) { + + default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.default_value) +} +inline ::std::string* Field::mutable_default_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.default_value) + return default_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Field::release_default_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value) + + return default_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_allocated_default_value(::std::string* default_value) { + if (default_value != NULL) { + + } else { + + } + default_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), default_value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value) +} + +// ------------------------------------------------------------------- + +// Enum + +// optional string name = 1; +inline void Enum::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Enum::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Enum::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Enum.name) +} +inline void Enum::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Enum.name) +} +inline void Enum::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Enum.name) +} +inline ::std::string* Enum::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Enum::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Enum.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Enum::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.name) +} + +// repeated .google.protobuf.EnumValue enumvalue = 2; +inline int Enum::enumvalue_size() const { + return enumvalue_.size(); +} +inline void Enum::clear_enumvalue() { + enumvalue_.Clear(); +} +inline const ::google::protobuf::EnumValue& Enum::enumvalue(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.enumvalue) + return enumvalue_.Get(index); +} +inline ::google::protobuf::EnumValue* Enum::mutable_enumvalue(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue) + return enumvalue_.Mutable(index); +} +inline ::google::protobuf::EnumValue* Enum::add_enumvalue() { + // @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue) + return enumvalue_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >* +Enum::mutable_enumvalue() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.enumvalue) + return &enumvalue_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >& +Enum::enumvalue() const { + // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue) + return enumvalue_; +} + +// repeated .google.protobuf.Option options = 3; +inline int Enum::options_size() const { + return options_.size(); +} +inline void Enum::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Enum::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Enum::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Enum::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Enum.options) + return options_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Enum::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.options) + return &options_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Enum::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Enum.options) + return options_; +} + +// optional .google.protobuf.SourceContext source_context = 4; +inline bool Enum::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +inline void Enum::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} +inline const ::google::protobuf::SourceContext& Enum::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} +inline ::google::protobuf::SourceContext* Enum::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context) + return source_context_; +} +inline ::google::protobuf::SourceContext* Enum::release_source_context() { + // @@protoc_insertion_point(field_release:google.protobuf.Enum.source_context) + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} +inline void Enum::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context) +} + +// optional .google.protobuf.Syntax syntax = 5; +inline void Enum::clear_syntax() { + syntax_ = 0; +} +inline ::google::protobuf::Syntax Enum::syntax() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax) + return static_cast< ::google::protobuf::Syntax >(syntax_); +} +inline void Enum::set_syntax(::google::protobuf::Syntax value) { + + syntax_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax) +} + +// ------------------------------------------------------------------- + +// EnumValue + +// optional string name = 1; +inline void EnumValue::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& EnumValue::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void EnumValue::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name) +} +inline void EnumValue::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValue.name) +} +inline void EnumValue::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValue.name) +} +inline ::std::string* EnumValue::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* EnumValue::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void EnumValue::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name) +} + +// optional int32 number = 2; +inline void EnumValue::clear_number() { + number_ = 0; +} +inline ::google::protobuf::int32 EnumValue::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.number) + return number_; +} +inline void EnumValue::set_number(::google::protobuf::int32 value) { + + number_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.number) +} + +// repeated .google.protobuf.Option options = 3; +inline int EnumValue::options_size() const { + return options_.size(); +} +inline void EnumValue::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& EnumValue::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* EnumValue::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* EnumValue::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options) + return options_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +EnumValue::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValue.options) + return &options_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +EnumValue::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options) + return options_; +} + +// ------------------------------------------------------------------- + +// Option + +// optional string name = 1; +inline void Option::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Option::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Option.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Option::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Option.name) +} +inline void Option::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Option.name) +} +inline void Option::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Option.name) +} +inline ::std::string* Option::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Option.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Option::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.Option.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Option::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name) +} + +// optional .google.protobuf.Any value = 2; +inline bool Option::has_value() const { + return !_is_default_instance_ && value_ != NULL; +} +inline void Option::clear_value() { + if (GetArenaNoVirtual() == NULL && value_ != NULL) delete value_; + value_ = NULL; +} +inline const ::google::protobuf::Any& Option::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Option.value) + return value_ != NULL ? *value_ : *default_instance_->value_; +} +inline ::google::protobuf::Any* Option::mutable_value() { + + if (value_ == NULL) { + value_ = new ::google::protobuf::Any; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value) + return value_; +} +inline ::google::protobuf::Any* Option::release_value() { + // @@protoc_insertion_point(field_release:google.protobuf.Option.value) + + ::google::protobuf::Any* temp = value_; + value_ = NULL; + return temp; +} +inline void Option::set_allocated_value(::google::protobuf::Any* value) { + delete value_; + value_ = value; + if (value) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::google::protobuf::Field_Kind> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Field_Kind>() { + return ::google::protobuf::Field_Kind_descriptor(); +} +template <> struct is_proto_enum< ::google::protobuf::Field_Cardinality> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Field_Cardinality>() { + return ::google::protobuf::Field_Cardinality_descriptor(); +} +template <> struct is_proto_enum< ::google::protobuf::Syntax> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Syntax>() { + return ::google::protobuf::Syntax_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/type.proto b/thirdparty/linux/include/google/protobuf/type.proto new file mode 100644 index 0000000..1c9cf53 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/type.proto @@ -0,0 +1,180 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/any.proto"; +import "google/protobuf/source_context.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TypeProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; + +// A protocol buffer message type. +message Type { + // The fully qualified message name. + string name = 1; + // The list of fields. + repeated Field fields = 2; + // The list of types appearing in `oneof` definitions in this type. + repeated string oneofs = 3; + // The protocol buffer options. + repeated Option options = 4; + // The source context. + SourceContext source_context = 5; + // The source syntax. + Syntax syntax = 6; +} + +// A single field of a message type. +message Field { + // Basic field types. + enum Kind { + // Field type unknown. + TYPE_UNKNOWN = 0; + // Field type double. + TYPE_DOUBLE = 1; + // Field type float. + TYPE_FLOAT = 2; + // Field type int64. + TYPE_INT64 = 3; + // Field type uint64. + TYPE_UINT64 = 4; + // Field type int32. + TYPE_INT32 = 5; + // Field type fixed64. + TYPE_FIXED64 = 6; + // Field type fixed32. + TYPE_FIXED32 = 7; + // Field type bool. + TYPE_BOOL = 8; + // Field type string. + TYPE_STRING = 9; + // Field type group. Proto2 syntax only, and deprecated. + TYPE_GROUP = 10; + // Field type message. + TYPE_MESSAGE = 11; + // Field type bytes. + TYPE_BYTES = 12; + // Field type uint32. + TYPE_UINT32 = 13; + // Field type enum. + TYPE_ENUM = 14; + // Field type sfixed32. + TYPE_SFIXED32 = 15; + // Field type sfixed64. + TYPE_SFIXED64 = 16; + // Field type sint32. + TYPE_SINT32 = 17; + // Field type sint64. + TYPE_SINT64 = 18; + }; + + // Whether a field is optional, required, or repeated. + enum Cardinality { + // For fields with unknown cardinality. + CARDINALITY_UNKNOWN = 0; + // For optional fields. + CARDINALITY_OPTIONAL = 1; + // For required fields. Proto2 syntax only. + CARDINALITY_REQUIRED = 2; + // For repeated fields. + CARDINALITY_REPEATED = 3; + }; + + // The field type. + Kind kind = 1; + // The field cardinality. + Cardinality cardinality = 2; + // The field number. + int32 number = 3; + // The field name. + string name = 4; + // The field type URL, without the scheme, for message or enumeration + // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + string type_url = 6; + // The index of the field type in `Type.oneofs`, for message or enumeration + // types. The first type has index 1; zero means the type is not in the list. + int32 oneof_index = 7; + // Whether to use alternative packed wire representation. + bool packed = 8; + // The protocol buffer options. + repeated Option options = 9; + // The field JSON name. + string json_name = 10; + // The string value of the default value of this field. Proto2 syntax only. + string default_value = 11; +} + +// Enum type definition. +message Enum { + // Enum type name. + string name = 1; + // Enum value definitions. + repeated EnumValue enumvalue = 2; + // Protocol buffer options. + repeated Option options = 3; + // The source context. + SourceContext source_context = 4; + // The source syntax. + Syntax syntax = 5; +} + +// Enum value definition. +message EnumValue { + // Enum value name. + string name = 1; + // Enum value number. + int32 number = 2; + // Protocol buffer options. + repeated Option options = 3; +} + +// A protocol buffer option, which can be attached to a message, field, +// enumeration, etc. +message Option { + // The option's name. For example, `"java_package"`. + string name = 1; + // The option's value. For example, `"com.google.protobuf"`. + Any value = 2; +} + +// The syntax in which a protocol buffer element is defined. +enum Syntax { + // Syntax `proto2`. + SYNTAX_PROTO2 = 0; + // Syntax `proto3`. + SYNTAX_PROTO3 = 1; +} diff --git a/thirdparty/linux/include/google/protobuf/unknown_field_set.h b/thirdparty/linux/include/google/protobuf/unknown_field_set.h new file mode 100644 index 0000000..aa75291 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/unknown_field_set.h @@ -0,0 +1,346 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Contains classes used to keep track of unrecognized fields seen while +// parsing a protocol message. + +#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ +#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ + +#include +#include +#include +#include +#include + +namespace google { +namespace protobuf { + namespace io { + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h + class ZeroCopyInputStream; // zero_copy_stream.h + } + namespace internal { + class WireFormat; // wire_format.h + class MessageSetFieldSkipperUsingCord; + // extension_set_heavy.cc + } + +class Message; // message.h +class UnknownField; // below + +// An UnknownFieldSet contains fields that were encountered while parsing a +// message but were not defined by its type. Keeping track of these can be +// useful, especially in that they may be written if the message is serialized +// again without being cleared in between. This means that software which +// simply receives messages and forwards them to other servers does not need +// to be updated every time a new field is added to the message definition. +// +// To get the UnknownFieldSet attached to any message, call +// Reflection::GetUnknownFields(). +// +// This class is necessarily tied to the protocol buffer wire format, unlike +// the Reflection interface which is independent of any serialization scheme. +class LIBPROTOBUF_EXPORT UnknownFieldSet { + public: + UnknownFieldSet(); + ~UnknownFieldSet(); + + // Remove all fields. + inline void Clear(); + + // Remove all fields and deallocate internal data objects + void ClearAndFreeMemory(); + + // Is this set empty? + inline bool empty() const; + + // Merge the contents of some other UnknownFieldSet with this one. + void MergeFrom(const UnknownFieldSet& other); + + // Similar to above, but this function will destroy the contents of other. + void MergeFromAndDestroy(UnknownFieldSet* other); + + // Swaps the contents of some other UnknownFieldSet with this one. + inline void Swap(UnknownFieldSet* x); + + // Computes (an estimate of) the total number of bytes currently used for + // storing the unknown fields in memory. Does NOT include + // sizeof(*this) in the calculation. + int SpaceUsedExcludingSelf() const; + + // Version of SpaceUsed() including sizeof(*this). + int SpaceUsed() const; + + // Returns the number of fields present in the UnknownFieldSet. + inline int field_count() const; + // Get a field in the set, where 0 <= index < field_count(). The fields + // appear in the order in which they were added. + inline const UnknownField& field(int index) const; + // Get a mutable pointer to a field in the set, where + // 0 <= index < field_count(). The fields appear in the order in which + // they were added. + inline UnknownField* mutable_field(int index); + + // Adding fields --------------------------------------------------- + + void AddVarint(int number, uint64 value); + void AddFixed32(int number, uint32 value); + void AddFixed64(int number, uint64 value); + void AddLengthDelimited(int number, const string& value); + string* AddLengthDelimited(int number); + UnknownFieldSet* AddGroup(int number); + + // Adds an unknown field from another set. + void AddField(const UnknownField& field); + + // Delete fields with indices in the range [start .. start+num-1]. + // Caution: implementation moves all fields with indices [start+num .. ]. + void DeleteSubrange(int start, int num); + + // Delete all fields with a specific field number. The order of left fields + // is preserved. + // Caution: implementation moves all fields after the first deleted field. + void DeleteByNumber(int number); + + // Parsing helpers ------------------------------------------------- + // These work exactly like the similarly-named methods of Message. + + bool MergeFromCodedStream(io::CodedInputStream* input); + bool ParseFromCodedStream(io::CodedInputStream* input); + bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); + bool ParseFromArray(const void* data, int size); + inline bool ParseFromString(const string& data) { + return ParseFromArray(data.data(), static_cast(data.size())); + } + + static const UnknownFieldSet* default_instance(); + private: + // For InternalMergeFrom + friend class UnknownField; + // Merges from other UnknownFieldSet. This method assumes, that this object + // is newly created and has fields_ == NULL; + void InternalMergeFrom(const UnknownFieldSet& other); + void ClearFallback(); + + // fields_ is either NULL, or a pointer to a vector that is *non-empty*. We + // never hold the empty vector because we want the 'do we have any unknown + // fields' check to be fast, and avoid a cache miss: the UFS instance gets + // embedded in the message object, so 'fields_ != NULL' tests a member + // variable hot in the cache, without the need to go touch a vector somewhere + // else in memory. + std::vector* fields_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet); +}; + +// Represents one field in an UnknownFieldSet. +class LIBPROTOBUF_EXPORT UnknownField { + public: + enum Type { + TYPE_VARINT, + TYPE_FIXED32, + TYPE_FIXED64, + TYPE_LENGTH_DELIMITED, + TYPE_GROUP + }; + + // The field's tag number, as seen on the wire. + inline int number() const; + + // The field type. + inline Type type() const; + + // Accessors ------------------------------------------------------- + // Each method works only for UnknownFields of the corresponding type. + + inline uint64 varint() const; + inline uint32 fixed32() const; + inline uint64 fixed64() const; + inline const string& length_delimited() const; + inline const UnknownFieldSet& group() const; + + inline void set_varint(uint64 value); + inline void set_fixed32(uint32 value); + inline void set_fixed64(uint64 value); + inline void set_length_delimited(const string& value); + inline string* mutable_length_delimited(); + inline UnknownFieldSet* mutable_group(); + + // Serialization API. + // These methods can take advantage of the underlying implementation and may + // archieve a better performance than using getters to retrieve the data and + // do the serialization yourself. + void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const; + uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const; + + inline int GetLengthDelimitedSize() const; + + private: + friend class UnknownFieldSet; + + // If this UnknownField contains a pointer, delete it. + void Delete(); + + // Reset all the underlying pointers to NULL. A special function to be only + // used while merging from a temporary UFS. + void Reset(); + + // Make a deep copy of any pointers in this UnknownField. + void DeepCopy(const UnknownField& other); + + // Set the wire type of this UnknownField. Should only be used when this + // UnknownField is being created. + inline void SetType(Type type); + + union LengthDelimited { + string* string_value_; + }; + + uint32 number_; + uint32 type_; + union { + uint64 varint_; + uint32 fixed32_; + uint64 fixed64_; + mutable union LengthDelimited length_delimited_; + UnknownFieldSet* group_; + }; +}; + +// =================================================================== +// inline implementations + +inline UnknownFieldSet::UnknownFieldSet() : fields_(NULL) {} + +inline UnknownFieldSet::~UnknownFieldSet() { Clear(); } + +inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); } + +inline void UnknownFieldSet::Clear() { + if (fields_ != NULL) { + ClearFallback(); + } +} + +inline bool UnknownFieldSet::empty() const { + // Invariant: fields_ is never empty if present. + return !fields_; +} + +inline void UnknownFieldSet::Swap(UnknownFieldSet* x) { + std::swap(fields_, x->fields_); +} + +inline int UnknownFieldSet::field_count() const { + return fields_ ? static_cast(fields_->size()) : 0; +} +inline const UnknownField& UnknownFieldSet::field(int index) const { + GOOGLE_DCHECK(fields_ != NULL); + return (*fields_)[index]; +} +inline UnknownField* UnknownFieldSet::mutable_field(int index) { + return &(*fields_)[index]; +} + +inline void UnknownFieldSet::AddLengthDelimited( + int number, const string& value) { + AddLengthDelimited(number)->assign(value); +} + + +inline int UnknownField::number() const { return number_; } +inline UnknownField::Type UnknownField::type() const { + return static_cast(type_); +} + +inline uint64 UnknownField::varint() const { + assert(type() == TYPE_VARINT); + return varint_; +} +inline uint32 UnknownField::fixed32() const { + assert(type() == TYPE_FIXED32); + return fixed32_; +} +inline uint64 UnknownField::fixed64() const { + assert(type() == TYPE_FIXED64); + return fixed64_; +} +inline const string& UnknownField::length_delimited() const { + assert(type() == TYPE_LENGTH_DELIMITED); + return *length_delimited_.string_value_; +} +inline const UnknownFieldSet& UnknownField::group() const { + assert(type() == TYPE_GROUP); + return *group_; +} + +inline void UnknownField::set_varint(uint64 value) { + assert(type() == TYPE_VARINT); + varint_ = value; +} +inline void UnknownField::set_fixed32(uint32 value) { + assert(type() == TYPE_FIXED32); + fixed32_ = value; +} +inline void UnknownField::set_fixed64(uint64 value) { + assert(type() == TYPE_FIXED64); + fixed64_ = value; +} +inline void UnknownField::set_length_delimited(const string& value) { + assert(type() == TYPE_LENGTH_DELIMITED); + length_delimited_.string_value_->assign(value); +} +inline string* UnknownField::mutable_length_delimited() { + assert(type() == TYPE_LENGTH_DELIMITED); + return length_delimited_.string_value_; +} +inline UnknownFieldSet* UnknownField::mutable_group() { + assert(type() == TYPE_GROUP); + return group_; +} + +inline int UnknownField::GetLengthDelimitedSize() const { + GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); + return static_cast(length_delimited_.string_value_->size()); +} + +inline void UnknownField::SetType(Type type) { + type_ = type; +} + + +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ diff --git a/thirdparty/linux/include/google/protobuf/util/field_comparator.h b/thirdparty/linux/include/google/protobuf/util/field_comparator.h new file mode 100644 index 0000000..1b4d65b --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/util/field_comparator.h @@ -0,0 +1,259 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: ksroka@google.com (Krzysztof Sroka) + +#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__ +#define GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__ + +#include +#include + +#include + +namespace google { +namespace protobuf { + +class Message; +class EnumValueDescriptor; +class FieldDescriptor; + +namespace util { + +class FieldContext; + +// Base class specifying the interface for comparing protocol buffer fields. +// Regular users should consider using or subclassing DefaultFieldComparator +// rather than this interface. +// Currently, this does not support comparing unknown fields. +class LIBPROTOBUF_EXPORT FieldComparator { + public: + FieldComparator(); + virtual ~FieldComparator(); + + enum ComparisonResult { + SAME, // Compared fields are equal. In case of comparing submessages, + // user should not recursively compare their contents. + DIFFERENT, // Compared fields are different. In case of comparing + // submessages, user should not recursively compare their + // contents. + RECURSE, // Compared submessages need to be compared recursively. + // FieldComparator does not specify the semantics of recursive + // comparison. This value should not be returned for simple + // values. + }; + + // Compares the values of a field in two protocol buffer messages. + // Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE + // for submessages. Returning RECURSE for fields not being submessages is + // illegal. + // In case the given FieldDescriptor points to a repeated field, the indices + // need to be valid. Otherwise they should be ignored. + // + // FieldContext contains information about the specific instances of the + // fields being compared, versus FieldDescriptor which only contains general + // type information about the fields. + virtual ComparisonResult Compare( + const google::protobuf::Message& message_1, + const google::protobuf::Message& message_2, + const google::protobuf::FieldDescriptor* field, + int index_1, int index_2, + const google::protobuf::util::FieldContext* field_context) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldComparator); +}; + +// Basic implementation of FieldComparator. Supports three modes of floating +// point value comparison: exact, approximate using MathUtil::AlmostEqual +// method, and arbitrarily precise using MathUtil::WithinFractionOrMargin. +class LIBPROTOBUF_EXPORT DefaultFieldComparator : public FieldComparator { + public: + enum FloatComparison { + EXACT, // Floats and doubles are compared exactly. + APPROXIMATE, // Floats and doubles are compared using the + // MathUtil::AlmostEqual method or + // MathUtil::WithinFractionOrMargin method. + // TODO(ksroka): Introduce third value to differenciate uses of AlmostEqual + // and WithinFractionOrMargin. + }; + + // Creates new comparator with float comparison set to EXACT. + DefaultFieldComparator(); + + virtual ~DefaultFieldComparator(); + + virtual ComparisonResult Compare( + const google::protobuf::Message& message_1, + const google::protobuf::Message& message_2, + const google::protobuf::FieldDescriptor* field, + int index_1, int index_2, + const google::protobuf::util::FieldContext* field_context); + + void set_float_comparison(FloatComparison float_comparison) { + float_comparison_ = float_comparison; + } + + FloatComparison float_comparison() const { + return float_comparison_; + } + + // Set whether the FieldComparator shall treat floats or doubles that are both + // NaN as equal (treat_nan_as_equal = true) or as different + // (treat_nan_as_equal = false). Default is treating NaNs always as different. + void set_treat_nan_as_equal(bool treat_nan_as_equal) { + treat_nan_as_equal_ = treat_nan_as_equal; + } + + bool treat_nan_as_equal() const { + return treat_nan_as_equal_; + } + + // Sets the fraction and margin for the float comparison of a given field. + // Uses MathUtil::WithinFractionOrMargin to compare the values. + // + // REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or + // field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT + // REQUIRES: float_comparison_ == APPROXIMATE + void SetFractionAndMargin(const FieldDescriptor* field, double fraction, + double margin); + + // Sets the fraction and margin for the float comparison of all float and + // double fields, unless a field has been given a specific setting via + // SetFractionAndMargin() above. + // Uses MathUtil::WithinFractionOrMargin to compare the values. + // + // REQUIRES: float_comparison_ == APPROXIMATE + void SetDefaultFractionAndMargin(double fraction, double margin); + + private: + // Defines the tolerance for floating point comparison (fraction and margin). + struct Tolerance { + double fraction; + double margin; + Tolerance() + : fraction(0.0), + margin(0.0) {} + Tolerance(double f, double m) + : fraction(f), + margin(m) {} + }; + + // Defines the map to store the tolerances for floating point comparison. + typedef map ToleranceMap; + + // The following methods get executed when CompareFields is called for the + // basic types (instead of submessages). They return true on success. One + // can use ResultFromBoolean() to convert that boolean to a ComparisonResult + // value. + bool CompareBool(const google::protobuf::FieldDescriptor& field, + bool value_1, bool value_2) { + return value_1 == value_2; + } + + // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and + // CompareFloat. + bool CompareDouble(const google::protobuf::FieldDescriptor& field, + double value_1, double value_2); + + bool CompareEnum(const google::protobuf::FieldDescriptor& field, + const EnumValueDescriptor* value_1, + const EnumValueDescriptor* value_2); + + // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and + // CompareFloat. + bool CompareFloat(const google::protobuf::FieldDescriptor& field, + float value_1, float value_2); + + bool CompareInt32(const google::protobuf::FieldDescriptor& field, + int32 value_1, int32 value_2) { + return value_1 == value_2; + } + + bool CompareInt64(const google::protobuf::FieldDescriptor& field, + int64 value_1, int64 value_2) { + return value_1 == value_2; + } + + bool CompareString(const google::protobuf::FieldDescriptor& field, + const string& value_1, const string& value_2) { + return value_1 == value_2; + } + + bool CompareUInt32(const google::protobuf::FieldDescriptor& field, + uint32 value_1, uint32 value_2) { + return value_1 == value_2; + } + + bool CompareUInt64(const google::protobuf::FieldDescriptor& field, + uint64 value_1, uint64 value_2) { + return value_1 == value_2; + } + + // This function is used by CompareDouble and CompareFloat to avoid code + // duplication. There are no checks done against types of the values passed, + // but it's likely to fail if passed non-numeric arguments. + template + bool CompareDoubleOrFloat(const google::protobuf::FieldDescriptor& field, + T value_1, T value_2); + + // Returns FieldComparator::SAME if boolean_result is true and + // FieldComparator::DIFFERENT otherwise. + ComparisonResult ResultFromBoolean(bool boolean_result) const; + + FloatComparison float_comparison_; + + // If true, floats and doubles that are both NaN are considered to be + // equal. Otherwise, two floats or doubles that are NaN are considered to be + // different. + bool treat_nan_as_equal_; + + // True iff default_tolerance_ has been explicitly set. + // + // If false, then the default tolerance for flaots and doubles is that which + // is used by MathUtil::AlmostEquals(). + bool has_default_tolerance_; + + // Default float/double tolerance. Only meaningful if + // has_default_tolerance_ == true. + Tolerance default_tolerance_; + + // Field-specific float/double tolerances, which override any default for + // those particular fields. + ToleranceMap map_tolerance_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DefaultFieldComparator); +}; + +} // namespace util +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__ diff --git a/thirdparty/linux/include/google/protobuf/util/field_mask_util.h b/thirdparty/linux/include/google/protobuf/util/field_mask_util.h new file mode 100644 index 0000000..e79b65e --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/util/field_mask_util.h @@ -0,0 +1,193 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__ + +#include + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace util { + +class LIBPROTOBUF_EXPORT FieldMaskUtil { + typedef google::protobuf::FieldMask FieldMask; + + public: + // Converts FieldMask to/from string, formatted by separating each path + // with a comma (e.g., "foo_bar,baz.quz"). + static string ToString(const FieldMask& mask); + static void FromString(StringPiece str, FieldMask* out); + + // Converts FieldMask to/from string, formatted according to proto3 JSON + // spec for FieldMask (e.g., "fooBar,baz.quz"). If the field name is not + // style conforming (i.e., not snake_case when converted to string, or not + // camelCase when converted from string), the conversion will fail. + static bool ToJsonString(const FieldMask& mask, string* out); + static bool FromJsonString(StringPiece str, FieldMask* out); + + // Checks whether the given path is valid for type T. + template + static bool IsValidPath(StringPiece path) { + return InternalIsValidPath(T::descriptor(), path); + } + + // Checks whether the given FieldMask is valid for type T. + template + static bool IsValidFieldMask(const FieldMask& mask) { + for (int i = 0; i < mask.paths_size(); ++i) { + if (!InternalIsValidPath(T::descriptor(), mask.paths(i))) return false; + } + return true; + } + + // Adds a path to FieldMask after checking whether the given path is valid. + // This method check-fails if the path is not a valid path for type T. + template + static void AddPathToFieldMask(StringPiece path, FieldMask* mask) { + GOOGLE_CHECK(IsValidPath(path)); + mask->add_paths(path); + } + + // Creates a FieldMask with all fields of type T. This FieldMask only + // contains fields of T but not any sub-message fields. + template + static void GetFieldMaskForAllFields(FieldMask* out) { + InternalGetFieldMaskForAllFields(T::descriptor(), out); + } + + // Converts a FieldMask to the canonical form. It will: + // 1. Remove paths that are covered by another path. For example, + // "foo.bar" is covered by "foo" and will be removed if "foo" + // is also in the FieldMask. + // 2. Sort all paths in alphabetical order. + static void ToCanonicalForm(const FieldMask& mask, FieldMask* out); + + // Creates an union of two FieldMasks. + static void Union(const FieldMask& mask1, const FieldMask& mask2, + FieldMask* out); + + // Creates an intersection of two FieldMasks. + static void Intersect(const FieldMask& mask1, const FieldMask& mask2, + FieldMask* out); + + // Returns true if path is covered by the given FieldMask. Note that path + // "foo.bar" covers all paths like "foo.bar.baz", "foo.bar.quz.x", etc. + static bool IsPathInFieldMask(StringPiece path, const FieldMask& mask); + + class MergeOptions; + // Merges fields specified in a FieldMask into another message. See the + // comments in MergeOptions regarding compatibility with + // google/protobuf/field_mask.proto + static void MergeMessageTo(const Message& source, const FieldMask& mask, + const MergeOptions& options, Message* destination); + + // Removes from 'message' any field that is not represented in the given + // FieldMask. If the FieldMask is empty, does nothing. + static void TrimMessage(const FieldMask& mask, Message* message); + + private: + friend class SnakeCaseCamelCaseTest; + // Converts a field name from snake_case to camelCase: + // 1. Every character after "_" will be converted to uppercase. + // 2. All "_"s are removed. + // The conversion will fail if: + // 1. The field name contains uppercase letters. + // 2. Any character after a "_" is not a lowercase letter. + // If the conversion succeeds, it's guaranteed that the resulted + // camelCase name will yield the original snake_case name when + // converted using CamelCaseToSnakeCase(). + // + // Note that the input can contain characters not allowed in C identifiers. + // For example, "foo_bar,baz_quz" will be converted to "fooBar,bazQuz" + // successfully. + static bool SnakeCaseToCamelCase(StringPiece input, string* output); + // Converts a field name from camelCase to snake_case: + // 1. Every uppercase letter is converted to lowercase with a additional + // preceding "-". + // The conversion will fail if: + // 1. The field name contains "_"s. + // If the conversion succeeds, it's guaranteed that the resulted + // snake_case name will yield the original camelCase name when + // converted using SnakeCaseToCamelCase(). + // + // Note that the input can contain characters not allowed in C identifiers. + // For example, "fooBar,bazQuz" will be converted to "foo_bar,baz_quz" + // successfully. + static bool CamelCaseToSnakeCase(StringPiece input, string* output); + + static bool InternalIsValidPath(const Descriptor* descriptor, + StringPiece path); + + static void InternalGetFieldMaskForAllFields(const Descriptor* descriptor, + FieldMask* out); +}; + +// Note that for compatibility with the defined behaviour for FieldMask in +// google/protobuf/field_mask.proto, set replace_message_fields and +// replace_repeated_fields to 'true'. The default options are not compatible +// with google/protobuf/field_mask.proto. +class LIBPROTOBUF_EXPORT FieldMaskUtil::MergeOptions { + public: + MergeOptions() + : replace_message_fields_(false), replace_repeated_fields_(false) {} + // When merging message fields, the default behavior is to merge the + // content of two message fields together. If you instead want to use + // the field from the source message to replace the corresponding field + // in the destination message, set this flag to true. When this flag is set, + // specified submessage fields that are missing in source will be cleared in + // destination. + void set_replace_message_fields(bool value) { + replace_message_fields_ = value; + } + bool replace_message_fields() const { return replace_message_fields_; } + // The default merging behavior will append entries from the source + // repeated field to the destination repeated field. If you only want + // to keep the entries from the source repeated field, set this flag + // to true. + void set_replace_repeated_fields(bool value) { + replace_repeated_fields_ = value; + } + bool replace_repeated_fields() const { return replace_repeated_fields_; } + + private: + bool replace_message_fields_; + bool replace_repeated_fields_; +}; + +} // namespace util +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__ diff --git a/thirdparty/linux/include/google/protobuf/util/json_util.h b/thirdparty/linux/include/google/protobuf/util/json_util.h new file mode 100644 index 0000000..6d3cee5 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/util/json_util.h @@ -0,0 +1,190 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Utility functions to convert between protobuf binary format and proto3 JSON +// format. +#ifndef GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace io { +class ZeroCopyInputStream; +class ZeroCopyOutputStream; +} // namespace io +namespace util { + +struct JsonParseOptions { + // Whether to ignore unknown JSON fields during parsing + bool ignore_unknown_fields; + + JsonParseOptions() : ignore_unknown_fields(false) {} +}; + +struct JsonPrintOptions { + // Whether to add spaces, line breaks and indentation to make the JSON output + // easy to read. + bool add_whitespace; + // Whether to always print primitive fields. By default primitive fields with + // default values will be omitted in JSON joutput. For example, an int32 field + // set to 0 will be omitted. Set this flag to true will override the default + // behavior and print primitive fields regardless of their values. + bool always_print_primitive_fields; + + JsonPrintOptions() : add_whitespace(false), + always_print_primitive_fields(false) { + } +}; + +// DEPRECATED. Use JsonPrintOptions instead. +typedef JsonPrintOptions JsonOptions; + +// Converts from protobuf message to JSON. This is a simple wrapper of +// BinaryToJsonString(). It will use the DescriptorPool of the passed-in +// message to resolve Any types. +LIBPROTOBUF_EXPORT util::Status MessageToJsonString(const Message& message, + string* output, + const JsonOptions& options); + +inline util::Status MessageToJsonString(const Message& message, + string* output) { + return MessageToJsonString(message, output, JsonOptions()); +} + +// Converts from JSON to protobuf message. This is a simple wrapper of +// JsonStringToBinary(). It will use the DescriptorPool of the passed-in +// message to resolve Any types. +LIBPROTOBUF_EXPORT util::Status JsonStringToMessage(const string& input, + Message* message, + const JsonParseOptions& options); + +inline util::Status JsonStringToMessage(const string& input, + Message* message) { + return JsonStringToMessage(input, message, JsonParseOptions()); +} + +// Converts protobuf binary data to JSON. +// The conversion will fail if: +// 1. TypeResolver fails to resolve a type. +// 2. input is not valid protobuf wire format, or conflicts with the type +// information returned by TypeResolver. +// Note that unknown fields will be discarded silently. +LIBPROTOBUF_EXPORT util::Status BinaryToJsonStream( + TypeResolver* resolver, + const string& type_url, + io::ZeroCopyInputStream* binary_input, + io::ZeroCopyOutputStream* json_output, + const JsonPrintOptions& options); + +inline util::Status BinaryToJsonStream( + TypeResolver* resolver, const string& type_url, + io::ZeroCopyInputStream* binary_input, + io::ZeroCopyOutputStream* json_output) { + return BinaryToJsonStream(resolver, type_url, binary_input, json_output, + JsonPrintOptions()); +} + +LIBPROTOBUF_EXPORT util::Status BinaryToJsonString( + TypeResolver* resolver, + const string& type_url, + const string& binary_input, + string* json_output, + const JsonPrintOptions& options); + +inline util::Status BinaryToJsonString(TypeResolver* resolver, + const string& type_url, + const string& binary_input, + string* json_output) { + return BinaryToJsonString(resolver, type_url, binary_input, json_output, + JsonPrintOptions()); +} + +// Converts JSON data to protobuf binary format. +// The conversion will fail if: +// 1. TypeResolver fails to resolve a type. +// 2. input is not valid JSON format, or conflicts with the type +// information returned by TypeResolver. +LIBPROTOBUF_EXPORT util::Status JsonToBinaryStream( + TypeResolver* resolver, + const string& type_url, + io::ZeroCopyInputStream* json_input, + io::ZeroCopyOutputStream* binary_output, + const JsonParseOptions& options); + +inline util::Status JsonToBinaryStream( + TypeResolver* resolver, + const string& type_url, + io::ZeroCopyInputStream* json_input, + io::ZeroCopyOutputStream* binary_output) { + return JsonToBinaryStream(resolver, type_url, json_input, binary_output, + JsonParseOptions()); +} + +LIBPROTOBUF_EXPORT util::Status JsonToBinaryString( + TypeResolver* resolver, + const string& type_url, + const string& json_input, + string* binary_output, + const JsonParseOptions& options); + +inline util::Status JsonToBinaryString( + TypeResolver* resolver, + const string& type_url, + const string& json_input, + string* binary_output) { + return JsonToBinaryString(resolver, type_url, json_input, binary_output, + JsonParseOptions()); +} + +namespace internal { +// Internal helper class. Put in the header so we can write unit-tests for it. +class LIBPROTOBUF_EXPORT ZeroCopyStreamByteSink : public strings::ByteSink { + public: + explicit ZeroCopyStreamByteSink(io::ZeroCopyOutputStream* stream) + : stream_(stream) {} + + virtual void Append(const char* bytes, size_t len); + + private: + io::ZeroCopyOutputStream* stream_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyStreamByteSink); +}; +} // namespace internal + +} // namespace util +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__ diff --git a/thirdparty/linux/include/google/protobuf/util/message_differencer.h b/thirdparty/linux/include/google/protobuf/util/message_differencer.h new file mode 100644 index 0000000..654d1a6 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/util/message_differencer.h @@ -0,0 +1,849 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: jschorr@google.com (Joseph Schorr) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This file defines static methods and classes for comparing Protocol +// Messages. +// +// Aug. 2008: Added Unknown Fields Comparison for messages. +// Aug. 2009: Added different options to compare repeated fields. +// Apr. 2010: Moved field comparison to FieldComparator. + +#ifndef GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__ +#define GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__ + +#include +#include +#include +#include +#include // FieldDescriptor +#include // Message +#include +#include + +namespace google { +namespace protobuf { + +class DynamicMessageFactory; +class FieldDescriptor; + +namespace io { +class ZeroCopyOutputStream; +class Printer; +} + +namespace util { + +class FieldContext; // declared below MessageDifferencer + +// A basic differencer that can be used to determine +// the differences between two specified Protocol Messages. If any differences +// are found, the Compare method will return false, and any differencer reporter +// specified via ReportDifferencesTo will have its reporting methods called (see +// below for implementation of the report). Based off of the original +// ProtocolDifferencer implementation in //net/proto/protocol-differencer.h +// (Thanks Todd!). +// +// MessageDifferencer REQUIRES that compared messages be the same type, defined +// as messages that share the same descriptor. If not, the behavior of this +// class is undefined. +// +// People disagree on what MessageDifferencer should do when asked to compare +// messages with different descriptors. Some people think it should always +// return false. Others expect it to try to look for similar fields and +// compare them anyway -- especially if the descriptors happen to be identical. +// If we chose either of these behaviors, some set of people would find it +// surprising, and could end up writing code expecting the other behavior +// without realizing their error. Therefore, we forbid that usage. +// +// This class is implemented based on the proto2 reflection. The performance +// should be good enough for normal usages. However, for places where the +// performance is extremely sensitive, there are several alternatives: +// - Comparing serialized string +// Downside: false negatives (there are messages that are the same but their +// serialized strings are different). +// - Equals code generator by compiler plugin (net/proto2/contrib/equals_plugin) +// Downside: more generated code; maintenance overhead for the additional rule +// (must be in sync with the original proto_library). +// +// Note on handling of google.protobuf.Any: MessageDifferencer automatically +// unpacks Any::value into a Message and compares its individual fields. +// Messages encoded in a repeated Any cannot be compared using TreatAsMap. +// +// +// Note on thread-safety: MessageDifferencer is *not* thread-safe. You need to +// guard it with a lock to use the same MessageDifferencer instance from +// multiple threads. Note that it's fine to call static comparison methods +// (like MessageDifferencer::Equals) concurrently. +class LIBPROTOBUF_EXPORT MessageDifferencer { + public: + // Determines whether the supplied messages are equal. Equality is defined as + // all fields within the two messages being set to the same value. Primitive + // fields and strings are compared by value while embedded messages/groups + // are compared as if via a recursive call. Use IgnoreField() and Compare() + // if some fields should be ignored in the comparison. + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + static bool Equals(const Message& message1, const Message& message2); + + // Determines whether the supplied messages are equivalent. Equivalency is + // defined as all fields within the two messages having the same value. This + // differs from the Equals method above in that fields with default values + // are considered set to said value automatically. For details on how default + // values are defined for each field type, see http://shortn/_x2Gv6XFrWt. + // Also, Equivalent() ignores unknown fields. Use IgnoreField() and Compare() + // if some fields should be ignored in the comparison. + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + static bool Equivalent(const Message& message1, const Message& message2); + + // Determines whether the supplied messages are approximately equal. + // Approximate equality is defined as all fields within the two messages + // being approximately equal. Primitive (non-float) fields and strings are + // compared by value, floats are compared using MathUtil::AlmostEquals() and + // embedded messages/groups are compared as if via a recursive call. Use + // IgnoreField() and Compare() if some fields should be ignored in the + // comparison. + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + static bool ApproximatelyEquals(const Message& message1, + const Message& message2); + + // Determines whether the supplied messages are approximately equivalent. + // Approximate equivalency is defined as all fields within the two messages + // being approximately equivalent. As in + // MessageDifferencer::ApproximatelyEquals, primitive (non-float) fields and + // strings are compared by value, floats are compared using + // MathUtil::AlmostEquals() and embedded messages/groups are compared as if + // via a recursive call. However, fields with default values are considered + // set to said value, as per MessageDiffencer::Equivalent. Use IgnoreField() + // and Compare() if some fields should be ignored in the comparison. + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + static bool ApproximatelyEquivalent(const Message& message1, + const Message& message2); + + // Identifies an individual field in a message instance. Used for field_path, + // below. + struct SpecificField { + // For known fields, "field" is filled in and "unknown_field_number" is -1. + // For unknown fields, "field" is NULL, "unknown_field_number" is the field + // number, and "unknown_field_type" is its type. + const FieldDescriptor* field; + int unknown_field_number; + UnknownField::Type unknown_field_type; + + // If this a repeated field, "index" is the index within it. For unknown + // fields, this is the index of the field among all unknown fields of the + // same field number and type. + int index; + + // If "field" is a repeated field which is being treated as a map or + // a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates + // the index the position to which the element has moved. This only + // applies to ReportMoved() and (in the case of TreatAsMap()) + // ReportModified(). In all other cases, "new_index" will have the same + // value as "index". + int new_index; + + // For unknown fields, these are the pointers to the UnknownFieldSet + // containing the unknown fields. In certain cases (e.g. proto1's + // MessageSet, or nested groups of unknown fields), these may differ from + // the messages' internal UnknownFieldSets. + const UnknownFieldSet* unknown_field_set1; + const UnknownFieldSet* unknown_field_set2; + + // For unknown fields, these are the index of the field within the + // UnknownFieldSets. One or the other will be -1 when + // reporting an addition or deletion. + int unknown_field_index1; + int unknown_field_index2; + + SpecificField() + : field(NULL), + unknown_field_number(-1), + index(-1), + new_index(-1), + unknown_field_set1(NULL), + unknown_field_set2(NULL), + unknown_field_index1(-1), + unknown_field_index2(-1) {} + }; + + // Abstract base class from which all MessageDifferencer + // reporters derive. The five Report* methods below will be called when + // a field has been added, deleted, modified, moved, or matched. The third + // argument is a vector of FieldDescriptor pointers which describes the chain + // of fields that was taken to find the current field. For example, for a + // field found in an embedded message, the vector will contain two + // FieldDescriptors. The first will be the field of the embedded message + // itself and the second will be the actual field in the embedded message + // that was added/deleted/modified. + class LIBPROTOBUF_EXPORT Reporter { + public: + Reporter(); + virtual ~Reporter(); + + // Reports that a field has been added into Message2. + virtual void ReportAdded( + const Message& message1, const Message& message2, + const vector& field_path) = 0; + + // Reports that a field has been deleted from Message1. + virtual void ReportDeleted( + const Message& message1, + const Message& message2, + const vector& field_path) = 0; + + // Reports that the value of a field has been modified. + virtual void ReportModified( + const Message& message1, + const Message& message2, + const vector& field_path) = 0; + + // Reports that a repeated field has been moved to another location. This + // only applies when using TreatAsSet or TreatAsMap() -- see below. Also + // note that for any given field, ReportModified and ReportMoved are + // mutually exclusive. If a field has been both moved and modified, then + // only ReportModified will be called. + virtual void ReportMoved( + const Message& message1, + const Message& message2, + const vector& field_path) { } + + // Reports that two fields match. Useful for doing side-by-side diffs. + // This function is mutually exclusive with ReportModified and ReportMoved. + // Note that you must call set_report_matches(true) before calling Compare + // to make use of this function. + virtual void ReportMatched( + const Message& message1, + const Message& message2, + const vector& field_path) { } + + // Reports that two fields would have been compared, but the + // comparison has been skipped because the field was marked as + // 'ignored' using IgnoreField(). This function is mutually + // exclusive with all the other Report() functions. + // + // The contract of ReportIgnored is slightly different than the + // other Report() functions, in that |field_path.back().index| is + // always equal to -1, even if the last field is repeated. This is + // because while the other Report() functions indicate where in a + // repeated field the action (Addition, Deletion, etc...) + // happened, when a repeated field is 'ignored', the differencer + // simply calls ReportIgnored on the repeated field as a whole and + // moves on without looking at its individual elements. + // + // Furthermore, ReportIgnored() does not indicate whether the + // fields were in fact equal or not, as Compare() does not inspect + // these fields at all. It is up to the Reporter to decide whether + // the fields are equal or not (perhaps with a second call to + // Compare()), if it cares. + virtual void ReportIgnored( + const Message& message1, + const Message& message2, + const vector& field_path) { } + + // Report that an unknown field is ignored. (see comment above). + // Note this is a different function since the last SpecificField in field + // path has a null field. This could break existing Reporter. + virtual void ReportUnknownFieldIgnored( + const Message& message1, const Message& message2, + const vector& field_path) {} + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reporter); + }; + + // MapKeyComparator is used to determine if two elements have the same key + // when comparing elements of a repeated field as a map. + class LIBPROTOBUF_EXPORT MapKeyComparator { + public: + MapKeyComparator(); + virtual ~MapKeyComparator(); + + virtual bool IsMatch(const Message& message1, + const Message& message2, + const vector& parent_fields) const { + GOOGLE_CHECK(false) << "IsMatch() is not implemented."; + return false; + } + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapKeyComparator); + }; + + // Abstract base class from which all IgnoreCriteria derive. + // By adding IgnoreCriteria more complex ignore logic can be implemented. + // IgnoreCriteria are registed with AddIgnoreCriteria. For each compared + // field IsIgnored is called on each added IgnoreCriteria until one returns + // true or all return false. + // IsIgnored is called for fields where at least one side has a value. + class LIBPROTOBUF_EXPORT IgnoreCriteria { + public: + IgnoreCriteria(); + virtual ~IgnoreCriteria(); + + // Returns true if the field should be ignored. + virtual bool IsIgnored( + const Message& message1, + const Message& message2, + const FieldDescriptor* field, + const vector& parent_fields) = 0; + + // Returns true if the unknown field should be ignored. + // Note: This will be called for unknown fields as well in which case + // field.field will be null. + virtual bool IsUnknownFieldIgnored( + const Message& message1, const Message& message2, + const SpecificField& field, + const vector& parent_fields) { + return false; + } + }; + + // To add a Reporter, construct default here, then use ReportDifferencesTo or + // ReportDifferencesToString. + explicit MessageDifferencer(); + + ~MessageDifferencer(); + + enum MessageFieldComparison { + EQUAL, // Fields must be present in both messages + // for the messages to be considered the same. + EQUIVALENT, // Fields with default values are considered set + // for comparison purposes even if not explicitly + // set in the messages themselves. Unknown fields + // are ignored. + }; + + enum Scope { + FULL, // All fields of both messages are considered in the comparison. + PARTIAL // Only fields present in the first message are considered; fields + // set only in the second message will be skipped during + // comparison. + }; + + // DEPRECATED. Use FieldComparator::FloatComparison instead. + enum FloatComparison { + EXACT, // Floats and doubles are compared exactly. + APPROXIMATE // Floats and doubles are compared using the + // MathUtil::AlmostEquals method. + }; + + enum RepeatedFieldComparison { + AS_LIST, // Repeated fields are compared in order. Differing values at + // the same index are reported using ReportModified(). If the + // repeated fields have different numbers of elements, the + // unpaired elements are reported using ReportAdded() or + // ReportDeleted(). + AS_SET, // Treat all the repeated fields as sets by default. + // See TreatAsSet(), as below. + }; + + // The elements of the given repeated field will be treated as a set for + // diffing purposes, so different orderings of the same elements will be + // considered equal. Elements which are present on both sides of the + // comparison but which have changed position will be reported with + // ReportMoved(). Elements which only exist on one side or the other are + // reported with ReportAdded() and ReportDeleted() regardless of their + // positions. ReportModified() is never used for this repeated field. If + // the only differences between the compared messages is that some fields + // have been moved, then the comparison returns true. + // + // If the scope of comparison is set to PARTIAL, then in addition to what's + // above, extra values added to repeated fields of the second message will + // not cause the comparison to fail. + // + // Note that set comparison is currently O(k * n^2) (where n is the total + // number of elements, and k is the average size of each element). In theory + // it could be made O(n * k) with a more complex hashing implementation. Feel + // free to contribute one if the current implementation is too slow for you. + // If partial matching is also enabled, the time complexity will be O(k * n^2 + // + n^3) in which n^3 is the time complexity of the maximum matching + // algorithm. + // + // REQUIRES: field->is_repeated() and field not registered with TreatAsList + void TreatAsSet(const FieldDescriptor* field); + + // The elements of the given repeated field will be treated as a list for + // diffing purposes, so different orderings of the same elements will NOT be + // considered equal. + // + // REQUIRED: field->is_repeated() and field not registered with TreatAsSet + void TreatAsList(const FieldDescriptor* field); + + // The elements of the given repeated field will be treated as a map for + // diffing purposes, with |key| being the map key. Thus, elements with the + // same key will be compared even if they do not appear at the same index. + // Differences are reported similarly to TreatAsSet(), except that + // ReportModified() is used to report elements with the same key but + // different values. Note that if an element is both moved and modified, + // only ReportModified() will be called. As with TreatAsSet, if the only + // differences between the compared messages is that some fields have been + // moved, then the comparison returns true. See TreatAsSet for notes on + // performance. + // + // REQUIRES: field->is_repeated() + // REQUIRES: field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + // REQUIRES: key->containing_type() == field->message_type() + void TreatAsMap(const FieldDescriptor* field, const FieldDescriptor* key); + // Same as TreatAsMap except that this method will use multiple fields as + // the key in comparison. All specified fields in 'key_fields' should be + // present in the compared elements. Two elements will be treated as having + // the same key iff they have the same value for every specified field. There + // are two steps in the comparison process. The first one is key matching. + // Every element from one message will be compared to every element from + // the other message. Only fields in 'key_fields' are compared in this step + // to decide if two elements have the same key. The second step is value + // comparison. Those pairs of elements with the same key (with equal value + // for every field in 'key_fields') will be compared in this step. + // Time complexity of the first step is O(s * m * n ^ 2) where s is the + // average size of the fields specified in 'key_fields', m is the number of + // fields in 'key_fields' and n is the number of elements. If partial + // matching is enabled, an extra O(n^3) will be incured by the maximum + // matching algorithm. The second step is O(k * n) where k is the average + // size of each element. + void TreatAsMapWithMultipleFieldsAsKey( + const FieldDescriptor* field, + const vector& key_fields); + // Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field + // do not necessarily need to be a direct subfield. Each element in + // key_field_paths indicate a path from the message being compared, listing + // successive subfield to reach the key field. + // + // REQUIRES: + // for key_field_path in key_field_paths: + // key_field_path[0]->containing_type() == field->message_type() + // for i in [0, key_field_path.size() - 1): + // key_field_path[i+1]->containing_type() == + // key_field_path[i]->message_type() + // key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE + // !key_field_path[i]->is_repeated() + void TreatAsMapWithMultipleFieldPathsAsKey( + const FieldDescriptor* field, + const vector >& key_field_paths); + + // Uses a custom MapKeyComparator to determine if two elements have the same + // key when comparing a repeated field as a map. + // The caller is responsible to delete the key_comparator. + // This method varies from TreatAsMapWithMultipleFieldsAsKey only in the + // first key matching step. Rather than comparing some specified fields, it + // will invoke the IsMatch method of the given 'key_comparator' to decide if + // two elements have the same key. + void TreatAsMapUsingKeyComparator( + const FieldDescriptor* field, + const MapKeyComparator* key_comparator); + + // Add a custom ignore criteria that is evaluated in addition to the + // ignored fields added with IgnoreField. + // Takes ownership of ignore_criteria. + void AddIgnoreCriteria(IgnoreCriteria* ignore_criteria); + + // Indicates that any field with the given descriptor should be + // ignored for the purposes of comparing two messages. This applies + // to fields nested in the message structure as well as top level + // ones. When the MessageDifferencer encounters an ignored field, + // ReportIgnored is called on the reporter, if one is specified. + // + // The only place where the field's 'ignored' status is not applied is when + // it is being used as a key in a field passed to TreatAsMap or is one of + // the fields passed to TreatAsMapWithMultipleFieldsAsKey. + // In this case it is compared in key matching but after that it's ignored + // in value comparison. + void IgnoreField(const FieldDescriptor* field); + + // Sets the field comparator used to determine differences between protocol + // buffer fields. By default it's set to a DefaultFieldComparator instance. + // MessageDifferencer doesn't take ownership over the passed object. + // Note that this method must be called before Compare for the comparator to + // be used. + void set_field_comparator(FieldComparator* comparator); + + // DEPRECATED. Pass a DefaultFieldComparator instance instead. + // Sets the fraction and margin for the float comparison of a given field. + // Uses MathUtil::WithinFractionOrMargin to compare the values. + // NOTE: this method does nothing if differencer's field comparator has been + // set to a custom object. + // + // REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or + // field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT + // REQUIRES: float_comparison_ == APPROXIMATE + void SetFractionAndMargin(const FieldDescriptor* field, double fraction, + double margin); + + // Sets the type of comparison (as defined in the MessageFieldComparison + // enumeration above) that is used by this differencer when determining how + // to compare fields in messages. + void set_message_field_comparison(MessageFieldComparison comparison); + + // Tells the differencer whether or not to report matches. This method must + // be called before Compare. The default for a new differencer is false. + void set_report_matches(bool report_matches) { + report_matches_ = report_matches; + } + + // Sets the scope of the comparison (as defined in the Scope enumeration + // above) that is used by this differencer when determining which fields to + // compare between the messages. + void set_scope(Scope scope); + + // Returns the current scope used by this differencer. + Scope scope(); + + // DEPRECATED. Pass a DefaultFieldComparator instance instead. + // Sets the type of comparison (as defined in the FloatComparison enumeration + // above) that is used by this differencer when comparing float (and double) + // fields in messages. + // NOTE: this method does nothing if differencer's field comparator has been + // set to a custom object. + void set_float_comparison(FloatComparison comparison); + + // Sets the type of comparison for repeated field (as defined in the + // RepeatedFieldComparison enumeration above) that is used by this + // differencer when compare repeated fields in messages. + void set_repeated_field_comparison(RepeatedFieldComparison comparison); + + // Compares the two specified messages, returning true if they are the same, + // false otherwise. If this method returns false, any changes between the + // two messages will be reported if a Reporter was specified via + // ReportDifferencesTo (see also ReportDifferencesToString). + // + // This method REQUIRES that the two messages have the same + // Descriptor (message1.GetDescriptor() == message2.GetDescriptor()). + bool Compare(const Message& message1, const Message& message2); + + // Same as above, except comparing only the list of fields specified by the + // two vectors of FieldDescriptors. + bool CompareWithFields(const Message& message1, const Message& message2, + const vector& message1_fields, + const vector& message2_fields); + + // Automatically creates a reporter that will output the differences + // found (if any) to the specified output string pointer. Note that this + // method must be called before Compare. + void ReportDifferencesToString(string* output); + + // Tells the MessageDifferencer to report differences via the specified + // reporter. Note that this method must be called before Compare for + // the reporter to be used. It is the responsibility of the caller to delete + // this object. + // If the provided pointer equals NULL, the MessageDifferencer stops reporting + // differences to any previously set reporters or output strings. + void ReportDifferencesTo(Reporter* reporter); + + // An implementation of the MessageDifferencer Reporter that outputs + // any differences found in human-readable form to the supplied + // ZeroCopyOutputStream or Printer. If a printer is used, the delimiter + // *must* be '$'. + // + // WARNING: this reporter does not necessarily flush its output until it is + // destroyed. As a result, it is not safe to assume the output is valid or + // complete until after you destroy the reporter. For example, if you use a + // StreamReporter to write to a StringOutputStream, the target string may + // contain uninitialized data until the reporter is destroyed. + class LIBPROTOBUF_EXPORT StreamReporter : public Reporter { + public: + explicit StreamReporter(io::ZeroCopyOutputStream* output); + explicit StreamReporter(io::Printer* printer); // delimiter '$' + virtual ~StreamReporter(); + + // When set to true, the stream reporter will also output aggregates nodes + // (i.e. messages and groups) whose subfields have been modified. When + // false, will only report the individual subfields. Defaults to false. + void set_report_modified_aggregates(bool report) { + report_modified_aggregates_ = report; + } + + // The following are implementations of the methods described above. + virtual void ReportAdded(const Message& message1, const Message& message2, + const vector& field_path); + + virtual void ReportDeleted(const Message& message1, + const Message& message2, + const vector& field_path); + + virtual void ReportModified(const Message& message1, + const Message& message2, + const vector& field_path); + + virtual void ReportMoved(const Message& message1, + const Message& message2, + const vector& field_path); + + virtual void ReportMatched(const Message& message1, + const Message& message2, + const vector& field_path); + + virtual void ReportIgnored(const Message& message1, + const Message& message2, + const vector& field_path); + + virtual void ReportUnknownFieldIgnored( + const Message& message1, const Message& message2, + const vector& field_path); + + protected: + // Prints the specified path of fields to the buffer. + virtual void PrintPath(const vector& field_path, + bool left_side); + + // Prints the value of fields to the buffer. left_side is true if the + // given message is from the left side of the comparison, false if it + // was the right. This is relevant only to decide whether to follow + // unknown_field_index1 or unknown_field_index2 when an unknown field + // is encountered in field_path. + virtual void PrintValue(const Message& message, + const vector& field_path, + bool left_side); + + // Prints the specified path of unknown fields to the buffer. + virtual void PrintUnknownFieldValue(const UnknownField* unknown_field); + + // Just print a string + void Print(const string& str); + + private: + io::Printer* printer_; + bool delete_printer_; + bool report_modified_aggregates_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StreamReporter); + }; + + private: + // A MapKeyComparator to be used in TreatAsMapUsingKeyComparator. + // Implementation of this class needs to do field value comparison which + // relies on some private methods of MessageDifferencer. That's why this + // class is declared as a nested class of MessageDifferencer. + class MultipleFieldsMapKeyComparator; + // Returns true if field1's number() is less than field2's. + static bool FieldBefore(const FieldDescriptor* field1, + const FieldDescriptor* field2); + + // Combine the two lists of fields into the combined_fields output vector. + // All fields present in both lists will always be included in the combined + // list. Fields only present in one of the lists will only appear in the + // combined list if the corresponding fields_scope option is set to FULL. + void CombineFields(const vector& fields1, + Scope fields1_scope, + const vector& fields2, + Scope fields2_scope, + vector* combined_fields); + + // Internal version of the Compare method which performs the actual + // comparison. The parent_fields vector is a vector containing field + // descriptors of all fields accessed to get to this comparison operation + // (i.e. if the current message is an embedded message, the parent_fields + // vector will contain the field that has this embedded message). + bool Compare(const Message& message1, const Message& message2, + vector* parent_fields); + + // Compares all the unknown fields in two messages. + bool CompareUnknownFields(const Message& message1, const Message& message2, + const google::protobuf::UnknownFieldSet&, + const google::protobuf::UnknownFieldSet&, + vector* parent_fields); + + // Compares the specified messages for the requested field lists. The field + // lists are modified depending on comparison settings, and then passed to + // CompareWithFieldsInternal. + bool CompareRequestedFieldsUsingSettings( + const Message& message1, const Message& message2, + const vector& message1_fields, + const vector& message2_fields, + vector* parent_fields); + + // Compares the specified messages with the specified field lists. + bool CompareWithFieldsInternal( + const Message& message1, const Message& message2, + const vector& message1_fields, + const vector& message2_fields, + vector* parent_fields); + + // Compares the repeated fields, and report the error. + bool CompareRepeatedField(const Message& message1, const Message& message2, + const FieldDescriptor* field, + vector* parent_fields); + + // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields. + bool CompareFieldValue(const Message& message1, + const Message& message2, + const FieldDescriptor* field, + int index1, + int index2); + + // Compares the specified field on the two messages, returning + // true if they are the same, false otherwise. For repeated fields, + // this method only compares the value in the specified index. This method + // uses Compare functions to recurse into submessages. + // The parent_fields vector is used in calls to a Reporter instance calls. + // It can be NULL, in which case the MessageDifferencer will create new + // list of parent messages if it needs to recursively compare the given field. + // To avoid confusing users you should not set it to NULL unless you modified + // Reporter to handle the change of parent_fields correctly. + bool CompareFieldValueUsingParentFields(const Message& message1, + const Message& message2, + const FieldDescriptor* field, + int index1, + int index2, + vector* parent_fields); + + // Compares the specified field on the two messages, returning comparison + // result, as returned by appropriate FieldComparator. + FieldComparator::ComparisonResult GetFieldComparisonResult( + const Message& message1, const Message& message2, + const FieldDescriptor* field, int index1, int index2, + const FieldContext* field_context); + + // Check if the two elements in the repeated field are match to each other. + // if the key_comprator is NULL, this function returns true when the two + // elements are equal. + bool IsMatch(const FieldDescriptor* repeated_field, + const MapKeyComparator* key_comparator, + const Message* message1, const Message* message2, + const vector& parent_fields, + int index1, int index2); + + // Returns true when this repeated field has been configured to be treated + // as a set. + bool IsTreatedAsSet(const FieldDescriptor* field); + + // Returns true when this repeated field is to be compared as a subset, ie. + // has been configured to be treated as a set or map and scope is set to + // PARTIAL. + bool IsTreatedAsSubset(const FieldDescriptor* field); + + // Returns true if this field is to be ignored when this + // MessageDifferencer compares messages. + bool IsIgnored( + const Message& message1, + const Message& message2, + const FieldDescriptor* field, + const vector& parent_fields); + + // Returns true if this unknown field is to be ignored when this + // MessageDifferencer compares messages. + bool IsUnknownFieldIgnored(const Message& message1, const Message& message2, + const SpecificField& field, + const vector& parent_fields); + + // Returns MapKeyComparator* when this field has been configured to + // be treated as a map. If not, returns NULL. + const MapKeyComparator* GetMapKeyComparator(const FieldDescriptor* field); + + // Attempts to match indices of a repeated field, so that the contained values + // match. Clears output vectors and sets their values to indices of paired + // messages, ie. if message1[0] matches message2[1], then match_list1[0] == 1 + // and match_list2[1] == 0. The unmatched indices are indicated by -1. + // This method returns false if the match failed. However, it doesn't mean + // that the comparison succeeds when this method returns true (you need to + // double-check in this case). + bool MatchRepeatedFieldIndices(const Message& message1, + const Message& message2, + const FieldDescriptor* repeated_field, + const vector& parent_fields, + vector* match_list1, + vector* match_list2); + + // If "any" is of type google.protobuf.Any, extract its payload using + // DynamicMessageFactory and store in "data". + bool UnpackAny(const Message& any, google::protobuf::scoped_ptr* data); + + // Checks if index is equal to new_index in all the specific fields. + static bool CheckPathChanged(const vector& parent_fields); + + // Defines a map between field descriptors and their MapKeyComparators. + // Used for repeated fields when they are configured as TreatAsMap. + typedef map FieldKeyComparatorMap; + + // Defines a set to store field descriptors. Used for repeated fields when + // they are configured as TreatAsSet. + typedef set FieldSet; + + Reporter* reporter_; + DefaultFieldComparator default_field_comparator_; + FieldComparator* field_comparator_; + MessageFieldComparison message_field_comparison_; + Scope scope_; + RepeatedFieldComparison repeated_field_comparison_; + + FieldSet set_fields_; + FieldSet list_fields_; + // Keeps track of MapKeyComparators that are created within + // MessageDifferencer. These MapKeyComparators should be deleted + // before MessageDifferencer is destroyed. + // When TreatAsMap or TreatAsMapWithMultipleFieldsAsKey is called, we don't + // store the supplied FieldDescriptors directly. Instead, a new + // MapKeyComparator is created for comparison purpose. + vector owned_key_comparators_; + FieldKeyComparatorMap map_field_key_comparator_; + vector ignore_criteria_; + + FieldSet ignored_fields_; + + bool compare_unknown_fields_; + bool report_matches_; + + string* output_string_; + + google::protobuf::scoped_ptr dynamic_message_factory_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageDifferencer); +}; + +// This class provides extra information to the FieldComparator::Compare +// function. +class LIBPROTOBUF_EXPORT FieldContext { + public: + explicit FieldContext( + vector* parent_fields) + : parent_fields_(parent_fields) {} + + vector* parent_fields() const { + return parent_fields_; + } + + private: + vector* parent_fields_; +}; + +} +} + +} // namespace google +#endif // GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__ diff --git a/thirdparty/linux/include/google/protobuf/util/time_util.h b/thirdparty/linux/include/google/protobuf/util/time_util.h new file mode 100644 index 0000000..1bac089 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/util/time_util.h @@ -0,0 +1,293 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ + +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif + +#include +#include + +namespace google { +namespace protobuf { +namespace util { + +class LIBPROTOBUF_EXPORT TimeUtil { + typedef google::protobuf::Timestamp Timestamp; + typedef google::protobuf::Duration Duration; + + public: + // The min/max Timestamp/Duration values we support. + // + // For "0001-01-01T00:00:00Z". + static const int64 kTimestampMinSeconds = -62135596800LL; + // For "9999-12-31T23:59:59.999999999Z". + static const int64 kTimestampMaxSeconds = 253402300799LL; + static const int64 kDurationMinSeconds = -315576000000LL; + static const int64 kDurationMaxSeconds = 315576000000LL; + + // Converts Timestamp to/from RFC 3339 date string format. + // Generated output will always be Z-normalized and uses 3, 6 or 9 + // fractional digits as required to represent the exact time. When + // parsing, any fractional digits (or none) and any offset are + // accepted as long as they fit into nano-seconds precision. + // Note that Timestamp can only represent time from + // 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. Converting + // a Timestamp outside of this range is undefined behavior. + // See https://www.ietf.org/rfc/rfc3339.txt + // + // Example of generated format: + // "1972-01-01T10:00:20.021Z" + // + // Example of accepted format: + // "1972-01-01T10:00:20.021-05:00" + static string ToString(const Timestamp& timestamp); + static bool FromString(const string& value, Timestamp* timestamp); + + // Converts Duration to/from string format. The string format will contains + // 3, 6, or 9 fractional digits depending on the precision required to + // represent the exact Duration value. For example: + // "1s", "1.010s", "1.000000100s", "-3.100s" + // The range that can be represented by Duration is from -315,576,000,000 + // to +315,576,000,000 inclusive (in seconds). + static string ToString(const Duration& duration); + static bool FromString(const string& value, Duration* timestamp); + +#ifdef GetCurrentTime +#undef GetCurrentTime // Visual Studio has macro GetCurrentTime +#endif + // Gets the current UTC time. + static Timestamp GetCurrentTime(); + // Returns the Time representing "1970-01-01 00:00:00". + static Timestamp GetEpoch(); + + // Converts between Duration and integer types. The behavior is undefined if + // the input value is not in the valid range of Duration. + static Duration NanosecondsToDuration(int64 nanos); + static Duration MicrosecondsToDuration(int64 micros); + static Duration MillisecondsToDuration(int64 millis); + static Duration SecondsToDuration(int64 seconds); + static Duration MinutesToDuration(int64 minutes); + static Duration HoursToDuration(int64 hours); + // Result will be truncated towards zero. For example, "-1.5s" will be + // truncated to "-1s", and "1.5s" to "1s" when converting to seconds. + // It's undefined behavior if the input duration is not valid or the result + // exceeds the range of int64. A duration is not valid if it's not in the + // valid range of Duration, or have an invalid nanos value (i.e., larger + // than 999999999, less than -999999999, or have a different sign from the + // seconds part). + static int64 DurationToNanoseconds(const Duration& duration); + static int64 DurationToMicroseconds(const Duration& duration); + static int64 DurationToMilliseconds(const Duration& duration); + static int64 DurationToSeconds(const Duration& duration); + static int64 DurationToMinutes(const Duration& duration); + static int64 DurationToHours(const Duration& duration); + // Creates Timestamp from integer types. The integer value indicates the + // time elapsed from Epoch time. The behavior is undefined if the input + // value is not in the valid range of Timestamp. + static Timestamp NanosecondsToTimestamp(int64 nanos); + static Timestamp MicrosecondsToTimestamp(int64 micros); + static Timestamp MillisecondsToTimestamp(int64 millis); + static Timestamp SecondsToTimestamp(int64 seconds); + // Result will be truncated down to the nearest integer value. For example, + // with "1969-12-31T23:59:59.9Z", TimestampToMilliseconds() returns -100 + // and TimestampToSeconds() returns -1. It's undefined behavior if the input + // Timestamp is not valid (i.e., its seconds part or nanos part does not fall + // in the valid range) or the return value doesn't fit into int64. + static int64 TimestampToNanoseconds(const Timestamp& timestamp); + static int64 TimestampToMicroseconds(const Timestamp& timestamp); + static int64 TimestampToMilliseconds(const Timestamp& timestamp); + static int64 TimestampToSeconds(const Timestamp& timestamp); + + // Conversion to/from other time/date types. Note that these types may + // have a different precision and time range from Timestamp/Duration. + // When converting to a lower precision type, the value will be truncated + // to the nearest value that can be represented. If the value is + // out of the range of the result type, the return value is undefined. + // + // Conversion to/from time_t + static Timestamp TimeTToTimestamp(time_t value); + static time_t TimestampToTimeT(const Timestamp& value); + + // Conversion to/from timeval + static Timestamp TimevalToTimestamp(const timeval& value); + static timeval TimestampToTimeval(const Timestamp& value); + static Duration TimevalToDuration(const timeval& value); + static timeval DurationToTimeval(const Duration& value); +}; + +} // namespace util +} // namespace protobuf + + +namespace protobuf { +// Overloaded operators for Duration. +// +// Assignment operators. +LIBPROTOBUF_EXPORT Duration& operator+=(Duration& d1, const Duration& d2); // NOLINT +LIBPROTOBUF_EXPORT Duration& operator-=(Duration& d1, const Duration& d2); // NOLINT +LIBPROTOBUF_EXPORT Duration& operator*=(Duration& d, int64 r); // NOLINT +LIBPROTOBUF_EXPORT Duration& operator*=(Duration& d, double r); // NOLINT +LIBPROTOBUF_EXPORT Duration& operator/=(Duration& d, int64 r); // NOLINT +LIBPROTOBUF_EXPORT Duration& operator/=(Duration& d, double r); // NOLINT +// Overload for other integer types. +template +Duration& operator*=(Duration& d, T r) { // NOLINT + int64 x = r; + return d *= x; +} +template +Duration& operator/=(Duration& d, T r) { // NOLINT + int64 x = r; + return d /= x; +} +LIBPROTOBUF_EXPORT Duration& operator%=(Duration& d1, const Duration& d2); // NOLINT +// Relational operators. +inline bool operator<(const Duration& d1, const Duration& d2) { + if (d1.seconds() == d2.seconds()) { + return d1.nanos() < d2.nanos(); + } + return d1.seconds() < d2.seconds(); +} +inline bool operator>(const Duration& d1, const Duration& d2) { + return d2 < d1; +} +inline bool operator>=(const Duration& d1, const Duration& d2) { + return !(d1 < d2); +} +inline bool operator<=(const Duration& d1, const Duration& d2) { + return !(d2 < d1); +} +inline bool operator==(const Duration& d1, const Duration& d2) { + return d1.seconds() == d2.seconds() && d1.nanos() == d2.nanos(); +} +inline bool operator!=(const Duration& d1, const Duration& d2) { + return !(d1 == d2); +} +// Additive operators +inline Duration operator-(const Duration& d) { + Duration result; + result.set_seconds(-d.seconds()); + result.set_nanos(-d.nanos()); + return result; +} +inline Duration operator+(const Duration& d1, const Duration& d2) { + Duration result = d1; + return result += d2; +} +inline Duration operator-(const Duration& d1, const Duration& d2) { + Duration result = d1; + return result -= d2; +} +// Multiplicative operators +template +inline Duration operator*(Duration d, T r) { + return d *= r; +} +template +inline Duration operator*(T r, Duration d) { + return d *= r; +} +template +inline Duration operator/(Duration d, T r) { + return d /= r; +} +LIBPROTOBUF_EXPORT int64 operator/(const Duration& d1, const Duration& d2); + +inline Duration operator%(const Duration& d1, const Duration& d2) { + Duration result = d1; + return result %= d2; +} + +inline ostream& operator<<(ostream& out, const Duration& d) { + out << google::protobuf::util::TimeUtil::ToString(d); + return out; +} + +// Overloaded operators for Timestamp +// +// Assignement operators. +LIBPROTOBUF_EXPORT Timestamp& operator+=(Timestamp& t, const Duration& d); // NOLINT +LIBPROTOBUF_EXPORT Timestamp& operator-=(Timestamp& t, const Duration& d); // NOLINT +// Relational operators. +inline bool operator<(const Timestamp& t1, const Timestamp& t2) { + if (t1.seconds() == t2.seconds()) { + return t1.nanos() < t2.nanos(); + } + return t1.seconds() < t2.seconds(); +} +inline bool operator>(const Timestamp& t1, const Timestamp& t2) { + return t2 < t1; +} +inline bool operator>=(const Timestamp& t1, const Timestamp& t2) { + return !(t1 < t2); +} +inline bool operator<=(const Timestamp& t1, const Timestamp& t2) { + return !(t2 < t1); +} +inline bool operator==(const Timestamp& t1, const Timestamp& t2) { + return t1.seconds() == t2.seconds() && t1.nanos() == t2.nanos(); +} +inline bool operator!=(const Timestamp& t1, const Timestamp& t2) { + return !(t1 == t2); +} +// Additive operators. +inline Timestamp operator+(const Timestamp& t, const Duration& d) { + Timestamp result = t; + return result += d; +} +inline Timestamp operator+(const Duration& d, const Timestamp& t) { + Timestamp result = t; + return result += d; +} +inline Timestamp operator-(const Timestamp& t, const Duration& d) { + Timestamp result = t; + return result -= d; +} +LIBPROTOBUF_EXPORT Duration operator-(const Timestamp& t1, const Timestamp& t2); + +inline ostream& operator<<(ostream& out, const Timestamp& t) { + out << google::protobuf::util::TimeUtil::ToString(t); + return out; +} + +} // namespace protobuf + + +} // namespace google +#endif // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__ diff --git a/thirdparty/linux/include/google/protobuf/util/type_resolver.h b/thirdparty/linux/include/google/protobuf/util/type_resolver.h new file mode 100644 index 0000000..77d4416 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/util/type_resolver.h @@ -0,0 +1,75 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ +#define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ + +#include + +#include +#include + + +namespace google { +namespace protobuf { +class Type; +class Enum; +} // namespace protobuf + + +namespace protobuf { +class DescriptorPool; +namespace util { + +// Abstract interface for a type resovler. +// +// Implementations of this interface must be thread-safe. +class LIBPROTOBUF_EXPORT TypeResolver { + public: + TypeResolver() {} + virtual ~TypeResolver() {} + + // Resolves a type url for a message type. + virtual util::Status ResolveMessageType( + const string& type_url, google::protobuf::Type* message_type) = 0; + + // Resolves a type url for an enum type. + virtual util::Status ResolveEnumType(const string& type_url, + google::protobuf::Enum* enum_type) = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeResolver); +}; + +} // namespace util +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ diff --git a/thirdparty/linux/include/google/protobuf/util/type_resolver_util.h b/thirdparty/linux/include/google/protobuf/util/type_resolver_util.h new file mode 100644 index 0000000..c0ef3c1 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/util/type_resolver_util.h @@ -0,0 +1,52 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ + +#include + +#include +namespace google { +namespace protobuf { +class DescriptorPool; +namespace util { +class TypeResolver; + +// Creates a TypeResolver that serves type information in the given descriptor +// pool. Caller takes ownership of the returned TypeResolver. +LIBPROTOBUF_EXPORT TypeResolver* NewTypeResolverForDescriptorPool( + const string& url_prefix, const DescriptorPool* pool); + +} // namespace util +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ diff --git a/thirdparty/linux/include/google/protobuf/wire_format.h b/thirdparty/linux/include/google/protobuf/wire_format.h new file mode 100644 index 0000000..aaee21f --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/wire_format.h @@ -0,0 +1,337 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// atenasio@google.com (Chris Atenasio) (ZigZag transform) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__ + +#include +#include +#include +#include +#include +#include + +// Do UTF-8 validation on string type in Debug build only +#ifndef NDEBUG +#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED +#endif + +namespace google { +namespace protobuf { + namespace io { + class CodedInputStream; // coded_stream.h + class CodedOutputStream; // coded_stream.h + } + class UnknownFieldSet; // unknown_field_set.h +} + +namespace protobuf { +namespace internal { + +// This class is for internal use by the protocol buffer library and by +// protocol-complier-generated message classes. It must not be called +// directly by clients. +// +// This class contains code for implementing the binary protocol buffer +// wire format via reflection. The WireFormatLite class implements the +// non-reflection based routines. +// +// This class is really a namespace that contains only static methods +class LIBPROTOBUF_EXPORT WireFormat { + public: + + // Given a field return its WireType + static inline WireFormatLite::WireType WireTypeForField( + const FieldDescriptor* field); + + // Given a FieldDescriptor::Type return its WireType + static inline WireFormatLite::WireType WireTypeForFieldType( + FieldDescriptor::Type type); + + // Compute the byte size of a tag. For groups, this includes both the start + // and end tags. + static inline int TagSize(int field_number, FieldDescriptor::Type type); + + // These procedures can be used to implement the methods of Message which + // handle parsing and serialization of the protocol buffer wire format + // using only the Reflection interface. When you ask the protocol + // compiler to optimize for code size rather than speed, it will implement + // those methods in terms of these procedures. Of course, these are much + // slower than the specialized implementations which the protocol compiler + // generates when told to optimize for speed. + + // Read a message in protocol buffer wire format. + // + // This procedure reads either to the end of the input stream or through + // a WIRETYPE_END_GROUP tag ending the message, whichever comes first. + // It returns false if the input is invalid. + // + // Required fields are NOT checked by this method. You must call + // IsInitialized() on the resulting message yourself. + static bool ParseAndMergePartial(io::CodedInputStream* input, + Message* message); + + // Serialize a message in protocol buffer wire format. + // + // Any embedded messages within the message must have their correct sizes + // cached. However, the top-level message need not; its size is passed as + // a parameter to this procedure. + // + // These return false iff the underlying stream returns a write error. + static void SerializeWithCachedSizes( + const Message& message, + int size, io::CodedOutputStream* output); + + // Implements Message::ByteSize() via reflection. WARNING: The result + // of this method is *not* cached anywhere. However, all embedded messages + // will have their ByteSize() methods called, so their sizes will be cached. + // Therefore, calling this method is sufficient to allow you to call + // WireFormat::SerializeWithCachedSizes() on the same object. + static int ByteSize(const Message& message); + + // ----------------------------------------------------------------- + // Helpers for dealing with unknown fields + + // Skips a field value of the given WireType. The input should start + // positioned immediately after the tag. If unknown_fields is non-NULL, + // the contents of the field will be added to it. + static bool SkipField(io::CodedInputStream* input, uint32 tag, + UnknownFieldSet* unknown_fields); + + // Reads and ignores a message from the input. If unknown_fields is non-NULL, + // the contents will be added to it. + static bool SkipMessage(io::CodedInputStream* input, + UnknownFieldSet* unknown_fields); + + // Read a packed enum field. If the is_valid function is not NULL, values for + // which is_valid(value) returns false are appended to unknown_fields_stream. + static bool ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input, + uint32 field_number, + bool (*is_valid)(int), + UnknownFieldSet* unknown_fields, + RepeatedField* values); + + // Write the contents of an UnknownFieldSet to the output. + static void SerializeUnknownFields(const UnknownFieldSet& unknown_fields, + io::CodedOutputStream* output); + // Same as above, except writing directly to the provided buffer. + // Requires that the buffer have sufficient capacity for + // ComputeUnknownFieldsSize(unknown_fields). + // + // Returns a pointer past the last written byte. + static uint8* SerializeUnknownFieldsToArray( + const UnknownFieldSet& unknown_fields, + uint8* target); + + // Same thing except for messages that have the message_set_wire_format + // option. + static void SerializeUnknownMessageSetItems( + const UnknownFieldSet& unknown_fields, + io::CodedOutputStream* output); + // Same as above, except writing directly to the provided buffer. + // Requires that the buffer have sufficient capacity for + // ComputeUnknownMessageSetItemsSize(unknown_fields). + // + // Returns a pointer past the last written byte. + static uint8* SerializeUnknownMessageSetItemsToArray( + const UnknownFieldSet& unknown_fields, + uint8* target); + + // Compute the size of the UnknownFieldSet on the wire. + static int ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields); + + // Same thing except for messages that have the message_set_wire_format + // option. + static int ComputeUnknownMessageSetItemsSize( + const UnknownFieldSet& unknown_fields); + + + // Helper functions for encoding and decoding tags. (Inlined below and in + // _inl.h) + // + // This is different from MakeTag(field->number(), field->type()) in the case + // of packed repeated fields. + static uint32 MakeTag(const FieldDescriptor* field); + + // Parse a single field. The input should start out positioned immediately + // after the tag. + static bool ParseAndMergeField( + uint32 tag, + const FieldDescriptor* field, // May be NULL for unknown + Message* message, + io::CodedInputStream* input); + + // Serialize a single field. + static void SerializeFieldWithCachedSizes( + const FieldDescriptor* field, // Cannot be NULL + const Message& message, + io::CodedOutputStream* output); + + // Compute size of a single field. If the field is a message type, this + // will call ByteSize() for the embedded message, insuring that it caches + // its size. + static int FieldByteSize( + const FieldDescriptor* field, // Cannot be NULL + const Message& message); + + // Parse/serialize a MessageSet::Item group. Used with messages that use + // opion message_set_wire_format = true. + static bool ParseAndMergeMessageSetItem( + io::CodedInputStream* input, + Message* message); + static void SerializeMessageSetItemWithCachedSizes( + const FieldDescriptor* field, + const Message& message, + io::CodedOutputStream* output); + static int MessageSetItemByteSize( + const FieldDescriptor* field, + const Message& message); + + // Computes the byte size of a field, excluding tags. For packed fields, it + // only includes the size of the raw data, and not the size of the total + // length, but for other length-delimited types, the size of the length is + // included. + static int FieldDataOnlyByteSize( + const FieldDescriptor* field, // Cannot be NULL + const Message& message); + + enum Operation { + PARSE = 0, + SERIALIZE = 1, + }; + + // Verifies that a string field is valid UTF8, logging an error if not. + // This function will not be called by newly generated protobuf code + // but remains present to support existing code. + static void VerifyUTF8String(const char* data, int size, Operation op); + // The NamedField variant takes a field name in order to produce an + // informative error message if verification fails. + static void VerifyUTF8StringNamedField(const char* data, + int size, + Operation op, + const char* field_name); + + private: + // Skip a MessageSet field. + static bool SkipMessageSetField(io::CodedInputStream* input, + uint32 field_number, + UnknownFieldSet* unknown_fields); + + // Parse a MessageSet field. + static bool ParseAndMergeMessageSetField(uint32 field_number, + const FieldDescriptor* field, + Message* message, + io::CodedInputStream* input); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat); +}; + +// Subclass of FieldSkipper which saves skipped fields to an UnknownFieldSet. +class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper { + public: + UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields) + : unknown_fields_(unknown_fields) {} + virtual ~UnknownFieldSetFieldSkipper() {} + + // implements FieldSkipper ----------------------------------------- + virtual bool SkipField(io::CodedInputStream* input, uint32 tag); + virtual bool SkipMessage(io::CodedInputStream* input); + virtual void SkipUnknownEnum(int field_number, int value); + + protected: + UnknownFieldSet* unknown_fields_; +}; + +// inline methods ==================================================== + +inline WireFormatLite::WireType WireFormat::WireTypeForField( + const FieldDescriptor* field) { + if (field->is_packed()) { + return WireFormatLite::WIRETYPE_LENGTH_DELIMITED; + } else { + return WireTypeForFieldType(field->type()); + } +} + +inline WireFormatLite::WireType WireFormat::WireTypeForFieldType( + FieldDescriptor::Type type) { + // Some compilers don't like enum -> enum casts, so we implicit_cast to + // int first. + return WireFormatLite::WireTypeForFieldType( + static_cast( + implicit_cast(type))); +} + +inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) { + return WireFormatLite::MakeTag(field->number(), WireTypeForField(field)); +} + +inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) { + // Some compilers don't like enum -> enum casts, so we implicit_cast to + // int first. + return WireFormatLite::TagSize(field_number, + static_cast( + implicit_cast(type))); +} + +inline void WireFormat::VerifyUTF8String(const char* data, int size, + WireFormat::Operation op) { +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + WireFormatLite::VerifyUtf8String( + data, size, static_cast(op), NULL); +#else + // Avoid the compiler warning about unused variables. + (void)data; (void)size; (void)op; +#endif +} + +inline void WireFormat::VerifyUTF8StringNamedField( + const char* data, int size, WireFormat::Operation op, + const char* field_name) { +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + WireFormatLite::VerifyUtf8String( + data, size, static_cast(op), field_name); +#endif +} + + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_H__ diff --git a/thirdparty/linux/include/google/protobuf/wire_format_lite.h b/thirdparty/linux/include/google/protobuf/wire_format_lite.h new file mode 100644 index 0000000..580d4db --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/wire_format_lite.h @@ -0,0 +1,724 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// atenasio@google.com (Chris Atenasio) (ZigZag transform) +// wink@google.com (Wink Saville) (refactored from wire_format.h) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// This header is logically internal, but is made public because it is used +// from protocol-compiler-generated code, which may reside in other components. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ + +#include +#include +#include +#include // for CodedOutputStream::Varint32Size + +namespace google { + +namespace protobuf { + template class RepeatedField; // repeated_field.h +} + +namespace protobuf { +namespace internal { + +class StringPieceField; + +// This class is for internal use by the protocol buffer library and by +// protocol-complier-generated message classes. It must not be called +// directly by clients. +// +// This class contains helpers for implementing the binary protocol buffer +// wire format without the need for reflection. Use WireFormat when using +// reflection. +// +// This class is really a namespace that contains only static methods. +class LIBPROTOBUF_EXPORT WireFormatLite { + public: + + // ----------------------------------------------------------------- + // Helper constants and functions related to the format. These are + // mostly meant for internal and generated code to use. + + // The wire format is composed of a sequence of tag/value pairs, each + // of which contains the value of one field (or one element of a repeated + // field). Each tag is encoded as a varint. The lower bits of the tag + // identify its wire type, which specifies the format of the data to follow. + // The rest of the bits contain the field number. Each type of field (as + // declared by FieldDescriptor::Type, in descriptor.h) maps to one of + // these wire types. Immediately following each tag is the field's value, + // encoded in the format specified by the wire type. Because the tag + // identifies the encoding of this data, it is possible to skip + // unrecognized fields for forwards compatibility. + + enum WireType { + WIRETYPE_VARINT = 0, + WIRETYPE_FIXED64 = 1, + WIRETYPE_LENGTH_DELIMITED = 2, + WIRETYPE_START_GROUP = 3, + WIRETYPE_END_GROUP = 4, + WIRETYPE_FIXED32 = 5, + }; + + // Lite alternative to FieldDescriptor::Type. Must be kept in sync. + enum FieldType { + TYPE_DOUBLE = 1, + TYPE_FLOAT = 2, + TYPE_INT64 = 3, + TYPE_UINT64 = 4, + TYPE_INT32 = 5, + TYPE_FIXED64 = 6, + TYPE_FIXED32 = 7, + TYPE_BOOL = 8, + TYPE_STRING = 9, + TYPE_GROUP = 10, + TYPE_MESSAGE = 11, + TYPE_BYTES = 12, + TYPE_UINT32 = 13, + TYPE_ENUM = 14, + TYPE_SFIXED32 = 15, + TYPE_SFIXED64 = 16, + TYPE_SINT32 = 17, + TYPE_SINT64 = 18, + MAX_FIELD_TYPE = 18, + }; + + // Lite alternative to FieldDescriptor::CppType. Must be kept in sync. + enum CppType { + CPPTYPE_INT32 = 1, + CPPTYPE_INT64 = 2, + CPPTYPE_UINT32 = 3, + CPPTYPE_UINT64 = 4, + CPPTYPE_DOUBLE = 5, + CPPTYPE_FLOAT = 6, + CPPTYPE_BOOL = 7, + CPPTYPE_ENUM = 8, + CPPTYPE_STRING = 9, + CPPTYPE_MESSAGE = 10, + MAX_CPPTYPE = 10, + }; + + // Helper method to get the CppType for a particular Type. + static CppType FieldTypeToCppType(FieldType type); + + // Given a FieldSescriptor::Type return its WireType + static inline WireFormatLite::WireType WireTypeForFieldType( + WireFormatLite::FieldType type) { + return kWireTypeForFieldType[type]; + } + + // Number of bits in a tag which identify the wire type. + static const int kTagTypeBits = 3; + // Mask for those bits. + static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; + + // Helper functions for encoding and decoding tags. (Inlined below and in + // _inl.h) + // + // This is different from MakeTag(field->number(), field->type()) in the case + // of packed repeated fields. + static uint32 MakeTag(int field_number, WireType type); + static WireType GetTagWireType(uint32 tag); + static int GetTagFieldNumber(uint32 tag); + + // Compute the byte size of a tag. For groups, this includes both the start + // and end tags. + static inline int TagSize(int field_number, WireFormatLite::FieldType type); + + // Skips a field value with the given tag. The input should start + // positioned immediately after the tag. Skipped values are simply discarded, + // not recorded anywhere. See WireFormat::SkipField() for a version that + // records to an UnknownFieldSet. + static bool SkipField(io::CodedInputStream* input, uint32 tag); + + // Skips a field value with the given tag. The input should start + // positioned immediately after the tag. Skipped values are recorded to a + // CodedOutputStream. + static bool SkipField(io::CodedInputStream* input, uint32 tag, + io::CodedOutputStream* output); + + // Reads and ignores a message from the input. Skipped values are simply + // discarded, not recorded anywhere. See WireFormat::SkipMessage() for a + // version that records to an UnknownFieldSet. + static bool SkipMessage(io::CodedInputStream* input); + + // Reads and ignores a message from the input. Skipped values are recorded + // to a CodedOutputStream. + static bool SkipMessage(io::CodedInputStream* input, + io::CodedOutputStream* output); + +// This macro does the same thing as WireFormatLite::MakeTag(), but the +// result is usable as a compile-time constant, which makes it usable +// as a switch case or a template input. WireFormatLite::MakeTag() is more +// type-safe, though, so prefer it if possible. +#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ + static_cast( \ + ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \ + | (TYPE)) + + // These are the tags for the old MessageSet format, which was defined as: + // message MessageSet { + // repeated group Item = 1 { + // required int32 type_id = 2; + // required string message = 3; + // } + // } + static const int kMessageSetItemNumber = 1; + static const int kMessageSetTypeIdNumber = 2; + static const int kMessageSetMessageNumber = 3; + static const int kMessageSetItemStartTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, + WireFormatLite::WIRETYPE_START_GROUP); + static const int kMessageSetItemEndTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, + WireFormatLite::WIRETYPE_END_GROUP); + static const int kMessageSetTypeIdTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber, + WireFormatLite::WIRETYPE_VARINT); + static const int kMessageSetMessageTag = + GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + + // Byte size of all tags of a MessageSet::Item combined. + static const int kMessageSetItemTagsSize; + + // Helper functions for converting between floats/doubles and IEEE-754 + // uint32s/uint64s so that they can be written. (Assumes your platform + // uses IEEE-754 floats.) + static uint32 EncodeFloat(float value); + static float DecodeFloat(uint32 value); + static uint64 EncodeDouble(double value); + static double DecodeDouble(uint64 value); + + // Helper functions for mapping signed integers to unsigned integers in + // such a way that numbers with small magnitudes will encode to smaller + // varints. If you simply static_cast a negative number to an unsigned + // number and varint-encode it, it will always take 10 bytes, defeating + // the purpose of varint. So, for the "sint32" and "sint64" field types, + // we ZigZag-encode the values. + static uint32 ZigZagEncode32(int32 n); + static int32 ZigZagDecode32(uint32 n); + static uint64 ZigZagEncode64(int64 n); + static int64 ZigZagDecode64(uint64 n); + + // ================================================================= + // Methods for reading/writing individual field. The implementations + // of these methods are defined in wire_format_lite_inl.h; you must #include + // that file to use these. + +// Avoid ugly line wrapping +#define input io::CodedInputStream* input_arg +#define output io::CodedOutputStream* output_arg +#define field_number int field_number_arg +#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE + + // Read fields, not including tags. The assumption is that you already + // read the tag to determine what field to read. + + // For primitive fields, we just use a templatized routine parameterized by + // the represented type and the FieldType. These are specialized with the + // appropriate definition for each declared type. + template INL + static bool ReadPrimitive(input, CType* value); + + // Reads repeated primitive values, with optimizations for repeats. + // tag_size and tag should both be compile-time constants provided by the + // protocol compiler. + template INL + static bool ReadRepeatedPrimitive(int tag_size, + uint32 tag, + input, + RepeatedField* value); + + // Identical to ReadRepeatedPrimitive, except will not inline the + // implementation. + template + static bool ReadRepeatedPrimitiveNoInline(int tag_size, + uint32 tag, + input, + RepeatedField* value); + + // Reads a primitive value directly from the provided buffer. It returns a + // pointer past the segment of data that was read. + // + // This is only implemented for the types with fixed wire size, e.g. + // float, double, and the (s)fixed* types. + template INL + static const uint8* ReadPrimitiveFromArray(const uint8* buffer, CType* value); + + // Reads a primitive packed field. + // + // This is only implemented for packable types. + template INL + static bool ReadPackedPrimitive(input, RepeatedField* value); + + // Identical to ReadPackedPrimitive, except will not inline the + // implementation. + template + static bool ReadPackedPrimitiveNoInline(input, RepeatedField* value); + + // Read a packed enum field. If the is_valid function is not NULL, values for + // which is_valid(value) returns false are silently dropped. + static bool ReadPackedEnumNoInline(input, + bool (*is_valid)(int), + RepeatedField* values); + + // Read a packed enum field. If the is_valid function is not NULL, values for + // which is_valid(value) returns false are appended to unknown_fields_stream. + static bool ReadPackedEnumPreserveUnknowns( + input, + field_number, + bool (*is_valid)(int), + io::CodedOutputStream* unknown_fields_stream, + RepeatedField* values); + + // Read a string. ReadString(..., string* value) requires an existing string. + static inline bool ReadString(input, string* value); + // ReadString(..., string** p) is internal-only, and should only be called + // from generated code. It starts by setting *p to "new string" + // if *p == &GetEmptyStringAlreadyInited(). It then invokes + // ReadString(input, *p). This is useful for reducing code size. + static inline bool ReadString(input, string** p); + // Analogous to ReadString(). + static bool ReadBytes(input, string* value); + static bool ReadBytes(input, string** p); + + + enum Operation { + PARSE = 0, + SERIALIZE = 1, + }; + + // Returns true if the data is valid UTF-8. + static bool VerifyUtf8String(const char* data, int size, + Operation op, + const char* field_name); + + static inline bool ReadGroup (field_number, input, MessageLite* value); + static inline bool ReadMessage(input, MessageLite* value); + + // Like above, but de-virtualize the call to MergePartialFromCodedStream(). + // The pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override MergePartialFromCodedStream()). + template + static inline bool ReadGroupNoVirtual(field_number, input, + MessageType* value); + template + static inline bool ReadMessageNoVirtual(input, MessageType* value); + + // The same, but do not modify input's recursion depth. This is useful + // when reading a bunch of groups or messages in a loop, because then the + // recursion depth can be incremented before the loop and decremented after. + template + static inline bool ReadGroupNoVirtualNoRecursionDepth(field_number, input, + MessageType* value); + + template + static inline bool ReadMessageNoVirtualNoRecursionDepth(input, + MessageType* value); + + // Write a tag. The Write*() functions typically include the tag, so + // normally there's no need to call this unless using the Write*NoTag() + // variants. + INL static void WriteTag(field_number, WireType type, output); + + // Write fields, without tags. + INL static void WriteInt32NoTag (int32 value, output); + INL static void WriteInt64NoTag (int64 value, output); + INL static void WriteUInt32NoTag (uint32 value, output); + INL static void WriteUInt64NoTag (uint64 value, output); + INL static void WriteSInt32NoTag (int32 value, output); + INL static void WriteSInt64NoTag (int64 value, output); + INL static void WriteFixed32NoTag (uint32 value, output); + INL static void WriteFixed64NoTag (uint64 value, output); + INL static void WriteSFixed32NoTag(int32 value, output); + INL static void WriteSFixed64NoTag(int64 value, output); + INL static void WriteFloatNoTag (float value, output); + INL static void WriteDoubleNoTag (double value, output); + INL static void WriteBoolNoTag (bool value, output); + INL static void WriteEnumNoTag (int value, output); + + // Write fields, including tags. + static void WriteInt32 (field_number, int32 value, output); + static void WriteInt64 (field_number, int64 value, output); + static void WriteUInt32 (field_number, uint32 value, output); + static void WriteUInt64 (field_number, uint64 value, output); + static void WriteSInt32 (field_number, int32 value, output); + static void WriteSInt64 (field_number, int64 value, output); + static void WriteFixed32 (field_number, uint32 value, output); + static void WriteFixed64 (field_number, uint64 value, output); + static void WriteSFixed32(field_number, int32 value, output); + static void WriteSFixed64(field_number, int64 value, output); + static void WriteFloat (field_number, float value, output); + static void WriteDouble (field_number, double value, output); + static void WriteBool (field_number, bool value, output); + static void WriteEnum (field_number, int value, output); + + static void WriteString(field_number, const string& value, output); + static void WriteBytes (field_number, const string& value, output); + static void WriteStringMaybeAliased( + field_number, const string& value, output); + static void WriteBytesMaybeAliased( + field_number, const string& value, output); + + static void WriteGroup( + field_number, const MessageLite& value, output); + static void WriteMessage( + field_number, const MessageLite& value, output); + // Like above, but these will check if the output stream has enough + // space to write directly to a flat array. + static void WriteGroupMaybeToArray( + field_number, const MessageLite& value, output); + static void WriteMessageMaybeToArray( + field_number, const MessageLite& value, output); + + // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override SerializeWithCachedSizes()). + template + static inline void WriteGroupNoVirtual( + field_number, const MessageType& value, output); + template + static inline void WriteMessageNoVirtual( + field_number, const MessageType& value, output); + +#undef output +#define output uint8* target + + // Like above, but use only *ToArray methods of CodedOutputStream. + INL static uint8* WriteTagToArray(field_number, WireType type, output); + + // Write fields, without tags. + INL static uint8* WriteInt32NoTagToArray (int32 value, output); + INL static uint8* WriteInt64NoTagToArray (int64 value, output); + INL static uint8* WriteUInt32NoTagToArray (uint32 value, output); + INL static uint8* WriteUInt64NoTagToArray (uint64 value, output); + INL static uint8* WriteSInt32NoTagToArray (int32 value, output); + INL static uint8* WriteSInt64NoTagToArray (int64 value, output); + INL static uint8* WriteFixed32NoTagToArray (uint32 value, output); + INL static uint8* WriteFixed64NoTagToArray (uint64 value, output); + INL static uint8* WriteSFixed32NoTagToArray(int32 value, output); + INL static uint8* WriteSFixed64NoTagToArray(int64 value, output); + INL static uint8* WriteFloatNoTagToArray (float value, output); + INL static uint8* WriteDoubleNoTagToArray (double value, output); + INL static uint8* WriteBoolNoTagToArray (bool value, output); + INL static uint8* WriteEnumNoTagToArray (int value, output); + + // Write fields, including tags. + INL static uint8* WriteInt32ToArray(field_number, int32 value, output); + INL static uint8* WriteInt64ToArray(field_number, int64 value, output); + INL static uint8* WriteUInt32ToArray(field_number, uint32 value, output); + INL static uint8* WriteUInt64ToArray(field_number, uint64 value, output); + INL static uint8* WriteSInt32ToArray(field_number, int32 value, output); + INL static uint8* WriteSInt64ToArray(field_number, int64 value, output); + INL static uint8* WriteFixed32ToArray(field_number, uint32 value, output); + INL static uint8* WriteFixed64ToArray(field_number, uint64 value, output); + INL static uint8* WriteSFixed32ToArray(field_number, int32 value, output); + INL static uint8* WriteSFixed64ToArray(field_number, int64 value, output); + INL static uint8* WriteFloatToArray(field_number, float value, output); + INL static uint8* WriteDoubleToArray(field_number, double value, output); + INL static uint8* WriteBoolToArray(field_number, bool value, output); + INL static uint8* WriteEnumToArray(field_number, int value, output); + + INL static uint8* WriteStringToArray( + field_number, const string& value, output); + INL static uint8* WriteBytesToArray( + field_number, const string& value, output); + + // Whether to serialize deterministically (e.g., map keys are + // sorted) is a property of a CodedOutputStream, and in the process + // of serialization, the "ToArray" variants may be invoked. But they don't + // have a CodedOutputStream available, so they get an additional parameter + // telling them whether to serialize deterministically. + INL static uint8* InternalWriteGroupToArray( + field_number, const MessageLite& value, bool deterministic, output); + INL static uint8* InternalWriteMessageToArray( + field_number, const MessageLite& value, bool deterministic, output); + + // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override SerializeWithCachedSizes()). + template + INL static uint8* InternalWriteGroupNoVirtualToArray( + field_number, const MessageType& value, bool deterministic, output); + template + INL static uint8* InternalWriteMessageNoVirtualToArray( + field_number, const MessageType& value, bool deterministic, output); + + // For backward-compatibility, the last four methods also have versions + // that are non-deterministic always. + INL static uint8* WriteGroupToArray( + field_number, const MessageLite& value, output) { + return InternalWriteGroupToArray(field_number_arg, value, false, target); + } + INL static uint8* WriteMessageToArray( + field_number, const MessageLite& value, output) { + return InternalWriteMessageToArray(field_number_arg, value, false, target); + } + template + INL static uint8* WriteGroupNoVirtualToArray( + field_number, const MessageType& value, output) { + return InternalWriteGroupNoVirtualToArray(field_number_arg, value, false, + target); + } + template + INL static uint8* WriteMessageNoVirtualToArray( + field_number, const MessageType& value, output) { + return InternalWriteMessageNoVirtualToArray(field_number_arg, value, false, + target); + } + +#undef output +#undef input +#undef INL + +#undef field_number + + // Compute the byte size of a field. The XxSize() functions do NOT include + // the tag, so you must also call TagSize(). (This is because, for repeated + // fields, you should only call TagSize() once and multiply it by the element + // count, but you may have to call XxSize() for each individual element.) + static inline int Int32Size ( int32 value); + static inline int Int64Size ( int64 value); + static inline int UInt32Size (uint32 value); + static inline int UInt64Size (uint64 value); + static inline int SInt32Size ( int32 value); + static inline int SInt64Size ( int64 value); + static inline int EnumSize ( int value); + + // These types always have the same size. + static const int kFixed32Size = 4; + static const int kFixed64Size = 8; + static const int kSFixed32Size = 4; + static const int kSFixed64Size = 8; + static const int kFloatSize = 4; + static const int kDoubleSize = 8; + static const int kBoolSize = 1; + + static inline int StringSize(const string& value); + static inline int BytesSize (const string& value); + + static inline int GroupSize (const MessageLite& value); + static inline int MessageSize(const MessageLite& value); + + // Like above, but de-virtualize the call to ByteSize(). The + // pointer must point at an instance of MessageType, *not* a subclass (or + // the subclass must not override ByteSize()). + template + static inline int GroupSizeNoVirtual (const MessageType& value); + template + static inline int MessageSizeNoVirtual(const MessageType& value); + + // Given the length of data, calculate the byte size of the data on the + // wire if we encode the data as a length delimited field. + static inline int LengthDelimitedSize(int length); + + private: + // A helper method for the repeated primitive reader. This method has + // optimizations for primitive types that have fixed size on the wire, and + // can be read using potentially faster paths. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static bool ReadRepeatedFixedSizePrimitive( + int tag_size, + uint32 tag, + google::protobuf::io::CodedInputStream* input, + RepeatedField* value); + + // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields. + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static bool ReadPackedFixedSizePrimitive(google::protobuf::io::CodedInputStream* input, + RepeatedField* value); + + static const CppType kFieldTypeToCppTypeMap[]; + static const WireFormatLite::WireType kWireTypeForFieldType[]; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite); +}; + +// A class which deals with unknown values. The default implementation just +// discards them. WireFormat defines a subclass which writes to an +// UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since +// ExtensionSet is part of the lite library but UnknownFieldSet is not. +class LIBPROTOBUF_EXPORT FieldSkipper { + public: + FieldSkipper() {} + virtual ~FieldSkipper() {} + + // Skip a field whose tag has already been consumed. + virtual bool SkipField(io::CodedInputStream* input, uint32 tag); + + // Skip an entire message or group, up to an end-group tag (which is consumed) + // or end-of-stream. + virtual bool SkipMessage(io::CodedInputStream* input); + + // Deal with an already-parsed unrecognized enum value. The default + // implementation does nothing, but the UnknownFieldSet-based implementation + // saves it as an unknown varint. + virtual void SkipUnknownEnum(int field_number, int value); +}; + +// Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream. + +class LIBPROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper { + public: + explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields) + : unknown_fields_(unknown_fields) {} + virtual ~CodedOutputStreamFieldSkipper() {} + + // implements FieldSkipper ----------------------------------------- + virtual bool SkipField(io::CodedInputStream* input, uint32 tag); + virtual bool SkipMessage(io::CodedInputStream* input); + virtual void SkipUnknownEnum(int field_number, int value); + + protected: + io::CodedOutputStream* unknown_fields_; +}; + + +// inline methods ==================================================== + +inline WireFormatLite::CppType +WireFormatLite::FieldTypeToCppType(FieldType type) { + return kFieldTypeToCppTypeMap[type]; +} + +inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) { + return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); +} + +inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { + return static_cast(tag & kTagTypeMask); +} + +inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { + return static_cast(tag >> kTagTypeBits); +} + +inline int WireFormatLite::TagSize(int field_number, + WireFormatLite::FieldType type) { + int result = io::CodedOutputStream::VarintSize32( + field_number << kTagTypeBits); + if (type == TYPE_GROUP) { + // Groups have both a start and an end tag. + return result * 2; + } else { + return result; + } +} + +inline uint32 WireFormatLite::EncodeFloat(float value) { + union {float f; uint32 i;}; + f = value; + return i; +} + +inline float WireFormatLite::DecodeFloat(uint32 value) { + union {float f; uint32 i;}; + i = value; + return f; +} + +inline uint64 WireFormatLite::EncodeDouble(double value) { + union {double f; uint64 i;}; + f = value; + return i; +} + +inline double WireFormatLite::DecodeDouble(uint64 value) { + union {double f; uint64 i;}; + i = value; + return f; +} + +// ZigZag Transform: Encodes signed integers so that they can be +// effectively used with varint encoding. +// +// varint operates on unsigned integers, encoding smaller numbers into +// fewer bytes. If you try to use it on a signed integer, it will treat +// this number as a very large unsigned integer, which means that even +// small signed numbers like -1 will take the maximum number of bytes +// (10) to encode. ZigZagEncode() maps signed integers to unsigned +// in such a way that those with a small absolute value will have smaller +// encoded values, making them appropriate for encoding using varint. +// +// int32 -> uint32 +// ------------------------- +// 0 -> 0 +// -1 -> 1 +// 1 -> 2 +// -2 -> 3 +// ... -> ... +// 2147483647 -> 4294967294 +// -2147483648 -> 4294967295 +// +// >> encode >> +// << decode << + +inline uint32 WireFormatLite::ZigZagEncode32(int32 n) { + // Note: the right-shift must be arithmetic + return (static_cast(n) << 1) ^ (n >> 31); +} + +inline int32 WireFormatLite::ZigZagDecode32(uint32 n) { + return (n >> 1) ^ -static_cast(n & 1); +} + +inline uint64 WireFormatLite::ZigZagEncode64(int64 n) { + // Note: the right-shift must be arithmetic + return (static_cast(n) << 1) ^ (n >> 63); +} + +inline int64 WireFormatLite::ZigZagDecode64(uint64 n) { + return (n >> 1) ^ -static_cast(n & 1); +} + +// String is for UTF-8 text only, but, even so, ReadString() can simply +// call ReadBytes(). + +inline bool WireFormatLite::ReadString(io::CodedInputStream* input, + string* value) { + return ReadBytes(input, value); +} + +inline bool WireFormatLite::ReadString(io::CodedInputStream* input, + string** p) { + return ReadBytes(input, p); +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ diff --git a/thirdparty/linux/include/google/protobuf/wire_format_lite_inl.h b/thirdparty/linux/include/google/protobuf/wire_format_lite_inl.h new file mode 100644 index 0000000..93d7c82 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/wire_format_lite_inl.h @@ -0,0 +1,876 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// wink@google.com (Wink Saville) (refactored from wire_format.h) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ +#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ + +#ifdef _MSC_VER +// This is required for min/max on VS2013 only. +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace internal { + +// Implementation details of ReadPrimitive. + +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = static_cast(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + uint32* value) { + return input->ReadVarint32(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + uint64* value) { + return input->ReadVarint64(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = ZigZagDecode32(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = ZigZagDecode64(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + uint32* value) { + return input->ReadLittleEndian32(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + uint64* value) { + return input->ReadLittleEndian64(value); +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int32* value) { + uint32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = static_cast(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int64* value) { + uint64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = static_cast(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + float* value) { + uint32 temp; + if (!input->ReadLittleEndian32(&temp)) return false; + *value = DecodeFloat(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + double* value) { + uint64 temp; + if (!input->ReadLittleEndian64(&temp)) return false; + *value = DecodeDouble(temp); + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + bool* value) { + uint64 temp; + if (!input->ReadVarint64(&temp)) return false; + *value = temp != 0; + return true; +} +template <> +inline bool WireFormatLite::ReadPrimitive( + io::CodedInputStream* input, + int* value) { + uint32 temp; + if (!input->ReadVarint32(&temp)) return false; + *value = static_cast(temp); + return true; +} + +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + uint32, WireFormatLite::TYPE_FIXED32>( + const uint8* buffer, + uint32* value) { + return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + uint64, WireFormatLite::TYPE_FIXED64>( + const uint8* buffer, + uint64* value) { + return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + int32, WireFormatLite::TYPE_SFIXED32>( + const uint8* buffer, + int32* value) { + uint32 temp; + buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); + *value = static_cast(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + int64, WireFormatLite::TYPE_SFIXED64>( + const uint8* buffer, + int64* value) { + uint64 temp; + buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); + *value = static_cast(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + float, WireFormatLite::TYPE_FLOAT>( + const uint8* buffer, + float* value) { + uint32 temp; + buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); + *value = DecodeFloat(temp); + return buffer; +} +template <> +inline const uint8* WireFormatLite::ReadPrimitiveFromArray< + double, WireFormatLite::TYPE_DOUBLE>( + const uint8* buffer, + double* value) { + uint64 temp; + buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); + *value = DecodeDouble(temp); + return buffer; +} + +template +inline bool WireFormatLite::ReadRepeatedPrimitive( + int, // tag_size, unused. + uint32 tag, + io::CodedInputStream* input, + RepeatedField* values) { + CType value; + if (!ReadPrimitive(input, &value)) return false; + values->Add(value); + int elements_already_reserved = values->Capacity() - values->size(); + while (elements_already_reserved > 0 && input->ExpectTag(tag)) { + if (!ReadPrimitive(input, &value)) return false; + values->AddAlreadyReserved(value); + elements_already_reserved--; + } + return true; +} + +template +inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( + int tag_size, + uint32 tag, + io::CodedInputStream* input, + RepeatedField* values) { + GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size); + CType value; + if (!ReadPrimitive(input, &value)) + return false; + values->Add(value); + + // For fixed size values, repeated values can be read more quickly by + // reading directly from a raw array. + // + // We can get a tight loop by only reading as many elements as can be + // added to the RepeatedField without having to do any resizing. Additionally, + // we only try to read as many elements as are available from the current + // buffer space. Doing so avoids having to perform boundary checks when + // reading the value: the maximum number of elements that can be read is + // known outside of the loop. + const void* void_pointer; + int size; + input->GetDirectBufferPointerInline(&void_pointer, &size); + if (size > 0) { + const uint8* buffer = reinterpret_cast(void_pointer); + // The number of bytes each type occupies on the wire. + const int per_value_size = tag_size + sizeof(value); + + int elements_available = + std::min(values->Capacity() - values->size(), size / per_value_size); + int num_read = 0; + while (num_read < elements_available && + (buffer = io::CodedInputStream::ExpectTagFromArray( + buffer, tag)) != NULL) { + buffer = ReadPrimitiveFromArray(buffer, &value); + values->AddAlreadyReserved(value); + ++num_read; + } + const int read_bytes = num_read * per_value_size; + if (read_bytes > 0) { + input->Skip(read_bytes); + } + } + return true; +} + +// Specializations of ReadRepeatedPrimitive for the fixed size types, which use +// the optimized code path. +#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ +template <> \ +inline bool WireFormatLite::ReadRepeatedPrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + int tag_size, \ + uint32 tag, \ + io::CodedInputStream* input, \ + RepeatedField* values) { \ + return ReadRepeatedFixedSizePrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + tag_size, tag, input, values); \ +} + +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) +READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) + +#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE + +template +bool WireFormatLite::ReadRepeatedPrimitiveNoInline( + int tag_size, + uint32 tag, + io::CodedInputStream* input, + RepeatedField* value) { + return ReadRepeatedPrimitive( + tag_size, tag, input, value); +} + +template +inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, + RepeatedField* values) { + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + CType value; + if (!ReadPrimitive(input, &value)) return false; + values->Add(value); + } + input->PopLimit(limit); + return true; +} + +template +inline bool WireFormatLite::ReadPackedFixedSizePrimitive( + io::CodedInputStream* input, RepeatedField* values) { + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; + const int old_entries = values->size(); + const int new_entries = length / sizeof(CType); + const int new_bytes = new_entries * sizeof(CType); + if (new_bytes != length) return false; + // We would *like* to pre-allocate the buffer to write into (for + // speed), but *must* avoid performing a very large allocation due + // to a malicious user-supplied "length" above. So we have a fast + // path that pre-allocates when the "length" is less than a bound. + // We determine the bound by calling BytesUntilTotalBytesLimit() and + // BytesUntilLimit(). These return -1 to mean "no limit set". + // There are four cases: + // TotalBytesLimit Limit + // -1 -1 Use slow path. + // -1 >= 0 Use fast path if length <= Limit. + // >= 0 -1 Use slow path. + // >= 0 >= 0 Use fast path if length <= min(both limits). + int64 bytes_limit = input->BytesUntilTotalBytesLimit(); + if (bytes_limit == -1) { + bytes_limit = input->BytesUntilLimit(); + } else { + bytes_limit = + std::min(bytes_limit, static_cast(input->BytesUntilLimit())); + } + if (bytes_limit >= new_bytes) { + // Fast-path that pre-allocates *values to the final size. +#if defined(PROTOBUF_LITTLE_ENDIAN) + values->Resize(old_entries + new_entries, 0); + // values->mutable_data() may change after Resize(), so do this after: + void* dest = reinterpret_cast(values->mutable_data() + old_entries); + if (!input->ReadRaw(dest, new_bytes)) { + values->Truncate(old_entries); + return false; + } +#else + values->Reserve(old_entries + new_entries); + CType value; + for (int i = 0; i < new_entries; ++i) { + if (!ReadPrimitive(input, &value)) return false; + values->AddAlreadyReserved(value); + } +#endif + } else { + // This is the slow-path case where "length" may be too large to + // safely allocate. We read as much as we can into *values + // without pre-allocating "length" bytes. + CType value; + for (int i = 0; i < new_entries; ++i) { + if (!ReadPrimitive(input, &value)) return false; + values->Add(value); + } + } + return true; +} + +// Specializations of ReadPackedPrimitive for the fixed size types, which use +// an optimized code path. +#define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ +template <> \ +inline bool WireFormatLite::ReadPackedPrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ + io::CodedInputStream* input, \ + RepeatedField* values) { \ + return ReadPackedFixedSizePrimitive< \ + CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values); \ +} + +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) +READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) + +#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE + +template +bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, + RepeatedField* values) { + return ReadPackedPrimitive(input, values); +} + + + +inline bool WireFormatLite::ReadGroup(int field_number, + io::CodedInputStream* input, + MessageLite* value) { + if (!input->IncrementRecursionDepth()) return false; + if (!value->MergePartialFromCodedStream(input)) return false; + input->DecrementRecursionDepth(); + // Make sure the last thing read was an end tag for this group. + if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { + return false; + } + return true; +} +inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, + MessageLite* value) { + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; + std::pair p = + input->IncrementRecursionDepthAndPushLimit(length); + if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + return input->DecrementRecursionDepthAndPopLimit(p.first); +} + +// We name the template parameter something long and extremely unlikely to occur +// elsewhere because a *qualified* member access expression designed to avoid +// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the +// name of the qualifying class to be looked up both in the context of the full +// expression (finding the template parameter) and in the context of the object +// whose member we are accessing. This could potentially find a nested type +// within that object. The standard goes on to require these names to refer to +// the same entity, which this collision would violate. The lack of a safe way +// to avoid this collision appears to be a defect in the standard, but until it +// is corrected, we choose the name to avoid accidental collisions. +template +inline bool WireFormatLite::ReadGroupNoVirtual( + int field_number, io::CodedInputStream* input, + MessageType_WorkAroundCppLookupDefect* value) { + if (!input->IncrementRecursionDepth()) return false; + if (!value-> + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) + return false; + input->UnsafeDecrementRecursionDepth(); + // Make sure the last thing read was an end tag for this group. + if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { + return false; + } + return true; +} +template +inline bool WireFormatLite::ReadGroupNoVirtualNoRecursionDepth( + int field_number, io::CodedInputStream* input, + MessageType_WorkAroundCppLookupDefect* value) { + return value->MessageType_WorkAroundCppLookupDefect:: + MergePartialFromCodedStream(input) && + input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP)); +} +template +inline bool WireFormatLite::ReadMessageNoVirtual( + io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { + int length; + if (!input->ReadVarintSizeAsInt(&length)) return false; + std::pair p = + input->IncrementRecursionDepthAndPushLimit(length); + if (p.second < 0 || !value-> + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) + return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + return input->DecrementRecursionDepthAndPopLimit(p.first); +} +template +inline bool WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { + io::CodedInputStream::Limit old_limit = input->ReadLengthAndPushLimit(); + if (!value-> + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) + return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + return input->CheckEntireMessageConsumedAndPopLimit(old_limit); +} + +// =================================================================== + +inline void WireFormatLite::WriteTag(int field_number, WireType type, + io::CodedOutputStream* output) { + output->WriteTag(MakeTag(field_number, type)); +} + +inline void WireFormatLite::WriteInt32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteVarint32SignExtended(value); +} +inline void WireFormatLite::WriteInt64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(static_cast(value)); +} +inline void WireFormatLite::WriteUInt32NoTag(uint32 value, + io::CodedOutputStream* output) { + output->WriteVarint32(value); +} +inline void WireFormatLite::WriteUInt64NoTag(uint64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(value); +} +inline void WireFormatLite::WriteSInt32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteVarint32(ZigZagEncode32(value)); +} +inline void WireFormatLite::WriteSInt64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteVarint64(ZigZagEncode64(value)); +} +inline void WireFormatLite::WriteFixed32NoTag(uint32 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(value); +} +inline void WireFormatLite::WriteFixed64NoTag(uint64 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(value); +} +inline void WireFormatLite::WriteSFixed32NoTag(int32 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(static_cast(value)); +} +inline void WireFormatLite::WriteSFixed64NoTag(int64 value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(static_cast(value)); +} +inline void WireFormatLite::WriteFloatNoTag(float value, + io::CodedOutputStream* output) { + output->WriteLittleEndian32(EncodeFloat(value)); +} +inline void WireFormatLite::WriteDoubleNoTag(double value, + io::CodedOutputStream* output) { + output->WriteLittleEndian64(EncodeDouble(value)); +} +inline void WireFormatLite::WriteBoolNoTag(bool value, + io::CodedOutputStream* output) { + output->WriteVarint32(value ? 1 : 0); +} +inline void WireFormatLite::WriteEnumNoTag(int value, + io::CodedOutputStream* output) { + output->WriteVarint32SignExtended(value); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template +inline void WireFormatLite::WriteGroupNoVirtual( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_START_GROUP, output); + value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); + WriteTag(field_number, WIRETYPE_END_GROUP, output); +} +template +inline void WireFormatLite::WriteMessageNoVirtual( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + io::CodedOutputStream* output) { + WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32( + value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()); + value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); +} + +// =================================================================== + +inline uint8* WireFormatLite::WriteTagToArray(int field_number, + WireType type, + uint8* target) { + return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), + target); +} + +inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); +} +inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), + target); +} +inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), + target); +} +inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray( + static_cast(value), target); +} +inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), + target); +} +inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, + uint8* target) { + return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), + target); +} +inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); +} +inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, + uint8* target) { + return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); +} + +inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, + uint32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteUInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, + uint64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteUInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteSInt32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteSInt64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number, + uint32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteFixed32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number, + uint64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteFixed64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number, + int32 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteSFixed32NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number, + int64 value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteSFixed64NoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteFloatToArray(int field_number, + float value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); + return WriteFloatNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, + double value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); + return WriteDoubleNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteBoolToArray(int field_number, + bool value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteBoolNoTagToArray(value, target); +} +inline uint8* WireFormatLite::WriteEnumToArray(int field_number, + int value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); + return WriteEnumNoTagToArray(value, target); +} + +inline uint8* WireFormatLite::WriteStringToArray(int field_number, + const string& value, + uint8* target) { + // String is for UTF-8 text only + // WARNING: In wire_format.cc, both strings and bytes are handled by + // WriteString() to avoid code duplication. If the implementations become + // different, you will need to update that usage. + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); +} +inline uint8* WireFormatLite::WriteBytesToArray(int field_number, + const string& value, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); +} + + +inline uint8* WireFormatLite::InternalWriteGroupToArray( + int field_number, const MessageLite& value, bool deterministic, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); + target = value.InternalSerializeWithCachedSizesToArray(deterministic, target); + return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); +} +inline uint8* WireFormatLite::InternalWriteMessageToArray( + int field_number, const MessageLite& value, bool deterministic, + uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + value.GetCachedSize(), target); + return value.InternalSerializeWithCachedSizesToArray(deterministic, target); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template +inline uint8* WireFormatLite::InternalWriteGroupNoVirtualToArray( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + bool deterministic, uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); + target = value.InternalSerializeWithCachedSizesToArray(deterministic, target); + return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); +} +template +inline uint8* WireFormatLite::InternalWriteMessageNoVirtualToArray( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + bool deterministic, uint8* target) { + target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); + target = io::CodedOutputStream::WriteVarint32ToArray( + value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target); + return value.InternalSerializeWithCachedSizesToArray(deterministic, target); +} + +// =================================================================== + +inline int WireFormatLite::Int32Size(int32 value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} +inline int WireFormatLite::Int64Size(int64 value) { + return io::CodedOutputStream::VarintSize64(static_cast(value)); +} +inline int WireFormatLite::UInt32Size(uint32 value) { + return io::CodedOutputStream::VarintSize32(value); +} +inline int WireFormatLite::UInt64Size(uint64 value) { + return io::CodedOutputStream::VarintSize64(value); +} +inline int WireFormatLite::SInt32Size(int32 value) { + return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); +} +inline int WireFormatLite::SInt64Size(int64 value) { + return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); +} +inline int WireFormatLite::EnumSize(int value) { + return io::CodedOutputStream::VarintSize32SignExtended(value); +} + +inline int WireFormatLite::StringSize(const string& value) { + return static_cast( + io::CodedOutputStream::VarintSize32(static_cast(value.size())) + + value.size()); +} +inline int WireFormatLite::BytesSize(const string& value) { + return static_cast( + io::CodedOutputStream::VarintSize32(static_cast(value.size())) + + value.size()); +} + + +inline int WireFormatLite::GroupSize(const MessageLite& value) { + return value.ByteSize(); +} +inline int WireFormatLite::MessageSize(const MessageLite& value) { + return LengthDelimitedSize(value.ByteSize()); +} + +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template +inline int WireFormatLite::GroupSizeNoVirtual( + const MessageType_WorkAroundCppLookupDefect& value) { + return value.MessageType_WorkAroundCppLookupDefect::ByteSize(); +} +template +inline int WireFormatLite::MessageSizeNoVirtual( + const MessageType_WorkAroundCppLookupDefect& value) { + return LengthDelimitedSize( + value.MessageType_WorkAroundCppLookupDefect::ByteSize()); +} + +inline int WireFormatLite::LengthDelimitedSize(int length) { + return io::CodedOutputStream::VarintSize32(length) + length; +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ diff --git a/thirdparty/linux/include/google/protobuf/wrappers.pb.h b/thirdparty/linux/include/google/protobuf/wrappers.pb.h new file mode 100644 index 0000000..73f8ff6 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/wrappers.pb.h @@ -0,0 +1,1216 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/wrappers.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fwrappers_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fwrappers_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + +class BoolValue; +class BytesValue; +class DoubleValue; +class FloatValue; +class Int32Value; +class Int64Value; +class StringValue; +class UInt32Value; +class UInt64Value; + +// =================================================================== + +class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DoubleValue) */ { + public: + DoubleValue(); + virtual ~DoubleValue(); + + DoubleValue(const DoubleValue& from); + + inline DoubleValue& operator=(const DoubleValue& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const DoubleValue& default_instance(); + + void UnsafeArenaSwap(DoubleValue* other); + void Swap(DoubleValue* other); + + // implements Message ---------------------------------------------- + + inline DoubleValue* New() const { return New(NULL); } + + DoubleValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DoubleValue& from); + void MergeFrom(const DoubleValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(DoubleValue* other); + protected: + explicit DoubleValue(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional double value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + double value() const; + void set_value(double value); + + // @@protoc_insertion_point(class_scope:google.protobuf.DoubleValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + double value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static DoubleValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FloatValue) */ { + public: + FloatValue(); + virtual ~FloatValue(); + + FloatValue(const FloatValue& from); + + inline FloatValue& operator=(const FloatValue& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const FloatValue& default_instance(); + + void UnsafeArenaSwap(FloatValue* other); + void Swap(FloatValue* other); + + // implements Message ---------------------------------------------- + + inline FloatValue* New() const { return New(NULL); } + + FloatValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FloatValue& from); + void MergeFrom(const FloatValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FloatValue* other); + protected: + explicit FloatValue(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional float value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + float value() const; + void set_value(float value); + + // @@protoc_insertion_point(class_scope:google.protobuf.FloatValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + float value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static FloatValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int64Value) */ { + public: + Int64Value(); + virtual ~Int64Value(); + + Int64Value(const Int64Value& from); + + inline Int64Value& operator=(const Int64Value& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const Int64Value& default_instance(); + + void UnsafeArenaSwap(Int64Value* other); + void Swap(Int64Value* other); + + // implements Message ---------------------------------------------- + + inline Int64Value* New() const { return New(NULL); } + + Int64Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Int64Value& from); + void MergeFrom(const Int64Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Int64Value* other); + protected: + explicit Int64Value(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + ::google::protobuf::int64 value() const; + void set_value(::google::protobuf::int64 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Int64Value) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + ::google::protobuf::int64 value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static Int64Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt64Value) */ { + public: + UInt64Value(); + virtual ~UInt64Value(); + + UInt64Value(const UInt64Value& from); + + inline UInt64Value& operator=(const UInt64Value& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const UInt64Value& default_instance(); + + void UnsafeArenaSwap(UInt64Value* other); + void Swap(UInt64Value* other); + + // implements Message ---------------------------------------------- + + inline UInt64Value* New() const { return New(NULL); } + + UInt64Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UInt64Value& from); + void MergeFrom(const UInt64Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(UInt64Value* other); + protected: + explicit UInt64Value(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional uint64 value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + ::google::protobuf::uint64 value() const; + void set_value(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.UInt64Value) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + ::google::protobuf::uint64 value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static UInt64Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int32Value) */ { + public: + Int32Value(); + virtual ~Int32Value(); + + Int32Value(const Int32Value& from); + + inline Int32Value& operator=(const Int32Value& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const Int32Value& default_instance(); + + void UnsafeArenaSwap(Int32Value* other); + void Swap(Int32Value* other); + + // implements Message ---------------------------------------------- + + inline Int32Value* New() const { return New(NULL); } + + Int32Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Int32Value& from); + void MergeFrom(const Int32Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Int32Value* other); + protected: + explicit Int32Value(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + ::google::protobuf::int32 value() const; + void set_value(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Int32Value) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + ::google::protobuf::int32 value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static Int32Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt32Value) */ { + public: + UInt32Value(); + virtual ~UInt32Value(); + + UInt32Value(const UInt32Value& from); + + inline UInt32Value& operator=(const UInt32Value& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const UInt32Value& default_instance(); + + void UnsafeArenaSwap(UInt32Value* other); + void Swap(UInt32Value* other); + + // implements Message ---------------------------------------------- + + inline UInt32Value* New() const { return New(NULL); } + + UInt32Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UInt32Value& from); + void MergeFrom(const UInt32Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(UInt32Value* other); + protected: + explicit UInt32Value(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional uint32 value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + ::google::protobuf::uint32 value() const; + void set_value(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.UInt32Value) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + ::google::protobuf::uint32 value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static UInt32Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BoolValue) */ { + public: + BoolValue(); + virtual ~BoolValue(); + + BoolValue(const BoolValue& from); + + inline BoolValue& operator=(const BoolValue& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const BoolValue& default_instance(); + + void UnsafeArenaSwap(BoolValue* other); + void Swap(BoolValue* other); + + // implements Message ---------------------------------------------- + + inline BoolValue* New() const { return New(NULL); } + + BoolValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BoolValue& from); + void MergeFrom(const BoolValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BoolValue* other); + protected: + explicit BoolValue(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + bool value() const; + void set_value(bool value); + + // @@protoc_insertion_point(class_scope:google.protobuf.BoolValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + bool value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static BoolValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.StringValue) */ { + public: + StringValue(); + virtual ~StringValue(); + + StringValue(const StringValue& from); + + inline StringValue& operator=(const StringValue& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const StringValue& default_instance(); + + void UnsafeArenaSwap(StringValue* other); + void Swap(StringValue* other); + + // implements Message ---------------------------------------------- + + inline StringValue* New() const { return New(NULL); } + + StringValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const StringValue& from); + void MergeFrom(const StringValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(StringValue* other); + protected: + explicit StringValue(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const char* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + ::std::string* unsafe_arena_release_value(); + void unsafe_arena_set_allocated_value( + ::std::string* value); + + // @@protoc_insertion_point(class_scope:google.protobuf.StringValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static StringValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BytesValue) */ { + public: + BytesValue(); + virtual ~BytesValue(); + + BytesValue(const BytesValue& from); + + inline BytesValue& operator=(const BytesValue& from) { + CopyFrom(from); + return *this; + } + + inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } + inline void* GetMaybeArenaPointer() const { + return MaybeArenaPtr(); + } + static const ::google::protobuf::Descriptor* descriptor(); + static const BytesValue& default_instance(); + + void UnsafeArenaSwap(BytesValue* other); + void Swap(BytesValue* other); + + // implements Message ---------------------------------------------- + + inline BytesValue* New() const { return New(NULL); } + + BytesValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BytesValue& from); + void MergeFrom(const BytesValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BytesValue* other); + protected: + explicit BytesValue(::google::protobuf::Arena* arena); + private: + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::google::protobuf::Arena* arena); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bytes value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const void* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + ::std::string* unsafe_arena_release_value(); + void unsafe_arena_set_allocated_value( + ::std::string* value); + + // @@protoc_insertion_point(class_scope:google.protobuf.BytesValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static BytesValue* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// DoubleValue + +// optional double value = 1; +inline void DoubleValue::clear_value() { + value_ = 0; +} +inline double DoubleValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.DoubleValue.value) + return value_; +} +inline void DoubleValue::set_value(double value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DoubleValue.value) +} + +// ------------------------------------------------------------------- + +// FloatValue + +// optional float value = 1; +inline void FloatValue::clear_value() { + value_ = 0; +} +inline float FloatValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.FloatValue.value) + return value_; +} +inline void FloatValue::set_value(float value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FloatValue.value) +} + +// ------------------------------------------------------------------- + +// Int64Value + +// optional int64 value = 1; +inline void Int64Value::clear_value() { + value_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 Int64Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Int64Value.value) + return value_; +} +inline void Int64Value::set_value(::google::protobuf::int64 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Int64Value.value) +} + +// ------------------------------------------------------------------- + +// UInt64Value + +// optional uint64 value = 1; +inline void UInt64Value::clear_value() { + value_ = GOOGLE_ULONGLONG(0); +} +inline ::google::protobuf::uint64 UInt64Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UInt64Value.value) + return value_; +} +inline void UInt64Value::set_value(::google::protobuf::uint64 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UInt64Value.value) +} + +// ------------------------------------------------------------------- + +// Int32Value + +// optional int32 value = 1; +inline void Int32Value::clear_value() { + value_ = 0; +} +inline ::google::protobuf::int32 Int32Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Int32Value.value) + return value_; +} +inline void Int32Value::set_value(::google::protobuf::int32 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Int32Value.value) +} + +// ------------------------------------------------------------------- + +// UInt32Value + +// optional uint32 value = 1; +inline void UInt32Value::clear_value() { + value_ = 0u; +} +inline ::google::protobuf::uint32 UInt32Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UInt32Value.value) + return value_; +} +inline void UInt32Value::set_value(::google::protobuf::uint32 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UInt32Value.value) +} + +// ------------------------------------------------------------------- + +// BoolValue + +// optional bool value = 1; +inline void BoolValue::clear_value() { + value_ = false; +} +inline bool BoolValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.BoolValue.value) + return value_; +} +inline void BoolValue::set_value(bool value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.BoolValue.value) +} + +// ------------------------------------------------------------------- + +// StringValue + +// optional string value = 1; +inline void StringValue::clear_value() { + value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); +} +inline const ::std::string& StringValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.StringValue.value) + return value_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void StringValue::set_value(const ::std::string& value) { + + value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value) +} +inline void StringValue::set_value(const char* value) { + + value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), + GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_char:google.protobuf.StringValue.value) +} +inline void StringValue::set_value(const char* value, + size_t size) { + + value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string( + reinterpret_cast(value), size), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.StringValue.value) +} +inline ::std::string* StringValue::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.StringValue.value) + return value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); +} +inline ::std::string* StringValue::release_value() { + // @@protoc_insertion_point(field_release:google.protobuf.StringValue.value) + + return value_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); +} +inline ::std::string* StringValue::unsafe_arena_release_value() { + // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.StringValue.value) + GOOGLE_DCHECK(GetArenaNoVirtual() != NULL); + + return value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); +} +inline void StringValue::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, + GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.StringValue.value) +} +inline void StringValue::unsafe_arena_set_allocated_value( + ::std::string* value) { + GOOGLE_DCHECK(GetArenaNoVirtual() != NULL); + if (value != NULL) { + + } else { + + } + value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + value, GetArenaNoVirtual()); + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.StringValue.value) +} + +// ------------------------------------------------------------------- + +// BytesValue + +// optional bytes value = 1; +inline void BytesValue::clear_value() { + value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); +} +inline const ::std::string& BytesValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.BytesValue.value) + return value_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void BytesValue::set_value(const ::std::string& value) { + + value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value) +} +inline void BytesValue::set_value(const char* value) { + + value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), + GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_char:google.protobuf.BytesValue.value) +} +inline void BytesValue::set_value(const void* value, + size_t size) { + + value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string( + reinterpret_cast(value), size), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.BytesValue.value) +} +inline ::std::string* BytesValue::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.BytesValue.value) + return value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); +} +inline ::std::string* BytesValue::release_value() { + // @@protoc_insertion_point(field_release:google.protobuf.BytesValue.value) + + return value_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); +} +inline ::std::string* BytesValue::unsafe_arena_release_value() { + // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.BytesValue.value) + GOOGLE_DCHECK(GetArenaNoVirtual() != NULL); + + return value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); +} +inline void BytesValue::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, + GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.BytesValue.value) +} +inline void BytesValue::unsafe_arena_set_allocated_value( + ::std::string* value) { + GOOGLE_DCHECK(GetArenaNoVirtual() != NULL); + if (value != NULL) { + + } else { + + } + value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + value, GetArenaNoVirtual()); + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.BytesValue.value) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fwrappers_2eproto__INCLUDED diff --git a/thirdparty/linux/include/google/protobuf/wrappers.proto b/thirdparty/linux/include/google/protobuf/wrappers.proto new file mode 100644 index 0000000..4828ad9 --- /dev/null +++ b/thirdparty/linux/include/google/protobuf/wrappers.proto @@ -0,0 +1,119 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/wrappers"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "WrappersProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; +option objc_class_prefix = "GPB"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +message BytesValue { + // The bytes value. + bytes value = 1; +} diff --git a/thirdparty/linux/include/minotaur/AMPLHessian.h b/thirdparty/linux/include/minotaur/AMPLHessian.h new file mode 100644 index 0000000..050e644 --- /dev/null +++ b/thirdparty/linux/include/minotaur/AMPLHessian.h @@ -0,0 +1,99 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file AMPLHessian.h + * \brief Declare the AMPLHessian class for extracting Hessian of Lagrangian + * from AMPL. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURAMPLHESSIAN_H +#define MINOTAURAMPLHESSIAN_H + +#include "asl.h" + +#include "HessianOfLag.h" + +namespace MINOTAUR_AMPL { +class AMPLInterface; +typedef AMPLInterface * AMPLInterfacePtr; + +/** + * \brief AMPLHessian class has methods to call Hessian of Lagrangian evaluation + * routines of AMPL. This class is not meant to calculate Hessian of native + * Minotaur functions. + */ +class AMPLHessian : public Minotaur::HessianOfLag { +public: + /** + * \brief Construct AMPLHessian using an AMPL(ASL) interface. + * \param[in] iface Pointer to AMPLInterface class from which we read the + * instance. + */ + AMPLHessian(AMPLInterfacePtr iface); + + /// Destroy. + ~AMPLHessian(); + + /// Return the number of non-zeros in the Hessian of Lagrangian. + Minotaur::UInt getNumNz() const; + + /** + * \brief Fill in row and column indices of nonzeros in Hessian of + * Lagrangian. + * + * Given arrays irow and jcol, fill in the row and column index of each + * non-zero in the Hessian of Lagrangian. The entries are ordered by + * rows. + * \param [out] jcol Array of size returned by getNumNz(). + * \param [out] irow Array of size returned by getNumNz(). + */ + void fillRowColIndices(Minotaur::UInt *iRow, Minotaur::UInt *jCol); + + /** + * \brief Evaluate Hessian of Lagrangian at a given point x, row-wise. + * \param[in] x The point at which Hessian of Lagrangian is to be evaluated. + * \param[in] obj_mult The multiplier for the objective. + * \param[in] con_mult Array of multipliers for constraints. + * \param[out] values The array of size returned by getNumNz() into which + * values are saved. + * \param[out] error is set to a nonzero value if a problem is encountered, + * otherwise it is left undisturbed. + */ + void fillRowColValues(const double *x, double obj_mult, const double + *con_mult, double *values, int *error); + + /// Ugly hack for maximization problems. + void negateObj(); + +private: + /// Pointer to the AMPL's asl. + ASL *myAsl_; + + /// No. of nonzeros in Hessian of Lagrangian. Initialized in the constructor. + Minotaur::UInt nNz_; + + /// Size of tmp_ array. + bool negObj_; +}; +typedef boost::shared_ptr AMPLHessianPtr; +} + + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: + diff --git a/thirdparty/linux/include/minotaur/AMPLInterface.h b/thirdparty/linux/include/minotaur/AMPLInterface.h new file mode 100644 index 0000000..8ded592 --- /dev/null +++ b/thirdparty/linux/include/minotaur/AMPLInterface.h @@ -0,0 +1,359 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file AMPLInterface.h + * \brief Declare the AMPLInterface class fo reading problems from AMPL. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURAMPLINTERFACE_H +#define MINOTAURAMPLINTERFACE_H + +#include "Types.h" + +#include "asl.h" +#include "nlp.h" +//#undef filename + +namespace Minotaur { +class CGraph; +class CNode; +class Environment; +class LinearFunction; +class PolynomialFunction; +class Problem; +class QuadraticFunction; +class Solution; +typedef boost::shared_ptr CGraphPtr; +typedef boost::shared_ptr EnvironmentPtr; +typedef boost::shared_ptr LinearFunctionPtr; +typedef boost::shared_ptr PolyFunPtr; +typedef boost::shared_ptr ProblemPtr; +typedef boost::shared_ptr QuadraticFunctionPtr; +typedef boost::shared_ptr ConstSolutionPtr; +} + +namespace MINOTAUR_AMPL { + +class AMPLNonlinearFunction; +typedef boost::shared_ptr AMPLNlfPtr; + +/// What kind of ASL reader is used to read the .nl file. +typedef enum { + FReader, /// No derivatives, linear objective and constraints only. + FGReader, /// first derivatives. This reader will be used to read the + /// expression tree. + FGHReader, /// First derivatives and Hessian-vector products. Need a + /// loop for computing full hessian. + PFGReader, /// First derivatives and partially separable structure. + PFGHReader /// First and second derivatives and partially separable + /// structure. Can compute full hessian. This reader is used + /// when NLPs are solved by calling ASL's evaluation routines. +} ReaderType; + + +class AMPLInterface; +typedef AMPLInterface * AMPLInterfacePtr; + + +// ------------------------------------------------------------------------ // +// ------------------------------------------------------------------------ // + +/** + * \brief Interface to read ampl models using AMPL Solver Library. + * AMPLInterface class provides methods to read and evaluate an instance + * from AMPL generated .nl files. It also provides methods to evaluate + * functions, gradients, jacobians and hessians. + */ +class AMPLInterface { +public: + /// Constructor. + AMPLInterface(Minotaur::EnvPtr env, std::string solver="minotaurampl"); + + /// Destroy. + ~AMPLInterface(); + + /// Free the ASL data structure myAsl_; + void freeASL(); + + /// Get pointer to the ASL structure myAsl_ + ASL * getAsl(); + + /// Get the initial point provided in the .nl file + const double * getInitialPoint() const; + + /// Get the number of defined variables. + Minotaur::UInt getNumDefs() const; + + /// What kind of reader from ASL was used to read the .nl file. + ReaderType getReaderType(); + + /// Read an instance from a .nl file 'fname'. + Minotaur::ProblemPtr readInstance(std::string fname); + + /// Write the solution to the AMPL acceptable .sol file. + void writeSolution(Minotaur::ConstSolutionPtr sol, + Minotaur::SolveStatus status); + + void writeProblem(std::ostream &out) const; +private: + /// Log manager + Minotaur::EnvPtr env_; + + /** + * A map describing what kind of an AMPL OPCODE a given function has. + * See comments for createFunctionMap_(). + */ + std::map functionMap_; + + /// Tolerance to check integrality (of powers for example). + const double intTol_; + + /// Log manager + Minotaur::LoggerPtr logger_; + + /// For logging. + static const std::string me_; + + /// Pointer to ASL. + ASL *myAsl_; + + /// Number of constraints. Needs to be stored for jacobian evaluations. + int nCons_; + + /** + * The number of defied variables. AMPL stores the number of 5 kinds of + * defined variables: + * ncomo = number of defined variables in more than one objectives only + * ncomc = number of defined variables in more than one constraints only + * ncomb = number of defined variables in both objectives and constraints + * ncomo1 = number of defined variables in only one objective + * ncomc1 = number of defined variables in only one constraint. + */ + int nDefVars_; + + /// ncomo+ncomc+ncomb + int nDefVarsBco_; + + /// ncomo1+ncomc1 + int nDefVarsCo1_; + + /** + * Total number of variables. It does not include the number of "defined + * variables" or common expressions. + */ + int nVars_; + + /// Reader that was used to read the .nl file. + ReaderType readerType_; + + /// A vector of variables that are in this instance. + std::vector vars_; + + /// Tolerance to check if zero. + const double zTol_; + + /// Add 'defined variables', i.e., variables for common-expressions. + void addDefinedVars_(Minotaur::ProblemPtr instance); + + /// Add the i-th linear constraint from ASL. + void addLinearConstraint_(int i, Minotaur::ProblemPtr problemPtr); + + /// Add the i-th linear objective from ASL. + void addLinearObjective_(int i, Minotaur::ProblemPtr problemPtr); + + /** + * Get linear terms in the i-th constraint and put them into lf. If lf + * is NULL, new space is allocated. + */ + void addLinearTermsFromConstr_(Minotaur::LinearFunctionPtr &lf, int i); + + /** + * Get linear terms in the i-th objective and put them into lf. If lf + * is NULL, new space is allocated. + */ + void addLinearTermsFromObj_(Minotaur::LinearFunctionPtr &lf, int i); + + /// Add ampl specific options to Minotaur options. + void addOptions_(); + + /// Add the i-th non-linear constraint from ASL as a quadratic constraint + void addQuadraticConstraint_(int i, Minotaur::ProblemPtr problemPtr); + + void addQuadraticDefCons_(Minotaur::ProblemPtr instance); + void addQuadraticDefCons2_(Minotaur::ProblemPtr instance); + + /// Add the i-th non-linear objective from ASL as a quadratic objective + void addQuadraticObjective_(int i, Minotaur::ProblemPtr problemPtr); + + /// Add variables in ASL to the instance + void addVariablesFromASL_(Minotaur::ProblemPtr problemPtr); + + /// Add 'SOS' constrants of type 1 and 2. + void addSOS_(Minotaur::ProblemPtr instance); + + /** + * Call ASL routines and create an instance. The expression tree is + * traversed and the instance is stored in Minotaur data structures. + * ASL is not needed once the instance is constructed. + */ + Minotaur::ProblemPtr copyInstanceFromASL_(); + Minotaur::ProblemPtr copyInstanceFromASL2_(); + + /** + * AMPL has "N_OPS" different operations defined in opcode.hd in the ASL + * folder. Each operation has an associated function (efunc), say f_i, i + * = 0...(N_OPS-1). The data structure myAsl_->I->r_ops_ is an array of + * these functions. Thus myAsl_->I->r_ops_[0] is a pointer to a function + * corresponding to OPPLUS in opcode.hd. Similarly myAsl_->I->r_ops_[1] + * for OPMINUS and so on. + * + * Given an operation, say OPMINUS, it is easy to find the function that + * performs that operation. However, AMPL expression-trees do not store + * these opcodes. They just store function pointers. It is difficult to + * know what operation is associated with a given function. So we need + * to create a map from each such function to operation-code. + */ + void createFunctionMap_(); + + /// Find the type of input problem by querying ASL expression trees. + Minotaur::ProblemType findProblemType_(); + + /// Find variables in an expression and add them to the set 'vars'. + void findVars_(expr *e_ptr, std::set & vars); + + + /// Get computational graph from an expression. + Minotaur::CNode* getCGraph_(expr *e_ptr, Minotaur::CGraphPtr cgraph, + Minotaur::ProblemPtr instance); + + /// Get the most general function type that describes all constraints. + Minotaur::FunctionType getConstraintsType_(); + + /// Get the function type of i-th constraint. + Minotaur::FunctionType getConstraintType_(int i); + + /** + * Get the function type that describes the defined variable of type + * '1' + */ + Minotaur::FunctionType getDef1ConstraintType_(int i); + + /// Get the function type that describes the defined variable + Minotaur::FunctionType getDefConstraintType_(int i); + + /** + * Return function type of the ASL expression e_ptr. This function is + * recursive as an expression can have another expression as its + * operand. + */ + Minotaur::FunctionType getExpressionType_(expr *e_ptr); + + /** + * Call ASL routines and create an instance. Any nonlinear functions + * will be evaluated by calling ASL. + */ + Minotaur::ProblemPtr getInstanceFromASL_( + std::vector > &vids); + /** + * Return function type of the ASL sub-expresstion e_ptr when the root + * node has a plus or a minus. This function is + * called when an opcode OPMULT is found. + */ + Minotaur::FunctionType getMultExpressionType_(expr *e_ptr); + + /// Return the function type of objective. + Minotaur::FunctionType getObjFunctionType_(Minotaur::UInt obj_index=0); + + /** + * When a solver is called from ampl, options are passed as + * environment variables. For e.g. if the solver name is qg, and + * option "presolve" is set to 1, then environment variable qg_presolve + * is set to 1. + */ + void getOptionsFromEnv_(std::string pre); + + /** + * Return function type of the ASL sub-expresstion e_ptr when the root + * node has a plus or a minus. This function is + * called when an opcode OPPLUS or OPMINUS is encountered. + */ + Minotaur::FunctionType getPMExpressionType_(expr *e_ptr); + + void getPoly_(Minotaur::LinearFunctionPtr & lfPtr, + Minotaur::QuadraticFunctionPtr & qfPtr, + Minotaur::PolyFunPtr & pfPtr, + double & c, expr *e_ptr); + + /** + * Return function type of the ASL sub-expresstion e_ptr when the root + * node has a (expr)^(constant) operation. This function is + * called when an opcode OP1POW is found. + */ + Minotaur::FunctionType getPow1ExpressionType_(expr *e_ptr); + + /** + * Return function type of the ASL sub-expresstion e_ptr when the root + * node has a SUMLIST operation. This function is + * called when an opcode SUMLIST is found. + */ + Minotaur::FunctionType getSumlistExpressionType_(expr *e_ptr); + + /// Read a stub file using one of several readers provided by ASL + void readFile_(std::string *fname, ReaderType readerType); + + Minotaur::ProblemPtr readInstanceASL_(std::string fname); + Minotaur::ProblemPtr readInstanceCG_(std::string fname); + + void saveNlVars_(std::vector > &vars); + + /** + * \brief Complain about an unsupported operation. + * \param [in] opcode Minotaur opcode that we are complaining about. + */ + void unsupportedOp_(int opcode); + + /** + * \brief Write an expression. + * \param [in] e_ptr ASL expression that should be written. + * \param [in] out output stream that we write to. + */ + void writeExpression_(expr *e_ptr, std::ostream &out) const; + + /** + * \brief Write the expression (function) of a constraint or objective. + * \param [in] i The index of constraint that needs to be written. It is + * ignored if is_obj is true. + * \param [in] is_obj True if we want to write objective. + * \param [in] out output stream that we write to. + */ + void writeExpression_(int i, bool is_obj, std::ostream &out) const; + + /** + * \brief Write linear part of a function. + * \param [in] i The index of constraint whose linear part we want to write. + * It is ignored if is_obj is true. + * \param [is_obj] True if objective, false otherwise. + * \param [in] stream to which to write. + */ + void writeLin_(Minotaur::UInt i, bool is_obj, std::ostream &out) const; +}; + +} // namespace MINOTAUR_AMPL + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/AMPLJacobian.h b/thirdparty/linux/include/minotaur/AMPLJacobian.h new file mode 100644 index 0000000..d8be9b5 --- /dev/null +++ b/thirdparty/linux/include/minotaur/AMPLJacobian.h @@ -0,0 +1,123 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file AMPLJacobian.h + * \brief Declare the AMPLJacobian class forreadin pcting Jacobian from AMPL. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURAMPLJACOBIAN_H +#define MINOTAURAMPLJACOBIAN_H + +#include "asl.h" + +#include "Jacobian.h" + +namespace MINOTAUR_AMPL { + +class AMPLInterface; +typedef AMPLInterface * AMPLInterfacePtr; + +/** + * \brief Jacobian class has methods to call Jacobian evaluation routines of AMPL. + * This class is not meant to calculate Jacobian of native Minotaur + * functions. + */ +class AMPLJacobian : public Minotaur::Jacobian { +public: + /** + * \brief Construct AMPLJacobian using an AMPL(ASL) interface. + * \param[in] iface Pointer to AMPLInterface class from which we read the + * instance. + */ + AMPLJacobian(AMPLInterfacePtr iface); + + /// Destroy. + ~AMPLJacobian(); + + /** + * \brief Fill in column and row indices of nonzeros in Jacobian. + * + * Given arrays irow and jcol, fill in the row and column index of each + * non-zero in the jacobian. The entries are ordered by columns. This + * is slightly inefficient because AMPL computes the gradients row-wise + * and then translates them to column-wise (using goff). + * e.g. + * x1x3 + x1^2x4 = 2 + * x0 + x5 = 0 + * then, irow = [0 0 0 1 1] + * jcol = [1 3 4 0 5] + * + * \param [out] jcol Array of size returned by getNumNz(). + * \param [out] irow Array of size returned by getNumNz(). + */ + void fillColRowIndices(Minotaur::UInt *jcol, Minotaur::UInt *irow); + + /** + * \brief Fill the indices of non-zeros in Jacobian, row-wise (or + * constraint-wise). + * \param [out] irow Array of size returned by getNumNz(). + * \param [out] jcol Array of size returned by getNumNz(). + */ + void fillRowColIndices(Minotaur::UInt *irow, Minotaur::UInt *jcol); + + /** + * \brief Evaluate Jacobian at a given point x, column-wise. + * Fill the values of Jacobian at a given point x into array 'values'. + * The ordering is same as that provided by + * fillColRowIndices(). + * \param[in] x The point at which Jacobian is to be evaluated. + * \param[out] values The array of size returned by getNumNz() into which + * values are saved. + * \param[out] error is set to a nonzero value if a problem is encountered, + * otherwise it is left undisturbed. + */ + void fillColRowValues(const double *x, + double *values, int *error); + + /** + * \brief Evaluate Jacobian at a given point x, row-wise. + * \param[in] x The point at which Jacobian is to be evaluated. + * \param[out] values The array of size returned by getNumNz() into which + * values are saved. + * \param[out] error is set to a nonzero value if a problem is encountered, + * otherwise it is left undisturbed. + */ + void fillRowColValues(const double *x, double *values, int *error); + + /// Return the number of non-zeros in the Jacobian. + Minotaur::UInt getNumNz(); + +private: + /// Pointer to the AMPL's asl. + ASL *myAsl_; + + /// Number of nonzeros in Jacobian. Initialized in the constructor. + Minotaur::UInt nNz_; + + /// Temporary array used to save Jacobian in fillRowColValues() function. + double *tmp_; + + /// Size of tmp_ array. + Minotaur::UInt tmpSize_; +}; +typedef boost::shared_ptr AMPLJacobianPtr; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: + diff --git a/thirdparty/linux/include/minotaur/AMPLNonlinearFunction.cpp b/thirdparty/linux/include/minotaur/AMPLNonlinearFunction.cpp new file mode 100644 index 0000000..2a4daa3 --- /dev/null +++ b/thirdparty/linux/include/minotaur/AMPLNonlinearFunction.cpp @@ -0,0 +1,165 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file AMPLNonlinearFunction.cpp + * \brief Define the AMPLNonlinearFunction class for calling evaluation and + * gradient routines of ASL for nonlinear functions. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#include + +#include "MinotaurConfig.h" +#include "AMPLNonlinearFunction.h" + +using namespace MINOTAUR_AMPL; + +AMPLNonlinearFunction::AMPLNonlinearFunction() + : nVars_(0), + amplIndex_(0), + myAsl_(0), + neg_(false), + isInObj_(false) +{ +} + + +AMPLNonlinearFunction::AMPLNonlinearFunction(Minotaur::UInt i, + Minotaur::UInt n, ASL* my_asl, + bool is_in_obj) + : nVars_(n), + amplIndex_(i), + myAsl_(my_asl), + neg_(false), + isInObj_(is_in_obj) +{ + +} + + +Minotaur::NonlinearFunctionPtr +AMPLNonlinearFunction::cloneWithVars(Minotaur::VariableConstIterator, + int *err) const +{ + *err = 1; + return Minotaur::NonlinearFunctionPtr(); +} + + +double AMPLNonlinearFunction::eval(const double *x, int *error) +{ + double r; + double *xx = const_cast(x); + fint ferror = 0; + + if (true == isInObj_) { + r = (*((ASL*)myAsl_)->p.Objval)((ASL*)myAsl_, amplIndex_, xx, &ferror); + } else { + // call the corresponding eval function from ampl. + r = (*((ASL*)myAsl_)->p.Conival)((ASL*)myAsl_, amplIndex_, xx, &ferror); + } + if (neg_) { + r *= -1.; + } + *error = (int) ferror; + return r; +} + + +void AMPLNonlinearFunction::evalGradient (const double *x, double *grad_f, + int *error) +{ + double *xx = const_cast(x); + fint ferror = 0; + + std::fill(grad_f, grad_f+nVars_, 0); + if (true == isInObj_) { + (*(myAsl_)->p.Objgrd)(myAsl_, 0, xx, grad_f, &ferror); + } else { + (*(myAsl_)->p.Congrd)(myAsl_, amplIndex_, xx, grad_f, &ferror); + } + if (neg_) { + for (Minotaur::UInt i=0; iinsert(vars_.begin(), vars_.end()); +} + + +#ifdef NDEBUG +void AMPLNonlinearFunction::multiply(double ) +#else +void AMPLNonlinearFunction::multiply(double c) +#endif +{ + assert(fabs(c+1.0)<1e-9); // only allowed to multiply by -1.0 + neg_ = !neg_; +} + + +void AMPLNonlinearFunction::prepJac(Minotaur::VarSetConstIter, + Minotaur::VarSetConstIter) +{ + assert(!"can't fill jacobian in a ampl nonlinear function."); +} + + +void AMPLNonlinearFunction::setVars(Minotaur::VarSetConstIterator vb, + Minotaur::VarSetConstIterator ve) +{ + vars_.insert(vb, ve); +} + + +void AMPLNonlinearFunction::write(std::ostream &out) const +{ + out << "nonlinear function"; +} + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/ActiveNodeStore.h b/thirdparty/linux/include/minotaur/ActiveNodeStore.h new file mode 100644 index 0000000..2090be3 --- /dev/null +++ b/thirdparty/linux/include/minotaur/ActiveNodeStore.h @@ -0,0 +1,99 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file ActiveNodeStore.h + * \brief Declare the base class ActiveNodeStore for storing active nodes of + * the branch-and-bound tree. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURACTIVENODESTORE_H +#define MINOTAURACTIVENODESTORE_H + +#include "Types.h" + +namespace Minotaur { + + class Node; + typedef boost::shared_ptr NodePtr; + + /** + * \brief Save and retrieve active nodes. + * + * Nodes that have not been processed yet by the branch-and-bound algorithm + * are called active nodes. This base class is used to store them in a + * suitable data structure (stack or heap). + */ + class ActiveNodeStore { + + public: + /// Default Constructor. + ActiveNodeStore () {} + + /// Destroy. + virtual ~ActiveNodeStore() {} + + /// Find the minimum lower bound of all the active nodes. + virtual double getBestLB() const = 0; + + /// Find the maximum depth of all active nodes. + virtual UInt getDeepestLevel() const = 0; + + /// Get the number of active nodes. + virtual UInt getSize() const = 0; + + /** + * \brief Check if there are any active nodes left. + * + * \return true if there are no active nodes in the heap, otherwise + * return false. + */ + virtual bool isEmpty() const = 0; + + /// Remove the best node from the store. + virtual void pop() = 0; + + /** + * \brief Add a node to the set of active nodes. + * + * \param[in] n Pointer to node to be added. + */ + virtual void push(NodePtr n) = 0; + + /** + * \brief Access to the best candidate for evaluating next. + * + * Does not remove the best candidate from the storage. It just returns + * a pointer to it. Use pop() to remove the candidate. + * \return pointer to the best candidate node. + */ + virtual NodePtr top() const = 0; + + /** + * \brief Display the active nodes. + * + * Write in order the node IDs and the criteria used to order the + * nodes, e.g. bound value and depth. + * \param[in] out output stream to write to. + */ + virtual void write(std::ostream &out) const = 0; + }; + typedef boost::shared_ptr ActiveNodeStorePtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/BndProcessor.h b/thirdparty/linux/include/minotaur/BndProcessor.h new file mode 100644 index 0000000..61ff385 --- /dev/null +++ b/thirdparty/linux/include/minotaur/BndProcessor.h @@ -0,0 +1,150 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file BndProcessor.h + * \brief Define simple node-processor for branch-and-bound + * \author Ashutosh Mahajan, IIT Bombay + */ + +#ifndef MINOTAURBNDPROCESSOR_H +#define MINOTAURBNDPROCESSOR_H + +#include "NodeProcessor.h" + +namespace Minotaur { + + class Engine; + class Problem; + class Solution; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ConstProblemPtr; + typedef boost::shared_ptr ConstSolutionPtr; + + struct BPStats { + UInt bra; /// Number of times relaxation became infeasible + UInt inf; /// Number of times relaxation became infeasible + UInt opt; /// Number of times relaxation gave optimal feasible solution + UInt prob; /// Number of times problem ocurred in solving + UInt proc; /// Number of nodes processed + UInt ub; /// Number of nodes pruned because of bound + }; + + /** + * \brief Simple node-processor for branch-and-bound. + * + * BndProcessor is a derived class of NodeProcessor. It is meant to solve + * relaxations at each node. It performs only pruning and branching in a + * node. Does not call any presolving, cutting, or heuristic search. + */ + class BndProcessor : public NodeProcessor { + + public: + /// Default constructor + BndProcessor(); + + /// Constructor with a given engine. + BndProcessor(EnvPtr env, EnginePtr engine, HandlerVector handlers_); + + /// Destroy + ~BndProcessor(); + + // True if a new solution was found while processing this node. + bool foundNewSolution(); + + // Find branches that will be used to branch at this node. + Branches getBranches(); + + // Get warm-start information. + WarmStartPtr getWarmStart(); + + // Implement NodeProcessor::process(). + void process(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool); + + // write statistics. Base class method. + void writeStats(std::ostream &out) const; + + // write statistics. Base class method. + void writeStats() const; + + protected: + + /// Branches found by this processor for this node + Branches branches_; + + /** + * If true, we continue to search, if engine reports error. If false, + * we assume that the relaxation is infeasible when engine returns error. + */ + bool contOnErr_; + + /// If lb is greater than cutOff_, we can prune this node. + double cutOff_; + + /// Engine used to process the relaxation + EnginePtr engine_; + + /// Status of the engine + EngineStatus engineStatus_; + + /// All the handlers that are used for this processor + HandlerVector handlers_; + + /// Log + LoggerPtr logger_; + + /// For logging. + static const std::string me_; + + /// How many new solutions were found by the processor. + UInt numSolutions_; + + /// Relaxation that is processed by this processor. + RelaxationPtr relaxation_; + + /// Statistics + BPStats stats_; + + /// Warm-start information for start processing the children + WarmStartPtr ws_; + + /** + * Check if the solution is feasible to the original problem. + * In case it is feasible, we can store the solution and update the + * upper bound. Additionally, if the solution is optimal for the + * current node, then the node can be pruned. + */ + virtual bool isFeasible_(NodePtr node, ConstSolutionPtr sol, + SolutionPoolPtr s_pool, bool &should_prune); + + /// Solve the relaxation. + virtual void solveRelaxation_(); + + /** + * Check if a node can be pruned either because the relaxation is + * infeasible or because the cost is too high. + */ + virtual bool shouldPrune_(NodePtr node, double solval, + SolutionPoolPtr s_pool); + + }; + + typedef boost::shared_ptr BndProcessorPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/BqpdEngine.h b/thirdparty/linux/include/minotaur/BqpdEngine.h new file mode 100644 index 0000000..96459b7 --- /dev/null +++ b/thirdparty/linux/include/minotaur/BqpdEngine.h @@ -0,0 +1,352 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2010 - 2014 The MINOTAUR Team. +// + +/// \file BqpdEngine.h +/// \author Sven Leyffer, Argonne National Laboratory. +/// Declare the class BqpdEngine. + + +#ifndef MINOTAURBQPDENGINE_H +#define MINOTAURBQPDENGINE_H + +#include + +#include "QPEngine.h" + +namespace Minotaur { + + class Timer; + class Environment; + class Problem; + class Solution; + typedef boost::shared_ptr EnvPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr SolutionPtr; + + struct BqpdStats { + UInt calls; /// Total number of calls to solve. + UInt strCalls; /// Calls to solve while strong branching. + double time; /// Sum of time taken in all calls to solve. + double strTime; /// Time taken in strong branching alone. + double cTime; /// Time taken in copying data for strong-branching. + UInt iters; /// Sum of number of iterations in all calls. + UInt strIters; /// Number of iterations in strong branching alone. + }; + + class BqpdData; + /** + * BqpdEngine is used to solve QP problems using bqpd. + * bqpd finds a KT point for the bounded QP problem + * + * minimize f(x) = ct.x + xt.G.x/2 + * + * subject to l <= [I : A]t.x <= u (t = transpose) + * + * where x and c are n-vectors, G is a symmetric n*n matrix, and A is an + * n*m matrix. If G is also positive semi-definite then the KT point is a + * global solution, else usually a local solution. The method may also be + * used efficiently to solve an LP problem (G=0). bqpd can be used to solve + * problems completely to optimality or approximately. + */ + + class BqpdEngine : public QPEngine { + public: + friend class Problem; + + /// Default constructor. + BqpdEngine(); + + /// Constructor using given environment options. + BqpdEngine(EnvPtr env); + + /// Destroy. + ~BqpdEngine(); + + // Implement Engine::addConstraint() */ + void addConstraint(ConstraintPtr); + + // Change bound on a constraint. + void changeBound(ConstraintPtr cons, BoundType lu, double new_val); + + // Change bound on a variable. + void changeBound(VariablePtr var, BoundType lu, double new_val); + + // Implement Engine::changeBound(VariablePtr, double, double). + void changeBound(VariablePtr var, double new_lb, double new_ub); + + // Implement Engine::changeConstraint(). + void changeConstraint(ConstraintPtr con, LinearFunctionPtr lf, + double lb, double ub); + + // base class method + void changeConstraint(ConstraintPtr con, NonlinearFunctionPtr nlf); + + // change objective. + void changeObj(FunctionPtr f, double cb); + + /// Method to unload the current problem + void clear(); + + // Implement Engine::disableStrBrSetup() + void disableStrBrSetup(); + + /// Return an empty BqpdEngine pointer. + EnginePtr emptyCopy(); + + // Implement Engine::enableStrBrSetup() + void enableStrBrSetup(); + + // get name. + std::string getName() const; + + /// Report the solution. + ConstSolutionPtr getSolution(); + + /// Report the solution value from the last solve. + double getSolutionValue(); + + /// Report the status of the last solve. + EngineStatus getStatus(); + + // Implement Engine::getWarmStart(). // NULL for now. + ConstWarmStartPtr getWarmStart() {return WarmStartPtr(); }; + + // Implement Engine::getWarmStartCopy(). // NULL for now. + WarmStartPtr getWarmStartCopy() {return WarmStartPtr(); }; + + /// Method to read the problem and initialize bqpd. + void load(ProblemPtr problem); + + // Implement Engine::loadFromWarmStart(). + void loadFromWarmStart(WarmStartPtr ) {}; + + // Convert 'min f' to 'min -f'. + void negateObj(); + + // delete constraints. + void removeCons(std::vector &delcons); + + // Implement Engine::resetIterationLimit(). + void resetIterationLimit(); + + // Implement Engine::setIterationLimit(). + void setIterationLimit(int limit); + + /// Solve the problem that was loaded and report the status. + EngineStatus solve(); + + // Write statistics. + void writeStats(std::ostream &out) const; + + private: + /// Number of bound changes since last solve. + UInt bndChanges_; + + /** + * \brief True if some variable bounds are relaxed. Bqpd has difficulty + * hot-strating in this case. + */ + bool bndRelaxed_; + + const double bTol_; + + /// Checkpoint copy of fStart_. + BqpdData *chkPt_; + + /// If a constraint is modified, this is set to true. + bool consModed_; + + /// Array to calculate dual solution for constraints. + double *dualCons_; + + /// Array to calculate dual solution for variables. + double *dualX_; + + /// Environment. + EnvPtr env_; + + /// Information for full start + BqpdData *fStart_; + + /// Bounds are considered infinite if their value goes beyond this value. + const double infty_; + + /// Number of iterations that can be performed during solve + int iterLimit_; + + /// Max value of iterLimit_, when solving a relaxation + const int maxIterLimit_; + + /// String name used in log messages. + static const std::string me_; + + /// Constant part of the obj. + double objOff_; + + /// If the previous call was a strong-branching call. + bool prevStrBr_; + + /// Problem that is loaded, if any. + ProblemPtr problem_; + + /** + * If true, we should try to resolve in a different mode when error is + * reported. + */ + bool resolveError_; + + /// Solution found by the engine. + SolutionPtr sol_; + + /// Statistics. + BqpdStats *stats_; + + /// True if currently doing strong-branching iterations. False otherwise. + bool strBr_; + + /// Timer for bqpd solves. + Timer *timer_; + + /// Mode used for warm starting: 1-6 + int wsMode_; + + /// Free the memory allocated + void freeProb_(); + + /// Allocate the data structures for Bqpd. + void load_(); + + /// Copy constraint bounds from the problem. + void setConsBounds_(); + + /// Fill sparsity pattern and values of the gradients. + void setGradient_(); + + /// Fill sparsity pattern and values of the Hessian. + void setHessian_(); + + /// Set the intial point for solving the QP. + void setInitialPoint_(); + + /// Copy variable bounds from the problem. + void setVarBounds_(); + + /** + * Actually call bqpd to solve a QP using a specific mode. It is called + * after all data has been set. + */ + void solve_(int mode, double &f); + + /// Copy primal and dual values of the solution from bqpd. + void storeSol_(double f); + + }; + + + /// Information for restarting from the previous optimal solution. + class BqpdData { + public: + /// Constructor. + BqpdData(UInt n_t, UInt m_t, int kmax_t, UInt maxa_t, UInt lh1_t, + UInt nJac, bool zero=true); + + /// Destroy. + ~BqpdData(); + + /// Allocate space and copy. + BqpdData *clone(); + + /// Only copy. No space allocation. + void copyFrom(const BqpdData* rhs); + + /// Display all data. + void write(std::ostream &out) const; + + /// Number of variables. + UInt n; + + /// Number of constraints. + UInt m; + + /// kmax given to bqpd + int kmax; + + /// Number of nonzeros in Hessian. + UInt lh1; + + /// Number of nonzeros in Jacobian. + UInt nJac; + + /// Size of a + UInt maxa; + + /// Initial point for solving QP. + double *x; + + /// Residuals/multipliers. + double *r; + + /// Steepest-edge normalization coefficients . + double *e; + + /// Denominators for ratio tests. + double *w; + + /// Gradient vector of f(x). + double *g; + + /// Indices of the active constraints . + int *ls; + + /// Workspace associated with recursion. + double *alp; + + /// Workspace associated with recursion. + int *lp; + + /// Information on return from bqpd. + int *info; + + /// Lower bounds for variables and constraints. + double *bl; + + /// Upper bounds for variables and constraints. + double *bu; + + /// Storage for jacobian. + double *a; + + /// Storage for jacobian. + int *la; + + /// Storage for hessian values and other things. + double *ws; + + /// Storage for hessian indices and other things. + int *lws; + + /// Pointer to equality constraints, used by bqpd. + int peq; + + // Dimension of reduced-space, set only when mode>=0. + int k; + }; + + + typedef boost::shared_ptr BqpdEnginePtr; +} // end namespace Minotaur + +#endif +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/BrCand.h b/thirdparty/linux/include/minotaur/BrCand.h new file mode 100644 index 0000000..96f0df7 --- /dev/null +++ b/thirdparty/linux/include/minotaur/BrCand.h @@ -0,0 +1,129 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file BrCand.h + * \author Ashutosh Mahajan, IIT Bombay + * \brief Declare the classes BranchCand storing candidates for branching. + */ + +#ifndef MINOTAURBRCAND_H +#define MINOTAURBRCAND_H + +#include +#include "Types.h" + +namespace Minotaur { + +class Handler; +class Variable; +typedef boost::shared_ptr HandlerPtr; +typedef boost::shared_ptr VariablePtr; + +/** + * \brief Base class for describing candidates for branching on a node in + * branch-and-bound. + * + * A BranchCand object is something that can be branched upon. This class is + * abstract. Examples are BrVarCand, BrSOS1Cand, BrSOS2Cand, BrHyperCand, + * BrGenCand etc. + */ +class BrCand { +public: + /// Constructor + BrCand() {}; + + /// Destroy + virtual ~BrCand() {}; + + /** + * Return the distance of the current point from the branching constraint: + * down direction. For an integer constrained variable, x, it would be + * \f$ x - \lfloor x \rfloor \f$. + */ + virtual double getDDist() = 0; + + /// Get the preferred direction. + virtual BranchDirection getDir() const {return prefDir_;}; + + /// Return the handler that created this candidate. + virtual HandlerPtr getHandler() { return h_; }; + + /// Display for debugging. + virtual std::string getName() const {return "default br-cand";}; + + /** + * \brief Return the index in the pseudo cost array. If it is not in the + * array, return a value less than 0. + */ + virtual int getPCostIndex() const { return pCostIndex_; }; + + /// Return the score for this candidate. + virtual double getScore() { return score_; }; + + /** + * Return the distance of the current point from the branching constraint: + * up direction For an integer constrained variable, x, it would be \f$ + * x - \lceil x \rceil \f$. + */ + virtual double getUDist() = 0; + + /** + * \brief Set the preferred direction that will be processed first in + * the branch-and-bound tree. + */ + virtual void setDir(BranchDirection d) {prefDir_ = d;}; + + /** + * \brief Set the distance of the current solution from the down branch and + * the up branch. + */ + void setDist(double ddist, double udist); + + /// Set the handler that created this candidate. + virtual void setHandler(HandlerPtr h) { h_ = h; }; + + /** + * \brief Set score for this candidate. + * + * The score is used to compare two candidates. + * \param [in] score The desired score of this candidate. + */ + virtual void setScore(const double score) { score_ = score; }; + +protected: + /// Handler that created this candidate. + HandlerPtr h_; + + /// Index of the this candidate in the pseudo-cost array. + int pCostIndex_; + + /// Which is preferred for processing next? UpBranch or DownBranch? + BranchDirection prefDir_; + + /// Score of this candidate. + double score_; +}; + +/** + * \brief Comparison function to sort candidates in the decreasing order of + * their score. + */ +bool CompareScore(BrCandPtr c1, BrCandPtr c2); +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/BrVarCand.h b/thirdparty/linux/include/minotaur/BrVarCand.h new file mode 100644 index 0000000..a5d5a73 --- /dev/null +++ b/thirdparty/linux/include/minotaur/BrVarCand.h @@ -0,0 +1,73 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file BrVarCand.h + * \author Ashutosh Mahajan, IIT Bombay + * \brief Declare the classes BrVarCand storing candidates for branching. + */ + +#ifndef MINOTAURBRVARCAND_H +#define MINOTAURBRVARCAND_H + +#include +#include "Types.h" +#include "BrCand.h" + +namespace Minotaur { + +/** + * \brief Derived class of BrCand, it defines candidates for branching on + * bounds of a variable. + */ +class BrVarCand : public BrCand { +public: + /// Constructor. + BrVarCand(VariablePtr var, int i, double d, double u); + + // Destroy. + ~BrVarCand(); + + // base class method. + double getDDist(); + + // base class method. + std::string getName() const; + + // base class method. + double getUDist(); + + /// Get the variable that we are branching on. + VariablePtr getVar(); + + // base class method + void setDist(double ddist, double udist); + +private: + /// distance from lower-side branch (obtained by changing ub) + double dDist_; + + /// distance from upper-side branch (obtained by changing lb) + double uDist_; + + /// The variable on which we should branch. + VariablePtr var_; + +}; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Branch.h b/thirdparty/linux/include/minotaur/Branch.h new file mode 100644 index 0000000..846d6d5 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Branch.h @@ -0,0 +1,173 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Branch.h + * \author Ashutosh Mahajan, Argonne National Laboratory. + * \brief Declare the class Branch for describing branches in branch-and-bound. + */ + + +#ifndef MINOTAURBRANCH_H +#define MINOTAURBRANCH_H + +#include "Types.h" + +namespace Minotaur { + +class BrCand; +class Modification; +typedef boost::shared_ptr BrCandPtr; +typedef boost::shared_ptr ModificationPtr; + +/** + * \brief Base class for storing branching modifications. + * + * A Branch just has a vector of modifications. This vector of + * modifications can be applied to obtain a child node from the parent's + * relaxation. For each child node, we must have an associated Branch object. + * The object can also have other information (estimates on lower bounds of + * child etc). + */ +class Branch { +public: + /// Constructor + Branch(); + + /// Destroy + ~Branch(); + + /** + * \brief Add a problem modification to the current vector of modifications + * associated with this branch. + * \param[in] mod The modification that must be added to the child node. + */ + void addPMod(ModificationPtr mod); + + /** + * \brief Add a relaxation modification to the current vector of modifications + * associated with this branch. + * \param[in] mod The modification that must be added to the child node. + */ + void addRMod(ModificationPtr mod); + + /** + * \brief Set the candidate that was used to generate this branch. + * \param[in] cand The branching candidate that was used to create this + * branch. + */ + void setBrCand(BrCandPtr cand) {brCand_ = cand;}; + + /// The first modification in the vector of modifications (problem). + ModificationConstIterator pModsBegin() const + { return pMods_.begin(); } + + /// The first modification in the vector of modifications (relaxation). + ModificationConstIterator rModsBegin() const + { return rMods_.begin(); } + + /// The last iterator of the vector of modifications (problem). + ModificationConstIterator pModsEnd() const + { return pMods_.end(); } + + /// The last iterator of the vector of modifications (relaxation). + ModificationConstIterator rModsEnd() const + { return rMods_.end(); } + + /** + * \brief The reverse iterators are used for undoing the changes to the + * problem. It is important that the changes are reverted in the reverse + * order. + */ + ModificationRConstIterator pModsRBegin() const + { return pMods_.rbegin(); } + + /** + * \brief The reverse iterators are used for undoing the changes to the + * relaxation. It is important that the changes are reverted in the reverse + * order. + */ + ModificationRConstIterator rModsRBegin() const + { return rMods_.rbegin(); } + + /** + * \brief The last reverse iterator for modifications for the problem. + * Corresponds to the first modification in the vector. + */ + ModificationRConstIterator pModsREnd() const { return pMods_.rend(); } + + /** + * \brief The last reverse iterator for modifications for the relaxation. + * Corresponds to the first modification in the vector. + */ + ModificationRConstIterator rModsREnd() const { return rMods_.rend(); } + + /** + * \brief Return the activity or the value of the branching expression + * before we branched. Used for updating pseudo-costs. + */ + double getActivity() const; + + /** + * \brief Set the activity or the value of the branching expression + * before we branched. + * \param[in] value The value of activity. + */ + void setActivity(double value); + + /// Return the branching candidate that was used to create this branch. + BrCandPtr getBrCand() {return brCand_;}; + + /// Write the branch to 'out' + void write(std::ostream &out) const; + +protected: + /// Name. + const static std::string me_; + + /** + * \brief A vector of modifications of Problem that define this branch. + * + * A branch may have more than one modifications. For instance, fixing a + * variable to zero may have implications on bounds of other variables + * as well. + */ + ModVector pMods_; + + /** + * \brief A vector of modifications of Relaxation that define this branch. + * + * A branch may have more than one modifications. For instance, fixing a + * variable to zero may have implications on bounds of other variables + * as well. + */ + ModVector rMods_; + + /** + * \brief The value of the branching expression before we branched. + * + * If an integer variable has value 1.3 before branching, and we + * branch on it, the value is set at 1.3 + */ + double activity_; + + /// Branching candidate that is used to create this branch. + BrCandPtr brCand_; +}; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/BranchAndBound.h b/thirdparty/linux/include/minotaur/BranchAndBound.h new file mode 100644 index 0000000..f8e31bc --- /dev/null +++ b/thirdparty/linux/include/minotaur/BranchAndBound.h @@ -0,0 +1,299 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file BranchAndBound.h + * \brief Declare the default branch-and-bound-algorithm. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURBRANCHANDBOUND_H +#define MINOTAURBRANCHANDBOUND_H + +#include "Types.h" + +namespace Minotaur { + + struct BabOptions; + struct BabStats; + class NodeProcessor; + class NodeRelaxer; + class Problem; + class Solution; + class SolutionPool; + class Timer; + class TreeManager; + typedef boost::shared_ptr BabOptionsPtr; + typedef boost::shared_ptr NodeProcessorPtr; + typedef boost::shared_ptr NodeRelaxerPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr SolutionPtr; + typedef boost::shared_ptr SolutionPoolPtr; + typedef boost::shared_ptr TreeManagerPtr; + + + /** + * \brief Implement a generic branch-and-bound algorithm on a single cpu. + */ + class BranchAndBound { + + public: + /// Default constructor. + BranchAndBound(); + + /// Constructor for a given Problem and Environment. + BranchAndBound(EnvPtr env, ProblemPtr problem); + + /// Destroy. + virtual ~BranchAndBound(); + + /** + * \brief Add a heuristic that will be called before root node. + * \param [in] h The heuristic that should be called. This heuristic will + * be called after all previously added heuristic. + */ + void addPreRootHeur(HeurPtr h); + + /** + * \brief Return the percentage gap between the lower and upper bounds. + * + * Gap percentage is calculated as + * \f$\frac{u - l}{\left|u\right|+\epsilon} \times 100\f$, where \f$u\f$ + * is the upper bound, \f$l\f$ is the lower bound and \f$\epsilon\f$ is a + * small constant to avoid division by zero. + */ + double getPerGap(); + + /** + * \brief Return the lower bound from the search tree. + * + * This bound is defined as the minimum of the bounds from all active + * nodes. It may not be a bound on the optimal solution value. + */ + double getLb(); + + /// Return a pointer to NodeProcessor used in branch-and-bound. + NodeProcessorPtr getNodeProcessor(); + + /// Return a pointer to NodeRelaxer used in branch-and-bound. + NodeRelaxerPtr getNodeRelaxer(); + + /* + * \brief Return solution from the last solve. If no solution was found, return + * NULL. + */ + SolutionPtr getSolution(); + + /// Return the final status. + SolveStatus getStatus(); + + /** + * \brief Return a pointer to the tree manager. The client can then + * directly query the TreeManager for its size and other attributes. + */ + TreeManagerPtr getTreeManager(); + + /** + * \brief Return the upper bound for the solution value from the search tree. + * + * This bound may or may not correspond to a feasible solution of the + * problem. It may be obtained from a feasible solution of a relaxation of + * the problem. + */ + double getUb(); + + /// Return number of nodes processed while solving. + UInt numProcNodes(); + + /** + * \brief Set log level. + * + * \param [in] level The desired log level for this class. + */ + void setLogLevel(LogLevel level); + + /** + * \brief Set the NodeProcessor that processes each node. + * + * \param [in] p The desired node-processor. + */ + void setNodeProcessor(NodeProcessorPtr p); + + /** + * \brief Set the NodeRelaxer for setting-up relaxations at each node. + * + * \param [in] nr The desired node-relaxer. + */ + void setNodeRelaxer(NodeRelaxerPtr nr); + + /** + * \brief Switch to turn on/off root-node creation. + * + * Sometimes a client may set up a root node on its own and + * may not want the default root node. + * \param [in] b True if root node should be created, false otherwise. + */ + void shouldCreateRoot(bool b); + + /// Start solving the Problem using branch-and-bound + void solve(); + + /// Return total time taken + double totalTime(); + + /// Write statistics to the ostream out + void writeStats(std::ostream & out); + + /// Write statistics to the logger + void writeStats(); + + private: + /// Pointer to the enviroment. + EnvPtr env_; + + /// Log manager for displaying messages. + LoggerPtr logger_; + + /// String name used in log messages. + static const std::string me_; + + /// The processor to process each node. + NodeProcessorPtr nodePrcssr_; + + /// The relaxer to create a relaxation at each node. + NodeRelaxerPtr nodeRlxr_; + + /// Options. + BabOptionsPtr options_; + + /** + * \brief Heuristics that need to be called before creating and solving the root + * node. + */ + HeurVector preHeurs_; + + /// The Problem that is solved using branch-and-bound. + ProblemPtr problem_; + + /// The TreeManager used to manage the search tree. + SolutionPoolPtr solPool_; + + /** + * \brief Statistics about the branch-and-bound (including time, number of + * iterations etc.) + */ + BabStats *stats_; + + /// The status of the branch-and-bound algorithm. + SolveStatus status_; + + /** + * \brief Timer for keeping track of time. + * + * The user or the environment from which branch-and-bound is called can + * set up the timer and even start it before sending it to + * branch-and-bound. + */ + Timer *timer_; + + /// The TreeManager used to manage the search tree. + TreeManagerPtr tm_; + + /** + * \brief Process the root node. + * + * \param [out] should_prune True if the root node can be pruned. + * \param [out] should_dive True if we should dive to a child node. + */ + NodePtr processRoot_(bool *should_prune, bool *should_dive); + + /// Return True if a node can be pruned. + bool shouldPrune_(NodePtr node); + + /** + * \brief Check whether the branch-and-bound can stop because of time + * limit, or node limit or if solved? + */ + bool shouldStop_(); + + /** + * \brief Display status: number of nodes, bounds, time etc. + * + * \param [in] current_uncounted If True, then the number of nodes in the + * log-message is incremented by one. This may happen when diving: the + * node being processed is not in the list of active nodes in the tree. + */ + void showStatus_(bool current_uncounted); + }; + + /// Statistics about the branch-and-bound. + struct BabStats + { + /// Constructor. All data is initialized to zero. + BabStats(); + + /// Number of nodes processed. + UInt nodesProc; + + /// Total time used in branch-and-bound. + double timeUsed; + + /// Time of the last log display. + double updateTime; + }; + + + /// Different options and parameters that control branch-and-bound + struct BabOptions + { + /// Default constructor. + BabOptions(); + + /// Constructor created from options in environment. + BabOptions(EnvPtr env); + + /** + * \brief Should the root be created in branch-and-bound (yes), or the + * user calls branch-and-bound after creating the root (no)? + */ + bool createRoot; + + /// Time in seconds between status updates of the progress. + double logInterval; + + /// Verbosity of log. + LogLevel logLevel; + + /// Limit on number of nodes processed. + UInt nodeLimit; + + /** + * \brief Stop if the percent gap between lower and upper bounds of the + * objective function falls below this level. + */ + double perGapLimit; + + /// Limit on number of nodes processed. + UInt solLimit; + + /// Time limit in seconds for the branch-and-bound. + double timeLimit; + }; + + typedef boost::shared_ptr BranchAndBoundPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Brancher.h b/thirdparty/linux/include/minotaur/Brancher.h new file mode 100644 index 0000000..f48583a --- /dev/null +++ b/thirdparty/linux/include/minotaur/Brancher.h @@ -0,0 +1,98 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Brancher.h + * \brief Declare the base class Brancher for finding and creating branches in + * Branch-and-Bound. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURBRANCHER_H +#define MINOTAURBRANCHER_H + +#include "Types.h" + +namespace Minotaur { + + class Node; + class Relaxation; + class Solution; + class SolutionPool; + typedef boost::shared_ptr NodePtr; + typedef boost::shared_ptr RelaxationPtr; + typedef boost::shared_ptr ConstSolutionPtr; + typedef boost::shared_ptr SolutionPoolPtr; + + /** + * \brief A brancher is used to find suitable branches for a given node. e.g. + * LexicoBrancher. This class is abstract. + */ + class Brancher { + + public: + /// Default constructor. + Brancher(); + + /// Destroy. + virtual ~Brancher(); + + /** + * \brief Find a branching candidate. + * + * \return NULL if x does not have any + * fractional values for integer constrained variables or if no branching + * candidates are found (e.g. when we realize that problem is infeasible). + * \param[in] rel Relaxation at the current node. + * \param[in] node The current node. + * \param[in] sol The solution at the current node. + * \param[in] s_pool Solution pool containing known feasible solutions. + * \param[out] br_status Status returned by this brancher. + * \param[out] mods Modification returned by this brancher. NULL if none + * found. + */ + virtual Branches findBranches(RelaxationPtr rel, NodePtr node, + ConstSolutionPtr sol, + SolutionPoolPtr s_pool, + BrancherStatus & br_status, + ModVector &mods) = 0; + + /// Return the name of this brancher. + virtual std::string getName() const = 0; + + /** + * \brief Update pseudo-costs after LP is solved. + * + * \param[in] node The node for which relaxation is solved. The pseudo cost of + * branching candidate used in node->parent is updated. + * \param[in] sol The solution of the relaxation at this node (not the + * parent). + */ + virtual void updateAfterLP(NodePtr node, ConstSolutionPtr sol); + + /// Write statistics to the given out stream. + virtual void writeStats(std::ostream &) const {}; + + protected: + /// Log manager. + LoggerPtr logger_; + + }; + typedef boost::shared_ptr BrancherPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/CGraph.h b/thirdparty/linux/include/minotaur/CGraph.h new file mode 100644 index 0000000..5167b74 --- /dev/null +++ b/thirdparty/linux/include/minotaur/CGraph.h @@ -0,0 +1,266 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file CGraph.h + * \brief Declare class CGraph for storing computational graph of a nonlinear + * function. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURCGRAPH_H +#define MINOTAURCGRAPH_H + +#include + +#include "Types.h" +#include "NonlinearFunction.h" +#include "OpCode.h" +#include "LinearFunction.h" +#include "QuadraticFunction.h" + +namespace Minotaur { + +class CGraph; +class CNode; +typedef boost::shared_ptr CGraphPtr; +typedef std::deque CNodeQ; +typedef std::vector CNodeVector; +typedef std::map VarNodeMap; + +class CGraph : public NonlinearFunction { +public: + /// Default constructor. + CGraph(); + + // Construct from a Quadratic & Linear Function + CGraph(QuadraticFunctionPtr qf, LinearFunctionPtr lf); + + /// Default constructor. + ~CGraph(); + + void addConst(const double eps, int &err); + + NonlinearFunctionPtr clone(int *err) const; + + NonlinearFunctionPtr cloneWithVars(VariableConstIterator, int *) const; + + // base class method. + NonlinearFunctionPtr getPersp(VariablePtr z, double eps, int *err) const; + + // base class method. + void computeBounds(double *lb, double *ub, int *error); + + // Evaluate at a given array. + double eval(const double *x, int *err); + + // Evaluate gradient at a given array. + void evalGradient(const double *x, double *grad_f, int *error); + + // Evaluate hessian of at a given vector. + void evalHessian(double mult, const double *x, + const LTHessStor *stor, double *values, + int *error); + + // Fill hessian sparsity. + void fillHessStor(LTHessStor *stor); + + // Finalize hessian offsets, if needed. + void finalHessStor(const LTHessStor *stor); + + // Add gradient values to sparse Jacobian + void fillJac(const double *x, double *values, int *error); + + /** + * After adding all the nodes of the graph, finalize is called to create the + * forward and backward traversal queues, and related book-keeping. + */ + void finalize(); + + // base class method. + double getFixVarOffset(VariablePtr v, double val); + + // get type of function + FunctionType getType() const; + + UInt getNumNodes(); + + UInt getHessNz(); + + //reset node index every time a node is added or deleted + void resetNodeIndex(); + + /// Get the output node. + const CNode* getOut() const; + + VariablePtr getVar(const CNode *cnode) const; + + // Get variables that exist in this function. + void getVars(VariableSet *vars); + + bool isIdenticalTo(CGraphPtr cg); + + // base class method + bool isSumOfSquares() const; + + // multiply by a constant. + void multiply(double c); + + /** + * \brief Create a new node with one or two children, and add it to the + * graph. The children should already be a nodes of the graph. + * + * \param [in] op OpCode of the new node + * \param [in] lchild The left child of the new node. It should + * never be NULL. + * \param [in] rchild If the opcode needs two children, e.g. OpPlus, OpMult + * etc, then rchild should be the right child. For univariate functions like + * OpSqrt, it should be NULL. + * \return The new node created in this function. + */ + CNode* newNode(OpCode op, CNode *lchild, CNode *rchild); + + /** + * \brief Create a new node with more than two children, and add it to the + * graph. The children should already be a nodes of the graph. + * + * \param [in] op OpCode of the new node + * \param [in] child An array of pointers to children. It should be size 'n'. + * \param [in] n The size of array 'child'. + * \return The new node created in this function. + */ + CNode* newNode(OpCode op, CNode **child, UInt n); + + /** + * \brief Create a new node with constant real value. It does not have any + * children. + * + * \param [in] d The value. + * \return The new node created in this function. Its opcode is OpNum + */ + CNode* newNode(double d); + + /** + * \brief Create a new node with constant integer value. It does not have any + * children. + * + * \param [in] i The value. + * \return The new node created in this function. Its opcode is OpInt + */ + CNode* newNode(int i); + + /** + * \brief Create a new node denoting an input variable. It does not have any + * children. + * + * The function checks if the variable already exists in the graph. If so, + * it returns the pointer to that node. Otherwise it creates a new node. + * + * \param [in] v The variable. + * \return The new node found or created in this function. Its opcode is + * OpVar + */ + CNode* newNode(VariablePtr v); + + // base class method. + void prepJac(VarSetConstIter vbeg, VarSetConstIter vend); + + // base class method. + void removeVar(VariablePtr v, double val); + + /** + * \brief Set the node that should be the output of this graph. This node + * should already be a part of this graph (created by newNode() function). + * + * \param [in] node The node that is the output. + */ + void setOut(CNode *node); + + // base class method. + void sqrRoot(int &err); + + // base class method. + void subst(VariablePtr out, VariablePtr in, double rat); + + // base class method. + void varBoundMods(double lb, double ub, VarBoundModVector &mods, + SolveStatus *status); + + // method to return all the dependent nodes of the cgraph. + CNodeQ dNodes() {return dq_ ;} ; + + // display. + void write(std::ostream &out) const; + +private: + /// All nodes of the graph. + CNodeVector aNodes_; + + bool changed_; + + /// All dependent nodes, i.e. nodes with OpCode different from OpVar, OpInt + /// and OpNum. + CNodeQ dq_; + + UIntVector hInds_; + UInt hNnz_; + UIntVector hOffs_; + UIntVector hStarts_; + UIntVector gOffs_; + + + /// Topmost node or output node. We assume only one is present. + CNode *oNode_; + + /// A map that tells which node corresponds to a given variable. + VarNodeMap varNode_; + + /// All nodes with OpCode OpVar. + CNodeQ vq_; + + CGraphPtr clone_(int *err) const; + + void fwdGrad_(CNode *node); + void fwdGrad2_(std::stack *st2, CNode *node); + + void fillHessInds_(CNode *node, UIntQ *inds); + void fillHessInds2_(CNode *node, UIntQ *inds); + + /// Recursive function to check whether CGraph represents a sum of squares. + bool isSOSRec_(CNode *node) const; + + void revHess_(int *error); + void revHess2_(std::stack *st2, double mult, UInt vind, + double *values, UInt *nz, int *error); + + /** + * Routine to propagate gradient by a reverse mode traversal. + * + * \param [out] error Set to a nonzero if an error occurs. Otherwise, leave + * it unchanged. + */ + void grad_(int *error); + + void setupHess_(VariablePtr v, CNode *node, std::set & vps); + + void simplifyDq_(); + +}; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/CNode.h b/thirdparty/linux/include/minotaur/CNode.h new file mode 100644 index 0000000..6d1771c --- /dev/null +++ b/thirdparty/linux/include/minotaur/CNode.h @@ -0,0 +1,430 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file CNode.h + * \brief Declare class CNode to represent node of a computational graph of a + * nonlinear function. + * \author Ashutosh Mahajan, IIT Bombay + */ + +#ifndef MINOTAURCNODE_H +#define MINOTAURCNODE_H + +#include "OpCode.h" +#include "Types.h" + +namespace Minotaur { + +class Variable; +class CNode; + +struct CompareCNodes { + bool operator()(const CNode* n1, const CNode *n2) const; +}; +struct CompareCNodesR { + bool operator()(const CNode* n1, const CNode *n2) const; +}; +typedef boost::shared_ptr VariablePtr; +typedef std::set CNodeSet; +typedef std::set CNodeRSet; + +class CQIter2 { +public: + CNode *node; + CQIter2 *next; + CQIter2 *prev; +}; + +/** + * \brief CNode denotes a node in the computational graph. It stores the + * op-code, children, parents and other auxiliary information to evaluate the + * function and its derivative, check its properties etc. + */ +class CNode { +public: + + /// Default constructor + CNode(); + + /** + * \brief: Construct a node from its children and an opcode + * + * Constructor with a specific opcode and children. + * \param [in] op Opcode of the new CNode + * \param [in] children Pointer to an array of child nodes, can be null + * \param [in] Number of children, can be zero or more + */ + CNode(OpCode op, CNode **children, UInt num_child); + + /** + * \brief: Construct a node from two children, left and right, and an opcode + * + * Constructor with a specific opcode and two children. + * \param [in] op Opcode of the new CNode + * \param [in] lchild Pointer to the left child node + * \param [in] rchild Pointer to the right child node + */ + CNode(OpCode op, CNode *lchild, CNode *rchild); + + /// Destroy. + ~CNode(); + + /// Clone the node. Does not copy pointers to parents, children, etc. + CNode *clone() const; + + /** + * \brief Add a parent to a given node (a parent depends on the child in + * function evaluation). + * + * \parm [in] Pointer to the parent node + */ + void addPar(CNode *node); + + /** + * \brief Replace one of the children of a given node by another node. + * + * \param [in] out Pointer to the existing child node that will be replaced + * \param [in] in Pointer to the new child node that will replace the + * existing child. + */ + void changeChild(CNode *out, CNode *in); + + /** + * \brief Make copies of links pointing to parents and children to another + * node. Used in cloning the CGraph. + * + * \param [in,out] out The node to which the links must be copied. This is + * the clone. + * \param [nmap] in A map of nodes in of current CGraph to the nodes of new + * CGraph. + */ + void copyParChild(CNode *out, std::map *nmap) const; + + /** + * \brief Evaluate the function at this node. + * + * \param [in] x The point at which the CGraph containing this CNode is + * being evaluated. x is used only for nodes that have opcode OpVar. For all + * other nodes, the values of the children are used in evaluating the + * function. + * \param [out] error Nonzero if some error occurs in evaluation e.g. log of + * a negative number, etc. + */ + void eval(const double *x, int *error); + + /** + * \brief Evaluate the value of just this node based on the single value + * given as an input parameter. Ignores the values at the children nodes. + * Used by Transformer classes. Applicable only to nodes that require a + * single input (like OpUMinus, OpSqrt, etc) and not others (like OpSumList, + * OpPlus, OpMult, etc.) + * + * \param [in] x The input argument for the function. + * \param [out] error Nonzero if there is an error in evaluation like some + * IEEE exception. + * \return The value of the function evaluated. + */ + double evalSingle(double x, int *error) const; + + /** + * \brief Find the type of the function (constant, linear, polynomial, etc.) + * based on the function type of children. + */ + FunctionType findFType(); + + /** + * \brief Calculate the derivative of the function at this node based on + * values and gradients of children nodes. Used in forward-mode gradient + * calculation. + */ + void fwdGrad(); + + /// \return The value of the boolean flag. + bool getB() const { return b_; }; + + /// \return The value of the gradient value. + double getG() const { return g_; }; + + /// \return The value of the hessian value at this node. + double getH() const {return h_;}; + + /// \return The ID + UInt getId() const {return id_;}; + + /// \return index of the node + UInt getIndex() const {return index_;}; + + /// \return The pointer to left child + CNode* getL() const { return l_; }; + + /// \return The lower bound + double getLb() const { return lb_; }; + + /// \return Pointer to the beginning of array of pointers to children + CNode** getListL() const { return child_; }; + + /// \return Pointer to the end of array of pointers to children + CNode** getListR() const { return child_+numChild_; }; + + /// \return The opcode of this node. + OpCode getOp() const { return op_; }; + CQIter2* getParB() const { return parB_; }; + + /// \return The pointer to right child + CNode* getR() const { return r_; }; + int getTempI() const { return ti_; }; + + /// \return The stored function type (does not evaluate). + FunctionType getType() const { return fType_; } ; + + /// \return The upper bound + double getUb() const { return ub_; }; + + /// \return The unique parent if any, otherwise return NULL + CNode* getUPar() const { return uPar_; }; + + /// \return Pointer to the variable if the node is OpVar, otherwise NULL + const Variable* getV() const { return v_; }; + + /// \return The value of function stored at this node (does not evaluate) + double getVal() const { return val_; }; + + /** + * \brief Push gradient values to children for reverse mode gradient + * evaluation. + * + * \param [out] error Nonzero if there is an error in evaluation. + */ + void grad(int *error); + + /// \return The number of children nodes. + UInt numChild() const { return numChild_; }; + + /// \return The number of parents + UInt numPar() const { return numPar_; }; + + /** + * \brief Find whether child-nodes must participate in evaluation of the + * current column of the hessian-matrix. Sets values of internal flags and + * variables. + */ + void propHessSpa(); + + /// A variant of propHessSpa() + void propHessSpa2(CNodeRSet *nset); + + /** + * \brief Deduce and push new bounds to child-nodes based on bounds of this + * node. + * + * \param [out] is_inf True if it detects inconsistency, i.e. infeasibility + * \param [out] error Nonzero if some error is encountered in evaluation. + */ + void propBounds(bool *is_inf, int *error); + + /** + * \brief Reverse mode hessian evaluation. Hessian values are pushed to + * children nodes. + * + * \param [out] error Nonzero if some error is encountered in evaluation. + */ + void hess(int *error); + + /** + * \brief Reverse mode hessian evaluation with sparsity detection. Hessian + * values are pushed to children nodes. + * + * \param [in, out] nset Children are added to nset if they participate in + * Hessian. + * \param [out] error Nonzero if some error is encountered in evaluation. + */ + void hess2(CNodeRSet *nset, int *error); + + /** + * \brief Set the boolean flag. + * + * \param [in] b The flag. + */ + void setB(bool b) {b_ = b;}; + + /** + * \brief Set lower and upper bounds on the node. + * + * \param [in] lb Lower bound. + * \param [in] ub Upper bound. + */ + void setBounds(double lb, double ub) {lb_ = lb; ub_ = ub; }; + + /** + * \brief Set the constant double value (OpNum and OpInt). + * + * \param [in] d The value. + */ + void setDouble(double d) {d_ = d;}; + + /** + * \brief Set the value of the derivative (reverse mode gradient) + * + * \param [in] g The value. + */ + void setG(double g) {g_ = g;}; + + /** + * \brief Set the value of the derivative (forward mode gradient) + * + * \param [in] gi The value. + */ + void setGi(double gi) {gi_ = gi;}; + + /** + * \brief Set the value of the hessian. + * + * \param [in] h The value. + */ + void setH(double h) {h_ = h;}; + + /** + * \brief Set the value of the node ID. + * + * \param [in] i The value. + */ + void setId(UInt i) {id_ = i;}; + + /** + * \brief Set the value of the node index. + * + * \param [in] i The value. + */ + void setIndex(UInt i) {index_ = i;}; + + + /** + * \brief Set the pointer to the left-most child + * + * \param [in] n The pointer. + */ + void setL(CNode *n) {l_ = n;}; + + /** + * \brief Set the OpCode. + * + * \param [in] op The OpCode value. + */ + void setOp(OpCode op) {op_ = op;}; + + /** + * \brief Set the pointer to the right-most child + * + * \param [in] n The pointer. + */ + void setR(CNode *n) {r_ = n;}; + + /** + * \brief Set the value of the temporary integer ti_ + * + * \param [in] ti The pointer. + */ + void setTempI(int i) { ti_ = i; }; + + /** + * \brief Set the value of function type of the graph rooted at this node + * + * \param [in] t The type. + */ + void setType(FunctionType t); + + /** + * \brief Set the value of function at this node + * + * \param [in] v The value. + */ + void setVal(double v); + + /** + * \brief Set the Variable at this node (for OpVar nodes) + * + * \param [in] v The variable pointer. + */ + + void setV(VariablePtr v) {v_ = v.get();}; + + /** + * \brief Find bounds deduced from the bounds of children nodes and update + * lb_ and ub_ + * + * \param [out] error Nonzero if some error is encountered in evaluating the + * bounds. + */ + void updateBnd(int *error); + + /// Print the function expression at current node only. + void write(std::ostream &out) const; + + /// Print the function expression at current node and the sub-tree. + void writeSubExp(std::ostream &out) const; + +protected: + bool b_; /// Boolean flag used in finding hessian sparsity + CNode **child_; /// array of size numChild_ + 1. The last pointer is a null + double d_; /// Constant double value in OpNum and OpInt nodes + FunctionType fType_; /// Function type of the graph rooted at this node + double g_; /// Value of the derivative of output w.r.t. this node + /// (reverse mode) + double gi_; /// Value of the derivative of this node w.r.t. to a given var + /// (forward mode) + double h_; /// Value of the hessian + UInt id_; /// Unique ID of a dependent node. 0 for independent nodes. + UInt index_; /// Unique index of the node + CNode *l_; /// Left child + double lb_; /// lower bound that a node can achieve + UInt numChild_; /// Number of children + UInt numPar_; /// Number of parents + OpCode op_; /// Operation code + CQIter2 *parB_; /// Pointer to the first parent (parents begin) + CQIter2 *parE_; /// Pointer to the last parent (parents end) + CNode *r_; /// Right child + int ti_; /// Temporary integer variable to find patterns of + /// sparsity in the hessian. + double ub_; /// upper bound that a node can achieve + + + CNode *uPar_; /// Unique parent of this node. NULL if the node has + /// multiple parents + const Variable* v_; /// Pointer the variable in case it is OpVar + double val_; /// Current value of the expression based on the value + /// of the children + + /** + * \brief Change the current bounds of the function value at this node to + * new bounds only if the new bounds are tighter. Also checks whether the + * new bounds are inconsistent. + * + * \param [in] lb New lower bound + * \param [in] ub New upper bound + * \param [out] is_inf Set to true if lb is more than ub after the update. + * Otherwise, remains unchanged. + */ + void propBounds_(double lb, double ub, bool *is_inf); + +}; +typedef std::vector CNodeVector; +} + + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Constraint.h b/thirdparty/linux/include/minotaur/Constraint.h new file mode 100644 index 0000000..4172342 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Constraint.h @@ -0,0 +1,223 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Constraint.h + * \brief Get information about a constraint in a given Problem. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURCONSTRAINT_H +#define MINOTAURCONSTRAINT_H + +#include + +#include "Types.h" + +namespace Minotaur { + class Function; + class LinearFunction; + class QuadraticFunction; + class NonlinearFunction; + typedef boost::shared_ptr FunctionPtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr NonlinearFunctionPtr; + typedef boost::shared_ptr QuadraticFunctionPtr; + typedef std::set >::const_iterator + VariableFunIterator; + + /** + * \brief The Constraint class is used to manage a constraint. + * + * The general form of a constraint is: + * \f[ + * l \leq f(x) \leq u, + * \f] + * where \f$f(x)\f$ is a function of the variables and \f$l, u\f$ are + * constraints placed on \f$f\f$. \f$l\f$ can be \f$-\infty\f$ and/or + * \f$u\f$ can be \f$\infty\f$. + * + * A constraint should only be constructed through a Problem object. Doing + * this ensures that constraints have ID's unique for that problem. A + * constraint can thus be part of only one problem. A function \f$f\f$ that + * is part of a constraint should also not be shared at several places in + * the same problem or amongst different problems. Similarly, constraints + * should be deleted only through a problem. Changes in a constraint (e.g. + * changing name, bounds etc) may be done directly. + * + * The state of a constraint describes whether the constraint is free or + * deleted etc. It is Fixed if each variable in the constraints has been + * fixed. + * + * A Constraint also stores a map of variables that occur in that + * constraint. The map tells whether the variable is in a non-linear, + * or quadratic etc part of the constraint. A variable that occurs + * once in linear and thrice in quadratic parts will have four entries in + * the map, once for each occurrence. + * + * The name of a constraint can be set by the user. There are no checks for + * duplicate names. The ID of the constraint however is unique in the + * problem. + */ + class Constraint { + public: + + /// Only Problem class can modify a Constraint. All modification methods + /// are private. + friend class Problem; + friend class TransSep; + + + /// Default constructor. + Constraint(); + + /** + * \brief This is the only real constructor. All others should call this + * constructor. + * + * Create a constraint with + * \param [in] id the unique id of the constraint (determined by + * Problem object), + * \param [in] index the index of the constraint in the problem, + * \param [in] f the function in the body of the constraint, + * \param [in] lb the lower bound, can be -INFINITY, + * \param [in] ub the upper bound, can be INFINITY, + * \param [in] name The string name of the constraint. + */ + Constraint(UInt id, UInt index, FunctionPtr f, double lb, double ub, + std::string name); + + /// Destroy + virtual ~Constraint(); + + /// Get the value or activity at a given point. + double getActivity(const double *x, int *error) const; + + /// Return a pointer to the function. + const FunctionPtr getFunction() const { return f_; } + + /// Get the function type. + FunctionType getFunctionType() const; + + /// Return the unique id of the constraint. + UInt getId() const { return id_; } + + /// Return the index of the constraint. + UInt getIndex() const { return index_; } + + /// Get the 'l' value. or the lower bound constraint on 'f'. + double getLb() const { return lb_; } + + /// Get the linear part of the constraint function 'f'. + const LinearFunctionPtr getLinearFunction() const; + + // Get the name of the constraint. + const std::string getName() const; + + /// Get the nonlinear part of the constraint function 'f'. + const NonlinearFunctionPtr getNonlinearFunction() const; + + /// Get the quadratic part of the constraint function 'f'. + const QuadraticFunctionPtr getQuadraticFunction() const; + + /// Get the current state of the constraint: freed, fixed etc. + ConsState getState() const { return state_; } + + /// Get the 'u' value. or the upper bound constraint on 'f'. + double getUb() const { return ub_; } + + /// display the constraint + void write(std::ostream &out) const; + + protected: + /// Add a constant to the constraint function. lb - c <= f <= ub - c. + void add_(double cb); + + /// Change the linear part of constraint. + void changeLf_(LinearFunctionPtr lf); + + /// Change the nonlinear part of constraint. + void changeNlf_(NonlinearFunctionPtr nlf); + + /// Delete variables fixed at value val. + void delFixedVar_(VariablePtr v, double val); + + /** + * \brief Negate the constraint. + * + * Convert the constraint to + * \f[ + * -u \leq -f(x) \leq -l + * \f] + */ + void reverseSense_(); + + /// Set the id. + void setId_(UInt n) { id_ = n; } + + /// Set the index. + void setIndex_(UInt n) { index_ = n; } + + /** + * \brief Set a new lower bound. + * + * The new lower bound can be -INFINITY. It can change the state of + * the constraint. + */ + void setLb_(double newlb) { lb_ = newlb; } + + /// Set name of the constraint + void setName_(std::string name); + + /// Set state of the constraint. + void setState_(ConsState state) { state_ = state; return; } + + /** + * \brief Set a new upper bound. + * + * The new bound can be INFINITY. It can affect the state of the + * constraint. + */ + void setUb_(double newub) { ub_ = newub; } + + /// \brief Substitute a variable \f$x_1\f$ by \f$rx_2\f$. + void subst_(VariablePtr out, VariablePtr in, double rat, bool *instay); + + private: + /// The function 'f' in l <= f(x) <= u. + FunctionPtr f_; + + /// id that is unique for this constraint in the problem. + UInt id_; + + /// id that is unique for this constraint in the problem. + UInt index_; + + /// 'l' [-infinity, infinity). + double lb_; + + /// name of the constraint. could be NULL. + std::string name_; + + /// free or fixed etc. + ConsState state_; + + /// 'u' (-infinity, infinity]. + double ub_; + }; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/CoverCutGenerator.h b/thirdparty/linux/include/minotaur/CoverCutGenerator.h new file mode 100644 index 0000000..ece6019 --- /dev/null +++ b/thirdparty/linux/include/minotaur/CoverCutGenerator.h @@ -0,0 +1,387 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file CoverCutGenerator.h + * \brief Declare base class CoverCutGenerator. + * \author Serdar Yildiz, Argonne National Laboratory + */ + +#ifndef MINOTAURCOVERCUTGENERATOR_H +#define MINOTAURCOVERCUTGENERATOR_H + +#include +#include +using std::ofstream; +#include +using std::string; + +#include "KnapsackList.h" +#include "Problem.h" +#include "Solution.h" +#include "Types.h" +#include "Cut.h" +#include "Relaxation.h" +#include "Environment.h" + +namespace Minotaur { + + typedef enum { + Cover = 0, + Cons, + Obj, + Set + } PrintType; + + typedef enum { + Totalcuts = 0, + Cuts, + Violated, + Extended, + Simple, + Gns, + Singlectwo, + Basic, + Noviol, + Noinitcover + } KnapCovType; + + struct CovCutGenStats + { + UInt knaps; /// Number of total knapsacks solved. + UInt totalcuts; /// Number of all cuts i.e. included duplicates as well. + UInt cuts; /// Number of total cover cuts generated. + UInt violated; /// Number of violated cuts. + UInt extended; /// Number of extended cuts generated. + UInt simple; /// Number of simple lifted cover cuts generated. + UInt gns; /// Number of Gu, Nemhauser, Savelsbergh cuts generated. + UInt singlectwo; /// Number of general lifted only a single element for C2 + /// is downlifted. + UInt basic; /// Number of cuts generated from initial cover set. + // Time is not calculated yet. + UInt noviol; // GNS procedure terminated since there is no violation after + // upliftin F + UInt noinitcov; // GNS procedure terminated since there is no initial cover generated. + double time; // Total time used by generator. + }; + + + + typedef boost::shared_ptr ConstCutPtr; + typedef CovCutGenStats* CovCutGenStatsPtr; + typedef CovCutGenStats const * ConstCovCutGenStatsPtr; + typedef boost::shared_ptr OfstreamPtr; + + /** + * The CoverCutGenerator class generates a set of minimal covers + * for each knapsack constraint. + * First, the knapsack list is created. + * Second, Cover cuts for a chosen minimal cover for a corresponding + * knapsack inequality is created + * the inequalites are added to a cut list. + */ + class CoverCutGenerator { + public: + // Default constructor + CoverCutGenerator(); + + // Constructor that uses a problem and a solution given. + CoverCutGenerator(ProblemPtr p, SolutionPtr s, EnvPtr env); + + // Constructor that uses a relaxation and a solution given. + CoverCutGenerator(RelaxationPtr rel, ConstSolutionPtr sol, EnvPtr env); + + // Destructor + ~CoverCutGenerator(); + + // Initialize data elements. + bool initialize(RelaxationPtr p, ConstSolutionPtr s, EnvPtr env); + + // Obtain the knapsack constraint list from problem. + void generateKnapList(); + + // Checks if the constraint has a cover set. + bool hasCover(ConstraintIterator it); + + // Check if it is a GUB. + bool GUB(ConstraintIterator itcons); + + // Constructs a vector of nonzero variables in the given solution. + void nonzeroVars(LinearFunctionPtr lf, + CoverSetPtr nonzerovars, + CoverSetPtr zerovars); + + // Sort nonzero variables array in nonincreasing order. + void sortNonIncreasing(CoverSetPtr nonzeros); + + // Sort the variables in nondecreasing order of their reduced costs. + void sortReducedCosts(CoverSetPtr & vars); + + /** Generates a cover set from a vector of variables and their coefficients + * in the knapsack constraint. + * It uses Gu, Nemhauser, Savelsbergh approach. + */ + bool coverSetGeneratorGNS(ConstConstraintPtr cons, CoverSetPtr cover); + + + + /* Modified GNS cover set generator such that it always generates a cover. + This function generates a cover set by using different strategies. + * For now, it generates a modified version of Gu, Nemhauser, Savelsbergh + * such that it generates a cover set even though the number of nonzero + * elements in solution vector given is not enough for cover set generation + * s.t sum(a_i) <= b for i s.t. x^*_i != 0. + */ + CoverSetPtr coverSetGenGNSModified(ConstConstraintPtr cons); + + + /** This is the default cover set generator. + * It simply adds the variables to the set until the sum > b. + * It orders the variables in order of their coefficients in nonincreasing + * order. + * By this way, the cover will probably be minimal cover. + */ + CoverSetPtr coverSetGeneratorDefault(ConstConstraintPtr cons); + + + // Obtain initial cover. + //CoverSetPtr initialCover(ConstConstraintPtr constraintPtr); + + /** + * This generates the variable-coefficient pair vector + * from a given linear function. + */ + CoverSetPtr varCoeff(LinearFunctionPtr lf); + + /** Constructs the variable-value pair vector from a given vector and a + * linear function that inclued coefficients. + */ + void variableCoeffPair(CoverSetPtr cover,LinearFunctionPtr lf); + + /** Calculates the sum of coefficients of a given vector of + * variable-coefficient pairs + */ + double sumCoeffs(CoverSetPtr cover); + + /** Drops some of the variables and obtains a minimal cover form a given + * cover. + */ + void minimalCover(CoverSetPtr cover, + ConstConstraintPtr cons); + + // Generates all the cover cuts from all knapsack constraints. + void generateAllCuts(); + + // Generate cover partitions C1, C2 and Cbar according to Gu, Nemhauser, + // Savelsbergh. + void coverPartitionGNS(const ConstConstraintPtr cons, + const ConstCoverSetPtr cover, + CoverSetPtr cone, + CoverSetPtr ctwo, + CoverSetPtr fset, + CoverSetPtr rset); + + // Generates set N\C, the variables outside of cover set. + void cBar(const ConstCoverSetPtr coverSetPtr, + CoverSetPtr cBar, + const ConstConstraintPtr constraint); + + // Lifts a variables up or down as it is specified by uplift. + double lift(const ConstCoverSetPtr obj, + const ConstCoverSetPtr constraint, + const CoverSetConstIterator variable, + double & rhs, + double & inititalb, + bool uplift); + + // Simple lifted cover + void simple(const ConstCoverSetPtr cover, + const ConstCoverSetPtr cbar, + const ConstConstraintPtr cons); + + // Simple lifted cover + void allCTwo(const ConstCoverSetPtr cover, + const ConstCoverSetPtr cone, + const ConstCoverSetPtr cbar, + const ConstConstraintPtr cons); + + // Initialize the cover inequality by changing the coefficients of cover set + // by 1s. + void initCoverIneq(const ConstCoverSetPtr coverset, CoverSetPtr coverineq); + + // Lifting strategy of Gu, Nemhauser, and Savelsbergh.i + bool liftingGNS(const ConstCoverSetPtr cone, + const ConstCoverSetPtr ctwo, + const ConstCoverSetPtr fset, + const ConstCoverSetPtr rset, + CoverSetPtr constraint, + const ConstConstraintPtr cons, + double & ub); + + + // This lifts the variables in a given set according to Gu, Nemhauser and + // Savelsbergh algorithm by considering the amount of contribution. + void liftSetF(CoverSetPtr obj, + CoverSetPtr consknap, + const ConstCoverSetPtr setf, + CoverSetPtr coverineq, + double & ub, + double & initialb, + const bool liftup); + + // This function lifts up and lifts down the variables similar to liftSet + // but the assumprions are changed as the same as liftSetGNS. + void liftSet(CoverSetPtr obj, + CoverSetPtr consknap, + const ConstCoverSetPtr varset, + CoverSetPtr constraint, + double & ub, + double & initialb, + bool liftup); + + // Generates a Gu, Nemhauser, Savelsbergh lifted cover inequality. + bool GNS(const ConstConstraintPtr cons); + + // Generates a cover cut from a cover set. + CutPtr generateCut(const ConstCoverSetPtr constraint, const double ub); + + // Add the cut to the list and insert the corresponding violation to + // violation list. + void addCut(CutPtr cut); + + // Check if the same cut is already included. + bool checkExists(CoverSetPtr cov, double rhs); + + // Generates all the cover cuts from a given knapsack constraint. + void generateCuts(ConstConstraintPtr constraint); + + // Generates an extended cover from a given cover set. + void extendedCover(CoverSetPtr cover, ConstConstraintPtr cons); + + // Implementation based on Horowitz-Shahni algorithm implementation in + // CglKnapsackCover + UInt binaryKnapsackSolver(UInt n, double b, double const * c, + double const *a, double & z, int * x); + + // Calculates the violation for the given cut. + double violation(CutPtr cut); + + // Return const pointer for problem, check if this works!!!. + ConstProblemPtr getProblem() const {return ConstProblemPtr(p_);} + + // Return const knapsack list. + ConstKnapsackListPtr getKnapsackList() const + {return ConstKnapsackListPtr(knapsackListPtr_);} + + // Return const solution. + ConstSolutionPtr getSolution() const + {return ConstSolutionPtr(s_);} + + // Return const cut list. + CutVector getCutList() const + {return cutVec_;} + + // Return violation list. + DoubleVector getViolList() const + {return violList_;} + + // Return number of constraints considered. + UInt getNumCons() const {return numCons_;} + + // Return statistics of cover cut generator. + ConstCovCutGenStatsPtr getStats() const {return ConstCovCutGenStatsPtr(stats_);} + + // Initialize statistics + void initStats(); + + // Adds a cut from a given cover set and rhs by checking integrality and if + // the cut already exists. + bool addCut(CoverSetPtr cov, double rhs, UInt cuttype); + + // Return only the violated cuts. + CutVector getViolatedCutList() const + {return violatedCuts_;}; + + // Check if the given solution satisfies integrality for given problem. + bool checkIntegral(RelaxationPtr p, ConstSolutionPtr s); + + // Print inequality + void printIneq(const ConstCoverSetPtr cov, double rhs, + PrintType type, string message); + + // Print lifting problem. + void printLiftProb(const ConstCoverSetPtr obj, + const ConstCoverSetPtr consknap, + const CoverSetConstIterator variable, + double rhs, + double initialb, + bool uplift, + double b, + double gamma, + double alpha); + + private: + // Environment. + EnvPtr env_; + + // Problem that cover cuts will be generated for. + ProblemPtr p_; + + // List of cuts generated. + CutVector cutVec_; + + // List of violated cuts. + CutVector violatedCuts_; + + // List of violations obtained from cuts generated in the same order. + DoubleVector violList_; + + // List of knapsack inequalities in the problem. + KnapsackListPtr knapsackListPtr_; + + /** + * Given (possibly fractional) solution. + * Cut will be designed to violate this solution. + */ + ConstSolutionPtr s_; + + // Number of knapsack inequalities considered. + UInt numCons_; + + // Statistics for cover cut generator. + CovCutGenStatsPtr stats_; + + // Hash map that is used to check if a cut is already created or not. + std::map< std::vector, UInt> cutmap; + + // Integer tolerance. + double intTol_; + + // Objective tolerance. + double objtol_; + + // Output file. + OfstreamPtr output_; + + // Output file name + string outfile_; + }; +} + +#endif // MINOTAURCOVERCUTGENERATOR_H + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/CutInfo.h b/thirdparty/linux/include/minotaur/CutInfo.h new file mode 100644 index 0000000..1f8ab55 --- /dev/null +++ b/thirdparty/linux/include/minotaur/CutInfo.h @@ -0,0 +1,114 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2010 - 2014 The MINOTAUR Team. +// + +/** + * \file CutInfo.h + * \brief Define the Cut class for valid inequalities and additional + * information. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURCUTINFO_H +#define MINOTAURCUTINFO_H + +#include "Types.h" + +namespace Minotaur { + + class Engine; + typedef boost::shared_ptr EnginePtr; + + /** + * The Cut class is meant to manage the cutting planes generated by + * different cut generators and handlers. This is a base class and special + * classes of cuts can be derived from it. + */ + class CutInfo { + + public: + /// Default Constructor. + CutInfo(); + + /// Create a cut using a constraint. + CutInfo(ConstraintPtr c, const double* hashval); + + /// Destroy. + ~CutInfo(); + + /// By how much does a given point x violate this cut. + void evalScore(const double *x, double &vio, double &score); + + /// Write to out. + void write(std::ostream &out) const; + + /// Write to std::cout. + void write() const {write(std::cout);} + + /// Update active counts + void updateActive(bool wasactive) { + if (wasactive) { + cntSinceActive_ = 0; + numActive_++; + } + else cntSinceActive_++; + } + + /// Update viol counts + void updateViol(bool wasviol) { + if (wasviol) cntSinceViol_ = 0; + else cntSinceViol_++; + } + + /// Get basic info + UInt getCntSinceActive() { return cntSinceActive_;} + UInt getCntSinceViol() { return cntSinceViol_;} + UInt getNumActive() { return numActive_;} + double getHashVal() { return hashVal_;} + + protected: + + void evalFixedScore(); + + /// Pointer to the constraint. + ConstraintPtr cons_; + + /// True if allowed to delete the cut + bool canDelete_; + + /// For cuts in relaxation, + UInt cntSinceActive_; + + /// For cuts in pool. + UInt cntSinceViol_; + + /// Total number of relaxations where it was active. + UInt numActive_; + + /// Score. + double fixedScore_; + + /// To check duplicacy + double hashVal_; + + + }; + typedef boost::shared_ptr CutInfoPtr; + typedef std::vector< CutInfoPtr > CutInfoVector; + typedef CutInfoVector::iterator CutInfoIterator; + typedef CutInfoVector::const_iterator CutInfoConstIterator; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/CutManager.h b/thirdparty/linux/include/minotaur/CutManager.h new file mode 100644 index 0000000..8ae6c47 --- /dev/null +++ b/thirdparty/linux/include/minotaur/CutManager.h @@ -0,0 +1,173 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2010 - 2014 The MINOTAUR Team. +// + +/** + * \file CutManager.h + * \brief Manages addition and deletion of cuts to problem. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURCUTMANAGER_H +#define MINOTAURCUTMANAGER_H + +#include "Types.h" + + +namespace Minotaur { + +class Environment; +class Function; +class Problem; +class Solution; +class Cut; +class CutManager; +typedef boost::shared_ptr EnvPtr; +typedef boost::shared_ptr FunctionPtr; +typedef boost::shared_ptr ProblemPtr; +typedef boost::shared_ptr CutPtr; +typedef std::vector CutVector; +typedef CutVector::iterator CutVectorIter; +typedef boost::shared_ptr CutManagerPtr; +typedef boost::shared_ptrConstSolutionPtr; + +/** + * \brief Abstract base class to manage cuts in the relaxation. + * + * The CutManager class is meant to ``manage'' the cutting planes generated by + * different cut generators and handlers. By manage we mean: + * -# Removing cuts if they become inactive. + * -# Adding cuts from storage if violated. + * -# Adding newly generated cuts. + * -# Keeping a list of constraints that are cuts. + * This class is not meant to generate cuts (a job of CutGenerator) or even + * store them (CutStorage). + */ +class CutManager { + +public: + /// Empty constructor. + CutManager() {}; + + /// Destroy. + virtual ~CutManager() {}; + + /** + * \brief Add a cut to be managed by the cut manager. + * + * \param [in] c Cut pointer to be added. Do not change a cut after it is + * added. + */ + virtual void addCut(CutPtr c) = 0; + + /** + * \brief Add a cut + * \param [in] p Problem to add a cut to + * \param [in] f Function of the cut + * \param [in] lb Lower bound + * \param [in] ub Upper bound + * \param [in] direct_to_rel Whether add the cut directly to rel + * \param [in] never_del Whether the cut should always remain in the pool + * \return A pointer to the constraint added to rel + */ + virtual ConstraintPtr addCut(ProblemPtr p, FunctionPtr f, double lb, + double ub, bool direct_to_rel, bool never_del) + = 0; + + /** + * \brief Add a cut to be managed by the cut manager. The cut is not added + * to the problem by this function (See separate() for it). + * + * \param [in] cbeg 'Begin' iterator of the vector of cuts to be added. + * \param [in] cend 'End' iterator of the vector of cuts to be added. + */ + virtual void addCuts(CutVectorIter cbeg, CutVectorIter cend) = 0; + + /// Get the total number of cuts available to the manager. + virtual UInt getNumCuts() const = 0; + + /** + * \brief Get the total number of cuts currently enabled, i.e., added to the + * relaxation. + */ + virtual UInt getNumEnabledCuts() const = 0; + + /// Get the total number of cuts currently not enabled. + virtual UInt getNumDisabledCuts() const = 0; + + /** + * \brief Get the total number of cuts added to manager (but not to problem) + * before the last call to separate() or postSolveUpdate(). + */ + virtual UInt getNumNewCuts() const = 0; + + /** + * \brief Update information on a node which is branched. + * \param[in] NodePtr branched node. + * \param[in] ConstSolutionPtr solution of the lp solve in the node. + * \param[in] int number of children + */ + virtual void nodeIsBranched(NodePtr, ConstSolutionPtr, int) { }; + + /** + * \brief Update information when a node is processed. + * \param[in] NodePtr node which has already been processed + */ + virtual void nodeIsProcessed(NodePtr) { }; + + /** + * Updates information about the cuts after problem is solved. + * Also removes cuts from relaxation and/or the storage. + * \param[in] sol Solution from previous solve. + * \param[in] e_status Status of the engine + */ + virtual void postSolveUpdate(ConstSolutionPtr sol, EngineStatus e_status) = 0; + + /** + * \brief Separate a given point using the cuts in the storage. + * \param[in] sol Solution that needs to be separated. + * \param[out] separated True if solution is separated by cuts. False + * otherwise. + * \param[out] n_added The number of cuts added by this routine to the + * problem. + */ + virtual void separate(ProblemPtr p, ConstSolutionPtr sol, bool* separated, + UInt* n_added) = 0; + + /** + * \brief Update information of the cuts in the pool + * \param [in] problem Pointer to the relaxation problem + * \param [in] sol Solution of the LP solve + * \param [in] node Node in which information gets updated + */ + virtual void updatePool(ProblemPtr, ConstSolutionPtr) { }; + + /** + * \brief Update information about cuts in the relaxation + * \param [in] sol Solution of the LP solve + * \param [in] problem Pointer to the relaxation problem + */ + virtual void updateRel(ConstSolutionPtr, ProblemPtr) { }; + + /// Write cuts to output. + virtual void write(std::ostream &out) const = 0; + + /// Write statistics to output. + virtual void writeStats(std::ostream &out) const = 0; + +}; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/CxQuadHandler.h b/thirdparty/linux/include/minotaur/CxQuadHandler.h new file mode 100644 index 0000000..2af8150 --- /dev/null +++ b/thirdparty/linux/include/minotaur/CxQuadHandler.h @@ -0,0 +1,353 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file CxQuadHandler.h + * \brief Define the CxQuadHandler class for handling convex quadratic + * objective functions and constraints. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURCXQUADRATICHANDLER_H +#define MINOTAURCXQUADRATICHANDLER_H + +#include "Handler.h" + +namespace Minotaur { + +class Engine; +class Function; +class LinearFunction; +class Objective; +class Problem; +class QuadraticFunction; +typedef boost::shared_ptr EnginePtr; +typedef boost::shared_ptr FunctionPtr; +typedef boost::shared_ptr LinearFunctionPtr; +typedef boost::shared_ptr ObjectivePtr; +typedef boost::shared_ptr ConstProblemPtr; +typedef boost::shared_ptr QuadraticFunctionPtr; + +/// Save information about constraints of the form \f$ y \leq x^2 \f$. +struct Secant { + VariablePtr auxVar; /// The variable y. + VariablePtr sqVar; /// The variable x. + ConstraintPtr cons; /// The linear constraint that is used as approx. +}; + +/// Pointer to Secant +typedef Secant * SecantPtr; + +/// Vector-iterator for Secant +typedef std::vector< SecantPtr >::iterator SecantIterator; + +/// Map of 'x' and the secant that is used for \f$ y \leq x^2 \f$. +typedef std::map VarSecantMap; + +/// Iterator for VarSecantMap +typedef VarSecantMap::iterator VarSecantMapIter; + + +/** + * A McCormick object stores some information about McCormick inequalities + * for the constraints of the form \f$x_0x_1 \leq y\f$ or \f$x_0x_1 \geq y \f$ + * or \f$x_0x_1 = y\f$. + */ +class McCormick { +public: + /// LT: x0x1 <= y; GT: x0x1 >= y; EQ: x0x1 = y + typedef enum { + LT, + GT, + EQ + } Sense; + +private: + /// First variable. + VariablePtr x0_; + + /// Second variable. + VariablePtr x1_; + + /// Auxiliary variable. + VariablePtr y_; + + /// Greater than, less than or equal to. + Sense s_; + + /// Constraint 0. + ConstraintPtr c0_; + + /// Constraint 1. + ConstraintPtr c1_; + + /// Constraint 2. + ConstraintPtr c2_; + + /// Constraint 3. + ConstraintPtr c3_; + +public: + /// Default constructor. + McCormick(VariablePtr x0, VariablePtr x1, Sense sense); + + /// Destroy. + ~McCormick(); + + /** + * Set the auxiliary variable. If a bilinear term repeats itself, all + * such terms must share the same auxiliary variable. + */ + void setAux(VariablePtr y) {y_ = y;}; + + /// Set the zeroth constraint: \f$ y \geq l_0x_1 + l_1x_0 - l_1l_0 \f$. + void setC0(ConstraintPtr c) {c0_ = c;}; + + /// Set the first constraint: \f$ y \geq u_0x_1 + u_1x_0 - u_1u_0 \f$. + void setC1(ConstraintPtr c) {c1_ = c;}; + + /// Set the third constrait: \f$ y \leq u_1x_0 + l_0x_1 - l_0u_1 \f$. + void setC2(ConstraintPtr c) {c2_ = c;}; + + /// Set the third constrait: \f$ y \leq l_1x_0 + u_0x_1 - l_1u_0 \f$. + void setC3(ConstraintPtr c) {c3_ = c;}; + + /// Get one of the four constraints. + ConstraintPtr getC0() {return c0_;}; + ConstraintPtr getC1() {return c1_;}; + ConstraintPtr getC2() {return c2_;}; + ConstraintPtr getC3() {return c3_;}; + + /// Get the auxiliary variable. + VariablePtr getAux() {return y_;}; + + /// Get \f$x_0\f$ + VariablePtr getX0() {return x0_;}; + + /// Get \f$x_1\f$ + VariablePtr getX1() {return x1_;}; + + /// Get the variable other than x, in the product. + VariablePtr getOtherX(ConstVariablePtr x) const; + + /// Get the sense of the bilinear constraint: LT, EQ, GT. + Sense getSense() {return s_;}; + + /// Set the sense of the bilinear constraint: LT, EQ, GT. + void setSense(Sense sense) {s_ = sense;}; + + /// Check if a bilinear constraint is violated at the current point x. + bool isViolated(const double *x, const double &tol) const; + + /** + * Check if a bilinear constraint is violated for the given values of + * \f$x_0, x_1, y\f$. + */ + bool isViolated(const double &x0val, const double &x1val, + const double &y0val, const double &tol) const; +}; +/// shared pointer to McCormick object. +typedef boost::shared_ptr McCormickPtr; + +/** + * Compare two McCormick objects. Since we keep them in a set, we need to + * sort them. We use lexicographic ordering (i.e. based on ids of + * \f$(x_0, x_1)\f$). + */ +struct CompareMcCormick { + bool operator()(McCormickPtr b0, McCormickPtr b1) const; +}; + +/// A set of McCormick objects. +typedef std::set McCormickSet; + +/// Iterator of McCormick objects over a set. +typedef McCormickSet::iterator McCormickSetIter; + + +/** + * An CxQuadHandler handles the convex parts of quadratic functions of a + * problem. For now, we will just handle squares of singleton variables e.g. + * \f$\sum_ix_i^2 \leq u_0\f$. \f$u_0\f$ could be an auxiliary varible or a + * constant. Later we will introduce sums of squares of + * general linear functions as well. + */ +class CxQuadHandler : public Handler { +protected: + /** + * For each constraint of the type \f$y \leq x^2\f$, we add a new + * secant approximation. This map stores the 'y' variables and the + * associated linear secant-constraint. + */ + VarSecantMap cvCons_; + + /** + * Keep a set of McCormick inequalities that were added and for which + * we will update the co-efficients etc. + */ + McCormickSet mcCons_; + + /** + * Variables that occur in bilinear terms and also concave square terms. + * These do not include auxiliary variables that are added in relaxation. + * These are all the candidates that we consider for branching. + */ + VarSet brVars_; + + /// Tolerance. + double eTol_; + + /// Logger. + LoggerPtr logger_; + + /// For printing. + static const std::string me_; + + /// Original problem. + ProblemPtr problem_; + + /** + * Add quadratic/linear relaxations of the quadratic range constraint + * 'cons'. + */ + void relaxTwoSided_(QuadraticFunctionPtr qf, ConstraintPtr cons, + RelaxationPtr rel); + + /** + * Add quadratic/linear relaxations of the quadratic constraint 'cons' + * that only has an upperbound. + */ + void relaxOneSided_(QuadraticFunctionPtr qf, ConstraintPtr cons, + RelaxationPtr rel); + + /// Relax the objective function, to make it convex + void relaxObj_(ObjectivePtr obj, RelaxationPtr rel); + + /** + * Get secant approximation for the inequality: + * \f$ y - x^2 \leq 0\f$, and add it to the relaxation. + */ + void addSecant_(VariablePtr x, VariablePtr y, RelaxationPtr rel); + + /// Get linear function and right hand side (r) for a secant constraint. + LinearFunctionPtr getNewSecantLf_(VariablePtr x, VariablePtr y, + double & lb, double & ub, double & r); + + /// Add all four McCormick inequalities for \f$ y = x_0x_1\f$. + VariablePtr addMcCormick_(VariablePtr x0, VariablePtr x1, + RelaxationPtr rel); + + /// Add two McCormick inequalities for \f$ y \geq x_0x_1\f$. + VariablePtr addMcCormickLower_(VariablePtr x0, VariablePtr x1, + RelaxationPtr rel); + + /// Add two McCormick inequalities for \f$ y \leq x_0x_1\f$. + VariablePtr addMcCormickUpper_(VariablePtr x0, VariablePtr x1, + RelaxationPtr rel); + + /// Generate the appropriate McCormick inequality using the bounds. + LinearFunctionPtr getMcLf_(VariablePtr x0, double lb0, double ub0, + VariablePtr x1, double lb1, double ub1, VariablePtr y, + double &rhs, UInt i); + + void binToLin_(); + void binToLinFun_(FunctionPtr f, LinearFunctionPtr lf2); + + /** + * For now, this handler will introduce a new variable for each sum of + * squares of variables. We will also add constraints, that have these + * functions, from the original problem if such constraints have not + * already been added. If these constraints are already in the problem, + * we will add the corresponding new variable in the linear function of + * the constraint. Bounds: \f$ u_O \in [0,\sum_i\max(lb_i^2, ub_i^2)\f$]. + */ + void relax_(RelaxationPtr rel, bool *is_inf); + + void removeFixed_(); + void removeFixedFun_(FunctionPtr f, LinearFunctionPtr lf2, double *c); +public: + /// Default constructor. + CxQuadHandler(EnvPtr env, ProblemPtr problem); + + /// Destroy + ~CxQuadHandler(); + + // Does nothing. + void relaxInitFull(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxInitInc(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf); + + + /** + * Suppose we added a variable \f$u_0 \geq \sum_i x_i^2\f$. In this + * function, check if at a given point, \f$(u_0^*, x^*)\f$, the above + * constraint holds or not. Return true if the constraint holds, false + * otherwise. Checks the conditions for all such constraints but stops + * at the first infeasible one. + */ + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool &is_inf, double &inf_meas); + + /** + * Not implemented yet. + */ + void separate(ConstSolutionPtr sol, NodePtr node, RelaxationPtr rel, + CutManager *cutman, SolutionPoolPtr s_pool, bool *sol_found, + SeparationStatus *status); + + + /// Return \f$u_0\f$ it is constrained to be an integer. + void getBranchingCandidates(RelaxationPtr rel, + const DoubleVector &x, ModVector &mods, + BrVarCandSet &cands, BrCandVector &, + bool & is_inf); + + // Implement Handler::getBrMod(). + ModificationPtr getBrMod(BrCandPtr cand, DoubleVector &x, + RelaxationPtr rel, BranchDirection dir); + + // Implement Handler::getBranches(). + Branches getBranches(BrCandPtr cand, DoubleVector & x, + RelaxationPtr rel, SolutionPoolPtr s_pool); + + // presolve. + SolveStatus presolve(PreModQ *pre_mods, bool *changed); + + // Implement Handler::presolveNode(). + bool presolveNode(RelaxationPtr rel, NodePtr node, + SolutionPoolPtr s_pool, ModVector &p_mods, + ModVector &r_mods); + + // Write name + std::string getName() const; + +}; + +/// Shared pointer to CxQuadHandler. +typedef boost::shared_ptr CxQuadHandlerPtr; + +/// Shared pointer to const CxQuadHandler. +typedef boost::shared_ptr CxQuadConstHandlerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/CxUnivarHandler.h b/thirdparty/linux/include/minotaur/CxUnivarHandler.h new file mode 100644 index 0000000..3205381 --- /dev/null +++ b/thirdparty/linux/include/minotaur/CxUnivarHandler.h @@ -0,0 +1,285 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file CxUnivarHandler.h + * \brief Define the CxUnivarHandler class for handling convex univariate + * functions. + * \author Ashutosh Mahajan, Argonne National Laboratory and Jim Luedtke, + * UW-Madison + */ + +#ifndef MINOTAURCXUNIVARHANDLER_H +#define MINOTAURCXUNIVARHANDLER_H + +#include "Handler.h" + +namespace Minotaur { + + class Engine; + class Function; + class LinearFunction; + class Objective; + class Problem; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr FunctionPtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr ObjectivePtr; + typedef boost::shared_ptr ConstProblemPtr; + + + class CxUnivarConstraintData { + + protected: + + /// Tolerance for constraint violation. + double eTol_; + + /// Tolerance for when upper and lower bounds considered equal. + double vTol_; + + /// This is the constraint of the orginal problem + ConstraintPtr con_; + + /// Input variable, i.e., x in y = f(x) + /// This should be a pointer to the `original' variable, look at + /// corresponding bounds in the relaxation to get bounds + ConstVariablePtr iv_; + + // Points to the relaxation version of the input variable + // Updated only after relaxInit is called + VariablePtr riv_; + + /// Output variable, i.e., y in y = f(x) + /// This is a pointer to the `original' variable + ConstVariablePtr ov_; + + // Points to the relaxation version of the output variable + // Updated only after relaxInit is called + VariablePtr rov_; + + /// 'L' => y <= f(x), so only add secants + /// 'G' -> y >= f(x), so only add linearizations + /// 'E' -> y == f(x), so do both + char sense_; + + /// Secant constraint in the relaxation + ConstraintPtr secCon_; + + /// Array of linearization constraints in the relaxation + ConstraintVector linCons_; + + public: + + /// Creates initial relaxations + void initRelax(RelaxationPtr rel, DoubleVector& tmpX, DoubleVector& grad); + + /// Update the current relaxation based on current variable bounds + void updateRelax(RelaxationPtr rel, DoubleVector& tmpX, DoubleVector& grad, + ModVector &mods); + + bool isFeasible(const double* x); + + double getViol(const std::vector< double > & x); + + // Creates and adds the secant inequality defined by current constraint to + // the relaxation + // Returns the constraint that was added, which may be null if it was not + // possible to add a constraint (e.g., due to an infinite bound) + void addSecant(RelaxationPtr rel, ConstVariablePtr iv, + ConstVariablePtr ov, FunctionPtr fn, DoubleVector& tmpX, + bool init, ModVector &mods); + + // Creates and adds linearization inequalities to approximate the lower + // envelope of the convex function + // Returns a vector of constraints that were added + void addLin(RelaxationPtr rel, ConstVariablePtr iv, + ConstVariablePtr ov, FunctionPtr fn, + DoubleVector& tmpX, DoubleVector& grad, bool init, + ModVector &mods); + + ConstraintPtr getOriginalCon() const { return con_; } + ConstraintPtr getSecantCon() const { return secCon_; } + + ConstVariablePtr getROutVar() const { return rov_; } ; + + ConstVariablePtr getRInputVar() const { return riv_; } ; + + //ConstraintVector & getLinCons + ConstraintIterator linConsBegin() { return linCons_.begin(); } + ConstraintIterator linConsEnd() { return linCons_.end(); } + + + char getSense() { return sense_; } ; + + /// Default constructor. + CxUnivarConstraintData(double eTol, double vTol, ConstraintPtr newcon, ConstVariablePtr ovar, + ConstVariablePtr ivar, char sense); + + /// Destroy + ~CxUnivarConstraintData() {}; + + + }; + + typedef boost::shared_ptr CxUnivarConstraintDataPtr; + typedef std::vector CxUnivarConstraintDataVector; + typedef CxUnivarConstraintDataVector::iterator CxUnivarConstraintIterator; + + + /** + * An CxUnivarHandler handles convex univariate functions. The upper relaxation is + * handled with the single secant inequality, the lower relaxation is handled + * with linearizations. + */ + + /** + * TODO: This class could easily be extended to handle perspective cuts if a binary varaible is known which turns off the input variable + * + */ + class CxUnivarHandler : public Handler { + + + protected: + + /// Tolerance for constraint violation. + double eTol_; + + /// Tolerance for when upper and lower bounds considered equal. + double vTol_; + + /// Original problem. + ProblemPtr problem_; + + /// Logger. + LoggerPtr logger_; + + /// For printing. + static const std::string me_; + + /// Internal data associated with each constraint + CxUnivarConstraintDataVector cons_data_; + + /// A temporary vector of zeros, for evaluating functions + DoubleVector tmpX_; + + /// A temporary vector of zeros, for getting gradients + DoubleVector grad_; + + public: + /// Default constructor. + CxUnivarHandler(EnvPtr env, ProblemPtr problem); + + /// Destroy + ~CxUnivarHandler(); + + /** + * Adds constraint to list (as all handlers), but also constructs the + * associated constraint data. + */ + void addConstraint(ConstraintPtr newcon, ConstVariablePtr ivar, + ConstVariablePtr ovar, char sense = 'E'); + + // base class method. + void addConstraint(ConstraintPtr ) { assert(0); }; + + /** + * For this handler, nothing is different at root or any node when doing full + * relax + */ + void relaxInitFull(RelaxationPtr /*rel*/, bool* /* is_inf */) {}; + + void relaxInitInc(RelaxationPtr rel, bool* is_inf); + + /** + * Check feasibility. + */ + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool &should_prune, double &inf_meas); + + /** + * Not implemented yet. Eventually, could add violated linearization + * inequalities for underestimator portion + */ + void separate(ConstSolutionPtr sol, NodePtr node, RelaxationPtr rel, + CutManager *cutman, SolutionPoolPtr s_pool, bool *sol_found, + SeparationStatus *status); + + + /** + * Create a relaxation by adding the secant inequality for the upper estimator, + * and some number of linearization inequalities, at a minimum from the end + * points + */ + virtual void relaxNodeFull(NodePtr /* node */, RelaxationPtr /* rel */, + bool* /* should_prune */) {} ; + + /** + * Create a relaxation by updating the secant inequality for the upper + * estimator, and adding lineariations at the end points, if they are new + */ + virtual void relaxNodeInc(NodePtr node, RelaxationPtr rel, + bool* isInfeasible); + + // base class method + virtual void getBranchingCandidates(RelaxationPtr rel, const DoubleVector &x, + ModVector &mods, BrVarCandSet &cands, + BrCandVector &gencands, bool & is_inf); + + // Implement Handler::getBrMod(). + virtual ModificationPtr getBrMod(BrCandPtr cand, DoubleVector &x, + RelaxationPtr rel, BranchDirection dir); + + // Implement Handler::getBranches(). + virtual Branches getBranches(BrCandPtr cand, DoubleVector & x, + RelaxationPtr rel, SolutionPoolPtr s_pool); + + // presolve. + virtual SolveStatus presolve(PreModQ *pre_mods, bool *changed); + + // Implement Handler::presolveNode(). + virtual bool presolveNode(RelaxationPtr p, NodePtr node, + SolutionPoolPtr s_pool, ModVector &p_mods, + ModVector &r_mods); + + + // Write name + virtual std::string getName() const; + + private: + // Helper functions + BranchPtr doBranch_(BranchDirection UpOrDown, ConstVariablePtr v, + double bvalue); + + + + }; + + /// Shared pointer to CxUnivarHandler. + typedef boost::shared_ptr CxUnivarConstraintDataPtr; + + /// Shared pointer to const CxUnivarHandler. + typedef boost::shared_ptr + CxUnivarConstConstraintDataPtr; + + /// Shared pointer to CxUnivarHandler. + typedef boost::shared_ptr CxUnivarHandlerPtr; + + /// Shared pointer to const CxUnivarHandler. + typedef boost::shared_ptr CxUnivarConstHandlerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Eigen.h b/thirdparty/linux/include/minotaur/Eigen.h new file mode 100644 index 0000000..0216632 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Eigen.h @@ -0,0 +1,249 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Eigen.h + * \brief Declare methods and data structures of Eigen class for computing + * eigen values and vectors of a matrix. + * \author Ashutosh Mahajan, IIT Bombay + */ + + +#ifndef MINOTAUREIGEN_H +#define MINOTAUREIGEN_H + +#include "LinearFunction.h" +#include "QuadraticFunction.h" + +namespace Minotaur { + + class QuadraticFunction; + typedef boost::shared_ptr QuadraticFunctionPtr; + typedef boost::shared_ptr ConstQuadraticFunctionPtr; + //class EigenVector; + //typedef boost::shared_ptr EigenVectorPtr; + //typedef LinearFunction EigenVector; + //typedef LinearFunctionPtr EigenVectorPtr; + typedef std::pair EigenPair; + typedef std::vector::const_iterator EigenPairConstIterator; + + class Eigen; + typedef boost::shared_ptr EigenPtr; + + // /** + // In Minotaur, EigenVectors are used only in the context of quadratic + // functions. Thus an Eigen Vector is just a linear function. + // */ + // class EigenVector { + // public: + // // /** + // // Default constructor + // // */ + // EigenVector(); + + // // /** + // // Destroy + // // */ + // ~EigenVector() {} + + // // /** + // // Display the nonzero coefficients of the eigen vector. + // // */ + // void write(std::ostream &s) const; + + // private: + // // /** + // // The vector + // // */ + // LinearFunctionPtr lf_; + // }; + + + // /** + // The EigenCalculator class is used to calculate eigen vectors and values + // for matrices and other objects that have an associated matrix (like a + // quadratic). + // */ + class EigenCalculator { + public: + + /// Default constructor + EigenCalculator(); + + /// Destroy + ~EigenCalculator() {}; + + /// Calculate EigenValues only + EigenPtr findValues(ConstQuadraticFunctionPtr qf); + + /// Calculate EigenValues for a full dense matrix. H is a square symmetric + /// array of arrays. Its size is nxn. + EigenPtr findValues(int n, double** H); + + /// Calculate EigenVectors as well + EigenPtr findVectors(ConstQuadraticFunctionPtr qf); + + // /** + // Let qf = x'Ax, lf = cx. First find eigen vectors of the hessian of + // qf. Then, x'Ax = x'QRERQ'x, where Q is orthogonal (QQ' = I). R is a + // diagonal matrix with i-th diagonal element being the square root of + // i-th eigen value. E has entries 1,-1 along the diagonal. Let y = + // RQ'x. Then c'x = c'QR^(-1)y = b'y. b = R^(-1)Q'c. This function + // calculates Q, RER, b. + // + // The "x" vectors in qf and lf are not the same. e.g. x0*x0 + x1*x1 + + // 2x0*x1 + 2x0 + x2 + x3. here lf does not contain x1 and has extra + // variables x2 and x3. The vector 'c' thus corresponds to only 2x0 and + // we get: 1*(x0 + x1)^2 + 0*(x0 - x1)^2 + 1*(x0+x1) + 1*(x0-x1) + x2 + + // x3. p_terms will thus have (x0 + x1 + 0.5)^2, n_terms will have + // terms that have negative eigen values. lin_terms will have + // x0-x1+x2+x3 and cb = -0.25. + // */ + void getSumOfSquares ( + std::vector & p_terms, + std::vector & n_terms, + std::vector & p_const, + std::vector & n_const, + LinearFunctionPtr & lin_terms, double & c, + ConstQuadraticFunctionPtr qf, + ConstLinearFunctionPtr lf); + + private: + + /** + \brief The quadratic function for whose Hessian we wish to find the eigen + values. + */ + ConstQuadraticFunctionPtr qf_; + + /// Dimension of the square matrix + UInt n_; + + /** + \brief The square matrix is stored as a single array. The element A[i,j] + can be accessed at A_[i+j*n_]. And element A_[i] = A[i mod n_, i/n_]. + */ + double *A_; + + /// Number of eigen values found. + int m_; + + /** + The absolute error tolerance for the eigenvalues. An approximate + eigenvalue is accepted as converged when it is determined to lie in an + interval [a,b] of width less than or equal to + ABSTOL + EPS * max(|a|,|b|) + */ + double abstol_; + + /// N for eigen values only, V for values and vectors. + char findVectors_; + + /// Array where the eigen vectors are stored by LAPACK. + double *w_; + + // /** + // the first M columns of z contain the orthonormal eigenvectors of the + // matrix A corresponding to the selected eigenvalues, with the i-th + // column of Z holding the eigenvector associated with W(i). If JOBZ = + // 'N', then Z is not referenced. Note: the user must ensure that at + // least max(1,M) columns are supplied in the array Z; if RANGE = 'V', + // the exact value of M is not known in advance and an upper bound must + // be used. Supplying N columns is always safe. + // */ + double *z_; + + // /** + // The i-th eigenvector is nonzero only in elements + // ISUPPZ( 2*i-1 ) through ISUPPZ( 2*i ). + // */ + int *isuppz_; + + /// A map of what is the index in matrix A_ of a variable + std::map indices_; + + /// What variable does column 'i' of matrix A_ represent. + std::vector vars_; + + /// Dot product of coefficients of two linear functions + double getDotProduct_(ConstLinearFunctionPtr lf1, + ConstLinearFunctionPtr lf2); + + /// Call Lapack routines to calculate the values. + void calculate_(); + + /** + \brief Allocate the A_ matrix and fill in the values from the quadratic + function qf. + */ + void fillA_(); + + /** + \brief Get eigen values and (if calculated) eigen vectors from the + calculator. + */ + EigenPtr getEigen_(); + + /// Construct a linear function based on the eigen vectors of A_. + LinearFunctionPtr getLinearFunction_(const int i); + }; + + class Eigen { + public: + /// Default constructor + Eigen(); + + /// Add an eigen value and an eigen vector to the current list. + void add(double value, LinearFunctionPtr e_vector); + + /// Get the number of negative eigen values + UInt numNegative() const; + + /// Get the number of zero eigen values + UInt numZero() const; + + /// Get the number of positive eigen values + UInt numPositive() const; + + /// Get the first evPair + EigenPairConstIterator begin() const; + + /// Get the last evPair + EigenPairConstIterator end() const; + + /// Display the values and the vectors. + void write(std::ostream &s) const; + + private: + /** + \brief Each item in this vector is a pair of an eigen value and the + corresponding vector. + */ + std::vector evPairs_; + + /// Number of negative eigen values. + UInt neg_; + + /// Number of eigen values that are zero. + UInt zero_; + + /// Number of positive eigen values. + UInt pos_; + }; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Engine.h b/thirdparty/linux/include/minotaur/Engine.h new file mode 100644 index 0000000..84d0102 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Engine.h @@ -0,0 +1,203 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Engine.h + * \brief Define the base class Engine. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURENGINE_H +#define MINOTAURENGINE_H + +#include "Types.h" + +namespace Minotaur { + + class Constraint; + class Function; + class LinearFunction; + class NonlinearFunction; + class Solution; + class WarmStart; + class Engine; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ConstEnginePtr; + typedef boost::shared_ptr FunctionPtr; + typedef boost::shared_ptr ConstraintPtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr NonlinearFunctionPtr; + typedef boost::shared_ptr ConstSolutionPtr; + typedef boost::shared_ptr WarmStartPtr; + typedef boost::shared_ptr ConstWarmStartPtr; + + /** + * An Engine is a solver that can solve a Problem. In most invocations of an + * engine, we will solve a Relaxation. This is an abstract base class and all + * engines are implemented are derived from here. + */ + class Engine { + + public: + /// Default constructor. + Engine(); + + /// Destroy. + virtual ~Engine(); + + /// Add a new constraint to the engine. + virtual void addConstraint(ConstraintPtr) = 0; + + /// Change a bound of a constraint. + virtual void changeBound(ConstraintPtr cons, BoundType lu, + double new_val) = 0; + + /// Change a bound of a variable. + virtual void changeBound(VariablePtr var, BoundType lu, double new_val) + = 0; + + /// Change both bounds of a variable. + virtual void changeBound(VariablePtr var, double new_lb, double new_ub) + = 0; + + /** + * \brief Change the linear function, and the bounds of a constraint. + * \param [in] c Original constraint that is to be changed. + * \param [lf] The new linear function. + * \param [lb] The new lower bound. + * \param [ub] The new upper bound. + */ + virtual void changeConstraint(ConstraintPtr c, LinearFunctionPtr lf, + double lb, double ub) = 0; + + /** + * \brief Change the nonlinear function, and the bounds of a constraint. + * \param [in] c Original constraint that is to be changed. + * \param [nlf] The new nonlinear function. + */ + virtual void changeConstraint(ConstraintPtr c, NonlinearFunctionPtr nlf) = 0; + + /// Change objective function. + virtual void changeObj(FunctionPtr f, double cb) = 0; + + /// Clear the loaded problem, if any, from the engine. + virtual void clear() = 0; + + /// Restore settings after strong branching. + virtual void disableStrBrSetup() = 0; + + /// Get a fresh copy of the engine, without the problem loaded into it. + virtual EnginePtr emptyCopy() {return EnginePtr();} // NULL by default. + + /// Make settings for strong branching. + virtual void enableStrBrSetup() = 0; + + /// Get the solution obtained after solving the problem. + virtual ConstSolutionPtr getSolution() = 0; + + /// Get the solution value. + virtual double getSolutionValue() = 0; + + /// Solve the problem that was loaded previously. + virtual EngineStatus solve() = 0; + + /// Get the name. + virtual std::string getName() const = 0; + + /// Get the status of the last solve command. + virtual EngineStatus getStatus() = 0; + + /// Return a string that describes the status in simple words. + virtual std::string getStatusString(); + + /** + * Get warm start information from the engine. This warm start + * information can change if the engine is used to solve something else + * again. + */ + virtual ConstWarmStartPtr getWarmStart() = 0; + + /** + * Get a full copy of warm start information from the engine. Does not + * change even if the engine starts solving something else later on. + */ + virtual WarmStartPtr getWarmStartCopy() = 0; + + /** + * Initialize the engine to solve the given problem. Memory is + * allocated in this function. + */ + virtual void load(ProblemPtr problem) = 0; + + /** + * Use warm start information for solving the next problem. + * May Create a copy of WarmStart and use the + * copy inside the engine; the copy (but not the original) gets updated + * after solving a relaxation. + */ + virtual void loadFromWarmStart(const WarmStartPtr ws) = 0; + + /// Negate the objective function. Min f is changed to Min -f. + virtual void negateObj() = 0; + + /// Return pointer to the log manager + virtual LoggerPtr getLogger() { return logger_; } + + /** + * \brief Delete constraints from the engine. + * + * \param [in] delcons A vector of constraint pointers that should be + * deleted from the engine. + */ + virtual void removeCons(std::vector &delcons) = 0; + + /// Reset the iteration limit to maximum possible. + virtual void resetIterationLimit() = 0; + + /** + * Set a limit on number of iterations. For strong-branching, for + * instance. + */ + virtual void setIterationLimit(int limit) = 0; + + /// Set a new log manager + virtual void setLogger(LoggerPtr logger) { logger_ = logger; } + + /// Set options to solve the NLP only once or very few times, with + /// possibly several changes. + virtual void setOptionsForSingleSolve() {}; + + /// Set options to solve the NLP repeatedly, with few changes. + virtual void setOptionsForRepeatedSolve() {}; + + /** + * Write statistics to the logger. If the log level is too low, no + * statistics may be written. + */ + virtual void writeStats(std::ostream &) const {}; + + protected: + /// Status of the last solve. + EngineStatus status_; + + /// Keep log. + LoggerPtr logger_; + +}; + +} + +#endif +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/EngineFactory.h b/thirdparty/linux/include/minotaur/EngineFactory.h new file mode 100644 index 0000000..779a173 --- /dev/null +++ b/thirdparty/linux/include/minotaur/EngineFactory.h @@ -0,0 +1,70 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file EngineFactory.h + * \brief Declare EngineFactory class for creating different engines. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURENGINEFACTORY_H +#define MINOTAURENGINEFACTORY_H + +#include "Types.h" + +namespace Minotaur { + + class Engine; + class LPEngine; + class NLPEngine; + class QPEngine; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr LPEnginePtr; + typedef boost::shared_ptr NLPEnginePtr; + typedef boost::shared_ptr QPEnginePtr; + + class EngineFactory { + public: + /// Default constructor + EngineFactory(); + + /// Constructor with minotaur environment. + EngineFactory(EnvPtr env); + + /// Destroy. + ~EngineFactory(); + + /// Get an engine. Returns NULL if no engine is available. + EnginePtr getEngine(); + + /// Get an LP Engine + LPEnginePtr getLPEngine(); + + /// Get a QP Engine. Returns NULL if none available. + QPEnginePtr getQPEngine(); + + /// Get an NLP Engine. Returns NULL if none available. + NLPEnginePtr getNLPEngine(); + + private: + /// Minotaur Environment. + EnvPtr env_; + }; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Environment.h b/thirdparty/linux/include/minotaur/Environment.h new file mode 100644 index 0000000..bc7e37e --- /dev/null +++ b/thirdparty/linux/include/minotaur/Environment.h @@ -0,0 +1,170 @@ +// +// MINOTAUR -- It's only half bull! +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Environment.h + * \brief Define the Environment class. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef ENVIRONMENT_H +#define ENVIRONMENT_H + +#include "Types.h" + +namespace Minotaur { + + class Interrupt; + class Timer; + class TimerFactory; + + /** + * The environment is a container class that has pointers to the + * Logger, interrupt handler, timer factory and options that need to be + * passed to Minotaur. + */ + class Environment { + public: + /// Default constructor. + Environment(); + + /// Destroy. + ~Environment(); + + /// Get the logger that is setup for the whole environment. + LoggerPtr getLogger() const; + + /// Get the current log level + LogLevel getLogLevel() const; + + /// Get a new timer. The calling function has to free this timer. + Timer *getNewTimer(); + + /// Get the options database. + OptionDBPtr getOptions(); + + /** + * Get the time from the 'global timer' i.e. the total time consumed so + * far. + * + * \param[out] err 0 if no error occured, positive otherwise. + * \return The time used so far. + */ + double getTime(int &err); + + /** + * \brief Get the global timer. + * + * \return The timer used to query the time elapsed since the solver + * started. + */ + const Timer* getTimer(); + + /// Get the version string + std::string getVersion(); + + /// Read the options using a char array that has 'argc' words in it. + void readOptions(int argc, char **argv); + + /// Read options from a string. + void readOptions(const std::string &str); + + /// Set the log level of the default logger + void setLogLevel(LogLevel l); + + /** + * \brief Start a 'global' timer that can be queried for the total time used + * so far by the solution process. + * + * \param[out] err 0 if no error occured, positive otherwise. + */ + void startTimer(int &err); + + /** + * \brief Stop the 'global' timer. + * + * \param[out] err 0 if no error occured, positive otherwise. + */ + void stopTimer(int &err); + + private: + /// Logger that is used for the whole environment. + LoggerPtr logger_; + + /// For log: + static const std::string me_; + + /// The options database + OptionDBPtr options_; + + /// The global timer + Timer *timer_; + + /// The generator that is used to build timers. + TimerFactory *timerFac_; + + /// Add an option to the database. + void convertAndAddOneOption_(BoolOptionPtr &b_option, + IntOptionPtr &i_option, + DoubleOptionPtr &d_option, + StringOptionPtr &s_option, + FlagOptionPtr &f_option, + std::string &name, + std::string &value, + std::ostringstream &logstr); + + /// Create default set of options + void createDefaultOptions_(); + + /* + * Find an option with the provided name. The option is option of that + * type is returned and all others are NULLed. + */ + void findOption_(const std::string &name, BoolOptionPtr &b_option, + IntOptionPtr &i_option, DoubleOptionPtr &d_option, + StringOptionPtr &s_option, FlagOptionPtr &f_option); + + /** + * Return true if the string "str" corresponds to true. ("T", "TRUE", + * "Y", "YES", "1", or their lower case equivalents). Returns false + * otherwise. + */ + bool getBoolValue_(const std::string & str); + + /** + * Reach options from config file and increment the number of + * instances. + */ + void readConfigFile_(std::string fname, UInt &num_p); + + /** + * Remove leading dashes "--" or "-" from front of a string. Returns + * the number of dashes removed. The string "name" is modified. + */ + UInt removeDashes_(std::string &name); + + /// Remove the string "minotaur." from front of a string. + void removeMinotaurPrepend_(std::string & fullname); + + /** + * Remove the substring that follows '=' sign in 'name' and return the + * substring. + */ + std::string separateEqualToArg_(std::string &name); + }; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Exception.h b/thirdparty/linux/include/minotaur/Exception.h new file mode 100644 index 0000000..a5ac3fe --- /dev/null +++ b/thirdparty/linux/include/minotaur/Exception.h @@ -0,0 +1,34 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + + +#ifndef MINOTAUREXCEPTION_H +#define MINOTAUREXCEPTION_H + +namespace Minotaur { + class Exception { + public: + Exception() { } + Exception(const Exception&) { } // Copy constructor + virtual ~Exception() { } // Destructor + + private: + Exception& operator=(const Exception&); // Copy assignment + }; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/FeasibilityPump.h b/thirdparty/linux/include/minotaur/FeasibilityPump.h new file mode 100644 index 0000000..4cd465b --- /dev/null +++ b/thirdparty/linux/include/minotaur/FeasibilityPump.h @@ -0,0 +1,253 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// +/** + * \file FeasibilityPump.h + * \brief Declare the class FeasibilityPump derived from base class Heuristic. + * \author Jayash Koshal, Argonne National Laboratory + */ + +#ifndef FEASIBILITYPUMP_H +#define FEASIBILITYPUMP_H + +#include "Heuristic.h" + +namespace Minotaur { + class Engine; + class Problem; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ProblemPtr; + + /// statistics for Feasibility Pump heuristic + struct FeasPumpStats { + UInt numNLPs; /// Number of NLPs solved in the heuristic + UInt errors; /// Number of errors in NLP solved + UInt numCycles; /// Number of time the same solution was obtained + double time; /// Total time taken by the heuristic + double bestObjValue; /// Best objective value of the feasible solution + }; + + /** + * \brief Feasibility Pump for MINLPs + * + * A Feasibility Pump heuristic used to find solutions for Mixed + * Integer NLPs by solving a relaxed NLP using an NLP engine. After an + * initial solve a sequence of points are found which are closest to + * the nearest integer solution obtained by rounding the previous + * point. + */ + + class FeasibilityPump : public Heuristic { + + public: + + /// default constructor + FeasibilityPump(EnvPtr env, ProblemPtr p, EnginePtr e); + + /// constructor for derived class + FeasibilityPump(EnvPtr env, ProblemPtr p, EnginePtr nlpe, EnginePtr + e); + + /// default destructor + virtual ~FeasibilityPump(); + + /// call to the heuristic + void solve(NodePtr node, RelaxationPtr rel, SolutionPoolPtr s_pool); + + /// write statistic to the logger + void writeStats(std::ostream &out) const; + + protected: + + /// Message name for the heuristic + const static std::string me_; + + /// Binary/integer variables present in the problem + VarVector bins_; + + /// Pointer to the engine to be used to solve the problem + EnginePtr e_; + + /// Pointer to the environment + EnvPtr env_; + + /// Vector for hash value of solutions + DoubleVector hashVal_; + + /// Tolerance for a number to be considered as an integer + double intTol_; + + /// Pointer to the logger + LoggerPtr logger_; + + /// Number of variables to be flipped if cycling is detected + UInt nToFlip_; + + /// Pointer to the problem being solved + ProblemPtr p_; + + /// A random vector for inner product with the solution + DoubleVector random_; + + /// Vector of rounded solution + DoubleVector roundedSol_; + + /// Statistics for the Feasibility Pump heuristic + FeasPumpStats* stats_; + + /// Timer of the heuristic + Timer* timer_; + + /** + * \brief Function to construct/update the objective function + * + * \param[in] prob Pointer to the cloned problem + * \param[in] sol Pointer to the solution of relaxation that was + * previously solved. + * + * This function selects the variable which are fractional and + * construct the objective function out of such variables. The + * new objective function replaces the objective of the problem + * passed + */ + virtual void constructObj_(ProblemPtr prob, ConstSolutionPtr sol); + + /** + * \brief Function to convert a solution of the cloned problem to + * that of an original problem + * + * \param[in] s_pool Pointer to solution pool of original problem + * \param[in] sol Solution pointer to the modified (cloned) + * problem + * + * The binary variables are fixed by changing their bounds in the + * original problem and then the original problem is resolved to + * obtain a feasible solution. Bounds are relaxed at the end. + */ + void convertSol_(SolutionPoolPtr s_pool, ConstSolutionPtr sol); + + /** + * \brief A search function for detection of cycling + * + * \param[in] find_value Value to be located in a vector containing + * hash values of already visited rounded solutions + * + * \return true If the point already exist implying cycling + * and false otherwise + */ + bool cycle_(double find_value); + + /** + * \brief A function to hash the solutions + * + * \return The hash value of the solution + * + * A hashing function which calculates the inner product of vector + * x with a FIXED random vector in (0,1]^n. This function uses the + * roundedSol_ vector and random_ vector to calculate the hash value + */ + double hash_(); + + /** + * \brief Function to implement the Feasibility Pump method + * + * \param[in] Constant pointer to primal solution + * \param[in] Pointer to solution pool + * + */ + virtual void implementFP_(const double* x, SolutionPoolPtr s_pool); + + /** + * \brief Function to check the integrality of a variable + * + * \param[in] Constant pointer to the primal solution + * + * return true if there is any fractional variable else false + */ + bool isFrac_(const double* x); + + + /** + * \brief A function to perturb the rounded solution in case of + * cycling + * + * \param[in] hash_val Hash value of the current rounded solution + * \param[in] n_to_flip Number of variables to be flipped + * + * This function uses selectToFlip_ to get candidates for flipping + * till a new rounded solution is obtained which is not visited + * earlier. Cycling_ is used to detect earlier existence. The + * parameter n_to_flip is passed by the calling method is usually + * an indicator of integer infeasibilities of the solution. + */ + void perturb_(double hash_val, UInt n_to_flip); + + /** + * \brief A function to restore the upper and lower bounds of the + * problem. + * + * \param[in] LB_copy. Pointer to an array of lower bound. + * \param[in] UB_copy. Pointer to an array of upper bound. + * \param[in] numvars. Number of variables in the problem. + * + */ + void restoreBounds_(double* LB_copy, double* UB_copy, UInt vars); + + /** + * \brief A function to save the upper and lower bounds of the + * problem. + * + * \param[in] LB_copy. Pointer to an array of lower bound. Space has + * to be allocated. + * \param[in] UB_copy. Pointer to an array of upper bound. Space has + * to be allocated. + * \param[in] numvars. Number of variables in the problem. + * + */ + void saveBounds_(double* LB_copy, double* UB_copy, UInt vars); + + /** + * \brief A funtion to randomly select "n" binary/integer + * variable to be flipped. + * + * \param[in] n_to_flip Number of variables to be flipped + * + * \return The vector of pointer to the variables selected as + * candidate + * + * This function uses random sampling for selection of variables as + * a candidate for be flipped from 0 to 1 or 1 to 0. + */ + VarVector selectToFlip_(UInt n_to_flip); + + /** + * \brief Function to decide whether to use Feasibility Pump + * + * return true or false. + * + * We decide not to use Feasibility Pump is problem has integer + * variables and/or if the problem is nonlinear (constraints or + * objective) + */ + virtual bool shouldFP_(); + + }; + + typedef boost::shared_ptr FeasPumpPtr; + +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/FilterSQPEngine.h b/thirdparty/linux/include/minotaur/FilterSQPEngine.h new file mode 100644 index 0000000..103e104 --- /dev/null +++ b/thirdparty/linux/include/minotaur/FilterSQPEngine.h @@ -0,0 +1,345 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2010 - 2014 The MINOTAUR Team. +// + +/** + * \file FilterSQPEngine.h + * \author Sven Leyffer, Argonne National Laboratory. + * Define the class FilterSQPEngine. + */ + + +#ifndef MINOTAURFILTERSQPENGINE_H +#define MINOTAURFILTERSQPENGINE_H + +#include "NLPEngine.h" +#include "WarmStart.h" + +namespace Minotaur { + class Environment; + class FilterSQPWarmStart; + class Problem; + class Solution; + class Timer; + typedef boost::shared_ptr EnvPtr; + typedef boost::shared_ptr FilterWSPtr; + typedef boost::shared_ptr ConstFilterWSPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr SolutionPtr; + + struct FilterSQPStats { + UInt calls; ///< Total number of calls to solve. + UInt iters; ///< Sum of number of iterations in all calls. + UInt strCalls; ///< Calls to solve while strong branching. + UInt strIters; ///< Number of iterations in strong branching alone. + double strTime; ///< time taken in strong branching alone. + double time; ///< Sum of time taken in all calls to solve. + }; + + class FilterSQPWarmStart : public WarmStart { + public: + + /// Default constructor + FilterSQPWarmStart(); + + /// Copy constructor. Creates a full copy, not just copies pointers. + FilterSQPWarmStart(ConstFilterWSPtr warm_st); + + /// Destroy + ~FilterSQPWarmStart(); + + /// Get solution. + SolutionPtr getPoint(); + + // Implement WarmStart::hasInfo(). + bool hasInfo(); + + /** + * Overwrite the primal and dual values of warm-start. Sometimes, the + * warm-start data is initialized and needs to be updated. This + * should be called in place of deleting and creating a new warm-start + * object. + */ + void setPoint(SolutionPtr sol); + + // Implement WarmStart::write(). + void write(std::ostream &out) const; + + private: + /// The starting solution that is used to warm-start. + SolutionPtr sol_; + }; + + /** + * FilterSQPEngine is the class that is used to solve NLP problems using + * the FilterSQP solver. FilterSQP can be used to solve problems completely to + * optimality or approximately. + */ + class FilterSQPEngine : public NLPEngine { + + public: + friend class Problem; + + /// Default constructor. + FilterSQPEngine(); + + /// Constructor using given environment options. + FilterSQPEngine(EnvPtr env); + + /// Destroy. + ~FilterSQPEngine(); + + // Base class method + void addConstraint(ConstraintPtr c); + + // Change bound on a constraint. + void changeBound(ConstraintPtr cons, BoundType lu, double new_val); + + // Change bound on a variable. + void changeBound(VariablePtr var, BoundType lu, double new_val); + + // Implement Engine::changeBound(VariablePtr, double, double). + void changeBound(VariablePtr var, double new_lb, double new_ub); + + // Implement Engine::changeConstraint(). + void changeConstraint(ConstraintPtr con, LinearFunctionPtr lf, + double lb, double ub); + + // Implement Engine::changeConstraint(). + void changeConstraint(ConstraintPtr c, NonlinearFunctionPtr nlf); + + // change objective. + void changeObj(FunctionPtr f, double cb); + + void clear(); + + /// Restore settings after strong branching. + void disableStrBrSetup(); + + /// Return an empty FilterSQPEngine pointer. + EnginePtr emptyCopy(); + + /// Make settings for strong branching. + void enableStrBrSetup(); + + /** + * Evaluate the activity of constraints and fill the values in 'c'. + * This is a callback function that is called by filter. + */ + void evalCons(const double *x, double *c, int *error); + + /** + * Evaluate the gradient of objective and fill in 'a'. + * This is a callback function that is called by filter. + */ + void evalGrad(const double *x, double *a, int *error); + + /** + * Evaluate the hessian of lagrangian at point x and fill in. + * This is a callback function that is called by filter. + */ + void evalHessian(const double *x, double *lam, + const int phase, double *ws, int *lws, int *l_hess, + int *li_hess, int *error); + + /// Report the solution value from the last solve. + double evalObjValue(const double *x, int *err); + + // Get name. + std::string getName() const; + + /// Report the solution value from the last solve. + double getSolutionValue(); + + /// Report the solution. + ConstSolutionPtr getSolution(); + + /// Report the status of the last solve. + EngineStatus getStatus(); + + // Implement Engine::getWarmStart(). // NULL for now. + ConstWarmStartPtr getWarmStart(); + + // Implement Engine::getWarmStartCopy(). // NULL for now. + WarmStartPtr getWarmStartCopy(); + + /// Method to read the problem and initialize FilterSQP. + void load(ProblemPtr problem); + + // Implement Engine::loadFromWarmStart(). + void loadFromWarmStart(WarmStartPtr ws); + + // Convert 'min f' to 'min -f'. + void negateObj(); + + // base class method. + void removeCons(std::vector &delcons); + + // Implement Engine::resetIterationLimit(). + void resetIterationLimit(); + + // Implement Engine::setIterationLimit(). + void setIterationLimit(int limit); + + /// Solve the problem that was loaded and report the status. + EngineStatus solve(); + + // Write statistics. + void writeStats(std::ostream &out) const; + + private: + + /// Jacobian storage. + double *a_; + + /// Lower bounds. + double *bl_; + + /// if lb > ub and lb < ub+bTol_, we make ub = lb. + double bTol_; + + /// Upper bounds. + double *bu_; + + /// values of constraint functions + double *c_; + + /** + * If true, reallocate space in the next solve. Important, if + * constraints or objectives have changed. + */ + bool consChanged_; + + /// Linear (L) or Nonlinear (N). + char *cstype_; + + /// Environment. + EnvPtr env_; + + /// if rstat_[4] FilterSQPEnginePtr; +} // end namespace Minotaur + +#endif +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Function.h b/thirdparty/linux/include/minotaur/Function.h new file mode 100644 index 0000000..93f8375 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Function.h @@ -0,0 +1,263 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Function.h + * \brief Get information about a Function. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURFUNCTION_H +#define MINOTAURFUNCTION_H + +#include "Types.h" + +namespace Minotaur { + + class Function; + class LinearFunction; + class QuadraticFunction; + class NonlinearFunction; + struct LTHessStor; + typedef boost::shared_ptr FunctionPtr; + typedef boost::shared_ptr ConstFunctionPtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr ConstLinearFunctionPtr; + typedef boost::shared_ptr QuadraticFunctionPtr; + typedef boost::shared_ptr NonlinearFunctionPtr; + + /** + * The class Function is meant to model functions that are used to specify + * constraints and objectives in a problem. A function can have three or + * more components: linear, quadratic and nonlinear. Each of these types is + * implemented as a separate class. A Function thus keeps a pointer to each + * of these components and has methods to consolidate methods of these + * components. For instance, a function evaluation will just call these + * evaluation routines of the components and add them together. If any of the + * individual components of a function (linear, quadratic, nonlinear) + * are modified, one should delete the existing function and create a new + * one as some of the data-structures may not get updated with the changes. + */ + class Function { + public: + + /// Default constructor + Function(); + + /// Construct a function using only a linear function. + Function(LinearFunctionPtr lf); + + /** + * Construct a function using a linear function and a quadratic + * function. + */ + Function(LinearFunctionPtr lf, QuadraticFunctionPtr qf); + + /// Construct a function using a linear function and a nonlinear function. + Function(LinearFunctionPtr lf, NonlinearFunctionPtr nlf); + + /** + * Construct a function using a linear function, a quadratic + * function and a nonlinear function. + */ + Function(LinearFunctionPtr lf, QuadraticFunctionPtr qf, + NonlinearFunctionPtr nlf); + + /// Construct a function using only a nonlinear function. + Function(NonlinearFunctionPtr nlf); + + /// Destroy. + virtual ~Function(); + + /// Make a clone using new variables. vbeg points to the variable id 0. + /// vbeg+k points to variable id k, where k>=0. + virtual FunctionPtr cloneWithVars(VariableConstIterator vbeg, int *err) + const; + + /** + * Evaluate the function at a given point x. error must be zero if no + * errors were encountered. + */ + virtual double eval(const DoubleVector &x, int *error) const; + + /// Evaluate the function at a given point x. + virtual double eval(const double *x, int *error) const; + + virtual void prepJac(); + + /** + * Evaluate Gradient at the given point x and fill in the array grad_f. + */ + virtual void evalGradient(const double *x, double *grad_f, int *error) + const; + + virtual void fillJac(const double *x, double *values, int *error); + /** + * Get number of terms in the hessian of the function. We only count + * terms that are nonzero in the lower-triangular half (including the + * diagonal) of the hessian matrix. + */ + virtual UInt getNumNzInHess(); + + /** + * Return true if variable var is one of the arguments of this function. + * Return false otherwise. + */ + virtual bool hasVar(VariablePtr var) const; + + /** + * Return the type of a function: linear, quadratic, nonlinear etc. If + * the return type is quadratic, we may still have a linear component. + */ + virtual FunctionType getType(); + + /** + * \brief Check if function is linear in a variable. + * + * \param[in] v The variable that we want to test. + * \return True if this function is linear or constant in variable v. + */ + bool isLinearIn(ConstVariablePtr v); + virtual FunctionType getVarFunType(ConstVariablePtr v); + + /// Return the linear part of the function. + virtual const LinearFunctionPtr getLinearFunction() const; + + /// Return the quadratic part of the function. + virtual const QuadraticFunctionPtr getQuadraticFunction() const; + + /// Return the nonlinear part of the function. + virtual const NonlinearFunctionPtr getNonlinearFunction() const; + + /// Return a begin-iterator for the variables that are in this function. + VarSetConstIterator varsBegin(); + + /// Return an end-iterator for the variables that are in this function. + VarSetConstIterator varsEnd(); + + /// Return the number of variables that are in this function + virtual UInt getNumVars() const; + + /** + * Evaluate the hessian at a given point 'x'. Multiply the evaluated + * values by the lagrangean multiplier 'mult' and add the given matrix + * to the existing values in 'values' + */ + virtual void evalHessian(const double mult, const double *x, + const size_t *offset, double *values , int *error); + virtual void evalHessian(double mult, const double *x, + const LTHessStor *stor, double *values , int *error); + + + /// Fill in the values of offset, starting from position pos. + virtual void fillHessOffset(size_t *offset, size_t &pos, + std::set & v_pairs); + + virtual void fillHessStor(LTHessStor *stor); + virtual void finalHessStor(const LTHessStor *stor); + + /// Change the linear function part + virtual void changeLf(LinearFunctionPtr lf); + + /// Change the nonlinear function part + virtual void changeNlf(NonlinearFunctionPtr nlf); + + /// Substitute a variable with another. + virtual void subst(VariablePtr out, VariablePtr in, double rat); + + /** + * Multiply with a constant. If c is zero, then function becomes empty. We + * make the components NULL in such a case + */ + virtual void operator*=(const double c); + + /** + * Remove the quadratic part of the function and return a pointer to the + * quadratic part. + */ + QuadraticFunctionPtr removeQuadratic(); + + /** + * Remove the nonlinear part of the function and return a pointer to + * the nonlinear part. + */ + NonlinearFunctionPtr removeNonlinear(); + + /** + * Add a linear function. If the function already has a linear function, + * the new function is algebraically added, otherwise the new function is + * cloned. + */ + void add(ConstLinearFunctionPtr lPtr); + + void removeVar(VariablePtr v, double val); + double getFixVarOffset(VariablePtr v, double val); + + /// Express the function and send the output to the output stream "out". + friend std::ostream &operator<<(std::ostream &out, const Function &f); + + /// Express the function and send the output to the output stream "out". + virtual void write(std::ostream &out) const; + + protected: + /// The type of the function. + FunctionType type_; + + /// The variables that occur in this function + VariableSet vars_; + + /** + * This map describes what variable exists in what kind of a function. + * For instance, if the function is x1^2 + e^x1 + ln(x1) + 2x1, then + * this map will have three entries, one at quadratic, one as nonlinear + * (e^x1 + ln(x1)) and one as linear. + */ + std::set > varFuns_; + + /** + * Pairs of variables for which the corresponding entry in the hessian + * is non-zero is saved along with the index of that pair. Thus, if + * \f$x_3x_4\f$ is a term in the function, then the element (4,3) is + * non-zero in the hessian. Let us also suppose that this is the 7th + * nonzero element in the hessian. Then \f$((x_3,x_4), 7)\f$ is a member + * of this map. + */ + // VarPairIntMap hessMap_; + + private: + + /// The linear function part of the function. Could be NULL. + LinearFunctionPtr lf_; + + /// The quadratic function part of the function. Could be NULL. + QuadraticFunctionPtr qf_; + + /// The nonlinear function part of the function. Could be NULL. + NonlinearFunctionPtr nlf_; + + /** + * Collect all the variables from the components into a single vector. + * Duplicates are removed. + */ + void collectVars_(); + + // + //void createHessMap_(); + }; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Handler.h b/thirdparty/linux/include/minotaur/Handler.h new file mode 100644 index 0000000..75dc115 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Handler.h @@ -0,0 +1,325 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Handler.h + * \brief Define abstract base class for handlers of various kinds. + * \author Ashutosh Mahajan, Argonne National Laboratory + * + * Defines the base class Handler. + */ + +#ifndef MINOTAURHANDLER_H +#define MINOTAURHANDLER_H + +#include "Types.h" + +namespace Minotaur { + + class CutManager; + class Node; + class Relaxation; + class PreMod; + class Solution; + class SolutionPool; + typedef boost::shared_ptr NodePtr; + typedef boost::shared_ptr RelaxationPtr; + typedef boost::shared_ptr PreModPtr; + typedef boost::shared_ptr ConstSolutionPtr; + typedef boost::shared_ptr SolutionPoolPtr; + typedef std::deque PreModQ; + typedef PreModQ::iterator PreModQIter; + typedef PreModQ::const_iterator PreModQConstIter; + + + /** + * \brief Base class for handling specific types of constraints or + * objective. + * + * A Handler is used to handle a particular kind of constraint/objective. + * It provides methods for creating a relaxation, checking if a given point + * is feasible, separating a given point and providing a branching + * candidate. + */ + class Handler { + public: + + /// Default constructor. + Handler() {}; + + + /// Destroy. + virtual ~Handler() {}; + + /** + * \brief Add constraint to be handled by this handler. + * + * \param[in] newcon Constraint to be added. + */ + virtual void addConstraint(ConstraintPtr newcon) + { cons_.push_back(newcon); }; + + /** + * \returns The beginning of constraints handled by this handler. + */ + virtual ConstraintVector::const_iterator consBegin() const + {return cons_.begin();}; + + /** + * \returns The end of constraints handled by this handler. + */ + virtual ConstraintVector::const_iterator consEnd() const + {return cons_.end();}; + + /** + * \brief Return branches for branching. + * + * Get branches by branching on the given candidate. In the general scheme + * for branching, we store only bound changes, though we are also + * capable of storing other mods. + * + * \param[in] cand Candidate on which the brancher wants to branch. + * \param[in] x The solution of the relaxation at the current node. + * \param[in] rel The relaxation at the current node. + * \param[in] s_pool Best feasible solutions found so far. + * \return a vector of branch-objects. + */ + virtual Branches getBranches(BrCandPtr cand, DoubleVector &x, + RelaxationPtr rel, SolutionPoolPtr s_pool) = 0; + + /** + * \brief find branching candidates. + * + * A brancher will ask each handler by calling this function to list + * branching candidates. + * \param[in] rel Relaxation being solved at current node. + * \param[in] x Solution of the relaxation. + * \param[out] mods Any modifications that the handler found (Unused). + * \param[out] cands The set of candidates to which branching candidates + * must be inserted. This set has candidates that want to branch on a single + * variable only. Other candidates must go into gencands. + * \param[out] gencands The vector of general branching candidates. All + * candidates that do not want to branch on a variable dichotomy must be + * added in this vector. + * \param[out] is_inf true if the handler finds that the problem + * is infeasible and the node can be pruned. + */ + virtual void getBranchingCandidates(RelaxationPtr rel, + const DoubleVector &x, + ModVector &mods, BrVarCandSet &cands, + BrCandVector &gencands, + bool &is_inf) = 0; + + /** + * \brief Get the modifcation that creates a given (up or down) branch. + * + * If one branch is pruned by the brancher (e.g. strong brancher), + * then we can apply the modifications of + * other branch to the relaxation without branching. This routine + * returns such a modification. This function is also called for + * obtaining modifications for strong branching on a candidate. + * \param[in] cand The candidate for which we want the + * modification. + * \param[in] x The solution of relaxation at current node. + * \param[in] rel The relaxation at current node. + * \param[in] dir The Direction for which we want the modification, Up + * or Down?. + * \return Modification that can be applied to the relaxation before + * re-solving it. + */ + virtual ModificationPtr getBrMod(BrCandPtr cand, DoubleVector &x, + RelaxationPtr rel, BranchDirection dir) = 0; + + /// Return the name of the handler. + virtual std::string getName() const = 0; + + /** + * \brief Check if a solution is feasible. + * + * Check if a given solution is feasible for the constraints that are + * handled by this handler. should_prune is true if the handler finds that + * the problem itself is infeasible and the current node can be pruned + * (which is different from a solution not being feasible). + * + * \param[in] sol The solution of the relaxation whose feasibility we + * want to test. + * \param[in] rel The relaxation. + * \param[out] should_prune True if the relaxation is infeasible and we + * can prune the node associated. + * \param[out] inf_meas A measure of infeasibility. It may be used by + * heuristics and other code to make the tree-search faster. Computing this + * value is optional. + * \return True if sol is feasible for constraints/objective asociated + * with this handler. False if sol is not feasible. + */ + virtual bool isFeasible(ConstSolutionPtr sol, RelaxationPtr rel, + bool &should_prune, double &inf_meas) = 0; + + /** + * \brief Return true if this handler is needed for the problem. + * + * It is useful to know if a handler is required or not. For example, a + * handler may be deleted if it is not needed. + */ + virtual bool isNeeded() { return ! cons_.empty(); } + + /** + * \brief Initial presolve. + * + * Do the initial presolve. For now we will assume that presolve + * modifies the given problem. We do not create a new problem. All + * modifications that require post-processing for getting the solution + * back are prepended to 'pre_mods' by the handler. + * + * \param[in] pre_mods A pointer to a queue of PreMod objects. + * Modifications made by the presolver must be prepended (not appended) + * to pre_mods. The order is important for post-solve. + * \param[out] changed True if the presolve modified the problem. + * \return status of presolve. + */ + virtual SolveStatus presolve(PreModQ *pre_mods, bool *changed) = 0; + + /** + * \brief Presolve the problem and its relaxation at a node. + * + * Presolve the problem and its relaxation at a given node. Bound + * propagation and other simple modifications can be made in this function. + * It is called after the node relaxation is setup but before it is solved. + * Both the problem and its relaxation are presolved. Changes to the problem + * are stored in the tree. Changes to the relaxation are optional and may or + * may not be stored in the tree. + * \param[in] rel Relaxation at the current node. + * \param[in] node Current node. + * \param[in] s_pool Pool of solutions. + * \param[in] p_mods Unused. Modifications to the problem that must be + * stored in this node so that they are applied to all descendant nodes as + * well. All modifications must be appended not prepended. + * \param[out] r_mods Modifications to the relaxation that must be stored in + * this node so that they are applied to all descendant nodes as well. All + * modifications must be appended not prepended. This may be unnecessary in + * certain algorithms. + * \return true if Node can be pruned because infeasibility is detected. + */ + virtual bool presolveNode(RelaxationPtr rel, NodePtr node, + SolutionPoolPtr s_pool, ModVector &p_mods, + ModVector &r_mods) = 0; + + /** + * \brief Create root relaxation if doing full node relaxations. + * + * This method is used to add all the variables and constraints handled + * by this handler, with the understanding that nodes will also be fully + * rebuilt. The relaxation is already created, it should not be + * freed or re-allocated. + * \param[in,out] rel The relaxation that is being constructed. + * \param[out] is_inf is true if the handler finds that the + * problem is infeasible. + */ + virtual void relaxInitFull(RelaxationPtr rel, bool *is_inf) = 0 ; + + /** + * \brief Create root relaxation if doing incremental node relaxations. + * + * This method is used to add all the variables and constraints handled + * by this handler, with the understanding that nodes will incrementally + * relaxed. The relaxation is already created, it should not be + * freed or re-allocated. + * \param[in,out] rel The relaxation that is being constructed. + * \param[out] is_inf is true if the handler finds that the + * problem is infeasible. + */ + virtual void relaxInitInc(RelaxationPtr rel, bool *is_inf) = 0 ; + + /** + * \brief Create a relaxation for a node, building from scratch. + * + * Create a relaxation of the constraints. Either this method, or + * relaxNodeInc should be called at each node. Here, we only make minor + * modifications to the same relaxation. + * + * \param[in] node is the node for which relaxation is to be created. + * \param[in] rel is the relaxation that is being + * constructed. Do not allocate or re-allocate space for it. Just add + * new variables or constraints to it. + * \param[out] is_inf is true if the node can be pruned. + */ + virtual void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf) = 0; + + /** + * \brief Create an incremental relaxation for a node. + * + * Create a relaxation of the constraints. Either this method, or + * nodeRelaxFull relax should be called at root node. + * Usually we only make minor modifications to the same relaxation. + * \param[in] node is the node for which relaxation is to be created. + * \param[in] rel is the relaxation that is being constructed. Do not + * allocate or re-allocate space for it. Just add new variables or + * constraints to it. + * \param[out] is_inf is true if the node can be pruned. + */ + virtual void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf) = 0; + + /** + * \brief add cuts to separate a given point. + * + * Add cuts to the relaxation to cutoff a solution. We assume that all + * cuts are globally valid. + * + * \param[in] sol The solution that needs to be cut off + * \param[in] node The node that we are currently solving. + * \param[in] rel The relaxation at this node. + * \param[in] cutman The CutManager where cuts should be sent. + * \param[in] s_pool The SolutionPool containing solutions found so far. + * \param[out] sol_found True if a new solution has been found while + * separating + * \param[out] status SeparationStatus returned by this routine. + */ + virtual void separate(ConstSolutionPtr sol, NodePtr node, + RelaxationPtr rel, CutManager *cutman, + SolutionPoolPtr s_pool, bool *sol_found, + SeparationStatus *status) = 0; + + /** + * \brief Tell the handler whether the problem will be modified or the + * relaxation will be modified or both. These modifications will be saved in + * the tree as well. + * + * \param[in] mod_prob If true, modify the problem in branching and + * presolving + * \param[in] mod_rel If true, modify the relaxation in branching and + * presolving. + */ + virtual void setModFlags(bool mod_prob, bool mod_rel) + {modProb_ = mod_prob; modRel_ = mod_rel;}; + + /// Write statistics to ostream out. + virtual void writeStats(std::ostream &) const {}; + + protected: + ConstraintVector cons_; + + /// If true, modify the original (or transformed) problem. + bool modProb_; + + /// If true, modify the relaxation of original (or transformed) problem. + bool modRel_; + + + }; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/HessianOfLag.h b/thirdparty/linux/include/minotaur/HessianOfLag.h new file mode 100644 index 0000000..0417656 --- /dev/null +++ b/thirdparty/linux/include/minotaur/HessianOfLag.h @@ -0,0 +1,144 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file HessianOfLag.h + * \brief Declare class HessianOfLag to get information about hessian of + * Lagrangean of a Problem. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURHESSIAN_H +#define MINOTAURHESSIAN_H + +#include "Types.h" + +namespace Minotaur { + class Function; + typedef boost::shared_ptr FunctionPtr; + + struct LTHessStor { + UInt nz; + UInt nlVars; + VariablePtr *rows; + std::deque *colQs; + UInt *cols; + UInt *starts; + }; + + + /** + * Given a function f(x), the hessian of f(x) is defined as the matrix whose + * element \f$(i,j)\f$ is: d^2f/dx_idx_j], i=0,1,...,n-1, j=0,1,...,n-1. + * Hessian is thus a square symmetric matrix. We store only the + * lower-triangular part of the matrix, i.e., i=0,1,...,n-1, j=0,...,i + * + * Thus each function can have an associated Hessian. NLP solvers do not + * usually require hessian of the objective function or a function from a + * single constraint. They usually need hessian of the lagrangean function. + * This function is defined as: + * \f[ l = \lambda_0f + \sum_{i=1}^m\lambda_ig_i \f] + * + * This class provides methods for building and managing hessian of the + * lagrangean by calling the methods of the Functions in objective and + * constraints. + */ + class HessianOfLag { + public: + /// Default constructor + HessianOfLag(); + + HessianOfLag(Problem *p); + + /** + * Construct Hessian of Lagrangean from an objective, obj, + * and a vector of constraints cons. 'n' is the number of variables and + * is also the size of square matrix. + */ + //HessianOfLag(ConstObjPtr obj, const ConstraintVector & cons, + // const UInt n); + + /// Destroy. + virtual ~HessianOfLag(); + + /** + * Return the number of non-zero elements in the lower-triangular part + * of the hessian, including the diagonal). + */ + virtual UInt getNumNz() const; + + /** + * Given arrays iRow and jCol of size getNumNz(), fill the values of + * rows and columns that have non-zeros. + * + * e.g. if f(x) = x0^2 + x1^3x2 + x1 + * + * then getNumNz() = 3 + * iRow = [0, 1, 2] + * jCol = [0, 1, 1] + */ + virtual void fillRowColIndices(UInt *irow, UInt *jcol); + + /** + * Given arrays iRow and jCol of size getNumNz(), fill the values of + * hessian matrix at a given point 'x', into the array 'values'. for the + * above example, + * values = [2, 6x1x2, 3x1^2] + */ + virtual void fillRowColValues(const double *x, double obj_mult, + const double *con_mult, double *values, + int *error); + + /// Ugly hack to solve maximization problem. TODO: delete it. + virtual void negateObj() {}; + + virtual void setupRowCol(); + + virtual void write(std::ostream &out) const; + + private: + /** + * If a lagrange multiplier is less than etol_, then it is considered + * zero. + */ + double etol_; + + FunctionPtr obj_; + + /** + * Stores for each constraint, where each hessian non-zero entry goes. + * e.g. + * x_1^2 + x_4x_5 <= 0 + * x_1^2 + x_2^2 + x_3^2 - 10*x_4x_5 <= 0 + * Then the non-zeros are stored for elements + * (1,1), (2,2), (3,3), (4,5) + * The offsets matrix is much bigger than the non-zeros. It contains: + * 0, 3, 0, 1, 2, 3 + * The first 0 means that the hessian value of x^1 goes in position 0. + * The hessian value for x_4x_5 goes in position 3 and so on. + */ + + Problem *p_; + LTHessStor stor_; + + }; + + typedef boost::shared_ptr HessianOfLagPtr; + typedef boost::shared_ptr ConstHessianOfLagPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Heuristic.h b/thirdparty/linux/include/minotaur/Heuristic.h new file mode 100644 index 0000000..cfeb272 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Heuristic.h @@ -0,0 +1,61 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Heuristic.h + * \brief Define abstract base class for heuristics of various kinds. + * \author Ashutosh Mahajan, Argonne National Laboratory + * + * Defines the base class Heuristic. + */ + +#ifndef MINOTAURHEURISTIC_H +#define MINOTAURHEURISTIC_H + +#include "Types.h" + +namespace Minotaur { + + class Node; + class Relaxation; + class SolutionPool; + typedef boost::shared_ptr NodePtr; + typedef boost::shared_ptr RelaxationPtr; + typedef boost::shared_ptr SolutionPoolPtr; + + + /** + */ + class Heuristic { + public: + + /// Default constructor. + Heuristic() {}; + + /// Destroy + virtual ~Heuristic() {}; + + /// Use this heuristic. + virtual void solve(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool) = 0; + + /// Write statistics to the logger. + virtual void writeStats(std::ostream &out) const = 0; + }; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/IntVarHandler.h b/thirdparty/linux/include/minotaur/IntVarHandler.h new file mode 100644 index 0000000..e367d89 --- /dev/null +++ b/thirdparty/linux/include/minotaur/IntVarHandler.h @@ -0,0 +1,139 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file IntVarHandler.h + * \brief Declare the IntVarHandler class for handling integer constrained + * variables. It checks integrality and provides branching candidates. Does + * not do any presolving and cut-generation. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURINTVARHANDLER_H +#define MINOTAURINTVARHANDLER_H + +#include "Handler.h" + +namespace Minotaur { + + +/** + * IntVarHandler class considers integer variables of a problem. It only + * checks integrality of the variables. It does not implement separate() + * function. Implements functions for isFeasible and branching. + */ +class IntVarHandler : public Handler { +public: + + /// Default constructor. + IntVarHandler(); + + /// Constructor. + IntVarHandler(EnvPtr env, ProblemPtr problem); + + /// Destroy. + ~IntVarHandler(); + + // Implement Handler::getBranches(). + Branches getBranches(BrCandPtr cand, DoubleVector & x, + RelaxationPtr rel, SolutionPoolPtr s_pool); + + // base class method + void getBranchingCandidates(RelaxationPtr rel, + const DoubleVector &x, ModVector &mods, + BrVarCandSet &cands, BrCandVector &gencands, + bool &is_inf); + + // Implement Handler::getBrMod(). + ModificationPtr getBrMod(BrCandPtr cand, DoubleVector &x, + RelaxationPtr rel, BranchDirection dir); + + /// Return the integer tolerance. + double getTol() const; + + // Write name + std::string getName() const; + + // Check if solution is feasible. + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool & should_prune, double &inf_meas); + + bool isNeeded(); + + /// Does nothing. + void postsolveGetX(const double *, UInt, DoubleVector *) {}; + + /// Presolve. Don't do anything. + SolveStatus presolve(PreModQ *, bool *) {return Finished;}; + + /// Does nothing. + bool presolveNode(RelaxationPtr, NodePtr, SolutionPoolPtr, ModVector &, + ModVector &) + {return false;}; + + // Does nothing. + void relaxInitFull(RelaxationPtr rel, bool *is_inf) ; + + // Does nothing. + void relaxInitInc(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf) ; + + // Does nothing. + void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf); + + /** + * We do not need separation for this handler. So we just return without + * doing anything. + */ + void separate(ConstSolutionPtr, NodePtr , RelaxationPtr, CutManager *, + SolutionPoolPtr, bool *, SeparationStatus *) {}; + + /// Set the integer tolerance. + void setTol(double tol); + + /// Does nothing. + void writePreStats(std::ostream &) const {}; + +private: + /// Environment. + EnvPtr env_; + + /// True if we are doing guided dive, false otherwise. + bool gDive_; + + /** + * Tolerance for checking integrality. + * If |round(x) - x| < intTol_, then it is considered to be integer + * valued. + */ + double intTol_; + + /// Log + LoggerPtr logger_; + + /// For log: + static const std::string me_; + + /// The problem for which the handler was created. + ProblemPtr problem_; +}; +typedef boost::shared_ptr IntVarHandlerPtr; +typedef boost::shared_ptr ConstIntVarHandlerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Interrupt.h b/thirdparty/linux/include/minotaur/Interrupt.h new file mode 100644 index 0000000..fd46c5f --- /dev/null +++ b/thirdparty/linux/include/minotaur/Interrupt.h @@ -0,0 +1,80 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +#ifndef MINOTAURINTERRUPT_H +#define MINOTAURINTERRUPT_H + +// This class is used to detect interrupts and exit gracefully. +// Exception CANNOT be thrown within the signal handler, which +// is the reason for having a separate function to check if an +// interrupt has occurred. + +// Questions: +// Can we eliminate the static member functions? +// Should we use setjmp and longjmp when an interrupt is triggered? +// What should exception should be thrown on an interrupt? +// If the keyboard interrupt is obtained after some limit, we exit +// from the code. However, we would like to use the Minotaur::Logger +// to log the reason. How is this done without a static pointer to +// a Logger? + + +#include "Exception.h" +#include "Logger.h" + +namespace Minotaur { + + class InterruptException : public Exception { + private: + InterruptException& operator=(const InterruptException&); + + public: + InterruptException() : Exception() { } + InterruptException(const InterruptException&) : Exception() { } + ~InterruptException() { } + }; + + class Interrupt { + public: + Interrupt(UInt l=5) {limit_ = l; } + virtual ~Interrupt() {} // Destructor + + inline void SetLimit(UInt l) { limit_ = l; } + inline UInt GetLimit() const { return limit_; } + + inline void SetLogger(LoggerPtr l) { logger_ = l; } + inline LoggerPtr GetLogger() const { return logger_; } + + virtual void Start(); + virtual void Stop(); + virtual void Check() const throw(InterruptException); + + private: + void (*originalHandler_)(int); + + static volatile UInt interrupts_; + static UInt limit_; // Maximum + static LoggerPtr logger_; + + static void Handler(int); + + Interrupt (const Interrupt &); + Interrupt & operator = (const Interrupt &); + }; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/IpoptEngine.h b/thirdparty/linux/include/minotaur/IpoptEngine.h new file mode 100644 index 0000000..8d3cd0e --- /dev/null +++ b/thirdparty/linux/include/minotaur/IpoptEngine.h @@ -0,0 +1,341 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file IpoptEngine.h + * \brief Declare an interface to the IPOPT nlp-solver. + * \author Ashutosh Mahajan, Argonne National Laboratory + * + * This file contains declartions for interface to Ipopt. + */ + + +#ifndef MINOTAURIPOPTENGINE_H +#define MINOTAURIPOPTENGINE_H + +#include "NLPEngine.h" +#include "Solution.h" +#include "WarmStart.h" + + +namespace Ipopt { + class IpoptApplication; + class IpoptFunInterface; + class TNLP; +} + + +namespace Minotaur { + + class Environment; + class IpoptEngine; + class Problem; + class Timer; + typedef boost::shared_ptr EnvPtr; + typedef boost::shared_ptr IpoptEnginePtr; + typedef boost::shared_ptr ProblemPtr; + + struct IpoptStats { + UInt calls; ///< Total number of calls to solve. + UInt iters; ///< Sum of number of iterations in all calls. + double ptime; ///< Sum of time taken in all calls to presolve. + UInt strCalls; ///< Calls to solve while strong branching. + UInt strIters; ///< Number of iterations in strong branching alone. + double strTime; ///< time taken in strong branching alone. + double time; ///< Sum of time taken in all calls to solve. + }; + + + /// The solution obtained from/for Ipopt. + class IpoptSolution; + typedef boost::shared_ptr IpoptSolPtr; + typedef boost::shared_ptr ConstIpoptSolPtr; + + class IpoptSolution : public Solution { + public: + + /// Default constructor + IpoptSolution(); + + /// Construct a solution for a problem from an array of doubles. + IpoptSolution(const double *x, ProblemPtr problem); + + /** + * Construct a solution for a problem from an array of doubles and + * objective value. + */ + IpoptSolution(const double *x, double objval, ProblemPtr problem); + + /// Copy constructor + IpoptSolution(ConstIpoptSolPtr); + + /// Destroy. + ~IpoptSolution(); + + /** + * Return a pointer to the dual associated with the lower bound on + * variables. + */ + const double * getLowerDualOfVars() const {return dualXLow_;}; + + /** + * Return a pointer to the dual associated with the upper bound on + * variables. + */ + const double * getUpperDualOfVars() const {return dualXUp_;}; + + // base class + void setDualOfVars(const double *) { assert(!"implement me!"); }; + + /// Set duals of variable-bounds: both the lower and upper. + void setDualOfVars(const double *lower, const double *upper); + + /// Write to an output. + void write(std::ostream &out) const; + + private: + /// dual of lower bounds. + double *dualXLow_; + + /// dual of upper bounds. + double *dualXUp_; + }; + + + class IpoptWarmStart; + typedef boost::shared_ptr IpoptWarmStartPtr; + typedef boost::shared_ptr ConstIpoptWarmStartPtr; + + /// Class for saving and using Warm-start information in Ipopt. + class IpoptWarmStart : public WarmStart { + public: + /// Default constructor + IpoptWarmStart(); + + /// Copy constructor. Creates a full copy, not just copies pointers. + IpoptWarmStart(ConstIpoptWarmStartPtr ws); + + /// Destroy + ~IpoptWarmStart(); + + /// Return the soluton that can be used as starting point. + IpoptSolPtr getPoint(); + + // Implement WarmStart::hasInfo(). + bool hasInfo(); + + void makeCopy(); + + /** + * Overwrite the primal and dual values of warm-start. Sometimes, the + * warm-start data is initialized and needs to be updated. This + * should be called in place of deleting and creating a new warm-start + * object. + */ + void setPoint(IpoptSolPtr sol); + + // Implement WarmStart::write(). + void write(std::ostream &out) const; + + private: + /// The starting solution that is used to warm-start. + IpoptSolPtr sol_; + }; + + +// ----------------------------------------------------------------------- // +// ----------------------------------------------------------------------- // + + class IpoptEngine : public NLPEngine { + public: + + friend class Problem; + + /// Default constructor + IpoptEngine(); + + /// Default constructor + IpoptEngine(EnvPtr env); + + /// Destroy + ~IpoptEngine(); + + // Base class method + void addConstraint(ConstraintPtr c); + + void changeBound(ConstraintPtr cons, BoundType lu, double new_val); + + // Implement Engine::changeBound(VariablePtr, BoundType, double). + void changeBound(VariablePtr var, BoundType lu, double new_val); + + // Implement Engine::changeBound(VariablePtr, double, double). + void changeBound(VariablePtr var, double new_lb, double new_ub); + + // Implement Engine::changeConstraint(). + void changeConstraint(ConstraintPtr con, LinearFunctionPtr lf, + double lb, double ub); + + // Implement Engine::changeConstraint(). + void changeConstraint(ConstraintPtr, NonlinearFunctionPtr); + + // change objective. + void changeObj(FunctionPtr f, double cb); + + /// Clear the loaded problem, if any, from the engine. + void clear(); + + /// Restore settings after strong branching. + void disableStrBrSetup(); + + /// Return an empty IpoptEngine pointer. + EnginePtr emptyCopy(); + + /// Make settings for strong branching. + void enableStrBrSetup(); + + // get name. + std::string getName() const; + + // Implement Engine::getSolution(). + ConstSolutionPtr getSolution(); + + // Implement Engine::getSolutionValue(). + double getSolutionValue(); + + // Implement Engine::getStatus(). + EngineStatus getStatus(); + + // Implement Engine::getWarmStart(). + ConstWarmStartPtr getWarmStart(); + + // Implement Engine::getWarmStartCopy(). + WarmStartPtr getWarmStartCopy(); + + /// Load the problem into IPOPT. We create the TNLP interface to IPOPT. + void load(ProblemPtr problem); + + // Implement Engine::loadFromWarmStart(). + void loadFromWarmStart(const WarmStartPtr ws); + + // Convert 'min f' to 'min -f'. + void negateObj(); + + // base class method. + void removeCons(std::vector &delcons); + + // Implement Engine::resetIterationLimit(). + void resetIterationLimit(); + + // Implement Engine::setIterationLimit(). + void setIterationLimit(int limit); + + void setOptionsForSingleSolve(); + + void setOptionsForRepeatedSolve(); + + /** + * Solve the problem that was loaded. Uses the TNLP interface to IPOPT + * for solving the NLP. + */ + EngineStatus solve(); + + /// Write statistics. + void writeStats(std::ostream &out) const; + + private: + /// True if a bound on variable has been modified since last change. + bool bndChanged_; + + /// True if a constraint has been modified since last change. + bool consChanged_; + + /// Optimal dual values associated with x >= l. + double *dual_x_l_; + + /// Optimal dual values associated with x <= u. + double *dual_x_u_; + + /// Optimal dual values associated with l <= g(x) <= u. + double *dual_g_; + + /// Environment. + EnvPtr env_; + + /// If lb>ub+etol_, declare infeasible. + const double etol_; + + /// Where to put logs. + LoggerPtr logger_; + + /// The maximum limit that can be set on Ipopt. + static const int maxIterLimit_ = 3000; + + /// String name used in log messages. + static const std::string me_; + + Ipopt::IpoptApplication *myapp_; + + Ipopt::IpoptFunInterface *mynlp_; + + /** + * True if we want to save warm start information of the current + * solution for the next solve. False, if no information needs to be + * saved. Saving information does not mean that it will be used. + * useWs_ flag must be on to use the warm-start information. + */ + bool prepareWs_; + + /// Try to solve without calling ipopt. + bool presolve_(); + + /// Problem that is loaded, if any. + ProblemPtr problem_; + + /** + * The solution obtained from last solve. The solution_ in + * IpoptFunInterface points to the same array as this one. So the + * solution from Ipopt is copied to this array only once. This array + * does not get freed in IpoptFunInterface and so must be freed here. + */ + IpoptSolPtr sol_; + + /// Statistics. + IpoptStats *stats_; + + /// True if strong branching. False otherwise. + bool strBr_; + + /** + * Timer for Ipopt solves. Includes time spent in call-backs: + * evaluating functions and derivatives. + */ + Timer *timer_; + + /** + * True if we want to use warm-start information, either from a + * previous solve or from a user provided structure. + */ + bool useWs_; + + /// Private copy of the warm start information. + IpoptWarmStartPtr ws_; + + /// Set problem specific options to make IPOPT faster + void setOptionsForProb_(); + }; +} + +#endif +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/IpoptEngineTnlp.h b/thirdparty/linux/include/minotaur/IpoptEngineTnlp.h new file mode 100644 index 0000000..99640ca --- /dev/null +++ b/thirdparty/linux/include/minotaur/IpoptEngineTnlp.h @@ -0,0 +1,142 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file IpoptEngineTnlp.h + * \brief Declare the IPOPT TNLP class that provides Ipopt with the gradient, + * hessian and function evaluations. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURIPOPTENGINETNLP_H +#define MINOTAURIPOPTENGINETNLP_H + +namespace Ipopt { + class IpoptFunInterface : public TNLP + { + public: + + /// Default constructor. + IpoptFunInterface(Minotaur::ProblemPtr problem, + Minotaur::IpoptSolPtr sol); + + /// default destructor. + ~IpoptFunInterface(); + + /// Copy the solution explicitly (without sharing pointers). + void copySolution(Minotaur::IpoptSolPtr sol); + + /// Method to return the objective value. + bool eval_f(Index n, const Number* x, bool new_x, + Number& obj_value); + + /// Method to return the constraint residuals. + bool eval_g(Index n, const Number* x, bool new_x, + Index m, Number* g); + + /// Method to return the gradient of the objective. + bool eval_grad_f(Index n, const Number* x, + bool new_x, Number* grad_f); + + /** + * Method to return: + * 1) The structure of the jacobian (if "values" is NULL) + * 2) The values of the jacobian (if "values" is not NULL). + */ + bool eval_jac_g(Index n, const Number* x, + bool new_x, Index m, Index nele_jac, + Index* iRow, Index *jCol, + Number* values); + + /** + * Method to return: + * 1) The structure of the hessian of the lagrangian (if "values" is + * NULL) + * 2) The values of the hessian of the lagrangian (if "values" + * is not NULL) + */ + bool eval_h(Index n, const Number* x, bool new_x, + Number obj_factor, Index m, + const Number* lambda, bool new_lambda, + Index nele_hess, Index* iRow, + Index* jCol, Number* values); + + + /** + * This method is called when the algorithm is complete so the TNLP can + * store/write the solution + */ + void finalize_solution(SolverReturn status, + Index n, const Number* x, const Number* z_L, + const Number* z_U, Index m, const Number* g, + const Number* lambda, Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + /// Method to return the bounds for my problem. + bool get_bounds_info(Index n, Number* x_l, + Number* x_u, Index m, + Number* g_l, Number* g_u); + + /// Method to return some info about the nlp. + bool get_nlp_info(Index& n, Index& m, + Index& nnz_jac_g, Index& + nnz_h_lag, IndexStyleEnum& index_style); + + /// Get solution. + const Minotaur::IpoptSolPtr getSolution() {return sol_;} + + /// Get solution value. + double getSolutionValue() const; + + /// Method to return the starting point for the algorithm. + bool get_starting_point(Index n, bool init_x, + Number* x, bool init_z, + Number* z_L, Number* z_U, + Index m, bool init_lambda, + Number* lambda); + + /// Set solution. + void setSolution(Minotaur::IpoptSolPtr sol) {sol_ = sol;} + + + private: + /// Copying is not allowed. + IpoptFunInterface(const IpoptFunInterface &); + + /// Assignment is not allowed. + IpoptFunInterface& operator=(const IpoptFunInterface&); + + /// If the variable is fixed, relax the upper bound by this much. + double bOff_; + + /// If fabs(lb-ub) + +#include "Types.h" + +namespace Minotaur { + class Iterate { + public: + Iterate(std::vector &x, std::vector &l); + ~Iterate() { }; + + private: + std::vector x_; + std::vector l_; + }; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Jacobian.h b/thirdparty/linux/include/minotaur/Jacobian.h new file mode 100644 index 0000000..760fed2 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Jacobian.h @@ -0,0 +1,125 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Jacobian.h + * \brief Get information about Jacobian of a given Problem. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURJACOBIAN_H +#define MINOTAURJACOBIAN_H + +#include "Types.h" + +namespace Minotaur { + + + /** + * This class is used for the Jacobian of a Problem. When a problem has + * constraints of the form: + * \f[ g_i(x) \leq 0 \f] + * The Jacobian at a point + * \f$x^*\f$ is a matrix whose \f$i-\f$th row is the gradient, + * \f$\nabla f_i(x^*)\f$. + * + * This class also provides the sparsity pattern of the non-zeros in the + * Jacobian. By default, we save the Jacobian constraint-wise and then + * variable-wise. Thus, if we a have the constraints: + * + * x_0^2 + x1^3 \leq 3 + * x_0 + x_2 + x_3 \leq 4 + * x_1 + x_3 \leq 4 + * x_3^3 \leq 8 + * + * We will save the indices of nonzeros in a 2-d matrix, rows corresponding + * to constraints and columns corresponding to variables. The matrix will + * have entries: + * 0 1 + * 0 2 3 + * 1 3 + * 3 + * + * The above scheme makes it easy to fill nonzeros in Constraint-Ordered + * manner, but more expensive to fill in Variable-Ordered manner. So we also + * use another 2-d matrix as above, but the matrix now looks like: + * 0 0 1 1 + * 1 2 2 + * 3 + */ + class Jacobian { + + public: + + /// Default constructor. + Jacobian(); + + /// Constructor using constraints. + Jacobian(const std::vector & cons, const UInt n); + + /// Destroy. + virtual ~Jacobian(); + + /// Return the number of nonzeros in the Jacobian. + virtual UInt getNumNz(); + + /** + * Given arrays iRow and jCol, fill in the row and column index of each + * non-zero in the jacobian. + * e.g. + * \f{eqnarray*} + * x_1x_3 + x_1^2x_4 &=& 2 \\ x_0 + x_5 &=& 0 + * \f} + * + * then, iRow = [1 0 0 0 1], jCol = [0 1 3 4 5]. These indices are + * arranged first in the order of increasing jCol and then increasing + * iRow. + */ + virtual void fillRowColIndices(UInt *iRow, UInt *jCol); + + /** + * Given arrays iRow and jCol as above, fill in the row and column index + * of each non-zero in the jacobian. For the above example, when \f$x = + * (-1, 1, 1, 1, 0)\f$, then values = [3 -1 1 1 1]. + */ + virtual void fillRowColValues(const double *x, double *values, + int *error); + + /// Fill indices, column wise. + virtual void fillColRowIndices(UInt *, UInt *) + { assert(!"implement me!");} + + /// Fill values, column wise. + virtual void fillColRowValues(const double *, double *, int *) + { assert(!"implement me!");} + + void write(std::ostream &out) const; + + private: + /** + * The constraints that constitute the system whose jacobian needs to be + * evaluated. + */ + const std::vector * cons_; + + /// Number of nonzeros + UInt nz_; + + }; + typedef boost::shared_ptr JacobianPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/KnapCovHandler.h b/thirdparty/linux/include/minotaur/KnapCovHandler.h new file mode 100644 index 0000000..83ab945 --- /dev/null +++ b/thirdparty/linux/include/minotaur/KnapCovHandler.h @@ -0,0 +1,175 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file KnapCovHandler.h + * \brief Declare the KnapCovHandler class for handling knapsack cover + * constraints. It generates the cuts whenever they are needed. + * \author Serdar Yildiz, Argonne National Laboratory + */ + +#ifndef MINOTAURKNAPCOVHANDLER_H +#define MINOTAURKNAPCOVHANDLER_H + +#include "Handler.h" +#include "Types.h" +#include "Solution.h" +#include "Variable.h" +#include "Relaxation.h" +#include "CoverCutGenerator.h" + +namespace Minotaur { + +// Pointers for knapsack cover cut handler are defined. +class KnapCovHandler; +typedef boost::shared_ptr KnapCovHandlerPtr; +typedef boost::shared_ptr ConstKnapCovHandler; + +class Logger; +typedef boost::shared_ptr LoggerPtr; + + +struct KCStats +{ + UInt knaps; /// Number of knapsacks solved. + UInt cuts; /// Number of cover cuts generated. + UInt extended; /// Number of extended cover cuts generated. + UInt simple; /// Number of simple lifted cuts generated. + UInt gns; /// Number of Gu, Nemhauser, Savelsbergh lifted cover cuts + /// generated. + UInt singlectwo; /// Number of general lifted cover cuts generated by using + /// a single element for C2 (downlifting). + double time; /// Total time used to generate cuts. + UInt cutdel; /// Number of cuts marked for deletion. +}; + +/** + * KnapCovHandler class considers knapsack cover cuts in the problem. It + * generates the cuts and manages them. + */ +class KnapCovHandler : public Handler { +public: + + /// Default constructor. + KnapCovHandler(); + + /// Constructor. + KnapCovHandler(EnvPtr env, ProblemPtr problem); + + /// Destroy + ~KnapCovHandler(); + + /// Does nothing. + void relaxInitFull(RelaxationPtr , bool * ) {}; + + /// Does nothing. + void relaxInitInc(RelaxationPtr , bool * ) {}; + + /// Does nothing. + void relaxNodeFull(NodePtr , RelaxationPtr , bool * ) {}; + + /// Does nothing. + void relaxNodeInc(NodePtr , RelaxationPtr , bool * ) {}; + + /// Check if solution is feasible. + /// Checks all the constraints if they are satisfied by the given solution. + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool &should_prune, double &inf_meas); + + + /** + * We need separation for this handler to generate the knapsack cover + * cuts. + * A set of knapsack cover cuts will be generated. + */ + void separate(ConstSolutionPtr, NodePtr, RelaxationPtr, CutManager *cutman, + SolutionPoolPtr, bool *, SeparationStatus * status); + + /// Does nothing. + virtual void getBranchingCandidates(RelaxationPtr, + const DoubleVector &, ModVector &, + BrVarCandSet &, BrCandVector &, + bool &) {}; + + /// Does nothing. + virtual ModificationPtr getBrMod(BrCandPtr , DoubleVector & , + RelaxationPtr , BranchDirection ) + {return ModificationPtr();}; + + /// Does nothing. + virtual Branches getBranches(BrCandPtr , DoubleVector & , + RelaxationPtr , SolutionPoolPtr ) + {return Branches();}; + + /// Does nothing. + SolveStatus presolve(PreModQ *, bool *) {return Finished;}; + + /// Does nothing. + //void postsolveGetX(const double *, UInt, DoubleVector *) {}; + + // Does nothing. + virtual bool presolveNode(RelaxationPtr , NodePtr , + SolutionPoolPtr , ModVector &, + ModVector &) {return false;}; + + // Write name. + std::string getName() const; + + /// Show statistics. + void writeStats(std::ostream &) const; + + /// Updates the handler statistics by using returned information form + /// cover cut generator. + // void updateStats(ConsCovCutGenStatsPtr covstats); + + // Return specific statistics. + UInt KC_knaps(){return stats_->knaps;} + UInt KC_cuts() {return stats_->cuts;} + UInt KC_extended() {return stats_->extended;} + UInt KC_simple() {return stats_->simple;} + UInt KC_gns() {return stats_->gns;} + UInt KC_singlectwo() {return stats_->singlectwo;} + double KC_time() {return stats_->time;} + +private: + /// Environment. + EnvPtr env_; + + /// The problem for which the handler is created. + ProblemPtr minlp_; + + /// Log. + LoggerPtr logger_; + + /// Statistics. + KCStats * stats_; + + // Number of variables in the MINLP. + UInt numvars_; + + /// Tolerance for checking integrality. + double intTol_; + + /// For log: + static const std::string me_; +}; +} + + +#endif // MINOTAURKNAPCOVHANDLER_H + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: + diff --git a/thirdparty/linux/include/minotaur/KnapsackList.h b/thirdparty/linux/include/minotaur/KnapsackList.h new file mode 100644 index 0000000..2306a5a --- /dev/null +++ b/thirdparty/linux/include/minotaur/KnapsackList.h @@ -0,0 +1,82 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file KnapsackList.h + * \brief Declare base class KnapsackList. + * \author Serdar Yildiz, Argonne National Laboratory +*/ + +#ifndef MINOTAURKNAPSACKLIST_H +#define MINOTAURKNAPSACKLIST_H + +#include "Problem.h" +#include "Constraint.h" + +namespace Minotaur { +/** + * The KnapsackList class generates the list of knapsack + * constraint pointers for a given problem. +*/ +class KnapsackList{ +public: + // Default constructor. + KnapsackList(); + + // Constructs list from a given problem. + KnapsackList(ProblemPtr p); + + // Destructor. + ~KnapsackList(); + + // Generates the list of knapsack constraints. + void generateList(); + + // Evaluate a constraint and decide to add it to the list. + void evalConstraint(ConstraintConstIterator it); + + // Add a constraint to list not. + void addConstraint(ConstraintConstIterator it); + + // Get number of knapsack constraints. + UInt getNumKnaps() const {return list_->size();} + + // Get number of constrainst checked for linear or not. + UInt getNumConsChecked() const {return numConsChecked_;} + + // Get an iterator for the beginning of knapsack list. + ConstraintIterator getListBegin() {return list_->begin();} + + // Get an iterator for the end of the knapsack list. + ConstraintIterator getListEnd() {return list_->end();} + + +private: + // The problem that knapsack list is generated from. + ProblemPtr p_; + // A vector of pointers to kanpsack constraints. + ConstraintVectorPtr list_; + // Number of constraints checked. + UInt numConsChecked_; +}; + +} + +#endif // MINOTAURKNAPSACKLIST_H + + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LGCIGenerator.h b/thirdparty/linux/include/minotaur/LGCIGenerator.h new file mode 100644 index 0000000..a16ea02 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LGCIGenerator.h @@ -0,0 +1,363 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file LGCIGenerator.h + * \brief Declare base class KnapsackList. + * \author Serdar Yildiz, Argonne National Laboratory + */ + +#ifndef MINOTAURLGCIGENERATOR_H +#define MINOTAURLGCIGENERATOR_H + +#include +#include +using std::ofstream; +#include +using std::string; + + +#include "KnapsackList.h" +#include "Problem.h" +#include "Solution.h" +#include "Types.h" +#include "Cut.h" +#include "Relaxation.h" +#include "Environment.h" +#include "ProbStructure.h" +#include "LPEngine.h" + +namespace Minotaur { + +typedef enum { + Cover = 0, + Cons, + Obj, + Set +} PrintType; + +typedef enum { + Totalcuts = 0, + Cuts, + Violated, + Gns, + Noviol, + Noinitcover +} LGCIType; + +// Shows why cut is not added to the list. +typedef enum { + Duplicate = 0, + NotViolated +}CutFail; + +struct LGCIGenStats +{ + UInt liftsubprobs; /// Number of total subproblems solved for lifting. + UInt totalcuts; /// Number of all cuts i.e. including duplicates as well. + UInt cuts; /// Number of total cover cuts generated excluding duplicates. + UInt violated; /// Number of violated cuts. + UInt knapcons; // Number of knapsack constraints. + UInt knapcov; /// Number of knapsack inequalities considered that has cover + /// inequalities. + UInt knapgub; /// Number of knapsack inequalities that has a set of GUBs + /// that cover its variables. + UInt gns; /// Number of Gu, Nemhauser, Savelsbergh cuts generated. + UInt noviol; /// Number cuts that does not violate current relaxation + /// solution. + UInt noinitcov; /// GNS procedure terminated since no inital GNS cover constructed. + double time; /// Total time used by generator. +}; + +// Typedefs for ease of coding. +class LGCIGenerator; +typedef boost::shared_ptr LGCIGeneratorPtr; +typedef boost::shared_ptr ConstLGCIGeneratorPtr; +typedef LGCIGenStats* LGCIGenStatsPtr; +typedef LGCIGenStats const * ConstLGCIGenStatsPtr; +typedef boost::shared_ptr ConstLinearFunctionPtr; +typedef std::map OrigLiftVars; +typedef boost::shared_ptr OrigLiftVarsPtr; + +/** + * LGCIGenerator class generates lifted GUB cover inequalities from a + * given problem and a solution. + * It generates the list of knapsack inequalities suitable for cut generation. + * It checks if the considered knapsack constraint has at least one cover. + * If not then it checks another knapsack inequality. + * It generates an overlapping GUB set that covers knapsack variables. + * It by using a simple elimination rule, i.e., take out duplicates, obtains a non-overlapping GUB set. + */ +class LGCIGenerator { +public: + // Default constructor. + LGCIGenerator(); + + // Constructor that uses a problem and a solution. + LGCIGenerator(ProblemPtr p, SolutionPtr s, + EnvPtr env, LPEnginePtr lpengine); + + // Constructor that uses a relaxation and a solution given. + LGCIGenerator(RelaxationPtr rel, ConstSolutionPtr sol, + EnvPtr env, LPEnginePtr lpengine); + + // Destructor. + ~LGCIGenerator(); + + // Initialize data elements. + void initialize(); + + // Initialize statistics. + void initStats(); + + // Checks if the constraint has a cover set. + bool hasCover(ConstraintConstIterator it); + + // Checks if there is a set of GUBs that covers the knapsack inequality. + bool hasGubCover(ConstraintConstIterator it, + ConstConstraintVectorPtr gublist); + + // Generates initial cover by using GNS algorithm. + bool coverSetGeneratorGNS(ConstConstraintPtr cons, + CoverSetPtr cover); + + /* Modified GNS cover set generator such that it always generates a cover. + * This function generates a cover set by using different strategies. + * For now, it generates a modified version of Gu, Nemhauser, Savelsbergh + * such that it generates a cover set even though the number of nonzero + * elements in solution vector given is not enough for cover set generation + * s.t sum(a_i) <= b for i s.t. x^*_i != 0. + */ + bool coverSetGenGNSModified(ConstConstraintPtr cons); + + /** Constructs the variable-value pair vector from a given vector and a + * linear function that inclued coefficients. + */ + void varCoeff(ConstConstraintPtr cons, CoverSetPtr cover); + + /** Calculates the sum of coefficients of a given vector of + * variable-coefficient pairs + */ + double sumCoeffs(CoverSetPtr cover); + + /** Drops some of the variables and obtains a minimal cover form a given + * cover. + */ + void minimalCover(CoverSetPtr cover, ConstConstraintPtr cons); + + // Generates all LGCI cover cuts from all constraints. + void generateAllCuts(); + + // Generate cover partitions C1, C2, F and R + void coverPartitionGNS(const ConstConstraintPtr cons, + const ConstCoverSetPtr cover, + CoverSetPtr cone, + CoverSetPtr ctwo, + CoverSetPtr fset, + CoverSetPtr rset); + + // Lifts a variable up or down as it is specified by uplift. + double lift(const ConstCoverSetPtr obj, + const ConstCoverSetPtr inequality, + const CoverSetConstIterator variable, + double & rhs, + double & initialb, + bool uplift); + + // Initialize cover inequality by changing the coefficients of cover set + // by ones. + void initCoverIneq(const ConstCoverSetPtr cover, CoverSetPtr coverineq); + + /** Lifting strategy of GNS for LGCI lifting. Different from Knapsack + * cover genereator. + * Generates Gu, Nemhauser, Savelsbergh LGCI generation algorithm. + */ + bool liftingGNS(const ConstCoverSetPtr cone, + const ConstCoverSetPtr ctwo, + const ConstCoverSetPtr fset, + const ConstCoverSetPtr rset, + CoverSetPtr constraint, + const ConstConstraintPtr cons, + ConstConstraintVectorPtr gublist, + double & ub); + + + /** This lifts the variables in a given set in the given order + */ + bool liftSet(CoverSetPtr obj, + CoverSetPtr constraintset, + const ConstCoverSetPtr varset, + CoverSetPtr inequality, + double & ub, + double & initialb, + bool liftup); + + // Generates all the cover cuts from a given knapsack constraint. + void generateCuts(ConstConstraintPtr cons, ConstConstraintVectorPtr gublist); + + // Generate a cut from a given variable set and rhs. + void generateCut(const ConstCoverSetPtr inequality, double ub, CutPtr cut); + + // Generates a GNS LGCI cut. + bool GNS(const ConstConstraintPtr cons, ConstConstraintVectorPtr gublist); + + // Add the cut to the list and insert corresponding violation to violation + // list. + void addCut(CutPtr cut); + + bool addCut(CoverSetPtr cov, double rhs, UInt cuttype, CutFail& failtype); + + // Check if the same cut is already included in the list. + bool checkExists(CoverSetPtr inequality, double rhs); + + // Solves the lifting problem. + double liftingProbsolver(); + + // Calculates the violation for the given cut. + double violation(CutPtr cut); + + // Constructs a vector of nonzero variables in the given solution. + void nonzeroVars(const ConstLinearFunctionPtr lf, + CoverSetPtr nonzerovars, + CoverSetPtr zerovars); + + // Sort nonzero variab;e array in nonincreasing order. + void sortNonIncreasing(CoverSetPtr nonzeros); + + // This function generates set N\C, the variables outside of cover set. + void cBar(const ConstCoverSetPtr cover, + CoverSetPtr cbar, + const ConstConstraintPtr cons); + + // Generate GUBs from constraints in map data type. + void generateGubMaps(ConstConstraintVectorPtr gublist, + boost::shared_ptr< std::vector > gubcoverlist, + boost::shared_ptr< std::vector > guborigcoeffs); + + // Generate non overlapping GUB constraint set. + void nonOverlap(boost::shared_ptr< std::vector > gubcoverlist); + + // Initialize the GUB constraints in lifting problem. + void initGubCons(const ConstCoverSetPtr cone, + boost::shared_ptr > gubcoverlist, + boost::shared_ptr > gubcons); + + // Lift elements in the set. + void liftSet(CoverSetPtr obj, + boost::shared_ptr >origgubs, + CoverSetPtr consknap, + boost::shared_ptr > gubcons, + const ConstCoverSetPtr varset, + CoverSetPtr coverineq, + double & rhs, + double & initialknap, + double * initialgub, + bool liftup); + + // Lift the current variable. + double lift(CoverSetPtr obj, + boost::shared_ptr > origgubs, + CoverSetPtr consknap, + boost::shared_ptr > gubcons, + const CoverSetConstIterator variable, + double & rhs, + double & initialbknap, + double * initialgub, + bool liftup); + + // Return const GUB identifier. + ConstProbStructPtr getProbStruct() const + {return probstruct_;} + + // Return const knapsack list. + ConstKnapsackListPtr getKnapsackList() const + {return ConstKnapsackListPtr(knapList_);} + + // Return statistics of LGCIGenerator. + ConstLGCIGenStatsPtr getStats() const + {return ConstLGCIGenStatsPtr(stats_);} + + // Print inequality. + void printIneq(const ConstCoverSetPtr cov, double rhs, + PrintType type, string message); + + + void addCons(CoverSetPtr obj, + CoverSetPtr consknap, + double bknap, + boost::shared_ptr< std::vector > gubcons, + double * bgubs, + OrigLiftVarsPtr varmap, + ProblemPtr liftprob); + + VariablePtr addVar(VariablePtr var, OrigLiftVarsPtr varmap, ProblemPtr liftprob); + + + double roundHeur(ProblemPtr prob); + + // Return const pointer for problem. + +private: + // Environment. + EnvPtr env_; + // Problem that cover cuts will be generated for. + ProblemPtr p_; + // List of cuts generated. + CutVector cutVec_; + // List of violated cut. + CutVector violatedCuts_; + // List of violations for cuts corresponding in cut list. + DoubleVector violList_; + // List of knapsack inequalities. + KnapsackListPtr knapList_; + /** + * Given (possibly fractional) solution. + * Cut will be designed to violate this solution. + */ + SolutionPtr s_; + // Problem structure to obtaib GUB list for variables in knapsack inequality. + ConstProbStructPtr probstruct_; + // Number of knapsack ineqs used for cut generation. + UInt numCons_; + // Statistics for LGCI generator. + LGCIGenStatsPtr stats_; + // Hash map that is used to check if a cut is already created or not. + std::map< std::vector, UInt> cutmap_; + // Integer tolerance. + double intTol_; + + // Output file + ofstream output_; + // Output file name + string outfile_; + // LP solver. + LPEnginePtr lpengine_; + +}; + +} + + + + +#endif // MINOTAURLGCIGENERATOR_H + + + + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: + diff --git a/thirdparty/linux/include/minotaur/LPEngine.h b/thirdparty/linux/include/minotaur/LPEngine.h new file mode 100644 index 0000000..00ec962 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LPEngine.h @@ -0,0 +1,54 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file LPEngine.h + * \author Ashutosh Mahajan, Argonne National Laboratory. + * \brief Declare the class LPEngine for solving LPs and getting solution. + */ + + +#ifndef MINOTAURLPENGINE_H +#define MINOTAURLPENGINE_H + +#include "Engine.h" + +namespace Minotaur { + + /** + * The LPEengine class is an abstract class for interfacing LP solvers (like + * OsiLPEngine). A derived class must implement calls to the LP solver for + * the methods described here. + * + * \todo add more methods for accessing simplex tableaux. + * \todo add more methods for accessing dual rays etc. + */ + + class LPEngine : public Engine { + + public: + friend class Problem; + + /// Constructor. May set default parameters/options here. + LPEngine() {}; + + /// Destructor must be implemented if memory needs to be freed + virtual ~LPEngine() {}; + }; + typedef boost::shared_ptr LPEnginePtr; +} + +#endif +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LPRelaxation.h b/thirdparty/linux/include/minotaur/LPRelaxation.h new file mode 100644 index 0000000..080df53 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LPRelaxation.h @@ -0,0 +1,58 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + + +#ifndef MINOTAURLPRELAXATION_H +#define MINOTAURLPRELAXATION_H + +#include "Modification.h" +#include "Relaxation.h" + +namespace Minotaur { + + // /** + // LPRelaxation is a relaxation in which all constraints and objectives + // have only linear functions. + // */ + class LPRelaxation : public Relaxation { + public: + // /** + // Construct an empty Nonlinear Relaxation. + // */ + LPRelaxation(); + + // /** + // Construct from a problem. + // */ + LPRelaxation(ProblemPtr problem); + + // /** + // Destroy + // */ + virtual ~LPRelaxation() { }; + + protected: + // /** + // Pointer to the original problem + // */ + ConstProblemPtr originalProblem_; + }; + + typedef boost::shared_ptr LPRelaxationPtr; + typedef boost::shared_ptr ConstLPRelaxationPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LexicoBrancher.h b/thirdparty/linux/include/minotaur/LexicoBrancher.h new file mode 100644 index 0000000..be40d83 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LexicoBrancher.h @@ -0,0 +1,88 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file LexicoBrancher.h + * \brief Declare methods and data structures for lexicographic branching. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURLEXICOBRANCHER_H +#define MINOTAURLEXICOBRANCHER_H + +#include "Brancher.h" + +namespace Minotaur { + + struct LexicoBrStats { + UInt calls; /// Number of times called to find a branching candidate. + double time; /// Total time spent in branching. + }; + + class Timer; + + /** + * A class to select the first branching candidate that is avialable. Can + * be used for demonstration or when we don't have any idea how to branch. + */ + class LexicoBrancher : public Brancher { + + public: + /// Default constructor. + LexicoBrancher(); + + /// Construct with an environment. + LexicoBrancher(EnvPtr env, HandlerVector handlers); + + /// Destroy. + ~LexicoBrancher(); + + /** + * Find a branching candidate. Returns NULL if x does not have any + * fractional values for integer constrained variables. + */ + Branches findBranches(RelaxationPtr rel, NodePtr node, + ConstSolutionPtr sol, SolutionPoolPtr s_pool, + BrancherStatus & br_status, ModVector &mods); + + /// Write the statistics. + void writeStats(std::ostream &out) const; + + /// Return name. + std::string getName() const; + + private: + /// Name + const static std::string me_; + + /// Log manager. + Logger* logger_; + + /// Handlers that provide branching candidates. + HandlerVector handlers_; + + /// Timer + Timer *timer_; + + /// Statistics. + LexicoBrStats *stats_; + + }; + typedef boost::shared_ptr LexicoBrancherPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LinBil.h b/thirdparty/linux/include/minotaur/LinBil.h new file mode 100644 index 0000000..4bac7b0 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LinBil.h @@ -0,0 +1,128 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file LinBil.h + * \brief Declare a class for storing linear under and overestimators of + * bilinear functions + * \f$ y_1 = x_1x_2 \f$, + * \author Ashutosh Mahajan, IIT Bombay + */ + +#ifndef MINOTAURLINBIL_H +#define MINOTAURLINBIL_H + +#include "Handler.h" + +namespace Minotaur { + +/** + * A LinBil object stores some information about linear-relaxation inequalities + * for the bilinear constraints of the form \f$x_0x_1 = y\f$ + */ +class LinBil { +private: + /// Absolute feasibility tolerance + double aTol_; + + /// Constraint 0. + ConstraintPtr c0_; + + /// Constraint 1. + ConstraintPtr c1_; + + /// Constraint 2. + ConstraintPtr c2_; + + /// Constraint 3. + ConstraintPtr c3_; + + /// Relative feasibility tolerance + double rTol_; + + /// First variable. + VariablePtr x0_; + + /// Second variable. + VariablePtr x1_; + + /// Auxiliary variable. + VariablePtr y_; + + +public: + /// Default constructor. + LinBil(VariablePtr y, VariablePtr x0, VariablePtr x1); + + /// Destroy. + ~LinBil(); + + /// Get the first out of the four constraints. + ConstraintPtr getC0() {return c0_;}; + + /// Get the second out of the four constraints. + ConstraintPtr getC1() {return c1_;}; + + /// Get the third out of the four constraints. + ConstraintPtr getC2() {return c2_;}; + + /// Get the fourth out of the four constraints. + ConstraintPtr getC3() {return c3_;}; + + /// Get the auxiliary variable. + VariablePtr getY() {return y_;}; + + /// Get \f$x_0\f$ + VariablePtr getX0() {return x0_;}; + + /// Get \f$x_1\f$ + VariablePtr getX1() {return x1_;}; + + /// Get the variable other than x, in the product. + VariablePtr getOtherX(ConstVariablePtr x) const; + + /// Check if a bilinear constraint is violated at the current point x. + bool isViolated(const double *x, double &vio) const; + + /** + * \brief Check if a bilinear constraint is violated for the given values of + * \f$x_0, x_1, y\f$. + */ + bool isViolated(const double x0val, const double x1val, + const double y0val) const; + + void setCons(ConstraintPtr c0, ConstraintPtr c1, ConstraintPtr c2, + ConstraintPtr c3); +}; + +/** + * Compare two LinBil objects. Since we keep them in a set, we need to + * sort them. We use lexicographic ordering (i.e. based on ids of + * \f$(x_0, x_1)\f$). + */ +struct CompareLinBil { + bool operator() (LinBil* b0, LinBil* b1) const; +}; + +/// A set of bilinear objects. +typedef std::set LinBilSet; + +/// Iterator of LinBil objects over a set. +typedef LinBilSet::iterator LinBilSetIter; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LinConMod.h b/thirdparty/linux/include/minotaur/LinConMod.h new file mode 100644 index 0000000..e061b78 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LinConMod.h @@ -0,0 +1,98 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file LinConMod.h + * \brief Declare the class LinConMod. It is used to save modifications in the + * linear functions of constraints. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURLINCONMOD_H +#define MINOTAURLINCONMOD_H + +#include "Modification.h" + +namespace Minotaur { + +class Engine; +class LinConMod; +class LinearFunction; +typedef boost::shared_ptr EnginePtr; +typedef boost::shared_ptr< LinConMod > LinConModPtr; +typedef boost::shared_ptr< const LinConMod > ConstLinConModPtr; +typedef std::vector < LinConModPtr > LinConModVector; +typedef LinConModVector::iterator LinConModIter; +typedef LinConModVector::const_iterator LinConModConstIter; +typedef boost::shared_ptr LinearFunctionPtr; + +/** + * LinConMod keeps the changes in the linear function part, and the right + * hand side (only the upper bound) of a constraint. + */ +class LinConMod : public Modification { +public: + /// Constructor. + LinConMod(ConstraintPtr con, LinearFunctionPtr new_lf, double new_ub, + double new_lb); + + /// Destroy. + ~LinConMod(); + + /// Apply it to the problem. + void applyToProblem(ProblemPtr problem); + + // base class method. + ModificationPtr fromRel(RelaxationPtr, ProblemPtr ) const + {return LinConModPtr();}; + + // base class method. + ModificationPtr toRel(ProblemPtr, RelaxationPtr) const + {return LinConModPtr();}; + + /// Restore the modification for a problem. + void undoToProblem(ProblemPtr problem); + + /// Write it to 'out'. + void write(std::ostream &out) const; + +private: + /// Pointer to the constraint whose linear part is changed. + ConstraintPtr con_; + + /// New linear function. + LinearFunctionPtr newLf_; + + /// New constraint lower bound + double newLb_; + + /// New constraint upper bound. + double newUb_; + + /// Old linear function. + LinearFunctionPtr oldLf_; + + /// Old constraint lower bound + double oldLb_; + + /// Old constraint upper bound. + double oldUb_; + +}; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LinFeasPump.h b/thirdparty/linux/include/minotaur/LinFeasPump.h new file mode 100644 index 0000000..2206ef3 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LinFeasPump.h @@ -0,0 +1,175 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// +/** + * \file LinFeasPump.h + * \brief Feasibility pump using Linear relaxation + * \author Jayash Koshal, Argonne National Laborator + */ + +#ifndef LINFEASPUMP_H +#define LINFEASPUMP_H + +#include "FeasibilityPump.h" + +namespace Minotaur { + class Engine; + class LinearFunction; + class LinearHandler; + class Problem; + class QGHandler; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr LinHandlerPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr QGHandlerPtr; + + /// statistics for Linear Feasibility Pump + struct LinFeasStats { + double bestObjValue; /// Objective value for best feasible sol + UInt numLPs; /// Number of NLPs solved in the heuristic + }; + + /** + * \brief Linear Feasibility Pump for MINLPs. + * + * A Linear Feasibility Pump heuristic used to find solutions for Mixed + * Integer NLPs by solving a linear relaxation of NLP using a LP + * engine. An NLP is solved after every "n" iterations and solution + * from NLP solve is used to construct a LP relaxation. This class is + * derived from the class FeasibilityPump. + */ + + class LinFeasPump : public FeasibilityPump { + + public: + + /** + * \brief Default constructor + * + * \param[in] env Environment pointer + * \param[in] p Problem pointer + * \param[in] e1 The NLP engine pointer + * \param[in[ e2 The LP engine pointer + * + * The constructor initializes the base class using env, p and e1 + * and uses e2 to initialize the LP engine. Logger of the base is + * also defined in this function. + */ + LinFeasPump(EnvPtr env, ProblemPtr p, EnginePtr e1, EnginePtr e2); + + /// Default destructor + ~LinFeasPump(); + + /// Call to the heuristic + void solve(NodePtr node, RelaxationPtr rel, SolutionPoolPtr s_pool); + + /// Write statistics to the logger + void writeStats(std::ostream &out) const; + + protected: + + /// Message name for the heuristic + const static std::string me_; + + /// gradient of the objective function + double* gradientObj_; + + /// Linear Handler pointer + LinHandlerPtr lh_; + + /// LP Engine to be used to solving linear relaxation + EnginePtr lpE_; + + /// objective improvement constraint pointer + ConstraintPtr objConstraint_; + + /// The objective variable added by linearization of objective. If + /// the objective is linear, it is NULL. + VariablePtr objVar_; + + /// clone of linear objective function + LinearFunctionPtr olfClone_; + + /// QG Handler + QGHandlerPtr qh_; + + /// Relaxation Pointer + RelaxationPtr r_; + + /// Statistics + LinFeasStats* statsLFP_; + + // base class method. + void constructObj_(ProblemPtr prob, ConstSolutionPtr sol); + + /** + * \brief Fucntion to implement the linear feasibility pump + * + * \param[in] s_pool Pointer to solution pool + * \param[in] x Is not required. Can be NULL. + */ + void implementFP_(const double* x, SolutionPoolPtr s_pool); + + /** + * \brief Calculate the gap between the NLP relaxation solution and + * integer feasible solution. + * + * \param[in] f_nlp nlp solution value. + * \param[in] x const pointer to integer feasible solution. + * + * \return gap. gap is given by + * \f$ \frac{f(x)-f(x_nlp)}{|f(x)|+1e-6}\f$ + */ + double getSolGap_(double f_nlp, double f_feas); + + /** + * \brief A function to prepare the linear relaxation + * + * \return True if problem is infeasible else false + * + * This function first initializes the Linear Handler and QG + * Handler which are then used to construct a linear relaxation + * from the original problem + */ + bool prepareLP_(); + + /** + * \brief This function makes a cut by including the objective as + * constraint. + * + * \param[in] f_nlp NLP solution value + * solution + * \param[in] x const pointer to the primal feasible solution + * + * If a feasible solution is found we add an additional constraint + * to the problem to force the heuristic to find a better feasible + * fucntion. The constraint added is a linear relaxation of the + * objective at the feasible point, i.e. + * \f$ \nabla f(x^{LP}) + (x-x^{LP}) < 0 \f$ + */ + void separatingCut_(double f_nlp, SolutionPoolPtr s_pool); + + /** + * \brief Function to decide whether to use Linear Feasibility Pump + * + * \return true if to be implemented else fasle + * + * The linear feasibility pump is not implemented for problems with + * equality constraints for the form \f$ c(x) = 0 \f$ + */ + bool shouldFP_(); + + }; + + typedef boost::shared_ptr LinFeasPumpPtr; +} +#endif + +// local variables: +// mode: c++ +// eval: (c-set-style "gnu") +// eval: (setq indent-tabs-mode nil) +// end: diff --git a/thirdparty/linux/include/minotaur/LinMods.h b/thirdparty/linux/include/minotaur/LinMods.h new file mode 100644 index 0000000..fddb242 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LinMods.h @@ -0,0 +1,93 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file LinMods.h + * \brief Declare the class LinMods. It is used to save several modifications + * in the linear functions of constraints and changes in bounds of variables. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURLINMODS_H +#define MINOTAURLINMODS_H + +#include "LinConMod.h" +#include "VarBoundMod.h" + +namespace Minotaur { + + class LinMods; + typedef boost::shared_ptr< LinMods > LinModsPtr; + typedef boost::shared_ptr< const LinMods > ConstLinModsPtr; + + /** + * LinMods keeps record of changes in linear functions of different + * constraints and the changes in bounds of different variables. + */ + class LinMods : public Modification { + public: + /// Constructor. + LinMods(); + + /// Destroy. + ~LinMods(); + + /// Apply it to the problem. + void applyToProblem(ProblemPtr problem); + + // base class method. + ModificationPtr fromRel(RelaxationPtr, ProblemPtr ) const + {return LinModsPtr();}; + + /// Insert a new VarBoundMod + void insert(VarBoundModPtr bmod); + + /// Insert a new VarBoundMod2 + void insert(VarBoundMod2Ptr b2mod); + + /// Insert a new LinConMod + void insert(LinConModPtr lmod); + + /** + * Return true if there are no modifications stored in this object. + * False otherwise. + */ + bool isEmpty() const; + + // base class method. + ModificationPtr toRel(ProblemPtr, RelaxationPtr) const + {return LinModsPtr();}; + + /// Restore the modification for a problem. + void undoToProblem(ProblemPtr problem); + + /// Write it to 'out'. + void write(std::ostream &) const; + + private: + /// Vector of simple bound changes. + std::vector bmods_; + + /// Vector of bound changes where both bounds of a variable are changed. + std::vector bmods2_; + + /// Vector of changes in linear functions of constraints. + std::vector lmods_; + }; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LinearCut.h b/thirdparty/linux/include/minotaur/LinearCut.h new file mode 100644 index 0000000..a1fb551 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LinearCut.h @@ -0,0 +1,90 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2010 - 2014 The MINOTAUR Team. +// + +/** + * \file LinearCut.h + * \brief Define the class of valid inequalities of the form \f$ ax \leq b\f$ + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURLINEARCUT_H +#define MINOTAURLINEARCUT_H + +#include "Cut.h" + + +namespace Minotaur { + + class Function; + typedef boost::shared_ptr FunctionPtr; + /** + * A linear cut is a valid inequality of the form \f$ l \leq ax \leq u \f$, + * where \f$a \in \mathcal{R}^n, l \in \mathcal{R}, u \in \mathcal{R}\f$. + */ + class LinearCut : public Cut { + + public: + /// Default Constructor. + LinearCut(); + + /// Construct a cut of the form: \f$ax \leq b \f$ + LinearCut(LinearFunctionPtr lf, double lb, double ub); + + /// Destroy + ~LinearCut(); + + /// By how much does a given point x violate this cut. + double getViolation(const double *){ return 0.; }; + + /// Get ub of the inequality. + double getUb(){ return ub_; }; + + /// Get lb of the inequality. + double getLb(){ return lb_; }; + + /// Add this cut to problem. + void applyToProblem(ProblemPtr); + + /// Remove this cut from the problem. + void undoToProblem(ProblemPtr); + + /// Write this cut to the outstream. + void write(std::ostream &out) const; + + + protected: + /// Pointer to the constraint that is added to the problem. + ConstraintPtr cons_; + + /// Function or the lhs. + FunctionPtr f_; + + /// lb. + double lb_; + + /// Linear function or the lhs. + LinearFunctionPtr lf_; + + /// ub. + double ub_; + }; + typedef boost::shared_ptr LinearCutPtr; + typedef std::vector< LinearCutPtr > LinearCutVector; + typedef CutVector::iterator LinearCutIterator; + typedef CutVector::const_iterator LinearCutConstIterator; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LinearFunction.h b/thirdparty/linux/include/minotaur/LinearFunction.h new file mode 100644 index 0000000..20dbd17 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LinearFunction.h @@ -0,0 +1,253 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file LinearFunction.h + * \author Ashutosh Mahajan, Argonne National Laboratory. + * \brief Declare the class LinearFunction for storing and modifying a + * linear function. + */ + +#ifndef MINOTAURLINEARFUNCTION_H +#define MINOTAURLINEARFUNCTION_H + +#include "Types.h" + +namespace Minotaur { + class LinearFunction; + class QuadraticFunction; + class Variable; + + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr ConstLinearFunctionPtr; + typedef boost::shared_ptr QuadraticFunctionPtr; + typedef boost::shared_ptr ConstQuadraticFunctionPtr; + typedef boost::shared_ptr VariablePtr; + + + /// The base class linear function is of the form c'x. + class LinearFunction { + public: + /// Default constructor + LinearFunction(); + + /** + * Constructor with a tolerance level below which a coefficient is + * considered to be zero. + */ + LinearFunction(const double tol); + + /** + * Construct a linear function from a coefficient array of size n and n + * variables. + */ + LinearFunction(double *a, VariableConstIterator vbeg, + VariableConstIterator vend, double tol); + + + /// Destroy + ~LinearFunction(); + + void add(LinearFunctionPtr lf); + + /** + * Add new a linear term to this linear function, with coefficient a. Use + * this method only when you are sure that the linear function does not + * already contain this variable. Otherwise use incTerm(). If the weight "a" + * is zero, then nothing is added. + */ + void addTerm(ConstVariablePtr var, const double a); + + /** + * Removes all terms from the function + */ + void clearAll(); + + /** + * Copy the linear function. Variables and weights are copied. The weights + * in the clone and the original do not share the same space in memory. + */ + LinearFunctionPtr clone() const; + + LinearFunctionPtr cloneWithVars(VariableConstIterator vbeg) const; + + /** + * \brief Get bounds based on lower and upperbounds of each variable + * \param [out] l This pointer should contain lower bound. + * \param [out] u This pointer should contain upper bound. + */ + void computeBounds(double *l, double *u); + + /** + * Evaluate the value of this linear function at a given vector of + * doubles. It is assumed that the x[i] has the value for variable with id + * 'i'. + */ + double eval(const std::vector &x) const; + + /** + * Evaluate the value of this linear function at a given vector of + * doubles. It is assumed that the x[i] has the value for variable with id + * 'i'. + */ + double eval(const double *x) const; + + /** + * Evaluate the gradient of this linear function. It is assumed that x[id] + * will have the gradient along the direction of variable with ID=id. + */ + void evalGradient(double *grad_f) const; + + void fillJac(double *values, int *error); + + double getFixVarOffset(VariablePtr v, double val); + + /// Get the number of terms in this function. + UInt getNumTerms() const { return(terms_.size()); } + + void getVars(VariableSet *vars); + + /** + * Get the weight of a variable in this function. If the variable is not + * found, it returns zero. Conversely, if the weight returned is zero, + * then variable is not stored in the data structures of this function. + */ + double getWeight(ConstVariablePtr var) const; + + /** + * \brief Check if function contains a variable. + * + * \param[in] v The variable that we want to test. + * \return True if this function is has v. False if it doesn't use it. + */ + bool hasVar(ConstVariablePtr v) const; + + /** + * Add new a linear term to this linear function, with coefficient a. If + * the function already contains this variable, then the value is + * incremented. If the new value becomes zero, the variable is dropped. + */ + void incTerm(ConstVariablePtr var, const double a); + + /// Multiply the linear function by a number. + void multiply(double d); + + void prepJac(VarSetConstIter vbeg, VarSetConstIter vend); + + /// Remove a variable v from the function. + void removeVar(VariablePtr v, double val); + + /// Square the function. + QuadraticFunctionPtr square(); + + /// Iterate over the terms in the linear function: begin. + VariableGroupConstIterator termsBegin() const; + + /// Iterate over the terms in the linear function: end. + VariableGroupConstIterator termsEnd() const; + + /// Writes the function to a stream. + void write(std::ostream &out) const; + + + /** + * Add a linear function to this linear function. Terms that become zero + * are still retained in the function. + */ + friend LinearFunctionPtr operator + (ConstLinearFunctionPtr l1, + ConstLinearFunctionPtr l2); + + /** + * Subtract a linear function from this function. Terms that become zero + * are still retained in the function. + */ + friend LinearFunctionPtr operator-(ConstLinearFunctionPtr l1, + ConstLinearFunctionPtr l2); + + /// Multiply a linear function with a constant. + friend LinearFunctionPtr operator*(const double c, + ConstLinearFunctionPtr l2); + + /** + * Multiply two linear functions to get a quadratic function. If either of + * the linear functions is NULL, return NULL. + */ + friend QuadraticFunctionPtr operator*(ConstLinearFunctionPtr l1, + ConstLinearFunctionPtr l2); + + /** + * This increment operator is dangerous to use because it only works on + * objects of type LinearFunction and does not work on type + * LinearFunctionPtr. So if you have: + * + * LinearFunctionPtr lPtr, l2Ptr; + * + * Then you cannot do: + * + * lPtr += l2Ptr; + * + * You will have to do: + * + * (*lPtr) += l2Ptr; + * + * The user must ensure left operand is not NULL. + */ + void operator+=(ConstLinearFunctionPtr l2); + + /** + * Subtract l2 from this linear function. + * The user mu ensure left operand is not NULL. + */ + void operator-=(ConstLinearFunctionPtr l2); + + /** + * Multiply with a constant. Same precaution as for += + * operator above. If c is zero, then function becomes empty. It is + * better for the calling routine to check if c is zero, if so, just + * delete the function. + */ + void operator*=(const double c); + + + private: + /** + * True if terms in linear function are modified since previous call to + * prepJac. + */ + bool hasChanged_; + + /// Offsets for jacobian. + DoubleVector off_; + + /** + * terms_ is a map with variables as keys and their coefficients as + * values. + */ + VariableGroup terms_; + + /// Tolerance below which a coefficient is considered 0. + double tol_; + + /// Copy constructor is not allowed. + LinearFunction (const LinearFunction &l); + + /// Copy by assignment is not allowed. + LinearFunction & operator = (const LinearFunction &l); + + }; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/LinearHandler.h b/thirdparty/linux/include/minotaur/LinearHandler.h new file mode 100644 index 0000000..53933e7 --- /dev/null +++ b/thirdparty/linux/include/minotaur/LinearHandler.h @@ -0,0 +1,278 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file LinearHandler.h + * \brief Declare the LinearHandler class for handling integer and continuous + * variables. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURLINEARHANDLER_H +#define MINOTAURLINEARHANDLER_H + +#include "Handler.h" + +namespace Minotaur { + +class LinearFunction; +typedef boost::shared_ptr LinearFunctionPtr; + +/// Store statistics of presolving. +struct LinPresolveStats +{ + int iters; ///> Number of iterations (main cycle). + double time; ///> Total time used in initial presolve. + double timeN;///> Total time used in presolveNode. + int varDel; ///> Number of variables marked for deletion. + int conDel; ///> Number of constraints marked for deletion. + int var2Bin; ///> Number of variables converted to binary. + int var2Int; ///> Number of variables converted to integers. + int vBnd; ///> Number of times variable-bounds were tightened. + int cBnd; ///> Number of times constraint-bounds were tightened. + int cImp; ///> Number of times coefficient in a constraint was improved. + int bImpl; ///> No. of times a binary var. was changed to implied binary. + int nMods; ///> Number of changes made in all nodes. +}; + +/// Options for presolve. +struct LinPresolveOpts { + bool doPresolve; /// True if presolve is enabled, false otherwise. + + bool showStats; /// True if stats are displayed, false otherwise. + + int maxIters; /// Maximum number of iterations. + + bool purgeVars; /// If True, purge fixed variables. + + bool purgeCons; /// If True, purge redundant constraints. + + bool dualFix; /// If True, do dual cost fixing. + + bool coeffImp; /// If True, do coefficient improvement. +}; + + +/** + * An LinearHandler handles variables of a problem. It only checks bounds + * and integrality of the variables. + */ +class LinearHandler : public Handler { +public: + + /// Default constructor. + LinearHandler(); + + /// Constructor. + LinearHandler(EnvPtr env, ProblemPtr problem); + + /// Destroy + ~LinearHandler(); + + // Does nothing. + void relaxInitFull(RelaxationPtr rel, bool *is_inf) ; + + // Does nothing. + void relaxInitInc(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf) ; + + // Does nothing. + void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf); + + /** + * We assume that linear constraints and bound constraints are always + * satisfied. Always return true. + */ + bool isFeasible(ConstSolutionPtr, RelaxationPtr, bool &, double &) + {return true;} + + bool isNeeded() { return true; } + + /** + * Generate valid cuts using linear constraints. + */ + void separate(ConstSolutionPtr sol, NodePtr node, + RelaxationPtr rel, CutManager *cutman, SolutionPoolPtr s_pool, + bool *sol_found, SeparationStatus *status); + + /// Does nothing. + virtual void getBranchingCandidates(RelaxationPtr , + const DoubleVector &, ModVector &, + BrVarCandSet &, BrCandVector &, + bool &) {}; + + /// Does nothing. + virtual ModificationPtr getBrMod(BrCandPtr, DoubleVector &, + RelaxationPtr, BranchDirection) + {return ModificationPtr();}; // NULL + + /// Does nothing. + virtual Branches getBranches(BrCandPtr, DoubleVector &, RelaxationPtr, + SolutionPoolPtr) + {return Branches();}; // NULL + + // presolve. + virtual SolveStatus presolve(PreModQ *pre_mods, bool *changed); + + // Implement Handler::presolveNode(). + virtual bool presolveNode(RelaxationPtr p, NodePtr node, + SolutionPoolPtr s_pool, ModVector &p_mods, + ModVector &r_mods); + + + // Write name + virtual std::string getName() const; + + /// Return a constant pointer to the presolve options. + const LinPresolveOpts* getOpts() const; + + /// If true show statistics. + void setPreOptShowStats(bool val) {pOpts_->showStats = val;}; + + /// Maximum number of iterations. + void setPreOptMaxIters(int val) {pOpts_->maxIters = val;}; + + /// If True, purge fixed variables. + void setPreOptPurgeVars(bool val) {pOpts_->purgeVars = val;}; + + /// If True, purge redundant constraints. + void setPreOptPurgeCons(bool val) {pOpts_->purgeCons = val;}; + + void setPreOptDualFix(bool val) {pOpts_->dualFix = val;}; + + void setPreOptCoeffImp(bool val) {pOpts_->coeffImp = val;}; + + void simplePresolve(ProblemPtr p, SolutionPoolPtr spool, ModVector &t_mods, + SolveStatus &status); + + /// Write the presolve statistics. + void writePreStats(std::ostream &out) const; + + // Write statistics. + void writeStats(std::ostream &out) const; + +protected: + /// Environment. + EnvPtr env_; + + /// The problem for which the handler was created. + ProblemPtr problem_; + + /// Log + LoggerPtr logger_; + + /// Tolerance for checking integrality. + /** + * If |round(x) - x| < intTol_, then it is considered to be integer + * valued. + */ + const double intTol_; + + /// Tolerance. + const double eTol_; + + /// Infinity. Bounds beyond this number are treated as infinity. + const double infty_; + + /// Statistics of presolve. + LinPresolveStats *pStats_; + + /// Options for presolve. + LinPresolveOpts *pOpts_; + + /** + * Linear variables: variables that do not appear in nonlinear + * functions, both in objective and constraints. + */ + VarQueue linVars_; + + + /// For log. + static const std::string me_; + + void chkIntToBin_(VariablePtr v); + + void chkSing_(bool *changed); + void coeffImp_(bool *changed); + void computeImpBounds_(ConstraintPtr c, VariablePtr z, double zval, + double *lb, double *ub); + void copyBndsFromRel_(RelaxationPtr rel, ModVector &p_mods); + + void delFixedVars_(bool *changed); + + void dualFix_(bool *changed); + void dupRows_(bool *changed); + + /// check if lb <= ub for all variables and constraints. + SolveStatus checkBounds_(ProblemPtr p); + + void findLinVars_(); + + void findAllBinCons_(); + void fixToCont_(); + + void getLfBnds_(LinearFunctionPtr lf, double *lo, double *up); + void getSingLfBnds_(LinearFunctionPtr lf, double *lo, double *up); + + SolveStatus linBndTighten_(ProblemPtr p, bool apply_to_prob, + ConstraintPtr c_ptr, bool *changed, ModQ *mods, UInt *nintmods); + + void purgeVars_(PreModQ *pre_mods); + + /** + * \brief Common routine for building relaxation by copying all the linear + * constraints and variable-bounds from a given problem. + * + * \param[in] p The problem whose relaxation we want to create. + * \param[in] rel The relaxation in which we want to add new variables + * and constraints. + * \param [out] is_inf True if problem p is found to be infeasible, false + * otherwise. + */ + void relax_(ProblemPtr p, RelaxationPtr rel, bool *is_inf); + + void substVars_(bool *changed, PreModQ *pre_mods); + + /// Round the bounds + void tightenInts_(ProblemPtr p, bool apply_to_prob, bool *changed, + ModQ *mods); + + bool treatDupRows_(ConstraintPtr c1, ConstraintPtr c2, double mult, + bool *changed); + + void updateLfBoundsFromLb_(ProblemPtr p, bool apply_to_prob, + LinearFunctionPtr lf, double lb, double uu, + bool is_sing, bool *changed, ModQ *mods, + UInt *nintmods); + + void updateLfBoundsFromUb_(ProblemPtr p, bool apply_to_prob, + LinearFunctionPtr lf, double ub, double ll, + bool is_sing, bool *changed, ModQ *mods, + UInt *nintmods); + + SolveStatus varBndsFromCons_(ProblemPtr p, bool apply_to_prob, bool *changed, + ModQ *mods, UInt *nintmods); + + SolveStatus varBndsFromObj_(ProblemPtr p, double ub, bool apply_to_prob, + bool *changed, ModQ *mods); +}; +typedef boost::shared_ptr LinearHandlerPtr; +typedef boost::shared_ptr ConstLinearHandlerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Logger.h b/thirdparty/linux/include/minotaur/Logger.h new file mode 100644 index 0000000..833fddd --- /dev/null +++ b/thirdparty/linux/include/minotaur/Logger.h @@ -0,0 +1,96 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2010 - 2014 The MINOTAUR Team. +// + +/** + * \file Logger.h + * \brief Declare class for creating logs. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURLOGGER_H +#define MINOTAURLOGGER_H + +/** + * This class handles all output. Attached to each message is the level and + * only output requested by the user is generated. Formation of C-style + * output is delayed until after the level is checked. C++-style output + * requires that a string be written and passed to the logger; the code + * needs to check if the output would be used prior to constructing it. + * + * Note GAMS will create a derived class that differentiates where to + * send the output (log, listing, or status files) based on the level. + * A FORTRAN derived class will create a string and send it to a wrapper + * that writes the string using FORTRAN calls. + * + * We may want to describe the output levels in this section. + */ + +#include +#include + +#include "Types.h" + +namespace Minotaur { + class Logger { + public: + /// Default constructor + Logger(LogLevel max_level=LogInfo); + + /// Destroy + virtual ~Logger(); + + /// Do not write messages that are above maxLevel + inline void setMaxLevel(LogLevel maxLevel) { maxLevel_ = maxLevel; } + + /// Get the maxLevel + inline LogLevel getMaxLevel() const { return maxLevel_; } + + /// Get the stream where one can write messages. + virtual std::ostream& msgStream(LogLevel level) const; + + /// Get the stream where one can write errors. + std::ostream& errStream() const; + + protected: + // Maximum output level + LogLevel maxLevel_; + + private: + /// Copy constructor is not allowed. + Logger (const Logger &l); + + /// Copy by assignment is not allowed. + Logger & operator = (const Logger &l); + + /// nullbuf class does not print anything. + class nullbuf : public std::streambuf { + protected: + /// \todo Don't know what this does. + virtual int_type overflow(int_type c) { return c; } + }; + /// Null stream buffer + nullbuf nb_; + + // Null output stream + mutable std::ostream nout_; + }; + + typedef boost::shared_ptr LoggerPtr; + typedef boost::shared_ptr ConstLoggerPtr; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/MINLPDiving.h b/thirdparty/linux/include/minotaur/MINLPDiving.h new file mode 100644 index 0000000..1a7e041 --- /dev/null +++ b/thirdparty/linux/include/minotaur/MINLPDiving.h @@ -0,0 +1,339 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file MINLPDiving.h + * \brief Define the class MINLPDiving derived from base class Heuristics. + * \author Jayash Koshal, Argonne National Laboratory + * + * Declares the class MINLPDiving. + */ + + #ifndef MINOTAURMINLPDIVING_H + #define MINOTAURMINLPDIVING_H + + #include "Heuristic.h" + #include + #include + + + namespace Minotaur { + class Engine; + class LinearHandler; + class Problem; + class Solution; + class Timer; + class VarBoundMod; + typedef boost::shared_ptr ConstSolutionPtr; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr VarBoundModPtr; + + /// Direction of rounding + typedef enum { + Floor, /// Round to the smallest integer + Ceil, /// Round to the largest integer + Nearest, /// Round to the nearest integer + Farthest /// Round to the farthest integer + } Direction; + + /// Order of rounding: least fractional or most fractional + typedef enum { + Least, /// Select the variable with Least fractional part + Most /// Select the variable with Most fractional part + } Order; + + /// Type of score evaluation for fractional variable + typedef enum { + Fractional, /// Score of variable is the fractional part` + VectorLength, /// Score of variable is the Vector Length + LexBound, /// Score of variable is the index of the variable + ReducedCost /// Score of variable is the reduced cost + } Scoretype; + + /** + * \brief A statistic struct for MINLP Diving heuristic + */ + struct DivingheurStats { + UInt numNLPs[4]; /// NLPs solved in each selection method. + UInt numInfeas[4]; /// Infeasible NLPs solved. + UInt errors[4]; /// NLPs that encountered errors. + UInt numSol[4]; /// Solutions obtained. + double time[4]; /// Time for each selection method. + UInt iterations[4]; /// NLP iterations. + UInt totalNLPs; /// NLPs solved. + UInt totalSol; /// Solutions found. + UInt numLocal; /// Local optimal solutions obtained. + double best_obj_value; /// Best objective value of feasible solution. + double totalTime; /// Total time taken in Diving heuristics. + }; + + /** + * \brief Diving heuristif for MINLPs. + * + * A Diving Heuristic used to find solutions for Mixed Integer NLPs + * by solving the Relaxed NLP using an NLP engine. The engine is + * called once initially to generate a solution which is rounded + * and used for diving. + */ + + class MINLPDiving : public Heuristic { + public: + + /// default constructor + MINLPDiving(EnvPtr env, ProblemPtr p, EnginePtr e); + + /// default destructor + ~MINLPDiving(); + + /// call to heuristic + void solve(NodePtr node, RelaxationPtr rel, SolutionPoolPtr s_pool); + + /// writing the statistics to the logger + void writeStats(std::ostream &out) const; + + protected: + + const static std::string me_; + + /// Average of dual variables from the previous iterations + /// which is to be used to reduced cost diving + DoubleVector avgDual_; + + /// Engine being used to solve the problem + EnginePtr e_; + + /// Environment + EnvPtr env_; + + /// Gradient of objective function for vector length diving + double* gradientObj_; + + /// If a value is this far from an integer, it is considered + /// integer. + double intTol_; + + /// Mods implied by bound changes in the previous node's presolve. + /// We only store mods of one node only. + ModVector lastNodeMods_; + + /// Linear Handler for presolving. + LinearHandler *lh_; + + /// Logger + LoggerPtr logger_; + + /// Maximum number of NLPs allowed for diving heuristic + UInt maxNLP_; + + /// Maximum number of feasible solution required from heuristic + UInt maxSol_; + + /** A stack of modification pointer. All modification are stored + * in stack and for backtracking the stack is unwinded to restore + * feasibility + */ + std::stack mods_; + + /// Number of method for selection of variables + UInt nSelector_; + + /// Problem to be solved + ProblemPtr p_; + + /// Violated variable fraction part list + DoubleVector score_; + + /// Statistics for the heuristic + DivingheurStats *stats_; + + /// Timer for this heuristic + Timer* timer_; + + /// violated variable index list + UIntVector violated_; + + typedef UInt (MINLPDiving::*FuncPtr) (UInt numfrac, + const double* x, Direction d, Order o); + + /** + * \brief Backtracking method + * + * \param[in] n_flipped Number of bound changes made in previous + * dive + * + * All the changes are made by unwinding the modification stack + * n_flipped number of times + */ + void backtrack_(UInt n_flipped); + + /** + * \brief Fractional selection method for fractional variable + * + * \param[in] numfrac Number of fractional variables in current + * solution + * \param[in] x Constant pointer to primal solution + * \param[in] d Direction of rounding + * \param[in] o Order for selection of fractional variables + */ + UInt FracBounds_(UInt numfrac, const double* x, + Direction d, Order o); + + /** + * \brief Get the score of solution + * + * \param[in] x Const pointer to the primal solution + * \param[in] s Scoretype + * + * The score of the solution is determined based on one of the + * predefined scoretypes. + */ + void getScore_(const double* x, Scoretype s); + + /** + * \brief Function to implement diving + * + * \param[in] i Index of the method number + * \param[in] x Const pointer to the root node primal solution + * \param[in] s_pool Pointer to the solution pool + * + * Method for selection of fractional variable as candidate for + * rouding are chosen for diving. Changes made to the problem are + * stored in the stack of modification. + */ + void implementDive_(int i, const double*x, SolutionPoolPtr s_pool); + + /** + * \brief The number of fractional variables in current solution + * + * \param[in] x Const pointer to primal solution + * + * \return Number of fractional variables + */ + UInt isFrac_(const double* x); + + /** + * \brief Lexicographic selection method for fractional variable + * + * \param[in] numfrac Number of fractional variables in current + * solution + * \param[in] x Constant pointer to primal solution + * \param[in] d Direction of rounding + * \param[in] o Order for selection of fractional variables + */ + UInt LexBounds_(UInt numfrac, const double* x, + Direction d, Order o); + + /** + * \brief Reduced cost diving selection method for fractional variable + * + * \param[in] numfrac Number of fractional variables in current + * solution + * \param[in] x Constant pointer to primal solution + * \param[in] d Direction of rounding + * \param[in] o Order for selection of fractional variables + */ + UInt ReducedCost_(UInt numfrac, const double* x, + Direction d, Order o); + + /** + * \brief Restore the bounds for the problem + * + * \param[in] LB_copy Pointer to saved bounds + * \param[in] UB_copt Pointer to saved bounds + * \param[in] vars Number of variables in the problem + */ + void restoreBounds_(double* LB_copy, double* UB_copy, UInt vars); + + /** + * \brief Rounding a value in a given direction + * + * \param[in] value Fractional value to be rounded + * \param[in] d Direction to be used for rounding + * + * \return rounded value of the fractional variable + */ + double rounding_(double value, Direction d); + + /** + * \brief Save bounds of the problem + * + * \param[in] LB_copy Pointer to bounds, space has to be allocated + * \param[in] UB_copt Pointer to bounds, space has to be allocated + * \param[in] vars Number of variables in the problem + */ + void saveBounds_(double* LB_copy, double* UB_copy, UInt vars); + + /** + * \brief Select the method, ordering and direction. + * + * \param[in] i Index of the method number + * \param d Reference to direction of rouding + * \param o Reference to order for selecting variable + * + * \return FuncPtr Address of the selected Diving method + */ + FuncPtr selectHeur_(int i, Direction &d, Order &o); + + /** + * \brief Function to decide on diving or not + * + * return true or false + * + * We decide not to dive is the problem size is large and hessian + * is dense + */ + bool shouldDive_(); + + /** + * \brief Sort the score + * + * \param[in] left Beginning of the container + * \param[in] right End of the container + * + * If the number of non-zero in hessian or number of bin+int <20 + * don't dive + */ + void sort_(UInt left, UInt right); + + /** + * \brief Update the average of dual multiplier + * + * \param[in] sol Constant Pointer to the solution + */ + void updateAvgDual_(ConstSolutionPtr sol); + + /** + * \brief Vector Length selection method for fractional variable + * + * \param[in] numfrac Number of fractional variables in current + * solution + * \param[in] x Constant pointer to primal solution + * \param[in] d Direction of rounding + * \param[in] o Order for selection of fractional variables + */ + UInt VectorLength_(UInt numfrac, const double* x, + Direction d, Order o); + + /// Function to decide on vector length diving + bool vectorFlag_(UInt min_vlength); + + }; + + typedef boost::shared_ptr MINLPDivingPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/MaxFreqBrancher.h b/thirdparty/linux/include/minotaur/MaxFreqBrancher.h new file mode 100644 index 0000000..c881907 --- /dev/null +++ b/thirdparty/linux/include/minotaur/MaxFreqBrancher.h @@ -0,0 +1,137 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file MaxFreqBrancher.h + * \brief Declare methods and data structures for maximum-frequency branching. + * \author Suresh B, IIT Bombay + */ + + +#ifndef MINOTAURMAXFREQBRANCHER_H +#define MINOTAURMAXFREQBRANCHER_H + +#include "Brancher.h" + +namespace Minotaur { + + class Timer; + + struct MaxFreqBrStats { + UInt calls; /// Number of times called to find a branching candidate. + double time; /// Total time spent in branching. + }; + + /// A class to select a variable for branching using maximum-frequency branching. + class MaxFreqBrancher : public Brancher { + + public: + /// Construct using an environment pointer and initialize . + MaxFreqBrancher(EnvPtr env, HandlerVector & handlers); + + /// Destroy. + ~MaxFreqBrancher(); + + // Find a branching candidate. Returns NULL if x does not have any + // thing to branch on or if no branching candidates are needed. + Branches findBranches(RelaxationPtr rel, NodePtr node, + ConstSolutionPtr sol, SolutionPoolPtr s_pool, + BrancherStatus & br_status, ModVector &mods); + + // Update pseudo-cost/other information after branching. + virtual void updateAfterLP(NodePtr, ConstSolutionPtr); + + // write statistics. + void writeStats(std::ostream &out) const; + + // Return name. + std::string getName() const; + + /** + * \brief Initialize data structures. + * + * \param[in] rel Relaxation for which this brancher is used. + */ + void initialize(RelaxationPtr rel); + + private: + /// Name + const static std::string me_; + + /// Tolerance for checking if a variable is fixed or not. + double zTol_; + + /// Status of problem after using this brancher + BrancherStatus status_; + + /// The problem that is being solved at this node. + RelaxationPtr rel_; + + DoubleVector x_; + + /** + * \brief Handlers that will be used to find candidates and the relaxations + * after branching. + */ + HandlerVector handlers_; + + /// Timer + Timer *timer_; + + /// Statistics. + MaxFreqBrStats * stats_; + + /// Set of candidates (for simple branching on variable dichotomy). + BrVarCandSet cands_; + + /// True if data structures are initialized. False otherwise. + bool init_; + + /** + * \brief The vector that keeps a count of how many times a candidate + * has been fraction, for each candidate. + */ + UIntVector fracCount_; + + /** + * \brief The vector that keeps a count of how many times a candidate + * has been not fixed, for each candidate. + */ + UIntVector unfixedCount_; + + /** + * \brief Update fractional count vector fracCount_ based upon current + * set of candidates. + */ + void updateFracCount_(); + + /** + * \brief Update unfixed count vector unfixedCount_ based upon current + * relaxation. + */ + void updateUnfixedCount_(); + + /// Fills up the set of candidates in the cands_ array. + void findCandidates_(); + + /// Returns the candidate that has maximum frequency. + BrCandPtr findBestCandidate_(); + + }; + typedef boost::shared_ptr MaxFreqBrancherPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/MaxVioBrancher.h b/thirdparty/linux/include/minotaur/MaxVioBrancher.h new file mode 100644 index 0000000..1342f7f --- /dev/null +++ b/thirdparty/linux/include/minotaur/MaxVioBrancher.h @@ -0,0 +1,99 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file MaxVioBrancher.h + * \brief Declare methods and data structures for maximum violation branching. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURMAXVIOBRANCHER_H +#define MINOTAURMAXVIOBRANCHER_H + +#include "Brancher.h" + +namespace Minotaur { + + class Timer; + + struct MaxVioBrStats { + UInt calls; /// Number of times called to find a branching candidate. + double time; /// Total time spent in branching. + }; + + /// A class to select a variable for branching using maximum-violated branching. + class MaxVioBrancher : public Brancher { + + public: + /// Construct using an environment pointer and initialize . + MaxVioBrancher(EnvPtr env, HandlerVector & handlers); + + /// Destroy. + ~MaxVioBrancher(); + + // find branches after a node is processed. + Branches findBranches(RelaxationPtr rel, NodePtr node, + ConstSolutionPtr sol, SolutionPoolPtr s_pool, + BrancherStatus & br_status, ModVector &mods); + + /// Update pseudo-cost/other information after branching. + virtual void updateAfterLP(NodePtr , ConstSolutionPtr ); + + // write statistics. + void writeStats(std::ostream &out) const; + + /// Return name. + std::string getName() const; + + private: + /// Set of candidates (variables for branching). + BrVarCandSet cands_; + + /// Vector of candidates (general candidates for branching). + BrCandVector gencands_; + + /** + * \brief Handlers that will be used to find candidates and also the + * relaxations after branching. + */ + HandlerVector handlers_; + + /// Name + const static std::string me_; + + /// The problem that is being solved at this node. + RelaxationPtr rel_; + + /// Statistics. + MaxVioBrStats * stats_; + + /// Timer + Timer *timer_; + + DoubleVector x_; + + /// Fills up the set of candidates in the cands_ array. + void findCandidates_(ModVector &mods, bool &should_prune); + + /// Returns the candidate that was violated maximally. + BrCandPtr findBestCandidate_(); + + }; + typedef boost::shared_ptr MaxVioBrancherPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/MinotaurCFortran.h b/thirdparty/linux/include/minotaur/MinotaurCFortran.h new file mode 100644 index 0000000..d833979 --- /dev/null +++ b/thirdparty/linux/include/minotaur/MinotaurCFortran.h @@ -0,0 +1,16 @@ +#ifndef F77_HEADER_INCLUDED +#define F77_HEADER_INCLUDED + +/* Mangling for Fortran global symbols without underscores. */ +#define F77_GLOBAL(name,NAME) name##_ + +/* Mangling for Fortran global symbols with underscores. */ +#define F77_GLOBAL_(name,NAME) name##_ + +/* Mangling for Fortran module symbols without underscores. */ +#define F77_MODULE(mod_name,name, mod_NAME,NAME) __##mod_name##_MOD_##name + +/* Mangling for Fortran module symbols with underscores. */ +#define F77_MODULE_(mod_name,name, mod_NAME,NAME) __##mod_name##_MOD_##name + +#endif diff --git a/thirdparty/linux/include/minotaur/MinotaurConfig.h b/thirdparty/linux/include/minotaur/MinotaurConfig.h new file mode 100644 index 0000000..5ebe94b --- /dev/null +++ b/thirdparty/linux/include/minotaur/MinotaurConfig.h @@ -0,0 +1,16 @@ +#ifdef MINOTAURCONFIG_H +#error "Do not include MinotaurConfig.h in a header file." +#else +#define MINOTAURCONFIG_H +#endif + +#include "MinotaurCFortran.h" + +#ifdef F77_GLOBAL +#define F77_FUNC F77_GLOBAL +#define F77_FUNC_ F77_GLOBAL_ +#endif + +/* Define to 1 if you have the getrusage() function. */ +#define MINOTAUR_RUSAGE + diff --git a/thirdparty/linux/include/minotaur/MinotaurDeconfig.h b/thirdparty/linux/include/minotaur/MinotaurDeconfig.h new file mode 100644 index 0000000..1046886 --- /dev/null +++ b/thirdparty/linux/include/minotaur/MinotaurDeconfig.h @@ -0,0 +1,45 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +// /** +// Some headers in external packages like Ipopt and Osi redefine the +// following. To avoid compiler warnings, we undefine them here. This should +// not be included from any header files because if someone else includes our +// headers in their package, then this will clear their definitions. +// +// This should be called from .cpp files only much like MinotaurConfig.h +// +// MinotaurConfig.h is not present in the source code but is generated at +// build time by configure. This file should not be included in any of the +// Minotaur headers as it has generic names that may conflict with similar +// definitions in other packages. +// +// \todo For now we have MINOTAUR_RUSAGE also defined in MinotaurConfig.h. Not +// sure if it belongs there. +// */ + +#undef PACKAGE_BUGREPORT + +#undef PACKAGE_NAME + +#undef PACKAGE_STRING + +#undef PACKAGE_TARNAME + +#undef PACKAGE_VERSION + +#undef F77_FUNC_ + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Modification.h b/thirdparty/linux/include/minotaur/Modification.h new file mode 100644 index 0000000..ccc897b --- /dev/null +++ b/thirdparty/linux/include/minotaur/Modification.h @@ -0,0 +1,82 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Problem.h + * \brief Declare the base class Modification. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURMODIFICATION_H +#define MINOTAURMODIFICATION_H + +#include "Types.h" + +namespace Minotaur { + class Modification; + class Problem; + class Relaxation; + typedef boost::shared_ptr ModificationPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr RelaxationPtr; + + /** + * Modification is a (pure) abstract class for changes that can be done to a + * problem + */ + class Modification { + protected: + /// Default constructor + Modification() {} + + public: + /// Default destroy + virtual ~Modification() {}; + + /** + * \brief Covert a modification for a relaxation to one for its original + * problem. + * \param[in] rel Relaxation for which this mod is applicable. + * \param[in] p Problem for which the new mod will be applicable. + * \returns Modification applicable to p + */ + virtual ModificationPtr fromRel(RelaxationPtr rel, ProblemPtr p) const + = 0; + + /** + * \brief Covert a modification for a problem to one for its + * relaxation. + * \param[in] p Problem for which this mod is applicable. + * \param[in] rel Relaxation for which the new mod will be applicable. + * \returns Modification applicable to rel. + */ + virtual ModificationPtr toRel(ProblemPtr p, RelaxationPtr rel) const = 0; + + /// Apply it to the problem. + virtual void applyToProblem(ProblemPtr problem) = 0; + + /// Restore the modification for a problem. + virtual void undoToProblem(ProblemPtr problem) = 0; + + /// Write it to 'out'. + virtual void write(std::ostream &out) const = 0; + }; + +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/MsProcessor.h b/thirdparty/linux/include/minotaur/MsProcessor.h new file mode 100644 index 0000000..abe24e7 --- /dev/null +++ b/thirdparty/linux/include/minotaur/MsProcessor.h @@ -0,0 +1,230 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file MsProcessor.h + * \brief Define multi-start node-processor for branch-and-bound + * \author Prashant Palkar, IIT Bombay + */ + +#ifndef MINOTAURMSPROCESSOR_H +#define MINOTAURMSPROCESSOR_H + +#include "NodeProcessor.h" + +namespace Minotaur { + + class Engine; + class Problem; + class Solution; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ConstProblemPtr; + typedef boost::shared_ptr ConstSolutionPtr; + + struct MBPStats { + UInt bra; /// Number of times relaxation became infeasible + UInt inf; /// Number of times relaxation became infeasible + UInt opt; /// Number of times relaxation gave optimal feasible solution + UInt prob; /// Number of times problem ocurred in solving + UInt proc; /// Number of nodes processed + UInt ub; /// Number of nodes pruned because of bound + }; + + /** + * \brief Simple multi-start node-processor for branch-and-bound. + * + * MsProcessor is a derived class of NodeProcessor. It is meant to solve + * a relaxation multiple times at each node using different starting points. + * It performs only pruning and branching in a node. Does not call any + * presolving or cutting. + */ + class MsProcessor : public NodeProcessor { + + public: + /// Default constructor + MsProcessor(); + + /// Constructor with a given engine. + MsProcessor(EnvPtr env, EnginePtr engine, HandlerVector handlers_); + + /// Destroy + ~MsProcessor(); + + // True if a new solution was found while processing this node. + bool foundNewSolution(); + + // Find branches that will be used to branch at this node. + Branches getBranches(); + + // Get warm-start information. + WarmStartPtr getWarmStart(); + + // Implement NodeProcessor::process(). + void process(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool); + + // Get a corner of the variable space box randomly + double* getBoxCorner(UInt n, RelaxationPtr rel1, + int threadid, int K); + + // Get a corner of the variable space box randomly + double* getFarBoxCorner(UInt n, RelaxationPtr rel1, + int threadid, double* prev_opt, int K); + + + // Generate a random starting point within variable bounds (for relaxations) + double* getStartPointScheme1(UInt n, RelaxationPtr rel1); + + /** + * Generate a (re)starting point preferably within variable bounds outside a + * radius (for relaxations) + */ + double* getStartPointScheme2(UInt n, RelaxationPtr rel1, int threadid, + double radius, int numsols, + double* prev_start_point); + + /** + * Generate a (re)starting point preferably within variable bounds outside a + * radius (for relaxations) in a conjugate direction + */ + double* getStartPointScheme4(UInt n, RelaxationPtr rel1, int threadid, + double radius, int numsols, + double* prev_start_point, + double* prev_opt, double costhetalim); + + /** + * Generate a starting point as the convex combination of prev optimal + * and the farthest box corner from that point. + */ + double* getStartPointScheme5(UInt n, RelaxationPtr rel1, int threadid, + double radius, double* prev_start_point, + double* prev_opt, int K, double lambda); + + /** + * Generate a starting point and take a direction as the linear + * combination of active constraint gradients at that point; choose step + * length based on the function decrease along this direction and + * average constraint violation. + */ + //double* getStartPointScheme6(UInt n, RelaxationPtr rel1, int threadid, + //double radius, int numsols, + //double* prev_start_point, + //double* prev_opt, int K, double lambda); + + // Generate initial point based on variable fixing + double* genInitialPoint(UInt n, RelaxationPtr rel); + + // Calculating inner product of two vectors + double InnerProduct(double b[], double c[], UInt n); + + // Calculating Euclidean norm + double ENorm(double b[], UInt n); + + // Calculate the Euclidean distance between two vectors + double EDist(double b[], double c[], UInt n); + + // Testing parallelism + void par(); + + // write statistics. Base class method. + void writeStats(std::ostream &out) const; + + // write statistics. Base class method. + void writeStats() const; + + protected: + + /// Modifications done to NLP before solving it. + std::stack relMods_; + + /// Branches found by this processor for this node + Branches branches_; + + /** + * If true, we continue to search, if engine reports error. If false, + * we assume that the relaxation is infeasible when engine returns error. + */ + bool contOnErr_; + + /// If lb is greater than cutOff_, we can prune this node. + double cutOff_; + + /// Engine used to process the relaxation + EnginePtr engine_; + + /// Status of the engine + EngineStatus engineStatus_; + + /// All the handlers that are used for this processor + HandlerVector handlers_; + + /// Log + LoggerPtr logger_; + + /// For logging. + static const std::string me_; + + /// How many new solutions were found by the processor. + UInt numSolutions_; + + /// Number of restarts to improve the first intial point + UInt numRestarts_; + + /// Number of processing cores to be used by the processor + UInt numThreads_; + + /// Relaxation that is processed by this processor. + RelaxationPtr relaxation_; + + /// Scheme id for generating initial point + UInt schemeId_; + +/// Statistics + MBPStats stats_; + + /// Warm-start information for start processing the children + WarmStartPtr ws_; + + /** + * Check if the solution is feasible to the original problem. + * In case it is feasible, we can store the solution and update the + * upper bound. Additionally, if the solution is optimal for the + * current node, then the node can be pruned. + */ + virtual bool isFeasible_(NodePtr node, ConstSolutionPtr sol, + SolutionPoolPtr s_pool, bool &should_prune); + + /// Solve the relaxation. + virtual void solveRelaxation_(); + + /// Solve the relaxation. + virtual void solveRelaxation_(EnginePtr e1); + + + /** + * Check if a node can be pruned either because the relaxation is + * infeasible or because the cost is too high. + */ + virtual bool shouldPrune_(NodePtr node, double solval, + SolutionPoolPtr s_pool); + + }; + + typedef boost::shared_ptr MsProcessorPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/MultilinearTermsHandler.h b/thirdparty/linux/include/minotaur/MultilinearTermsHandler.h new file mode 100644 index 0000000..29cc437 --- /dev/null +++ b/thirdparty/linux/include/minotaur/MultilinearTermsHandler.h @@ -0,0 +1,315 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file MultilinearTermsHandler.h + * \brief A Handler for a general collection of MultilinearTerms + */ + +#ifndef MINOTAURMULTILINEARTERMSHANDLER_H +#define MINOTAURMULTILINEARTERMSHANDLER_H + +#include + +#include "Handler.h" +#include "LPEngine.h" + + +namespace Minotaur { + +//typedef boost::shared_ptr ConstProblemPtr; +//typedef boost::shared_ptr ConstVariablePtr; + +// These should maybe go in Terms.h and be public -- they seem pretty generic +typedef std::set SetOfVars; +typedef std::set SetOfSetOfVars; + + +/* + * This class is needed to store information about term cover + * It is not a horribly efficient implementation, as I didn't even bother + * to make an adjacency list (yet) + */ + +class Hypergraph { + +public: + +class CompareSetsOfVars +{ +public: + bool operator()(const SetOfVars &lhs, const SetOfVars &rhs ) const + { + return lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } +}; + + typedef std::map SetOfVarsDoubleMap; + typedef std::list ListOfSetOfVars; + typedef std::map AdjListType; + +public: + Hypergraph(ConstProblemPtr p) : problem_(p) {} ; + virtual ~Hypergraph () {}; + + void adjustEdgeWeightsBetween(const VariablePtr v, const SetOfVars &g, + bool phaseOne); + void create(std::map const &terms); + double getWeight(const SetOfVars &e); + SetOfVars heaviestEdge(bool &maxWeightPositive) const; + VariablePtr heaviestIncidentVertex(const SetOfVars &g); + ListOfSetOfVars incidentEdges(ConstVariablePtr v) const; + + VariablePtr maxWeightedDegreeVertex(bool &maxWeightPositive) const; + int numEdges() const { return E_.size(); } + int numVertices() const { return V_.size(); } + + SetOfVars randomEdge(bool &maxWeightPositive); + void resetWeights(); + void setWeight(const SetOfVars &e, double w); + double weightedDegree(ConstVariablePtr v) const; + void write(std::ostream &out) const; + +private: + + ConstProblemPtr problem_; + + SetOfVars V_; + AdjListType adjList_; + + SetOfSetOfVars E_; + SetOfVarsDoubleMap weights_; + SetOfVarsDoubleMap originalWeights_; + +}; + + +typedef boost::shared_ptr HypergraphPtr; +typedef boost::shared_ptr HypergraphConstPtr; + +/** A MultilinearTermsHandler handles all (single) multilinear term + * constraints + */ +class MultilinearTermsHandler : public Handler { + +public: + typedef enum { + relaxInit_Call, + relaxNodeInc_Call, + getBrMod_Call + } HandleCallingFunction; + + +public: + + /// Default constructor. + MultilinearTermsHandler(EnvPtr env, ProblemPtr problem); + + /// Destroy. + virtual ~MultilinearTermsHandler() {}; + + /** + * Add constraint + */ + void addConstraint(ConstraintPtr newcon, ConstVariablePtr ovar, + std::set ivars); + +private: + void addConstraint(ConstraintPtr) {}; + +public: + + // base class method + virtual void getBranchingCandidates(RelaxationPtr rel, + const DoubleVector &x, ModVector &mods, + BrVarCandSet &cands, BrCandVector &, + bool &is_inf); + + /** + * Check if each multilinear term is satisfied. Stops on the first + * violated constraint. + */ + bool isFeasible(ConstSolutionPtr, RelaxationPtr, bool &should_prune, + double &inf_meas ); + + // Does nothing. + void relaxInitFull(RelaxationPtr, bool *) { assert(0); } ; + + // Build initial relaxation + void relaxInitInc(RelaxationPtr, bool *); + + // Does nothing. + void relaxNodeFull(NodePtr, RelaxationPtr, bool *) {assert(0); }; + + // All changes are in the branches to the relaxation, so this need not do anything + void relaxNodeInc(NodePtr n, RelaxationPtr r , bool *is_inf); + + + /// Can not return any cuts for this case. + void separate(ConstSolutionPtr, NodePtr , RelaxationPtr , CutManager *, + SolutionPoolPtr, bool *, SeparationStatus *) {}; + + virtual ModificationPtr getBrMod(BrCandPtr , DoubleVector &, + RelaxationPtr , BranchDirection ); + + virtual Branches getBranches(BrCandPtr cand, DoubleVector &x , + RelaxationPtr rel, SolutionPoolPtr s_pool); + + // presolve. + virtual SolveStatus presolve(PreModQ *, bool *) {return Finished;}; + + // Implement Handler::presolveNode() + virtual bool presolveNode(RelaxationPtr, NodePtr, SolutionPoolPtr, ModVector &, + ModVector &) + {return false;}; + + + // Write name + std::string getName() const { return std::string("Multilinear Term Handler"); } + +protected: + + /// Environment + EnvPtr env_; + + /// The handler 'handles' constraints of this problem + ConstProblemPtr problem_; + +private: + + LPEnginePtr lp_engine_; + + // (Absolute?) error tolerance for branching. + double eTol_; + LoggerPtr logger_; + + // Parameters for term cover + UInt maxGroupSize_; + double augmentCoverFactor_; + int initialTermCoverSize_; + +private: + typedef std::set SetOfVars; + typedef std::set SetOfSetOfVars; + + // This contains map in *original* variables (not relaxation variables) + typedef std::map TermContainer; + TermContainer termsO_; + + TermContainer termsR_; + + // This contains relaxation variable pointers + typedef std::vector GroupContainer; + GroupContainer groups_; + + typedef std::vector PointContainer; + PointContainer points_; + + // Stores the lambda variables for group + // These (of course) will be variables in the relaxation + std::vector > lambdavars_; + +#if 0 + //XXX Don't need these anymore? + // Multimap between + // The map is between + typedef std::multimap VariableConstraintMMap; + VariableConstraintMMap xConMMap_; + + typedef std::map ConstraintIntMap; + ConstraintIntMap conGroupMap_; + + // Map between + // The map is between + std::map zConMap_; +#endif + + // We want (int, VarPtr) as key. ConstraintPtr as value + typedef std::pair IntVarPtrPair; + typedef std::map IntVarPtrPairConstraintMap; + + IntVarPtrPairConstraintMap xConMap_; + IntVarPtrPairConstraintMap zConMap_; + + + // Hypergraph for termcover + HypergraphPtr H_; + +public: + typedef TermContainer::const_iterator ConstTermIterator; + typedef TermContainer::iterator TermIterator; + + typedef GroupContainer::const_iterator ConstGroupIterator; + typedef GroupContainer::iterator GroupIterator; + + +private: + + // A bunch of helper functions + void addEdgeToGroups_(const SetOfVars &e, bool phaseOne); + bool allVarsBinary_(const SetOfVars &v) const; + bool edgeIsContainedInGroup_(const SetOfVars &e, const SetOfVars &g) const; + bool edgeWillFitInGroup_(const SetOfVars &e, const SetOfVars &g) const; + + // Helper function to do branch + BranchPtr doBranch_(BranchDirection UpOrDown, ConstVariablePtr v, + double bvalue); + + // A greedy dense term covering heuristic + void greedyDenseHeuristic_(); + + /* This chunk of code adds (or modifies) + x_{V_g} = \sum_{k=1}^{2 |V_g|} \lambda_k^g \chi^{k,g} \forall g \in G + */ + void handleXDefConstraints_(RelaxationPtr relaxation, HandleCallingFunction wherefrom, ModVector &mods); + + /* This chunk of code adds + z_t = \sum_{k=1}^{2 |V_g|} \lambda_k^g, \Prod_{j \in J_t} \chi_j^{g,k} + \forall J_t \subseteq V_g + */ + void handleZDefConstraints_(RelaxationPtr relaxation, HandleCallingFunction wherefrom, ModVector &mods); + + // Helper function to make the groups + void makeGroups_(); + + // Returns the powerset of s + std::set powerset_(SetOfVars const &s); + + // Removes subsets that appear in the groups + void removeSubsetsFromGroups_(); + + // Setup the (initial) weights for weighted term cover approach + //void setupWeights_(); + + bool varsAreGrouped_(SetOfVars const &termvars) const; + + //WeightContainer::iterator findMaxWeight_(); + + bool varIsAtLowerBoundAtPoint_(ConstVariablePtr &x, SetOfVars const &p); + bool varIsAtUpperBoundAtPoint_(ConstVariablePtr &x, SetOfVars const &p) { + return !(varIsAtLowerBoundAtPoint_(x, p)); + } + + // A stoopid weighted degree heuristic + void weightedDegreeHeuristic_(); + +}; +typedef boost::shared_ptr MultilinearTermsHandlerPtr; +typedef boost::shared_ptr MultilinearConstHandlerPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NLPEngine.h b/thirdparty/linux/include/minotaur/NLPEngine.h new file mode 100644 index 0000000..696aa81 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NLPEngine.h @@ -0,0 +1,61 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file NLPEngine.h + * \brief Declare NLPEngine Class for solving nonlinear problems using a + * nonlinear solver. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURNLPENGINE_H +#define MINOTAURNLPENGINE_H + +#include "Engine.h" + +namespace Minotaur { + + /** + * The NLPEngine class is an abstract class for interfacing NLP solvers (like + * Ipopt). A derived class must implement calls to the NLP solver for + * the methods described here. + * + * Usually, NLP solvers generate a sequence of points and ask back the + * function evaluation, gradient of objective function, jacobian of the + * constraints, hessian of the lagrangean etc. A derived class of NLPEngine + * should therefore implment methods that can return the desired information + * to the solver. + * + * \todo add more methods for modifying the problem + * \todo add more methods for setting solver options and parameters + */ + class NLPEngine : public Engine + { + public: + friend class Problem; + + /// Default constructor. + NLPEngine() {}; + + /// Default destructor. + virtual ~NLPEngine() {}; + + }; + typedef boost::shared_ptr NLPEnginePtr; +} + +#endif +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NLPMultiStart.h b/thirdparty/linux/include/minotaur/NLPMultiStart.h new file mode 100644 index 0000000..aabfa17 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NLPMultiStart.h @@ -0,0 +1,120 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file NLPMultiStart.h + * \brief Define a derived class from class Heuristic for multistart heuristic. + * \author Jayash Koshal, Argonne National Laboratory + * \author A. Mahajan, IIT Bombay + * + * Defines the base class Heuristic. + */ + +#ifndef MINOTAURNLPMULTISTART_H +#define MINOTAURNLPMULTISTART_H + +#include "Heuristic.h" + +namespace Minotaur { + + class Engine; + class Problem; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ProblemPtr; + + + /// Statistic for Multistart heuristic + struct MSHeurStats { + UInt numNLPs; + UInt numInfeas; + UInt numImprove; + UInt numBadstatus; + double time; + UInt iterations; + double bestObjValue; + }; + + + /** + * \brief Multistart heuristic for continuous NLPs. + * + * A Heuristic used to find solutions for continuous NLPs by solving the + * NLP using NLP engine. The engine is called multiple times from different + * strategically constructed starting points. + */ + class NLPMultiStart : public Heuristic { + + public: + + /// Default constructor. + NLPMultiStart(EnvPtr env, ProblemPtr p, EnginePtr e); + + /// Destroy. + ~NLPMultiStart(); + + /// Use this heuristic. + void solve(NodePtr node, RelaxationPtr rel, SolutionPoolPtr s_pool); + + // Write statistics to logger + void writeStats(std::ostream &out) const; + + const static std::string me_; + + private: + + /** bound on the distance. If radius of the ball is less than this + * number then radius = distBound_ + */ + double distBound_; + + /// Engine being used to solve problem. + EnginePtr e_; + + /// Environment + EnvPtr env_; + + /// Logger. + LoggerPtr logger_; + + /// Problem that is being solved. + ProblemPtr p_; + + /// random search direction + double *random_; + + /// Statistics for Multistart heuristic + MSHeurStats stats_; + + /** + * \brief New starting point construction. + * + * Construct an initial point outside a ball centered at current optimal + * solution of the NLP solver and radius being distance between current + * starting point amplified by a factor. + * + * \param[in] Pointa Current initial point for the solver + * \param[in] Pointb Current optimal solution + * \param[in] rho The amplification factor + * \param]in] vars Number of variables + */ + void constructInitial_(double* a, const double* b, double rho, UInt vars); + + }; + + typedef boost::shared_ptr NLPMSPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NLPRelaxation.h b/thirdparty/linux/include/minotaur/NLPRelaxation.h new file mode 100644 index 0000000..3400865 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NLPRelaxation.h @@ -0,0 +1,66 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + + +#ifndef MINOTAURNLPRELAXATION_H +#define MINOTAURNLPRELAXATION_H + +#include "Relaxation.h" + +namespace Minotaur { + + // /** + // A nonlinear relaxation is of the form: + // + // min f(x) + // + // s.t. l_g <= g(x) <= u_g + // + // l_x <= x <= u_x + // + // x real or integer + // + // where g(x) may have a nonlinear function in one or more constraints. + // */ + class NLPRelaxation : public Relaxation { + public: + // /** + // Construct an empty Nonlinear Relaxation. + // */ + NLPRelaxation(); + + // /** + // Construct relaxation from a problem. For now, just copy the whole problem. + // */ + NLPRelaxation(ProblemPtr problem); + + // /** + // Destroy + // */ + virtual ~NLPRelaxation() { }; + + protected: + // /** + // Pointer to the original problem + // */ + ConstProblemPtr originalProblem_; + }; + + typedef boost::shared_ptr NLPRelaxationPtr; + typedef boost::shared_ptr ConstNLPRelaxationPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NlPresHandler.h b/thirdparty/linux/include/minotaur/NlPresHandler.h new file mode 100644 index 0000000..ae209a3 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NlPresHandler.h @@ -0,0 +1,182 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file NlPresHandler.h + * \brief Declare the NlPresHandler class for try some NLP presolve ideas. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURNLPRESHANDLER_H +#define MINOTAURNLPRESHANDLER_H + +#include "Handler.h" + +namespace Minotaur { + +class CGraph; +class CNode; +class PreAuxVars; +typedef boost::shared_ptr CGraphPtr; +typedef boost::shared_ptr PreAuxVarsPtr; + + +/// Store statistics of presolving. +struct NlPresStats +{ + int iters; /// Number of iterations (main cycle). + double time; /// Total time used in initial presolve. + int varDel; /// Number of variables marked for deletion. + int conDel; /// Number of constraints marked for deletion. + int pRefs; /// Number of perspective reformulations + int vBnd; /// Number of times variable-bounds were tightened. + int cBnd; /// Number of times constraint-bounds were tightened. + int cImp; /// Number of times coefficient in a constraint was improved. + int nMods; /// Number of changes in nodes. + int qCone; /// Number of times a quadratic constraint changed to a + /// conic constraint. +}; + + +/// Options for presolve. +struct NlPresOpts { + bool doPresolve; /// True if presolve is enabled, false otherwise. + bool showStats; /// True if stats are displayed, false otherwise. + int maxIters; /// Maximum number of iterations. + bool coeffImp; /// If True, do coefficient improvement. +}; + + +/** + * A NlPresHandler presolves nonlinear constraints. Experimental. + */ +class NlPresHandler : public Handler { +public: + + /// Default constructor. + NlPresHandler(); + + /// Constructor. + NlPresHandler(EnvPtr env, ProblemPtr p); + + /// Destroy + ~NlPresHandler(); + + // Does nothing. + void relaxInitFull(RelaxationPtr , bool *) {}; + + // Does nothing. + void relaxInitInc(RelaxationPtr , bool *) {}; + + // Does nothing. + void relaxNodeFull(NodePtr , RelaxationPtr , bool *) {}; + + // Does nothing. + void relaxNodeInc(NodePtr , RelaxationPtr , bool *) {}; + + /** + * We assume that nonlinear presolve handler is never called for checking + * feasibility. Always return true. + */ + bool isFeasible(ConstSolutionPtr, RelaxationPtr, bool &, double &) + {return true;} + + /** + * Generate valid cuts using linear constraints. + */ + void separate(ConstSolutionPtr , NodePtr , RelaxationPtr , CutManager *, + SolutionPoolPtr , bool *, SeparationStatus *) {}; + + /// Does nothing. + void getBranchingCandidates(RelaxationPtr, const DoubleVector &, + ModVector &, BrVarCandSet &, BrCandVector &, + bool &) {}; + + /// Does nothing. + ModificationPtr getBrMod(BrCandPtr, DoubleVector &, + RelaxationPtr, BranchDirection) + {return ModificationPtr();}; // NULL + + /// Does nothing. + Branches getBranches(BrCandPtr, DoubleVector &, RelaxationPtr, + SolutionPoolPtr) + {return Branches();}; // NULL + + // presolve. + SolveStatus presolve(PreModQ *pre_mods, bool *changed); + + // Implement Handler::presolveNode(). + bool presolveNode(RelaxationPtr p, NodePtr node, SolutionPoolPtr s_pool, + ModVector &p_mods, ModVector &r_mods); + + // Write name + std::string getName() const; + + /** + * \brief Write statistics about presolve. + * \param [in] out The output stream to which statistics are printed. + */ + void writePreStats(std::ostream &out) const; + + // base class method. + void writeStats(std::ostream &out) const; +private: + /// Should we try perspective reformulation? + bool doPersp_; + + /// Should we try perspective reformulation? + bool doQuadCone_; + + /// Environment. + EnvPtr env_; + + /// Tolerance for checking feasibility etc. + double eTol_; + + /// Log manager + LoggerPtr logger_; + + /// Problem that will be presolved. + ProblemPtr p_; + + NlPresStats stats_; + + /// Tolerance for checking zero. + double zTol_; + + /// Who am I? + static const std::string me_; + + void bin2Lin_(ProblemPtr p, PreModQ *mods, bool *changed); + void bin2LinF_(ProblemPtr p, LinearFunctionPtr lf, + UInt nz, const UInt *irow, const UInt *jcol, + const double *values, PreAuxVarsPtr mods); + + bool canBin2Lin_(ProblemPtr p, UInt nz, const UInt *irow, + const UInt *jcol, const double *values); + void chkRed_(bool *changed); + void coeffImpr_(bool *changed); + void computeImpBounds_(ConstraintPtr c, VariablePtr z, + double zval, double *lb, double *ub); + void perspMod_(ConstraintPtr c, VariablePtr z); + void perspRef_(ProblemPtr p, PreModQ *mods, bool *changed); + void quadConeRef_(ProblemPtr p, PreModQ *mods, bool *changed); + SolveStatus varBndsFromCons_(bool *changed); +}; +typedef boost::shared_ptr NlPresHandlerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Node.h b/thirdparty/linux/include/minotaur/Node.h new file mode 100644 index 0000000..88e486e --- /dev/null +++ b/thirdparty/linux/include/minotaur/Node.h @@ -0,0 +1,298 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Node.h + * \brief Define base class Node. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURNODE_H +#define MINOTAURNODE_H + +#include "Types.h" + +namespace Minotaur { + + class Node; + class Relaxation; + class WarmStart; + typedef boost::shared_ptr NodePtr; + typedef boost::shared_ptr ConstNodePtr; + typedef boost::shared_ptr RelaxationPtr; + typedef boost::shared_ptr WarmStartPtr; + + /** + * A Node is a node in the search tree or the branch-and-bound tree. + * Associated with a node is a parent node from which the node is derived by + * adding branching constraints. Similarly a node may have one or more + * children each obtained by adding some branching constraints. + * Associated with each node is an array (or vector) of modifications that + * were applied to the parent in order to get the node. For instance, a + * modification could be change of one or more bounds on the variables. + + * At each node, one can find a solution that is feasible to the original + * instance or show that the relaxation at the node is infeasible or obtain + * some other information. One can, at each node, solve a relaxation, + * tighten it, preprocess it, run heuristics. + + * A node that has been evaluated and does not need any further processing + * and does not need to be branched upon is called a pruned node. A node + * that has not been processed yet is called an active node. A node that has + * been processed (is ready for branching or has been pruned) is called a + * fathomed node. A node whose all successors have been fathomed or deleted + * can be deleted. Since we store at each node, the modification that + * generated it from its parent, we can not delete nodes that have active + * successors. + + * A Child of the current node can be obtained by applying a branch to the + * node. All immediate child nodes are saved in a vector. + */ + class Node { + + public: + /// Default constructor. + Node(); + + /** + * Construct a node from a parent node by applying all the modifications + * stored in the given branch. + */ + Node(NodePtr parentNode, BranchPtr branch); + + /// Default destructor. + virtual ~Node(); + + /// Add a child node. + void addChild(NodePtr childNode); + + /** + * At each node one can make several modifications to the problem. + * Each such modification must be stored. This includes all the + * modifications that were used to create this node from its parent + * (while branching). + */ + void addPMod(ModificationPtr m) { pMods_.push_back(m); } + + /** + * At each node one can make several modifications to the relaxation. + * Each such modification must be stored. This includes all the + * modifications that were used to create this node from its parent + * (while branching). + */ + void addRMod(ModificationPtr m) { rMods_.push_back(m); } + + /** + * Apply the modifications including the branching that were made + * at this node to the problem. + */ + void applyPMods(ProblemPtr p); + + /** + * Apply the modifications including the branching that were made + * at this node to the problem. + */ + void applyRMods(RelaxationPtr rel); + + /** + * Apply the modifications including the branching that were made + * at this node to the problem. First, each modification is translated + * appropriately so that it becomes applicable for this relaxation. + */ + void applyRModsTrans(RelaxationPtr rel); + + /** + * Apply the modifications to problem and relaxation. + */ + void applyMods(RelaxationPtr rel, ProblemPtr p); + + /// Access the children by iterating over the vector. + NodePtrIterator childrenBegin() { return children_.begin(); } + + /// Last child. + NodePtrIterator childrenEnd() { return children_.end(); } + + /** + * Return the pointer to the branch that was used to create this node + * from its parent. + */ + BranchPtr getBranch() const { return branch_; } + + /// Return the depth of the node in the tree. + UInt getDepth() const { return depth_; } + + /// Return the ID of this node. + UInt getId() const { return id_; } + + /// Return the lower bound of the relaxation obtained at this node. + double getLb() const { return lb_; } + + /// Number of children of this node. + UInt getNumChildren() { return children_.size(); } + + /// Return a pointer to the parent node. + NodePtr getParent() const { return parent_; } + + /// Get the status of this node. + NodeStatus getStatus() const { return status_; } + + /// Get the tie-breaking score. + double getTbScore() const { return tbScore_; } + + /// Get the warm start information. + WarmStartPtr getWarmStart() { return ws_; } + + /// \todo Dont know what this is meant for. + void makeChildOf(boost::shared_ptr parent); + + /** + * Get the first modification that was applied at this node to the + * problem (and not the relaxation). Remember + * that the vector starts with modifications that were used to branch. + */ + ModificationConstIterator modsBegin() const { return pMods_.begin(); } + + /// End of modifications applied at this node. + ModificationConstIterator modsEnd() const { return pMods_.end(); } + + /// Reverse iterators. + ModificationRConstIterator modsRBegin() const { return pMods_.rbegin(); } + + /// Reverse iterators. + ModificationRConstIterator modsREnd() const { return pMods_.rend(); } + + /// Set the status of this node. + void setStatus(NodeStatus status) { status_ = status; } + + /// Get the tie-breaking score. + void setTbScore(double d) { tbScore_ = d; } + + /** + * Remove a child node from the list of children. If the node is + * fathomed and if this list is empty, we can delete this node. + */ + void removeChild(NodePtrIterator childNodeIter); + + /// Disassociate all children from this node. + void removeChildren(); + + /// Remove the pointer to the parent node. Used when deleting a node. + void removeParent(); + + /// Remove warm start information associated with this node. + void removeWarmStart() { ws_.reset(); } + + /** + * Set the ID of this node. ID of a node is unique for the given tree. + * The treemanager must ensure this. + */ + void setId(UInt id); + + /// Set the depth of the node in the tree. + void setDepth(UInt depth); + + /// Set a lower bound for the relaxation at this node. + void setLb(double value); + + /// Set warm start information + void setWarmStart (WarmStartPtr ws); + + /** + * Undo the modifications including the branching that were made + * at this node to the problem. + */ + void undoPMods(ProblemPtr p); + + /** + * Undo the modifications including the branching that were made + * at this node to the problem. + */ + void undoRMods(RelaxationPtr r); + + /** + * Undo the modifications including the branching that were made + * at this node to the problem. First, each modification is translated + * appropriately so that it becomes applicable for this relaxation. + */ + void undoRModsTrans(RelaxationPtr r); + + /** + * Undo the modifications including the branching that were made + * at this node to the problem and the relaxation. + */ + void undoMods(RelaxationPtr rel, ProblemPtr p); + + ///Write the node + void write(std::ostream &o) const; + + private: + /** + * The branching constraints that were used to create this node from its + * parent. + */ + BranchPtr branch_; + + /// Vector of immediate child nodes. + NodePtrVector children_; + + /// Depth in the tree. Also tells how many predecessors. + UInt depth_; + + /// Id of this node. + UInt id_; + + /** + * Lower bound on the relaxation at this node (not to original + * relaxation). + */ + double lb_; + + /** + * Vector of modifications that are applied to the problem at this node + * include the ones used in branching. + */ + std::vector pMods_; + + /** + * Vector of modifications that are applied to the relaxation at this node + * include the ones used in branching. + */ + std::vector rMods_; + + /// The parent of this node. This is NULL if the node is a root node. + NodePtr parent_; + + /// The status of this node. + NodeStatus status_; + + /// Score to break tie-breaks. + double tbScore_; + + /// The warm start information saved for this node + WarmStartPtr ws_; + + /// Not allowed to copy a node. + Node(const Node &node); + + /// Not allowed to copy a node. + Node(NodePtr node); + }; + + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NodeHeap.h b/thirdparty/linux/include/minotaur/NodeHeap.h new file mode 100644 index 0000000..7693e21 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NodeHeap.h @@ -0,0 +1,110 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file NodeHeap.h + * \brief Define the class NodeHeap for storing active nodes of the + * branch-and-bound tree on a heap. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURNODEHEAP_H +#define MINOTAURNODEHEAP_H + +#include "ActiveNodeStore.h" + +namespace Minotaur { + + /** + * When the active nodes of the branch-and-bound tree are not explored in a + * last-in-first-out (LIFO) order, we store them in a heap. A heap is a + * binary tree with the properties: + * -# Every node has a score higher than each of its children. + * -# If a node is the only child of its parent, then it is the last node + * in the heap. + * . + * In order to create a heap, we need to have criteria for comparing nodes. + * These criteria are determined by the parameter for + * node-selection-strategy: best bound, best estimate, best estimate+guided + * dive etc. + */ + class NodeHeap : public ActiveNodeStore { + + public: + /// Types of ordering. + enum Type { Value, Depth }; + + /// Constructor. + NodeHeap(Type type) : type_(type) {} + + /// Destroy. + virtual ~NodeHeap(); + + /** + * Return true if there are no active nodes in the heap, otherwise + * return false. + */ + virtual bool isEmpty() const { return nodes_.empty(); } + + /** + * Find the minimum lower bound of all the active nodes in the heap. + * If the heap is ordered by best bound, then the root has the + * minimum value. + */ + virtual double getBestLB() const; + + /// Find the maximum depth of all active nodes. + virtual UInt getDeepestLevel() const; + + /// Remove the best node from the heap. + virtual void pop(); + + /** + * Write in order the node ID and the criteria used to order the + * heap, e.g. bound value and depth. + */ + virtual void write(std::ostream &out) const; + + /// Add a node to the set of active nodes. + virtual void push(NodePtr n); + + /// Set the type of ordering of this heap. + virtual void setType(Type type); + + /// Get access to the best node in this heap. + virtual NodePtr top() const { return (nodes_.front()); } + + /// Get the number of active nodes in the heap. + virtual UInt getSize() const { return (nodes_.size()); } + + /// Get iterator to the first node in the heap. + NodePtrIterator nodesBegin(); + + /// Get iterator to the last node in the heap. + NodePtrIterator nodesEnd(); + + private: + /// Vector of active nodes. + NodePtrVector nodes_; + + /// The type of criteria used to order the heap. + Type type_; + }; + typedef boost::shared_ptr NodeHeapPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NodeIncRelaxer.h b/thirdparty/linux/include/minotaur/NodeIncRelaxer.h new file mode 100644 index 0000000..28beaa4 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NodeIncRelaxer.h @@ -0,0 +1,113 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file NodeIncRelaxer.h + * \brief Declare the NodeIncRelaxer class. It creates relaxation by + * only incrementing changes made in ancestor nodes. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURNODEINCRELAXER_H +#define MINOTAURNODEINCRELAXER_H + +#include "Handler.h" +#include "NodeRelaxer.h" + +namespace Minotaur { + +/** + * The root relaxation is stored as rel_. In each node, we apply all + * modifications stored in each ancestor of the node. When we are done + * processing the node, we undo all these changes. + * + * If we dive after processing a node, we do not need to undo all changes + * and apply them again. We just apply the modifications of the parent. + */ +class NodeIncRelaxer : public NodeRelaxer { +public: + /// Default constructor + NodeIncRelaxer(EnvPtr env, HandlerVector handlers); + + /// Destroy + ~NodeIncRelaxer(); + + // Implement NodeRelaxer::CreateRootRelaxation() + RelaxationPtr createRootRelaxation(NodePtr rootNode, bool &prune); + + // Implement NodeRelaxer::CreateNodeRelaxation() + RelaxationPtr createNodeRelaxation(NodePtr node, bool dived, bool &prune); + + /// Get the current value of modProb_ flag. + bool getModFlag(); + + // Implement NodeRelaxer::reset() + void reset(NodePtr node, bool diving); + + /** + * /brief Set the engine that is used to solve the relaxations. We need to set + * it in order to be able to load warm-starts at a node. + * + * \param[in] e Engine that will be modified whenever a new node is about to + * be processed. + */ + void setEngine(EnginePtr e); + + /** + * \brief If mod_prob is true, the problem will also be modified at each + * node. By default, only the relaxation is modified. + */ + void setModFlag(bool mod_prob); + + // get the relaxation pointer, rel_. + RelaxationPtr getRelaxation(); + + /// Set your own relaxation pointer. + void setRelaxation(RelaxationPtr rel); + + /// Set the problem pointer + void setProblem(ProblemPtr p); +private: + /// Pointer engine used to solve the relaxation. + EnginePtr engine_; + + /// Environment + EnvPtr env_; + + /// Vector of handlers that will make the relaxation. + HandlerVector handlers_; + + /** + * True if Problem is modified in each node, false if only relaxation is + * modified. + */ + bool modProb_; + + /// The problem being solved by branch-and-bound. + ProblemPtr p_; + + /** + * \brief We only keep one relaxation. It is modified at each node and then + * reset. + */ + RelaxationPtr rel_; +}; + +typedef boost::shared_ptr NodeIncRelaxerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NodeProcessor.h b/thirdparty/linux/include/minotaur/NodeProcessor.h new file mode 100644 index 0000000..ca35d82 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NodeProcessor.h @@ -0,0 +1,116 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file NodeProcessor.h + * \brief Define the NodeProcessor class for processing nodes in the + * branch-and-bound algorithm. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURNODEPROCESSOR_H +#define MINOTAURNODEPROCESSOR_H + +#include "Types.h" + +namespace Minotaur { + + class Brancher; + class Relaxation; + class SolutionPool; + class WarmStart; + class CutManager; + typedef boost::shared_ptr BrancherPtr; + typedef boost::shared_ptr RelaxationPtr; + typedef boost::shared_ptr SolutionPoolPtr; + typedef boost::shared_ptr WarmStartPtr; + typedef boost::shared_ptr CutManagerPtr; + /** + * NodeProcessor class is the place that does the most important tasks in + * branch-and-bound. It processes a given node. By processing a node, we + * mean: + * -# presolving + * -# solving the relaxation + * -# checking if the relaxation or the problem itself is infeasible + * -# adding cuts, tightening bounds + * -# branching decision. + * + * The base class can be overridden with derived class for specific classes + * of problems. In the default class, we do no presolving, solve the + * relaxation by calling a continuous solver (lp_engine for LPs and + * nlp_engine for NLPs). We do not add any cuts or tighten bounds. We branch + * lexicographically. + */ + + class NodeProcessor { + public: + /// Default constructor. + NodeProcessor() { } + + /// Destroy. + virtual ~NodeProcessor() { } + + /// Set the brancher that will be used with this node processor. + virtual void setBrancher(BrancherPtr brancher); + + /// Process the root node. + virtual void processRootNode(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool); + + /** + * Process relaxation at the given node. If a solution is found, + * it must be added to the solution pool. + */ + virtual void process(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool) = 0; + + /// Find branches that will be used to branch at this node. + virtual Branches getBranches() = 0; + + /** + * True if the node processor found at least one feasible solution while + * processing this node. + */ + virtual bool foundNewSolution() = 0; + + /** + * Return the warm start information that will be used to start + * processing children. + */ + virtual WarmStartPtr getWarmStart() = 0; + + /// Return brancher. + virtual BrancherPtr getBrancher() { return brancher_;}; + + /// Write statistics to a given output stream + virtual void writeStats(std::ostream &) const {}; + + /// Write statistics to our own logger + virtual void writeStats() const {}; + + virtual void setCutManager(CutManager *) {}; + protected: + /// What brancher is used for this processor + BrancherPtr brancher_; + + }; + + typedef boost::shared_ptr NodeProcessorPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NodeRelaxer.h b/thirdparty/linux/include/minotaur/NodeRelaxer.h new file mode 100644 index 0000000..2a23c55 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NodeRelaxer.h @@ -0,0 +1,95 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file NodeRelaxer.h + * \brief Define the NodeRelaxer class for creating relaxation for nodes in the + * branch-and-bound algorithm. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURNODERELAXER_H +#define MINOTAURNODERELAXER_H + +#include "Types.h" + +namespace Minotaur { + +class Modification; +class Relaxation; +typedef boost::shared_ptr RelaxationPtr; + +/** + * NodeRelaxer class is used to create relaxations for nodes in a tree. + * The relaxation at a node can be created in different ways, depending upon + * the problem and the algorithm used. For instance, in NLP-BB, we can + * simply relax the integrality constraints. In this case, we can just keep + * one copy of the relaxation and change bounds in different nodes. For LP + * based branch-and-reduce, the relaxation could be very different in a + * node, and we may want to create new relaxation in every node. + * + * Relaxations are created using handlers. Therefore, the NodeRelaxer must + * have compatible handlers. For instance, we can not have a handler return + * cuts in NLP-BB. Also, we can not have handler branch on a new variable + * created in a relaxation, if we are creating in each node, new relaxations + * from scratch. + * + * This is the abstract base class. + */ +class NodeRelaxer { +public: + /// Default constructor. + NodeRelaxer() { } + + /// Destroy. + virtual ~NodeRelaxer() { } + + /**Create the root node. Prune is true if then node can be pruned. + Also returns a vector of modifications that can be applied to the + root node. This is used if "strong" (LP-based) bounds tightening is + done. + */ + virtual RelaxationPtr createRootRelaxation(NodePtr rootNode, + bool &prune) = 0; + + /** + * Set the brancher that will be used with this node processor. dived + * is true if this node is processed right after its parent. prune is + * true if the node was found to be infeasible after creating the + * relaxation. + */ + virtual RelaxationPtr createNodeRelaxation(NodePtr node, bool dived, + bool &prune) = 0; + + /** + * After processing the node, some node relaxers may like to make + * changes. This function is the place to do it. diving is true if the + * next node to be processed is a child node of the current node. + */ + virtual void reset(NodePtr node, bool diving) = 0; + + /** + * Return a pointer to the last relaxation that was created by this + * relaxer. + */ + virtual RelaxationPtr getRelaxation() = 0; +}; + +typedef boost::shared_ptr NodeRelaxerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NodeStack.h b/thirdparty/linux/include/minotaur/NodeStack.h new file mode 100644 index 0000000..a77174f --- /dev/null +++ b/thirdparty/linux/include/minotaur/NodeStack.h @@ -0,0 +1,94 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file NodeStack.h + * \brief Define the class NodeStack for storing active nodes of the + * branch-and-bound tree on a stack data structure. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURNODESTACK_H +#define MINOTAURNODESTACK_H + +#include "ActiveNodeStore.h" + +namespace Minotaur { + + typedef std::deque NodePtrStack; + typedef NodePtrStack::iterator NodeStackIter; + typedef NodePtrStack::const_iterator NodeStackConstIter; + + /** + * When the active nodes of the branch-and-bound tree are explored in a + * last-in-first-out (LIFO) order, we store them in a stack. This is + * essentially a depth first search. + */ + class NodeStack : public ActiveNodeStore { + + public: + /// Constructor + NodeStack(); + + /// Destroy + virtual ~NodeStack(); + + /** + * \brief Return true if there are no active nodes in the heap, + * otherwise return false. + */ + virtual bool isEmpty() const; + + /** + * \brief Find the minimum lower bound of all the active nodes in the + * stack. This function is expensive and must be avoided for large + * trees. + */ + virtual double getBestLB() const; + + /// The maximum depth is the depth of the topmost node in the stack. + virtual UInt getDeepestLevel() const; + + /// Remove the best node from the heap. + virtual void pop(); + + /// Write in order the node ID and the depth of each active node. + virtual void write(std::ostream &out) const; + + /// Add a node to the set of active nodes. + virtual void push(NodePtr n); + + /// Get access to the best node in this heap. + virtual NodePtr top() const { return (nodes_.front()); } + + /// Get the number of active nodes in the heap. + virtual UInt getSize() const { return (nodes_.size()); } + + /// Get iterator to the first node in the heap. + NodeStackIter nodesBegin(); + + /// Get iterator to the last node in the heap. + NodeStackIter nodesEnd(); + + private: + /// stack of active nodes. + NodePtrStack nodes_; + }; + typedef boost::shared_ptr NodeStackPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/NonlinearFunction.h b/thirdparty/linux/include/minotaur/NonlinearFunction.h new file mode 100644 index 0000000..3275b57 --- /dev/null +++ b/thirdparty/linux/include/minotaur/NonlinearFunction.h @@ -0,0 +1,292 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file NonlinearFunction.h + * \brief Declare abstract base class NonlinearFunction. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURNONLINEARFUNCTION_H +#define MINOTAURNONLINEARFUNCTION_H + +#include "Types.h" + +namespace Minotaur { + + struct LTHessStor; + class NonlinearFunction; + class VarBoundMod; + typedef boost::shared_ptr NonlinearFunctionPtr; + typedef boost::shared_ptr VarBoundModPtr; + typedef std::vector VarBoundModVector; + typedef VarBoundModVector::iterator VarBoundModIter; + + /** + * \brief Base class for nonlinear functions. + */ + class NonlinearFunction { + + public: + /// Default constructor + NonlinearFunction(); + + /// Destroy. + virtual ~NonlinearFunction(); + + /** + * \brief Add a constant to the function + * + * Add a constant to the given nonlinear function. Adding a constant + * alone usually does not make sense. However, it is useful as a + * intermediate step. For instance, in writing the perspective: + * z*f(x/(z+e)) + * \param [in] d The value of the constant. + * \param [out] err must be nonzero if the constant could not be added. + */ + virtual void addConst(const double d, int &err); + + /** + * \brief Change the nonlinear function to its square-root. + * + * \param [out] err must be nonzero if the operation is unsuccessful + */ + virtual void sqrRoot(int &err); + + /** + * \brief Make a clone using new variables. + * + * \param [in] vbeg it points to the variable id 0. vbeg+k points to + * variable id k, where k>=0. + * \param [out] err must be nonzero if function wasn't cloned. + */ + virtual NonlinearFunctionPtr cloneWithVars(VariableConstIterator vbeg, + int *err) const = 0; + + /** + * \brief Calculate upper and lower bounds on the function using bounds of + * the variables. + * \param [out] lb Pointer that will contain the value of lower bound. + * \param [out] ub Pointer that will contain the value of upper bound. + * \param [out] error 0 if no error is encountered, nonzero otherwise. + */ + virtual void computeBounds(double *lb, double *ub, int *error); + + /** + * \brief Evaluate the function at a given point x. + * + * \param [in] x The size of the array x must exceed the highest index of the + * variables used in the function. + * \param [out] *error It should be set a positive value if there is + * error encountered while evaluating. Leave undisturbed otherwise. + * \return The value of function of x. + */ + virtual double eval(const double *x, int *error) = 0; + + /** + * \brief Evaluate and add gradient at a given point. + * + * \param [in] x The size of the array x must exceed the highest index of the + * variables used in the function. + * \param [out] grad_f The values of grad_f are incremented with the + * gradient of this function at x. The array grad_f is dense. + * \param [out] error It should be set a positive value if there is + * error encountered while evaluating. Leave undisturbed otherwise. + */ + virtual void evalGradient(const double *x, double *grad_f, int *error) + = 0; + + /** + * \brief Evaluate and add hessian at a given point. + * + * \param [in] mult Multiplier for this objective/constraint function + * \param [in] x The point where we need the hessian. + * \param [in] stor The Hessian storage information. + * \param [out] values The Hessian values to which we add Hessian of + * this function. + * \param [out] error We set it to nonzero if any errors are encountered. Do + * not change it otherwise. + */ + virtual void evalHessian(const double mult, const double *x, + const LTHessStor *stor, double *values, + int *error) = 0; + + /** + * \brief Fill sparsity of hessian into hessian storage. + * + * \param [in,out] stor We add variables into stor->cols + */ + virtual void fillHessStor(LTHessStor *stor ) = 0; + + /** + * \brief Evaluate and add gradient at a given point to the jacobian. + * + * \param [in] x The size of the array x must exceed the highest index of the + * variables used in the function. + * \param [out] values The values of jacobian are incremented with the + * gradient of this function at x. 'values' only contains nonzeros of + * jacobian. The indices (or offsets) where this nonlinear function + * should put in the values should be calculated in the prepJac + * function. + * \param [out] error It should be set a zero value if there is + * error encountered while evaluating. Leave undisturbed otherwise. + */ + virtual void fillJac(const double *x, double *values, int *error) = 0; + + /** + * \brief Finalize hessian preparation. + * + * \param [in] stor contains the sparsity pattern of hessian of + * lagrangian. The nonlinear function should save offsets or make + * other preparation to evaluate hessian. + */ + virtual void finalHessStor(const LTHessStor *stor) = 0; + + /** + * \brief If a variable is fixed at a given value and removed, what is + * the constant (offset) needed to be added. + * + * param [in] v The variable that is fixed.
    + * param [in] val The value at which v is to be fixed.
    + * \return Return the value of the offset. + */ + virtual double getFixVarOffset(VariablePtr /* v */, double /* val */) + {assert (!"implment me!"); return 0;}; + + /// Return the type of function: polynomial, ... + virtual FunctionType getType() const; + + /** + * \brief Get variables used in this function + * + * \param [in] vars A set of variable-pointers into which variables are + * to be inserted. + */ + virtual void getVars(VariableSet *vars) = 0; + + /** + * \brief Check if function contains a variable. + * + * \param [in] v The variable that we want to test. + * \return True if this function is has v. False if it doesn't use it. + */ + virtual bool hasVar(ConstVariablePtr v) const; + + /** + * \brief Check if the function is a sum of square terms + * + * \return True if this function is a sum of squares, False otherwise + */ + virtual bool isSumOfSquares() const { + return true; + } + + /** + * \brief Multiply by a constant. + * + * \param [in] c double value with which we want to multiply. + */ + virtual void multiply(double c) = 0; + + /// Return the number of variables in this function. + virtual UInt numVars() { return vars_.size(); }; + + /** + * \brief Prepare for evaluating sparse jacobian. + * + * All the variables that are in this function can occur in one or more + * of linear, quadratic and nonlinear functions. All variables that + * occur in the whole function can be accessed by iterating between vbeg + * and vend. This function is used to find the offset for variables that + * occur in the nonlinear function. + */ + virtual void prepJac(VarSetConstIter vbeg, VarSetConstIter vend) = 0; + + /// Remove a variable v from the function after fixing it to value val. + virtual void removeVar(VariablePtr /* v */, double /* val */) + {assert (!"implement me!");}; + + /// Substitute a variable with another. + virtual void subst(VariablePtr /* out */, VariablePtr /* in */, + double /* rat */) + {assert (!"implement me!");}; + + /** + * \brief Take perspective of this function with respect to a given variable. + * + * Perspective of a given function f(x) with respect to a given variable z + * is g(x,z) = z.f(x/z) + * \param [in] z The variable for which you take the perspective + * \param [in] eps The tolerance to tackle function value at 0 value. If + * the perspective is approximated in the computational graph, the epsilon + * is added to the z variable. If the perspective uses exact graph, then + * an approximation in Hessian is used when z < eps. + * \param [out] err must be nonzero if function wasn't cloned. + * \return A new nonlinear function with an additional variable that gives + * the perspective of this function + */ + virtual NonlinearFunctionPtr getPersp(VariablePtr z, double eps, + int *err) const; + + /** + * \brief Tighten variables based on function bounds + * + * Given a lower and upper bound on the allowed values of the function, + * deduce bounds of variables and return the modifications in bounds. The + * modifications are not applied to the variables. + * + * param [in] lb A lower bound on function values
    + * param [in] ub An upper bound on function values
    + * param [out] mods A vector of modifications deduced by bound + * propagation/tightening
    + * param [out] status Tells whether there was an error in executing this + * routine or if the problem is infeasible etc. + */ + virtual void varBoundMods(double /* lb */, double /* ub */, + VarBoundModVector & /* mods */, + SolveStatus * /* status */) + {}; + + /** + * \brief First iterator for variables + * + * \return first iterator for the variables in this function. + */ + virtual VariableSet::iterator varsBegin() + {return vars_.begin();}; + + /** + * \brief Last iterator for variables + * + * \return last iterator for the variables in this function. + */ + virtual VariableSet::iterator varsEnd() + {return vars_.end();}; + + /// Display the nonlinear function. + virtual void write(std::ostream &out) const; + + protected: + /// A set of variables used in this function. + VariableSet vars_; + }; + + typedef boost::shared_ptr NonlinearFunctionPtr; + typedef boost::shared_ptr ConstNonlinearFunctionPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Objective.h b/thirdparty/linux/include/minotaur/Objective.h new file mode 100644 index 0000000..eb53e98 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Objective.h @@ -0,0 +1,214 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Objective.h + * \brief Declare the Objective class for storing and manipulating objective + * function. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef OBJECTIVE_H +#define OBJECTIVE_H + +#include + +#include "Types.h" + +namespace Minotaur { + + class Function; + class LinearFunction; + class QuadraticFunction; + class NonlinearFunction; + typedef boost::shared_ptr FunctionPtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr ConstLinearFunctionPtr; + typedef boost::shared_ptr NonlinearFunctionPtr; + typedef boost::shared_ptr QuadraticFunctionPtr; + typedef std::set >::const_iterator + VariableFunIterator; + /** + * The Objective class is meant to implement an objective function for the + * problem (or formulation). There are only a few differences between + * Objective and Constraint. The Objective has a sense (Maximize or + * Minimize) associated with it. The objective may also have a constant + * term. Like a constraint, an objective has a function and lower and upper + * bounds. These bounds are optional. An objective must have the ability to + * be evaluated at a given point, and also to return its gradient at a given + * point. + * + * Minotaur will always minimize an objective internally. So if the + * objective is to maximize, it will try to minimize the negative. + */ + class Objective + { + public: + /// Only Problem class can modify an Objective. All modification methods + /// are private. + friend class Problem; + + /// Default constructor + Objective(); + + /** + * Create an objective with a specific id, constant term and sense. Does + * not need a function. A default name is created. + */ + Objective(double cb = 0.0, ObjectiveType otyp = Minimize); + + /* + * Create an objective with a specific function, id, constant term and + * sense. A default name is created. + */ + Objective(FunctionPtr fPtr, double cb = 0.0, + ObjectiveType otyp = Minimize); + + /** + * Create an objective with a specific function, id, constant term, + * sense and a name. + */ + Objective(FunctionPtr fPtr, double cb, ObjectiveType otyp, + std::string name); + + /// Destroy + virtual ~Objective() { } + + + // Functions that query or get information. + + /// Return the constant term in this objective. + double getConstant() const { return cb_; } + + /// Return the type (Maximize or Minimize) of this objective. + ObjectiveType getObjectiveType() const; + + /// Return the type of the function in objective. + FunctionType getFunctionType() const; + + /// Return the state of the objective. Fixed, removed, freed etc. + ObjState getState() const { return state_; } + + /* + * Return the name of this objective. If the user did not create a name + * for the objective, it is generated automatically + */ + virtual const std::string getName() const; + + /// Return the function in the objective + const FunctionPtr getFunction() const { + return f_; + } + + /** + * Return the linear function part of the objective function. Could be + * NULL. + */ + const LinearFunctionPtr getLinearFunction() const; + + /** + * Return the quadratic function part of the objective function. Could be + * NULL. + */ + const QuadraticFunctionPtr getQuadraticFunction() const; + + /** + * Return the nonlinear function part of the objective function. Could be + * NULL. + */ + const NonlinearFunctionPtr getNonlinearFunction() const; + + /// Print the objective function to the output stream. + void write(std::ostream &out) const; + + /** + * Evaluate the objective function (along with the constant term) at the + * given point x. + */ + double eval(const double *x, int *err) const; + + /** + * Evaluate the gradient at the given point x and fill in the gradient + * values in the array grad_f. The array grad_f is assumed to have the + * required size (equal to number of variables in the problem). + */ + void evalGradient(const double *x, double *grad_f, int *error); + + /** + * Evaluate the gradient at the given point and fill in the gradient + * values in the array grad_f. The array grad_f is assumed to have the + * required size (equal to number of variables in the problem). + * \todo XXX: replace this function by the one below. + */ + void evalGradient(VariableGroup &point, double *grad_f); + + // Functions that modify or change the objective. + + private: + /** + * Constant term in the objective. When the objective is evaluated at a + * certain point, this term is included. + */ + double cb_; + + /// Maximize or Minimize. + ObjectiveType otyp_; + + /// The state of the function in the objective. Freed, fixed etc. + ObjState state_; + + /// The function in the objective. Could be NULL. + FunctionPtr f_; + + /** + * The name of this objective. The user can set or change this. The + * default name is derived from the id. + */ + std::string name_; + + void delFixedVar_(VariablePtr v, double val); + + /// Set the state of the objective. + void setState_(ObjState state) { state_ = state; return; } + + /** + * Take the sum of the existing linear function in the objective and + * lPtr and set this new function as the linear function of objective. + * Quadratic and other nonlinear parts are unaffected. lPtr is also + * unaffected. + */ + void add_(ConstLinearFunctionPtr lPtr); + + /// Add a constant to the objective function. + void add_(double cb); + + /// Remove the quadratic part of the function and return a pointer to it. + QuadraticFunctionPtr removeQuadratic_(); + + void subst_(VariablePtr out, VariablePtr in, double rat=1.0); + + /** + * Change the sense of objective and also multiply by (-1). Instead of + * max f(x), the objective is now min -f(x). + */ + void negate_(); + }; + + typedef boost::shared_ptr ObjectivePtr; + typedef boost::shared_ptr ConstObjPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/OpCode.h b/thirdparty/linux/include/minotaur/OpCode.h new file mode 100644 index 0000000..e0d3130 --- /dev/null +++ b/thirdparty/linux/include/minotaur/OpCode.h @@ -0,0 +1,67 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file OpCode.h + * \brief Declare the OpCodes used in Minotaur. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAUROPCODE_H +#define MINOTAUROPCODE_H + +namespace Minotaur { +typedef enum { + OpAbs, + OpAcos, + OpAcosh, + OpAsin, + OpAsinh, + OpAtan, + OpAtanh, + OpCeil, + OpCos, + OpCosh, + OpCPow, // k^x where k is constant. + OpDiv, + OpExp, + OpFloor, + OpInt, + OpIntDiv, + OpLog, + OpLog10, + OpMinus, + OpMult, + OpNone, + OpNum, + OpPlus, + OpPow, // y^x + OpPowK, // x^k, where k is constant. + OpRound, + OpSin, + OpSinh, + OpSqr, // x^2, same as OP2POW in AMPL. + OpSqrt, + OpSumList, + OpTan, + OpTanh, + OpUMinus, + OpVar +} OpCode; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Operations.h b/thirdparty/linux/include/minotaur/Operations.h new file mode 100644 index 0000000..9e72121 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Operations.h @@ -0,0 +1,100 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Operations.h + * \brief Declare some commonly used functions. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef OPERATIONS_H +#define OPERATIONS_H + +#include "LinearFunction.h" + +namespace Minotaur { + bool IsInt(double v, double tol=1e-12); + + double InnerProduct(const VariableGroup &g1, const VariableGroup &g2); + + double InnerProduct(const std::vector &x, const VariableGroup &g2); + + /// Inner product of two arrays, x and a, each of size n. + double InnerProduct(const double *x, const double *a, int n); + + void symMatDotV(UInt nz, const double *mat, const UInt *irow, const UInt *jcol, + const double *v, double *prod); + + void BoundsOnDiv(double l0, double u0, double l1, double u1, + double &lb, double &ub); + + /// Get bounds on y, where \f$ y = x_0x_1 \f$. If zero_x_inf_zero is true, + /// then product of 0 and infinity is taken as zero. + void BoundsOnProduct(bool zero_x_inf_zero, ConstVariablePtr x0, + ConstVariablePtr x1, double &lb, double &ub); + + /// Get bounds on y, where \f$ y = x_0x_1 \f$. If zero_x_inf_zero is true, + /// then product of 0 and infinity is taken as zero. + void BoundsOnProduct(bool zero_x_inf_zero, double l0, double u0, double l1, + double u1, double &lb, double &ub); + + void BoundsOnRecip(double l0, double u0, double &lb, double &ub); + + /// Get lower and upper bounds on a square of variable. + void BoundsOnSquare(ConstVariablePtr x1, double &lb, double &ub); + + /** + * Get lower and upper bounds on a square of variable whose bounds are + * provided. + */ + void BoundsOnSquare(const double x_lb, const double y_lb, double &lb, + double &ub); + + /** + * Get gcd(d1, d2). Returns d2 if d1 is zero. Returns d1 if d2 is zero. + * Otherwise, returns largest x > 0 s.t. d1/x and d2/x are integers. + * e.g. Gcd(10.5, 7.0) = 3.5. If d1 is zero, returns abs(d2), if d2 is zero, + * returns abs(d1). + */ + double Gcd(double d1, double d2, const double &etol = 1e-9); + + /** + * Get distance(a,b,n). Returns the Euclidian distance between point a and point b which + * in n-dimensional space. + */ + double getDistance(const double* Pointa, const double* Pointb, UInt n); + + /** + * Get minArray. Returns the minimum element of a dynamic array. + */ + double minArray(const double* A, UInt n); + + /// To display the initial point. + void displayArray(const double* point, UInt n, std::ostream &out); + + /// Sort a vector of variables according to values of x. + void sort(VarVector &vvec, double *x, bool ascend=true); + void sortRec(VarVector &vvec, double *x, int left, int right, int pivotind); + + /// Convert a string to lower case. + void toLowerCase(std::string &str); + + /// Convert a double representing seconds into wall clock time HH:MM:SS:mm + std::string toClockTime(double t); +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Option.h b/thirdparty/linux/include/minotaur/Option.h new file mode 100644 index 0000000..f7e5d48 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Option.h @@ -0,0 +1,248 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Option.h + * \brief Declare the Option class for managing options for Minotaur. + * \author Todd Munson, Argonne National Laboratory + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAUR_OPTIONS +#define MINOTAUR_OPTIONS + +#include + +#include "Types.h" + +namespace Minotaur { + /** + * Options are used to control the behavior of Minotaur: choice of + * algorithms, parameters, limits, outputs etc. They are also used to + * control the behavior of interfaces and engines that are linked with + * Minotaur: parameters for LP engine, verbosity, limits etc. This templated + * class works for any option whose value could be integer, double or string. + * + * All options in Minotaur must be one of the above three types. In the + * command line, all option names must be entered with a preceding '--'. + * e.g. + * ./minotaur --assume_convex yes --node_limit=2 --time_limit 100 + * + * Either form '--option_name=option_value' or '--option_name option value' + * is acceptable. + * + * Any simple options without values, like for instance '-v', '-q' are + * not allowed, but they can still be accepted if they are aliased to a + * minotaur acceptable option. In such cases, we need to tell Minotaur, how + * to expand small options like '-=', '-v', '-AMPL' into a proper Minotaur + * option. ... more to be added here. + * + * Interfaces to Minotaur, like AMPL, can also add their own options to the + * Minotaur option-database. + * + * Again, we assume that all options that begin with '--' have a value + * associated with it. We also assume that all options that begin with '-' + * do not have any value associated with it. So, for the command, + * ./minotaur -v 2 --assume_convex yes stub.nl + * we will assume that '2' is the name of input file, 'yes' is the value of + * option 'assume_convex' and stub.nl is also an input file. + */ + template class Option { + public: + /// Construct the option using name, description and value. + Option(const std::string& name, const std::string& desc, + bool is_known=false, T val=0); + + /// Destroy. + virtual ~Option(); + + /// Set the value of this option. + virtual void setValue(T val) { val_ = val; return; }; + + /// Get the value of option. + virtual T getValue() { return val_; }; + + /// Get the name of this option. + virtual const std::string & getName(); + + /// Get the help description of this option. + virtual const std::string & getDesc(); + + /// Check if this option was used somewhere. + virtual bool wasEverUsed() {return everUsed_;}; + + /// Set the 'used' flag. Used flag is true if + virtual void setUsedFlag(const bool &used_flag) {everUsed_ = used_flag;}; + + /// Return true if the option is known to Minotaur. + virtual bool isKnown() {return isKnown_;}; + + /// Set or unset the 'known' flag + virtual void setKnownFlag(const bool &known_flag) + {isKnown_ = known_flag;}; + + /// Write to the output stream. + virtual void write(std::ostream &out) const; + + protected: + /** + * The name of the option should not have any spaces. All spaces should + * be converted to underscore (_). If the name consists of a period (.), + * then the option is meant for the external library referred to by the + * name before the period. For instance the name: + * ipopt.some_tolerance + * tells us to provide Ipopt with the option "some_tolerance". Again, + * spaces are not allowed even if the external library has spaces in the + * name. + */ + std::string name_; + + /** + * A human-readable description of what the option does and what limits + * are expected. + */ + std::string desc_; + + /** + * The value of the option. For now, we don't check if the user + * specified options lie in the suggested limits. + */ + T val_; + + /** + * True, if this option was ever used by any of the procedures. False + * otherwise. + */ + bool everUsed_; + + /// True, if the option is known to minotaur. + bool isKnown_; + + private: + /// Copying is not allowed. + Option (const Option &o); + + /// Copy by assignment is not allowed. + Option & operator = (const Option &o); + }; + + + /** + * OptionDB is a class to store a set of options. One use of this class + * is to save the user specified options. + * The user may specify options using the command line arguments, or through + * the API. Further, some of the options may be invalid (with typos). This + * class can tell if the options specified by the user are legitimate + * options. + */ + class OptionDB { + public: + /// Default constructor. + OptionDB(); + + /// Destroy. + ~OptionDB(); + + /// Add a bool option to the database. + void insert(BoolOptionPtr option, bool is_flag=false); + + /// Add an int option to the database. + void insert(IntOptionPtr option); + + /// Add a double option to the database. + void insert(DoubleOptionPtr option); + + /// Add a string option to the database. + void insert(StringOptionPtr option); + + /// Find a bool option in the database. + BoolOptionPtr findBool(const std::string &name); + + /// Find an int option in the database. + IntOptionPtr findInt(const std::string &name); + + /// Find a double option in the database. + DoubleOptionPtr findDouble(const std::string &name); + + /// Find a string option in the database. + StringOptionPtr findString(const std::string &name); + + /// Find a flag option in the database. + FlagOptionPtr findFlag(const std::string &name); + + /** + * Remove from the database all options that have the provided name. + * Return the number of options that were removed. + */ + UInt remove(const std::string &name); + + /// Iterator to access the first bool option. + BoolOptionSetIter boolBegin(); + + /// Iterator to access the last bool option. + BoolOptionSetIter boolEnd(); + + /// Iterator to access the first integer option. + IntOptionSetIter intBegin(); + + /// Iterator to access the last integer option. + IntOptionSetIter intEnd(); + + /// Iterator to access the first double option. + DoubleOptionSetIter dblBegin(); + + /// Iterator to access the last double option. + DoubleOptionSetIter dblEnd(); + + /// Iterator to access the first string option. + StringOptionSetIter strBegin(); + + /// Iterator to access the last string option. + StringOptionSetIter strEnd(); + + /// Iterator to access the first flag. + FlagOptionSetIter flagBegin(); + + /// Iterator to access the last flag. + FlagOptionSetIter flagEnd(); + + /** + * Write the database to the output stream. It will print the option + * name, the value and if it was ever used. + */ + void write(std::ostream &out) const; + + private: + /// Set of all boolean options. + BoolOptionSet bool_ops_; + + /// Set of all integer options. + IntOptionSet int_ops_; + + /// Set of all double options. + DoubleOptionSet double_ops_; + + /// Set of all string options. + StringOptionSet string_ops_; + + /// Set of all flags (options that don't need any arguments). + FlagOptionSet flag_ops_; + }; + typedef boost::shared_ptr OptionDBPtr; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/OsiLPEngine.h b/thirdparty/linux/include/minotaur/OsiLPEngine.h new file mode 100644 index 0000000..c4c71cb --- /dev/null +++ b/thirdparty/linux/include/minotaur/OsiLPEngine.h @@ -0,0 +1,272 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file OsiLPEngine.h + * \brief Define an interface to the OSI-LP solver. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAUROSILPENGINE_H +#define MINOTAUROSILPENGINE_H + +#include "LPEngine.h" +#include "WarmStart.h" + +class CoinWarmStart; +class OsiSolverInterface; + + +namespace Minotaur { + + class Timer; + class Environment; + class Problem; + class Solution; + class WarmStart; + typedef boost::shared_ptr EnvPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr SolutionPtr; + typedef boost::shared_ptr WarmStartPtr; + + /// Statistics + struct OsiLPStats { + UInt calls; /// Total number of calls to solve. + UInt strCalls; /// Calls to solve while strong branching. + double time; /// Sum of time taken in all calls to solve. + double strTime; /// time taken in strong branching alone. + UInt iters; /// Sum of number of iterations in all calls. + UInt strIters; /// Number of iterations in strong branching alone. + }; + + typedef enum { + OsiClpEngine, + OsiCpxEngine, + OsiGlpkEngine, + OsiGrbEngine, + OsiMskEngine, + OsiSpxEngine, + OsiXprEngine, + OsiUndefEngine + } OsiLPEngineName; + + /// Actual implementation of warm start for OsiLP Engine. + class OsiLPWarmStart : public WarmStart { + public: + + friend class Problem; + + /// Default constructor. + OsiLPWarmStart(); + + /// Destroy. + ~OsiLPWarmStart(); + + /// Get the warm-start description. + CoinWarmStart * getCoinWarmStart() const; + + // Implement Engine::hasInfo(). + bool hasInfo(); + + /** + * Save the given coin-warm start. If must_delete is true, it is our + * responsibility to free it. + */ + void setCoinWarmStart(CoinWarmStart *coin_ws, bool must_delete); + + // Implement Engine::write(). + void write(std::ostream &out) const; + + private: + /** + * COIN provides the warm start basis. For now, we don't need our own + * data structures. + */ + CoinWarmStart *coinWs_; + + /** + * If true, we must delete the warm-start description. If it is false, + * we should never delete it. + */ + bool mustDelete_; + + }; + typedef boost::shared_ptrOsiLPWarmStartPtr; + typedef boost::shared_ptrConstOsiLPWarmStartPtr; + + + /// The OsiLPEngine engine uses the OSI interface to CLP solver. + class OsiLPEngine : public LPEngine { + public: + /// Default constructor. + OsiLPEngine(); + + /// Constructor with an environment. + OsiLPEngine(EnvPtr env); + + /// Destroy. + ~OsiLPEngine(); + + // Implement Engine::addConstraint(). + void addConstraint(ConstraintPtr); + + // Change bounds on a constraint. + void changeBound(ConstraintPtr cons, BoundType lu, double new_val); + + // Implement Engine::changeBound(VariablePtr, BoundType, double). + void changeBound(VariablePtr var, BoundType lu, double new_val); + + // Implement Engine::changeBound(VariablePtr, double, double). + void changeBound(VariablePtr var, double new_lb, double new_ub); + + // Implement Engine::changeConstraint(). + void changeConstraint(ConstraintPtr con, LinearFunctionPtr lf, + double lb, double ub); + + // Implement Engine::changeConstraint(). + void changeConstraint(ConstraintPtr c, NonlinearFunctionPtr nlf); + + // change the objective function. + void changeObj(FunctionPtr f, double cb); + + /// Clear the problem. + void clear(); + + // Implement Engine::disableStrBrSetup() + void disableStrBrSetup(); + + /// Return an empty OsiLPEngine pointer. + EnginePtr emptyCopy(); + + // Implement Engine::enableStrBrSetup() + void enableStrBrSetup(); + + /// Return the solution value of the objective after solving the LP. + double getSolutionValue(); + + // Implement Engine::getSolution(). + ConstSolutionPtr getSolution(); + + // Implement Engine::getStatus(). + EngineStatus getStatus(); + + /** + * Return the number of iterations it took to solve the last problem. + */ + int getIterationCount(); + + // get name. + std::string getName() const; + + /// Return the osilp interface. For hacks. + OsiSolverInterface * getSolver(); + + // Implement Engine::getWarmStart(). + // See OsiLPSolver.hpp to see Osi's description of warm-start pointer. + // It differs from solver to solver. We just return NULL for now. + ConstWarmStartPtr getWarmStart() + {assert(!"not implemented!"); return WarmStartPtr();}; + + // Implement Engine::getWarmStartCopy(). + WarmStartPtr getWarmStartCopy(); + + /** + * Load the problem into the engine. We create arrays of variables and + * constraints, the A matrix, rhs, objective etc from the problem and + * initialize the LP solver. + */ + void load(ProblemPtr problem); + + // Implement Engine::loadFromWarmStart(). + void loadFromWarmStart(const WarmStartPtr ws); + + // Convert 'min f' to 'min -f'. + void negateObj(); + + // base class method. + void removeCons(std::vector &delcons); + + // Implement Engine::resetIterationLimit(). + void resetIterationLimit(); + + // Implement Engine::setIterationLimit(). + void setIterationLimit(int limit); + + /** + * Solve the problem that was loaded. Calls resolve() function of Osi. + * The resolve() function ``smartly'' decides what method of clp should + * be called. + */ + EngineStatus solve(); + + /// Writes an LP file of the loaded LP. + void writeLP(const char *filename) const; + + /// Write statistics. + void writeStats(std::ostream &out) const; + + private: + /// True if any bound on variable on constraint was changed after + /// previous solve. + bool bndChanged_; + + /// True if a constraint (not it bound) was changed after previous solve. + bool consChanged_; + + /// Environment. + EnvPtr env_; + + /// Name of the engine: OsiCpx, OsiClp etc. + OsiLPEngineName eName_; + + /// The maximum limit that can be set on Osi solver. + int maxIterLimit_; + + /// String name used in log messages. + static const std::string me_; + + /// True if objective was changed after previous solve. + bool objChanged_; + + /** + * Pointer to the OSI solver interface that will actually be called to + * solve the instance. + */ + OsiSolverInterface *osilp_; + + /// Problem that is loaded, if any. + ProblemPtr problem_; + + /// Solution. + SolutionPtr sol_; + + /// Statistics. + OsiLPStats *stats_; + + /// True if strong-branching. + bool strBr_; + + /// Timer for OsiLP solves. Includes time spent in strong branching. + Timer *timer_; + + // Create a new solver (cplex, or clp or ..) + OsiSolverInterface *newSolver_(OsiLPEngineName ename); + }; + + typedef boost::shared_ptr OsiLPEnginePtr; +} + +#endif +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PCBProcessor.h b/thirdparty/linux/include/minotaur/PCBProcessor.h new file mode 100644 index 0000000..088d773 --- /dev/null +++ b/thirdparty/linux/include/minotaur/PCBProcessor.h @@ -0,0 +1,193 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file PCBProcessor.h + * \brief Define the derived class of NodeProcessor that solves LP + * relaxations. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURPCBPROCESSOR_H +#define MINOTAURPCBPROCESSOR_H + +#include "NodeProcessor.h" + +namespace Minotaur { + + class CutManager; + class Problem; + typedef boost::shared_ptr ConstProblemPtr; + + struct NodeStats { + UInt bra; /// Number of times relaxation became infeasible + UInt inf; /// Number of times relaxation became infeasible + UInt opt; /// Number of times relaxation gave optimal feasible solution + UInt prob; /// Number of times problem ocurred in solving + UInt proc; /// Number of nodes processed + UInt ub; /// Number of nodes pruned because of bound + }; + + /** + * \brief Default node processor used in solver for now. + * + * PCBProcessor is a derived class of NodeProcessor. It is meant to solve LPs + * at each node. It is used in a simple MILP branch-and-bound. + * As a stop-gap measure, it is being used for MINLP branch-and-bound as + * well. + */ + class PCBProcessor : public NodeProcessor { + + public: + /// Default constructor + PCBProcessor() { } + + /// Constructor with a given engine. + PCBProcessor(EnvPtr env, EnginePtr engine, HandlerVector handlers_); + + /// Destroy + ~PCBProcessor(); + + // Add a heuristic. + void addHeur(HeurPtr h); + + // True if a new solution was found while processing this node. + bool foundNewSolution(); + + // Find branches that will be used to branch at this node. + Branches getBranches(); + + // Get warm-start information. + WarmStartPtr getWarmStart(); + + // Implement NodeProcessor::process(). + void process(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool); + + void setCutManager(CutManager* cutman); + + // write statistics. Base class method. + void writeStats(std::ostream &out) const; + + // write statistics. Base class method. + void writeStats() const; + + private: + /// Branches found by this processor for this node + Branches branches_; + + /** + * If true, we continue to search, if engine reports error. If false, + * we assume that the relaxation is infeasible when engine returns error. + */ + bool contOnErr_; + + /// The cut manager. + CutManager *cutMan_; + + /// If lb is greater than cutOff_, we can prune this node. + double cutOff_; + + /// Engine used to process the relaxation + EnginePtr engine_; + + /// Status of the engine + EngineStatus engineStatus_; + + /// Pointer to environment + EnvPtr env_; + + /// All the handlers that are used for this processor + HandlerVector handlers_; + + /// Heuristics that can be called at each node. + HeurVector heurs_; + + /// Log + LoggerPtr logger_; + + /// For logging. + static const std::string me_; + + /// How frequently should node-presolve be called? If 1, then call at + /// all nodes. If 0, then never. If 4, then every fourth node, etc. + int presFreq_; + + /// How many new solutions were found by the processor. + UInt numSolutions_; + + /// Absolute tolerance for pruning a node on basis of bounds. + double oATol_; + + /// Relative tolerance for pruning a node on basis of bounds. + double oRTol_; + + /// Pointer to original problem + ConstProblemPtr problem_; + + /// Relaxation that is processed by this processor. + RelaxationPtr relaxation_; + + /// Statistics + NodeStats stats_; + + /// Warm-start information for start processing the children + WarmStartPtr ws_; + + /** + * Check if the solution is feasible to the original problem. + * In case it is feasible, we can store the solution and update the + * upper bound. Additionally, if the solution is optimal for the + * current node, then the node can be pruned. + */ + virtual bool isFeasible_(NodePtr node, ConstSolutionPtr sol, + SolutionPoolPtr s_pool, bool &should_prune); + + /// Presolve a node. + virtual bool presolveNode_(NodePtr node, SolutionPoolPtr s_pool); + + /// Solve the relaxation. + virtual void solveRelaxation_(); + + /** + * Check if a node can be pruned either because the relaxation is + * infeasible or because the cost is too high. + */ + virtual bool shouldPrune_(NodePtr node, double solval, + SolutionPoolPtr s_pool); + + + /// Separate the given point from the node relaxation + /** + * Call each handler and generate cuts. Cuts could be local or global. + * Local cuts must be added to the node (not implemented yet). Global + * cuts must be added to a global pool (not implemented yet). Separation + * status is SepPrune if there is no further need to solve the + * subproblem. It is SepResolve if the relaxation needs to be resolved. + */ + void separate_(ConstSolutionPtr sol, NodePtr node, SolutionPoolPtr s_pool, + SeparationStatus *status); + + // Implement NodeProcessor::tightenBounds_() + virtual void tightenBounds_(); + + }; + + typedef boost::shared_ptr PCBProcessorPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/ParBndProcessor.h b/thirdparty/linux/include/minotaur/ParBndProcessor.h new file mode 100644 index 0000000..8f0566e --- /dev/null +++ b/thirdparty/linux/include/minotaur/ParBndProcessor.h @@ -0,0 +1,157 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file ParBndProcessor.h + * \brief Define simple node-processor for parallel branch-and-bound + * \author Prashant Palkar, IIT Bombay + */ + +#ifndef MINOTAURPARBNDPROCESSOR_H +#define MINOTAURPARBNDPROCESSOR_H + +#include "NodeProcessor.h" + +namespace Minotaur { + + class Engine; + class Problem; + class Solution; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ConstProblemPtr; + typedef boost::shared_ptr ConstSolutionPtr; + + struct ParBPStats { + UInt bra; /// Number of times relaxation became infeasible + UInt inf; /// Number of times relaxation became infeasible + UInt opt; /// Number of times relaxation gave optimal feasible solution + UInt prob; /// Number of times problem ocurred in solving + UInt proc; /// Number of nodes processed + UInt ub; /// Number of nodes pruned because of bound + }; + + /** + * \brief Simple node-processor for branch-and-bound. + * + * BndProcessor is a derived class of NodeProcessor. It is meant to solve + * relaxations at each node. It performs only pruning and branching in a + * node. Does not call any presolving, cutting, or heuristic search. + */ + class ParBndProcessor : public NodeProcessor { + + public: + /// Default constructor + ParBndProcessor(); + + /// Constructor with a given engine. + ParBndProcessor(EnvPtr env, EnginePtr engine, HandlerVector handlers_); + + /// Destroy + ~ParBndProcessor(); + + // True if a new solution was found while processing this node. + bool foundNewSolution(); + + // Find branches that will be used to branch at this node. + Branches getBranches(); + + // Get warm-start information. + WarmStartPtr getWarmStart(); + + // Implement NodeProcessor::process(). + void process(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool); + + /** \brief Process a node. + * + * \param [in] init is true if pseudocosts have been initialized + */ + void process(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool, bool init); + + // write statistics. Base class method. + void writeStats(std::ostream &out) const; + + // write statistics. Base class method. + void writeStats() const; + + protected: + + /// Branches found by this processor for this node + Branches branches_; + + /** + * If true, we continue to search, if engine reports error. If false, + * we assume that the relaxation is infeasible when engine returns error. + */ + bool contOnErr_; + + /// If lb is greater than cutOff_, we can prune this node. + double cutOff_; + + /// Engine used to process the relaxation + EnginePtr engine_; + + /// Status of the engine + EngineStatus engineStatus_; + + /// All the handlers that are used for this processor + HandlerVector handlers_; + + /// Log + LoggerPtr logger_; + + /// For logging. + static const std::string me_; + + /// How many new solutions were found by the processor. + UInt numSolutions_; + + /// Relaxation that is processed by this processor. + RelaxationPtr relaxation_; + + /// Statistics + ParBPStats stats_; + + /// Warm-start information for start processing the children + WarmStartPtr ws_; + + /** + * Check if the solution is feasible to the original problem. + * In case it is feasible, we can store the solution and update the + * upper bound. Additionally, if the solution is optimal for the + * current node, then the node can be pruned. + */ + virtual bool isFeasible_(NodePtr node, ConstSolutionPtr sol, + SolutionPoolPtr s_pool, bool &should_prune); + + /// Solve the relaxation. + virtual void solveRelaxation_(); + + /** + * Check if a node can be pruned either because the relaxation is + * infeasible or because the cost is too high. + */ + virtual bool shouldPrune_(NodePtr node, double solval, + SolutionPoolPtr s_pool); + + }; + + typedef boost::shared_ptr ParBndProcessorPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/ParBranchAndBound.h b/thirdparty/linux/include/minotaur/ParBranchAndBound.h new file mode 100644 index 0000000..6f60250 --- /dev/null +++ b/thirdparty/linux/include/minotaur/ParBranchAndBound.h @@ -0,0 +1,401 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file ParBranchAndBound.h + * \brief Declare the default branch-and-bound-algorithm. + * \author Prashant Palkar, IIT Bombay + */ + +#ifndef MINOTAURPARBRANCHANDBOUND_H +#define MINOTAURPARBRANCHANDBOUND_H + +#include "Types.h" +#include + +namespace Minotaur { + + struct ParBabOptions; + struct ParBabStats; + class Engine; + class NodeProcessor; + class NodeRelaxer; + class ParNodeIncRelaxer; + class ParBndProcessor; + class ParTreeManager; + class Problem; + class Solution; + class SolutionPool; + class WarmStart; + class Timer; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ParBabOptionsPtr; + typedef boost::shared_ptr NodeProcessorPtr; + typedef boost::shared_ptr NodeRelaxerPtr; + typedef boost::shared_ptr ParNodeIncRelaxerPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr ParBndProcessorPtr; + typedef boost::shared_ptr SolutionPtr; + typedef boost::shared_ptr SolutionPoolPtr; + typedef boost::shared_ptr ParTreeManagerPtr; + typedef boost::shared_ptr WarmStartPtr; + + /** + * \brief Implement a generic parallel branch-and-bound algorithm on a multicore cpu. + */ + class ParBranchAndBound { + + public: + /// Default constructor. + ParBranchAndBound(); + + /// Constructor for a given Problem and Environment. + ParBranchAndBound(EnvPtr env, ProblemPtr p); + + /// Destroy. + virtual ~ParBranchAndBound(); + + void printsomething(); + /** + * \brief Add a heuristic that will be called before root node. + * \param [in] h The heuristic that should be called. This heuristic will + * be called after all previously added heuristic. + */ + void addPreRootHeur(HeurPtr h); + + /** + * \brief Return the percentage gap between the lower and upper bounds. + * + * Gap percentage is calculated as + * \f$\frac{u - l}{\left|u\right|+\epsilon} \times 100\f$, where \f$u\f$ + * is the upper bound, \f$l\f$ is the lower bound and \f$\epsilon\f$ is a + * small constant to avoid division by zero. + */ + double getPerGap(); + + /** + * \brief Return the lower bound from the search tree. + * + * This bound is defined as the minimum of the bounds from all active + * nodes. It may not be a bound on the optimal solution value. + */ + double getLb(); + + /// Return a pointer to NodeProcessor used in branch-and-bound. + NodeProcessorPtr getNodeProcessor(); + + /// Return a pointer to NodeRelaxer used in branch-and-bound. + NodeRelaxerPtr getNodeRelaxer(); + + /* + * \brief Return solution from the last solve. If no solution was found, return + * NULL. + */ + SolutionPtr getSolution(); + + /// Return the final status. + SolveStatus getStatus(); + + /** + * \brief Return a pointer to the tree manager. The client can then + * directly query the ParTreeManager for its size and other attributes. + */ + ParTreeManagerPtr getTreeManager(); + + /** + * \brief Return the upper bound for the solution value from the search tree. + * + * This bound may or may not correspond to a feasible solution of the + * problem. It may be obtained from a feasible solution of a relaxation of + * the problem. + */ + double getUb(); + + /** + * \brief Map nodes generated in serial and parallel branch-and-bound tree. + * + * The logic assumes that a parent node gives rise to only two children + * and the one created using the left branch is assigned an id first. + * + * \param [in] serVec The vector of node descriptions in serial tree. + * \param [in] parVec The vector of node descriptions in parallel tree. + */ + std::vector > mapSerialOutput ( + std::vector >serVec, + std::vector >parVec); + + /// Return number of nodes processed while solving. + UInt numProcNodes(); + + /** + * \brief Set log level. + * + * \param [in] level The desired log level for this class. + */ + void setLogLevel(LogLevel level); + + /** + * \brief Set the NodeProcessor that processes each node. + * + * \param [in] p The desired node-processor. + */ + void setNodeProcessor(NodeProcessorPtr p); + + /** + * \brief Set the NodeRelaxer for setting-up relaxations at each node. + * + * \param [in] nr The desired node-relaxer. + */ + void setNodeRelaxer(NodeRelaxerPtr nr); + + /** + * \brief Switch to turn on/off root-node creation. + * + * Sometimes a client may set up a root node on its own and + * may not want the default root node. + * \param [in] b True if root node should be created, false otherwise. + */ + void shouldCreateRoot(bool b); + + /// Start solving the Problem using branch-and-bound + void solve(); + + /// Convert a string to integer data type + int strToInt(std::string str); + + /** + * \brief Start solving the Problem using branch-and-bound + * + * \param [in] parNodeRelaxer is the array of node relaxers. + * \param [in] parBndProcessor is the array of node processors. + * \param [in] nThreads is the number of threads being used. + */ + void parsolve(ParNodeIncRelaxerPtr parNodeRelaxer[], + ParBndProcessorPtr parBndProcessor[], + UInt nThreads); + + /// Print a two-dimensional vector (customized). + void print2dvec(std::vector > output); + + /// Print a two-dimensional vector (customized). + void print2dvec(std::vector > output); + + /** + * \brief Read output of branch-and-bound tree generated by a single thread. + * + * Each line of the input file must contain the following node information. + * NodeId ParentId BrVar Lb ThreadId StartTime EndTime TbScore PruneStatus TreeUb + * Only the first three columns are used for mapping, rest are for + * completeness of tree information. Root node information is not needed. + */ + std::vector > readSerialOutput(const char* inputFile); + + /// Return total time taken. + double totalTime(); + + /// Write statistics to the ostream out + void writeStats(std::ostream & out); + + /// Write statistics of parallel algorithm to the ostream out + void writeParStats(std::ostream & out, + ParBndProcessorPtr parBndProcessor[]); + + /// Write statistics to the logger + void writeStats(); + + /// Get wall clock time + double getWallTime() { + struct timeval time; + if (gettimeofday(&time,NULL)) { + // Handle error + return 0; + } + return (double)time.tv_sec + (double)time.tv_usec * .000001; + } + + private: + /// Pointer to the enviroment. + EnvPtr env_; + + /// Log manager for displaying messages. + LoggerPtr logger_; + + /// String name used in log messages. + static const std::string me_; + + /// The processor to process each node. + NodeProcessorPtr nodePrcssr_; + + /// The relaxer to create a relaxation at each node. + NodeRelaxerPtr nodeRlxr_; + + /// Options. + ParBabOptionsPtr options_; + + /** + * \brief Heuristics that need to be called before creating and solving the root + * node. + */ + HeurVector preHeurs_; + + /// The Problem that is solved using branch-and-bound. + ProblemPtr problem_; + + /// The TreeManager used to manage the search tree. + SolutionPoolPtr solPool_; + + /** + * \brief Statistics about the branch-and-bound (including time, number of + * iterations etc.) + */ + ParBabStats *stats_; + + /// The status of the branch-and-bound algorithm. + SolveStatus status_; + + /** + * \brief Timer for keeping track of time. + * + * The user or the environment from which branch-and-bound is called can + * set up the timer and even start it before sending it to + * branch-and-bound. + */ + Timer *timer_; + + /// The TreeManager used to manage the search tree. + ParTreeManagerPtr tm_; + + /** + * \brief Process the root node. + * + * \param [out] should_prune True if the root node can be pruned. + * \param [out] should_dive True if we should dive to a child node. + */ + NodePtr processRoot_(bool *should_prune, bool *should_dive); + + /** + * \brief Process the root node. + * + * \param [out] should_prune True if the root node can be pruned. + * \param [out] should_dive True if we should dive to a child node. + * \param [out] parNodeRlxr used to create relaxations of nodes. + * \param [out] nodePrcssr used to solve a node. + * \param [out] ws information to be used as warmstart for next node. + */ + NodePtr processRoot_(bool *should_prune, bool *should_dive, + ParNodeIncRelaxerPtr parNodeRlxr, + ParBndProcessorPtr nodePrcssr, WarmStartPtr ws); + + + /// Return True if a node can be pruned. + bool shouldPrune_(NodePtr node); + + /** + * \brief Check whether the branch-and-bound can stop because of time + * limit, or node limit or if solved? + */ + bool shouldStop_(); + + /** + * \brief Check whether the branch-and-bound can stop because of time + * limit, or node limit or if solved? + * + * \param [out] wallStartTime is the start time of branch-and-bound. + * \param [out] treeLb is the lower bound of the branch-and-bound tree. + */ + bool shouldStopPar_(double wallStartTime, double treeLb); + + /** + * \brief Display status: number of nodes, bounds, time etc. + * + * \param [in] current_uncounted If True, then the number of nodes in the + * log-message is incremented by one. This may happen when diving: the + * node being processed is not in the list of active nodes in the tree. + */ + void showStatus_(bool current_uncounted); + + /** + * \brief Display status: number of nodes, bounds, time etc. + * + * \param [in] current_uncounted If True, then the number of nodes in the + * log-message is incremented by one. This may happen when diving: the + * node being processed is not in the list of active nodes in the tree. + * + * \param [out] treeLb is the lower bound of the branch-and-bound tree. + * \param [out] wallStartTime is the start time of branch-and-bound. + */ + void showParStatus_(UInt current_uncounted, double treeLb, + double wallStartTime); + }; + + /// Statistics about the branch-and-bound. + struct ParBabStats + { + /// Constructor. All data is initialized to zero. + ParBabStats(); + + /// Number of nodes processed. + UInt nodesProc; + + /// Total time used in branch-and-bound. + double timeUsed; + + /// Time of the last log display. + double updateTime; + }; + + + /// Different options and parameters that control branch-and-bound + struct ParBabOptions + { + /// Default constructor. + ParBabOptions(); + + /// Constructor created from options in environment. + ParBabOptions(EnvPtr env); + + /** + * \brief Should the root be created in branch-and-bound (yes), or the + * user calls branch-and-bound after creating the root (no)? + */ + bool createRoot; + + /// Time in seconds between status updates of the progress. + double logInterval; + + /// Verbosity of log. + LogLevel logLevel; + + /// Limit on number of nodes processed. + UInt nodeLimit; + + /** + * \brief Stop if the percent gap between lower and upper bounds of the + * objective function falls below this level. + */ + double perGapLimit; + + /// Limit on number of nodes processed. + UInt solLimit; + + /// Time limit in seconds for the branch-and-bound. + double timeLimit; + }; + + typedef boost::shared_ptr ParBranchAndBoundPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/ParNodeIncRelaxer.h b/thirdparty/linux/include/minotaur/ParNodeIncRelaxer.h new file mode 100644 index 0000000..2729bd3 --- /dev/null +++ b/thirdparty/linux/include/minotaur/ParNodeIncRelaxer.h @@ -0,0 +1,114 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file ParNodeIncRelaxer.h + * \brief Declare the ParNodeIncRelaxer class. It creates relaxation by + * only incrementing changes made in ancestor nodes. All modifications to be + * applied while creating the relaxation are fist translated appropriately. + * \author Prashant Palkar, IIT Bombay + */ + + +#ifndef MINOTAURPARNODEINCRELAXER_H +#define MINOTAURPARNODEINCRELAXER_H + +#include "Handler.h" +#include "NodeRelaxer.h" + +namespace Minotaur { + +/** + * The root relaxation is stored as rel_. In each node, we apply all + * modifications stored in each ancestor of the node. When we are done + * processing the node, we undo all these changes. + * + * If we dive after processing a node, we do not need to undo all changes + * and apply them again. We just apply the modifications of the parent. + */ +class ParNodeIncRelaxer : public NodeRelaxer { +public: + /// Default constructor + ParNodeIncRelaxer(EnvPtr env, HandlerVector handlers); + + /// Destroy + ~ParNodeIncRelaxer(); + + // Implement NodeRelaxer::CreateRootRelaxation() + RelaxationPtr createRootRelaxation(NodePtr rootNode, bool &prune); + + // Implement NodeRelaxer::CreateNodeRelaxation() + RelaxationPtr createNodeRelaxation(NodePtr node, bool dived, bool &prune); + + /// Get the current value of modProb_ flag. + bool getModFlag(); + + // Implement NodeRelaxer::reset() + void reset(NodePtr node, bool diving); + + /** + * /brief Set the engine that is used to solve the relaxations. We need to set + * it in order to be able to load warm-starts at a node. + * + * \param[in] e Engine that will be modified whenever a new node is about to + * be processed. + */ + void setEngine(EnginePtr e); + + /** + * \brief If mod_prob is true, the problem will also be modified at each + * node. By default, only the relaxation is modified. + */ + void setModFlag(bool mod_prob); + + // get the relaxation pointer, rel_. + RelaxationPtr getRelaxation(); + + /// Set your own relaxation pointer. + void setRelaxation(RelaxationPtr rel); + + /// Set the problem pointer + void setProblem(ProblemPtr p); +private: + /// Pointer engine used to solve the relaxation. + EnginePtr engine_; + + /// Environment + EnvPtr env_; + + /// Vector of handlers that will make the relaxation. + HandlerVector handlers_; + + /** + * True if Problem is modified in each node, false if only relaxation is + * modified. + */ + bool modProb_; + + /// The problem being solved by branch-and-bound. + ProblemPtr p_; + + /** + * \brief We only keep one relaxation. It is modified at each node and then + * reset. + */ + RelaxationPtr rel_; +}; + +typedef boost::shared_ptr ParNodeIncRelaxerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/ParTreeManager.h b/thirdparty/linux/include/minotaur/ParTreeManager.h new file mode 100644 index 0000000..de51027 --- /dev/null +++ b/thirdparty/linux/include/minotaur/ParTreeManager.h @@ -0,0 +1,255 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file TreeManager.h + * \brief Declare class ParTreeManager for managing tree for parallel Branch-and-Bound. + * \author Prashant Palkar, IIT Bombay + */ + +#ifndef MINOTAURPARTREEMANAGER_H +#define MINOTAURPARTREEMANAGER_H + +#include +#include + +#include "Types.h" + +namespace Minotaur { + + class ActiveNodeStore; + class WarmStart; + typedef boost::shared_ptr ActiveNodeStorePtr; + typedef boost::shared_ptr WarmStartPtr; + + // 1=like_red, 2=blue, 4=red, 5=yellow, 6=black, 7=pink, 8=cyan, 9=green + // 11=orange, 12=green, 13=pink, 14=light blue + /// Colors for tree-visualization using vbc + typedef enum { + VbcActive = 4, /// Unsolved, open. + VbcFeas = 2, /// incumbent. + VbcInf = 11, /// infeasible. + VbcSolved = 9, /// solved. + VbcSolving = 8, /// currently being solved. + VbcSubInf = 13, /// subtree is infeasible. + VbcSubOpt = 6 /// suboptimal. + } VbcColors; + + + /// Base class for managing the branch-and-bound tree. + class ParTreeManager { + + public: + /// Constructor. + ParTreeManager(EnvPtr env); + + /// Destroy. + ~ParTreeManager(); + + /// Return true if any active nodes remain in the tree. False otherwise. + bool anyActiveNodesLeft(); + + /** + * \brief Branch and create new nodes. + * + * \param[in] branches The branching constraints or bounds or disjunctions + * that are used to create the new nodes after branching. + * \param[in] node The node that we wish to branch upon. + * \param[in] ws The warm starting information that should be linked to + * in the new nodes. + * \returns The first child node. + */ + NodePtr branch(Branches branches, NodePtr node, WarmStartPtr ws); + + /** + * \brief Return the number of active nodes, i.e. nodes that have been + * created, but not processed yet. + */ + UInt getActiveNodes() const; + + /// Return the cut off value. It is INFINITY if it is not set. + double getCutOff(); + + /** + * \brief Return the gap between the lower and upper bound as a + * percentage. It is calculated as + * \f$\frac{ub-lb}{\left|ub\right|+\epsilon}\times 100\f$. + */ + double getPerGap(); + + /** + * \brief Return the gap between the lower and upper bound as a + * percentage, given a lower bound, when executing in parallel mode. It is + * calculated as + * \f$\frac{ub-lb}{\left|ub\right|+\epsilon}\times 100\f$. + * \param[in] treeLb is the lower bound of the tree, considering active + * nodes and other open nodes that have not been sent to the node pool. + */ + double getPerGapPar(double treeLb); + + /** + * \brief Return the value of the highest lower bound evaluated in the + * last update of he bound. + * + * Since evaluating the lower bound may be expensive or certain types of + * tree-managers, it may be updated infrequently. Consquently, the value + * returned here may be lower than the actual lower bound of + * the tree. Also see updateLb(). + */ + double getLb(); + + /// Return the best known upper bound. + double getUb(); + + /** + * \brief Return the size of the tree, including both active and processed + * nodes. + */ + UInt getSize() const; + + /** + * \brief Search for the best candidate that can be processed next. + * + * It may prune some of the nodes if their lower bound is more than the + * upper bound. \return the best candidate found. If no candidate is + * found, it returns NULL. The candidate is not removed from the storage. + * It is removed only when removeActiveNode() is called. + */ + NodePtr getCandidate(); + + /** + * \brief Insert the root node into the tree. + * + * \param[in] node The root node. + */ + void insertRoot(NodePtr node); + + /** + * \brief Prune a given node from the tree + * + * \param[in] node The node that must be pruned. + */ + void pruneNode(NodePtr node); + + /** + * \brief Remove a given active node from storage. + * + * It should be called after the node has been processed. + * \param[in] node The node to be removed from storage. + */ + void removeActiveNode(NodePtr node); + + /** + * \brief Set the cut off value for the objective function. + * + * Nodes with lower bound \f$ lb \geq value-\epsilon\f$ can be pruned. + * \param[in] value The cut off value. It can be INFINITY. + */ + void setCutOff(double value); + + /** + * \brief Set the best known objective function value. + * + * The function does NOT check if the given value is better than the + * previous. So care should be taken to pass only the best known value. It + * also updates the cutoff value that is used to prune nodes. + * \param[in] value The best known upper bound. + */ + void setUb(double value); + + /// Return true if the tree-manager recommends diving. False otherwise. + bool shouldDive(); + + /** + * \brief Recalculate and return the lower bound of the tree. + * + * If the active nodes are stored + * in a heap, nothing really needs to be done. For other types of storage, + * this operation may be expensive. The result is cached into + * bestLowerBound_. + * \return the updated lower bound. + */ + double updateLb(); + + private: + /// Set of nodes that are still active (those who need to be processed). + ActiveNodeStorePtr active_nodes_; + + /// An active node that is not in the ActiveNodeStore. One such node may + /// exist. When we are diving. It must be deleted in the end. + NodePtr aNode_; + + /// \brief Best known lower bound based on the last update. + double bestLowerBound_; + + /// \brief Best known upper bound. + double bestUpperBound_; + + /// Delete all nodes, active and inactive. + void clearAll(); + + /// The cutoff value above which nodes are assumed infeasible. + double cutOff_; + + /// Whether we should store tree information for vbc. + bool doVbc_; + + /// Tolerance for pruning nodes on the basis of bounds. + const double etol_; + + /// The search order: depth first, best first or something else. + TreeSearchOrder searchType_; + + /** + * \brief Number of nodes that have been created so far, including the + * ones that were deleted. + */ + UInt size_; + + /// Timer is used only for vbc tree emulation. + Timer *timer_; + + /// Tie breaking rule (second priority) for node selection. + std::string tbRule_; + + /// File name to store tree information for vbc. + std::ofstream vbcFile_; + + /// Check if the node can be pruned because of its bound. + bool shouldPrune_(NodePtr node); + + /** + * \brief Insert a candidate (that is not root) into the tree. + * + * \param[in] node The node that is to be inserted. + * \param[in] pop_now True if ... + */ + void insertCandidate_(NodePtr node, bool pop_now = false); + + /** + * \brief Remove a node from the tree. + * + * \param[in] node The node that is to be removed. It may remove the + * parents of the current node also if they are no longer required. + */ + void removeNode_(NodePtr node); + }; + + typedef boost::shared_ptr ParTreeManagerPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PerspCon.h b/thirdparty/linux/include/minotaur/PerspCon.h new file mode 100644 index 0000000..5bda601 --- /dev/null +++ b/thirdparty/linux/include/minotaur/PerspCon.h @@ -0,0 +1,140 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// +/** + * \file PerspCon.h + * \Declare base class PerspCon. + * \author Meenarli Sharma, Indian Institute of Technology Bombay +*/ + +#ifndef MINOTAURPERSPCON_H +#define MINOTAURPERSPCON_H + +#include +#include +using std::ofstream; +#include +using std::string; + +#include "Problem.h" +#include "Relaxation.h" +#include "Constraint.h" +#include "Variable.h" +#include "Types.h" +#include "Environment.h" + +namespace Minotaur { + +class PerspCon; +typedef boost::shared_ptr PerspConPtr; +typedef boost::shared_ptr ConstPerspConPtr; + +/** + * This class identifies structure of type f(x,z) <= b, lz <= x <= uz, z={0,1} or + * f(x) <= b, lz <= x <= uz, z={0,1}, for perspective cut generation. + **/ + +class PerspCon { +public: + /// Default constructor. + PerspCon(); + + ///Constructs from the given problem + PerspCon(ProblemPtr p, EnvPtr env); + + /// Destructor. + ~PerspCon(); + + /// Checks if the variables are bounded by only one binary variable. + bool checkLVars(ConstConstraintPtr cons, ConstVariablePtr binvar); + + /// Checks if the variables of nonlinear part are bounded by only one binary variable. + bool checkNVars(const NonlinearFunctionPtr nlf, ConstVariablePtr binvar); + + /// Checks if a given variable is bounded by binary variable. + bool checkVarBounds(ConstVariablePtr var, ConstVariablePtr binvar); + + /// Checks if all the variables are continuous or at most one binary. + /// Otherwise, we cannot generate perspective cuts. + bool checkVarTypes(ConstConstraintPtr cons, ConstVariablePtr& binvar); + + /// Checks if a constraint is a Perspective constraint. + bool evalConstraint(ConstConstraintPtr cons,VariablePtr& binvar); + + /// Generate list of perspective constraints for the original problem. + void generateList(); + + /// Get a pointer to the vector that contains binary variable of perspective constraints. + std::vector getConsBinVar() const {return binVar_;} + + /// Get total number of perspective constraints. + UInt getNumPersp() const {return cList_.size();} + + /// Get a pointer to the vector that contains perspective constraints. + std::vector getPerspCons() const {return cList_;} + + /// Status of perspective reformulation + // 1 is PR is carried out, 0 otherwise + bool getStatus(); + + /// Find binary variables that appear in a linear constraint (involving two + // terms) with variable var + void initialBinary(ConstVariablePtr var, VarSetPtr binaries); + + /// Print out information related to the perspective constraints + void displayInfo(const std::string); + + private: + /// Environment. + EnvPtr env_; + + /// For log: + static const std::string me_; + + ///Pointer to original problem + ProblemPtr p_; + + ///Log + LoggerPtr logger_; + + ///Vector of perspective constraint pointers + std::vector cList_; + + //Vector of pointers to binary variables of perspective constraint + std::vector binVar_; + + ///Returns lower bounding constraints of continuous variables + std::vector > lbc_; + + ///Returns upper bounding constraints of continuous variables + std::vector > ubc_; + + std::vector l_; + std::vector u_; + +/* + // Uncomment to determine structure of the constraints amenable to PR + // Vector of structure info of constraints amenable to PR + std::vector sType_; + UInt s_; +*/ + +}; // end of class PerspCon. + + +} // end of namespace. + +#endif // MINOTAURPERSPCON_H + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PerspCutGenerator.h b/thirdparty/linux/include/minotaur/PerspCutGenerator.h new file mode 100644 index 0000000..6e8e416 --- /dev/null +++ b/thirdparty/linux/include/minotaur/PerspCutGenerator.h @@ -0,0 +1,231 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file PerspCutGenerator.h + * \Declare PerspCutGenerator class . + * \author Meenarli Sharma, Indian Institute of Technology Bombay + */ + +#ifndef MINOTAURPERSPCUTGENERATOR_H +#define MINOTAURPERSPCUTGENERATOR_H + +#include +#include +using std::ofstream; +#include +using std::string; + +#include "Types.h" +#include "Problem.h" +#include "Solution.h" +#include "Cut.h" +#include "Relaxation.h" +#include "Environment.h" +#include "PerspCon.h" +#include "Logger.h" + +namespace Minotaur { + + //typedef enum { + //Cons = 0 + //} PrintType; + + //typedef enum { + //Totalcuts = 0, + //Cuts, + //Violated, + //Noviol + //} PerspType; + + //typedef enum { + //Duplicate = 0, + //Notviolated + //} CutFail; + + //struct PerspGenStats + //{ + //UInt totalcuts; + //UInt violated; + //UInt noviol; + //UInt perspcons; + //UInt perspnotcons; + //UInt perspconsidered; + //double time; + //}; + + // Typedefs + class PerspCutGenerator; + typedef boost::shared_ptr PerspCutGeneratorPtr; + typedef boost::shared_ptr ConstPerspCutGeneratorPtr; + //typedef PerspGenStats * PerspGenStatsPtr; + //typedef PerspGenStats const * ConstPerspGenStatsPtr; + + /** + * PerpsCutGenerator class generates perspective cuts from constraints. + * For each constraint, we considere to get the perspective of the constraint. + * We generate a linearization of perspective function at the current + * solution. + * Then, we add this linearization as an inequality to problem formulation. + */ + class PerspCutGenerator { + public: + /// Default constructor. + PerspCutGenerator(); + + + /// Constructor that uses a relaxation and a solution given. + //MS: do we need both rel and p here? + PerspCutGenerator(UInt relvars, ConstSolutionPtr sol, ConstConstraintPtr c, + ConstVariablePtr v); + /// Destructor. + ~PerspCutGenerator(); + + /// Initialize data elements. + //void initialize(); + + /// Generate all perspective cuts. + //bool generateAllCuts(); + + /// Generate perspective cut. + void generateCut(); + //ConstraintPtr generateCut(); + + void gPCut(FunctionPtr f, double * y); + //ConstraintPtr gPCut(FunctionPtr f, double * y); + + // Return function pointer of PC + LinearFunctionPtr getPFunction() {return lf_;} + + // Return constant term of PC + //double getConst(); + /// Add cut to the corresponding lists. + //bool addCut(CutPtr cut); + + /// Check if the same cut is already included in the list. + //bool checkExists(CutPtr cut); + + /// Calculates the violation for a given cut. + //double violation(CutPtr cut); + + ///True if a new perspective cut violating current solution is found + //bool newVioPC() const + //{return newVioCut_;} + + /// Return const cut list. + //CutVector getCutList() const + //{return cutList_;} + + /// Return cuts that violates relaxation solution. + //CutVector getViolatedCutList() const + //{return viollist_;} + + /// Return violation list. + //DoubleVector getViolList() const + //{return viols_;} + + /// Return statistics of cut generator. + //ConstPerspGenStatsPtr getStats() const + //{return ConstPerspGenStatsPtr(stats_);} + + /// Check if given solution satisfies integrality for given relaxation. + //bool checkIntegral(RelaxationPtr p, ConstSolutionPtr s); + + private: + // Environment. + //EnvPtr env_; + + // Problem that cover cuts will be generated for. + //ProblemPtr p_; + + // Relaxation that cover cuts will be generated for. + RelaxationPtr rel_; + + // For log + LoggerPtr logger_; + + // For log + static const std::string me_; + + // List of cuts generated. + //CutVector cutList_; + + // List of violated cuts. + //CutVector viollist_; + + // List of violations for cuts corresponding in cut list. + //DoubleVector viols_; + + //This is true is a new cut violating the current solution is added + //bool newVioCut_; + + // List of constraints that we can obtain perspective cuts. + // We call them perspective constraints. + // PerspConPtr persplist_; + + /** Given (possibly fractional) solution. + * Cut will be designed to violate this solution. + */ + ConstSolutionPtr s_; + + // Perspective constraints. + //PerspConPtr conslist_; + + ConstConstraintPtr cp_; + ConstVariablePtr bp_; + + // Violation tolerance. + //double objtol_; + + + // Statistics for perspective cut generator. + //PerspGenStatsPtr stats_; + + // Hash map that is used to check if a cut is already created or not. + //std::map< DoubleVector, UInt > cutmap_; + + // Integer tolerance. + //double intTol_; + + /// Tolerance for accepting a new solution value: absolute threshold. + //double solAbsTol_; + //double solRelTol_; + + // General tolerance. + //double eTol_; + + // Output file + ofstream output_; + + // Output file name + string outfile_; + + // Function of pc + LinearFunctionPtr lf_; + + // Constant term of pc + //double cnst_; + + // Number of variable in relaxation + UInt rnv_; + }; +} + +#endif // MINOTAURPERSPCUTGENERATOR_H + + + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PerspCutHandler.h b/thirdparty/linux/include/minotaur/PerspCutHandler.h new file mode 100644 index 0000000..8d09674 --- /dev/null +++ b/thirdparty/linux/include/minotaur/PerspCutHandler.h @@ -0,0 +1,171 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file PerspCutHandler.h + * \brief Declare the PerspCutHandler class for handling perspective cut + * constraints. It generates the cuts whenever they are needed. + * \author Meenarli Sharma, Indian Institute of Technology + */ + +#ifndef MINOTAURPERSPCUTHANDLER_H +#define MINOTAURPERSPCUTHANDLER_H + +#include "Handler.h" +#include "PerspCutGenerator.h" + +namespace Minotaur { + +// Pointers for handler. +class PerspCutHandler; +typedef boost::shared_ptr PerspCutHandlerPtr; +typedef boost::shared_ptr ConstPerspCutHandlerPtr; + +//class Logger; +//typedef boost::shared_ptr LoggerPtr; + +//struct PCStats +//{ + //UInt perspcons; + //UInt cuts; + //double time; +//}; + +class PerspCutHandler : public Handler { +public: + + /// Default constructor. + PerspCutHandler(); + + /// Constructor. + PerspCutHandler(EnvPtr env, ProblemPtr problem); + + /// Destroy. + ~PerspCutHandler(); + + /// Generate list of constraints amenable to PR. + bool perspList(); + + /// Does nothing. + void relaxInitFull(RelaxationPtr, bool * ) {}; + + /// Does nothing. + void relaxInitInc(RelaxationPtr, bool * ) {}; + + /// Does nothing. + void relaxNodeFull(NodePtr, RelaxationPtr, bool * ) {}; + + /// Does nothing. + void relaxNodeInc(NodePtr, RelaxationPtr, bool * ) {}; + + /// Check if solution is feasible. + /// Checks all the constraints if they are satisfied by the given solution. + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool &should_prune, double &inf_meas); + + /** + * We need separation for this handler to generate the knapsack cover + * cuts. + * A set of perspective cuts will be generated. + */ + void separate(ConstSolutionPtr, NodePtr, RelaxationPtr, CutManager *cutman, + SolutionPoolPtr, bool *, SeparationStatus * status); + + // Does nothing. + virtual void getBranchingCandidates(RelaxationPtr, + const DoubleVector &, ModVector &, + BrVarCandSet &, BrCandVector &, + bool &) {}; + + /// Does nothing. + virtual ModificationPtr getBrMod(BrCandPtr, DoubleVector &, + RelaxationPtr, BranchDirection) + {return ModificationPtr();}; + + /// Does nothing. + virtual Branches getBranches(BrCandPtr, DoubleVector &, + RelaxationPtr, SolutionPoolPtr) + {return Branches();}; + + /// Does nothing. + SolveStatus presolve(PreModQ *, bool *) {return Finished;}; + + /// Does nothing. + virtual bool presolveNode(RelaxationPtr, NodePtr, + SolutionPoolPtr, ModVector &, + ModVector &) {return false;}; + + /// Write name. + std::string getName() const; + + /// Show statistics. + void writeStats(std::ostream &out) const; + + /// Return specific statistics. + //UInt PC_cuts() {return stats_->cuts;} + //double PC_time() {return stats_->time;} + +private: + + /// Environment. + EnvPtr env_; + + /// The problem for which the handler is created. + ProblemPtr minlp_; + + /// Log. + LoggerPtr logger_; + + /// Statistics. + //PCStats * stats_; + + /** + * This is false if the current solution violates any perspective cuts. + */ + bool isFeas_; + + /// Tolerance for accepting a new solution value: absolute threshold. + const double solAbsTol_; + + const double solRelTol_; + + /// Number of variables in MINLP. + //UInt numvars_; + + /// Tolerance for checking integrality. + double intTol_; + + // Number of PC generated + UInt numCuts_; + + /// For log: + static const std::string me_; + + ///vector of pointers to perspective constraint + std::vector cons_; + + ///vector of pointers to perspective constraint + std::vector binvar_; + + // Pointer to Perspective constraints detailed information + PerspConPtr persplist_; + +}; + +} + +#endif // MINOTAURPERSPCUTHANDLER_H + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PolynomialFunction.h b/thirdparty/linux/include/minotaur/PolynomialFunction.h new file mode 100644 index 0000000..8c36001 --- /dev/null +++ b/thirdparty/linux/include/minotaur/PolynomialFunction.h @@ -0,0 +1,344 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file PolynomialFunction.h + * \brief Define the MonomialFunction and PolynomialFunction classs for + * handling polynomial constraints. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURPOLYNOMIALFUNCTION_H +#define MINOTAURPOLYNOMIALFUNCTION_H + +#include "NonlinearFunction.h" + +namespace Minotaur { + + class CGraph; + class CNode; + class LinearFunction; + class MonomialFunction; + class QuadraticFunction; + typedef boost::shared_ptr CGraphPtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr MonomialFunPtr; + typedef boost::shared_ptr QuadraticFunctionPtr; + typedef boost::shared_ptr ConstLinearFunctionPtr; + typedef boost::shared_ptr ConstMonomialFunPtr; + typedef boost::shared_ptr ConstQuadraticFunctionPtr; + typedef std::vector MonomialVector; + typedef MonomialVector::iterator MonomialIter; + typedef MonomialVector::const_iterator MonomialConstIter; + + + class PolynomialFunction; + typedef boost::shared_ptr PolyFunPtr; + typedef boost::shared_ptr ConstPolyFunPtr; + + /** + * \brief MonomialFunction represents functions of the form + * of the form \f$\prod_ia_ix_i^{b_i}\f$ where \f$a_i \in \mathbb{R}, b_i + * \in \mathbb{N}\f$. + */ + class MonomialFunction : public NonlinearFunction { + public: + /// Default constructor. + MonomialFunction(); + + /// A constant monomial. + MonomialFunction(double c); + + /// Constructor with a single variable, a multiplier, and a power. + MonomialFunction(double c, ConstVariablePtr v, UInt p); + + /// Destroy. + ~MonomialFunction(); + + /// Create a full copy. + MonomialFunPtr clone() const; + + /// Make a clone using new variables. vbeg points to the variable id 0. + /// vbeg+k points to variable id k, where k>=0. + NonlinearFunctionPtr cloneWithVars(VariableConstIterator vbeg, + int *err) const; + + // Evaluate. + double eval(const double *x, int *error); + + // Evaluate. + double eval(const DoubleVector &x, int *error); + + // Gradient. + void evalGradient(const double *x, double *grad_f, int *error); + + void evalHessian(const double , const double *, + const LTHessStor *, double *, + int *) + {assert(!"can't fill hessian in a monomial function.");}; + + /// Populate the cgraph with a subgraph representing this monomial and + /// return the root node of this subgraph. + CNode* fillCG(CGraphPtr cg); + + void fillJac(const double *, double *, int *) + {assert(!"can't fill jacobian in a monomial function.");}; + + void fillHessStor(LTHessStor *) + {assert(!"can't fill hessian in a monomial function.");}; + + void finalHessStor(const LTHessStor *) + {assert(!"can't fill hessian in a monomial function.");}; + + double getCoeff() const; + + /// Get the degree, sum of all powers. + int getDegree() const; + + /// Monomial terms + const VarIntMap* getTerms() const; + + void getVars(VariableSet *) {}; + + /// Multiply with a variable raised to power. + void multiply(double coeff, ConstVariablePtr v, int p); + + /// Multiply with another monomial. + void multiply(ConstMonomialFunPtr m2); + + /// Multiply a constant. + void multiply(double c); + + void prepJac(VarSetConstIter, VarSetConstIter) + {assert(!"can't fill jacobian in a monomial function.");}; + + /// Iterator for the first term. + VarIntMapConstIterator termsBegin(); + + /// Iterator at the end of the terms. + VarIntMapConstIterator termsEnd(); + + /// Raise the monomial to power k. + void toPower(int k); + + /// Display. + void write(std::ostream &out) const; + + /// Multiply a constant. + void operator*=(double c); + + /// Multiply a monomial. + void operator*=(ConstMonomialFunPtr m2); + + private: + /// The coefficient. + double coeff_; + + /// The degree of monomial. + int deg_; + + /** + * \brief If a coefficient's magnitude is lower than eTol_, it is considered + * zero. + */ + const double eTol_; + + /// The variables and their exponents. + VarIntMap terms_; + }; + + // -------------------------------------------------------------------------- + // -------------------------------------------------------------------------- + + /** + * \brief PolynomialFunction represents functions of the form + * \f$\sum_jm_j\f$, where \f$m_j\f$ is a MonomialFunction. + */ + class PolynomialFunction : public NonlinearFunction { + public: + /// Default constructor. + PolynomialFunction(); + + /// Expand polynomial from a computational graph. + PolynomialFunction(CGraphPtr cg); + + /// Destroy + ~PolynomialFunction(); + + /// Make a clone. + PolyFunPtr clone() const; + + /// Add a monomial m to this polynomial. The monomial is first cloned. + void add(ConstMonomialFunPtr m); + + // base class function. + NonlinearFunctionPtr cloneWithVars(VariableConstIterator vbeg, + int *err) const; + + /// Create a cgraph representing this polynomial and save it as a private + /// member. Useful for solving using native derivatives. + void createCG(); + + // base class function. + double eval(const double *x, int *error); + + // base class function. + void evalGradient(const double *x, double *grad_f, int *error); + + // base class function. + void evalHessian(const double mult, const double *x, + const LTHessStor *stor, double *values, + int *error); + + // base class function. + void fillHessStor(LTHessStor *stor); + + // base class function. + void fillJac(const double *x, double *values, int *error); + + // base class function. + void finalHessStor(const LTHessStor *stor); + + // base class function. + void getVars(VariableSet *); + + /// Get the constant term. + double getConstant(); + + /// Return type of function. + FunctionType getType() const; + + /// Return true if the constant is 0 and there are no terms. + bool isEmpty() const; + + /// Multiply with (lf + c), where lf is a linear function. + void multiply(ConstLinearFunctionPtr lf, double c); + + /// Multiply with c, a constant. + void multiply(double c); + + // base class function. + void prepJac(VarSetConstIter vb, VarSetConstIter ve); + + void recCG_(const CNode* cnode, double *c, MonomialVector *terms); + void recCGMult_(MonomialVector *t1, MonomialVector *t2, + double c1, double c2, + MonomialVector *terms, double *c); + /** + * \brief If the polynomial has a constant term, return it, and remove it + * from the polynomial. + */ + double removeConstant(); + + /** + * If the polynomial has a linear function, add it to 'lf', and remove + * it from the polynomial. If lf is empty and polynomial has linear + * terms, new space is allocated. + */ + void removeLinear(LinearFunctionPtr lf); + + /** + * If the polynomial has a quadratic function, add it to 'qf', and remove + * it from the polynomial. If qf is NULL and polynomial has quadratic + * terms, new space is allocated. + */ + void removeQuadratic(QuadraticFunctionPtr qf); + + /// Get an iterator to the first monomial + MonomialConstIter termsBegin(); + + /// Get an iterator to the last monomial + MonomialConstIter termsEnd(); + + /// Display. + void write(std::ostream &out) const; + + /** + * Add a monomial to this polynomial. The monomial is copied. The user + * can change the monomial later wihout affecting the polynomial. This + * function is dangerous because it operates on the raw pointer of the + * polynomial and not the shared pointer. The user must ensure that it + * is not null. + */ + void operator+=(ConstMonomialFunPtr m); + + /// Add a polynomial to the polynomial. + void operator+=(ConstPolyFunPtr p); + + /// Multiply by a constant. + void operator*=(double c); + + /// Add a constant. + void operator+=(double c); + + /// Add a linear function. + void operator+=(ConstLinearFunctionPtr lf); + + /// Subtract a linear function. + void operator-=(ConstLinearFunctionPtr lf); + + /// Multiply with a linear function. + void operator*=(ConstLinearFunctionPtr lf); + + /// Add a quadratic. + void operator+=(ConstQuadraticFunctionPtr qf); + + /// Multiply with a quadratic. + void operator*=(ConstQuadraticFunctionPtr qf); + + /// Multiply with a polynomial. + void operator*=(ConstPolyFunPtr p2); + + /// Add two polynomials. Creates a new polynomial. + friend PolyFunPtr operator + (ConstPolyFunPtr p1, ConstPolyFunPtr p2); + + /// Subtract two polynomials. + friend PolyFunPtr operator - (ConstPolyFunPtr p1, ConstPolyFunPtr p2); + + /// Multiply a polynomial with constant. + friend PolyFunPtr operator*(double c, ConstPolyFunPtr p2); + + /// Multiply a linear function and polynomial function. + friend PolyFunPtr operator*(ConstPolyFunPtr p2, + ConstLinearFunctionPtr l1); + + /// Multiply a polynomial with quadratic. + friend PolyFunPtr operator*(ConstPolyFunPtr p1, + ConstQuadraticFunctionPtr q2); + + /// Multiply a polynomial with constant. + friend PolyFunPtr operator*(ConstPolyFunPtr p1, ConstPolyFunPtr p2); + + protected: + /// Additional constant. + double cb_; + + /// If the polynomial is constructed from a CGraph, we keep a pointer. + CGraphPtr cg_; + + /// Tolerance. + const double eTol_; + + /// Each monomial term. + MonomialVector terms_; + + /// Clear/reset all terms. Polynomial becomes 0. + void clear_(); + }; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PreAuxVars.h b/thirdparty/linux/include/minotaur/PreAuxVars.h new file mode 100644 index 0000000..7d3db14 --- /dev/null +++ b/thirdparty/linux/include/minotaur/PreAuxVars.h @@ -0,0 +1,57 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file PreAuxVars.h + * \brief Declare the PreAuxVars class for saving additional variables + * variables added during presolve. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURPREAUXVARS_H +#define MINOTAURPREAUXVARS_H + +#include "PreMod.h" +#include "Variable.h" + +namespace Minotaur { + +class PreAuxVars : public PreMod { +public: + /// Constructor. + PreAuxVars(); + + /// Destroy. + ~PreAuxVars(); + + /// New variable that was created. + void insert(VariablePtr v); + + /// Remove aux-vars from the solution x. + void postsolveGetX(const DoubleVector &x, DoubleVector *newx); + + /// Return the number of additions. + UInt getSize(); + +private: + std::deque vars_; + +}; + +typedef boost::shared_ptr PreAuxVarsPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PreDelVars.h b/thirdparty/linux/include/minotaur/PreDelVars.h new file mode 100644 index 0000000..1e9007b --- /dev/null +++ b/thirdparty/linux/include/minotaur/PreDelVars.h @@ -0,0 +1,56 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file PreDelVars.h + * \brief Declare the PreDelVars class for saving and restoring variables in + * presolve. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURPREDELVARS_H +#define MINOTAURPREDELVARS_H + +#include "PreMod.h" +#include "Variable.h" + +namespace Minotaur { + + class PreDelVars : public PreMod { + public: + /// Constructor + PreDelVars(); + + /// Destroy + ~PreDelVars(); + + /// Add a new variable to the list. + void insert(VariablePtr v); + + /// Restore x. + void postsolveGetX(const DoubleVector &x, DoubleVector *newx); + + private: + /// A queue of variables deleted. + VarQueue vars_; + + }; + + typedef boost::shared_ptr PreDelVarsPtr; + typedef boost::shared_ptr ConstPreDelVarsPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PreMod.h b/thirdparty/linux/include/minotaur/PreMod.h new file mode 100644 index 0000000..bf15176 --- /dev/null +++ b/thirdparty/linux/include/minotaur/PreMod.h @@ -0,0 +1,50 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file PreMod.h + * \brief Declare the PreMod class for saving changes in presolve. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURPREMOD_H +#define MINOTAURPREMOD_H + +#include "Types.h" + +namespace Minotaur { + + /** + * PreMod class is an abstract base class. It has a method to transform a + * solution of the presolved problem in to a solution of a problem in which + * some of the modifications have been undone. + */ + class PreMod { + public: + /// Constructor. + PreMod() {}; + + /// Destroy. + virtual ~PreMod() {}; + + /// Restore x. + virtual void postsolveGetX(const DoubleVector &x, DoubleVector *newx) = 0; + + }; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/PreSubstVars.h b/thirdparty/linux/include/minotaur/PreSubstVars.h new file mode 100644 index 0000000..1249f55 --- /dev/null +++ b/thirdparty/linux/include/minotaur/PreSubstVars.h @@ -0,0 +1,63 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file PreSubstVars.h + * \brief Declare the PreSubstVars class for saving and restoring + * variables substituted during presolve. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURPRESUBSTVARS_H +#define MINOTAURPRESUBSTVARS_H + +#include "PreMod.h" +#include "Variable.h" + +namespace Minotaur { + +struct PreSubstVarData { + VariablePtr vout; /// Number of nlps solved. + UInt vinInd; /// Number of nlps feasible. + double rat; /// Number of nlps infeasible. +}; + +class PreSubstVars : public PreMod { +public: + /// Constructor. + PreSubstVars(); + + /// Destroy. + ~PreSubstVars(); + + /// Substitute variable 'vin' by variable 'vout'. + void insert(VariablePtr vout, VariablePtr vin, double rat = 1.0); + + /// Restore x. + void postsolveGetX(const DoubleVector &x, DoubleVector *newx); + + /// Return the number of substitutions. + UInt getSize(); + +private: + std::deque vars_; + +}; + +typedef boost::shared_ptr PreSubstVarsPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Presolver.h b/thirdparty/linux/include/minotaur/Presolver.h new file mode 100644 index 0000000..7a6afa8 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Presolver.h @@ -0,0 +1,151 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// +/** + * \file Presolver.h + * \brief Declare Presolver class for presolving. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURPRESOLVER_H +#define MINOTAURPRESOLVER_H + +#include "Types.h" + +namespace Minotaur { + + class Solution; + class PreMod; + typedef boost::shared_ptr PreModPtr; + typedef boost::shared_ptr SolutionPtr; + typedef std::deque PreModQ; + typedef PreModQ::iterator PreModQIter; + typedef PreModQ::const_iterator PreModQConstIter; + + /** + * A Presolver is used to modify a problem such that it becomes simplified + * or easier to solve. A Presolver, in its default form, will create a copy + * of the problem. A user will need to specifically tell presolver not to + * copy a problem. It should maintain a + * list of changes made to the original problem. + + * The Presolver may also be able to detect infeasibility, optimality, + * feasibility or unboundedness. A presolver in this way, is very much a + * solver. + */ + class Presolver { + public: + /// Default constructor. + Presolver (); + + /// Constructor for a given problem. + Presolver (ProblemPtr problem, EnvPtr env, HandlerVector handlers); + + /// Destroy. + virtual ~Presolver(); + + /// Default presolve. + virtual void presolve() {}; + + virtual SolveStatus getStatus(); + /** + * standardize is called before solving any problem even when + * presolve is disabled. This method is necessary to standardize the + * problem: + * convert maximize to minimize, + * add a new variable for the objective function, + * ... + */ + virtual void standardize(); + + virtual SolveStatus solve(); + + /// Search and remove any duplicate rows and columns from the problem. + virtual void removeDuplicates() {}; + + /** + * Translate a given x into solution of the original problem. + * The space for newx needs to be allocated. + */ + virtual void getX(const double *x, DoubleVector *newx); + + /** + * Construct a solution for the original problem from that of the + * presolved problem. + */ + SolutionPtr getPostSol(SolutionPtr s); + + protected: + /* + * The problem being presolved. Only one problem may be presolved by one + * Presolver. + */ + ProblemPtr problem_; + + /// Handlers used to presolve the problem. + HandlerVector handlers_; + + /// A queue of presolve-modifications required for post-solve. + PreModQ mods_; + + /// A value in [z-intTol_, z+intTol_], z integer, will be treated as z. + double intTol_; + + /// Tolerance for checking feasibility. + double eTol_; + + /// Log manager. + LoggerPtr logger_; + + /// For logging + static const std::string me_; + + /// Environment. + EnvPtr env_; + + /// Status. + SolveStatus status_; + + /// Remove objective function, if it is zero or constant. + void removeEmptyObj_(); + + /// convert to minimization problem. + void minimizify_(); + + /** + * Replace the objective with a linear function. The problem remains + * equivalent to the one before the function is called. + */ + void linearizeObjective_(); + + /** + * Some interfaces (like AMPL) and the users may specify binary + * variables as integer variables. This function converts such variables + * to binary. + */ + void ifIntsAreBins_(); + + /* + * Convert constraints of the form g(x) >= c to -g(x) <= -c. Do not + * change equality or range constraints. + */ + void standardizeConstraints_(); + + }; + + typedef boost::shared_ptr PresolverPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/ProbStructure.h b/thirdparty/linux/include/minotaur/ProbStructure.h new file mode 100644 index 0000000..9fd4cc8 --- /dev/null +++ b/thirdparty/linux/include/minotaur/ProbStructure.h @@ -0,0 +1,120 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file ProbStructure.h + * \brief Declare base class ProbStructure. + * \author Serdar Yildiz, Argonne National Laboratory +*/ + +#ifndef MINOTAURPROBSTRUCTURE_H +#define MINOTAURPROBSTRUCTURE_H + +#include + +#include "Problem.h" +#include "Constraint.h" +#include "Variable.h" +#include "Types.h" +#include "Environment.h" + +namespace Minotaur{ + +struct ProbStructStats +{ + UInt totalcons; // Total number of constraints checked. + UInt totalGUBs; // Total number of GUBs obtained. +}; + +class ProbStructure; +typedef boost::shared_ptr ConstProbStructPtr; +typedef boost::shared_ptr ProbStructPtr; +typedef ProbStructStats* ProbStructStatsPtr; +typedef ProbStructStats const * ConstProbStructStatsPtr; + +typedef std::pair VarConsPair; +typedef std::map VarCons; +typedef boost::shared_ptr< VarCons > VarConsPtr; +typedef VarCons::iterator VarConsIterator; +typedef VarCons::const_iterator VarConsConstIterator; + + +/** + * Serdar Yildiz: This class identifies GUB constraints in the given problem. + * One list contains all the GUB constraints just as they found in the + * constraint list. + * Second list is a vector of pairs that is in the format of + * pair pointers to all the GUBs for the corresponding variable. + */ +class ProbStructure{ +public: + /// Default constructor + ProbStructure(); + + /// Constructs from a given problem. + ProbStructure(ProblemPtr p, EnvPtr env); + + /// Destructor. + ~ProbStructure(); + + /// Checks if a variable is a GUB constraint. + bool evalConstraint(ConstConstraintPtr cons); + + /// Add a constraint to the lists. + void addConstraint(ConstConstraintPtr cons); + + /// Generate the lists for GUBs and GUBs corresponding to variables. + void generateLists(); + + /// Get total number of GUBs. + UInt getNumGUB() const {return list_->size();}; + + /// Get total number of GUBs for a given variable. + UInt getNumVarGUB(ConstVariablePtr var) const; + + /// Get total number of constraints checked. + UInt getNumConsChecked() const {return stats_->totalcons;}; + + /// Get the statistics about GUB identification. + ConstProbStructStatsPtr getStats() const {return stats_;}; + + /// Get a pointer to the vector that contains GUBs for a given variable. + ConstConstraintVectorPtr getVarGUBs(ConstVariablePtr var) const; + + /// Get a pointer to the vector that contains GUBs. + ConstConstraintVectorPtr getGUBs() const {return list_;}; + +private: + // Environment. + EnvPtr env_; + // Problem that we identify GUB constraints. + ProblemPtr p_; + // Constraint list that contains the pointers to GUB constraints. + ConstConstraintVectorPtr list_; + // Vector that contains pair. + VarConsPtr varlist_; + // Statistics about GUBs. + ProbStructStatsPtr stats_; +}; + +} // end of namespace + +#endif // MINOTAURPROBSTRUCTURE_H + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: + + diff --git a/thirdparty/linux/include/minotaur/Problem.h b/thirdparty/linux/include/minotaur/Problem.h new file mode 100644 index 0000000..bea8fbc --- /dev/null +++ b/thirdparty/linux/include/minotaur/Problem.h @@ -0,0 +1,678 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file Problem.h + * \brief Declare base class Problem. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURPROBLEM_H +#define MINOTAURPROBLEM_H + +#include +#include "Types.h" +#include "Variable.h" + +namespace Minotaur { + + class Engine; + class Function; + class HessianOfLag; + class Jacobian; + class LinearFunction; + class NonlinearFunction; + class Objective; + struct ProblemSize; + class QuadraticFunction; + class SOS; + class SparseMatrix; + typedef boost::shared_ptr FunctionPtr; + typedef boost::shared_ptr JacobianPtr; + typedef boost::shared_ptr HessianOfLagPtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr NonlinearFunctionPtr; + typedef boost::shared_ptr ObjectivePtr; + typedef boost::shared_ptr ProblemSizePtr; + typedef boost::shared_ptr QuadraticFunctionPtr; + typedef boost::shared_ptr ConstProblemSizePtr; + + /** + * \brief The Problem that needs to be solved. + * + * The Problem class contains the Variables, Constraints, Objectives that + * collectively define a particular problem that can be solved. A + * problem can be described as + * + * min/max f(x) + * + * s.t. l_i <= g_i(x) <= u_i, i = 1,2, ... , m + * + * l_i <= x_i <= u_i, i = 1, 2, ..., n + * + * A way of setting up an problem is to first ask it to create 'n' + * variables. Then the constraints and objective can be added one by one. + * + * A Problem is a very generic class. The Relaxation classes + * are derived from it. + */ + class Problem { + public: + /// Default constructor + Problem(); + + /// Destroy + virtual ~Problem(); + + /// Add 'c' to both lb and ub of a constraint. + virtual void addToCons(ConstraintPtr cons, double c); + + /// Add a linear function to the objective. + virtual void addToObj(LinearFunctionPtr lf); + + /// Add a constant term to the objective. + virtual void addToObj(double cb); + + /// Fill up the statistics about the size of the problem into size_. + virtual void calculateSize(bool shouldRedo=false); + + /// Change a bound (lower or upper) on a variable with ID=id. + virtual void changeBound(UInt id, BoundType lu, double new_val); + + /// Change both bounds (lower and upper) on a variable with ID=id + virtual void changeBound(UInt id, double new_lb, double new_ub); + + /// Change a bound (lower or upper) on a variable 'var'. + virtual void changeBound(VariablePtr var, BoundType lu, double new_val); + + /// Change lower and upper bounds on the variable 'var' + virtual void changeBound(VariablePtr var, double new_lb, + double new_ub); + + /// Change a bound (lower or upper) on a constraint 'con'. + virtual void changeBound(ConstraintPtr con, BoundType lu, double new_val); + + /// Change lower and upper bounds on the constraint 'con' + virtual void changeBound(ConstraintPtr con, double new_lb, + double new_ub); + + /** + * \brief Change the linear function, and the bounds of a constraint. + * \param [in] con Original constraint that is to be changed. + * \param [in] lf The new linear function. + * \param [in] lb The new lower bound. + * \param [in] ub The new upper bound. + */ + virtual void changeConstraint(ConstraintPtr con, LinearFunctionPtr lf, + double lb, double ub); + + /** + * \brief Change the nonlinear function and bounds of a constraint. + * \param [in] con Original constraint that is to be changed. + * \param [in] nlf The new nonlinear function. + */ + virtual void changeConstraint(ConstraintPtr con, NonlinearFunctionPtr nlf); + + + /** + * \brief Replace the objective function with a new function. + * + * \param[in] f The new obejctive function. f is cloned. If f is modified + * after this call, it won't affect the objective. + * \param[in] cb The new objective constant. + */ + virtual void changeObj(FunctionPtr f, double cb); + + /** + * \brief Check whether variables used in the constraints belong to the + * problem or not. + * + * This is a sanity check, used only for debugging. + * \returns 1 if the check failed, 0 if passed. + */ + virtual int checkConVars() const; + + /** + * \brief Delete the whole Problem. + * + * Variables and constraints are so interlinked that we just can not call + * the destructor. This function just deletes all the constraints. The + * variables and functions can still be used after this is called. + */ + virtual void clear(); + + /** + * \brief Clone the given Problem class. Jacobian and Hessian in the cloned + * problem are NULL. + * + * The variables are created. If the functions are stored in native format, + * they are also cloned. Problem size and the initial point are cloned as + * well. + */ + ProblemPtr clone() const; + + /// Iterate over constraints. Returns the 'begin' iterator. + virtual ConstraintConstIterator consBegin() const + { return cons_.begin(); } + + /// Iterate over constraints. Returns the 'end' iterator. + virtual ConstraintConstIterator consEnd() const { return cons_.end(); } + + /// Delete marked constraints. + virtual void delMarkedCons(); + + /// Delete marked variables. + virtual void delMarkedVars(); + + /** + * \brief Return what type of problem it is. May result in re-calculation of + * the problem size. + */ + virtual ProblemType findType(); + + /// Return a pointer to the constraint with a given index + virtual ConstraintPtr getConstraint(UInt index) const; + + /// Return the hessian of the lagrangean. Could be NULL. + virtual HessianOfLagPtr getHessian() const; + + /** + * \brief Get the initial point. Used by some engines like IpoptEngine. The + * pointer returned from this function should not be changed or deleted. + */ + virtual const double * getInitialPoint() const { return initialPt_; } + + /// Return the jacobian. Could be NULL. + virtual JacobianPtr getJacobian() const; + + /// Get pointer to the log manager. Could be NULL. + virtual LoggerPtr getLogger(); + + /// Return the number of constraints. + virtual UInt getNumCons() const { return cons_.size(); } + + /// Return the number of constraints marked for deletion. + virtual UInt getNumDCons() const { return numDCons_; } + + /// Return the number of variables marked for deletion. + virtual UInt getNumDVars() const { return numDVars_; } + + /** + * \brief Return the number of non-zeros in the hessian of the lagrangean of the + * problem. + * + * The lagrangean is defined as: + * \\sigma . f(x) + \\sum_{i=0}^{m-1}\\lambda_i . g_i(x), + * where \\sigma \\in R^1 and \\lambda \\in R^m are the dual multipliers. + * The hessian, w.r.t. x, is thus a square symmetric matrix. usually the + * multipliers are provided by NLP solvers. + * Such solvers may require during initialization, the number of non-zeros + * in the lower triangular of the hessian. + */ + virtual UInt getNumHessNnzs() const; + + /// Return the number of non zerors in the jacobian of the constraints. + virtual UInt getNumJacNnzs() const; + + /// Return the number of linear constraints in the problem. + UInt getNumLinCons(); + + /// Return the number of SOS Type 1 constraints. + UInt getNumSOS1(); + + /// Return the number of SOS Type 2 constraints. + UInt getNumSOS2(); + + /// Return the number of variables. + virtual UInt getNumVars() const { return vars_.size(); } + + /// Return a pointer to the objective Function + virtual ObjectivePtr getObjective() const; + + /// Return the value of objective function at given point x. + double getObjValue(const double *x, int *err) const; + + /// Fill up the statistics about the size of the problem into size_. + ConstProblemSizePtr getSize() const; + + /// Return a pointer to the variable with a given index + virtual VariablePtr getVariable(UInt index) const; + + /** + * \brief Return true if the derivative is available through Minotaur's own + * routines for storing nonlinear functions. + */ + virtual bool hasNativeDer() const; + + /** + * \brief Returns true if the problem has only linear constraints and linear + * objectives. + */ + virtual bool isLinear(); + + /// Return true if a constraint is marked deleted. + virtual bool isMarkedDel(ConstConstraintPtr con); + + /// Return true if a constraint is marked deleted. + virtual bool isMarkedDel(ConstVariablePtr var); + + /** + * \brief Returns true if the problem has + * (1) linear or quadratic objective, and + * (2) linear constraints only. + */ + virtual bool isQP(); + + /** + * \brief Returns true if the problem has only linear or quadratic constraints + * and linear or quadratic objectives. Returns false if a problem is + * linear. Returns false if problem is nonlinear. + */ + virtual bool isQuadratic(); + + /** + * \brief Mark a constraint for deleting. + * + * The constraint is not deleted, just marked. Call Problem::delMarkedCons() + * to actually delete all the marked constraints. + * \param[in] con The constraint to be marked. + */ + virtual void markDelete(ConstraintPtr con); + + /** + * \brief Mark a variable as deleted. + * + * The variable is not deleted, just marked. Call Problem::delMarkedVars() + * to actually delete all the marked variables. + * \param[in] var The variable to be marked. + */ + virtual void markDelete(VariablePtr var); + + /// The objective is multiplied by -1. + virtual void negateObj(); + + /** + * \brief Add a new binary variable and return a pointer to it. A name is + * automatically generated by default. + */ + virtual VariablePtr newBinaryVariable(); + + /** + * \brief Add a new binary variable. + * + * \param[in] name The predefined name for this variable. + */ + virtual VariablePtr newBinaryVariable(std::string name); + + /** + * \brief Add a new constraint and return a pointer to it. A name is + * automatically generated by default. + * + * \param[in] f Pointer to the Function in the constraint. It is not cloned. + * The pointer is saved as it is. + * \param[in] lb The lower bound of the constraint. May be -INFINITY. + * \param[in] ub The upper bound of the constraint. May be +INFINITY. + */ + virtual ConstraintPtr newConstraint(FunctionPtr f, double lb, double ub); + + /** + * \brief Add a new constraint and return a pointer to it. + * + * \param[in] f Pointer to the Function in the constraint. It is not cloned. + * The pointer is saved as it is. + * \param[in] lb The lower bound of the constraint. May be -INFINITY. + * \param[in] ub The upper bound of the constraint. May be +INFINITY. + * \param[in] name The name for the constraint. + */ + virtual ConstraintPtr newConstraint(FunctionPtr f, double lb, double ub, + std::string name); + + /** + * \brief Add a new objective. A name is automatically generated by + * default. + * + * \param[in] f Pointer to the Function in the objective. It is not + * cloned. The pointer is saved as it is. + * \param[in] cb The constant term in the objective function. + * \param[in] otyp Whether the objective is to Minimize or Maximize. + */ + virtual ObjectivePtr newObjective(FunctionPtr f, double cb, + ObjectiveType otyp); + + /** + * \brief Add a new objective. + * + * \param[in] f Pointer to the Function in the objective. It is not cloned. + * The pointer is saved as it is. + * \param[in] cb The constant term in the objective function. + * \param[in] otyp Whether the objective is to Minimize or Maximize. + * \param[in] name The name for the objective function. + * + * \returns Pointer to the newly added objective function. + */ + virtual ObjectivePtr newObjective(FunctionPtr f, double cb, + ObjectiveType otyp, std::string name); + + /** + * \brief Add a new SOS constraint with a name. + * + * \param[in] n Number of variables in this SOS constraint. + * \param[in] type SOS1 (SOS type 1) or SOS2 (SOS type 2). + * \param[in] weights Values of coefficients of variables in the SOS + * constraint or just relative weights. + * \param[in] vars Variables in the constraint. + * \param[in] priority The priority provided by the user for this + * constraint. + * \param[in] name The name provided by the user for this + * SOS. + * + * \returns Pointer to the newly added SOS data. + */ + virtual SOSPtr newSOS(int n, SOSType type, const double *weights, + const VarVector &vars, int priority, std::string name); + + /** + * \brief Add a new SOS constraint (name generated automatically). + * + * \param[in] n Number of variables in this SOS constraint. + * \param[in] type SOS1 (SOS type 1) or SOS2 (SOS type 2). + * \param[in] weights Values of coefficients of variables in the SOS + * constraint or just relative weights. + * \param[in] vars Variables in the constraint. + * \param[in] priority The priority provided by the user for this + * constraint. + * + * \returns Pointer to the newly added SOS data. + */ + virtual SOSPtr newSOS(int n, SOSType type, const double *weights, + const VarVector &vars, int priority); + + + /** + * \brief Add a new continuous, unbounded variable to the Problem. + * \param[in] stype The source of the variable + */ + virtual VariablePtr newVariable(VarSrcType stype=VarOrig); + + /** + * \brief Add a new variable with bounds, type. A name is automatically + * generated by default. + * + * \param[in] lb The lower bound on the variable. May be -INFINITY. + * \param[in] ub The upper bound on the variable. May be +INFINITY. + * \param[in] vtype Type of the variable: Integer, Continuous, Binary. + * \param[in] stype The source of the variable + */ + virtual VariablePtr newVariable(double lb, double ub, VariableType vtype, + VarSrcType=VarOrig); + + /** + * \brief Add a new variable. + * + * \param[in] lb The lower bound on the variable. May be -INFINITY. + * \param[in] ub The upper bound on the variable. May be +INFINITY. + * \param[in] vtype Type of the variable: Integer, Continuous, Binary. + * \param[in] name Name of the variable. + * \param[in] stype The source of the variable + */ + virtual VariablePtr newVariable(double lb, double ub, VariableType vtype, + std::string name, VarSrcType=VarOrig); + + /** + * \brief Clone the variables pointed by the iterators and add them. + * + * Given starting and stopping iterators of variables, clone these + * variables and add the copies to this problem. Do not add them to any + * constraints or objectives. The IDs are not copied. + * \param[in] v_begin The 'begin' iterator of the variable vector. + * \param[in] v_end The 'end' iterator of the variable vector. + * \param[in] stype The source of the variables + */ + virtual void newVariables(VariableConstIterator v_begin, + VariableConstIterator v_end, + VarSrcType stype=VarOrig); + + /** + * \brief Setup problem data-structures for solving it. + * + * Prepare necessary data structures for the next solve. e.g. + * if constraints have been modified, then re-evalate the sparsity + * pattern of Jacobian and Hessian. + */ + virtual void prepareForSolve(); + + /// Remove objective from the Problem. + virtual void removeObjective(); + + /// Remove the quadratic part of objective and return it. + virtual QuadraticFunctionPtr removeQuadFromObj(); + + /** + * Remove the jacobian and hessian data structures. Useful when you want to + * re-compute the derivatives after a problem has been modified. + */ + virtual void resetDer(); + + /** + * \brief Reset an initial point. + * + * Initial point is used by some engines like IpoptEngine. If new + * variables are added, then set their initial values to zero and keep the + * initial values of the other variables as before. + * \param[in] newvar is number of new variables added to the problem. + */ + virtual void resetInitialPoint(UInt newvar); + + + /** + * \brief Reverse the sense of a constraint. + * + * \param[in] cons The constraint whose sense has to be reversed. + */ + virtual void reverseSense(ConstraintPtr cons); + + /** + * \brief Set the engine that is used to solve this problem. + * + * The problem contains a pointer to the engine so that whenever the problem + * is modified, the engine also gets the modifications. This function sets + * the engine that must be modified whenever the problem is modified. + * \param[in] engine The engine pointer. + */ + virtual void setEngine(Engine* engine); + + /** + * \brief Set an initial point. + * + * Initial point is used by some engines like IpoptEngine. If the + * initial point has already been set before, it is overwritten by the + * new point. + * \param[in] x An array of double values containing the coordinates of the + * initial point. + */ + virtual void setInitialPoint(const double *x); + + /** + * \brief Set an initial point. + * + * Same as function Problem::setInitialPoint, but only set values for the + * first 'k' variables. Put in because of AMPL's defined variables. + * \param[in] x An array of double values containing the coordinates of the + * initial point. + * \param[in] k The first 'k' variables will be initialized. + */ + virtual void setInitialPoint(const double *x, size_t k); + + /** + * \brief Add a pointer to the hessian of the Lagrangean. + * + * \param[in] hessian Pointer to the HessianOfLag object. + */ + virtual void setHessian(HessianOfLagPtr hessian); + + /** + * \brief Set the jacobian of the constraints. + * + * \param[in] jacobian Pointer to the Jacobian object. + */ + virtual void setJacobian(JacobianPtr jacobian); + + /** + * Set the log manager. + * + * \param[in] logger The log manager which should be used for logging. + */ + virtual void setLogger(LoggerPtr logger); + + /** + * \brief Ask Problem to construct its own jacobian and hessian using + * Minotaur's native code for nonlinear functions. + */ + void setNativeDer(); + + /** + * \brief Change the variable type. + * + * \param[in] var The variable pointer whose type needs to be changed. + * \param[in] type The new VariableType. + */ + virtual void setVarType(VariablePtr var, VariableType type); + + virtual SOSConstIterator sos1Begin() const { return sos1_.begin(); }; + virtual SOSConstIterator sos1End() const { return sos1_.end(); }; + virtual SOSConstIterator sos2Begin() const { return sos2_.begin(); }; + virtual SOSConstIterator sos2End() const { return sos2_.end(); }; + + /** + * \brief Substitute a variable 'out' with the variable 'in' through out the + * problem. + * + * \param[in] out The variable that is to be substituted out. + * \param[in] in The variable that replaces the variable 'out'. + * \param[in] rat The ratio of substitution. + * \f$v_{in} = rat \times v_{out}\f$. + */ + virtual void subst(VariablePtr out, VariablePtr in, double rat=1.0); + + /// Should be called in the Engine's destructor + virtual void unsetEngine(); + + /// Iterate over variables. + virtual VariableConstIterator varsBegin() const { return vars_.begin(); } + + /// Iterate over variables. + virtual VariableConstIterator varsEnd() const { return vars_.end(); } + + /// only for debugging, developing etc. + virtual void write(std::ostream &out, std::streamsize out_p=6) const; + + /// Write the problem size to logger_ + virtual void writeSize(std::ostream &out) const; + + protected: + /// Vector of constraints. + ConstraintVector cons_; + + /** + * \brief Flag that is turned on if the constraints are added or modified. + * + * When the problem is changed, say constraints are added or deleted, + * all associated changes do not happen at that time. For example, when + * new constraint is added, the hessian and jacobian do not change. + * This variable is true if constraints have changed since the last + * time all changes were applied. + */ + bool consModed_; + + /// Engine that must be updated if problem is loaded to it, could be null + Engine* engine_; + + /// Pointer to the hessian of the lagrangean. Could be NULL. + HessianOfLagPtr hessian_; + + /// Initial point. Can be NULL. + double * initialPt_; + + /// Pointer to the jacobian of constraints. Can be NULL. + JacobianPtr jacobian_; + + /// Pointer to the log manager. All output messages are sent to it. + LoggerPtr logger_; + + /// For logging + static const std::string me_; + + /// If true, set up our own Hessian and Jacobian. + bool nativeDer_; + + /// ID of the next constraint. + UInt nextCId_; + + /// ID of the next SOS constraint. + int nextSId_; + + /// ID of the next variable. + UInt nextVId_; + + /// Number of constraints marked for deletion + UInt numDCons_; + + /// Number of variables marked for deletion + UInt numDVars_; + + /// Objective, could be NULL. + ObjectivePtr obj_; + + /// Size statistics for this Problem. + ProblemSizePtr size_; + + /// SOS1 constraints. + SOSVector sos1_; + + /// SOS2 constraints. + SOSVector sos2_; + + /// Vector of variables. + VarVector vars_; + + /// True if variables delete, added or their bounds changed. + bool varsModed_; + + /// Count the types of constraints and fill the values in size_. + virtual void countConsTypes_(); + + /// Count the types of objectives and fill the values in size_. + virtual void countObjTypes_(); + + /// Fill up the size_ with number of variables of each type. + virtual void countVarTypes_(); + + /** + * \brief Update the function types of all variables based on whether they + * appear as linear, quadratic or nonlinear in each objective and + * constraint. + */ + virtual void findVarFunTypes_(); + + bool isPolyp_(); + + void setIndex_(VariablePtr v, UInt i); + + }; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/ProblemSize.h b/thirdparty/linux/include/minotaur/ProblemSize.h new file mode 100644 index 0000000..bb8f128 --- /dev/null +++ b/thirdparty/linux/include/minotaur/ProblemSize.h @@ -0,0 +1,122 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file ProblemSize.h + * \brief Declare structure ProblemSize for storing statistics about the problem. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURPROBLEMSIZE_H +#define MINOTAURPROBLEMSIZE_H + +#include "Types.h" + +namespace Minotaur { + /// ProblemSize stores several statistics on the size of the Problem + struct ProblemSize { + /// Number of variables in the Problem. + UInt vars; + + /// Number of constraints in the Problem. + UInt cons; + + /// Number of objectives in the Problem. + UInt objs; + + /// Number of binary variables. + UInt bins; + + /// Number of integer variables not including binary variables + UInt fixed; + + /// Number of integer variables not including binary variables + UInt ints; + + /// Number of continuous variables + UInt conts; + + /// Number of constraints that have a linear function only. + UInt linCons; + + /// Number of SOS Type 1 constraints. + UInt SOS1Cons; + + /// Number of SOS Type 2 constraints. + UInt SOS2Cons; + + /** + * Number of constraints that have a bilinear function and optionally, a + * linear function. + */ + UInt bilinCons; + + /** + * Number of constraints that have a multilinear function and optionally, + * a linear function. + */ + UInt multilinCons; + + /** + * Number of constraints that have a quadratic function and optionally, a + * linear function. + */ + UInt quadCons; + + /// Number of constraints that have nonlinear function. + UInt nonlinCons; + + /// Number of constraints that have a linear function. + UInt consWithLin; + + /// Number of constraints that have a bilinear function. + UInt consWithBilin; + + /// Number of constraints that have a multilinear function. + UInt consWithMultilin; + + /// Number of constraints that have a quadratic function. + UInt consWithQuad; + + /// Number of constraints that have a nonlinear function. + UInt consWithNonlin; + + /// Number of terms in the all linear functions in the constraints. + UInt linTerms; + + /// Number of terms in the all multilinear functions in the constraints. + UInt multiLinTerms; + + /// Number of terms in the all quadratic functions in the constraints. + UInt quadTerms; + + /// Number of terms in linear function in the objectives. + UInt objLinTerms; + + /// Number of terms in quadratic function in the objectives. + UInt objQuadTerms; + + /// Type of objective: constant, linear, quadratic ... + FunctionType objType; + + }; + typedef boost::shared_ptr< ProblemSize > ProblemSizePtr; + typedef boost::shared_ptr< const ProblemSize > ConstProblemSizePtr; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/QGHandler.h b/thirdparty/linux/include/minotaur/QGHandler.h new file mode 100644 index 0000000..5cdcb97 --- /dev/null +++ b/thirdparty/linux/include/minotaur/QGHandler.h @@ -0,0 +1,290 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file QGHandler.h + * \Briefly declare a derived class of Handler that handles convex nonlinear constraints + * of a problem by using Quesada-Grossmann algorithm. + * \Author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURQGHANDLER_H +#define MINOTAURQGHANDLER_H + +#include + +#include "Handler.h" +#include "Engine.h" +#include "Problem.h" +#include "Function.h" + +namespace Minotaur { + +class WarmStart; +typedef boost::shared_ptr WarmStartPtr; + +struct QGStats { + size_t nlpS; /// Number of nlps solved. + size_t nlpF; /// Number of nlps feasible. + size_t nlpI; /// Number of nlps infeasible. + size_t cuts; /// Number of cuts added to the LP. +}; + + +/** + * \brief Handler for convex constraints, based on quesada-grossmann + * algorithm. + * + * QGHandler is a derived class of Handler. It adds cuts generated + * by solving an NLP whenever an integer (but infeasible) solution of LP relaxation is found. + */ +class QGHandler : public Handler { + +private: + /// Pointer to environment. + EnvPtr env_; + + /// Tolerance for checking integrality (should be obtained from env). + double intTol_; + + /** + * Was this handler used to check the feasibility. We generate cuts + * only if we checked the feasibility and it is false. + */ +// bool isFeas_; //MS: removed + + /** + * For any linearization constraint that we generate, all + * coefficients with absolute value less than it are assumed zero. + */ + const double linCoeffTol_; + + /// Log. + LoggerPtr logger_; + + /// For log: + static const std::string me_; + + /// Pointer to original problem. + ProblemPtr minlp_; + + /// Vector of constraints. + std::vector nlCons_; + + /// NLP/QP Engine used to solve the NLP/QP relaxations. + EnginePtr nlpe_; + + /// Modifications done to NLP before solving it. + std::stack nlpMods_; + + /// Status of the NLP/QP engine. + EngineStatus nlpStatus_; + + /// Warm-start information for solving NLPs. + WarmStartPtr nlpWs_; + + UInt numCuts_; + + int numvars_; + + /** + * When the objective function is nonlinear, we need to save it, so + * that we can add linear approximations. + */ + FunctionPtr objFun_; + + /** + * The variable corresponding to the objective function. It is a part of + * all linearizations of the objective function and it appears in the + * objective. + */ + VariablePtr objVar_; + + /// Is the objective function nonlinear? + bool oNl_; + + /// Pointer to original problem. + RelaxationPtr rel_; + + double relobj_; + + /// Tolerance for accepting a new solution value: absolute threshold. + const double solAbsTol_; + + /// Tolerance for accepting a new solution value: relative threshold. + const double solRelTol_; + + /// Tolerance for checking constraint violation. + // double eTol_; + + /// Tolerance for checking linear cut violation. + // double eLinTol_; + + /// Statistics. + QGStats *stats_; + + + +public: + /// Empty constructor. + QGHandler(); + + /** + * \brief Default Constructor. + * + * \param [in] env Environment pointer. + * \param [in] minlp The minlp for which cuts are generated (Not the + * relaxation.) + * \param [in] nlpe The engine to solve nonlinear continuous problem. + */ + QGHandler(EnvPtr env, ProblemPtr minlp, EnginePtr nlpe); + + /// Destroy. + ~QGHandler(); + + /// Does nothing. + Branches getBranches(BrCandPtr, DoubleVector &, RelaxationPtr, + SolutionPoolPtr) + {return Branches();}; // NULL + + /// Does nothing. + void getBranchingCandidates(RelaxationPtr, + const DoubleVector &, ModVector &, + BrVarCandSet &, BrCandVector &, bool &) {}; + + /// Does nothing. + ModificationPtr getBrMod(BrCandPtr, DoubleVector &, RelaxationPtr, + BranchDirection) + {return ModificationPtr();}; // NULL + + + // Base class method. + std::string getName() const; + + // Base class method. Check if x is feasible. x has to satisfy integrality + // and also nonlinear constraints. + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool & should_prune, double &inf_meas); + + /// Does nothing. + SolveStatus presolve(PreModQ *, bool *) {return Finished;}; + + /// Does nothing. + bool presolveNode(RelaxationPtr, NodePtr, SolutionPoolPtr, ModVector &, + ModVector &) + {return false;}; + + /// Does nothing. + void postsolveGetX(const double *, UInt, DoubleVector *) {}; + + // Base class method. calls relax_(). + void relaxInitFull(RelaxationPtr rel, bool *is_inf); + + // Base class method. calls relax_(). + void relaxInitInc(RelaxationPtr rel, bool *is_inf); + + // Base class method. Does nothing. + void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf); + + // Base class method. Does nothing. + void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf); + + + // Base class method. Find cuts. + void separate(ConstSolutionPtr sol, NodePtr node, RelaxationPtr rel, + CutManager *cutman, SolutionPoolPtr s_pool, bool *sol_found, + SeparationStatus *status); + + // Show statistics. + void writeStats(std::ostream &out) const; + +private: + /** + * Find the linearization of nonlinear functions at point x* and add + * them to the relaxation only (not to the lp engine) + */ + void addInitLinearX_(const double *x); + + /** + * Add cuts to cut out an integer point not satisfied by nonlinear + * constraints or objective. + */ + void cutIntSol_(ConstSolutionPtr sol, SolutionPoolPtr s_pool, + bool *sol_found, SeparationStatus *status); + + /** + * Fix integer constrained variables to integer values in x. Called + * before solving NLP. + */ + void fixInts_(const double *x); + + /** + * Solve the NLP relaxation of the MINLP and add linearizations about + * the optimal point. isInf is set to true if the relaxation is found + * infeasible. Throw an assert if the relaxation is unbounded. + */ + void initLinear_(bool *isInf); + + /** + * Obtain the linear function (lf) and constant (c) from the + * linearization of function f at point x. + */ + void linearAt_(FunctionPtr f, double fval, const double *x, + double *c, LinearFunctionPtr *lf); + + /** + * When the objective function is nonlinear, we need to replace it with + * a single variable. + */ + void linearizeObj_(RelaxationPtr rel); + + /// Add all linearizations at point x that violate inf_x. + int OAFromPoint_(const double *x, const double *inf_x, + SeparationStatus *status); + + int OAFromPointInf_(const double *x, const double *inf_x, + SeparationStatus *status); + + /** + * Create the initial relaxation. It is called from relaxInitFull and + * relaxInitInc functions. + */ + void relax_(RelaxationPtr rel, bool *is_inf); + + /// Solve the nlp. + void solveNLP_(); + + /// Undo the changes done in fixInts_(). + void unfixInts_(); + + /** + * Update the upper bound. XXX: Needs proper integration with + * Minotaur's Handler design. + */ + void updateUb_(SolutionPoolPtr s_pool, double *nlp_val, + bool *sol_found); + + }; + + typedef boost::shared_ptr QGHandlerPtr; +} + + +#endif + + + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/QGHandlerPDE.h b/thirdparty/linux/include/minotaur/QGHandlerPDE.h new file mode 100644 index 0000000..6a4a680 --- /dev/null +++ b/thirdparty/linux/include/minotaur/QGHandlerPDE.h @@ -0,0 +1,290 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file QGHandler.h + * \Briefly declare a derived class of Handler that handles convex nonlinear constraints + * of a problem by using Quesada-Grossmann algorithm. + * \Author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURQGHANDLER_H +#define MINOTAURQGHANDLER_H + +#include + +#include "Handler.h" +#include "Engine.h" +#include "Problem.h" +#include "Function.h" + +namespace Minotaur { + +class WarmStart; +typedef boost::shared_ptr WarmStartPtr; + +struct QGStats { + size_t nlpS; /// Number of nlps solved. + size_t nlpF; /// Number of nlps feasible. + size_t nlpI; /// Number of nlps infeasible. + size_t cuts; /// Number of cuts added to the LP. +}; + + +/** + * \brief Handler for convex constraints, based on quesada-grossmann + * algorithm. + * + * QGHandler is a derived class of Handler. It adds cuts generated + * by solving an NLP whenever an integer (but infeasible) solution of LP relaxation is found. + */ +class QGHandlerPDE : public Handler { + +private: + /// Pointer to environment. + EnvPtr env_; + + /// Tolerance for checking integrality (should be obtained from env). + double intTol_; + + /** + * Was this handler used to check the feasibility. We generate cuts + * only if we checked the feasibility and it is false. + */ +// bool isFeas_; //MS: removed + + /** + * For any linearization constraint that we generate, all + * coefficients with absolute value less than it are assumed zero. + */ + const double linCoeffTol_; + + /// Log. + LoggerPtr logger_; + + /// For log: + static const std::string me_; + + /// Pointer to original problem. + ProblemPtr minlp_; + ProblemPtr minlpC_; + + /// Vector of constraints. + //std::vector nlCons_; + + /// NLP/QP Engine used to solve the NLP/QP relaxations. + EnginePtr lpe_; + + /// Modifications done to NLP before solving it. + std::stack nlpMods_; + + /// Status of the NLP/QP engine. + EngineStatus nlpStatus_; + + /// Warm-start information for solving NLPs. + WarmStartPtr nlpWs_; + + UInt numCuts_; + + int numvars_; + + /** + * When the objective function is nonlinear, we need to save it, so + * that we can add linear approximations. + */ + FunctionPtr objFun_; + + /** + * The variable corresponding to the objective function. It is a part of + * all linearizations of the objective function and it appears in the + * objective. + */ + VariablePtr objVar_; + + /// Is the objective function nonlinear? + bool oNl_; + + /// Pointer to original problem. + RelaxationPtr rel_; + + double relobj_; + + /// Tolerance for accepting a new solution value: absolute threshold. + const double solAbsTol_; + + /// Tolerance for accepting a new solution value: relative threshold. + const double solRelTol_; + + /// Tolerance for checking constraint violation. + // double eTol_; + + /// Tolerance for checking linear cut violation. + // double eLinTol_; + + /// Statistics. + QGStats *stats_; + + + +public: + /// Empty constructor. + QGHandlerPDE(); + + /** + * \brief Default Constructor. + * + * \param [in] env Environment pointer. + * \param [in] minlp The minlp for which cuts are generated (Not the + * relaxation.) + * \param [in] nlpe The engine to solve nonlinear continuous problem. + */ + QGHandlerPDE(EnvPtr env, ProblemPtr minlp, EnginePtr lpe); + + /// Destroy. + ~QGHandlerPDE(); + + /// Does nothing. + Branches getBranches(BrCandPtr, DoubleVector &, RelaxationPtr, + SolutionPoolPtr) + {return Branches();}; // NULL + + /// Does nothing. + void getBranchingCandidates(RelaxationPtr, + const DoubleVector &, ModVector &, + BrVarCandSet &, BrCandVector &, bool &) {}; + + /// Does nothing. + ModificationPtr getBrMod(BrCandPtr, DoubleVector &, RelaxationPtr, + BranchDirection) + {return ModificationPtr();}; // NULL + + + // Base class method. + std::string getName() const; + + // Base class method. Check if x is feasible. x has to satisfy integrality + // and also nonlinear constraints. + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool & should_prune, double &inf_meas); + + /// Does nothing. + SolveStatus presolve(PreModQ *, bool *) {return Finished;}; + + /// Does nothing. + bool presolveNode(RelaxationPtr, NodePtr, SolutionPoolPtr, ModVector &, + ModVector &) + {return false;}; + + /// Does nothing. + void postsolveGetX(const double *, UInt, DoubleVector *) {}; + + // Base class method. calls relax_(). + void relaxInitFull(RelaxationPtr rel, bool *is_inf); + + // Base class method. calls relax_(). + void relaxInitInc(RelaxationPtr rel, bool *is_inf); + + // Base class method. Does nothing. + void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf); + + // Base class method. Does nothing. + void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf); + + + // Base class method. Find cuts. + void separate(ConstSolutionPtr sol, NodePtr node, RelaxationPtr rel, + CutManager *cutman, SolutionPoolPtr s_pool, bool *sol_found, + SeparationStatus *status); + + // Show statistics. + void writeStats(std::ostream &out) const; + +private: + /** + * Find the linearization of nonlinear functions at point x* and add + * them to the relaxation only (not to the lp engine) + */ + void addInitLinearX_(const double *x); + + /** + * Add cuts to cut out an integer point not satisfied by nonlinear + * constraints or objective. + */ + void cutIntSol_(ConstSolutionPtr sol, SolutionPoolPtr s_pool, + bool *sol_found, SeparationStatus *status); + + /** + * Fix integer constrained variables to integer values in x. Called + * before solving NLP. + */ + void fixInts_(); + + /** + * Solve the NLP relaxation of the MINLP and add linearizations about + * the optimal point. isInf is set to true if the relaxation is found + * infeasible. Throw an assert if the relaxation is unbounded. + */ + //void initLinear_(bool *isInf); + + /** + * Obtain the linear function (lf) and constant (c) from the + * linearization of function f at point x. + */ + void linearAt_(FunctionPtr f, double fval, const double *x, + double *c, LinearFunctionPtr *lf); + + /** + * When the objective function is nonlinear, we need to replace it with + * a single variable. + */ + void linearizeObj_(RelaxationPtr rel); + + /// Add all linearizations at point x that violate inf_x. + int OAFromPoint_(const double *x, SeparationStatus *status); + + //int OAFromPointInf_(const double *x, const double *inf_x, + //SeparationStatus *status); + + /** + * Create the initial relaxation. It is called from relaxInitFull and + * relaxInitInc functions. + */ + void relax_(RelaxationPtr rel, bool *is_inf); + + /// Solve the nlp. + void solveNLP_(); + + /// Undo the changes done in fixInts_(). + void unfixInts_(); + + /** + * Update the upper bound. XXX: Needs proper integration with + * Minotaur's Handler design. + */ + //void updateUb_(SolutionPoolPtr s_pool, double *nlp_val, + //bool *sol_found); + + }; + + typedef boost::shared_ptr QGHandlerPDEPtr; +} + + +#endif + + + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/QPDProcessor.h b/thirdparty/linux/include/minotaur/QPDProcessor.h new file mode 100644 index 0000000..0ff7b4a --- /dev/null +++ b/thirdparty/linux/include/minotaur/QPDProcessor.h @@ -0,0 +1,280 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file QPDProcessor.h + * \brief Define the derived class of QPDProcessor that solves QPs and NLP + * relaxations. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURQPDPROCESSOR_H +#define MINOTAURQPDPROCESSOR_H + +#include "NodeProcessor.h" + +namespace Minotaur { + + class Engine; + class NonlinearFunction; + class Problem; + class Solution; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr NonlinearFunctionPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr SolutionPtr; + typedef boost::shared_ptr ConstSolutionPtr; + + struct QPDStats { + UInt bra; /// Number of times relaxation became infeasible + UInt cuts; /// Number of cuts added + UInt inf; /// Number of times relaxation became infeasible + UInt nlp; /// Number of NLPs solved + UInt nlpI; /// Number of NLP-solves infeasible + UInt nlpU; /// Number of NLP-solves feasible + UInt opt; /// Number of times relaxation gave optimal feasible solution + UInt prob; /// Number of times problem ocurred in solving + UInt proc; /// Number of nodes processed + UInt sep; /// Number of times qp-point separated + UInt ub; /// Number of nodes pruned because of bound + }; + + /** + * QPDProcessor is a derived class of NodeProcessor. It is meant to solve QPs + * at each node. Sometimes it also solves NLPs. + */ + class QPDProcessor : public NodeProcessor { + + public: + /// Default constructor + QPDProcessor(); + + /// Create the processor using options from an environment. + QPDProcessor(EnvPtr env, ProblemPtr p, EnginePtr e, EnginePtr qe, + HandlerVector &handlers); + + /// Destroy + ~QPDProcessor(); + + // Add a heuristic. + void addHeur(HeurPtr h); + + // True if a new solution was found while processing this node. + bool foundNewSolution(); + + // Find branches that will be used to branch at this node. + Branches getBranches(); + + // Get warm-start information. + WarmStartPtr getWarmStart(); + + // Implement NodeProcessor::process(). + void process(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool); + + // Process root node. + void processRootNode(NodePtr node, RelaxationPtr rel, + SolutionPoolPtr s_pool); + + // write statistics. Base class method. + void writeStats(std::ostream &out) const; + + // write statistics to logger. Base class method. + void writeStats() const {}; + + private: + /// Branches found by this processor for this node. + Branches branches_; + + /// Engine used to process the NLP relaxation. + EnginePtr e_; + + /// Pointer to environment. + EnvPtr env_; + + VariablePtr eta_; + + VariablePtr etaL_; + + /// Vector of all handlers. + HandlerVector handlers_; + + /// Log + Logger *logger_; + + /* + * If Filter-SQP is used, the duals are negative of what QP from Hessian + * evaluation expects. If this flag is on, the duals are negated before + * creating QP. + */ + bool negDuals_; + + /// Name. For logging. + static const std::string me_; + + /// Vector of nonlinear constraints. + std::vector nlCons_; + + /// No. of solutions found while processing this node. + UInt numSolutions_; + + /// Pointer to original problem. + ProblemPtr p_; + + /// Relaxation that is processed by this processor. + RelaxationPtr qp_; + + /// Engine used to process the QP. + EnginePtr qpe_; + + const double solAbsTol_; + + const double solRelTol_; + + /** + * If QP-diving is used with Filter-SQP as nlp-engine, then we need to + * resolve QP after each call to nlp solve. Otherwise, bqpd gets in + * trouble. + */ + bool solveQPafNLP_; + + /// Statistics + QPDStats stats_; + + /// To impose upper bound. + ConstraintPtr ubCon_; + + /// Warm-start information for start processing the children. + WarmStartPtr ws_; + + bool boundTooFar_(ConstSolutionPtr sol, NodePtr node, + double best) ; + + void getLin_(FunctionPtr f, const double *x, UInt n, + VariableConstIterator vbeg, VariableConstIterator vend, + LinearFunctionPtr &lf, double &val); + + void getObjLin_(NonlinearFunctionPtr nlf, const double *x, + UInt n, VariableConstIterator vbeg, + VariableConstIterator vend, + LinearFunctionPtr &lf, double &val); + + void fixInts_(const double *x, std::stack *nlp_mods); + + void chkObjVio_(double vio, double etaval, bool &large_vio); + + void chkVio_(NodePtr node, double *vio, double &tvio, double &maxvio, + bool &large_vio); + + bool isHFeasible_(ConstSolutionPtr sol, bool &should_prune); + bool isHFeasible2_(ConstSolutionPtr sol, bool &ishigh, + bool &should_prune); + void chkObjVio2_(const double *qpx, NodePtr node, double best, + bool &hiobjd, bool &hietavio); + + bool isNLPFeasible2_(const double *qpx, double *vio, NodePtr node, bool + &hicvio); + bool isLargeCVio_(ConstConstraintPtr c, double vio, UInt depth); + + //bool isQPFeasible_(NodePtr node, ConstSolutionPtr sol, + // SolutionPoolPtr s_pool, bool &should_prune); + + bool isNLPFeasible_(ConstSolutionPtr sol, double *vio); + + SolutionPtr nlpSol2Qp_(ConstSolutionPtr sol); + + void OAFromPoint_(const double *x, ConstSolutionPtr sol, + SeparationStatus *status); + + bool presolveNode_(NodePtr node, SolutionPoolPtr s_pool); + + void processNLP_(NodePtr node, ConstSolutionPtr &sol, + ConstSolutionPtr qpsol, + SolutionPoolPtr s_pool, bool &should_prune); + + void processQP_(UInt iter, NodePtr node, ConstSolutionPtr &sol, + SolutionPoolPtr s_pool, bool &should_prune, + bool &should_resolve); + + void processQP2_(UInt iter, NodePtr node, ConstSolutionPtr &sol, + SolutionPoolPtr s_pool, bool &should_prune, + bool &should_resolve); + + void saveSol_(ConstSolutionPtr sol, SolutionPoolPtr s_pool, + NodePtr node); + void saveQPSol_(ConstSolutionPtr sol, SolutionPoolPtr s_pool, + NodePtr node); + + void separate_(bool is_nec, ConstSolutionPtr sol, const double *vio, + ConstSolutionPtr nlp_sol, NodePtr node, + SolutionPoolPtr s_pool, SeparationStatus *status); + + void separateB_(ConstSolutionPtr sol, ConstSolutionPtr nlp_sol, + double *vio, NodePtr node, SolutionPoolPtr s_pool, + SeparationStatus *status); + + void separateC_(ConstSolutionPtr sol, ConstSolutionPtr nlp_sol, + double *vio, NodePtr node, SolutionPoolPtr s_pool, + SeparationStatus *status); + + void separateO_(ConstSolutionPtr sol, ConstSolutionPtr nlp_sol, + double *vio, NodePtr node, SolutionPoolPtr s_pool, + SeparationStatus *status); + + void separateECP_(ConstSolutionPtr sol, const double *vio, + NodePtr node, SolutionPoolPtr , + SeparationStatus *status); + + void separateObj_(ConstSolutionPtr sol, ConstSolutionPtr nlp_sol, + double vio, SeparationStatus *status); + + void setupQP_(ConstSolutionPtr sol); + + /** + * Check if a node can be pruned either because the relaxation is + * infeasible or because the cost is too high. + */ + bool shouldPrune_(NodePtr node, EngineStatus nlp_status, + ConstSolutionPtr sol, SolutionPoolPtr s_pool); + + /** + * Check if a node can be pruned after solving QP. + */ + bool shouldPruneQP_(NodePtr node, EngineStatus nlp_status, + ConstSolutionPtr sol, SolutionPoolPtr s_pool); + + bool shouldSep_(bool is_nec, double vio, ConstConstraintPtr c); + bool shouldSepObj_(bool is_nec, double vio, double etaval); + + /// Solve original nlp. + void solveNLP_(ConstSolutionPtr &sol, EngineStatus &nlp_status); + + void solveQP_(ConstSolutionPtr &sol, EngineStatus &qp_status); + + SolutionPtr translateSol_(ConstSolutionPtr sol); + + void unfixInts_(std::stack *nlp_mods); + + void updateObjCons_(ConstSolutionPtr sol); + + void updateUb_(SolutionPoolPtr s_pool, double *nlpval); + }; + + typedef boost::shared_ptr QPDProcessorPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/QPDRelaxer.h b/thirdparty/linux/include/minotaur/QPDRelaxer.h new file mode 100644 index 0000000..dd9704d --- /dev/null +++ b/thirdparty/linux/include/minotaur/QPDRelaxer.h @@ -0,0 +1,91 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file QPDRelaxer.h + * \brief Declare the QPDRelaxer class. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURQPDRELAXER_H +#define MINOTAURQPDRELAXER_H + +#include "NodeRelaxer.h" + +namespace Minotaur { + + class Engine; + class Logger; + class Problem; + typedef boost::shared_ptr EnginePtr; + typedef boost::shared_ptr ConstProblemPtr; + + + /** + * QPDRelaxer creates ``relaxation'' by + * creating a QP approximation. It does not really create a relaxation. + * However, the Relaxation class suffices for its purposes. If we dived on a + * node, then we don't create another QP, but just change the bounds. + */ + class QPDRelaxer : public NodeRelaxer { + public: + /// Default constructor. + QPDRelaxer(EnvPtr env, ProblemPtr p, EnginePtr qe, EnginePtr e); + + /// Destroy. + ~QPDRelaxer(); + + // Implement NodeRelaxer::CreateRootRelaxation(). + RelaxationPtr createRootRelaxation(NodePtr rootNode, bool &prune); + + // Implement NodeRelaxer::CreateNodeRelaxation(). + RelaxationPtr createNodeRelaxation(NodePtr node, bool dived, bool &prune); + + // Implement NodeRelaxer::reset(). + void reset(NodePtr node, bool diving); + + // get the relaxation pointer, qp_. + RelaxationPtr getRelaxation(); + + private: + /// Environment + EnvPtr env_; + + /// Original Problem. + ProblemPtr p_; + + /** + * We only keep one QP formulation. We will clear all constraints (but + * not variables) and rebuild them if needed. + */ + RelaxationPtr qp_; + + /// Engine used to solve QP. + EnginePtr qpe_; + + /// Engine used to solve NLP. + EnginePtr e_; + + /// Logger. + Logger *logger_; + + }; + + typedef boost::shared_ptr QPDRelaxerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/QPEngine.h b/thirdparty/linux/include/minotaur/QPEngine.h new file mode 100644 index 0000000..b38a316 --- /dev/null +++ b/thirdparty/linux/include/minotaur/QPEngine.h @@ -0,0 +1,49 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +#ifndef MINOTAURQPENGINE_H +#define MINOTAURQPENGINE_H + +#include "Engine.h" + +namespace Minotaur { + + /** + * The QPEengine class is an abstract class for interfacing QP solvers (like + * bqpd). A derived class must implement calls to the QP solver for + * the methods described here. + * + * \todo add more methods for modifying the problem + * \todo add more methods for setting solver options and parameters + */ + + class QPEngine : public Engine { + + public: + friend class Problem; + + /// Constructor. May set default parameters/options here. + QPEngine() {}; + + virtual ~QPEngine() {}; + protected: + /// Destructor must be implemented. + }; + typedef boost::shared_ptr QPEnginePtr; +} + +#endif +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/QuadHandler.h b/thirdparty/linux/include/minotaur/QuadHandler.h new file mode 100644 index 0000000..19bf737 --- /dev/null +++ b/thirdparty/linux/include/minotaur/QuadHandler.h @@ -0,0 +1,390 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file QuadHandler.h + * \brief Declare a handler for simple quadratic constraints of the form + * \f$ y_1 = x_1x_2 \f$, + * and + * \f$ y_1 = x_1^2 \f$, + * It does not handle any other quadratic constraints. + * \author Ashutosh Mahajan, IIT Bombay + */ + +#ifndef MINOTAURQUADRATICHANDLER_H +#define MINOTAURQUADRATICHANDLER_H + +#include "Handler.h" +#include "LinBil.h" + +namespace Minotaur { + +class LinearFunction; +class Timer; +typedef boost::shared_ptr LinearFunctionPtr; + +/** + * \brief A structure to save information about constraints of the form \f$ y + * \leq x^2 \f$. + */ +struct LinSqr { + VariablePtr y; ///> The variable y. + VariablePtr x; ///> The variable x. + ConstraintPtr oeCon; ///> The linear constraint that gives the over estimator +}; +typedef LinSqr* LinSqrPtr; ///> Pointer to LinSqr +typedef std::vector LinSqrVec; ///> Vector of LinSqr +typedef LinSqrVec::iterator LinSqrVecIter; ///> Iterator for LinSqr + +/// Map of 'x' and the LinSqr that is used for \f$ y = x^2 \f$. +typedef std::map LinSqrMap; +typedef LinSqrMap::iterator LinSqrMapIter; ///> Iterator for LinSqrMap + + +/** + * A QuadHandler handles the quadratic functions of a problem in a simplistic + * fashion. For now, we will just handle squares of singleton variables e.g. + * \f$x_1^2 = y_1\f$, and bilinear terms: \f$x_1x_2 = y_1\f$. + */ +class QuadHandler : public Handler { +public: + /// Default constructor. + QuadHandler(EnvPtr env, ProblemPtr problem); + + /// Destroy + ~QuadHandler(); + + // base class method + void addConstraint(ConstraintPtr newcon); + + // Implement Handler::getBranches(). + Branches getBranches(BrCandPtr cand, DoubleVector & x, + RelaxationPtr rel, SolutionPoolPtr s_pool); + + // base class method + void getBranchingCandidates(RelaxationPtr rel, const DoubleVector &x, + ModVector &mods, BrVarCandSet &cands, + BrCandVector &gencands, bool &is_inf); + + // base class method + ModificationPtr getBrMod(BrCandPtr cand, DoubleVector &x, + RelaxationPtr rel, BranchDirection dir); + + // base class method + std::string getName() const; + + // base class method. + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool &should_prune, double &inf_meas); + + // base class method. + SolveStatus presolve(PreModQ *pre_mods, bool *changed); + + // base class method. Tightens bounds. + bool presolveNode(RelaxationPtr p, NodePtr node, + SolutionPoolPtr s_pool, ModVector &p_mods, + ModVector &r_mods); + + // base class method. Adds linear inequalities + void relaxInitFull(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxInitInc(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf); + + + // base class method. Adds linearlization cuts when available. + void separate(ConstSolutionPtr sol, NodePtr node, RelaxationPtr rel, + CutManager *cutman, SolutionPoolPtr s_pool, bool *sol_found, + SeparationStatus *status); + + // base class method. + void writeStats(std::ostream &out) const; + +private: + /// Store statistics of presolving. + struct SepaStats + { + int iters; ///> Number of times separation routine called. + int cuts; ///> Number of cuts added. + double time; ///> Total time used in separation + }; + + /// Store statistics of presolving. + struct PresolveStats + { + int iters; ///> Number of iterations (main cycle). + double time; ///> Total time used in initial presolve. + double timeN;///> Total time used in presolveNode. + int vBnd; ///> Number of times variable-bounds were tightened. + int nMods; ///> Number of changes made in all nodes. + }; + + /// Absolute feasibility tolerance + double aTol_; + + /// Update bounds if they can be improved by at least this quantity + double bTol_; + + /// Logger. + LoggerPtr logger_; + + /// For printing messages. + static const std::string me_; + + /// Transformed problem (not the relaxation). + ProblemPtr p_; + + /// Statistics about presolve + PresolveStats pStats_; + + /// Relative feasibility tolerance + double rTol_; + + /// Statistics about separation + SepaStats sStats_; + + /// Keep track of time + const Timer* timer_; + + /** + * \brief Container for all bilinear functions. This should contain + * variables and constraints of the problem, not the relaxation. + */ + LinBilSet x0x1Funs_; + + /** + * \brief Container for all square functions. This should contain variables and + * constraints of the problem, not the relaxation. + */ + LinSqrMap x2Funs_; + + /** + * \brief Add a gradient-based linearization inequality. + * \param[in] x The variable x in (y = x^2) + * \param[in] y The variable y in (y = x^2) + * \param[in] xl x coordinate at which the gradient is evaluated + * \param[in] yl y coordinate at which the gradient is evaluated + * \param[in] xval x coordinate of point that is to be cut off + * \param[in] yval y coordinate of point that is to be cut off + * \param[in] rel Relaxation pointer to which the cut is added + * \param[out] ifcuts True if the new inequality cuts off the point + * (xval,yval) + */ + void addCut_(VariablePtr x, VariablePtr y, double xl, double yl, double xval, + double yval, RelaxationPtr rel, bool &ifcuts); + + /** + * \brief Find the point at which a gradient-based linearization inequality + * can be added. + * \param[in] xval x coordinate of point that we want to cut off + * \param[in] yval y coordinate of point that we want to cut off + * \param[in] xl x coordinate of point at which gradient can be evaluated + * \param[in] yl y coordinate of point at which gradient can be evaluated + */ + void findLinPt_(double xval, double yval, double &xl, double &yl); + + /** + * \brief Get one of the four linear functions and right hand sides for the + * linear relaxation of a bilinear constraint y = x0x1. + * \param[in] x0 x0 variable + * \param[in] lb0 New lower bound of x0 + * \param[in] ub0 New upper bound of x0 + * \param[in] x1 x1 variable + * \param[in] lb1 New lower bound of x1 + * \param[in] ub1 New upper bound of x1 + * \param[in] y The y variable + * \param[in] type Could be 0,1,2,3. It tells the function which (out of the + * four) linear constraints do we want. + * \param[out] rhs The rhs (upperbound) of the linear constraint + * \return A linear function such that lf <= rhs is a relaxation of the + * bilinear constraint. + */ + LinearFunctionPtr getNewBilLf_(VariablePtr x0, double lb0, double ub0, + VariablePtr x1, double lb1, double ub1, + VariablePtr y, int type, double &rhs); + + /** + * \brief Get linear function and right hand side for the linear + * overestimator constraint for the square type y=x^2. + * \param[in] x The variable x + * \param[in] y The variable y + * \param[in] lb The new lower bound of x + * \param[in] ub The new upper bound of x + * \param[out] r The rhs (upper bound) of the linear constraint. + * \return A linear function such that lf <= rhs is a relaxation of the + * square constraint. + */ + LinearFunctionPtr getNewSqLf_(VariablePtr x, VariablePtr y, + double lb, double ub, double & r); + + + /// Return true if xval is one of the bounds of variable x + bool isAtBnds_(ConstVariablePtr x, double xval); + + /** + * \brief Strengthen bounds of variables in a bilinear constraint y=x0x1 + * \param[in] lx0x1 The bilinear term + * \param[out] changed True if any bounds of y, x0 or x1 have changed. False + * otherwise. + * Return true if the new bounds are inconsistent (i.e., lb > ub for any of + * the three variables) + */ + bool propBilBnds_(LinBil* lx0x1, bool *changed); + + /** + * \brief Strengthen bounds of variables in a bilinear constraint y=x0x1, + * and save the modifications if any. + * \param[in] lx0x1 The bilinear term + * \param[in] rel The relaxation that is currently being solved. + * \param[in] mod_rel If true, then change the relaxation also. The original + * (or transformed) problem p_ is always modified. + * \param[out] changed True if any bounds of y, x0 or x1 have changed. False + * otherwise. + * \param[in] p_mods A vector to save the modifications to the problem + * \param[in] r_mods A vector to save the modifications to the relaxation + * Return true if the new bounds are inconsistent (i.e., lb > ub for any of + * the three variables) + */ + bool propBilBnds_(LinBil* lx0x1, RelaxationPtr rel, bool mod_rel, + bool *changed, ModVector &p_mods, ModVector &r_mods); + + /** + * \brief Strengthen bounds of variables in a square constraint y=x0^2. + * \param[in] lx2 The sqaure term + * \param[out] changed True if any bounds of y or x0 have changed. False + * otherwise. + * Return true if the new bounds are inconsistent (i.e., lb > ub for any of + * the two variables) + */ + bool propSqrBnds_(LinSqrMapIter lx2, bool *changed); + + /** + * \brief Strengthen bounds of variables in a square constraint y=x0^2, + * and save the modifications if any. + * \param[in] lx2 The square term + * \param[in] rel The relaxation that is currently being solved. + * \param[in] mod_rel If true, then change the relaxation also. The original + * (or transformed) problem p_ is always modified. + * \param[out] changed True if any bounds of y or x0 have changed. False + * otherwise. + * \param[in] p_mods A vector to save the modifications to the problem + * \param[in] r_mods A vector to save the modifications to the relaxation + * Return true if the new bounds are inconsistent (i.e., lb > ub for any of + * the two variables) + */ + bool propSqrBnds_(LinSqrMapIter lx2, RelaxationPtr rel, bool mod_rel, + bool *changed, ModVector &p_mods, ModVector &r_mods); + + /** + * \brief Relax all the square constraints: y=x0^2 and bilinear constraints + * y=x0x1 in the problem. + * \param[in] rel The relaxation to which the new linear inequalities are + * added. + * \param[out] is_inf True if the relaxation is detected to be infeasible + * (because of inconsistent bounds or other reasons). + */ + void relax_(RelaxationPtr rel, bool *is_inf); + + /// Reset all statistics to zero. + void resetStats_(); + + /** + * \brief Modify bounds of a variable in the problem to the new bounds lb + * and ub if the new bounds are tighter. + * \param[in] v The variable + * \param[in] lb The new lower bound + * \param[in] ub The new upper bound + * \param[out] changed True if the new bounds are tighter than the existing + * bounds. False otherwise. + * \return the number of bound changes (1 or 2) if any bounds are changed. + * Returns -1 if the new bounds make the problem infeasible. Returns 0 + * otherwise. + */ + int updatePBounds_(VariablePtr v, double lb, double ub, bool *changed); + + /** + * \brief Modify bounds of a variable in the problem to the new bounds lb + * and ub if the new bounds are tighter. Additionally, save the + * modifications in the appropriate vectors so that they can be reverted at + * a later time. + * \param[in] v The variable + * \param[in] lb The new lower bound + * \param[in] ub The new upper bound + * \param[in] rel The relaxation that is currently being solved + * \param[in] mod_rel If true, then the relaxation is also modified. The + * original (or transformed) problem is always modified. + * \param[out] changed True if the new bounds are tighter than the existing + * bounds. False otherwise. + * \param[in] p_mods A vector to save the modifications to the problem + * \param[in] r_mods A vector to save the modifications to the relaxation + * \return the number of bound changes (1 or 2) if any bounds are changed. + * Returns -1 if the new bounds make the problem infeasible. Returns 0 + * otherwise. + */ + int updatePBounds_(VariablePtr v, double lb, double ub, RelaxationPtr rel, + bool mod_rel, bool *changed, ModVector &p_mods, + ModVector &r_mods); + + /** + * \brief Update linear relaxation of the bilinear constraints after some + * bounds have changed. The function checks whether each of the four + * constraints are binding at the required extreme points of the box. If + * not, the constraints are updated. + * \param[in] lx0x1 The bilinear term + * \param[in] rel The relaxation which contains the four linear constraints + * \param[in] r_mods A vector into which the modifications are appended so + * that they can be reverted at a later time. + */ + void upBilCon_(LinBil* lx0x1, RelaxationPtr rel, ModVector &r_mods); + + + /** + * \brief Update linear relaxation of the square constraints (y=x^2) after + * some bounds have changed. The function checks whether the upper bounding + * constraint is binding at the required extreme points of the box. If not, + * the constraint is updated. + * \param[in] con The linear constraint that can be updated + * \param[in] x The variable x. + * \param[in] y The variable y. + * \param[in] rel The relaxation which contains the linear constraint + * \param[in] r_mods A vector into which the modifications are appended so + * that they can be reverted at a later time. + */ + void upSqCon_(ConstraintPtr con, VariablePtr x, VariablePtr y, + RelaxationPtr rel, ModVector &r_mods); + + /** + * \brief Tighten the bounds on variables of the original (or transformed) + * problem on the basis of the quadratic constraints y=x0^2 or y=x0x1. + * Usually called in the initial presolve. + * \param[out] changed True if any bounds are strengthened + * \return true if some bounds become inconsistent, making the problem + * infeasible. Flase otherwise. + */ + bool varBndsFromCons_(bool *changed); +}; + +/// Shared pointer to QuadHandler. +typedef boost::shared_ptr QuadHandlerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/QuadraticFunction.h b/thirdparty/linux/include/minotaur/QuadraticFunction.h new file mode 100644 index 0000000..5d8ec9b --- /dev/null +++ b/thirdparty/linux/include/minotaur/QuadraticFunction.h @@ -0,0 +1,291 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file QuadraticFunction.h + * \brief Construct and manage quadratic functions. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURQUADRATICFUNCTION_H +#define MINOTAURQUADRATICFUNCTION_H + +#include "Types.h" + +namespace Minotaur { + class LinearFunction; + struct LTHessStor; + class QuadraticFunction; + class PolynomialFunction; + class Variable; + typedef boost::shared_ptr QuadraticFunctionPtr; + typedef boost::shared_ptr ConstQuadraticFunctionPtr; + typedef boost::shared_ptr PolyFunPtr; + typedef boost::shared_ptr ConstLinearFunctionPtr; + typedef boost::shared_ptr LinearFunctionPtr; + typedef boost::shared_ptr VariablePtr; + + //class EigenVector; + //typedef boost::shared_ptr EigenVectorPtr; + //typedef std::pair EigenPair; + + class QuadraticFunction { + public: + /// Default constructor + QuadraticFunction(); + + /// Constructor for an array of values + QuadraticFunction(UInt nz, double *vals, UInt *irow, UInt *jcol, + VariableConstIterator vbeg ); + + /** + * Construct a quadratic function from a row major coefficient array + * representing symmetric matrix of size n x n and n variables. + */ + QuadraticFunction(double* vals, VariableConstIterator vbeg, + VariableConstIterator vend); + + /// Destroy + ~QuadraticFunction(); + + /** + * Copy the linear function. Variables and weights are copied. The weights + * in the clone and the original do not share the same space in memory. + */ + QuadraticFunctionPtr clone() const; + + QuadraticFunctionPtr cloneWithVars(VariableConstIterator vbeg) const; + + /** + * Add a term of the form a*x_i*x_j to the expression. We do not check + * if a similar term does not exist. + */ + void addTerm(VariablePair vp, const double weight); + + /** + * Add a term of the form a*x_i*x_j to the expression. We do not check + * if a similar term does not exist. + */ + void addTerm(ConstVariablePtr v1, ConstVariablePtr v2, double weight); + + double getFixVarOffset(VariablePtr v, double val); + + /** + * Add a term of the form a*x_i*x_j to the expression. If a similar term + * exists, it is incremented. If the new coefficient becomes zero, the + * term is dropped. + */ + void incTerm(ConstVariablePair vp, const double weight); + + /** + * Add a term of the form a*x_i*x_j to the expression. If a similar term + * exists, it is incremented. If the new coefficient becomes zero, the + * term is dropped. + */ + void incTerm(ConstVariablePtr v1, ConstVariablePtr v2, const double weight); + + /* + * Multiply by a constant. If constant is zero, all terms are removed. + */ + void mult(double c); + + /** + * Remove a variable v from the function. Add to lf any linear terms + * obtained by fixing the variable to the value 'val'. + */ + void removeVar(VariablePtr v, double val, LinearFunctionPtr lf); + + void subst(VariablePtr out, VariablePtr in, double rat); + + /** + * Add a quadratic function to this quadratic function. Terms that become + * zero are not retained in the function. + */ + friend QuadraticFunctionPtr operator + (ConstQuadraticFunctionPtr q1, + ConstQuadraticFunctionPtr q2); + + /** + * Subtract a linear function from this function. Terms that become zero + * are still retained in the function. + */ + friend QuadraticFunctionPtr operator-(ConstQuadraticFunctionPtr q1, + ConstQuadraticFunctionPtr q2); + + /// Multiply a quadratic function with a constant. + friend QuadraticFunctionPtr operator*(const double c, + ConstQuadraticFunctionPtr q2); + + /// Multiply a linear function and quadratic function. + friend PolyFunPtr operator*(ConstQuadraticFunctionPtr q2, + ConstLinearFunctionPtr l1); + + /// Multiply two quadratics + friend PolyFunPtr operator*(ConstQuadraticFunctionPtr q1, + ConstQuadraticFunctionPtr q2); + + + /** + * This increment operator is dangerous to use because it only works on + * objects of type QuadraticFunction and does not work on type + * QuadraticFunctionPtr. So if you have: + * + * QuadraticFunctionPtr qPtr, q2Ptr; + * + * Then you cannot do: + * + * qPtr += q2Ptr; + * + * You will have to do: + * + * (*qPtr) += q2Ptr; + * + * The user must check if the left operand is not NULL. + */ + void operator+=(ConstQuadraticFunctionPtr q2); + + /** + * Multiply the quadratic with a constant. Same precaution as for += + * operator above. If c is zero, then quadratic becomes empty. It is + * better for the calling routine to check if c is zero, if so, just + * delete the quadratic. + */ + void operator*=(const double c); + + /// Get the list of variables and how many times they occur + VarCountConstMap * getVarMap() const; + + /// Constant Iterators to visit all the quadratic terms: begin. + VariablePairGroupConstIterator begin() const { return(terms_.begin()); } + + /// Constant Iterators to visit all the quadratic terms: end. + VariablePairGroupConstIterator end() const { return(terms_.end()); } + + /** + * Get the coefficient of a term. Returns 0 if the term does not exist + * in the function. + */ + double getWeight(ConstVariablePair & vp) ; + + /** + * Get the coefficient of a term. Returns 0 if the term does not exist + * in the function. + */ + double getWeight(ConstVariablePtr v1, ConstVariablePtr v2) ; + + /// Get the number of times variable v1 occurs in quadratic terms. + int getFreq(ConstVariablePtr v1); + + /** + * \brief Check if function contains a variable. + * + * \param[in] v The variable that we want to test. + * \return True if this function is has v. False if it doesn't use it. + */ + bool hasVar(ConstVariablePtr v) const; + + /** + * Evaluate the value of this quadratic expression for a given point x. + * It is assumed that x[i] is the value of the variable whose + * var->getIndex() returns i. + */ + double eval(const std::vector &x) const; + + /** + * Evaluate the value of this quadratic expression for a given point x. + * It is assumed that x[i] is the value of the variable whose + * var->getIndex() returns i. + */ + double eval(const double *x) const; + + /** + * Evaluate the values of the gradient of the quadratic expression at a + * given point x. It is assumed that x[i] is the value of the variable + * whose var->getIndex() returns i. + */ + void evalGradient(const double *x, double *grad_f); + + /** + * Evaluate the values of the gradient of the quadratic expression at a + * given point x. It is assumed that x[i] is the value of the variable + * whose var->getIndex() returns i. + */ + void evalGradient(const std::vector &x, + std::vector &grad_f); + void evalHessian(const double mult, const double *x, + const LTHessStor *stor, double *values , int *error); + + void prepJac(VarSetConstIter vbeg, VarSetConstIter vend); + void prepHess(); + + void fillHessStor(LTHessStor *hess); + void fillJac(const double *x, double *values, int *error); + void finalHessStor(const LTHessStor *hess); + + /// Get the number of terms in this expression + UInt getNumTerms() const; + + /// Get the number of variables in this expression + UInt getNumVars() const; + + void getVars(VariableSet *vars); + + /** + * Return true if the quadratic expression always returns zero on + * evaluation. + */ + bool isZero() const { return (getNumTerms() == 0); } + + /// Iterate over the variables in the quadratic function: begin. + VarIntMapConstIterator varsBegin() const; + + /// Iterate over the variables in the quadratic function: end. + VarIntMapConstIterator varsEnd() const; + + /// Display the quadratic function + void write(std::ostream &s) const; + + private: + /// Tolerance below which a coefficient is deemed zero + const double etol_; + + double *hCoeffs_; + UInt *hFirst_; + UInt *hOff_; + UInt *hSecond_; + UIntVector hStarts_; + + UIntVector jacOff_; + UIntVector jacInd_; + + /** + * Each item in this map is a pair of a variable-pair and a + * weight. A variable pair is in turn a pair of two variables. + */ + VariablePairGroup terms_; + + /** + * Set of variables that are in this quadratic and in how many times + * do they occur. e.g. x0 occurs 4 times in: + * x0^2 + 2x0x1 + x0x3 + */ + VarIntMap varFreq_; + + void sortLT_(UInt n, UInt *f, UInt *s, double *c); + }; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/RandomBrancher.h b/thirdparty/linux/include/minotaur/RandomBrancher.h new file mode 100644 index 0000000..eb802fa --- /dev/null +++ b/thirdparty/linux/include/minotaur/RandomBrancher.h @@ -0,0 +1,86 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file RandomBrancher.h + * \brief Declare methods and data structures for Random branching. + * \author Suresh B, IIT Bombay + */ + + +#ifndef MINOTAURRANDOMBRANCHER_H +#define MINOTAURRANDOMBRANCHER_H + +#include "Brancher.h" + +namespace Minotaur { + + struct RandomBrStats { + UInt calls; /// Number of times called, to find a branching candidate. + double time; /// Total time spent in branching. + }; + + class Timer; + + /// A class to select random branching candidate from the available ones. + class RandomBrancher : public Brancher { + + public: + /// Default constructor. + RandomBrancher(); + + /// Construct with an environment. + RandomBrancher(EnvPtr env, HandlerVector handlers); + + /// Destroy. + ~RandomBrancher(); + + // Find a branching candidate. Returns NULL if x does not have any + // thing to branch on or if no branching candidates are needed. + Branches findBranches(RelaxationPtr rel, NodePtr node, + ConstSolutionPtr sol, SolutionPoolPtr s_pool, + BrancherStatus & br_status, ModVector &mods); + + // Write the statistics. + void writeStats(std::ostream &out) const; + + // Return name. + std::string getName() const; + + private: + /// Name + const static std::string me_; + + /// Log manager. + Logger* logger_; + + /// Handlers that provide branching candidates. + HandlerVector handlers_; + + /// Timer + Timer *timer_; + + /// Statistics. + RandomBrStats *stats_; + + /// Seed to random number generator + UInt seed_; + + }; + typedef boost::shared_ptr RandomBrancherPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Relaxation.h b/thirdparty/linux/include/minotaur/Relaxation.h new file mode 100644 index 0000000..1b060bb --- /dev/null +++ b/thirdparty/linux/include/minotaur/Relaxation.h @@ -0,0 +1,98 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Relaxation.h + * \brief Declare the class Relaxation for storing and manipulating + * relaxations. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURRELAXATION_H +#define MINOTAURRELAXATION_H + +#include "Problem.h" + +namespace Minotaur { + + +/** + * Relaxation is a derived class of Problem. A relaxation is what is + * actually solved at each iteration of an algorithm. + * + * A Relaxation need not be a relaxation of the original problem. It could + * be a relaxation of the problem being solved at a given node. Since a + * relaxation could be as big as the + * the original problem (and even much bigger), we should take care to have + * as few copies of a relaxation around as possible. + * + * A relaxation is created from a Problem by using Handlers. It is assumed + * that a Problem is in its standard form. Each constraint is relaxed by one + * or more handlers. A handler may break the constraint into two parts, + * adding a new variable to the relaxed problem. For instance: a constraint + * \f$x^2 + y^2 - z^2 \leq 5\f$ can be broken as \f$x^2 + y^2 - v \leq 0\f$, + * \f$-z^2 + w \leq 0\f$, \f$v - w \leq 5\f$. + * + * Besides having constraints, variables, functions, jacobians and hessians + * much like the Problem, a relaxation can have additional data structures + * that may be used to solve the problem, e.g. reduced costs, conflict + * graphs, implications, valid inequalities, symmetry groups etc. + * Typically one would input a Problem and ask Minotaur to solve it using, + * say, branch-and-bound. + * + * Since a Relaxation is obtained by reformulating the original Problem, it + * should thus have methods to translate and return the solution values of + * the variables of the original problem. It should also keep a pointer to + * the original Problem from which it is derived. Some information stored in + * a relaxation may be global, i.e. valid for the original problem. Other + * information may be local, i.e. valid for the current iteration of + * branch-and-bound only. + */ +class Relaxation : public Problem { + +public: + /// Default constructor. + Relaxation(); + + /** + * Construct a relaxation from an Problem. In the default + * implementation, as many new variables and + * constraints as in the Problem are created. If nonlinear function can't be + * cloned, their pointers are saved. Everything else in the constraint + * (bounds, sense, map etc.) are copied. + */ + Relaxation(ProblemPtr problem); + + /// Destructor. No need yet. Use ~Problem(). + ~Relaxation() {}; + + VariablePtr getOriginalVar(VariablePtr r_var); + + VariablePtr getRelaxationVar(VariablePtr p_var); + + void setProblem(ProblemPtr p); + +protected: + /// Pointer to the original problem. + ConstProblemPtr p_; +}; + +typedef boost::shared_ptr RelaxationPtr; +typedef boost::shared_ptr ConstRelaxationPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/ReliabilityBrancher.h b/thirdparty/linux/include/minotaur/ReliabilityBrancher.h new file mode 100644 index 0000000..57b8f35 --- /dev/null +++ b/thirdparty/linux/include/minotaur/ReliabilityBrancher.h @@ -0,0 +1,353 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file ReliabilityBrancher.h + * \brief Declare methods and data structures for reliability branching. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURRELIABILITYBRANCHER_H +#define MINOTAURRELIABILITYBRANCHER_H + +#include "Brancher.h" + +namespace Minotaur { + +class Engine; +class Timer; +typedef boost::shared_ptr EnginePtr; + +struct RelBrStats { + UInt bndChange; /// Number of times variable bounds were changed. + UInt calls; /// Number of times called to find a branching candidate. + UInt engProbs; /// Number of times called to find a branching candidate. + UInt iters; /// Number of iterations in strong-branching. + UInt strBrCalls; /// Number of times strong branching on a variable. + double strTime; /// Total time spent in strong-branching. +}; + + +/// A class to select a variable for branching using reliability branching. +class ReliabilityBrancher : public Brancher { + +public: + /** + * \brief Construct using an environment pointer and handlers. + * \param [in] env Environment from which options etc. are obtained. + * \param [in] handlers Array of handlers which are used to obtain branching + * candidates and modifications. This array can not be changed while + * branch-and-bound is running. + */ + ReliabilityBrancher(EnvPtr env, HandlerVector & handlers); + + /// Destroy. + ~ReliabilityBrancher(); + + // base class function. + Branches findBranches(RelaxationPtr rel, NodePtr node, + ConstSolutionPtr sol, SolutionPoolPtr s_pool, + BrancherStatus & br_status, ModVector &mods); + + /// Return value of trustCutoff parameter. + bool getTrustCutoff(); + + /// Get iteration limit of engine. + UInt getIterLim(); + + // base class function. + std::string getName() const; + + /// Return the threshhold value. + UInt getThresh() const; + + /** + * \brief Initialize data structures. + * + * \param[in] rel Relaxation for which this brancher is used. + */ + void initialize(RelaxationPtr rel); + + /// Set value of trustCutoff parameter. + void setTrustCutoff(bool val); + + /** + * \brief Set engine. + * + * \param[in] engine Pointer to the engine used in strong branching. + */ + void setEngine(EnginePtr engine); + + /** + * \brief Set iteration limit of engine. + * + * \param [in] k The new iteration limit. + */ + void setIterLim(UInt k); + + /** + * \brief Set the depth at which we stop strong branching. + * + * \param[in] k The new depth value. + */ + void setMaxDepth(UInt k); + + /** + * \brief Don't do strong branching on a cand if we did it 'k' nodes + * or less ago. + * \param[in] k The new minimum value. + */ + void setMinNodeDist(UInt k); + + /** + * \brief Set reliability threshhold + * + * The pseudo cost is considered reliable if it has been updated k + * times. + * \param[in] k The new threshhold value. + */ + void setThresh(UInt k); + + // base class function. + void updateAfterLP(NodePtr node, ConstSolutionPtr sol); + + /// Write statistics. + void writeStats(std::ostream &out) const; + +private: + + /** + * \brief Find the variable that was selected for branching. + * + * This method can also find modifications based upon the + * results of strong branching. + * \param[in] objval Optimal objective value of the current relaxation. + * \param[in] cutoff The cutoff value for objective function (an upper + * bound). + * \param[in] node The node at which we are branching. + */ + BrCandPtr findBestCandidate_(const double objval, double cutoff, + NodePtr node); + + /** + * \brief Find and sort candidates for branching. + * + * Fills up the set of candidates in the cands_ array. + * The candidates have fractional values and + * are sorted by the min(timesUp_[i], timesDown_[i]). The variables after + * last_strong in the cands_ vector do not need any further strong + * branching. + */ + void findCandidates_(); + + /** + * \brief Find the score of a candidate based on its pseudo costs. + * + * \param[in] cand The branching candidate for which score is needed. + * \param[in] ch_down The down score + * \param[in] ch_up The up score. + * \param[out] score The total score returned by this function. + */ + void getPCScore_(BrCandPtr cand, double *ch_down, double *ch_up, + double *score); + + /** + * \brief Calculate score from the up score and down score. + * + * \param[in] up_score Up score. + * \param[in] down_score Down score. + */ + double getScore_(const double & up_score, const double & down_score); + + /** + * \brief Check if branch can be pruned on the basis of engine status and + * objective value. + * + * Check status and tell if we can prune the branch. is_rel is false if + * the engine reports failure in convergence. + * \param[in] chcutoff The minimum change in objective that will lead to + * cutoff. A change greater than this value will exceed the + * objective-cutoff. + * \param[in] change The observed change in the objective function value. + * \param[in] status Solve status of the engine. + * \param[out] is_rel True if the engine status is reliable enough to use + * the solution value as a reliable bound. + */ + bool shouldPrune_(const double &chcutoff, const double &change, + const EngineStatus & status, bool *is_rel); + + /** + * \brief Do strong branching on candidate. + * \param[in] cand Candidate for strong branching. + * \param[out] obj_up objective value estimate in up branch. + * \param[out] obj_down objective value estimate in down branch. + * \param[out] status_up engine status in up branch. + * \param[out] status_down engine status in down branch. + */ + void strongBranch_(BrCandPtr cand, double & obj_up, double & obj_down, + EngineStatus & status_up, EngineStatus & status_down); + + /** + * \brief Update Pseudocost based on the new costs. + * + * \param[in] i Index of the candidate. + * \param[in] new_cost The new cost estimate. + * \param[in] cost The vector of costs of all candidates. cost[i] is to + * be updated + * \param[in] count The vector that keeps a cound of how many times cost + * has been updated for each candidate. + */ + void updatePCost_(const int &i, const double &new_cost, + DoubleVector &cost, UIntVector &count); + + /** + * \brief Analyze the strong-branching results. + * + * \param[in] cand Candidate for which we performed strong branching. + * \param[in] chcutoff The minimum change in objective function value that + * will result in cutoff. + * \param[in,out] change_up Change observed in the objective function value + * in the up branch. It is modified if the engine status is error or + * unknown. + * \param[in,out] change_down Change observed in the objective function + * value in the down branch. It is modified if the engine status is error or + * unknown. + * \param[in] status_up The engine status in up branch. + * \param[in] status_down The engine status in up branch. + */ + void useStrongBranchInfo_(BrCandPtr cand, const double & chcutoff, + double & change_up, double & change_down, + const EngineStatus & status_up, + const EngineStatus & status_down); + + /** + * \brief Display score details of the candidate. + * + * \param[in] cand Candidate + * \param[in] score Score of candidate. + * \param[in] change_up Up change. + * \param[in] change_down Down change. + */ + void writeScore_(BrCandPtr cand, double score, double change_up, + double change_down); + + /** + * \brief Display scores of unreliable candidates and pseudo-costs of reliable + * ones. + * + * \param[in] out Outstream where scores are displayed. + */ + void writeScores_(std::ostream &out); + + /// The engine used for strong branching. + EnginePtr engine_; + + /// Tolerance for avoiding division by zero. + const double eTol_; + + /** + * \brief Handlers that will be used to find candidates and the relaxations + * after branching. + */ + HandlerVector handlers_; + + /// True if data structures initialized. False otherwise. + bool init_; + + /// When did we last strong-branch on a candidate. + UIntVector lastStrBranched_; + + /// If the depth of a node is greater than maxDepth_, then don't do any + /// strong brancing. + UInt maxDepth_; + + /** + * \brief Maximum number of iterations to be performed in each call to the + * engine. + */ + UInt maxIterations_; + + /** + * \brief Do not strong-branch on more than these many candidates + */ + UInt maxStrongCands_; + + /// Name. + const static std::string me_; + + /** + * \brief Don't do strong branching on a cand if we did it 'k' nodes + * or less ago. + */ + UInt minNodeDist_; + + /// Modifications that can be applied to the problem. + ModVector mods_; + + /// Vector of pseudocosts for rounding down. + DoubleVector pseudoDown_; + + /// Vector of pseudocosts for rounding up. + DoubleVector pseudoUp_; + + /// The problem that is being solved at this node. + RelaxationPtr rel_; + + /// A vector of candidates that have reliable pseudocosts. + std::vector relCands_; + + /// Statistics. + RelBrStats * stats_; + + /// Status of problem after using this brancher. + BrancherStatus status_; + + /// Timer to track time spent in this class. + Timer *timer_; + + /** + * \brief Number of times we have branched down and noted the effect on + * objective improvement. + */ + UIntVector timesDown_; + + /** + * \brief Number of times we have branched up and noted the effect on objective + * improvement. + */ + UIntVector timesUp_; + + /// How many times before we assume that the pseudo costs are reliable. + UInt thresh_; + + /// Should we use the objective value to deduce a modification. + bool trustCutoff_; + + /** + * \brief A vector of candidates that will need strong branching. These + * candidates will be arranged in some order of preferance. + */ + std::vector unrelCands_; + + /// The values of variables in the solution of the current relaxation. + DoubleVector x_; + +}; +typedef boost::shared_ptr ReliabilityBrancherPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/SOS.h b/thirdparty/linux/include/minotaur/SOS.h new file mode 100644 index 0000000..40a257c --- /dev/null +++ b/thirdparty/linux/include/minotaur/SOS.h @@ -0,0 +1,80 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + + +/** + * \file SOS.h + * \brief Declare data structures for an SOS-I and SOS-II constraint + * \author Ashutosh Mahajan, IIT Bombay + */ + +#ifndef MINOTAURSOS_H +#define MINOTAURSOS_H + +#include "Types.h" +#include "Variable.h" + +namespace Minotaur { + + +class SOS { +public: + /// Default constructor + SOS(); + + SOS(int n, SOSType type, const double *weights, const VarVector &vars, + int priority, int id, std::string name); + + /// Destroy + virtual ~SOS(); + + int getId() const; + int getNz(); + SOSType getType(); + int getPriority() const; + + std::string getName() const; + const double* getWeights(); + + VariableConstIterator varsBegin() const; + VariableConstIterator varsEnd() const; + +private: + /// Index within the problem. + int id_; + + /// Number of elements in the SOS + int n_; + + /// Priority of this SOS over others. + int priority_; + + /// \brief Type of SOS + SOSType type_; + + /// Values + double * weights_; + + /// Vector of variables. + VarVector vars_; + + /// Name of the sos-constraint + std::string name_; + +}; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/SOS1Handler.h b/thirdparty/linux/include/minotaur/SOS1Handler.h new file mode 100644 index 0000000..ba2c553 --- /dev/null +++ b/thirdparty/linux/include/minotaur/SOS1Handler.h @@ -0,0 +1,135 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file SOS1Handler.h + * \brief Declare the SOS1Handler class for handling SOS type I constraints. + * It checks integrality and provides branching candidates. Does + * not do any presolving and cut-generation. + * \author Ashutosh Mahajan, IIT Bombay + */ + +#ifndef MINOTAURSOS1HANDLER_H +#define MINOTAURSOS1HANDLER_H + +#include "Handler.h" + +namespace Minotaur { + +/** + * SOS1Handler class considers all SOS Type 1 constraints in the problem. + * It does not implement separate() function. Implements functions for + * checking feasibility and branching. + */ +class SOS1Handler : public Handler { +public: + + /// Default constructor. + SOS1Handler(); + + /// Constructor. + SOS1Handler(EnvPtr env, ProblemPtr problem); + + /// Destroy. + ~SOS1Handler(); + + // Does nothing. + void relaxInitFull(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxInitInc(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf); + + // Check if solution is feasible. + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool &should_prune, double &inf_meas); + + /// Empty method as we do not do any separation in SOS1. + void separate(ConstSolutionPtr, NodePtr , RelaxationPtr, CutManager *, + SolutionPoolPtr, bool *, SeparationStatus *); + + // Base class method. + void getBranchingCandidates(RelaxationPtr rel, const DoubleVector &x, + ModVector & mods, BrVarCandSet &cands, + BrCandVector &gencands, bool & is_inf); + + // Base class method. + ModificationPtr getBrMod(BrCandPtr cand, DoubleVector &x, + RelaxationPtr rel, BranchDirection dir); + + // Base class method. + Branches getBranches(BrCandPtr cand, DoubleVector & x, + RelaxationPtr rel, SolutionPoolPtr s_pool); + + bool isGUB(SOS *sos); + bool isNeeded(); + + /// Presolve. Do not do any presolving. + SolveStatus presolve(PreModQ *, bool *) {return Finished;}; + + /// Does nothing. + void postsolveGetX(const double *, UInt, DoubleVector *); + + /// Does nothing. + bool presolveNode(RelaxationPtr, NodePtr, SolutionPoolPtr, ModVector &, + ModVector &) + {return false;}; + + // Write name + std::string getName() const; + + void getNzNumSum_(SOSPtr sos, const DoubleVector x, int *nz, + double *nzsum); + + /// Does nothing. + void writePreStats(std::ostream &) const {}; + + /// Return the integer tolerance. + double getTol() const; + + /// Set the integer tolerance. + void setTol(double tol); + +private: + /// Environment. + EnvPtr env_; + + /// Log + LoggerPtr logger_; + + /// For log: + static const std::string me_; + + /// The problem for which the handler was created. + ProblemPtr problem_; + + /** + * \brief Tolerance for checking integrality. + * + * If abs(x) < zTol_, then it is considered to be zero. + */ + double zTol_; +}; +typedef boost::shared_ptr SOS1HandlerPtr; +typedef boost::shared_ptr ConstSOS1HandlerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/SOS2Handler.h b/thirdparty/linux/include/minotaur/SOS2Handler.h new file mode 100644 index 0000000..8651f37 --- /dev/null +++ b/thirdparty/linux/include/minotaur/SOS2Handler.h @@ -0,0 +1,143 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file SOS2Handler.h + * \brief Declare the SOS2Handler class for handling SOS type II constraints. + * It checks integrality and provides branching candidates. Does + * not do any presolving and cut-generation. + * \author Ashutosh Mahajan, IIT Bombay + */ + +#ifndef MINOTAURSOS2HANDLER_H +#define MINOTAURSOS2HANDLER_H + +#include "Handler.h" + +namespace Minotaur { + +/** + * SOS2Handler class considers all SOS Type 2 constraints in the problem. + * It does not implement separate() function. Implements functions for + * checking feasibility and branching. + */ +class SOS2Handler : public Handler { +public: + + /// Default constructor. + SOS2Handler(); + + /// Constructor. + SOS2Handler(EnvPtr env, ProblemPtr problem); + + /// Destroy. + ~SOS2Handler(); + + // Does nothing. + void relaxInitFull(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxInitInc(RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeFull(NodePtr node, RelaxationPtr rel, bool *is_inf); + + // Does nothing. + void relaxNodeInc(NodePtr node, RelaxationPtr rel, bool *is_inf); + + // Check if solution is feasible. + bool isFeasible(ConstSolutionPtr sol, RelaxationPtr relaxation, + bool &should_prune, double &inf_meas); + + /// Empty method as we do not do any separation in SOS1. + void separate(ConstSolutionPtr, NodePtr , RelaxationPtr, CutManager *, + SolutionPoolPtr, bool *, SeparationStatus *); + + // Base class method. + void getBranchingCandidates(RelaxationPtr rel, const DoubleVector &x, + ModVector & mods, BrVarCandSet &cands, + BrCandVector &gencands, bool & is_inf); + + // Base class method. + ModificationPtr getBrMod(BrCandPtr cand, DoubleVector &x, + RelaxationPtr rel, BranchDirection dir); + + // Base class method. + Branches getBranches(BrCandPtr cand, DoubleVector & x, + RelaxationPtr rel, SolutionPoolPtr s_pool); + + bool isNeeded(); + + /// Presolve. Do not do any presolving. + SolveStatus presolve(PreModQ *, bool *) {return Finished;}; + + /// Does nothing. + void postsolveGetX(const double *, UInt, DoubleVector *); + + /// Does nothing. + bool presolveNode(RelaxationPtr, NodePtr, SolutionPoolPtr, ModVector &, + ModVector &) + {return false;}; + + // Write name + std::string getName() const; + + void getNzNumSum_(SOSPtr sos, const DoubleVector x, int *nz, + double *nzsum); + + /// Does nothing. + void writePreStats(std::ostream &) const {}; + + /// Return the integer tolerance. + double getTol() const; + + /// Set the integer tolerance. + void setTol(double tol); + +private: + /// Environment. + EnvPtr env_; + + /// Log + LoggerPtr logger_; + + /// For log: + static const std::string me_; + + /// The problem for which the handler was created. + ProblemPtr problem_; + + /** + * \brief Tolerance for checking integrality. + * + * If abs(x) < zTol_, then it is considered to be zero. + */ + double zTol_; + + void getNzAvgWt_(SOSPtr sos, const DoubleVector x, + const double *weights, int *nz, double *avgwt); + + void getSumN_(SOSPtr sos, const DoubleVector &x, double *sum, int *nnz, + int *nv, int *nspos); + + bool isXFeasible_(const double *x, SOSPtr sos); + +}; +typedef boost::shared_ptr SOS2HandlerPtr; +typedef boost::shared_ptr ConstSOS2HandlerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/SOSBrCand.h b/thirdparty/linux/include/minotaur/SOSBrCand.h new file mode 100644 index 0000000..76367e9 --- /dev/null +++ b/thirdparty/linux/include/minotaur/SOSBrCand.h @@ -0,0 +1,88 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file SOSBrCand.h + * \author Ashutosh Mahajan, IIT Bombay + * \brief Declare the classes SOSBrCand for storing candidates for branching + * based upon SOS constraints. + */ + +#ifndef MINOTAURSOSBRCAND_H +#define MINOTAURSOSBRCAND_H + +#include +#include "Types.h" +#include "BrCand.h" + +namespace Minotaur { + +class SOS; + +/** + * \brief Derived class of BrCand, it defines candidates for branching on + * bounds SOS type 1 and 2 constraints. + */ +class SOSBrCand : public BrCand { +public: + /// Constructor. + SOSBrCand(); + SOSBrCand(const SOS* sos, VarVector &left, VarVector &right, double lsum, + double rsum); + + /// Destroy. + ~SOSBrCand(); + + // base class method. + double getDDist(); + + double getLSum() const; + + // base class method. + std::string getName() const; + + double getRSum() const; + + // base class method. + double getUDist(); + + VariableConstIterator lVarsBegin() const; + + VariableConstIterator lVarsEnd() const; + + VariableConstIterator rVarsBegin() const; + + VariableConstIterator rVarsEnd() const; + + +private: + /// Left branch + VarVector lvars_; + + /// Right branch + VarVector rvars_; + + double lsum_; + double rsum_; + + const SOS* sos_; +}; + +typedef boost::shared_ptr SOSBrCandPtr; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/SecantMod.h b/thirdparty/linux/include/minotaur/SecantMod.h new file mode 100644 index 0000000..c9c50f6 --- /dev/null +++ b/thirdparty/linux/include/minotaur/SecantMod.h @@ -0,0 +1,88 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Problem.h + * \brief Declare the derived class SecantMod for modifications associated + * with a secant. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + +#ifndef MINOTAURLINCONSTRMOD_H +#define MINOTAURLINCONSTRMOD_H + +#include "LinearFunction.h" +#include "LinConMod.h" +#include "VarBoundMod.h" + +namespace Minotaur { + + class SecantMod; + typedef boost::shared_ptr SecantModPtr; + typedef boost::shared_ptr ConstSecantModPtr; + + /// Modification of a single linear constraint and its upper bound. An old + /// constraint: + // + /// nlf + qf + lf <= ub + /// + /// is changed to: + /// + /// nlf + qf + new_lf <= new_ub + /// + class SecantMod : public Modification { + public: + /// Construct. + SecantMod(ConstraintPtr con, LinearFunctionPtr new_lf, double new_rhs, + VariablePtr x, BoundType lu, double new_b, VariablePtr y); + + /// Destroy. + ~SecantMod(); + + // Implement Modification::applyToProblem() + void applyToProblem(ProblemPtr problem); + + // base class method. + ModificationPtr toRel(ProblemPtr, RelaxationPtr) const + {return SecantModPtr();}; + + // base class method. + ModificationPtr fromRel(RelaxationPtr, ProblemPtr) const + {return SecantModPtr();}; + + // Implement Modification::undoToProblem() + void undoToProblem(ProblemPtr problem); + + /// Get the auxiliary variable or variable y where \f$y <= x^2\f$. + VariablePtr getY(); + + // Implement Modification::write() + void write(std::ostream &) const {}; + + private: + /// Changes in linear function in con_ + LinConModPtr lmod_; + + /// Bound changes on x. + VarBoundModPtr xmod_; + + /// Bound changes on y. + VarBoundMod2Ptr ymod_; + }; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/SimpleCutMan.h b/thirdparty/linux/include/minotaur/SimpleCutMan.h new file mode 100644 index 0000000..cab0664 --- /dev/null +++ b/thirdparty/linux/include/minotaur/SimpleCutMan.h @@ -0,0 +1,131 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2010 - 2014 The MINOTAUR Team. +// + +/** + * \file SimpleCutMan.h + * \brief Very simple implementation of a cut manager. + * \author Ashutosh Mahajan, IIT Bombay + */ + +#ifndef MINOTAURSIMPLECUTMAN_H +#define MINOTAURSIMPLECUTMAN_H + +#include +#include "CutManager.h" +#include "Types.h" + + +namespace Minotaur { + + /** + * \brief Derived class for managing cuts. Adds all violated cuts from the + * storage to the relaxation and never removes any. If a new cut is reported + * but not violated by the current solution then it is added to storage. + * This manager does not check for duplicacy or any other numerical problems + * in cuts. + */ + class SimpleCutMan : public CutManager { + + public: + /// Empty constructor. + SimpleCutMan(); + + /** + * \brief Default constructor. + * + * \param [in] env Minotaur Environment pointer. + * \param [in] p Problem pointer to which cuts will be added or deleted. + */ + SimpleCutMan(EnvPtr env, ProblemPtr p); + + /// Destroy. + ~SimpleCutMan(); + + // Base class method. + void addCut(CutPtr c); + + // Base class method. + ConstraintPtr addCut(ProblemPtr p, FunctionPtr f, double lb, + double ub, bool directToRel, bool neverDelete); + + // Base class method. + void addCuts(CutVectorIter cbeg, CutVectorIter cend); + + // Base class method. + UInt getNumCuts() const; + + // Base class method. + UInt getNumEnabledCuts() const; + + // Base class method. + UInt getNumDisabledCuts() const; + + // Base class method. + UInt getNumNewCuts() const; + + // Base class method. + void postSolveUpdate(ConstSolutionPtr sol, EngineStatus eng_status); + + // Base class method. + void separate(ProblemPtr p, ConstSolutionPtr sol, bool *separated, + UInt *added); + + // Base class method. + void write(std::ostream &out) const; + + // Base class method. + void writeStats(std::ostream &out) const; + + private: + /// Cuts already in the relaxation. + UInt enCuts_; + + /// Environment. + EnvPtr env_; + + /// For logging. + LoggerPtr logger_; + + /// For logging. + const static std::string me_; + + /** + * Cut storage for new cuts, i.e. those sent to pool after previous + * separate or postSolveUpdate(). + */ + CutList newCuts_; + + /// The relaxation problem that cuts are added to and deleted from. + ProblemPtr p_; + + /// Pool of cuts that were left unviolated. They may be added in the future. + CutList pool_; + + /// A cut will be added only if the violation exceeds violAbs_. + double violAbs_; + + /// A cut will be added only if the violation exceeds absolute + /// value of the the activity times the violRel_. + double violRel_; + + /// Append the newCuts_ to pool_ and clear newCuts_. + void mvNewToPool_(); + }; + +//typedef boost::shared_ptr CutManagerPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/SimpleTransformer.h b/thirdparty/linux/include/minotaur/SimpleTransformer.h new file mode 100644 index 0000000..c1be1d7 --- /dev/null +++ b/thirdparty/linux/include/minotaur/SimpleTransformer.h @@ -0,0 +1,140 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file SimpleTransformer.h + * \brief Declare class for simple transformation of problem. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURSIMPLETRANSFORMER_H +#define MINOTAURSIMPLETRANSFORMER_H + +#include "Types.h" +#include "Transformer.h" + +namespace Minotaur { + class CxUnivarHandler; + class CGraph; + class CNode; + class Environment; + class LinearHandler; + class Problem; + class QuadHandler; + class Solution; + class YEqCGs; + class YEqLFs; + class YEqVars; + typedef boost::shared_ptr CxUnivarHandlerPtr; + typedef boost::shared_ptr CGraphPtr; + typedef boost::shared_ptr EnvPtr; + typedef boost::shared_ptr LinearHandlerPtr; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr QuadHandlerPtr; + typedef boost::shared_ptr SolutionPtr; + typedef boost::shared_ptr ConstSolutionPtr; + + + /** + * \brief Class for reformulating a problem using simple rules so that + * handlers can be applied to it. + * + * No multilinear terms are created. QuadHandler is used only for terms + * \f$y=x_1x_2\f$. Squares etc. are handled by PowerHandler. ExpHandler + * takes care of exponential functions, and LogHandler handles logarithms. + * TrigHandler is used for trigonometric functions. Mainly used to teach + * Ashu some global optimization. + */ + class SimpleTransformer : public Transformer { + public: + + /// Default Constructor. + SimpleTransformer(); + + /// Constructor. + SimpleTransformer(EnvPtr env, ConstProblemPtr p); + + /// Destroy. + ~SimpleTransformer(); + + // base class method. + std::string getName() const; + + // base class method. + SolutionPtr getSolOrig(ConstSolutionPtr sol, int &err); + + // base class method. + SolutionPtr getSolTrans(ConstSolutionPtr sol, int &err); + + // base class method. + void reformulate(ProblemPtr &newp, HandlerVector &handlers, int &status); + + + private: + static const std::string me_; + + YEqCGs *yBiVars_; + + void absRef_(LinearFunctionPtr lfl, VariablePtr vl, double dl, + VariablePtr &v, double &d); + + void bilRef_(LinearFunctionPtr lfl, VariablePtr vl, double dl, + LinearFunctionPtr lfr, VariablePtr vr, double dr, + LinearFunctionPtr &lf, VariablePtr &v, double &d); + + VariablePtr newBilVar_(VariablePtr vl, VariablePtr vr); + + void powKRef_(LinearFunctionPtr lfl, + VariablePtr vl, double dl, double k, + LinearFunctionPtr &lf, VariablePtr &v, + double &d); + + /** + * \brief Reformulate the nonlinear constraints of the problem. + * + * \param [in] oldp Original problem. + */ + void refNonlinCons_(ConstProblemPtr oldp); + + /** + * \brief Reformulate the nonlinear objective of the problem. + * + * \param [in] oldp Original problem. + */ + void refNonlinObj_(ConstProblemPtr oldp); + + /** + * TODO + */ + void recursRef_(const CNode *node, LinearFunctionPtr &lf, VariablePtr &v, + double &d); + + void trigRef_(OpCode op, LinearFunctionPtr lfl, VariablePtr vl, + double dl, VariablePtr &v, double &d); + + void uniVarRef_(const CNode *n0, LinearFunctionPtr lfl, + VariablePtr vl, double dl, + LinearFunctionPtr &lf, VariablePtr &v, double &d); + + }; + typedef boost::shared_ptr SimpTranPtr; + typedef boost::shared_ptr ConstSimpTranPtr; + +} + +#endif + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Solution.h b/thirdparty/linux/include/minotaur/Solution.h new file mode 100644 index 0000000..b5c2005 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Solution.h @@ -0,0 +1,128 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Solution.h + * \brief Define base class Solution. + * \author Ashutosh Mahajan, Argonne National Laboratory + * + * Define the base class Solution. + */ + + +#ifndef MINOTAURSOLUTION_H +#define MINOTAURSOLUTION_H + +#include "Types.h" + +namespace Minotaur { + + class Solution; + typedef boost::shared_ptr SolutionPtr; + typedef boost::shared_ptr ConstSolutionPtr; + typedef std::vector SolutionPtrVector; + typedef std::vector::iterator SolutionIterator; + class Problem; + typedef boost::shared_ptr ProblemPtr; + + class Solution { + + public: + /// Default constructor. + Solution(); + + /// Construct a solution for a problem from an array of doubles. + Solution(double objval, const double *x, ProblemPtr problem); + + /// Construct a solution for a problem from a vector of doubles. + Solution(double objvalue, const DoubleVector &newx, + ProblemPtr problem); + + /// Copy. + Solution(ConstSolutionPtr sol); + + /// Destroy. + virtual ~Solution(); + + /// Copy values of variables. + virtual void setPrimal(const double *x); + + /// Copy values of dual variables of constraints. + virtual void setDualOfCons(const double *vals); + + /// Copy values of dual variables of variables. + virtual void setDualOfVars(const double *vals); + + /// Set a new solution value. + virtual void setObjValue(double new_val) {objValue_ = new_val;}; + + /// Return solution value. + virtual double getObjValue() const {return objValue_;}; + + /// Return the 2nd norm of constraint violations. + virtual double getConstraintViolation() {return consViol_;}; + + /// Return a pointer to the solution. + virtual const double * getPrimal() const {return x_;}; + + /// Return a pointer to the solution. + virtual const double * getDualOfCons() const {return dualCons_;}; + + /// Return a pointer to the solution. + virtual const double * getDualOfVars() const {return dualX_;}; + + /// Write to a stream. + virtual void write(std::ostream &out) const; + + /// Write primal values to a stream. + virtual void writePrimal(std::ostream &out, const VarVector *v=0) const; + + /// Write dual values to a stream. + virtual void writeDual(std::ostream &out) const; + + protected: + /// Number of variables. + UInt n_; + + /// Number of constraints. + UInt m_; + + /// Original problem (For accessing variable names). + ProblemPtr problem_; + + /// Store values of the variables in an array. + double *x_; + + /// Store values of the dual variables associated with constraints + /// in an array. + double *dualCons_; + + /// Store values of the dual variables associated with bounds on variables + /// in an array. + double *dualX_; + + /// Violation. + double consViol_; + + /// The objective value of this solution. + double objValue_; + + /// Complementarity. + double comple_; + }; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/SolutionPool.h b/thirdparty/linux/include/minotaur/SolutionPool.h new file mode 100644 index 0000000..a11993c --- /dev/null +++ b/thirdparty/linux/include/minotaur/SolutionPool.h @@ -0,0 +1,117 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file SolutionPool.h + * \brief Declare a container for storing solutions and their qualities. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + + + +#ifndef MINOTAURSOLUTIONPOOL_H +#define MINOTAURSOLUTIONPOOL_H + +#include "Problem.h" +#include "Solution.h" + +namespace Minotaur { + + class Environment; + class Timer; + typedef boost::shared_ptr EnvPtr; + + class SolutionPool { + public: + /// Default constructor. + SolutionPool(); + + /// Construct a solution pool of a given size for a given problem + SolutionPool(EnvPtr env, ProblemPtr problem, UInt limit=100); + + /// Add Solution to the pool + void addSolution(ConstSolutionPtr); + + /// Get number of solutions in the pool + UInt getNumSols() const; + + /// Get number of solutions in the pool + UInt getNumSolsFound() const; + + /// Get the limit on the number of solutions in the pool + UInt getSizeLimit() const; + + /// Put a limit on the number of solutions in the pool + void setSizeLimit(UInt limit); + + /// Get iterator for the first solution ... + SolutionIterator solsBegin() { return sols_.begin(); } + + /// ... and the end. + SolutionIterator solsEnd() { return sols_.end(); } + + /// Create a solution from a double array and add Solution to the pool. + void addSolution(const double *x, double obj_value); + + /** + * Get a solution with the best objective function value. Return NULL if + * the pool is empty. + */ + SolutionPtr getBestSolution(); + + /// Get the best objective function value + double getBestSolutionValue() const; + + /// Write statistics to the outstream. + void writeStats(std::ostream &out) const; + + private: + /// The solutions are stored in a vector. + std::vector sols_; + + /** + * The best solution in terms of objective function value. In case of tie, + * the most recently found one. + */ + SolutionPtr bestSolution_; + + /// For logging. + const static std::string me_; + + /// The number of solutions added to the pool. + UInt numSolsFound_; + + /// Problem for which we are saving solutions + ProblemPtr problem_; + + /// The limit on number of solutions in the pool. + UInt sizeLimit_; + + /// Time when the best solution is found. + double timeBest_; + + /// Time when the first solution is found. + double timeFirst_; + + /// Global timer. + const Timer* timer_; + + }; + + typedef boost::shared_ptr SolutionPoolPtr; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Timer.h b/thirdparty/linux/include/minotaur/Timer.h new file mode 100644 index 0000000..7d67da3 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Timer.h @@ -0,0 +1,185 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Timer.h + * \brief Define the TimerFactory and varios Timer classes + * \author Todd Munson, Argonne National Laboratory + */ + + +#ifndef MINOTAURTIMER_H +#define MINOTAURTIMER_H + +#include + +#ifndef CLOCKS_PER_SEC +# define CLOCKS_PER_SEC 1000000 +#endif + +#ifdef MINOTAUR_RUSAGE +# include + +# ifndef MICROSEC +# define MICROSEC 1000000 +# endif +#endif + +#include "Types.h" + +namespace Minotaur { + /** + * The Timer class is used to measure time. A Timer can be queried only + * after starting and before stopping it. A Timer should always be + * generated through the TimerFactory::GetTimer() method because different + * machines may need different types of timers. + */ + class Timer { + public: + Timer() { }; + virtual ~Timer() { }; + + virtual void start() = 0; + virtual void stop() = 0; + virtual double query() const = 0; + + private: + Timer (const Timer &); + Timer & operator = (const Timer &); + }; + + /** + * The default timer when getruage() function is not defined. Uses clock() + * to get time. + */ + class ClockTimer : public Timer { + private: + clock_t s_; + bool is_started_; + + public: + ClockTimer() : is_started_(false) { }; + ~ClockTimer() { }; + + /// Start the timer. + void start() { + s_ = clock(); + is_started_ = true; + return; + }; + + /// Stop the timer. Can not query after this. + void stop() { + is_started_ = false; + return; + }; + + double query() const { + if (!is_started_) { + throw("Some exception"); + } + + return ((clock() - s_) / (double) CLOCKS_PER_SEC); + }; + }; + +#ifdef MINOTAUR_RUSAGE + /** + * The default timer when getruage() function is avaialble. Uses rusage + * structure to get time. + */ + class UsageTimer : public Timer { + private: + struct rusage s_; + bool is_started_; + + public: + UsageTimer() : is_started_(false) { }; + ~UsageTimer() { }; + + /// Start the timer. + void start() { + getrusage(RUSAGE_SELF, &s_); + is_started_ = true; + return; + }; + + /// Stop the timer. Can not query after this. + void stop() { + is_started_ = false; + return; + }; + + /// Get how much cpu time has been used since this timer was started. + double query() const { + double t1, t2, m1, m2, s1, s2, m, s; + struct rusage e; + if (!is_started_) { + throw("Some exception"); + } + getrusage(RUSAGE_SELF, &e); + + m1 = (double) e.ru_utime.tv_usec; + m2 = (double) s_.ru_utime.tv_usec; + m = m1 - m2; + + s1 = (double) e.ru_utime.tv_sec; + s2 = (double) s_.ru_utime.tv_sec; + s = s1 - s2; + + t1 = s + m / MICROSEC; + + m1 = (double) e.ru_stime.tv_usec; + m2 = (double) s_.ru_stime.tv_usec; + m = m1 - m2; + + s1 = (double) e.ru_stime.tv_sec; + s2 = (double) s_.ru_stime.tv_sec; + s = s1 - s2; + + t2 = s + m / MICROSEC; + + return t1 + t2; + }; + }; +#endif + + /// The TimerFactory should be used to get the approrpriate Timer. + class TimerFactory { + public: + /// Default constructor. + TimerFactory() { }; + + /// Destroy. + virtual ~TimerFactory() { }; + + /// Return an appropriate Timer. + virtual Timer *getTimer() { +#ifdef MINOTAUR_RUSAGE + return new UsageTimer; +#else + return new ClockTimer; +#endif + }; + + private: + TimerFactory (const TimerFactory &); + TimerFactory & operator = (const TimerFactory &); + }; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/TransPoly.h b/thirdparty/linux/include/minotaur/TransPoly.h new file mode 100644 index 0000000..a0f4bce --- /dev/null +++ b/thirdparty/linux/include/minotaur/TransPoly.h @@ -0,0 +1,272 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file TransPoly.h + * \brief Declare class for reformulating a polynomial problem. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURTRANSPOLY_H +#define MINOTAURTRANSPOLY_H + +#include "Transformer.h" + +namespace Minotaur { + +class MultilinearTermsHandler; +class MonomialFunction; +class YEqMonomial; +class YEqCG; +typedef boost::shared_ptr MonomialFunPtr; +typedef boost::shared_ptr MultilinearTermsHandlerPtr; + + +/** + * \brief Base class for reformulating a general nonconvex mixed-integer + * problem into one that has univariate constraints and multilinear constraints. + */ +class TransPoly : public Transformer { +public: + + /// Default Constructor. + TransPoly(); + + /// Constructor. + TransPoly(EnvPtr env, ConstProblemPtr p); + + /// Destroy. + ~TransPoly(); + + // base class method. + std::string getName() const; + + // base class method. + SolutionPtr getSolOrig(ConstSolutionPtr sol, int &err); + + // base class method. + SolutionPtr getSolTrans(ConstSolutionPtr sol, int &err); + + // base class method. + void reformulate(ProblemPtr &newp, HandlerVector &handlers, int &status); + +private: + + /// Handler that takes care of constraints of the form y=u.v.w.x + MultilinearTermsHandlerPtr mHandler_; + + /// Save monomials so that auxiliary variables can be reused. + YEqMonomial *yMonoms_; + + /** + * \brief Assign a constraint to multilinear-terms handler. + * \param [in] con Constraint that is to be assigned to the handler. It must be + * of the form y = x1.x2.x3... + * \param [in] v The auxiliary variable y. + * \param [in] mf The multilinear term saved as monomial. Care must be taken + * to make sure all variables have power one in the monomial. See monomToMl_ + * function. + */ + void assignMH_(ConstraintPtr con, VariablePtr v, MonomialFunPtr mf); + + /** + * \brief Convert a monomial to another monomial with all powers equal to + * one. Variables with higher powers get replaced by new variables and + * constraints. + * \param [in] mf The input monomial of the form + * \f$x_1^{a_1}x_2^{a_2}\ldots\f$. + * \return A monomial function that is of the form \f$y_1y_2\ldots\f$. + */ + MonomialFunPtr monomToMl_(MonomialFunPtr mf); + + /** + * \brief Assign an auxiliary variable for a monomial. + * + * If the monomial was + * already handled before, return the associated variable, otherwise new + * constraint and variable are added. If the monomial has powers higher than + * one on some variables, additional transformation is carried out. + * \param [in] mf The input monomial of the form + * \f$x_1^{a_1}x_2^{a_2}\ldots\f$. + * \return A variable \f$y\f$ corresponding to + * \f$y = x_1^{a_1}x_2^{a_2}\ldots\f$ + */ + VariablePtr newPolyVar_(MonomialFunPtr mf); + + /** + * \brief Assign an auxiliary variable for a monomial, linear function or a + * product of variable and constant. + * + * This function may call newPolyVar_ above. This function judiciously + * creates auxiliary variables for the input monomial or linear functions. + * \param [in] mf The input monomial of the form + * \f$x_1^{a_1}x_2^{a_2}\ldots\f$. It may be NULL. + * \param [in] lf The input linear function. It may be NULL. + * \param [in] v The input variable. We want to have a constraint + * \f$y = kv\f$ in this case. mf, lf, v should be all NULL except one. + * \param [in] d double value that must be added to the mf or lf or the + * variable. + * \param [in] k The multiplier of v. + * \return The new auxiliary variable. + */ + VariablePtr newPolyVar_(const CNode *cnode, MonomialFunPtr mf, + LinearFunctionPtr lf, VariablePtr v, + double d, double k); + + /** + * \brief Traverse the computational graph recursively and transform the + * nonlinear constraint. + * + * \param [in] node The node whose sub-tree must be reformulated. + * \param [out] mf The monomial function representing this node. + * \param [out] v The variable representing this node. + * mf, lf, v should be all NULL except one. + * \param [in] d double value that is added to the mf, lf, or v at this node. + * \param [in] k The multiplier of v. + */ + void recursPolyRef_(const CNode *node, + MonomialFunPtr &mf, LinearFunctionPtr &lf, + VariablePtr &v, double &d, double &k); + + /** + * \brief Reformulate the node with OpMinus operation in the computational + * graph. + * + * Depending on the type of functions in the two children, this function + * adds new variables, or combines linear functions for the reformulation. + * \param [in] mfl Monomial function from the left child. It may be NULL. + * \param [in] mfr Monomial function from the right child. It may be NULL. + * \param [in] lfl Linear function from the left child. It may be NULL + * \param [in] lfr Linear function from the right child. It may be NULL + * \param [in] vl Variable from the left child. + * \param [in] vr Variable from the right child. + * \param [in] dl double value from the left child. + * \param [in] dr double value from the right child. + * \param [in] kl The multiplier of vl. + * \param [in] kr The multiplier of vr. + * \param [out] mf The new monomial function. It may be NULL. + * \param [out] lf The new linear function. It may be NULL. + * \param [out] v The new variable. It may be NULL. + * \param [out] d The new double value for addition. + * \param [out] k The multiplier of v. + */ + void refMinus_(MonomialFunPtr mfl, MonomialFunPtr mfr, + LinearFunctionPtr lfl, LinearFunctionPtr lfr, + VariablePtr vl, VariablePtr vr, + double dl, double dr, + double kl, double kr, + MonomialFunPtr &mf, LinearFunctionPtr &lf, + VariablePtr &v, double &d, double &k); + + /** + * \brief Reformulate the node with OpMult operation in the computational + * graph. + * + * Depending on the type of functions in the two children, this function + * adds new variables, or combines linear functions for the reformulation. + * \param [in] mfl Monomial function from the left child. It may be NULL. + * \param [in] mfr Monomial function from the right child. It may be NULL. + * \param [in] lfl Linear function from the left child. It may be NULL + * \param [in] lfr Linear function from the right child. It may be NULL + * \param [in] vl Variable from the left child. + * \param [in] vr Variable from the right child. + * \param [in] dl double value from the left child. + * \param [in] dr double value from the right child. + * \param [in] kl The multiplier of vl. + * \param [in] kr The multiplier of vr. + * \param [out] mf The new monomial function. It may be NULL. + * \param [out] lf The new linear function. It may be NULL. + * \param [out] v The new variable. It may be NULL. + * \param [out] d The new double value for addition. + * \param [out] k The multiplier of v. + */ + void refMult_(MonomialFunPtr mfl, MonomialFunPtr mfr, + LinearFunctionPtr lfl, LinearFunctionPtr lfr, + VariablePtr vl, VariablePtr vr, + double dl, double dr, + double kl, double kr, + MonomialFunPtr &mf, LinearFunctionPtr &lf, + VariablePtr &v, double &d, double &k); + + + /* + * \brief Reformulate the constraints of the original problem into new + * problem. + */ + void refNonlinCons_(); + + /* + * \brief Reformulate the objective function of the original problem into new + * problem. + */ + void refNonlinObj_(); + + /** + * \brief Reformulate the node with OpPlus operation in the computational + * graph. + * + * Depending on the type of functions in the two children, this function + * adds new variables, or combines linear functions for the reformulation. + * \param [in] mfl Monomial function from the left child. It may be NULL. + * \param [in] mfr Monomial function from the right child. It may be NULL. + * \param [in] lfl Linear function from the left child. It may be NULL + * \param [in] lfr Linear function from the right child. It may be NULL + * \param [in] vl Variable from the left child. + * \param [in] vr Variable from the right child. + * \param [in] dl double value from the left child. + * \param [in] dr double value from the right child. + * \param [in] kl The multiplier of vl. + * \param [in] kr The multiplier of vr. + * \param [out] mf The new monomial function. It may be NULL. + * \param [out] lf The new linear function. It may be NULL. + * \param [out] v The new variable. It may be NULL. + * \param [out] d The new double value for addition. + * \param [out] k The multiplier of v. + */ + void refPlus_(MonomialFunPtr mfl, MonomialFunPtr mfr, + LinearFunctionPtr lfl, LinearFunctionPtr lfr, + VariablePtr vl, VariablePtr vr, + double dl, double dr, + double kl, double kr, + MonomialFunPtr &mf, LinearFunctionPtr &lf, + VariablePtr &v, double &d, double &k); + + /** + * \brief Reformulate univariate nonlinear functions like square-root, + * constant power, log, sin etc. + * + * This function is called anytime a nonlinear operation is seen in the + * traversal of computational graph. If the expression is constant, it + * complains. Otherwise, newPolyVar_ function is called to reformulate. + * \param [in] node The node whose sub-tree must be reformulated. + * \param [in] mfl The monomial function representing this node. + * \param [in] lfl The linear function representing this node. + * \param [in] vl The variable representing this node. + * \param [in] dl The addition-constant associated with this node. + * \param [in] kl The multiplier of vl associated with this node. + * \param [out] v Auxiliary variable for this node. May be NULL. + * \param [out] d The addition-constant, if the sub-function is constant. + * \param [out] k Multiplier of auxiliary variable v. + */ + void refUnivarOpPoly_(const CNode *node, MonomialFunPtr mfl, + LinearFunctionPtr lfl, VariablePtr vl, double dl, + double kl, VariablePtr &v, double &d, + double &k); +}; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/TransSep.h b/thirdparty/linux/include/minotaur/TransSep.h new file mode 100644 index 0000000..59538e2 --- /dev/null +++ b/thirdparty/linux/include/minotaur/TransSep.h @@ -0,0 +1,233 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file TransSep.h + * \brief Declare TransSep class for detecting separable nonlinear + * constraints in the problem. It considers nonlinear constraints of a problem + * and checks whether they are separable. If a nonlinear constraint is + * separable, then it reformulates original problem by introducing extra + * variables. Original nonlinear constraint becomes linear and each separable + * part constitutes a nonlinear constraint. This class also gives computational + * graphs of nonlinear constraints corresponding separable parts of separable + * constraints. + * \Author Meenarli Sharma, Indian Institute of Technology Bombay. + */ + +#ifndef MINOTAURTRANSSEP_H +#define MINOTAURTRANSSEP_H + +#include + +#include "Types.h" +#include "NonlinearFunction.h" +#include "OpCode.h" +#include "CNode.h" + +namespace Minotaur { + + class CGraph; + class CNode; + class LinearHandler; + class Problem; + typedef boost::shared_ptr CGraphPtr; + typedef boost::shared_ptr EnvPtr; + typedef boost::shared_ptr ProblemPtr; + typedef std::deque CNodeQ; + + class TransSep { + public: + + /// Default constructor. + TransSep(); + + /** + * \brief Default Constructor. + * \param [in] env Environment pointer. + * \param [in] minlp The minlp for which separability is to detected + */ + TransSep(EnvPtr env, ProblemPtr problem); + + /// Destroy. + ~TransSep(); + + /** + * Check constraints of the given problem for separability. + */ + void candCons(); + + /// Clear data structures if constraint is not separable + void clearCont(); + + /// Clear and populates information + bool clearpopu(UInt *j, std::vector * m); + + /// Generate computation graph + void createCG(std::vector * cg, CNodeQ * dq); + + + /// Perform Depth first search rooted at node n1 at iteration number j + void depthFS(int j, CNode *n1, std::vector * m); + + /// Explore further from node n1 at iteration number j + void explore(int j, CNode *n1, std::vector * m, int opc); + + /// Generate final computation graph + void finalCG(std::vector * cg); + + /// Find separability of given problem + void findSep(); + + /// Get left child of node n1 + CNode* getLchild(CNode * n1) {return tempN_[n1->getL()->getIndex()];}; + + /// Get right child of node n1 + CNode* getRchild(CNode * n1) {return tempN_[n1->getR()->getIndex()];}; + + /// Return Ids of separable constraints in original problem + std::vector getSepConId() {return sepConId_;} + + /// Give separable status of problem. + /// 1 if problem is separable, 0 otherwise + bool getStatus(); + + /// Mark nodes visited. Used in generating computation graph of separable + /// parts + void markVis(UInt i); + + /// Merge current iteration with iteration mNum + void merge(int mNum); + + /// Find iteration to merge the current iteration to + int mergeIt(int j, int a, std::vector * m); + + /// Check separability of objective function + void objSepCheck(); + + /// Check whether constraint is separable + bool outCheck(const CNode * o); + + + /// Populate information about separable part + void populate(); + + /// Populate nodes list + void popuon(CNode * n1, int opc, int t); + + /// Populate tempN_ + void popuTempN(CGraphPtr c, CNode *n1, OpCode op, bool k); + + /// Generate computational graph of separable parts + std::vector sepCGraph(CNodeQ * dq); + + /** + * Check if the nonlinear constraint is separable. 1 if separable + * 0 if not separable + */ + bool sepCheck(); + + /// Populate initial list for depth first search rooted at node n1 + void tempPop(CNode *n1, std::stack * tempNodes); + + /// Update linear part of the constraint function + void updateLin(VariablePtr v, double d); + + /// Add information of the node already visited + bool visited(UInt *j, std::vector * m, CNode * n1, + int opc); + + /// Write reformulated problem after separability detection + void writeProb(); + + private: + /// Environment. + EnvPtr env_; + + /// Log + LoggerPtr logger_; + + // For log: + static const std::string me_; + + // Problem whose constraints are to be checked for separability detection. + ProblemPtr problem_; + + double coeff_; + + /// Iteration number at which a node of the cgraph is visited first + std::vector itnum_; + + // Separable parts + std::vector sepNodes_; + + // Opcodes of nodes in separable parts + std::vector< std::deque< int> > sepOps_; + + // Variables in separable parts + std::vector< std::vector< CNode *> > sepVars_; + + // Constant nodes in separable parts + std::vector< std::vector< CNode *> > sepConst_; + + // Ids of the Constraint that are separable + std::vector sepConId_; + + // No. of new constraints added to the original problem after sep detection + UInt newCons_; + + // No. of new variable added to the origina problem after sep detection + UInt newVars_; + + /// Used in generating computational graph of separable parts + std::vector tempN_; + + // True if objective is separable + bool objSep_; + + // True if problem is separable + bool sepStatus_; + + LinearFunctionPtr lf_; + double ub_; + double lb_; + + // Indicates whether the function under consideration belongs to + // consrtaint or objective. True for constraint, false for objective + bool f_; + + CNodeQ snodes_; + + std::deque sops_; + + std::vector svars_; + + std::vector sconst_; + + std::stack on_; + + std::stack onop_; + + UInt nnode_; + + UInt nvar_; + + }; + typedef boost::shared_ptr TransSepPtr; + typedef boost::shared_ptr ConstTransSepPtr; +} + +#endif // MINOTAURTRANSSEP_H + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Transformer.h b/thirdparty/linux/include/minotaur/Transformer.h new file mode 100644 index 0000000..b4eaf37 --- /dev/null +++ b/thirdparty/linux/include/minotaur/Transformer.h @@ -0,0 +1,259 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file Transformer.h + * \brief Declare base class for transforming problems. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURTRANSFORMER_H +#define MINOTAURTRANSFORMER_H + +#include "Types.h" +#include "OpCode.h" + +namespace Minotaur { +class CxUnivarHandler; +class CGraph; +class CNode; +class Environment; +class LinearHandler; +class Problem; +class QuadHandler; +class Solution; +class YEqLFs; +class YEqUCGs; +class YEqVars; +typedef boost::shared_ptr CxUnivarHandlerPtr; +typedef boost::shared_ptr CGraphPtr; +typedef boost::shared_ptr EnvPtr; +typedef boost::shared_ptr LinearHandlerPtr; +typedef boost::shared_ptr ProblemPtr; +typedef boost::shared_ptr QuadHandlerPtr; +typedef boost::shared_ptr SolutionPtr; +typedef boost::shared_ptr ConstSolutionPtr; + + +/** + * \brief Abstract base class for reformulating a problem so that handlers can + * be applied to it. + * + * A transformer will create a new problem equivalent to a given problem by + * spliting constraints, adding new variables etc. The end result is a + * problem whose each constraint can be handled by a specific handler. This + * class has some abstract virtual methods that must be implemented by a derived + * class. Other commonly used functions are implemented here. + */ +class Transformer { +public: + + /// Default Constructor. + Transformer(); + + /// Constructor. + Transformer(EnvPtr env, ConstProblemPtr oldp); + + /// Destroy. + virtual ~Transformer(); + + /// Get the name of this Transformer. + virtual std::string getName() const = 0; + + /** + * \brief Translate the solution of reformulated problem into that of + * original problem. + * + * \param [in] sol Solution of the reformulated problem. + * \param [out] err Zero if no error is encountered, nonzero otherwise. + * \return Solution of original problem. + */ + virtual SolutionPtr getSolOrig(ConstSolutionPtr sol, int &err) = 0; + + /** + * \brief Translate the solution of originial problem into that of + * reformulated problem. + * + * \param [in] sol Solution of the original problem. + * \param [out] err Zero if no error is encountered, nonzero otherwise. + * \return Solution of the reformulated problem. + */ + virtual SolutionPtr getSolTrans(ConstSolutionPtr sol, int &err) = 0; + + /** + * \brief Perform the reformulation, and assign handlers. + * + * \param [out] newp The new, reformulated problem. + * \param [out] handlers A vector of handlers used to reformulate the + * problem. + * \param [out] status Zero if reformulated successfully. Nonzero otherwise. + */ + virtual void reformulate(ProblemPtr &newp, HandlerVector &handlers, + int &status) = 0; + +protected: + /// The pointer to environment. + EnvPtr env_; + + /// Handler for linear constraints and variables. + LinearHandlerPtr lHandler_; + + /// Logger + LoggerPtr logger_; + + /// The transformed problem + ProblemPtr newp_; + + /// The original problem + ConstProblemPtr p_; + + /// Handler for quadratic terms + QuadHandlerPtr qHandler_; + + /// Handler for univariate constraints. + CxUnivarHandlerPtr uHandler_; + + /** + * \brief Storage for auxiliary variables defined by relations of the form + * \f$y_i = c^Tx + d\f$. + */ + YEqLFs *yLfs_; + + /** + * \brief Storage for auxiliary variables defined by relations of the form + * \f$y_i = f(x_j)\f$. + */ + YEqUCGs *yUniExprs_; + + /** + * \brief Storage for auxiliary variables defined by relations of the form + * \f$y_i = x_j + d\f$. + */ + YEqVars *yVars_; + + /// Tolerance for checking if a value is zero. + const double zTol_; + + /** + * \brief Check if all constraints in a problem have been assigned to a + * handler. + * + * \param[in] p Problem whose constraints need to be checked. + * \returns True if all constraints have been assigned. False otherwise. + */ + bool allConsAssigned_(ProblemPtr p, HandlerVector &handlers); + + /** + * \brief Assign an appropriate handler to a nonlinear constraint of the + * form \f$y_i = f(x)\f$. + * + * \param[in] cg A nonlinear function which is be replaced by the auxiliary + * variable. + * \param[in] c The nonlinear constraint \f$y_i = f(x)\f$ that is being + * assigned to. + */ + void assignHandler_(CGraphPtr cg, ConstraintPtr c); + + /** + * \brief Delete unused handlers. + * + * \param [in/out] handlers. Contains pointers to each handler. Unused ones + * are removed from the vector. + */ + void clearUnusedHandlers_(HandlerVector &handlers); + + /** + * \brief Copy all the linear constraints of the problem into the new problem. + * + * \param [in] p Input problem + * \param [in] newp The transformed problem to which new constraints are + * added. + */ + void copyLinear_(ConstProblemPtr p, ProblemPtr newp); + + /** + * \brief Copy all the linear constraints of the problem into the new problem. + * + * \param [in] p Input problem + * \param [in] newp The transformed problem to which new constraints are + * added. + */ + void copyVars_(ConstProblemPtr p, ProblemPtr newp); + + /** + * Converts the new Problem newp_ into one with a linear objective by adding + * a new variable if necessary. + */ + virtual void makeObjLin_(); + + /// Convert a maximization objective into minimization. + void minObj_(); + + /** + * \brief Find the auxiliary variable associated with \f$y_i = x_j+d\f$ or + * create a new one. + * + * \param [in] iv The variable \f$x_j\f$. + * \param [in] d The value \f$d\f$. + * \param [in] newp The transformed problem to which the new constraint + * should be added, in case this constraint is not found. + * \return The variable \f$y\f$. If the constraint is found, it returns the + * variable found in it, otherwise it addes a new variable to the problem + * and returns it. + */ + VariablePtr newVar_(VariablePtr iv, double d, ProblemPtr newp); + + /** + * \brief Find the auxiliary variable associated with \f$y_i = c^Tx+d\f$ or + * create a new one. + * + * \param [in/out] lf The linear function \f$c^Tx\f$. If a new variable is + * created, it is also subtracted from lf. + * \param [in] d The value \f$d\f$. + * \param [in] newp The transformed problem to which the new constraint + * should be added, in case this constraint is not found. + * \return The variable \f$y\f$. If the constraint is found, it returns the + * variable found in it, otherwise it addes a new variable to the problem + * and returns it. + */ + VariablePtr newVar_(LinearFunctionPtr lf, double d, ProblemPtr newp); + + /** + * \brief Find the auxiliary variable associated with \f$y_i = f(x)+d\f$ or + * create a new one. + * + * \param [in] The nonlinear function. + * \param [in] newp The transformed problem to which the new constraint + * should be added, in case this constraint is not found. + * \return The variable \f$y\f$. If the constraint is found, it returns the + * variable found in it, otherwise it addes a new variable to the problem + * and returns it. + */ + VariablePtr newVar_(CGraphPtr cg, ProblemPtr newp); + +private: + static const std::string me_; + +}; + +typedef boost::shared_ptr TransformerPtr; +typedef boost::shared_ptr ConstTransformerPtr; + +} + +#endif + + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/TreeManager.h b/thirdparty/linux/include/minotaur/TreeManager.h new file mode 100644 index 0000000..15924e1 --- /dev/null +++ b/thirdparty/linux/include/minotaur/TreeManager.h @@ -0,0 +1,242 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file TreeManager.h + * \brief Declare class TreeManager for managing tree for Branch-and-Bound. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURTREEMANAGER_H +#define MINOTAURTREEMANAGER_H + +#include +#include + +#include "Types.h" + +namespace Minotaur { + + class ActiveNodeStore; + class WarmStart; + typedef boost::shared_ptr ActiveNodeStorePtr; + typedef boost::shared_ptr WarmStartPtr; + + // 1=like_red, 2=blue, 4=red, 5=yellow, 6=black, 7=pink, 8=cyan, 9=green + // 11=orange, 12=green, 13=pink, 14=light blue + /// Colors for tree-visualization using vbc + typedef enum { + VbcActive = 4, /// Unsolved, open. + VbcFeas = 2, /// incumbent. + VbcInf = 11, /// infeasible. + VbcSolved = 9, /// solved. + VbcSolving = 8, /// currently being solved. + VbcSubInf = 13, /// subtree is infeasible. + VbcSubOpt = 6 /// suboptimal. + } VbcColors; + + + /// Base class for managing the branch-and-bound tree. + class TreeManager { + + public: + /// Constructor. + TreeManager(EnvPtr env); + + /// Destroy. + ~TreeManager(); + + /// Return true if any active nodes remain in the tree. False otherwise. + bool anyActiveNodesLeft(); + + /** + * \brief Branch and create new nodes. + * + * \param[in] branches The branching constraints or bounds or disjunctions + * that are used to create the new nodes after branching. + * \param[in] node The node that we wish to branch upon. + * \param[in] ws The warm starting information that should be linked to + * in the new nodes. + * \returns The first child node. + */ + NodePtr branch(Branches branches, NodePtr node, WarmStartPtr ws); + + /** + * \brief Return the number of active nodes, i.e. nodes that have been + * created, but not processed yet. + */ + UInt getActiveNodes() const; + + /// Return the cut off value. It is INFINITY if it is not set. + double getCutOff(); + + /** + * \brief Return the gap between the lower and upper bound as a + * percentage. It is calculated as + * \f$\frac{ub-lb}{\left|ub\right|+\epsilon}\times 100\f$. + */ + double getPerGap(); + + /** + * \brief Return the value of the highest lower bound evaluated in the + * last update of he bound. + * + * Since evaluating the lower bound may be expensive or certain types of + * tree-managers, it may be updated infrequently. Consquently, the value + * returned here may be lower than the actual lower bound of + * the tree. Also see updateLb(). + */ + double getLb(); + + /// Return the best known upper bound. + double getUb(); + + /** + * \brief Return the size of the tree, including both active and processed + * nodes. + */ + UInt getSize() const; + + /** + * \brief Search for the best candidate that can be processed next. + * + * It may prune some of the nodes if their lower bound is more than the + * upper bound. \return the best candidate found. If no candidate is + * found, it returns NULL. The candidate is not removed from the storage. + * It is removed only when removeActiveNode() is called. + */ + NodePtr getCandidate(); + + /** + * \brief Insert the root node into the tree. + * + * \param[in] node The root node. + */ + void insertRoot(NodePtr node); + + /** + * \brief Prune a given node from the tree + * + * \param[in] node The node that must be pruned. + */ + void pruneNode(NodePtr node); + + /** + * \brief Remove a given active node from storage. + * + * It should be called after the node has been processed. + * \param[in] node The node to be removed from storage. + */ + void removeActiveNode(NodePtr node); + + /** + * \brief Set the cut off value for the objective function. + * + * Nodes with lower bound \f$ lb \geq value-\epsilon\f$ can be pruned. + * \param[in] value The cut off value. It can be INFINITY. + */ + void setCutOff(double value); + + /** + * \brief Set the best known objective function value. + * + * The function does NOT check if the given value is better than the + * previous. So care should be taken to pass only the best known value. It + * also updates the cutoff value that is used to prune nodes. + * \param[in] value The best known upper bound. + */ + void setUb(double value); + + /// Return true if the tree-manager recommends diving. False otherwise. + bool shouldDive(); + + /** + * \brief Recalculate and return the lower bound of the tree. + * + * If the active nodes are stored + * in a heap, nothing really needs to be done. For other types of storage, + * this operation may be expensive. The result is cached into + * bestLowerBound_. + * \return the updated lower bound. + */ + double updateLb(); + + private: + /// Set of nodes that are still active (those who need to be processed). + ActiveNodeStorePtr active_nodes_; + + /// An active node that is not in the ActiveNodeStore. One such node may + /// exist. When we are diving. It must be deleted in the end. + NodePtr aNode_; + + /// \brief Best known lower bound based on the last update. + double bestLowerBound_; + + /// \brief Best known upper bound. + double bestUpperBound_; + + /// Delete all nodes, active and inactive. + void clearAll(); + + /// The cutoff value above which nodes are assumed infeasible. + double cutOff_; + + /// Whether we should store tree information for vbc. + bool doVbc_; + + /// Tolerance for pruning nodes on the basis of bounds. + const double etol_; + + /// The search order: depth first, best first or something else. + TreeSearchOrder searchType_; + + /** + * \brief Number of nodes that have been created so far, including the + * ones that were deleted. + */ + UInt size_; + + /// Timer is used only for vbc tree emulation. + Timer *timer_; + + /// File name to store tree information for vbc. + std::ofstream vbcFile_; + + /// Check if the node can be pruned because of its bound. + bool shouldPrune_(NodePtr node); + + /** + * \brief Insert a candidate (that is not root) into the tree. + * + * \param[in] node The node that is to be inserted. + * \param[in] pop_now True if ... + */ + void insertCandidate_(NodePtr node, bool pop_now = false); + + /** + * \brief Remove a node from the tree. + * + * \param[in] node The node that is to be removed. It may remove the + * parents of the current node also if they are no longer required. + */ + void removeNode_(NodePtr node); + }; + + typedef boost::shared_ptr TreeManagerPtr; + +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Types.h b/thirdparty/linux/include/minotaur/Types.h new file mode 100644 index 0000000..1a1856b --- /dev/null +++ b/thirdparty/linux/include/minotaur/Types.h @@ -0,0 +1,486 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Types.h + * \brief Declare important 'types' used in Minotaur. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURTYPES_H +#define MINOTAURTYPES_H + +#include +#include +#include +#include +#include +#include +#include + +//#ifndef MINOTAUR_RUSAGE +//# error MINOTAUR_RUSAGE is NOT defined +//#endif +namespace Minotaur { + + /// Standard types. + typedef unsigned int UInt; + + /// Containers for standard types + typedef std::deque < UInt > UIntQ; + typedef std::vector < bool > BoolVector; + typedef std::vector < double > DoubleVector; + typedef std::vector < int > IntVector; + typedef std::vector < UInt > UIntVector; + typedef std::set < UInt > UIntSet; + + /// The different classes of problems + typedef enum { + LP, + MILP, + QP, + MIQP, + QCQP, + MIQCQP, + POLYP, + MIPOLYP, + NLP, + MINLP, + UnknownProblem + } ProblemType; + + /** + * Objective sense. Minotaur minimizes. Always. If the sense is to Maximize, + * then Minotaur converts the objective. + */ + typedef enum { + Minimize, + Maximize + } ObjectiveType; + + /// Different types of functions in Minotaur. + typedef enum { + Constant, + Linear, + Bilinear, + Multilinear, + Quadratic, + Nonlinear, + Polynomial, + UnknownFunction + } FunctionType; + + /// Different types of variables. + typedef enum { + Binary, ///< Variable is constrained to be binary. + Integer, ///< Variable is constrained to be integer. + ImplBin, ///< Variable is continuous, but will take binary values only. + ImplInt, ///< Variable is continuous, but will take integer values only. + Continuous ///< Variable is continuous. + } VariableType; + + /// Where did the variable originate from? + typedef enum { + VarOrig, ///> Variable was part of the original problem + VarTran, ///> Variable created by Transformer + VarHand, ///> Variable created by Handler + VarOtherSrc ///> Variable created by some other source + } VarSrcType; + + /// Different types of variable-bounds. + typedef enum { + Lower, + Upper + } BoundType; + + /// SOS types + typedef enum { + SOS1, + SOS2 + } SOSType; + + /// Different states a variable can be in. + typedef enum { + DeletedVar, ///< Marked for deletion. + FixedVar, ///< Fixed to a value. + FreeVar, ///< Doesn't have bounds. Same as superbasic in LP + NormalVar ///< Not in any other category + } VarState; + + /// Different states a constraint can be in. + typedef enum { + DeletedCons, ///< Marked for deletion. + FreeCons, ///< Doesn't have bounds. Implies redundant. + NormalCons ///< Not in any other category + } ConsState; + + /// Different states an objective can be in. + typedef enum { + DeletedObj, ///< Marked for deletion. + NormalObj ///< Not in any other category + } ObjState; + + /// Different states an algorithm like branch-and-bound can be in. + typedef enum { + NotStarted, + Started, + Restarted, + SolvedOptimal, + SolvedInfeasible, + SolvedUnbounded, + SolvedGapLimit, + SolvedSolsLimit, + IterationLimitReached, + Interrupted, + TimeLimitReached, + SolLimitReached, + SolveError, + Finished + } SolveStatus; + + /// Different status that an external engine may report. + typedef enum { + ProvenOptimal, + ProvenLocalOptimal, + ProvenInfeasible, + ProvenLocalInfeasible, + ProvenUnbounded, + ProvenObjectiveCutOff, + EngineIterationLimit, + ProvenFailedCQFeas, + ProvenFailedCQInfeas, + FailedFeas, + FailedInfeas, + EngineError, + EngineUnknownStatus + } EngineStatus; + + /// What can a brancher do to a node in branch-and-bound. + typedef enum { + ModifiedByBrancher, + PrunedByBrancher, + NotModifiedByBrancher + } BrancherStatus; + + /// Two directions for branching + typedef enum { + DownBranch, + UpBranch + } BranchDirection; + + /// Status of a node in branch-and-bound. + typedef enum { + NodeNotProcessed, //< has been created but not yet been processed. + NodeInfeasible, //< can be pruned + NodeHitUb, //< can be pruned + NodeDominated, //< can be pruned + NodeOptimal, //< The solution obtained is integral, feasible and optimal + //< for the subtree. can prune. + NodeContinue, //< solution is neither optimal, nor the relaxation + //< provably infeasible. + //NodeFrac, //< fractional solution but optimal for the relaxation + //NodeInt, //< integer solution found at this node, + //< but may not be feasible/optimal. branch more. + NodeStopped + } NodeStatus; + + + /// Status from separation routine: + typedef enum { + SepaContinue, ///< Separation routine wants nothing. + SepaResolve, ///< Separation routine wants the relaxation resolved. + SepaPrune, ///< No need to further solve the subproblem. + SepaNone, ///< No separation found. + SepaError ///< Problem separating a point. + } SeparationStatus; + + + /// Levels of verbosity. + typedef enum { + LogNone, //< absolutely no messages + LogError, //< only error messages and warnings if any + LogInfo, //< errors, timed status, final solution + LogExtraInfo, //< some extra info, stats etc + LogDebug, //< more verbose + LogDebug1, //< more verbose + LogDebug2 //< more verbose + } LogLevel; + + /// Order of tree search. + typedef enum { + DepthFirst, + BestFirst, + BestThenDive /// First find the best bound, then dive until pruned. + } TreeSearchOrder; + + + /// Type of algorithms that can be used + typedef enum { + DefaultAlgo, + QPNLPBnb, + QG, + NLPBnb + } AlgoType; + + /// Logging + class Logger; + typedef boost::shared_ptr LoggerPtr; + + /// What is the function type on adding two functions f1 and f2? + FunctionType funcTypesAdd(FunctionType f1, FunctionType f2); + + /// What is the function type on multiplying two functions f1 and f2? + FunctionType funcTypesMult(FunctionType f1, FunctionType f2); + + /// Get the string equivalent of ProblemType. + std::string getProblemTypeString(ProblemType p); + + /// Get the string equivalent of FunctionType. + std::string getFunctionTypeString(FunctionType f); + + /// Get the string equivalent of SolveStatus. + std::string getSolveStatusString(SolveStatus s); + + class Constraint; + typedef boost::shared_ptr ConstraintPtr; + typedef boost::shared_ptr ConstConstraintPtr; + typedef std::vector::iterator ConstraintIterator; + typedef std::vector::const_iterator ConstraintConstIterator; + typedef std::vector ConstraintVector; + + class SOS; + typedef SOS* SOSPtr; + typedef std::vector SOSVector; + typedef SOSVector::iterator SOSIterator; + typedef SOSVector::const_iterator SOSConstIterator; + + // Serdar defined + typedef boost::shared_ptr ConstraintVectorPtr; + typedef std::vector ConstConstraintVector; + typedef boost::shared_ptr ConstConstraintVectorPtr; + typedef ConstConstraintVector::iterator ConstConstraintIterator; + typedef std::set ConstrSet; + typedef std::deque ConstrQ; + + + class Variable; + typedef boost::shared_ptr VariablePtr; + typedef boost::shared_ptr ConstVariablePtr; + typedef std::vector VarVector; + typedef std::deque VarQueue; + typedef VarVector::const_iterator VariableConstIterator; + typedef VarVector::iterator VariableIterator; + typedef std::vector::iterator ConstVarIter; + typedef VarQueue::const_iterator VarQueueConstIter; + typedef VarQueue::iterator VarQueueIter; + struct CompareVariablePtr { + bool operator()(ConstVariablePtr v1, ConstVariablePtr v2) const; + }; + typedef std::set VariableSet; + typedef VariableSet::const_iterator VarSetConstIterator; + typedef std::set VarSet; + + // Serdar added. + typedef boost::shared_ptr VarSetPtr; + typedef boost::shared_ptr ConstVarSetPtr; + typedef std::map VarIntMap; + typedef VarIntMap::const_iterator VarIntMapConstIterator; + typedef VarIntMap::iterator VarIntMapIterator; + + typedef VarSet::iterator VarSetIter; + typedef VarSet::const_iterator VarSetConstIter; + typedef std::set ConstVarSet; + typedef VarSet::const_iterator ConstVarSetIter; + + class Node; + typedef boost::shared_ptr NodePtr; + typedef std::vector NodePtrVector; + typedef std::vector::iterator NodePtrIterator; + + class Handler; + typedef boost::shared_ptr HandlerPtr; + typedef boost::shared_ptr ConstHandlerPtr; + typedef std::vector HandlerVector; + typedef HandlerVector::iterator HandlerIterator; + typedef HandlerVector::const_iterator HandlerConstIterator; + + class Environment; + typedef boost::shared_ptr EnvPtr; + class Problem; + typedef boost::shared_ptr ProblemPtr; + typedef boost::shared_ptr ConstProblemPtr; + + class Modification; + typedef boost::shared_ptr ModificationPtr; + typedef boost::shared_ptr ConstModificationPtr; + typedef std::vector ModVector; + typedef std::vector::const_iterator + ModificationConstIterator; + typedef std::vector::const_reverse_iterator + ModificationRConstIterator; + typedef std::deque ModQ; + typedef std::stack ModStack; + + class Branch; + typedef boost::shared_ptr BranchPtr; + typedef boost::shared_ptr ConstBranchPtr; + typedef std::vector BranchPtrVector; + typedef boost::shared_ptr Branches; + typedef std::vector::const_iterator BranchConstIterator; + + class BrCand; + typedef boost::shared_ptr BrCandPtr; + typedef boost::shared_ptr ConstBrCandPtr; + typedef std::vector< BrCandPtr > BrCandVector; + typedef BrCandVector::iterator BrCandVIter; + + class BrVarCand; + typedef boost::shared_ptr BrVarCandPtr; + typedef boost::shared_ptr ConstBrVarCandPtr; + struct CompareVarBrCand { + bool operator()(ConstBrVarCandPtr c1, ConstBrVarCandPtr c2) const; + }; + typedef std::set BrVarCandSet; + typedef BrVarCandSet::iterator BrVarCandIter; + typedef std::vector< BrVarCandPtr >::iterator BrVarCandVIter; + + // Serdar added this block + // Compare some pairs. + typedef std::pair id; + struct CompareIntDouble { + bool operator() (id id1, id id2) const; + }; + + // Compare rule to compare the value of the pair. + typedef std::pair VariableValuePair; + typedef boost::shared_ptr VariableValuePairPtr; + struct CompareValueVariablePair { + bool operator() (VariableValuePair v1,VariableValuePair v2) const; + }; + + // Map to determine GUB cover. + struct CompareValueVarInc{ + bool operator() (VariableValuePair v1, VariableValuePair v2) const; + }; + typedef std::map + VariableValueMap; + + + // Vector of pair which is VariableValuePair. + typedef std::vector VariableValuePairVector; + typedef boost::shared_ptr VariableValuePairVectorPtr; + typedef std::vector::iterator + VariableValuePairVectorIterator; + typedef std::vector::const_iterator + VariableValuePairVectorConstIterator; + + // Cover is a VariableSet + typedef VariableValuePairVector CoverSet; + typedef boost::shared_ptr CoverSetPtr; + typedef boost::shared_ptr ConstCoverSetPtr; + typedef CoverSet::iterator CoverSetIterator; + typedef CoverSet::const_iterator CoverSetConstIterator; + + // Pointers to classes added. + class KnapsackList; + typedef boost::shared_ptr KnapsackListPtr; + typedef boost::shared_ptr ConstKnapsackListPtr; + + // Cut class vectors etc. + class Cut; + typedef boost::shared_ptr CutPtr; + typedef std::vector CutVector; + typedef CutVector::iterator CutVectorIter; + typedef CutVector::const_iterator CutVectorConstIter; + typedef std::list CutList; + typedef CutList::iterator CutListIter; + + //LiftingProblem which is a knapsack problem type of Problem. + typedef Problem LiftingProblem; + typedef ProblemPtr LiftingProblemPtr; + // CoverCutGenerator pointer + class CoverCutGenerator; + typedef boost::shared_ptr CoverCutGeneratorPtr; + // LGCIGenerator pointer + class LGCIGenerator; + typedef boost::shared_ptr LGCIGeneratorPtr; + + class Function; + typedef boost::shared_ptr ConstFunctionPtr; + // Serdar ended. + + // declare options database + class OptionDB; + typedef boost::shared_ptr OptionDBPtr; + + // declare options + template class Option; + typedef boost::shared_ptr< Option > BoolOptionPtr; + typedef boost::shared_ptr< Option > IntOptionPtr; + typedef boost::shared_ptr< Option > DoubleOptionPtr; + typedef boost::shared_ptr< Option > StringOptionPtr; + typedef BoolOptionPtr FlagOptionPtr; + + // define sets of pointers + typedef std::set BoolOptionSet; + typedef std::set IntOptionSet; + typedef std::set DoubleOptionSet; + typedef std::set StringOptionSet; + typedef BoolOptionSet FlagOptionSet; + + // define iterators of pointers + typedef BoolOptionSet::iterator BoolOptionSetIter; + typedef IntOptionSet::iterator IntOptionSetIter; + typedef DoubleOptionSet::iterator DoubleOptionSetIter; + typedef StringOptionSet::iterator StringOptionSetIter; + typedef BoolOptionSetIter FlagOptionSetIter; + + + /// Variables should always be constant within a group + typedef std::map VariableGroup; + typedef std::map::iterator VariableGroupIterator; + typedef std::map::const_iterator + VariableGroupConstIterator; + + /// Pairs of variables are used in quadratic functions. + typedef std::pair VariablePair; + typedef std::pair ConstVariablePair; + + struct CompareVariablePair { + bool operator()(ConstVariablePair tv1, ConstVariablePair tv2) const; + }; + + /// Again, Variables should always be constant within a group + typedef std::map + VariablePairGroup; + typedef std::map VarPairIntMap; + typedef std::map::iterator VariablePairGroupIterator; + typedef std::map::const_iterator + VariablePairGroupConstIterator; + typedef std::map VarVarMap; + typedef VarVarMap::const_iterator VarVarMapConstIterator; + + typedef const std::map + VarCountConstMap; + + class Heuristic; + typedef boost::shared_ptr HeurPtr; + typedef std::vector HeurVector; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Variable.h b/thirdparty/linux/include/minotaur/Variable.h new file mode 100644 index 0000000..e8469bb --- /dev/null +++ b/thirdparty/linux/include/minotaur/Variable.h @@ -0,0 +1,195 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2009 - 2014 The MINOTAUR Team. +// + +/** + * \file Variable.h + * \brief Define the Variable class + * \author Ashutosh Mahajan, Argonne National Laboratory + * + * Methods for handling variables in a problem. + */ + + +#ifndef MINOTAURVARIABLE_H +#define MINOTAURVARIABLE_H + +#include + +#include "Types.h" + +namespace Minotaur { + +/** + * Variable class contains methods for defining and changing variables of a + * Problem. A variable has bounds (lb, ub), a type (binary, integer, + * continuous), a name, and an id which is unique for the variable and is + * usually generated by the Problem. + */ +class Variable { +public: + /// Only Problem class can modify a Variable. All modification methods + /// are private. + friend class Problem; + + /// Default constructor. + Variable(); + + /// Construct a variable with an id, lb, ub, type and name. + Variable(UInt id, UInt index, double lb, double ub, VariableType vtype, + std::string name); + + /// Destroy. + virtual ~Variable(); + + /// Create a copy. + boost::shared_ptr clone(UInt id) const; + + /// Get the unique id. + UInt getId() const { return id_; } + + /** + * Many operations rely on arrays of values. index_ is the index of + * variable in such arrays. Thus x[index_] will give the + * value of this variable in an array x, provided x was populated that + * way (Most engines etc. will populate it on the basis of index_). + */ + UInt getIndex() const { return index_; } + + /// Get lowerbound. + double getLb() const { return lb_; } + + /// Get upperbound. + double getUb() const { return ub_; } + + /// Get the type (binary, integer, continuous). + VariableType getType() const { return vtype_; } + + /// Get the function type of constraints that this variable is in. + FunctionType getFunType() const { return ftype_; } + + /// Get the type of origin of this variable + VarSrcType getSrcType() const { return stype_; } + + /// Get the state (fixed, deleted, ...). + VarState getState() const { return state_; } + + UInt getNumCons() const; + + /// First iterator of constraints where this variable appears. + ConstrSet::iterator consBegin(); + + /// Last iterator of constraints where this variable appears. + ConstrSet::iterator consEnd(); + + /// Get name of the variable. + const std::string getName() const; + + /** + * \brief Write the full description of the variable including name, bounds, + * type etc. + */ + void write(std::ostream &out) const; + + /// Write the list of constraints in which this variable occurs. + void writeConstraintMap(std::ostream & out) const; + +protected: + /// Change the id to a new value. + void setId_(UInt n) { id_ = n; } + + /// Change the state to a new value. + void setState_(VarState state) { state_ = state; return; } + + /// Change the lowerbound to a new value. + void setLb_(double newLb) { lb_ = newLb; } + + /// Change the upperbound to a new value. + void setUb_(double newUb) { ub_ = newUb; } + + /// Change the index to a new value. + void setIndex_(UInt n) { index_ = n; } + + /// Change the name to a new value. + void setName_(std::string newName) { name_ = newName; } + + /// Change the type to a new value. + void setType_(VariableType vtype) { vtype_ = vtype; return; } + + /// Change the function type to a new value. + void setFunType_(FunctionType ftype) { ftype_ = ftype; return; } + + /// Change the type of the origin of this variable + void setSrcType(VarSrcType stype) { stype_ = stype; } + + /** + * \brief Remove the constraint from the list of constraints this variable + * belongs to. + */ + void outOfConstraint_(ConstraintPtr cPtr); + + /** + * \brief Add the constraint to the list of constraints this variable + * belongs to. + */ + void inConstraint_(ConstraintPtr c); + + /// Clear the list of constraints this variable belongs to. + void clearConstraints_(); + +private: + /// unique id for this variable + UInt id_; + + /// index for this variable + UInt index_; + + /// lower bound + double lb_; + + /// upper bound + double ub_; + + /// type: integer, binary, continuous etc + VariableType vtype_; + + /// What kind of constraints does it appear in? Linear, Quadratic, ... + FunctionType ftype_; + + /// state: fixed, freed etc + VarState state_; + + /// Where did this variable originate? Original problem, transformer, etc. + VarSrcType stype_; + + /// name + std::string name_; + + /// Set of constraints in which this variable appears. + ConstrSet cons_; + + /// Copy constructor is not allowed. + Variable(const Variable &v); + + /// Copy by assignment is no allowed. + Variable & operator = (const Variable &v); +}; + +typedef std::set >::const_iterator +ConstraintFunIterator; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/Version.h b/thirdparty/linux/include/minotaur/Version.h new file mode 100644 index 0000000..172423c --- /dev/null +++ b/thirdparty/linux/include/minotaur/Version.h @@ -0,0 +1,22 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 -- 2014 The MINOTAUR Team. +// + +#ifndef MINOTAURVERSION_H +#define MINOTAURVERSION_H + +/* Define MINOTAUR_GIT_VERSION to whatever the output of git describe is. */ +#define MINOTAUR_GIT_VERSION "v0.2-177-geccae15" + +/* + * Version is defined as MINOTAUR_MAJOR_VERSION.MINOTAUR_MINOR_VERSION + * patch MINOTAUR_PATCH_VERSION + */ +#define MINOTAUR_MAJOR_VERSION 0 +#define MINOTAUR_MINOR_VERSION 2 +#define MINOTAUR_PATCH_VERSION 0 + +#endif + diff --git a/thirdparty/linux/include/minotaur/WarmStart.h b/thirdparty/linux/include/minotaur/WarmStart.h new file mode 100644 index 0000000..377aad9 --- /dev/null +++ b/thirdparty/linux/include/minotaur/WarmStart.h @@ -0,0 +1,75 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +// /** +// \file WarmStart.h +// \brief Define the base class WarmStart for storing the warm starting +// information for different types of engines. +// \author Ashutosh Mahajan, Argonne National Laboratory +// */ + + +#ifndef MINOTAURWARMSTART_H +#define MINOTAURWARMSTART_H + +#include "Types.h" + +namespace Minotaur { + + class WarmStart; + typedef boost::shared_ptr WarmStartPtr; + typedef boost::shared_ptr ConstWarmStartPtr; + + // /** + // Warm starting information enables an engine to quickly resolve a problem + // after that has been modified. + // + // We save warm start information on all those + // nodes of the branch-and-bound tree whose at least one child is saved for + // later processing. If all the children of a node are pruned or if the node + // has only one child and we decide to process it next, then we don't need + // to save warm start information for that node. + // + // For now we save complete warm-start information on each active node. A more + // memory efficient method is to save warm-start information for each node + // by just storing the differences from the parent. + // However, the benefits of saving the complete information are: + // -# Ease of coding. + // -# We can delete warm-start information of a node when it is processed. + // Thus, we have at most `A' nodes that have warm-start information saved + // on them, where `A' is the total number of active nodes in the tree. + // */ + class WarmStart { + public: + /// Default constructor + WarmStart() {} + + /// Destroy + virtual ~WarmStart() {} + + /// Return true if warm start information is initialized, false + /// otherwise. + virtual bool hasInfo() = 0; + + /// Write to an output stream + virtual void write(std::ostream &out) const = 0; + + /// \todo + //virtual void setEngine(EnginePtr engine) = 0; + }; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/YEqCGs.h b/thirdparty/linux/include/minotaur/YEqCGs.h new file mode 100644 index 0000000..2875144 --- /dev/null +++ b/thirdparty/linux/include/minotaur/YEqCGs.h @@ -0,0 +1,49 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file YEqCGs.h + * \brief Declare the class for storing auxiliary variables for nonlinear + * functions that are expressed as computational graphs. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURYEQCG_H +#define MINOTAURYEQCG_H + +#include "Types.h" +#include "OpCode.h" + +namespace Minotaur { +class CGraph; +typedef boost::shared_ptr CGraphPtr; + +class YEqCGs { +public: + YEqCGs(); + VariablePtr findY(CGraphPtr cg); + void insert(VariablePtr auxvar, CGraphPtr cg); + +private: + DoubleVector hash_; + DoubleVector rand_; + VarVector y_; + std::vector cg_; + double evalHash_(const CNode* node, UInt rank); +}; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/YEqLFs.h b/thirdparty/linux/include/minotaur/YEqLFs.h new file mode 100644 index 0000000..a906c46 --- /dev/null +++ b/thirdparty/linux/include/minotaur/YEqLFs.h @@ -0,0 +1,51 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file YEqLFs.h + * \brief Declare the class for storing auxiliary variables for + * linear functions. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURYEQLFS_H +#define MINOTAURYEQLFS_H + +#include "Types.h" + +namespace Minotaur { +class LinearFunction; +typedef boost::shared_ptr LinearFunctionPtr; + +class YEqLFs +{ +public: + YEqLFs(UInt n); + VariablePtr findY(LinearFunctionPtr lf, double k); + void insert(VariablePtr auxvar, LinearFunctionPtr lf, double k); + +private: + DoubleVector k_; + std::vector lf_; + UInt n_; + DoubleVector rand_; + DoubleVector hash_; + VarVector y_; + double evalHash_(LinearFunctionPtr lf); +}; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/YEqMonomial.h b/thirdparty/linux/include/minotaur/YEqMonomial.h new file mode 100644 index 0000000..184588a --- /dev/null +++ b/thirdparty/linux/include/minotaur/YEqMonomial.h @@ -0,0 +1,57 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file YEqMonomial.h + * \brief Declare class for storing auxiliary variables for monomial + * expressions. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURYEQMONOMIAL_H +#define MINOTAURYEQMONOMIAL_H + +#include "Types.h" + +namespace Minotaur { + +class MultilinearTermsHandler; +class MonomialFunction; +class Variable; +typedef boost::shared_ptr MonomialFunPtr; +typedef boost::shared_ptr MultilinearTermsHandlerPtr; +typedef boost::shared_ptr VariablePtr; + + +class YEqMonomial +{ +public: + YEqMonomial(UInt n); + VariablePtr findY(MonomialFunPtr mf); + void insert(VariablePtr auxvar, MonomialFunPtr mf); + +private: + std::vector mf_; + DoubleVector hash_; + UInt n_; + DoubleVector rand_; + VarVector y_; + double evalHash_(MonomialFunPtr mf_); +}; +} + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/YEqUCGs.h b/thirdparty/linux/include/minotaur/YEqUCGs.h new file mode 100644 index 0000000..ca2f243 --- /dev/null +++ b/thirdparty/linux/include/minotaur/YEqUCGs.h @@ -0,0 +1,53 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file YEqUCGs.h + * \brief Declare the class for storing auxiliary variables for univariate + * nonlinear functions that are expressed as computational graphs. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURYEQUCGS_H +#define MINOTAURYEQUCGS_H + +#include "Types.h" +#include "OpCode.h" + +namespace Minotaur { +class CGraph; +class CNode; +typedef boost::shared_ptr CGraphPtr; + +class YEqUCGs { +public: + YEqUCGs(); + ~YEqUCGs(); + VariablePtr findY(CGraphPtr cg); + void insert(VariablePtr auxvar, CGraphPtr cg); + +private: + std::vector cg_; + DoubleVector hash_; + std::vector op_; + DoubleVector rand_; + VarVector x_; + VarVector y_; + double evalHash_(const CNode* node, UInt rank); +}; +} +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/minotaur/YEqVars.h b/thirdparty/linux/include/minotaur/YEqVars.h new file mode 100644 index 0000000..59d942b --- /dev/null +++ b/thirdparty/linux/include/minotaur/YEqVars.h @@ -0,0 +1,52 @@ +// +// MINOTAUR -- It's only 1/2 bull +// +// (C)opyright 2008 - 2014 The MINOTAUR Team. +// + +/** + * \file YEqVars.h + * \brief Declare class for storing auxiliary variables equivalent to a sum of + * a variable and a constant. + * \author Ashutosh Mahajan, Argonne National Laboratory + */ + +#ifndef MINOTAURYEQVARS_H +#define MINOTAURYEQVARS_H + +#include "Types.h" +#include "OpCode.h" + +namespace Minotaur { +class CNode; + +class YEqVars +{ +public: + YEqVars(UInt n); + VariablePtr findY(VariablePtr x, double k); + void insert(VariablePtr auxvar, VariablePtr x, double k); + +private: + DoubleVector k_; + UIntVector hash_; + UInt n_; + std::vector x_; + VarVector y_; +}; +} + + + +#endif + +// Local Variables: +// mode: c++ +// eval: (c-set-style "k&r") +// eval: (c-set-offset 'innamespace 0) +// eval: (setq c-basic-offset 2) +// eval: (setq fill-column 78) +// eval: (auto-fill-mode 1) +// eval: (setq column-number-mode 1) +// eval: (setq indent-tabs-mode nil) +// End: diff --git a/thirdparty/linux/include/ortools/algorithms/dense_doubly_linked_list.h b/thirdparty/linux/include/ortools/algorithms/dense_doubly_linked_list.h new file mode 100644 index 0000000..9610624 --- /dev/null +++ b/thirdparty/linux/include/ortools/algorithms/dense_doubly_linked_list.h @@ -0,0 +1,96 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_ALGORITHMS_DENSE_DOUBLY_LINKED_LIST_H_ +#define OR_TOOLS_ALGORITHMS_DENSE_DOUBLY_LINKED_LIST_H_ + +#include +#include "ortools/base/logging.h" + +namespace operations_research { + +// Specialized doubly-linked list that initially holds [0..n-1] in an arbitrary +// (user-specified) and fixed order. +// It then supports O(1) removal and access to the next and previous element of +// a given (non-removed) element. +// +// It is very fast and compact: it uses exactly 8*n bytes of memory. +class DenseDoublyLinkedList { + public: + // You can construct a DenseDoublyLinkedList with any range-iterable class + // that also has a size() method. The order of the elements is given by the + // user and will never change (modulo the removal of elements). + template + explicit DenseDoublyLinkedList(const T& sorted_elements); + + int Size() const { return next_.size(); } + + // Next() (resp. Prev()) must be called on elements that haven't yet been + // removed. They will return -1 if called on the last (resp. first) element. + int Next(int i) const; + int Prev(int i) const; + + // You must not call Remove() twice with the same element. + void Remove(int i); + + private: + std::vector next_; + std::vector prev_; +}; + +// Inline implementations (forced inline for the speed). + +inline int DenseDoublyLinkedList::Next(int i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i, Size()); + DCHECK_GE(next_[i], -1); + return next_[i]; +} + +inline int DenseDoublyLinkedList::Prev(int i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i, Size()); + DCHECK_GE(prev_[i], -1); + return prev_[i]; +} + +inline void DenseDoublyLinkedList::Remove(int i) { + const int prev = Prev(i); + const int next = Next(i); + if (prev >= 0) next_[prev] = next; + if (next >= 0) prev_[next] = prev; + if (DEBUG_MODE) next_[i] = prev_[i] = -2; // To catch bugs. +} + +template +DenseDoublyLinkedList::DenseDoublyLinkedList(const T& elements) + : next_(elements.size(), -2), prev_(elements.size(), -2) { + int last = -1; + for (const int e : elements) { + DCHECK_GE(e, 0); + DCHECK_LE(e, Size()); + DCHECK_EQ(-2, prev_[e]) << "Duplicate element: " << e; + prev_[e] = last; + if (last >= 0) next_[last] = e; + last = e; + } + if (!elements.empty()) next_[elements.back()] = -1; + if (DEBUG_MODE) { + for (int p : prev_) DCHECK_NE(-2, p); + for (int n : next_) DCHECK_NE(-2, n); + } +} + +} // namespace operations_research + +#endif // OR_TOOLS_ALGORITHMS_DENSE_DOUBLY_LINKED_LIST_H_ diff --git a/thirdparty/linux/include/ortools/algorithms/dynamic_partition.h b/thirdparty/linux/include/ortools/algorithms/dynamic_partition.h new file mode 100644 index 0000000..fe79fca --- /dev/null +++ b/thirdparty/linux/include/ortools/algorithms/dynamic_partition.h @@ -0,0 +1,344 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// TODO(user, fdid): refine this toplevel comment when this file settles. +// +// Two dynamic partition classes: one that incrementally splits a partition +// into more and more parts; one that incrementally merges a partition into less +// and less parts. +// +// GLOSSARY: +// The partition classes maintain a partition of N integers 0..N-1 +// (aka "elements") into disjoint equivalence classes (aka "parts"). +// +// SAFETY: +// Like std::vector crashes when used improperly, these classes are not "safe": +// most of their methods may crash if called with invalid arguments. The client +// code is responsible for using this class properly. A few DCHECKs() will help +// catch bugs, though. + +#ifndef OR_TOOLS_ALGORITHMS_DYNAMIC_PARTITION_H_ +#define OR_TOOLS_ALGORITHMS_DYNAMIC_PARTITION_H_ + +#include +#include +#include "ortools/base/logging.h" + +namespace operations_research { + +// Partition class that supports incremental splitting, with backtracking. +// See http://en.wikipedia.org/wiki/Partition_refinement . +// More precisely, the supported edit operations are: +// - Refine the partition so that a subset S (typically, |S| <<< N) +// of elements are all considered non-equivalent to any element in ¬S. +// Typically, this should be done in O(|S|). +// - Undo the above operations (backtracking). +// +// TODO(user): rename this to BacktrackableSplittingPartition. +class DynamicPartition { + public: + // Creates a DynamicPartition on n elements, numbered 0..n-1. Start with + // the trivial partition (only one subset containing all elements). + explicit DynamicPartition(int n); + + // Ditto, but specify the initial part of each elements. Part indices must + // form a dense integer set starting at 0; eg. [2, 1, 0, 1, 1, 3, 0] is valid. + explicit DynamicPartition(const std::vector& initial_part_of_element); + + // Accessors. + int NumElements() const { return element_.size(); } + const int NumParts() const { return part_.size(); } + + // To iterate over the elements in part #i: + // for (int element : partition.ElementsInPart(i)) { ... } + // + // ORDERING OF ELEMENTS INSIDE PARTS: the order of elements within a given + // part is volatile, and may change with Refine() or UndoRefine*() operations, + // even if the part itself doesn't change. + struct IterablePart; + IterablePart ElementsInPart(int i) const; + + int PartOf(int element) const; + int SizeOfPart(int part) const; + int ParentOfPart(int part) const; + + // A handy shortcut to ElementsInPart(PartOf(e)). The returned IterablePart + // will never be empty, since it contains at least i. + IterablePart ElementsInSamePartAs(int i) const; + + // Returns a fingerprint of the given part. While collisions are possible, + // their probability is quite low. Two parts that have the same size and the + // same fingerprint are most likely identical. + // Also, two parts that have the exact same set of elements will *always* + // have the same fingerprint. + uint64 FprintOfPart(int part) const; + + // Refines the partition such that elements that are in distinguished_subset + // never share the same part as elements that aren't in that subset. + // This might be a no-op: in that case, NumParts() won't change, but the + // order of elements inside each part may change. + // + // ORDERING OF PARTS: + // For each i such that Part #i has a non-trivial intersection with + // "distinguished_subset" (neither empty, nor the full Part); Part #i is + // stripped out of all elements that are in "distinguished_subset", and + // those elements are sent to a newly created part, whose parent_part = i. + // The parts newly created by a single Refine() operations are sorted + // by parent_part. + // Example: a Refine() on a partition with 6 parts causes parts #1, #3 and + // #4 to be split: the partition will now contain 3 new parts: part #6 (with + // parent_part = 1), part #7 (with parent_part = 3) and part #8 (with + // parent_part = 4). + // + // TODO(user): the graph symmetry finder could probably benefit a lot from + // keeping track of one additional bit of information for each part that + // remains unchanged by a Refine() operation: was that part entirely *in* + // the distinguished subset or entirely *out*? + void Refine(const std::vector& distinguished_subset); + + // Undo one or several Refine() operations, until the number of parts + // becomes equal to "original_num_parts". + // Prerequisite: NumParts() >= original_num_parts. + void UndoRefineUntilNumPartsEqual(int original_num_parts); + + // Dump the partition to a std::string. There might be different conventions for + // sorting the parts and the elements inside them. + enum DebugStringSorting { + // Elements are sorted within parts, and parts are then sorted + // lexicographically. + SORT_LEXICOGRAPHICALLY, + // Elements are sorted within parts, and parts are kept in order. + SORT_BY_PART, + }; + std::string DebugString(DebugStringSorting sorting) const; + + // ADVANCED USAGE: + // All elements (0..n-1) of the partition, sorted in a way that's compatible + // with the hierarchical partitioning: + // - All the elements of any given part are contiguous. + // - Elements of a part P are always after elements of part Parent(P). + // - The order remains identical (and the above property holds) after any + // UndoRefine*() operation. + // Note that the order does get changed by Refine() operations. + // This is a reference, so it'll only remain valid and constant until the + // class is destroyed or until Refine() get called. + const std::vector& ElementsInHierarchicalOrder() const { + return element_; + } + + private: + // A DynamicPartition instance maintains a list of all of its elements, + // 'sorted' by partitions: elements of the same subset are contiguous + // in that list. + std::vector element_; + + // The reverse of elements_[]: element_[index_of_[i]] = i. + std::vector index_of_; + + // part_of_[i] is the index of the part that contains element i. + std::vector part_of_; + + struct Part { + // This part holds elements[start_index .. end_index-1]. + // INVARIANT: end_index > start_index. + int start_index; // Inclusive + int end_index; // Exclusive + + // The Part that this part was split out of. See the comment at Refine(). + // INVARIANT: part[i].parent_part <= i, and the equality holds iff part[i] + // has no parent. + int parent_part; // Index into the part[] array. + + // The part's fingerprint is the XOR of all fingerprints of its elements. + // See FprintOfInt32() in the .cc. + uint64 fprint; + + Part() : start_index(0), end_index(0), parent_part(0), fprint(0) {} + Part(int s, int e, int p, uint64 fp) + : start_index(s), end_index(e), parent_part(p), fprint(fp) {} + }; + std::vector part_; // The disjoint parts. + + // Used temporarily and exclusively by Refine(). This prevents Refine() + // from being thread-safe. + // INVARIANT: tmp_counter_of_part_ contains only 0s before and after Refine(). + std::vector tmp_counter_of_part_; + std::vector tmp_affected_parts_; +}; + +struct DynamicPartition::IterablePart { + std::vector::const_iterator begin() const { return begin_; } + std::vector::const_iterator end() const { return end_; } + std::vector::const_iterator begin_; + std::vector::const_iterator end_; + + int size() const { return end_ - begin_; } + + IterablePart() {} + IterablePart(const std::vector::const_iterator& b, + const std::vector::const_iterator& e) + : begin_(b), end_(e) {} + + // These typedefs allow this iterator to be used within testing::ElementsAre. + typedef int value_type; + typedef std::vector::const_iterator const_iterator; +}; + +// Partition class that supports incremental merging, using the union-find +// algorithm (see http://en.wikipedia.org/wiki/Disjoint-set_data_structure). +class MergingPartition { + public: + // At first, all nodes are in their own singleton part. + MergingPartition() { Reset(0); } + explicit MergingPartition(int num_nodes) { Reset(num_nodes); } + void Reset(int num_nodes); + + int NumNodes() const { return parent_.size(); } + + // Complexity: amortized O(Ackermann⁻¹(N)) -- which is essentially O(1) -- + // where N is the number of nodes. + // + // Return value: If this merge caused a representative node (of either node1 + // or node2) to stop being a representative (because only one can remain); + // this method returns that removed representative. Otherwise it returns -1. + // + // Details: a smaller part will always be merged onto a larger one. + // Upons ties, the smaller representative becomes the overall representative. + int MergePartsOf(int node1, int node2); // The 'union' of the union-find. + + // Get the representative of "node" (a node in the same equivalence class, + // which will also be returned for any other "node" in the same class). + // The complexity if the same as MergePartsOf(). + int GetRootAndCompressPath(int node); + + // Specialized reader API: prunes "nodes" to only keep at most one node per + // part: any node which is in the same part as an earlier node will be pruned. + void KeepOnlyOneNodePerPart(std::vector* nodes); + + // Output the whole partition as node equivalence classes: if there are K + // parts and N nodes, node_equivalence_classes[i] will contain the part index + // (a number in 0..K-1) of node #i. Parts will be sorted by their first node + // (i.e. node 0 will always be in part 0; then the next node that isn't in + // part 0 will be in part 1, and so on). + // Returns the number K of classes. + int FillEquivalenceClasses(std::vector* node_equivalence_classes); + + // Dump all components, with nodes sorted within each part and parts + // sorted lexicographically. Eg. "0 1 3 4 | 2 5 | 6 7 8". + std::string DebugString(); + + // Advanced usage: sets 'node' to be in its original singleton. All nodes + // who may point to 'node' as a parent will remain in an inconsistent state. + // This can be used to reinitialize a MergingPartition that has been sparsely + // modified in O(|modifications|). + // CRASHES IF USED INCORRECTLY. + void ResetNode(int node); + + int NumNodesInSamePartAs(int node) { + return part_size_[GetRootAndCompressPath(node)]; + } + + // FOR DEBUGGING OR SPECIAL "CONST" ACCESS ONLY: + // Find the root of the union-find tree with leaf 'node', i.e. its + // representative node, but don't use path compression. + // The amortized complexity can be as bad as log(N), as opposed to the + // version using path compression. + int GetRoot(int node) const; + + private: + // Along the upwards path from 'node' to its root, set the parent of all + // nodes (including the root) to 'parent'. + void SetParentAlongPathToRoot(int node, int parent); + + std::vector parent_; + std::vector part_size_; + + // Used transiently by KeepOnlyOneNodePerPart(). + std::vector tmp_part_bit_; +}; + +// *** Implementation of inline methods of the above classes. *** + +inline DynamicPartition::IterablePart DynamicPartition::ElementsInPart(int i) + const { + DCHECK_GE(i, 0); + DCHECK_LT(i, NumParts()); + return IterablePart(element_.begin() + part_[i].start_index, + element_.begin() + part_[i].end_index); +} + +inline int DynamicPartition::PartOf(int element) const { + DCHECK_GE(element, 0); + DCHECK_LT(element, part_of_.size()); + return part_of_[element]; +} + +inline int DynamicPartition::SizeOfPart(int part) const { + DCHECK_GE(part, 0); + DCHECK_LT(part, part_.size()); + const Part& p = part_[part]; + return p.end_index - p.start_index; +} + +inline int DynamicPartition::ParentOfPart(int part) const { + DCHECK_GE(part, 0); + DCHECK_LT(part, part_.size()); + return part_[part].parent_part; +} + +inline DynamicPartition::IterablePart DynamicPartition::ElementsInSamePartAs( + int i) const { + return ElementsInPart(PartOf(i)); +} + +inline uint64 DynamicPartition::FprintOfPart(int part) const { + DCHECK_GE(part, 0); + DCHECK_LT(part, part_.size()); + return part_[part].fprint; +} + +inline int MergingPartition::GetRoot(int node) const { + DCHECK_GE(node, 0); + DCHECK_LT(node, NumNodes()); + int child = node; + while (true) { + const int parent = parent_[child]; + if (parent == child) return child; + child = parent; + } +} + +inline void MergingPartition::SetParentAlongPathToRoot(int node, int parent) { + DCHECK_GE(node, 0); + DCHECK_LT(node, NumNodes()); + DCHECK_GE(parent, 0); + DCHECK_LT(parent, NumNodes()); + int child = node; + while (true) { + const int old_parent = parent_[child]; + parent_[child] = parent; + if (old_parent == child) return; + child = old_parent; + } +} + +inline void MergingPartition::ResetNode(int node) { + DCHECK_GE(node, 0); + DCHECK_LT(node, NumNodes()); + parent_[node] = node; + part_size_[node] = 1; +} + +} // namespace operations_research + +#endif // OR_TOOLS_ALGORITHMS_DYNAMIC_PARTITION_H_ diff --git a/thirdparty/linux/include/ortools/algorithms/dynamic_permutation.h b/thirdparty/linux/include/ortools/algorithms/dynamic_permutation.h new file mode 100644 index 0000000..d8dac7f --- /dev/null +++ b/thirdparty/linux/include/ortools/algorithms/dynamic_permutation.h @@ -0,0 +1,133 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_ALGORITHMS_DYNAMIC_PERMUTATION_H_ +#define OR_TOOLS_ALGORITHMS_DYNAMIC_PERMUTATION_H_ + +#include +#include // TODO(user): remove when no longer used. +#include + +#include "ortools/base/logging.h" + +namespace operations_research { + +class SparsePermutation; + +// Maintains a 'partial' permutation of [0..n-1] onto itself, with a dynamic +// API allowing it to be built incrementally, and allowing some backtracking. +// This is tuned for a specific usage by ./find_graph_symmetries.cc. +// +// RAM usage: as of 2014-04, this class needs less than: +// 32.125 * (n + 2 * support_size) bytes. +class DynamicPermutation { + public: + // Upon construction, every element i in [0..n-1] maps to itself. + explicit DynamicPermutation(int n); + + int Size() const { return image_.size(); } // Return the original "n". + + // Declares a set of mappings for this permutation: src[i] will map to dst[i]. + // Requirements that are DCHECKed: + // - "src" and "dst" must have the same size. + // - For all i, src[i] must not already be mapped to something. + // - For all i, dst[i] must not already be the image of something. + // + // Complexity: amortized O(src.size()). + void AddMappings(const std::vector& src, const std::vector& dst); + + // Undoes the last AddMappings() operation, and fills the "undone_mapping_src" + // vector with the src of that last operation. This works like an undo stack. + // For example, applying the sequence (Add, Add, Add, Undo, Add, Undo, Undo) + // has exactly the same effect as applying the first Add() alone. + // If you call this too may times (i.e. there is nothing left to undo), it is + // simply a no-op. + // + // Complexity: same as the AddMappings() operation being undone. + void UndoLastMappings(std::vector* undone_mapping_src); + + // Makes the permutation back to the identity (i.e. like right after + // construction). + // Complexity: O(support size). + void Reset(); + + int ImageOf(int i) const; // Complexity: one vector lookup. + + // Returns the union of all "src" ever given to AddMappings(). + const std::vector& AllMappingsSrc() const { return mapping_src_stack_; } + + // While the permutation is partially being built, the orbit of elements will + // either form unclosed paths, or closed cycles. In the former case, + // RootOf(i) returns the start of the path where i lies. If i is on a cycle, + // RootOf(i) will return some element of its cycle (meaning that if i maps to + // itself, RootOf(i) = i). + // + // Complexity: O(log(orbit size)) in average, assuming that the mappings are + // added in a random order. O(orbit size) in the worst case. + int RootOf(int i) const; + + // The exhaustive set of the 'loose end' of the incomplete cycles + // (e.g., paths) built so far. + // TODO(user): use a faster underlying container like SparseBitSet, and + // tweak this API accordingly. + const std::set& LooseEnds() const { return loose_ends_; } + + // Creates a SparsePermutation representing the current permutation. + // Requirements: the permutation must only have cycles. + // + // Complexity: O(support size). + std::unique_ptr CreateSparsePermutation() const; + + std::string DebugString() const; + + private: + std::vector image_; + // ancestor_[i] isn't exactly RootOf(i): it might itself have an ancestor, and + // so on. + std::vector ancestor_; + + // The concatenation of all "src" ever given to AddMappings(), and their + // sizes, to implement the undo stack. Note that "mapping_src_stack_" contains + // exactly the support of the permutation. + std::vector mapping_src_stack_; + std::vector mapping_src_size_stack_; + + // See the homonymous accessor, above. + std::set loose_ends_; + + // Used transiently by CreateSparsePermutation(). Its resting state is: + // size=Size(), all elements are false. + mutable std::vector tmp_mask_; +}; + +// Forced-inline for the speed. +inline int DynamicPermutation::ImageOf(int i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i, Size()); + return image_[i]; +} + +// Forced-inline for the speed. +inline int DynamicPermutation::RootOf(int i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i, Size()); + while (true) { + const int j = ancestor_[i]; + if (j == i) return i; + i = j; + } +} + +} // namespace operations_research + +#endif // OR_TOOLS_ALGORITHMS_DYNAMIC_PERMUTATION_H_ diff --git a/thirdparty/linux/include/ortools/algorithms/find_graph_symmetries.h b/thirdparty/linux/include/ortools/algorithms/find_graph_symmetries.h new file mode 100644 index 0000000..e5e1fe9 --- /dev/null +++ b/thirdparty/linux/include/ortools/algorithms/find_graph_symmetries.h @@ -0,0 +1,336 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This class solves the graph automorphism problem +// (https://en.wikipedia.org/wiki/Graph_automorphism), a variant of the famous +// graph isomorphism problem (https://en.wikipedia.org/wiki/Graph_isomorphism). +// +// The algorithm is largely based on the following article, published in 2008: +// "Faster Symmetry Discovery using Sparsity of Symmetries" by Darga, Sakallah +// and Markov. http://web.eecs.umich.edu/~imarkov/pubs/conf/dac08-sym.pdf. +// +// See the comments on the class below for more details. + +#ifndef OR_TOOLS_ALGORITHMS_FIND_GRAPH_SYMMETRIES_H_ +#define OR_TOOLS_ALGORITHMS_FIND_GRAPH_SYMMETRIES_H_ + +#include +#include + +#include "ortools/algorithms/dynamic_partition.h" +#include "ortools/algorithms/dynamic_permutation.h" +#include "ortools/graph/graph.h" +#include "ortools/util/iterators.h" +#include "ortools/util/stats.h" +#include "ortools/util/time_limit.h" +#include "ortools/base/status.h" + +namespace operations_research { + +class SparsePermutation; + +class GraphSymmetryFinder { + public: + typedef StaticGraph<> Graph; + + // If the Graph passed to the GraphSymmetryFinder is undirected, i.e. + // for every arc a->b, b->a is also present, then you should set + // "is_undirected" to true. + // This will, in effect, DCHECK() that the graph is indeed undirected, + // and bypass the need for reverse adjacency lists. + // + // If you don't know this in advance, you may use GraphIsSymmetric() from + // ortools/graph/util.h. + // + // "graph" must not have multi-arcs. + // TODO(user): support multi-arcs. + GraphSymmetryFinder(const Graph& graph, bool is_undirected); + + // Whether the given permutation is an automorphism of the graph given at + // construction. This costs O(sum(degree(x))) (the sum is over all nodes x + // that are displaced by the permutation). + bool IsGraphAutomorphism(const DynamicPermutation& permutation) const; + + // Find a set of generators of the automorphism subgroup of the graph that + // respects the given node equivalence classes. The generators are themselves + // permutations of the nodes: see http://en.wikipedia.org/wiki/Automorphism. + // These permutations may only map a node onto a node of its equivalence + // class: two nodes i and j are in the same equivalence class iff + // node_equivalence_classes_io[i] == node_equivalence_classes_io[j]; + // + // This set of generators is not necessarily the smallest possible (neither in + // the number of generators, nor in the size of these generators), but it is + // minimal in that no generator can be removed while keeping the generated + // group intact. + // TODO(user): verify the minimality in unit tests. + // + // Note that if "generators" is empty, then the graph has no symmetry: the + // only automorphism is the identity. + // + // The equivalence classes are actually an input/output: they are refined + // according to all asymmetries found. In the end, n1 and n2 will be + // considered equivalent (i.e. node_equivalence_classes_io[n1] == + // node_equivalence_classes_io[n2]) if and only if there exists a + // permutation of nodes that: + // - keeps the graph invariant + // - maps n1 onto n2 + // - maps each node to a node of its original equivalence class. + // + // This method also outputs the size of the automorphism group, expressed as + // a factorized product of integers (note that the size itself may be as + // large as N!). + // + // DEADLINE AND PARTIAL COMPLETION: + // If the deadline passed as argument is reached, this method will return + // quickly (within a few milliseconds). The outputs may be partially filled: + // - Each element of "generators", if non-empty, will be a valid permutation. + // - "node_equivalence_classes_io" will contain the equivalence classes + // corresponding to the orbits under all the generators in "generators". + // - "factorized_automorphism_group_size" will also be incomplete, and + // partially valid: its last element may be undervalued. But all prior + // elements are valid factors of the automorphism group size. + util::Status FindSymmetries( + double time_limit_seconds, std::vector* node_equivalence_classes_io, + std::vector>* generators, + std::vector* factorized_automorphism_group_size); + + // **** Methods below are public FOR TESTING ONLY. **** + + // Fully refine the partition of nodes, using the graph as symmetry breaker. + // This means applying the following steps on each part P of the partition: + // - Compute the aggregated in-degree of all nodes of the graph, only looking + // at arcs originating from nodes in P. + // - For each in-degree d=1...max_in_degree, refine the partition by the set + // of nodes with in-degree d. + // And recursively applying it on all new or modified parts. + // + // In our use cases, we may call this in a scenario where the partition was + // already partially refined on all parts #0...#K, then you should set + // "first_unrefined_part_index" to K+1. + void RecursivelyRefinePartitionByAdjacency( + int first_unrefined_part_index, DynamicPartition* partition); + + // Special wrapper of the above method: assuming that partition is already + // fully refined, further refine it by {node}, and propagate by adjacency. + // Also, optionally collect all the new singletons of the partition in + // "new_singletons", sorted by their part number in the partition. + void DistinguishNodeInPartition(int node, DynamicPartition* partition, + std::vector* new_singletons_or_null); + + private: + const Graph& graph_; + + inline int NumNodes() const { return graph_.num_nodes(); } + + // If the graph isn't symmetric, then we store the reverse adjacency lists + // here: for each i in 0..NumNodes()-1, the list of nodes that have an + // outgoing arc to i is stored (sorted by node) in: + // flattened_reverse_adj_lists_[reverse_adj_list_index_[i] ... + // reverse_adj_list_index_[i + 1]] + // and can be iterated on easily with: + // for (const int tail : TailsOfIncomingArcsTo(node)) ... + // + // If the graph was specified as symmetric upon construction, both these + // vectors are empty, and TailsOfIncomingArcsTo() crashes. + std::vector flattened_reverse_adj_lists_; + std::vector reverse_adj_list_index_; + BeginEndWrapper::const_iterator> TailsOfIncomingArcsTo( + int node) const; + + // Deadline management. Populated upon FindSymmetries(). + mutable std::unique_ptr time_limit_; + + // Internal search code used in FindSymmetries(), split out for readability: + // find one permutation (if it exists) that maps root_node to root_image_node + // and such that the image of "base_partition" by that permutation is equal to + // the "image_partition". If no such permutation exists, returns nullptr. + // + // "generators_found_so_far" and "permutations_displacing_node" are used for + // pruning in the search. The former is just the "generators" vector of + // FindGraphSymmetries(), with the permutations found so far; and the latter + // is an inverted index from each node to all permutations (that we found) + // that displace it. + std::unique_ptr FindOneSuitablePermutation( + int root_node, int root_image_node, DynamicPartition* base_partition, + DynamicPartition* image_partition, + const std::vector>& + generators_found_so_far, + const std::vector>& permutations_displacing_node); + + // Data structure used by FindOneSuitablePermutation(). See the .cc + struct SearchState { + int base_node; + + // We're tentatively mapping "base_node" to some image node. At first, we + // just pick a single candidate: we fill "first_image_node". If this + // candidate doesn't work out, we'll select all other candidates in the same + // image part, prune them by the symmetries we found already, and put them + // in "remaining_pruned_image_nodes" (and set "first_image_node" to -1). + int first_image_node; + std::vector remaining_pruned_image_nodes; + + int num_parts_before_trying_to_map_base_node; + + // Only parts that are at or beyond this index, or their parent parts, may + // be mismatching between the base and the image partitions. + int min_potential_mismatching_part_index; + + SearchState(int bn, int in, int np, int mi) + : base_node(bn), + first_image_node(in), + num_parts_before_trying_to_map_base_node(np), + min_potential_mismatching_part_index(mi) {} + + std::string DebugString() const; + }; + std::vector search_states_; + + // Subroutine of FindOneSuitablePermutation(), split out for modularity: + // With the partial candidate mapping given by "base_partition", + // "image_partition" and "current_permutation_candidate", determine whether + // we have a full match (eg. the permutation is a valid candidate). + // If so, simply return true. If not, return false but also fill + // "next_base_node" and "next_image_node" with what should be the next mapping + // decision. + // + // This also uses and updates "min_potential_mismatching_part_index_io" + // to incrementally search for mismatching parts along the partitions. + // + // Note(user): there may be false positives, i.e. this method may return true + // even if the partitions aren't actually a full match, because it uses + // fingerprints to compare part. This should almost never happen. + bool ConfirmFullMatchOrFindNextMappingDecision( + const DynamicPartition& base_partition, + const DynamicPartition& image_partition, + const DynamicPermutation& current_permutation_candidate, + int* min_potential_mismatching_part_index_io, int* next_base_node, + int* next_image_node) const; + + // Subroutine of FindOneSuitablePermutation(), split out for modularity: + // Keep only one node of "nodes" per orbit, where the orbits are described + // by a subset of "all_permutations": the ones with indices in + // "permutation_indices" and that are compatible with "partition". + // For each orbit, keep the first node that appears in "nodes". + void PruneOrbitsUnderPermutationsCompatibleWithPartition( + const DynamicPartition& partition, + const std::vector>& all_permutations, + const std::vector& permutation_indices, std::vector* nodes); + + // Temporary objects used by some of the class methods, and owned by the + // class to avoid (costly) re-allocation. Their resting states are described + // in the side comments; with N = NumNodes(). + DynamicPermutation tmp_dynamic_permutation_; // Identity(N) + mutable std::vector tmp_node_mask_; // [0..N-1] = false + std::vector tmp_degree_; // [0..N-1] = 0. + std::vector tmp_stack_; // Empty. + std::vector> tmp_nodes_with_degree_; // [0..N-1] = []. + MergingPartition tmp_partition_; // Reset(N). + std::vector tmp_compatible_permutations_; // Empty. + + // Internal statistics, used for performance tuning and debugging. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("GraphSymmetryFinder"), + initialization_time( + "a Initialization", this), + initialization_refine_time( + "b ┗╸Refine", this), + invariant_dive_time( + "c Invariant Dive", this), + main_search_time( + "d Main Search", this), + invariant_unroll_time( + "e ┣╸Dive unroll", this), + permutation_output_time( + "f ┣╸Permutation output", this), + search_time( + "g ┗╸FindOneSuitablePermutation()", this), + search_time_fail( + "h ┣╸Fail", this), + search_time_success( + "i ┣╸Success", this), + initial_search_refine_time( + "j ┣╸Initial refine", this), + search_refine_time( + "k ┣╸Further refines", this), + quick_compatibility_time( + "l ┣╸Compatibility checks", this), + quick_compatibility_fail_time( + "m ┃ ┣╸Fail", this), + quick_compatibility_success_time( + "n ┃ ┗╸Success", this), + dynamic_permutation_refinement_time( + "o ┣╸Dynamic permutation refinement", this), + map_election_std_time( + "p ┣╸Mapping election / full match detection", this), + map_election_std_mapping_time( + "q ┃ ┣╸Mapping elected", this), + map_election_std_full_match_time( + "r ┃ ┗╸Full Match", this), + automorphism_test_time( + "s ┣╸[Upon full match] Automorphism check", this), + automorphism_test_fail_time( + "t ┃ ┣╸Fail", this), + automorphism_test_success_time( + "u ┃ ┗╸Success", this), + search_finalize_time( + "v ┣╸[Upon auto success] Finalization", this), + dynamic_permutation_undo_time( + "w ┣╸[Upon auto fail, full] Dynamic permutation undo", this), + map_reelection_time( + "x ┣╸[Upon auto fail, partial] Mapping re-election", this), + non_singleton_search_time( + "y ┃ ┗╸Non-singleton search", this), + backtracking_time( + "z ┗╸Backtracking", this), + pruning_time( + "{ ┗╸Pruning", this), + search_depth( + "~ Search Stats: search_depth", this) {} + + TimeDistribution initialization_time; + TimeDistribution initialization_refine_time; + TimeDistribution invariant_dive_time; + TimeDistribution main_search_time; + TimeDistribution invariant_unroll_time; + TimeDistribution permutation_output_time; + TimeDistribution search_time; + TimeDistribution search_time_fail; + TimeDistribution search_time_success; + TimeDistribution initial_search_refine_time; + TimeDistribution search_refine_time; + TimeDistribution quick_compatibility_time; + TimeDistribution quick_compatibility_fail_time; + TimeDistribution quick_compatibility_success_time; + TimeDistribution dynamic_permutation_refinement_time; + TimeDistribution map_election_std_time; + TimeDistribution map_election_std_mapping_time; + TimeDistribution map_election_std_full_match_time; + TimeDistribution automorphism_test_time; + TimeDistribution automorphism_test_fail_time; + TimeDistribution automorphism_test_success_time; + TimeDistribution search_finalize_time; + TimeDistribution dynamic_permutation_undo_time; + TimeDistribution map_reelection_time; + TimeDistribution non_singleton_search_time; + TimeDistribution backtracking_time; + TimeDistribution pruning_time; + + IntegerDistribution search_depth; + }; + mutable Stats stats_; +}; + +} // namespace operations_research + +#endif // OR_TOOLS_ALGORITHMS_FIND_GRAPH_SYMMETRIES_H_ diff --git a/thirdparty/linux/include/ortools/algorithms/hungarian.h b/thirdparty/linux/include/ortools/algorithms/hungarian.h new file mode 100644 index 0000000..a23b884 --- /dev/null +++ b/thirdparty/linux/include/ortools/algorithms/hungarian.h @@ -0,0 +1,55 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// IMPORTANT NOTE: we advise using the code in +// graph/linear_assignment.h whose complexity is +// usually much smaller. +// TODO(user): base this code on LinearSumAssignment. +// + +// An O(n^4) implementation of the Kuhn-Munkres algorithm (a.k.a. the +// Hungarian algorithm) for solving the assignment problem. +// The assignment problem takes a set of agents, a set of tasks and a +// cost associated with assigning each agent to each task and produces +// an optimal (i.e., least cost) assignment of agents to tasks. +// The code also enables computing a maximum assignment by changing the +// input matrix. +// +// This code is based on (read: translated from) the Java version +// (read: translated from) the Python version at +// http://www.clapper.org/software/python/munkres/ +// which in turn is based on +// http://www.public.iastate.edu/~ddoty/HungarianAlgorithm.html. + +#ifndef OR_TOOLS_ALGORITHMS_HUNGARIAN_H_ +#define OR_TOOLS_ALGORITHMS_HUNGARIAN_H_ + +#include +#include + +namespace operations_research { + +// See IMPORTANT NOTE at the top of the file. +void MinimizeLinearAssignment(const std::vector >& cost, + std::unordered_map* direct_assignment, + std::unordered_map* reverse_assignment); + +// See IMPORTANT NOTE at the top of the file. +void MaximizeLinearAssignment(const std::vector >& cost, + std::unordered_map* direct_assignment, + std::unordered_map* reverse_assignment); + +} // namespace operations_research + +#endif // OR_TOOLS_ALGORITHMS_HUNGARIAN_H_ diff --git a/thirdparty/linux/include/ortools/algorithms/knapsack_solver.h b/thirdparty/linux/include/ortools/algorithms/knapsack_solver.h new file mode 100644 index 0000000..194cbc5 --- /dev/null +++ b/thirdparty/linux/include/ortools/algorithms/knapsack_solver.h @@ -0,0 +1,599 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// This library solves knapsacks: +// - 0-1 knapsack problems, +// - Multi-dimensional knapsack problems, +// - TODO(user) Multi-dimensional knapsack problem with n-ary conflicts +// between items. +// +// Given n items, each with a profit and a weight, given a knapsack of +// capacity c, the goal is to find a subset of items which fits inside c +// and maximizes the total profit. +// The knapsack problem can easily be extended from 1 to d dimensions. +// As an example, this can be useful to constrain the maximum number of +// items inside the knapsack. +// Without loss of generality, profits and weights are assumed to be positive. +// +// From a mathematical point of view, the multi-dimensional knapsack problem +// can be modeled by d linear constraints: +// ForEach(j:1..d)(Sum(i:1..n)(weight_ij * item_i) <= c_j +// where item_i is a 0-1 integer variable. +// Then the goal is to maximize: Sum(i:1..n)(profit_i * item_i). +// +// There are several ways to solve knapsack problems. One of the most +// efficient ways is based on dynamic programming (mainly when weights, profits +// and dimensions are small, the algorithm runs in pseudo polynomial time). +// Unfortunately when adding conflict constraints the problem becomes strongly +// NP-hard, i.e. there is no pseudo-polynomial algorithm to solve it. +// That's the reason why the most of the following code is based on branch and +// bound search. +// +// For instance to solve a 2-dimension knapsack problem with 9 items, +// one just has to feed a profit vector with the 9 profits, a vector of 2 +// vectors for weights, and a vector of capacities. +// E.g.: +// vector: profits = [1, 2, 3, 4, 5, 6, 7, 8, 9] +// vector of vector: weights = [ [1, 2, 3, 4, 5, 6, 7, 8, 9], +// [1, 1, 1, 1, 1, 1, 1, 1, 1]] +// vector: capacities = [34, 4] +// And then: +// KnapsackSolver solver(KnapsackSolver::KNAPSACK_MULTIDIMENSION_SOLVER, +// "Multi-dimensional solver"); +// solver.Init(profits, weights, capacities); +// int64 profit = solver.Solve(); + +#ifndef OR_TOOLS_ALGORITHMS_KNAPSACK_SOLVER_H_ +#define OR_TOOLS_ALGORITHMS_KNAPSACK_SOLVER_H_ + +#include +#include +#include +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { + +// ----- KnapsackSolver ----- +// KnapsackSolver is a factory for knapsack solvers. Several solvers are +// implemented, some can deal with a limited number of items, some can deal with +// several dimensions... +// Currently 4 algorithms are implemented: +// - KNAPSACK_BRUTE_FORCE_SOLVER: Limited to 30 items and one dimension, this +// solver uses a brute force algorithm, ie. explores all possible states. +// Experiments show competitive performance for instances with less than +// 15 items. +// - KNAPSACK_64ITEMS_SOLVER: Limited to 64 items and one dimension, this +// solver uses a branch & bound algorithm. This solver is about 4 times +// faster than KNAPSACK_MULTIDIMENSION_SOLVER. +// - KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER: Limited to one dimension, this solver +// is based on a dynamic programming algorithm. The time and space +// complexity is O(capacity * number_of_items). +// - KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER: This solver can deal +// with both large number of items and several dimensions. This solver is +// based on branch and bound. +// - KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER: This solver can deal with both +// large number of items and several dimensions. This solver is based on +// Integer Programming solver CBC. +// - KNAPSACK_MULTIDIMENSION_GLPK_MIP_SOLVER: This solver can deal with both +// large number of items and several dimensions. This solver is based on +// Integer Programming solver GLPK. +// +// KnapsackSolver also implements a problem reduction algorithm based on lower +// and upper bounds (see Ingargolia and Korsh: A reduction algorithm for +// zero-one single knapsack problems. Management Science, 1973). This reduction +// method is preferred to better algorithms (see, for instance, Martello +// and Toth: A new algorithm for the 0-1 knapsack problem. Management Science, +// 1988), because it remains valid with more complex problems, e.g., +// multi-dimensional, conflicts... +// +// The main idea is to compute lower and upper bounds for each item in or out +// of the knapsack; if the best lower bound is strictly greater than the upper +// bound when an item is in, then this item is surely not in the optimal +// solution. +class BaseKnapsackSolver; + +class KnapsackSolver { + public: + enum SolverType { + KNAPSACK_BRUTE_FORCE_SOLVER = 0, + KNAPSACK_64ITEMS_SOLVER = 1, + KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER = 2, + #if defined(USE_CBC) + KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER = 3, + #endif // USE_CBC + #if defined(USE_GLPK) + KNAPSACK_MULTIDIMENSION_GLPK_MIP_SOLVER = 4, + #endif // USE_GLPK + KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER = 5, + #if defined(USE_SCIP) + KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER = 6, + #endif // USE_SCIP + }; + + explicit KnapsackSolver(const std::string& solver_name); + KnapsackSolver(SolverType solver_type, const std::string& solver_name); + virtual ~KnapsackSolver(); + + // Initializes the solver and enters the problem to be solved. + void Init(const std::vector& profits, + const std::vector >& weights, + const std::vector& capacities); + + // Solves the problem and returns the profit of the optimal solution. + int64 Solve(); + + // Returns true if the item 'item_id' is packed in the optimal knapsack. + bool BestSolutionContains(int item_id) const; + // Returns true if the solution was proven optimal. + bool IsSolutionOptimal() const { return is_solution_optimal_; } + std::string GetName() const; + + bool use_reduction() const { return use_reduction_; } + void set_use_reduction(bool use_reduction) { use_reduction_ = use_reduction; } + + // Time limit in seconds. When a finite time limit is set the solution + // obtained might not be optimal if the limit is reached. + void set_time_limit(double time_limit_seconds) { + time_limit_seconds_ = time_limit_seconds; + } + + private: + // Trivial reduction of capacity constraints when the capacity is higher than + // the sum of the weights of the items. Returns the number of reduced items. + int ReduceCapacities(int num_items, + const std::vector >& weights, + const std::vector& capacities, + std::vector >* reduced_weights, + std::vector* reduced_capacities); + int ReduceProblem(int num_items); + void ComputeAdditionalProfit(const std::vector& profits); + void InitReducedProblem(const std::vector& profits, + const std::vector >& weights, + const std::vector& capacities); + + std::unique_ptr solver_; + std::vector known_value_; + std::vector best_solution_; + bool is_solution_optimal_ = false; + std::vector mapping_reduced_item_id_; + bool is_problem_solved_; + int64 additional_profit_; + bool use_reduction_; + double time_limit_seconds_; + std::unique_ptr time_limit_; + + DISALLOW_COPY_AND_ASSIGN(KnapsackSolver); +}; + +#if !defined(SWIG) +// The following code defines needed classes for the KnapsackGenericSolver +// class which is the entry point to extend knapsack with new constraints such +// as conflicts between items. +// +// Constraints are enforced using KnapsackPropagator objects, in the current +// code there is one propagator per dimension (KnapsackCapacityPropagator). +// One of those propagators, named master propagator, is used to guide the +// search, i.e. decides which item should be assigned next. +// Roughly speaking the search algorithm is: +// - While not optimal +// - Select next search node to expand +// - Select next item_i to assign (using master propagator) +// - Generate a new search node where item_i is in the knapsack +// - Check validity of this new partial solution (using propagators) +// - If valid, add this new search node to the search +// - Generate a new search node where item_i is not in the knapsack +// - Check validity of this new partial solution (using propagators) +// - If valid, add this new search node to the search +// +// TODO(user): Add a new propagator class for conflict constraint. +// TODO(user): Add a new propagator class used as a guide when the problem has +// several dimensions. + +// ----- KnapsackAssignement ----- +// KnapsackAssignement is a small struct used to pair an item with its +// assignment. It is mainly used for search nodes and updates. +struct KnapsackAssignment { + KnapsackAssignment(int _item_id, bool _is_in) + : item_id(_item_id), is_in(_is_in) {} + int item_id; + bool is_in; +}; + +// ----- KnapsackItem ----- +// KnapsackItem is a small struct to pair an item weight with its +// corresponding profit. +// The aim of the knapsack problem is to pack as many valuable items as +// possible. A straight forward heuristic is to take those with the greatest +// profit-per-unit-weight. This ratio is called efficiency in this +// implementation. So items will be grouped in vectors, and sorted by +// decreasing efficiency. +// Note that profits are duplicated for each dimension. This is done to +// simplify the code, especially the GetEfficiency method and vector sorting. +// As there usually are only few dimensions, the overhead should not be an +// issue. +struct KnapsackItem { + KnapsackItem(int _id, int64 _weight, int64 _profit) + : id(_id), weight(_weight), profit(_profit) {} + double GetEfficiency(int64 profit_max) const { + return (weight > 0) + ? static_cast(profit) / static_cast(weight) + : static_cast(profit_max); + } + + // The 'id' field is used to retrieve the initial item in order to + // communicate with other propagators and state. + const int id; + const int64 weight; + const int64 profit; +}; +typedef KnapsackItem* KnapsackItemPtr; + +// ----- KnapsackSearchNode ----- +// KnapsackSearchNode is a class used to describe a decision in the decision +// search tree. +// The node is defined by a pointer to the parent search node and an +// assignment (see KnapsackAssignement). +// As the current state is not explicitly stored in a search node, one should +// go through the search tree to incrementally build a partial solution from +// a previous search node. +class KnapsackSearchNode { + public: + KnapsackSearchNode(const KnapsackSearchNode* const parent, + const KnapsackAssignment& assignment); + int depth() const { return depth_; } + const KnapsackSearchNode* const parent() const { return parent_; } + const KnapsackAssignment& assignment() const { return assignment_; } + + int64 current_profit() const { return current_profit_; } + void set_current_profit(int64 profit) { current_profit_ = profit; } + + int64 profit_upper_bound() const { return profit_upper_bound_; } + void set_profit_upper_bound(int64 profit) { profit_upper_bound_ = profit; } + + int next_item_id() const { return next_item_id_; } + void set_next_item_id(int id) { next_item_id_ = id; } + + private: + // 'depth' field is used to navigate efficiently through the search tree + // (see KnapsackSearchPath). + int depth_; + const KnapsackSearchNode* const parent_; + KnapsackAssignment assignment_; + + // 'current_profit' and 'profit_upper_bound' fields are used to sort search + // nodes using a priority queue. That allows to pop the node with the best + // upper bound, and more importantly to stop the search when optimality is + // proved. + int64 current_profit_; + int64 profit_upper_bound_; + + // 'next_item_id' field allows to avoid an O(number_of_items) scan to find + // next item to select. This is done for free by the upper bound computation. + int next_item_id_; + + DISALLOW_COPY_AND_ASSIGN(KnapsackSearchNode); +}; + +// ----- KnapsackSearchPath ----- +// KnapsackSearchPath is a small class used to represent the path between a +// node to another node in the search tree. +// As the solution state is not stored for each search node, the state should +// be rebuilt at each node. One simple solution is to apply all decisions +// between the node 'to' and the root. This can be computed in +// O(number_of_items). +// +// However, it is possible to achieve better average complexity. Two +// consecutively explored nodes are usually close enough (i.e., much less than +// number_of_items) to benefit from an incremental update from the node +// 'from' to the node 'to'. +// +// The 'via' field is the common parent of 'from' field and 'to' field. +// So the state can be built by reverting all decisions from 'from' to 'via' +// and then applying all decisions from 'via' to 'to'. +class KnapsackSearchPath { + public: + KnapsackSearchPath(const KnapsackSearchNode& from, + const KnapsackSearchNode& to); + void Init(); + const KnapsackSearchNode& from() const { return from_; } + const KnapsackSearchNode& via() const { return *via_; } + const KnapsackSearchNode& to() const { return to_; } + const KnapsackSearchNode* MoveUpToDepth(const KnapsackSearchNode& node, + int depth) const; + + private: + const KnapsackSearchNode& from_; + const KnapsackSearchNode* via_; // Computed in 'Init'. + const KnapsackSearchNode& to_; + + DISALLOW_COPY_AND_ASSIGN(KnapsackSearchPath); +}; + +// ----- KnapsackState ----- +// KnapsackState represents a partial solution to the knapsack problem. +class KnapsackState { + public: + KnapsackState(); + + // Initializes vectors with number_of_items set to false (i.e. not bound yet). + void Init(int number_of_items); + // Updates the state by applying or reverting a decision. + // Returns false if fails, i.e. trying to apply an inconsistent decision + // to an already assigned item. + bool UpdateState(bool revert, const KnapsackAssignment& assignment); + + int GetNumberOfItems() const { return is_bound_.size(); } + bool is_bound(int id) const { return is_bound_.at(id); } + bool is_in(int id) const { return is_in_.at(id); } + + private: + // Vectors 'is_bound_' and 'is_in_' contain a boolean value for each item. + // 'is_bound_(item_i)' is false when there is no decision for item_i yet. + // When item_i is bound, 'is_in_(item_i)' represents the presence (true) or + // the absence (false) of item_i in the current solution. + std::vector is_bound_; + std::vector is_in_; + + DISALLOW_COPY_AND_ASSIGN(KnapsackState); +}; + +// ----- KnapsackPropagator ----- +// KnapsackPropagator is the base class for modeling and propagating a +// constraint given an assignment. +// +// When some work has to be done both by the base and the derived class, +// a protected pure virtual method ending by 'Propagator' is defined. +// For instance, 'Init' creates a vector of items, and then calls +// 'InitPropagator' to let the derived class perform its own initialization. +class KnapsackPropagator { + public: + explicit KnapsackPropagator(const KnapsackState& state); + virtual ~KnapsackPropagator(); + + // Initializes data structure and then calls InitPropagator. + void Init(const std::vector& profits, + const std::vector& weights); + + // Updates data structure and then calls UpdatePropagator. + // Returns false when failure. + bool Update(bool revert, const KnapsackAssignment& assignment); + // ComputeProfitBounds should set 'profit_lower_bound_' and + // 'profit_upper_bound_' which are constraint specific. + virtual void ComputeProfitBounds() = 0; + // Returns the id of next item to assign. + // Returns kNoSelection when all items are bound. + virtual int GetNextItemId() const = 0; + + int64 current_profit() const { return current_profit_; } + int64 profit_lower_bound() const { return profit_lower_bound_; } + int64 profit_upper_bound() const { return profit_upper_bound_; } + + // Copies the current state into 'solution'. + // All unbound items are set to false (i.e. not in the knapsack). + // When 'has_one_propagator' is true, CopyCurrentSolutionPropagator is called + // to have a better solution. When there is only one propagator + // there is no need to check the solution with other propagators, so the + // partial solution can be smartly completed. + void CopyCurrentStateToSolution(bool has_one_propagator, + std::vector* solution) const; + + protected: + // Initializes data structure. This method is called after initialization + // of KnapsackPropagator data structure. + virtual void InitPropagator() = 0; + + // Updates internal data structure incrementally. This method is called + // after update of KnapsackPropagator data structure. + virtual bool UpdatePropagator(bool revert, + const KnapsackAssignment& assignment) = 0; + + // Copies the current state into 'solution'. + // Only unbound items have to be copied as CopyCurrentSolution was already + // called with current state. + // This method is useful when a propagator is able to find a better solution + // than the blind instantiation to false of unbound items. + virtual void CopyCurrentStateToSolutionPropagator(std::vector* solution) + const = 0; + + const KnapsackState& state() const { return state_; } + const std::vector& items() const { return items_; } + + void set_profit_lower_bound(int64 profit) { profit_lower_bound_ = profit; } + void set_profit_upper_bound(int64 profit) { profit_upper_bound_ = profit; } + + private: + std::vector items_; + int64 current_profit_; + int64 profit_lower_bound_; + int64 profit_upper_bound_; + const KnapsackState& state_; + + DISALLOW_COPY_AND_ASSIGN(KnapsackPropagator); +}; + +// ----- KnapsackCapacityPropagator ----- +// KnapsackCapacityPropagator is a KnapsackPropagator used to enforce +// a capacity constraint. +// As a KnapsackPropagator is supposed to compute profit lower and upper +// bounds, and get the next item to select, it can be seen as a 0-1 Knapsack +// solver. The most efficient way to compute the upper bound is to iterate on +// items in profit-per-unit-weight decreasing order. The break item is +// commonly defined as the first item for which there is not enough remaining +// capacity. Selecting this break item as the next-item-to-assign usually +// gives the best results (see Greenberg & Hegerich). +// +// This is exactly what is implemented in this class. +// +// When there is only one propagator, it is possible to compute a better +// profit lower bound almost for free. During the scan to find the +// break element all unbound items are added just as if they were part of +// the current solution. This is used in both ComputeProfitBounds and +// CopyCurrentSolutionPropagator. +// For incrementality reasons, the ith item should be accessible in O(1). That's +// the reason why the item vector has to be duplicated 'sorted_items_'. +class KnapsackCapacityPropagator : public KnapsackPropagator { + public: + KnapsackCapacityPropagator(const KnapsackState& state, int64 capacity); + ~KnapsackCapacityPropagator() override; + void ComputeProfitBounds() override; + int GetNextItemId() const override { return break_item_id_; } + + protected: + // Initializes KnapsackCapacityPropagator (e.g., sort items in decreasing + // order). + void InitPropagator() override; + // Updates internal data structure incrementally (i.e., 'consumed_capacity_') + // to avoid a O(number_of_items) scan. + bool UpdatePropagator(bool revert, + const KnapsackAssignment& assignment) override; + void CopyCurrentStateToSolutionPropagator( + std::vector* solution) const override; + + private: + // An obvious additional profit upper bound corresponds to the linear + // relaxation: remaining_capacity * efficiency of the break item. + // It is possible to do better in O(1), using Martello-Toth bound U2. + // The main idea is to enforce integrality constraint on the break item, + // ie. either the break item is part of the solution, either it is not. + // So basically the linear relaxation is done on the item before the break + // item, or the one after the break item. + // This is what GetAdditionalProfit method implements. + int64 GetAdditionalProfit(int64 remaining_capacity, int break_item_id) const; + + const int64 capacity_; + int64 consumed_capacity_; + int break_item_id_; + std::vector sorted_items_; + int64 profit_max_; + + DISALLOW_COPY_AND_ASSIGN(KnapsackCapacityPropagator); +}; + +// ----- BaseKnapsackSolver ----- +// This is the base class for knapsack solvers. +class BaseKnapsackSolver { + public: + explicit BaseKnapsackSolver(const std::string& solver_name) + : solver_name_(solver_name) {} + virtual ~BaseKnapsackSolver() {} + + // Initializes the solver and enters the problem to be solved. + virtual void Init(const std::vector& profits, + const std::vector >& weights, + const std::vector& capacities) = 0; + + // Gets the lower and upper bound when the item is in or out of the knapsack. + // To ensure objects are correctly initialized, this method should not be + // called before ::Init. + virtual void GetLowerAndUpperBoundWhenItem(int item_id, bool is_item_in, + int64* lower_bound, + int64* upper_bound); + + // Solves the problem and returns the profit of the optimal solution. + virtual int64 Solve(TimeLimit* time_limit, bool* is_solution_optimal) = 0; + + // Returns true if the item 'item_id' is packed in the optimal knapsack. + virtual bool best_solution(int item_id) const = 0; + + virtual std::string GetName() const { return solver_name_; } + + private: + const std::string solver_name_; +}; + +// ----- KnapsackGenericSolver ----- +// KnapsackGenericSolver is the multi-dimensional knapsack solver class. +// In the current implementation, the next item to assign is given by the +// master propagator. Using SetMasterPropagator allows changing the default +// (propagator of the first dimension), and selecting another dimension when +// more constrained. +// TODO(user): In the case of a multi-dimensional knapsack problem, implement +// an aggregated propagator to combine all dimensions and give a better guide +// to select the next item (see, for instance, Dobson's aggregated efficiency). +class KnapsackGenericSolver : public BaseKnapsackSolver { + public: + explicit KnapsackGenericSolver(const std::string& solver_name); + ~KnapsackGenericSolver() override; + + // Initializes the solver and enters the problem to be solved. + void Init(const std::vector& profits, + const std::vector >& weights, + const std::vector& capacities) override; + int GetNumberOfItems() const { return state_.GetNumberOfItems(); } + void GetLowerAndUpperBoundWhenItem(int item_id, bool is_item_in, + int64* lower_bound, + int64* upper_bound) override; + + // Sets which propagator should be used to guide the search. + // 'master_propagator_id' should be in 0..p-1 with p the number of + // propagators. + void set_master_propagator_id(int master_propagator_id) { + master_propagator_id_ = master_propagator_id; + } + + // Solves the problem and returns the profit of the optimal solution. + int64 Solve(TimeLimit* time_limit, bool* is_solution_optimal) override; + // Returns true if the item 'item_id' is packed in the optimal knapsack. + bool best_solution(int item_id) const override { + return best_solution_.at(item_id); + } + + private: + // Clears internal data structure. + void Clear(); + + // Updates all propagators reverting/applying all decision on the path. + // Returns true if fails. Note that, even if fails, all propagators should + // be updated to be in a stable state in order to stay incremental. + bool UpdatePropagators(const KnapsackSearchPath& path); + // Updates all propagators reverting/applying one decision. + // Return true if fails. Note that, even if fails, all propagators should + // be updated to be in a stable state in order to stay incremental. + bool IncrementalUpdate(bool revert, const KnapsackAssignment& assignment); + // Updates the best solution if the current solution has a better profit. + void UpdateBestSolution(); + + // Returns true if new relevant search node was added to the nodes array, that + // means this node should be added to the search queue too. + bool MakeNewNode(const KnapsackSearchNode& node, bool is_in); + + // Gets the aggregated (min) profit upper bound among all propagators. + int64 GetAggregatedProfitUpperBound() const; + bool HasOnePropagator() const { return propagators_.size() == 1; } + int64 GetCurrentProfit() const { + return propagators_.at(master_propagator_id_)->current_profit(); + } + int64 GetNextItemId() const { + return propagators_.at(master_propagator_id_)->GetNextItemId(); + } + + std::vector propagators_; + int master_propagator_id_; + std::vector search_nodes_; + KnapsackState state_; + int64 best_solution_profit_; + std::vector best_solution_; + + DISALLOW_COPY_AND_ASSIGN(KnapsackGenericSolver); +}; +#endif // SWIG +} // namespace operations_research + +#endif // OR_TOOLS_ALGORITHMS_KNAPSACK_SOLVER_H_ diff --git a/thirdparty/linux/include/ortools/algorithms/sparse_permutation.h b/thirdparty/linux/include/ortools/algorithms/sparse_permutation.h new file mode 100644 index 0000000..8db0138 --- /dev/null +++ b/thirdparty/linux/include/ortools/algorithms/sparse_permutation.h @@ -0,0 +1,132 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_ALGORITHMS_SPARSE_PERMUTATION_H_ +#define OR_TOOLS_ALGORITHMS_SPARSE_PERMUTATION_H_ + +#include +#include + +#include "ortools/base/logging.h" + +namespace operations_research { + +// A compact representation for permutations of {0..N-1} that displaces few +// elements: it needs only O(K) memory for a permutation that displaces +// K elements. +class SparsePermutation { + public: + explicit SparsePermutation(int size) : size_(size) {} // Identity. + + // TODO(user,user): complete the reader API. + int Size() const { return size_; } + int NumCycles() const { return cycle_ends_.size(); } + + // Returns the "support" of this permutation; that is, the set of elements + // displaced by it. + const std::vector& Support() const { return cycles_; } + + // The permutation has NumCycles() cycles numbered 0 .. NumCycles()-1. + // To iterate over cycle #i of the permutation, do this: + // for (const int e : permutation.Cycle(i)) { ... + struct Iterator; + Iterator Cycle(int i) const; + + // This is useful for iterating over the pair {element, image} + // of a permutation: + // + // for (int c = 0; c < perm.NumCycles(); ++c) { + // int element = LastElementInCycle(c); + // for (int image : perm.Cycle(c)) { + // // The pair is (element, image). + // ... + // element = image; + // } + // } + // + // TODO(user): Provide a full iterator for this? Note that we have more + // information with the loop above. Not sure it is needed though. + int LastElementInCycle(int i) const; + + // To add a cycle to the permutation, repeatedly call AddToCurrentCycle() + // with the cycle's orbit, then call CloseCurrentCycle(); + // This shouldn't be called on trivial cycles (of length 1). + void AddToCurrentCycle(int x); + void CloseCurrentCycle(); + + // Removes the cycles with given indices from the permutation. This + // works in O(K) for a permutation displacing K elements. + void RemoveCycles(const std::vector& cycle_indices); + + // Output all non-identity cycles of the permutation, sorted + // lexicographically (each cycle is described starting by its smallest + // element; and all cycles are sorted lexicographically against each other). + // This isn't efficient; use for debugging only. + // Example: "(1 4 3) (5 9) (6 8 7)". + std::string DebugString() const; + + private: + const int size_; + std::vector cycles_; + std::vector cycle_ends_; +}; + +inline void SparsePermutation::AddToCurrentCycle(int x) { + DCHECK_GE(x, 0); + DCHECK_LT(x, size_); + cycles_.push_back(x); +} + +inline void SparsePermutation::CloseCurrentCycle() { + if (cycle_ends_.empty()) { + DCHECK_GE(cycles_.size(), 2); + } else { + DCHECK_GE(cycles_.size(), cycle_ends_.back() + 2); + } + cycle_ends_.push_back(cycles_.size()); +} + +struct SparsePermutation::Iterator { + // These typedefs allow this iterator to be used within testing::ElementsAre. + typedef int value_type; + typedef std::vector::const_iterator const_iterator; + + Iterator() {} + Iterator(const std::vector::const_iterator& b, + const std::vector::const_iterator& e) : begin_(b), end_(e) {} + + std::vector::const_iterator begin() const { return begin_; } + std::vector::const_iterator end() const { return end_; } + const std::vector::const_iterator begin_; + const std::vector::const_iterator end_; + + int size() const { return end_ - begin_; } +}; + +inline SparsePermutation::Iterator SparsePermutation::Cycle(int i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i, NumCycles()); + return Iterator(cycles_.begin() + (i == 0 ? 0 : cycle_ends_[i - 1]), + cycles_.begin() + cycle_ends_[i]); +} + +inline int SparsePermutation::LastElementInCycle(int i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i, cycle_ends_.size()); + DCHECK_GT(cycle_ends_[i], i == 0 ? 0 : cycle_ends_[i - 1]); + return cycles_[cycle_ends_[i] - 1]; +} + +} // namespace operations_research + +#endif // OR_TOOLS_ALGORITHMS_SPARSE_PERMUTATION_H_ diff --git a/thirdparty/linux/include/ortools/base/accurate_sum.h b/thirdparty/linux/include/ortools/base/accurate_sum.h new file mode 100644 index 0000000..44cacd3 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/accurate_sum.h @@ -0,0 +1,48 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + + +#ifndef OR_TOOLS_BASE_ACCURATE_SUM_H_ +#define OR_TOOLS_BASE_ACCURATE_SUM_H_ + +namespace operations_research { + +// Kahan summation compensation algorithm. +// +// http://en.wikipedia.org/wiki/Kahan_summation_algorithm +template +class AccurateSum { + public: + // You may copy-construct an AccurateSum. + AccurateSum() : sum_(), error_sum_() {} + + // Adds an FpNumber to the sum. + void Add(const FpNumber& value) { + error_sum_ += value; + const FpNumber new_sum = sum_ + error_sum_; + error_sum_ += sum_ - new_sum; + sum_ = new_sum; + } + + // Gets the value of the sum. + FpNumber Value() const { return sum_; } + + private: + FpNumber sum_; + FpNumber error_sum_; +}; + +} // namespace operations_research + +#endif // OR_TOOLS_BASE_ACCURATE_SUM_H_ diff --git a/thirdparty/linux/include/ortools/base/adjustable_priority_queue-inl.h b/thirdparty/linux/include/ortools/base/adjustable_priority_queue-inl.h new file mode 100644 index 0000000..a89dbc9 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/adjustable_priority_queue-inl.h @@ -0,0 +1,19 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_ADJUSTABLE_PRIORITY_QUEUE_INL_H_ +#define OR_TOOLS_BASE_ADJUSTABLE_PRIORITY_QUEUE_INL_H_ + +#include "ortools/base/adjustable_priority_queue.h" + +#endif // OR_TOOLS_BASE_ADJUSTABLE_PRIORITY_QUEUE_INL_H_ diff --git a/thirdparty/linux/include/ortools/base/adjustable_priority_queue.h b/thirdparty/linux/include/ortools/base/adjustable_priority_queue.h new file mode 100644 index 0000000..8c432c4 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/adjustable_priority_queue.h @@ -0,0 +1,140 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include "ortools/base/basictypes.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" + +#ifndef OR_TOOLS_BASE_ADJUSTABLE_PRIORITY_QUEUE_H_ +#define OR_TOOLS_BASE_ADJUSTABLE_PRIORITY_QUEUE_H_ + +namespace operations_research { + +template +class AdjustablePriorityQueue { + public: + AdjustablePriorityQueue() {} + + void Add(T* const val) { + elems_.push_back(val); + AdjustUpwards(elems_.size() - 1); + } + + void Remove(T* const val) { + const int i = val->GetHeapIndex(); + if (i == elems_.size() - 1) { + elems_.pop_back(); + return; + } + elems_[i] = elems_.back(); + elems_[i]->SetHeapIndex(i); + elems_.pop_back(); + NoteChangedPriority(elems_[i]); + } + + bool Contains(const T* const val) const { + const int i = val->GetHeapIndex(); + if (i < 0 || i >= elems_.size() || elems_[i] != val) { + return false; + } + return true; + } + + void NoteChangedPriority(T* val) { + const int i = val->GetHeapIndex(); + const int parent = (i - 1) / 2; + if (*elems_[parent] < *val) { + AdjustUpwards(i); + } else { + AdjustDownwards(i); + } + } + + T* Top() { return elems_[0]; } + + const T* Top() const { return elems_[0]; } + + void Pop() { Remove(Top()); } + + int Size() const { return elems_.size(); } + + bool IsEmpty() const { return elems_.empty(); } + + void Clear() { elems_.clear(); } + + void CheckValid() const { + for (int i = 0; i < elems_.size(); ++i) { + const int left_child = 1 + 2 * i; + if (left_child < elems_.size()) { + CHECK_GE(elems_[i], elems_[left_child]); + } + const int right_child = left_child + 1; + if (right_child < elems_.size()) { + CHECK_GE(elems_[i], elems_[right_child]); + } + } + } + + // This is for debugging, e.g. the caller can use it to + // examine the heap for rationality w.r.t. other parts of the + // program. + const std::vector* Raw() const { return &elems_; } + + private: + void AdjustUpwards(int i) { + T* const t = elems_[i]; + while (i > 0) { + const int parent = (i - 1) / 2; + if (!(*elems_[parent] < *t)) { + break; + } + elems_[i] = elems_[parent]; + elems_[i]->SetHeapIndex(i); + i = parent; + } + elems_[i] = t; + t->SetHeapIndex(i); + } + + void AdjustDownwards(int i) { + T* const t = elems_[i]; + while (true) { + const int left_child = 1 + 2 * i; + if (left_child >= elems_.size()) { + break; + } + const int right_child = left_child + 1; + const int next_i = (right_child < elems_.size() && + *elems_[left_child] < *elems_[right_child]) + ? right_child + : left_child; + if (!(*t < *elems_[next_i])) { + break; + } + elems_[i] = elems_[next_i]; + elems_[i]->SetHeapIndex(i); + i = next_i; + } + elems_[i] = t; + t->SetHeapIndex(i); + } + + std::vector elems_; + DISALLOW_COPY_AND_ASSIGN(AdjustablePriorityQueue); +}; +} // namespace operations_research + +#endif // OR_TOOLS_BASE_ADJUSTABLE_PRIORITY_QUEUE_H_ diff --git a/thirdparty/linux/include/ortools/base/basictypes.h b/thirdparty/linux/include/ortools/base/basictypes.h new file mode 100644 index 0000000..133f318 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/basictypes.h @@ -0,0 +1,22 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Basic integer type definitions for various platforms +// +#ifndef OR_TOOLS_BASE_BASICTYPES_H_ +#define OR_TOOLS_BASE_BASICTYPES_H_ + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" + +#endif // OR_TOOLS_BASE_BASICTYPES_H_ diff --git a/thirdparty/linux/include/ortools/base/bitmap.h b/thirdparty/linux/include/ortools/base/bitmap.h new file mode 100644 index 0000000..1035fc2 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/bitmap.h @@ -0,0 +1,86 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_BITMAP_H_ +#define OR_TOOLS_BASE_BITMAP_H_ + +#include +#include "ortools/base/basictypes.h" + +namespace operations_research { +namespace internal { +inline uint64 OneBit64(int pos) { return GG_ULONGLONG(1) << pos; } +inline uint64 BitPos64(uint64 pos) { return (pos & 63); } +inline uint64 BitOffset64(uint64 pos) { return (pos >> 6); } +inline uint64 BitLength64(uint64 size) { return ((size + 63) >> 6); } +inline bool IsBitSet64(const uint64* const bitset, uint64 pos) { + return (bitset[BitOffset64(pos)] & OneBit64(BitPos64(pos))); +} +inline void SetBit64(uint64* const bitset, uint64 pos) { + bitset[BitOffset64(pos)] |= OneBit64(BitPos64(pos)); +} +inline void ClearBit64(uint64* const bitset, uint64 pos) { + bitset[BitOffset64(pos)] &= ~OneBit64(BitPos64(pos)); +} +} // namespace internal + +class Bitmap { + public: + // Constructor : This allocates on a uint32 boundary. + // fill: true = initialize with 1's, false = initialize with 0's. + explicit Bitmap(uint32 size, bool fill = false) + : max_size_(size), + array_size_(internal::BitLength64(size)), + map_(new uint64[array_size_]) { + // initialize all of the bits + SetAll(fill); + } + + // Destructor: clean up. + ~Bitmap() { delete[] map_; } + + // Resizes the bitmap. + // If size < bits(), the extra bits will be discarded. + // If size > bits(), the extra bits will be filled with the fill value. + void Resize(uint32 size, bool fill = false); + + bool Get(uint32 index) const { + assert(max_size_ == 0 || index < max_size_); + return internal::IsBitSet64(map_, index); + } + void Set(uint32 index, bool value) { + assert(max_size_ == 0 || index < max_size_); + if (value) { + internal::SetBit64(map_, index); + } else { + internal::ClearBit64(map_, index); + } + } + + // Sets all the bits to true or false + void SetAll(bool value) { + memset(map_, (value ? 0xFF : 0x00), array_size_ * sizeof(*map_)); + } + + // Clears all bits in the bitmap + void Clear() { SetAll(false); } + + private: + uint32 max_size_; // the upper bound of the bitmap + uint32 array_size_; + uint64* map_; // the bitmap +}; + +} // namespace operations_research + +#endif // OR_TOOLS_BASE_BITMAP_H_ diff --git a/thirdparty/linux/include/ortools/base/callback.h b/thirdparty/linux/include/ortools/base/callback.h new file mode 100644 index 0000000..12cfe87 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/callback.h @@ -0,0 +1,14508 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_CALLBACK_H_ +#define OR_TOOLS_BASE_CALLBACK_H_ + +#include "ortools/base/logging.h" + +namespace operations_research { + +struct CallbackUtils_ { + static void FailIsRepeatable(const char* name); +}; + +} // namespace operations_research + +using operations_research::CallbackUtils_; + +// ----- base types ----- + +class Closure { + public: + virtual ~Closure() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual void Run() = 0; +}; + +template +class ResultCallback { + public: + virtual ~ResultCallback() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual R Run() = 0; +}; + +template +class Callback1 { + public: + virtual ~Callback1() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual void Run(A1) = 0; +}; + +template +class ResultCallback1 { + public: + virtual ~ResultCallback1() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual R Run(A1) = 0; +}; + +template +class Callback2 { + public: + virtual ~Callback2() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual void Run(A1, A2) = 0; +}; + +template +class ResultCallback2 { + public: + virtual ~ResultCallback2() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual R Run(A1, A2) = 0; +}; + +template +class Callback3 { + public: + virtual ~Callback3() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual void Run(A1, A2, A3) = 0; +}; + +template +class ResultCallback3 { + public: + virtual ~ResultCallback3() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual R Run(A1, A2, A3) = 0; +}; + +template +class Callback4 { + public: + virtual ~Callback4() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual void Run(A1, A2, A3, A4) = 0; +}; + +template +class ResultCallback4 { + public: + virtual ~ResultCallback4() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual R Run(A1, A2, A3, A4) = 0; +}; + +template +class Callback5 { + public: + virtual ~Callback5() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual void Run(A1, A2, A3, A4, A5) = 0; +}; + +template +class ResultCallback5 { + public: + virtual ~ResultCallback5() {} + virtual bool IsRepeatable() const { return false; } + virtual void CheckIsRepeatable() const {} + virtual R Run(A1, A2, A3, A4, A5) = 0; +}; + +// ----- Utility template code used by the callback specializations ----- + +// c_enable_if, equivalent semantics to c++11 std::enable_if, specifically: +// "If B is true, the member typedef type shall equal T; otherwise, there +// shall be no member typedef type." +// Specified by 20.9.7.6 [Other transformations] +template +struct c_enable_if { + typedef T type; +}; +template +struct c_enable_if {}; + +typedef char small_; + +struct big_ { + char dummy[2]; +}; + +template +struct is_class_or_union { + template + static small_ tester(void (U::*)()); + template + static big_ tester(...); + #ifndef SWIG + static const bool value = sizeof(tester(0)) == sizeof(small_); + #endif // SWIG +}; + +template +struct c_remove_reference { + typedef T type; +}; +template +struct c_remove_reference { + typedef T type; +}; + +template +struct ConstRef { + typedef typename c_remove_reference::type base_type; + typedef const base_type& type; +}; + +// ----- Callback specializations ----- + +template ::value>::type> +class _ConstMemberResultCallback_0_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)() const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_0(const T* object, MemberSignature member) + : ResultCallback(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(); + return result; + } else { + R result = (object_->*member_)(); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_0_0< + del, void, T, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)() const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_0(const T* object, MemberSignature member) + : Closure(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(); + } else { + (object_->*member_)(); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_0::base* NewCallback( + const T1* obj, R (T2::*member)() const) { + return new _ConstMemberResultCallback_0_0(obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_0::base* +NewPermanentCallback(const T1* obj, R (T2::*member)() const) { + return new _ConstMemberResultCallback_0_0(obj, member); +} +#endif + +template ::value>::type> +class _MemberResultCallback_0_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_0(T* object, MemberSignature member) + : ResultCallback(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(); + return result; + } else { + R result = (object_->*member_)(); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_0_0< + del, void, T, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_0(T* object, MemberSignature member) + : Closure(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(); + } else { + (object_->*member_)(); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_0::base* NewCallback( + T1* obj, R (T2::*member)()) { + return new _MemberResultCallback_0_0(obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_0::base* +NewPermanentCallback(T1* obj, R (T2::*member)()) { + return new _MemberResultCallback_0_0(obj, member); +} +#endif + +template +class _FunctionResultCallback_0_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (*FunctionSignature)(); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_0(FunctionSignature function) + : ResultCallback(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (*function_)(); + return result; + } else { + R result = (*function_)(); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_0_0 : public Closure { + public: + typedef Closure base; + typedef void (*FunctionSignature)(); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_0(FunctionSignature function) + : Closure(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (*function_)(); + } else { + (*function_)(); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_0_0::base* NewCallback( + R (*function)()) { + return new _FunctionResultCallback_0_0(function); +} + +template +inline typename _FunctionResultCallback_0_0::base* +NewPermanentCallback(R (*function)()) { + return new _FunctionResultCallback_0_0(function); +} + +template < + bool del, class R, class T, class P1, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_1_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_0(const T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_); + return result; + } else { + R result = (object_->*member_)(p1_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_1_0< + del, void, T, P1, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_0(const T* object, MemberSignature member, + typename ConstRef::type p1) + : Closure(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_); + } else { + (object_->*member_)(p1_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_0::base* +NewCallback(const T1* obj, R (T2::*member)(P1) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_0(obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_0::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_0(obj, member, p1); +} +#endif + +template < + bool del, class R, class T, class P1, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_1_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_0(T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_); + return result; + } else { + R result = (object_->*member_)(p1_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_1_0< + del, void, T, P1, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_0(T* object, MemberSignature member, + typename ConstRef::type p1) + : Closure(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_); + } else { + (object_->*member_)(p1_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_0::base* NewCallback( + T1* obj, R (T2::*member)(P1), typename ConstRef::type p1) { + return new _MemberResultCallback_1_0(obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_0::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_0(obj, member, p1); +} +#endif + +template +class _FunctionResultCallback_1_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (*FunctionSignature)(P1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_0(FunctionSignature function, + typename ConstRef::type p1) + : ResultCallback(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (*function_)(p1_); + return result; + } else { + R result = (*function_)(p1_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_1_0 : public Closure { + public: + typedef Closure base; + typedef void (*FunctionSignature)(P1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_0(FunctionSignature function, + typename ConstRef::type p1) + : Closure(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (*function_)(p1_); + } else { + (*function_)(p1_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_1_0::base* NewCallback( + R (*function)(P1), typename ConstRef::type p1) { + return new _FunctionResultCallback_1_0(function, p1); +} + +template +inline typename _FunctionResultCallback_1_0::base* +NewPermanentCallback(R (*function)(P1), typename ConstRef::type p1) { + return new _FunctionResultCallback_1_0(function, p1); +} + +template < + bool del, class R, class T, class P1, class P2, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_2_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_2_0< + del, void, T, P1, P2, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Closure(), object_(object), member_(member), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_); + } else { + (object_->*member_)(p1_, p2_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_0::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2) const, + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_0(obj, member, + p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_0::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2) const, + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_0(obj, member, + p1, p2); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_2_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_2_0< + del, void, T, P1, P2, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Closure(), object_(object), member_(member), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_); + } else { + (object_->*member_)(p1_, p2_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_0::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2), typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _MemberResultCallback_2_0(obj, member, p1, + p2); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_0::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _MemberResultCallback_2_0(obj, member, p1, + p2); +} +#endif + +template +class _FunctionResultCallback_2_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (*FunctionSignature)(P1, P2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback(), function_(function), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (*function_)(p1_, p2_); + return result; + } else { + R result = (*function_)(p1_, p2_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_2_0 : public Closure { + public: + typedef Closure base; + typedef void (*FunctionSignature)(P1, P2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Closure(), function_(function), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (*function_)(p1_, p2_); + } else { + (*function_)(p1_, p2_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_2_0::base* NewCallback( + R (*function)(P1, P2), typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_0(function, p1, p2); +} + +template +inline typename _FunctionResultCallback_2_0::base* +NewPermanentCallback(R (*function)(P1, P2), typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_0(function, p1, p2); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_3_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2, P3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_3_0< + del, void, T, P1, P2, P3, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2, P3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Closure(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_, p3_); + } else { + (object_->*member_)(p1_, p2_, p3_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_0::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_0( + obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_0::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, P3) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_0( + obj, member, p1, p2, p3); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_3_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2, P3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_3_0< + del, void, T, P1, P2, P3, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2, P3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Closure(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_, p3_); + } else { + (object_->*member_)(p1_, p2_, p3_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_0::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_0(obj, member, p1, + p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_0::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_0(obj, member, + p1, p2, p3); +} +#endif + +template +class _FunctionResultCallback_3_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (*FunctionSignature)(P1, P2, P3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback(), function_(function), p1_(p1), p2_(p2), p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (*function_)(p1_, p2_, p3_); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_3_0 : public Closure { + public: + typedef Closure base; + typedef void (*FunctionSignature)(P1, P2, P3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Closure(), function_(function), p1_(p1), p2_(p2), p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (*function_)(p1_, p2_, p3_); + } else { + (*function_)(p1_, p2_, p3_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_3_0::base* +NewCallback(R (*function)(P1, P2, P3), typename ConstRef::type p1, + typename ConstRef::type p2, typename ConstRef::type p3) { + return new _FunctionResultCallback_3_0(function, p1, p2, + p3); +} + +template +inline typename _FunctionResultCallback_3_0::base* +NewPermanentCallback(R (*function)(P1, P2, P3), typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_0(function, p1, p2, + p3); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_4_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_4_0< + del, void, T, P1, P2, P3, P4, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Closure(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_0::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_0( + obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_0::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_0( + obj, member, p1, p2, p3, p4); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_4_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_4_0< + del, void, T, P1, P2, P3, P4, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Closure(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_0::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _MemberResultCallback_4_0( + obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_0::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _MemberResultCallback_4_0( + obj, member, p1, p2, p3, p4); +} +#endif + +template +class _FunctionResultCallback_4_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (*FunctionSignature)(P1, P2, P3, P4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_4_0 : public Closure { + public: + typedef Closure base; + typedef void (*FunctionSignature)(P1, P2, P3, P4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Closure(), function_(function), p1_(p1), p2_(p2), p3_(p3), p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_); + } else { + (*function_)(p1_, p2_, p3_, p4_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_4_0::base* +NewCallback(R (*function)(P1, P2, P3, P4), typename ConstRef::type p1, + typename ConstRef::type p2, typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _FunctionResultCallback_4_0(function, p1, + p2, p3, p4); +} + +template +inline typename _FunctionResultCallback_4_0::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _FunctionResultCallback_4_0(function, p1, + p2, p3, p4); +} + +template ::value>::type> +class _ConstMemberResultCallback_5_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_5_0< + del, void, T, P1, P2, P3, P4, P5, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Closure(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_0::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_0( + obj, member, p1, p2, p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_0::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_0( + obj, member, p1, p2, p3, p4, p5); +} +#endif + +template ::value>::type> +class _MemberResultCallback_5_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_5_0< + del, void, T, P1, P2, P3, P4, P5, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Closure(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_0::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_0( + obj, member, p1, p2, p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_0::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_0( + obj, member, p1, p2, p3, p4, p5); +} +#endif + +template +class _FunctionResultCallback_5_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_5_0 : public Closure { + public: + typedef Closure base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Closure(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_5_0::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5), typename ConstRef::type p1, + typename ConstRef::type p2, typename ConstRef::type p3, + typename ConstRef::type p4, typename ConstRef::type p5) { + return new _FunctionResultCallback_5_0( + function, p1, p2, p3, p4, p5); +} + +template +inline typename _FunctionResultCallback_5_0::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_0( + function, p1, p2, p3, p4, p5); +} + +template ::value>::type> +class _ConstMemberResultCallback_6_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_6_0< + del, void, T, P1, P2, P3, P4, P5, P6, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_0(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Closure(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_0::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_0< + true, R, T1, P1, P2, P3, P4, P5, P6>(obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_0::base* +NewPermanentCallback( + const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_0(obj, member, p1, p2, p3, p4, p5, + p6); +} +#endif + +template ::value>::type> +class _MemberResultCallback_6_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_6_0< + del, void, T, P1, P2, P3, P4, P5, P6, + typename c_enable_if::value>::type> : public Closure { + public: + typedef Closure base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_0(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Closure(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_0::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_0( + obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_0::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _MemberResultCallback_6_0( + obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +template +class _FunctionResultCallback_6_0 : public ResultCallback { + public: + typedef ResultCallback base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, P6); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback"); + } + + virtual R Run() { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_6_0 : public Closure { + public: + typedef Closure base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, P6); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_0(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Closure(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Closure"); + } + + virtual void Run() { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_6_0::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, P6), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _FunctionResultCallback_6_0( + function, p1, p2, p3, p4, p5, p6); +} + +template +inline typename _FunctionResultCallback_6_0::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, P6), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _FunctionResultCallback_6_0( + function, p1, p2, p3, p4, p5, p6); +} + +template < + bool del, class R, class T, class A1, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_0_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(A1) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_1(const T* object, MemberSignature member) + : ResultCallback1(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(a1); + return result; + } else { + R result = (object_->*member_)(a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_0_1< + del, void, T, A1, typename c_enable_if::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(A1) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_1(const T* object, MemberSignature member) + : Callback1(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(a1); + } else { + (object_->*member_)(a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_1::base* +NewCallback(const T1* obj, R (T2::*member)(A1) const) { + return new _ConstMemberResultCallback_0_1(obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_1::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(A1) const) { + return new _ConstMemberResultCallback_0_1(obj, member); +} +#endif + +template < + bool del, class R, class T, class A1, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_0_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(A1); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_1(T* object, MemberSignature member) + : ResultCallback1(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(a1); + return result; + } else { + R result = (object_->*member_)(a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_0_1::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(A1); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_1(T* object, MemberSignature member) + : Callback1(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(a1); + } else { + (object_->*member_)(a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_1::base* NewCallback( + T1* obj, R (T2::*member)(A1)) { + return new _MemberResultCallback_0_1(obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_1::base* +NewPermanentCallback(T1* obj, R (T2::*member)(A1)) { + return new _MemberResultCallback_0_1(obj, member); +} +#endif + +template +class _FunctionResultCallback_0_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (*FunctionSignature)(A1); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_1(FunctionSignature function) + : ResultCallback1(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (*function_)(a1); + return result; + } else { + R result = (*function_)(a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_0_1 : public Callback1 { + public: + typedef Callback1 base; + typedef void (*FunctionSignature)(A1); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_1(FunctionSignature function) + : Callback1(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (*function_)(a1); + } else { + (*function_)(a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_0_1::base* NewCallback( + R (*function)(A1)) { + return new _FunctionResultCallback_0_1(function); +} + +template +inline typename _FunctionResultCallback_0_1::base* +NewPermanentCallback(R (*function)(A1)) { + return new _FunctionResultCallback_0_1(function); +} + +template < + bool del, class R, class T, class P1, class A1, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_1_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_1(const T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback1(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_1_1< + del, void, T, P1, A1, typename c_enable_if::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_1(const T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback1(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, a1); + } else { + (object_->*member_)(p1_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_1::base* +NewCallback(const T1* obj, R (T2::*member)(P1, A1) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_1(obj, member, + p1); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_1::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, A1) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_1(obj, member, + p1); +} +#endif + +template < + bool del, class R, class T, class P1, class A1, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_1_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_1(T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback1(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_1_1::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_1(T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback1(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, a1); + } else { + (object_->*member_)(p1_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_1::base* +NewCallback(T1* obj, R (T2::*member)(P1, A1), typename ConstRef::type p1) { + return new _MemberResultCallback_1_1(obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_1::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, A1), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_1(obj, member, p1); +} +#endif + +template +class _FunctionResultCallback_1_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (*FunctionSignature)(P1, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_1(FunctionSignature function, + typename ConstRef::type p1) + : ResultCallback1(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (*function_)(p1_, a1); + return result; + } else { + R result = (*function_)(p1_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_1_1 : public Callback1 { + public: + typedef Callback1 base; + typedef void (*FunctionSignature)(P1, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_1(FunctionSignature function, + typename ConstRef::type p1) + : Callback1(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (*function_)(p1_, a1); + } else { + (*function_)(p1_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_1_1::base* NewCallback( + R (*function)(P1, A1), typename ConstRef::type p1) { + return new _FunctionResultCallback_1_1(function, p1); +} + +template +inline typename _FunctionResultCallback_1_1::base* +NewPermanentCallback(R (*function)(P1, A1), typename ConstRef::type p1) { + return new _FunctionResultCallback_1_1(function, p1); +} + +template < + bool del, class R, class T, class P1, class P2, class A1, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_2_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_2_1< + del, void, T, P1, P2, A1, typename c_enable_if::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback1(), object_(object), member_(member), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, a1); + } else { + (object_->*member_)(p1_, p2_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_1::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, A1) const, + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_1( + obj, member, p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_1::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, A1) const, + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_1( + obj, member, p1, p2); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class A1, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_2_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_2_1::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback1(), object_(object), member_(member), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, a1); + } else { + (object_->*member_)(p1_, p2_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_1::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, A1), + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _MemberResultCallback_2_1(obj, member, p1, + p2); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_1::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, A1), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _MemberResultCallback_2_1(obj, member, + p1, p2); +} +#endif + +template +class _FunctionResultCallback_2_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (*FunctionSignature)(P1, P2, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback1(), function_(function), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (*function_)(p1_, p2_, a1); + return result; + } else { + R result = (*function_)(p1_, p2_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_2_1 : public Callback1 { + public: + typedef Callback1 base; + typedef void (*FunctionSignature)(P1, P2, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback1(), function_(function), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (*function_)(p1_, p2_, a1); + } else { + (*function_)(p1_, p2_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_2_1::base* +NewCallback(R (*function)(P1, P2, A1), typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_1(function, p1, p2); +} + +template +inline typename _FunctionResultCallback_2_1::base* +NewPermanentCallback(R (*function)(P1, P2, A1), typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_1(function, p1, + p2); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class A1, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_3_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_3_1< + del, void, T, P1, P2, P3, A1, typename c_enable_if::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1); + } else { + (object_->*member_)(p1_, p2_, p3_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_1::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, A1) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_1( + obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_1::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, P3, A1) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_1( + obj, member, p1, p2, p3); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class A1, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_3_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_3_1::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1); + } else { + (object_->*member_)(p1_, p2_, p3_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_1::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_1(obj, member, + p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_1::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_1( + obj, member, p1, p2, p3); +} +#endif + +template +class _FunctionResultCallback_3_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (*FunctionSignature)(P1, P2, P3, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback1(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, a1); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_3_1 : public Callback1 { + public: + typedef Callback1 base; + typedef void (*FunctionSignature)(P1, P2, P3, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback1(), function_(function), p1_(p1), p2_(p2), p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (*function_)(p1_, p2_, p3_, a1); + } else { + (*function_)(p1_, p2_, p3_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_3_1::base* +NewCallback(R (*function)(P1, P2, P3, A1), typename ConstRef::type p1, + typename ConstRef::type p2, typename ConstRef::type p3) { + return new _FunctionResultCallback_3_1(function, p1, + p2, p3); +} + +template +inline typename _FunctionResultCallback_3_1::base* +NewPermanentCallback(R (*function)(P1, P2, P3, A1), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_1(function, p1, + p2, p3); +} + +template ::value>::type> +class _ConstMemberResultCallback_4_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_4_1< + del, void, T, P1, P2, P3, P4, A1, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_1::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, A1) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_1( + obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_1::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, A1) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_1( + obj, member, p1, p2, p3, p4); +} +#endif + +template ::value>::type> +class _MemberResultCallback_4_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_4_1::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_1::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _MemberResultCallback_4_1( + obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_1::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _MemberResultCallback_4_1( + obj, member, p1, p2, p3, p4); +} +#endif + +template +class _FunctionResultCallback_4_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback1(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, a1); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_4_1 : public Callback1 { + public: + typedef Callback1 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback1(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, a1); + } else { + (*function_)(p1_, p2_, p3_, p4_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_4_1::base* +NewCallback(R (*function)(P1, P2, P3, P4, A1), typename ConstRef::type p1, + typename ConstRef::type p2, typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _FunctionResultCallback_4_1( + function, p1, p2, p3, p4); +} + +template +inline typename _FunctionResultCallback_4_1::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, A1), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _FunctionResultCallback_4_1( + function, p1, p2, p3, p4); +} + +template ::value>::type> +class _ConstMemberResultCallback_5_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_5_1< + del, void, T, P1, P2, P3, P4, P5, A1, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_1::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_1< + true, R, T1, P1, P2, P3, P4, P5, A1>(obj, member, p1, p2, p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_1::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_1< + false, R, T1, P1, P2, P3, P4, P5, A1>(obj, member, p1, p2, p3, p4, p5); +} +#endif + +template ::value>::type> +class _MemberResultCallback_5_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_5_1::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_1::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_1( + obj, member, p1, p2, p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_1::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_1( + obj, member, p1, p2, p3, p4, p5); +} +#endif + +template +class _FunctionResultCallback_5_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback1(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_5_1 : public Callback1 { + public: + typedef Callback1 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback1(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_5_1::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, A1), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_1( + function, p1, p2, p3, p4, p5); +} + +template +inline typename _FunctionResultCallback_5_1::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, A1), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_1( + function, p1, p2, p3, p4, p5); +} + +template ::value>::type> +class _ConstMemberResultCallback_6_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_6_1< + del, void, T, P1, P2, P3, P4, P5, P6, A1, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_1(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_1::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_1(obj, member, p1, p2, p3, p4, p5, + p6); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_1::base* +NewPermanentCallback( + const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_1< + false, R, T1, P1, P2, P3, P4, P5, P6, A1>(obj, member, p1, p2, p3, p4, p5, + p6); +} +#endif + +template ::value>::type> +class _MemberResultCallback_6_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_6_1::value>::type> : public Callback1 { + public: + typedef Callback1 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_1(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback1(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_1::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_1( + obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_1::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _MemberResultCallback_6_1(obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +template +class _FunctionResultCallback_6_1 : public ResultCallback1 { + public: + typedef ResultCallback1 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback1(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback1"); + } + + virtual R Run(A1 a1) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_6_1 : public Callback1 { + public: + typedef Callback1 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_1(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback1(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback1"); + } + + virtual void Run(A1 a1) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_6_1::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _FunctionResultCallback_6_1( + function, p1, p2, p3, p4, p5, p6); +} + +template +inline typename _FunctionResultCallback_6_1::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _FunctionResultCallback_6_1( + function, p1, p2, p3, p4, p5, p6); +} + +template < + bool del, class R, class T, class A1, class A2, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_0_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_2(const T* object, MemberSignature member) + : ResultCallback2(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(a1, a2); + return result; + } else { + R result = (object_->*member_)(a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_0_2< + del, void, T, A1, A2, typename c_enable_if::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_2(const T* object, MemberSignature member) + : Callback2(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(a1, a2); + } else { + (object_->*member_)(a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_2::base* +NewCallback(const T1* obj, R (T2::*member)(A1, A2) const) { + return new _ConstMemberResultCallback_0_2(obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_2::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(A1, A2) const) { + return new _ConstMemberResultCallback_0_2(obj, member); +} +#endif + +template < + bool del, class R, class T, class A1, class A2, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_0_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(A1, A2); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_2(T* object, MemberSignature member) + : ResultCallback2(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(a1, a2); + return result; + } else { + R result = (object_->*member_)(a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_0_2< + del, void, T, A1, A2, typename c_enable_if::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(A1, A2); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_2(T* object, MemberSignature member) + : Callback2(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(a1, a2); + } else { + (object_->*member_)(a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_2::base* +NewCallback(T1* obj, R (T2::*member)(A1, A2)) { + return new _MemberResultCallback_0_2(obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_2::base* +NewPermanentCallback(T1* obj, R (T2::*member)(A1, A2)) { + return new _MemberResultCallback_0_2(obj, member); +} +#endif + +template +class _FunctionResultCallback_0_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (*FunctionSignature)(A1, A2); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_2(FunctionSignature function) + : ResultCallback2(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (*function_)(a1, a2); + return result; + } else { + R result = (*function_)(a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_0_2 : public Callback2 { + public: + typedef Callback2 base; + typedef void (*FunctionSignature)(A1, A2); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_2(FunctionSignature function) + : Callback2(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (*function_)(a1, a2); + } else { + (*function_)(a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_0_2::base* NewCallback( + R (*function)(A1, A2)) { + return new _FunctionResultCallback_0_2(function); +} + +template +inline typename _FunctionResultCallback_0_2::base* +NewPermanentCallback(R (*function)(A1, A2)) { + return new _FunctionResultCallback_0_2(function); +} + +template < + bool del, class R, class T, class P1, class A1, class A2, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_1_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_2(const T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_1_2< + del, void, T, P1, A1, A2, typename c_enable_if::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_2(const T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback2(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, a1, a2); + } else { + (object_->*member_)(p1_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_2::base* +NewCallback(const T1* obj, R (T2::*member)(P1, A1, A2) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_2( + obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_2::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, A1, A2) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_2( + obj, member, p1); +} +#endif + +template < + bool del, class R, class T, class P1, class A1, class A2, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_1_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_2(T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_1_2< + del, void, T, P1, A1, A2, typename c_enable_if::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_2(T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback2(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, a1, a2); + } else { + (object_->*member_)(p1_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_2::base* +NewCallback(T1* obj, R (T2::*member)(P1, A1, A2), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_2(obj, member, + p1); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_2::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, A1, A2), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_2(obj, member, + p1); +} +#endif + +template +class _FunctionResultCallback_1_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (*FunctionSignature)(P1, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_2(FunctionSignature function, + typename ConstRef::type p1) + : ResultCallback2(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (*function_)(p1_, a1, a2); + return result; + } else { + R result = (*function_)(p1_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_1_2 : public Callback2< + A1, A2> { + public: + typedef Callback2 base; + typedef void (*FunctionSignature)(P1, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_2(FunctionSignature function, + typename ConstRef::type p1) + : Callback2(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (*function_)(p1_, a1, a2); + } else { + (*function_)(p1_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_1_2::base* +NewCallback(R (*function)(P1, A1, A2), typename ConstRef::type p1) { + return new _FunctionResultCallback_1_2(function, p1); +} + +template +inline typename _FunctionResultCallback_1_2::base* +NewPermanentCallback(R (*function)(P1, A1, A2), + typename ConstRef::type p1) { + return new _FunctionResultCallback_1_2(function, p1); +} + +template < + bool del, class R, class T, class P1, class P2, class A1, class A2, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_2_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_2_2< + del, void, T, P1, P2, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_2::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, A1, A2) const, + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_2( + obj, member, p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_2::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, A1, A2) const, + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_2( + obj, member, p1, p2); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class A1, class A2, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_2_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_2_2< + del, void, T, P1, P2, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_2::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, A1, A2), + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _MemberResultCallback_2_2(obj, member, + p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_2::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _MemberResultCallback_2_2( + obj, member, p1, p2); +} +#endif + +template +class _FunctionResultCallback_2_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (*FunctionSignature)(P1, P2, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback2(), function_(function), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (*function_)(p1_, p2_, a1, a2); + return result; + } else { + R result = (*function_)(p1_, p2_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_2_2 : public Callback2< + A1, A2> { + public: + typedef Callback2 base; + typedef void (*FunctionSignature)(P1, P2, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback2(), function_(function), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (*function_)(p1_, p2_, a1, a2); + } else { + (*function_)(p1_, p2_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_2_2::base* +NewCallback(R (*function)(P1, P2, A1, A2), typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_2(function, p1, + p2); +} + +template +inline typename _FunctionResultCallback_2_2::base* +NewPermanentCallback(R (*function)(P1, P2, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_2(function, p1, + p2); +} + +template ::value>::type> +class _ConstMemberResultCallback_3_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_3_2< + del, void, T, P1, P2, P3, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, p3_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_2::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, A1, A2) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_2( + obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_2::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, P3, A1, A2) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_2( + obj, member, p1, p2, p3); +} +#endif + +template ::value>::type> +class _MemberResultCallback_3_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_3_2< + del, void, T, P1, P2, P3, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, p3_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_2::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1, A2), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_2( + obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_2::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_2( + obj, member, p1, p2, p3); +} +#endif + +template +class _FunctionResultCallback_3_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (*FunctionSignature)(P1, P2, P3, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback2(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, a1, a2); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_3_2 : public Callback2 { + public: + typedef Callback2 base; + typedef void (*FunctionSignature)(P1, P2, P3, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback2(), function_(function), p1_(p1), p2_(p2), p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (*function_)(p1_, p2_, p3_, a1, a2); + } else { + (*function_)(p1_, p2_, p3_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_3_2::base* +NewCallback(R (*function)(P1, P2, P3, A1, A2), typename ConstRef::type p1, + typename ConstRef::type p2, typename ConstRef::type p3) { + return new _FunctionResultCallback_3_2( + function, p1, p2, p3); +} + +template +inline typename _FunctionResultCallback_3_2::base* +NewPermanentCallback(R (*function)(P1, P2, P3, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_2( + function, p1, p2, p3); +} + +template ::value>::type> +class _ConstMemberResultCallback_4_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_4_2< + del, void, T, P1, P2, P3, P4, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_2::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_2(obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_2::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, A1, A2) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_2(obj, member, p1, p2, p3, p4); +} +#endif + +template ::value>::type> +class _MemberResultCallback_4_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_4_2< + del, void, T, P1, P2, P3, P4, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_2::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _MemberResultCallback_4_2( + obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_2::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _MemberResultCallback_4_2( + obj, member, p1, p2, p3, p4); +} +#endif + +template +class _FunctionResultCallback_4_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback2(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, a1, a2); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_4_2 : public Callback2 { + public: + typedef Callback2 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback2(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, a1, a2); + } else { + (*function_)(p1_, p2_, p3_, p4_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_4_2::base* +NewCallback(R (*function)(P1, P2, P3, P4, A1, A2), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _FunctionResultCallback_4_2( + function, p1, p2, p3, p4); +} + +template +inline typename _FunctionResultCallback_4_2::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _FunctionResultCallback_4_2( + function, p1, p2, p3, p4); +} + +template ::value>::type> +class _ConstMemberResultCallback_5_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_5_2< + del, void, T, P1, P2, P3, P4, P5, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_2::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1, A2) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_2< + true, R, T1, P1, P2, P3, P4, P5, A1, A2>(obj, member, p1, p2, p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_2::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1, A2) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_2(obj, member, p1, p2, p3, p4, + p5); +} +#endif + +template ::value>::type> +class _MemberResultCallback_5_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_5_2< + del, void, T, P1, P2, P3, P4, P5, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_2::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1, A2), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_2( + obj, member, p1, p2, p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_2::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_2(obj, member, p1, p2, p3, p4, p5); +} +#endif + +template +class _FunctionResultCallback_5_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback2(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_5_2 : public Callback2 { + public: + typedef Callback2 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback2(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_5_2::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, A1, A2), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_2( + function, p1, p2, p3, p4, p5); +} + +template +inline typename _FunctionResultCallback_5_2::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_2( + function, p1, p2, p3, p4, p5); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class P6, class A1, class A2, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_6_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_6_2< + del, void, T, P1, P2, P3, P4, P5, P6, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_2(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_2::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_2(obj, member, p1, p2, p3, p4, + p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_2::base* +NewPermanentCallback( + const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_2< + false, R, T1, P1, P2, P3, P4, P5, P6, A1, A2>(obj, member, p1, p2, p3, p4, + p5, p6); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class P6, class A1, class A2, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_6_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_6_2< + del, void, T, P1, P2, P3, P4, P5, P6, A1, A2, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback2 { + public: + typedef Callback2 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_2(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback2(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_2::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_2(obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_2::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _MemberResultCallback_6_2(obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +template +class _FunctionResultCallback_6_2 : public ResultCallback2 { + public: + typedef ResultCallback2 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback2(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback2"); + } + + virtual R Run(A1 a1, A2 a2) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_6_2 : public Callback2 { + public: + typedef Callback2 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1, A2); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_2(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback2(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback2"); + } + + virtual void Run(A1 a1, A2 a2) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_6_2::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1, A2), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _FunctionResultCallback_6_2(function, p1, p2, p3, p4, p5, p6); +} + +template +inline typename _FunctionResultCallback_6_2::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1, A2), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _FunctionResultCallback_6_2(function, p1, p2, p3, p4, p5, p6); +} + +template < + bool del, class R, class T, class A1, class A2, class A3, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_0_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_3(const T* object, MemberSignature member) + : ResultCallback3(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_0_3< + del, void, T, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_3(const T* object, MemberSignature member) + : Callback3(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(a1, a2, a3); + } else { + (object_->*member_)(a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_3::base* +NewCallback(const T1* obj, R (T2::*member)(A1, A2, A3) const) { + return new _ConstMemberResultCallback_0_3(obj, + member); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_3::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(A1, A2, A3) const) { + return new _ConstMemberResultCallback_0_3(obj, + member); +} +#endif + +template < + bool del, class R, class T, class A1, class A2, class A3, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_0_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_3(T* object, MemberSignature member) + : ResultCallback3(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_0_3< + del, void, T, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_3(T* object, MemberSignature member) + : Callback3(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(a1, a2, a3); + } else { + (object_->*member_)(a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_3::base* +NewCallback(T1* obj, R (T2::*member)(A1, A2, A3)) { + return new _MemberResultCallback_0_3(obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_3::base* +NewPermanentCallback(T1* obj, R (T2::*member)(A1, A2, A3)) { + return new _MemberResultCallback_0_3(obj, member); +} +#endif + +template +class _FunctionResultCallback_0_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (*FunctionSignature)(A1, A2, A3); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_3(FunctionSignature function) + : ResultCallback3(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (*function_)(a1, a2, a3); + return result; + } else { + R result = (*function_)(a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_0_3 : public Callback3< + A1, A2, A3> { + public: + typedef Callback3 base; + typedef void (*FunctionSignature)(A1, A2, A3); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_3(FunctionSignature function) + : Callback3(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (*function_)(a1, a2, a3); + } else { + (*function_)(a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_0_3::base* +NewCallback(R (*function)(A1, A2, A3)) { + return new _FunctionResultCallback_0_3(function); +} + +template +inline typename _FunctionResultCallback_0_3::base* +NewPermanentCallback(R (*function)(A1, A2, A3)) { + return new _FunctionResultCallback_0_3(function); +} + +template < + bool del, class R, class T, class P1, class A1, class A2, class A3, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_1_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_3(const T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_1_3< + del, void, T, P1, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_3(const T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback3(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, a1, a2, a3); + } else { + (object_->*member_)(p1_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_3::base* +NewCallback(const T1* obj, R (T2::*member)(P1, A1, A2, A3) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_3( + obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_3::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, A1, A2, A3) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_3( + obj, member, p1); +} +#endif + +template < + bool del, class R, class T, class P1, class A1, class A2, class A3, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_1_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_3(T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_1_3< + del, void, T, P1, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_3(T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback3(), object_(object), member_(member), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, a1, a2, a3); + } else { + (object_->*member_)(p1_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_3::base* +NewCallback(T1* obj, R (T2::*member)(P1, A1, A2, A3), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_3(obj, member, + p1); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_3::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, A1, A2, A3), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_3( + obj, member, p1); +} +#endif + +template +class _FunctionResultCallback_1_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (*FunctionSignature)(P1, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_3(FunctionSignature function, + typename ConstRef::type p1) + : ResultCallback3(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (*function_)(p1_, a1, a2, a3); + return result; + } else { + R result = (*function_)(p1_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_1_3 : public Callback3< + A1, A2, A3> { + public: + typedef Callback3 base; + typedef void (*FunctionSignature)(P1, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_3(FunctionSignature function, + typename ConstRef::type p1) + : Callback3(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (*function_)(p1_, a1, a2, a3); + } else { + (*function_)(p1_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_1_3::base* +NewCallback(R (*function)(P1, A1, A2, A3), typename ConstRef::type p1) { + return new _FunctionResultCallback_1_3(function, p1); +} + +template +inline typename _FunctionResultCallback_1_3::base* +NewPermanentCallback(R (*function)(P1, A1, A2, A3), + typename ConstRef::type p1) { + return new _FunctionResultCallback_1_3(function, + p1); +} + +template ::value>::type> +class _ConstMemberResultCallback_2_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_2_3< + del, void, T, P1, P2, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_3::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, A1, A2, A3) const, + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_3( + obj, member, p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_3::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, A1, A2, A3) const, + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_3( + obj, member, p1, p2); +} +#endif + +template ::value>::type> +class _MemberResultCallback_2_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_2_3< + del, void, T, P1, P2, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_3::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _MemberResultCallback_2_3( + obj, member, p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_3::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _MemberResultCallback_2_3( + obj, member, p1, p2); +} +#endif + +template +class _FunctionResultCallback_2_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (*FunctionSignature)(P1, P2, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback3(), + function_(function), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (*function_)(p1_, p2_, a1, a2, a3); + return result; + } else { + R result = (*function_)(p1_, p2_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_2_3 : public Callback3 { + public: + typedef Callback3 base; + typedef void (*FunctionSignature)(P1, P2, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback3(), function_(function), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (*function_)(p1_, p2_, a1, a2, a3); + } else { + (*function_)(p1_, p2_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_2_3::base* +NewCallback(R (*function)(P1, P2, A1, A2, A3), typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_3(function, + p1, p2); +} + +template +inline typename _FunctionResultCallback_2_3::base* +NewPermanentCallback(R (*function)(P1, P2, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_3(function, + p1, p2); +} + +template ::value>::type> +class _ConstMemberResultCallback_3_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_3_3< + del, void, T, P1, P2, P3, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_3::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, A1, A2, A3) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_3(obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_3::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, A1, A2, A3) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_3(obj, member, p1, p2, p3); +} +#endif + +template ::value>::type> +class _MemberResultCallback_3_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_3_3< + del, void, T, P1, P2, P3, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_3::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_3( + obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_3::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_3( + obj, member, p1, p2, p3); +} +#endif + +template +class _FunctionResultCallback_3_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (*FunctionSignature)(P1, P2, P3, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback3(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, a1, a2, a3); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_3_3 : public Callback3 { + public: + typedef Callback3 base; + typedef void (*FunctionSignature)(P1, P2, P3, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback3(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (*function_)(p1_, p2_, p3_, a1, a2, a3); + } else { + (*function_)(p1_, p2_, p3_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_3_3::base* +NewCallback(R (*function)(P1, P2, P3, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_3( + function, p1, p2, p3); +} + +template +inline typename _FunctionResultCallback_3_3::base* +NewPermanentCallback(R (*function)(P1, P2, P3, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_3( + function, p1, p2, p3); +} + +template ::value>::type> +class _ConstMemberResultCallback_4_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_4_3< + del, void, T, P1, P2, P3, P4, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_3::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2, A3) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_3(obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_3::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, A1, A2, A3) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_3< + false, R, T1, P1, P2, P3, P4, A1, A2, A3>(obj, member, p1, p2, p3, p4); +} +#endif + +template ::value>::type> +class _MemberResultCallback_4_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_4_3< + del, void, T, P1, P2, P3, P4, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_3::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _MemberResultCallback_4_3( + obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_3::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _MemberResultCallback_4_3(obj, member, p1, p2, p3, p4); +} +#endif + +template +class _FunctionResultCallback_4_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback3(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_4_3 : public Callback3 { + public: + typedef Callback3 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback3(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3); + } else { + (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_4_3::base* +NewCallback(R (*function)(P1, P2, P3, P4, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _FunctionResultCallback_4_3( + function, p1, p2, p3, p4); +} + +template +inline typename _FunctionResultCallback_4_3::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _FunctionResultCallback_4_3( + function, p1, p2, p3, p4); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class A1, class A2, class A3, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_5_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_5_3< + del, void, T, P1, P2, P3, P4, P5, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_3::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_3(obj, member, p1, p2, p3, p4, + p5); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_3::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_3< + false, R, T1, P1, P2, P3, P4, P5, A1, A2, A3>(obj, member, p1, p2, p3, p4, + p5); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class A1, class A2, class A3, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_5_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_5_3< + del, void, T, P1, P2, P3, P4, P5, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_3::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_3(obj, member, p1, p2, p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_3::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_3(obj, member, p1, p2, p3, p4, p5); +} +#endif + +template +class _FunctionResultCallback_5_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback3(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_5_3 : public Callback3 { + public: + typedef Callback3 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback3(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_5_3::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_3(function, p1, p2, p3, p4, p5); +} + +template +inline typename _FunctionResultCallback_5_3::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_3(function, p1, p2, p3, p4, p5); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class P6, class A1, class A2, class A3, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_6_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_6_3< + del, void, T, P1, P2, P3, P4, P5, P6, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_3(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_3::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_3(obj, member, p1, p2, p3, + p4, p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_3::base* +NewPermanentCallback( + const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_3< + false, R, T1, P1, P2, P3, P4, P5, P6, A1, A2, A3>(obj, member, p1, p2, p3, + p4, p5, p6); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class P6, class A1, class A2, class A3, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_6_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_6_3< + del, void, T, P1, P2, P3, P4, P5, P6, A1, A2, A3, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback3 { + public: + typedef Callback3 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_3(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback3(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_3::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_3(obj, member, p1, p2, p3, p4, p5, + p6); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_3::base* +NewPermanentCallback( + T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_3(obj, member, p1, p2, p3, p4, p5, + p6); +} +#endif + +template +class _FunctionResultCallback_6_3 : public ResultCallback3 { + public: + typedef ResultCallback3 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback3(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback3"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_6_3 : public Callback3 { + public: + typedef Callback3 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_3(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback3(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback3"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_6_3::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1, A2, A3), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _FunctionResultCallback_6_3(function, p1, p2, p3, p4, p5, + p6); +} + +template +inline typename _FunctionResultCallback_6_3::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1, A2, A3), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _FunctionResultCallback_6_3(function, p1, p2, p3, p4, p5, + p6); +} + +template < + bool del, class R, class T, class A1, class A2, class A3, class A4, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_0_4 + : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_4(const T* object, MemberSignature member) + : ResultCallback4(), + object_(object), + member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_0_4< + del, void, T, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_4(const T* object, MemberSignature member) + : Callback4(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(a1, a2, a3, a4); + } else { + (object_->*member_)(a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_4::base* +NewCallback(const T1* obj, R (T2::*member)(A1, A2, A3, A4) const) { + return new _ConstMemberResultCallback_0_4( + obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_4::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(A1, A2, A3, A4) const) { + return new _ConstMemberResultCallback_0_4( + obj, member); +} +#endif + +template < + bool del, class R, class T, class A1, class A2, class A3, class A4, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_0_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_4(T* object, MemberSignature member) + : ResultCallback4(), + object_(object), + member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_0_4< + del, void, T, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_4(T* object, MemberSignature member) + : Callback4(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(a1, a2, a3, a4); + } else { + (object_->*member_)(a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_4::base* +NewCallback(T1* obj, R (T2::*member)(A1, A2, A3, A4)) { + return new _MemberResultCallback_0_4(obj, + member); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_4::base* +NewPermanentCallback(T1* obj, R (T2::*member)(A1, A2, A3, A4)) { + return new _MemberResultCallback_0_4(obj, + member); +} +#endif + +template +class _FunctionResultCallback_0_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (*FunctionSignature)(A1, A2, A3, A4); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_4(FunctionSignature function) + : ResultCallback4(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (*function_)(a1, a2, a3, a4); + return result; + } else { + R result = (*function_)(a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_0_4 : public Callback4 { + public: + typedef Callback4 base; + typedef void (*FunctionSignature)(A1, A2, A3, A4); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_4(FunctionSignature function) + : Callback4(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (*function_)(a1, a2, a3, a4); + } else { + (*function_)(a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_0_4::base* +NewCallback(R (*function)(A1, A2, A3, A4)) { + return new _FunctionResultCallback_0_4(function); +} + +template +inline typename _FunctionResultCallback_0_4::base* +NewPermanentCallback(R (*function)(A1, A2, A3, A4)) { + return new _FunctionResultCallback_0_4(function); +} + +template ::value>::type> +class _ConstMemberResultCallback_1_4 + : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_4(const T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_1_4< + del, void, T, P1, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_4(const T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback4(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_4::base* +NewCallback(const T1* obj, R (T2::*member)(P1, A1, A2, A3, A4) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_4( + obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_4::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, A1, A2, A3, A4) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_4( + obj, member, p1); +} +#endif + +template ::value>::type> +class _MemberResultCallback_1_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_4(T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_1_4< + del, void, T, P1, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_4(T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback4(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_4::base* +NewCallback(T1* obj, R (T2::*member)(P1, A1, A2, A3, A4), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_4( + obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_4::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, A1, A2, A3, A4), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_4( + obj, member, p1); +} +#endif + +template +class _FunctionResultCallback_1_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (*FunctionSignature)(P1, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_4(FunctionSignature function, + typename ConstRef::type p1) + : ResultCallback4(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (*function_)(p1_, a1, a2, a3, a4); + return result; + } else { + R result = (*function_)(p1_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_1_4 : public Callback4 { + public: + typedef Callback4 base; + typedef void (*FunctionSignature)(P1, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_4(FunctionSignature function, + typename ConstRef::type p1) + : Callback4(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (*function_)(p1_, a1, a2, a3, a4); + } else { + (*function_)(p1_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_1_4::base* +NewCallback(R (*function)(P1, A1, A2, A3, A4), typename ConstRef::type p1) { + return new _FunctionResultCallback_1_4(function, + p1); +} + +template +inline typename _FunctionResultCallback_1_4::base* +NewPermanentCallback(R (*function)(P1, A1, A2, A3, A4), + typename ConstRef::type p1) { + return new _FunctionResultCallback_1_4(function, + p1); +} + +template ::value>::type> +class _ConstMemberResultCallback_2_4 + : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_2_4< + del, void, T, P1, P2, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_4::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, A1, A2, A3, A4) const, + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_4(obj, member, p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_4::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, A1, A2, A3, A4) const, + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_4(obj, member, p1, p2); +} +#endif + +template ::value>::type> +class _MemberResultCallback_2_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_2_4< + del, void, T, P1, P2, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_4::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _MemberResultCallback_2_4( + obj, member, p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_4::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _MemberResultCallback_2_4( + obj, member, p1, p2); +} +#endif + +template +class _FunctionResultCallback_2_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (*FunctionSignature)(P1, P2, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback4(), + function_(function), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (*function_)(p1_, p2_, a1, a2, a3, a4); + return result; + } else { + R result = (*function_)(p1_, p2_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_2_4 : public Callback4 { + public: + typedef Callback4 base; + typedef void (*FunctionSignature)(P1, P2, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback4(), function_(function), p1_(p1), p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (*function_)(p1_, p2_, a1, a2, a3, a4); + } else { + (*function_)(p1_, p2_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_2_4::base* +NewCallback(R (*function)(P1, P2, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _FunctionResultCallback_2_4( + function, p1, p2); +} + +template +inline typename _FunctionResultCallback_2_4::base* +NewPermanentCallback(R (*function)(P1, P2, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_4( + function, p1, p2); +} + +template ::value>::type> +class _ConstMemberResultCallback_3_4 + : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_3_4< + del, void, T, P1, P2, P3, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_4::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, P3, A1, A2, A3, A4) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_4(obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_4::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, A1, A2, A3, A4) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_4(obj, member, p1, p2, p3); +} +#endif + +template ::value>::type> +class _MemberResultCallback_3_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_3_4< + del, void, T, P1, P2, P3, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_4::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_4( + obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_4::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_4(obj, member, p1, p2, p3); +} +#endif + +template +class _FunctionResultCallback_3_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (*FunctionSignature)(P1, P2, P3, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback4(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, a1, a2, a3, a4); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_3_4 : public Callback4 { + public: + typedef Callback4 base; + typedef void (*FunctionSignature)(P1, P2, P3, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback4(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (*function_)(p1_, p2_, p3_, a1, a2, a3, a4); + } else { + (*function_)(p1_, p2_, p3_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_3_4::base* +NewCallback(R (*function)(P1, P2, P3, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_4( + function, p1, p2, p3); +} + +template +inline typename _FunctionResultCallback_3_4::base* +NewPermanentCallback(R (*function)(P1, P2, P3, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_4( + function, p1, p2, p3); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class A1, class A2, class A3, class A4, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_4_4 + : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_4_4< + del, void, T, P1, P2, P3, P4, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_4::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, A1, A2, A3, A4) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_4< + true, R, T1, P1, P2, P3, P4, A1, A2, A3, A4>(obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_4::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, A1, A2, A3, A4) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_4(obj, member, p1, p2, p3, + p4); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class A1, class A2, class A3, class A4, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_4_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_4_4< + del, void, T, P1, P2, P3, P4, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_4::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _MemberResultCallback_4_4(obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_4::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _MemberResultCallback_4_4(obj, member, p1, p2, p3, p4); +} +#endif + +template +class _FunctionResultCallback_4_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback4(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_4_4 : public Callback4 { + public: + typedef Callback4 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback4(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + } else { + (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_4_4::base* +NewCallback(R (*function)(P1, P2, P3, P4, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _FunctionResultCallback_4_4(function, p1, p2, p3, p4); +} + +template +inline typename _FunctionResultCallback_4_4::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _FunctionResultCallback_4_4(function, p1, p2, p3, p4); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class A1, class A2, class A3, class A4, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_5_4 + : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_5_4< + del, void, T, P1, P2, P3, P4, P5, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_4::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3, A4) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_4(obj, member, p1, p2, p3, + p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_4::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3, A4) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_4< + false, R, T1, P1, P2, P3, P4, P5, A1, A2, A3, A4>(obj, member, p1, p2, p3, + p4, p5); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class A1, class A2, class A3, class A4, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_5_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_5_4< + del, void, T, P1, P2, P3, P4, P5, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_4::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_4(obj, member, p1, p2, p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_4::base* +NewPermanentCallback(T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_4(obj, member, p1, p2, p3, p4, p5); +} +#endif + +template +class _FunctionResultCallback_5_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback4(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_5_4 : public Callback4 { + public: + typedef Callback4 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback4(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_5_4::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_4(function, p1, p2, p3, p4, p5); +} + +template +inline typename _FunctionResultCallback_5_4::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_4(function, p1, p2, p3, p4, p5); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class P6, class A1, class A2, class A3, class A4, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_6_4 + : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + return result; + } else { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_6_4< + del, void, T, P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, + A4) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_4(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_4::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_4(obj, member, p1, p2, + p3, p4, p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_4::base* +NewPermanentCallback( + const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_4< + false, R, T1, P1, P2, P3, P4, P5, P6, A1, A2, A3, A4>(obj, member, p1, p2, + p3, p4, p5, p6); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class P6, class A1, class A2, class A3, class A4, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_6_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + return result; + } else { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_6_4< + del, void, T, P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, + typename c_enable_if< + is_class_or_union::value>::type> : public Callback4 { + public: + typedef Callback4 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_4(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback4(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_4::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_4(obj, member, p1, p2, p3, p4, + p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_4::base* +NewPermanentCallback( + T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_4(obj, member, p1, p2, p3, p4, + p5, p6); +} +#endif + +template +class _FunctionResultCallback_6_4 : public ResultCallback4 { + public: + typedef ResultCallback4 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback4(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("ResultCallback4"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_6_4 : public Callback4 { + public: + typedef Callback4 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_4(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback4(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback4"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_6_4::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _FunctionResultCallback_6_4(function, p1, p2, p3, p4, + p5, p6); +} + +template +inline typename _FunctionResultCallback_6_4::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _FunctionResultCallback_6_4(function, p1, p2, p3, p4, + p5, p6); +} + +template ::value>::type> +class _ConstMemberResultCallback_0_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_5(const T* object, MemberSignature member) + : ResultCallback5(), + object_(object), + member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_0_5< + del, void, T, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + + public: + inline _ConstMemberResultCallback_0_5(const T* object, MemberSignature member) + : Callback5(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(a1, a2, a3, a4, a5); + } else { + (object_->*member_)(a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_5::base* +NewCallback(const T1* obj, R (T2::*member)(A1, A2, A3, A4, A5) const) { + return new _ConstMemberResultCallback_0_5( + obj, member); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_0_5::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(A1, A2, A3, A4, A5) const) { + return new _ConstMemberResultCallback_0_5( + obj, member); +} +#endif + +template ::value>::type> +class _MemberResultCallback_0_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_5(T* object, MemberSignature member) + : ResultCallback5(), + object_(object), + member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_0_5< + del, void, T, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + + public: + inline _MemberResultCallback_0_5(T* object, MemberSignature member) + : Callback5(), object_(object), member_(member) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(a1, a2, a3, a4, a5); + } else { + (object_->*member_)(a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_5::base* +NewCallback(T1* obj, R (T2::*member)(A1, A2, A3, A4, A5)) { + return new _MemberResultCallback_0_5(obj, + member); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_0_5::base* +NewPermanentCallback(T1* obj, R (T2::*member)(A1, A2, A3, A4, A5)) { + return new _MemberResultCallback_0_5( + obj, member); +} +#endif + +template +class _FunctionResultCallback_0_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (*FunctionSignature)(A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_5(FunctionSignature function) + : ResultCallback5(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (*function_)(a1, a2, a3, a4, a5); + return result; + } else { + R result = (*function_)(a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_0_5 : public Callback5 { + public: + typedef Callback5 base; + typedef void (*FunctionSignature)(A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + + public: + explicit inline _FunctionResultCallback_0_5(FunctionSignature function) + : Callback5(), function_(function) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (*function_)(a1, a2, a3, a4, a5); + } else { + (*function_)(a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_0_5::base* +NewCallback(R (*function)(A1, A2, A3, A4, A5)) { + return new _FunctionResultCallback_0_5(function); +} + +template +inline typename _FunctionResultCallback_0_5::base* +NewPermanentCallback(R (*function)(A1, A2, A3, A4, A5)) { + return new _FunctionResultCallback_0_5( + function); +} + +template ::value>::type> +class _ConstMemberResultCallback_1_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_5(const T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(p1_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(p1_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_1_5< + del, void, T, P1, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _ConstMemberResultCallback_1_5(const T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback5(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_5::base* +NewCallback(const T1* obj, R (T2::*member)(P1, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_5(obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_1_5::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1) { + return new _ConstMemberResultCallback_1_5(obj, member, p1); +} +#endif + +template ::value>::type> +class _MemberResultCallback_1_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_5(T* object, MemberSignature member, + typename ConstRef::type p1) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(p1_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(p1_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_1_5< + del, void, T, P1, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + + public: + inline _MemberResultCallback_1_5(T* object, MemberSignature member, + typename ConstRef::type p1) + : Callback5(), + object_(object), + member_(member), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_5::base* +NewCallback(T1* obj, R (T2::*member)(P1, A1, A2, A3, A4, A5), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_5( + obj, member, p1); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_1_5::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, A1, A2, A3, A4, A5), + typename ConstRef::type p1) { + return new _MemberResultCallback_1_5( + obj, member, p1); +} +#endif + +template +class _FunctionResultCallback_1_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (*FunctionSignature)(P1, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_5(FunctionSignature function, + typename ConstRef::type p1) + : ResultCallback5(), + function_(function), + p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (*function_)(p1_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (*function_)(p1_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_1_5 : public Callback5 { + public: + typedef Callback5 base; + typedef void (*FunctionSignature)(P1, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + + public: + inline _FunctionResultCallback_1_5(FunctionSignature function, + typename ConstRef::type p1) + : Callback5(), function_(function), p1_(p1) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (*function_)(p1_, a1, a2, a3, a4, a5); + } else { + (*function_)(p1_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_1_5::base* +NewCallback(R (*function)(P1, A1, A2, A3, A4, A5), + typename ConstRef::type p1) { + return new _FunctionResultCallback_1_5( + function, p1); +} + +template +inline typename _FunctionResultCallback_1_5::base* +NewPermanentCallback(R (*function)(P1, A1, A2, A3, A4, A5), + typename ConstRef::type p1) { + return new _FunctionResultCallback_1_5( + function, p1); +} + +template ::value>::type> +class _ConstMemberResultCallback_2_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_2_5< + del, void, T, P1, P2, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _ConstMemberResultCallback_2_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_5::base* +NewCallback(const T1* obj, R (T2::*member)(P1, P2, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_5(obj, member, p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_2_5::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _ConstMemberResultCallback_2_5(obj, member, p1, p2); +} +#endif + +template ::value>::type> +class _MemberResultCallback_2_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_2_5< + del, void, T, P1, P2, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _MemberResultCallback_2_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_5::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _MemberResultCallback_2_5( + obj, member, p1, p2); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_2_5::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _MemberResultCallback_2_5(obj, member, p1, p2); +} +#endif + +template +class _FunctionResultCallback_2_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (*FunctionSignature)(P1, P2, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : ResultCallback5(), + function_(function), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (*function_)(p1_, p2_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (*function_)(p1_, p2_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_2_5 : public Callback5 { + public: + typedef Callback5 base; + typedef void (*FunctionSignature)(P1, P2, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + + public: + inline _FunctionResultCallback_2_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2) + : Callback5(), + function_(function), + p1_(p1), + p2_(p2) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (*function_)(p1_, p2_, a1, a2, a3, a4, a5); + } else { + (*function_)(p1_, p2_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_2_5::base* +NewCallback(R (*function)(P1, P2, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2) { + return new _FunctionResultCallback_2_5( + function, p1, p2); +} + +template +inline typename _FunctionResultCallback_2_5::base* +NewPermanentCallback(R (*function)(P1, P2, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2) { + return new _FunctionResultCallback_2_5( + function, p1, p2); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class A1, + class A2, class A3, class A4, class A5, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_3_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_3_5< + del, void, T, P1, P2, P3, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _ConstMemberResultCallback_3_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_5::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_5(obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_3_5::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _ConstMemberResultCallback_3_5< + false, R, T1, P1, P2, P3, A1, A2, A3, A4, A5>(obj, member, p1, p2, p3); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class A1, + class A2, class A3, class A4, class A5, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_3_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, P3, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_3_5< + del, void, T, P1, P2, P3, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, P3, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _MemberResultCallback_3_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_5::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_5(obj, member, p1, p2, p3); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_3_5::base* +NewPermanentCallback(T1* obj, R (T2::*member)(P1, P2, P3, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _MemberResultCallback_3_5(obj, member, p1, p2, p3); +} +#endif + +template +class _FunctionResultCallback_3_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (*FunctionSignature)(P1, P2, P3, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : ResultCallback5(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_3_5 : public Callback5 { + public: + typedef Callback5 base; + typedef void (*FunctionSignature)(P1, P2, P3, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + + public: + inline _FunctionResultCallback_3_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) + : Callback5(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (*function_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + } else { + (*function_)(p1_, p2_, p3_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_3_5::base* +NewCallback(R (*function)(P1, P2, P3, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_5(function, p1, p2, p3); +} + +template +inline typename _FunctionResultCallback_3_5::base* +NewPermanentCallback(R (*function)(P1, P2, P3, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3) { + return new _FunctionResultCallback_3_5(function, p1, p2, p3); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class A1, class A2, class A3, class A4, class A5, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_4_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_4_5< + del, void, T, P1, P2, P3, P4, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _ConstMemberResultCallback_4_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_5::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_5(obj, member, p1, p2, p3, + p4); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_4_5::base* +NewPermanentCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _ConstMemberResultCallback_4_5< + false, R, T1, P1, P2, P3, P4, A1, A2, A3, A4, A5>(obj, member, p1, p2, p3, + p4); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class A1, class A2, class A3, class A4, class A5, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_4_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_4_5< + del, void, T, P1, P2, P3, P4, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _MemberResultCallback_4_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_5::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _MemberResultCallback_4_5(obj, member, p1, p2, p3, p4); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_4_5::base* +NewPermanentCallback(T1* obj, + R (T2::*member)(P1, P2, P3, P4, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _MemberResultCallback_4_5(obj, member, p1, p2, p3, p4); +} +#endif + +template +class _FunctionResultCallback_4_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : ResultCallback5(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_4_5 : public Callback5 { + public: + typedef Callback5 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + + public: + inline _FunctionResultCallback_4_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) + : Callback5(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + } else { + (*function_)(p1_, p2_, p3_, p4_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_4_5::base* +NewCallback(R (*function)(P1, P2, P3, P4, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4) { + return new _FunctionResultCallback_4_5(function, p1, p2, p3, p4); +} + +template +inline typename _FunctionResultCallback_4_5::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4) { + return new _FunctionResultCallback_4_5(function, p1, p2, p3, p4); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class A1, class A2, class A3, class A4, class A5, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_5_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + return result; + } else { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_5_5< + del, void, T, P1, P2, P3, P4, P5, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4, + A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _ConstMemberResultCallback_5_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_5::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_5(obj, member, p1, p2, + p3, p4, p5); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_5_5::base* +NewPermanentCallback(const T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, + A3, A4, A5) const, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _ConstMemberResultCallback_5_5< + false, R, T1, P1, P2, P3, P4, P5, A1, A2, A3, A4, A5>(obj, member, p1, p2, + p3, p4, p5); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class A1, class A2, class A3, class A4, class A5, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_5_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + return result; + } else { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_5_5< + del, void, T, P1, P2, P3, P4, P5, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _MemberResultCallback_5_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_5::base* +NewCallback(T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_5(obj, member, p1, p2, p3, p4, + p5); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_5_5::base* +NewPermanentCallback(T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _MemberResultCallback_5_5(obj, member, p1, p2, p3, p4, + p5); +} +#endif + +template +class _FunctionResultCallback_5_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : ResultCallback5(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_5_5 : public Callback5 { + public: + typedef Callback5 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + + public: + inline _FunctionResultCallback_5_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) + : Callback5(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_5_5::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_5(function, p1, p2, p3, p4, + p5); +} + +template +inline typename _FunctionResultCallback_5_5::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5) { + return new _FunctionResultCallback_5_5(function, p1, p2, p3, p4, + p5); +} + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class P6, class A1, class A2, class A3, class A4, class A5, + class OnlyIf = typename c_enable_if::value>::type> +class _ConstMemberResultCallback_6_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, + A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + return result; + } else { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _ConstMemberResultCallback_6_5< + del, void, T, P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, + A5) const; + + private: + const T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _ConstMemberResultCallback_6_5(const T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_5::base* +NewCallback(const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_5( + obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _ConstMemberResultCallback_6_5::base* +NewPermanentCallback( + const T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5) const, + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _ConstMemberResultCallback_6_5( + obj, member, p1, p2, p3, p4, p5, p6); +} +#endif + +template < + bool del, class R, class T, class P1, class P2, class P3, class P4, + class P5, class P6, class A1, class A2, class A3, class A4, class A5, + class OnlyIf = typename c_enable_if::value>::type> +class _MemberResultCallback_6_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + return result; + } else { + R result = + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + return result; + } + } +}; + +template +class _MemberResultCallback_6_5< + del, void, T, P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5, + typename c_enable_if::value>::type> : public Callback5 { + public: + typedef Callback5 base; + typedef void (T::*MemberSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, + A5); + + private: + T* object_; + MemberSignature member_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _MemberResultCallback_6_5(T* object, MemberSignature member, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback5(), + object_(object), + member_(member), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + } else { + (object_->*member_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + member_ = NULL; + delete this; + } + } +}; + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_5::base* +NewCallback(T1* obj, + R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_5(obj, member, p1, p2, p3, + p4, p5, p6); +} +#endif + +#ifndef SWIG +template +inline typename _MemberResultCallback_6_5::base* +NewPermanentCallback( + T1* obj, R (T2::*member)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _MemberResultCallback_6_5(obj, member, p1, p2, p3, + p4, p5, p6); +} +#endif + +template +class _FunctionResultCallback_6_5 + : public ResultCallback5 { + public: + typedef ResultCallback5 base; + typedef R (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : ResultCallback5(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) + CallbackUtils_::FailIsRepeatable("ResultCallback5"); + } + + virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + return result; + } else { + R result = (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + return result; + } + } +}; + +template +class _FunctionResultCallback_6_5 : public Callback5 { + public: + typedef Callback5 base; + typedef void (*FunctionSignature)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5); + + private: + FunctionSignature function_; + typename c_remove_reference::type p1_; + typename c_remove_reference::type p2_; + typename c_remove_reference::type p3_; + typename c_remove_reference::type p4_; + typename c_remove_reference::type p5_; + typename c_remove_reference::type p6_; + + public: + inline _FunctionResultCallback_6_5(FunctionSignature function, + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) + : Callback5(), + function_(function), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6) {} + + virtual bool IsRepeatable() const { return !del; } + + virtual void CheckIsRepeatable() const { + if (del) CallbackUtils_::FailIsRepeatable("Callback5"); + } + + virtual void Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + if (!del) { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + } else { + (*function_)(p1_, p2_, p3_, p4_, p5_, p6_, a1, a2, a3, a4, a5); + // zero out the pointer to ensure segfault if used again + function_ = NULL; + delete this; + } + } +}; + +template +inline typename _FunctionResultCallback_6_5::base* +NewCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5), + typename ConstRef::type p1, typename ConstRef::type p2, + typename ConstRef::type p3, typename ConstRef::type p4, + typename ConstRef::type p5, typename ConstRef::type p6) { + return new _FunctionResultCallback_6_5(function, p1, p2, p3, + p4, p5, p6); +} + +template +inline typename _FunctionResultCallback_6_5::base* +NewPermanentCallback(R (*function)(P1, P2, P3, P4, P5, P6, A1, A2, A3, A4, A5), + typename ConstRef::type p1, + typename ConstRef::type p2, + typename ConstRef::type p3, + typename ConstRef::type p4, + typename ConstRef::type p5, + typename ConstRef::type p6) { + return new _FunctionResultCallback_6_5(function, p1, p2, p3, + p4, p5, p6); +} + +#endif // OR_TOOLS_BASE_CALLBACK_H_ diff --git a/thirdparty/linux/include/ortools/base/casts.h b/thirdparty/linux/include/ortools/base/casts.h new file mode 100644 index 0000000..532f75d --- /dev/null +++ b/thirdparty/linux/include/ortools/base/casts.h @@ -0,0 +1,31 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file is provided for compatibility purposes. +// +#ifndef OR_TOOLS_BASE_CASTS_H_ +#define OR_TOOLS_BASE_CASTS_H_ + +#include + +template +inline Dest bit_cast(const Source& source) { + COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), + bit_cast_on_object_with_different_sizes); + + Dest dest; + memcpy(&dest, &source, sizeof(dest)); + return dest; +} + +#endif // OR_TOOLS_BASE_CASTS_H_ diff --git a/thirdparty/linux/include/ortools/base/cleanup.h b/thirdparty/linux/include/ortools/base/cleanup.h new file mode 100644 index 0000000..8a311df --- /dev/null +++ b/thirdparty/linux/include/ortools/base/cleanup.h @@ -0,0 +1,42 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_CLEANUP_H_ +#define OR_TOOLS_BASE_CLEANUP_H_ + +#include + +namespace operations_research { +namespace util { + +template +class Cleanup { + public: + template + explicit Cleanup(G&& f) + : f_(std::forward(f)) {} + ~Cleanup() { f_(); } + + private: + F f_; +}; + +template +Cleanup MakeCleanup(F&& f) { + return Cleanup(std::forward(f)); +} + +} // namespace util +} // namespace operations_research + +#endif // OR_TOOLS_BASE_CLEANUP_H_ diff --git a/thirdparty/linux/include/ortools/base/commandlineflags.h b/thirdparty/linux/include/ortools/base/commandlineflags.h new file mode 100644 index 0000000..671dfbf --- /dev/null +++ b/thirdparty/linux/include/ortools/base/commandlineflags.h @@ -0,0 +1,19 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_COMMANDLINEFLAGS_H_ +#define OR_TOOLS_BASE_COMMANDLINEFLAGS_H_ + +#include "gflags/gflags.h" + +#endif // OR_TOOLS_BASE_COMMANDLINEFLAGS_H_ diff --git a/thirdparty/linux/include/ortools/base/encodingutils.h b/thirdparty/linux/include/ortools/base/encodingutils.h new file mode 100644 index 0000000..3606d52 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/encodingutils.h @@ -0,0 +1,37 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_ENCODINGUTILS_H_ +#define OR_TOOLS_BASE_ENCODINGUTILS_H_ + +#include + +namespace EncodingUtils { + +// Returns the number of characters of a UTF8-encoded std::string. +inline int UTF8StrLen(const std::string& utf8_str) { + if (utf8_str.empty()) return 0; + const char* c = utf8_str.c_str(); + int count = 0; + while (*c != '\0') { + ++count; + // See http://en.wikipedia.org/wiki/UTF-8#Description . + const unsigned char x = *c; + c += x < 0xC0 ? 1 : x < 0xE0 ? 2 : x < 0xF0 ? 3 : 4; + } + return count; +} + +} // namespace EncodingUtils + +#endif // OR_TOOLS_BASE_ENCODINGUTILS_H_ diff --git a/thirdparty/linux/include/ortools/base/file.h b/thirdparty/linux/include/ortools/base/file.h new file mode 100644 index 0000000..0ea655d --- /dev/null +++ b/thirdparty/linux/include/ortools/base/file.h @@ -0,0 +1,146 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_FILE_H_ +#define OR_TOOLS_BASE_FILE_H_ + +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/message.h" +#include "google/protobuf/text_format.h" +#include "google/protobuf/io/tokenizer.h" +#include "ortools/base/status.h" + +// This file defines some IO interfaces for compatibility with Google +// IO specifications. +class File { + public: + // Opens file "name" with flags specified by "flag". + // Flags are defined by fopen(), that is "r", "r+", "w", "w+". "a", and "a+". + static File* Open(const char* const name, const char* const flag); + +#ifndef SWIG // no overloading + inline static File* Open(const std::string& name, const char* const mode) { + return Open(name.c_str(), mode); + } +#endif // SWIG + + // Opens file "name" with flags specified by "flag". + // If open failed, program will exit. + static File* OpenOrDie(const char* const name, const char* const flag); + +#ifndef SWIG // no overloading + inline static File* OpenOrDie(const std::string& name, const char* const flag) { + return OpenOrDie(name.c_str(), flag); + } +#endif // SWIG + + // Reads "size" bytes to buff from file, buff should be pre-allocated. + size_t Read(void* const buff, size_t size); + + // Reads "size" bytes to buff from file, buff should be pre-allocated. + // If read failed, program will exit. + void ReadOrDie(void* const buff, size_t size); + + // Reads a line from file to a std::string. + // Each line must be no more than max_length bytes. + char* ReadLine(char* const output, uint64 max_length); + + // Reads the whole file to a std::string, with a maximum length of 'max_length'. + // Returns the number of bytes read. + int64 ReadToString(std::string* const line, uint64 max_length); + + // Writes "size" bytes of buff to file, buff should be pre-allocated. + size_t Write(const void* const buff, size_t size); + + // Writes "size" bytes of buff to file, buff should be pre-allocated. + // If write failed, program will exit. + void WriteOrDie(const void* const buff, size_t size); + + // Writes a std::string to file. + size_t WriteString(const std::string& line); + + // Writes a std::string to file and append a "\n". + bool WriteLine(const std::string& line); + + // Closes the file. + bool Close(); + util::Status Close(int flags); + + // Flushes buffer. + bool Flush(); + + // Returns file size. + size_t Size(); + + // Inits internal data structures. + static void Init(); + + // Returns the file name. + std::string filename() const; + + // Deletes a file. + static bool Delete(const char* const name); + static bool Delete(const std::string& name) { + return Delete(name.c_str()); + } + + // Tests if a file exists. + static bool Exists(const char* const name); + + bool Open() const; + + private: + File(FILE* const descriptor, const std::string& name); + + FILE* f_; + const std::string name_; +}; + +namespace file { +inline int Defaults() { return 0xBABA; } + +// As of 2016-01, these methods can only be used with flags = file::Defaults(). +util::Status Open(const std::string& filename, const std::string& mode, + File** f, int flags); +util::Status SetTextProto(const std::string& filename, const google::protobuf::Message& proto, + int flags); +util::Status SetBinaryProto(const std::string& filename, + const google::protobuf::Message& proto, int flags); +util::Status SetContents(const std::string& filename, const std::string& contents, + int flags); +util::Status GetContents(const std::string& filename, std::string* output, int flags); +util::Status WriteString(File* file, const std::string& contents, int flags); + +bool ReadFileToString(const std::string& file_name, std::string* output); +bool WriteStringToFile(const std::string& data, const std::string& file_name); +bool ReadFileToProto(const std::string& file_name, google::protobuf::Message* proto); +void ReadFileToProtoOrDie(const std::string& file_name, google::protobuf::Message* proto); +bool WriteProtoToASCIIFile(const google::protobuf::Message& proto, + const std::string& file_name); +void WriteProtoToASCIIFileOrDie(const google::protobuf::Message& proto, + const std::string& file_name); +bool WriteProtoToFile(const google::protobuf::Message& proto, const std::string& file_name); +void WriteProtoToFileOrDie(const google::protobuf::Message& proto, + const std::string& file_name); + +util::Status Delete(const std::string& path, int flags); + +} // namespace file + +#endif // OR_TOOLS_BASE_FILE_H_ diff --git a/thirdparty/linux/include/ortools/base/filelinereader.h b/thirdparty/linux/include/ortools/base/filelinereader.h new file mode 100644 index 0000000..a9292b9 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/filelinereader.h @@ -0,0 +1,52 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_FILELINEREADER_H_ +#define OR_TOOLS_BASE_FILELINEREADER_H_ + +#include +#include +#include +#include + +#include "ortools/base/callback.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/file.h" + +namespace operations_research { +// The FileLineReader class will read a text file specified by +// 'filename' line by line. Each line will be cleaned with respect to +// termination ('\n' and '\r'). The line callback will be called in +// sequence on each line. +class FileLineReader { + public: + // Creates a file line reader object that will read the file 'filename' + // line by line. + explicit FileLineReader(const char* const filename); + + ~FileLineReader(); + + // Sets the line callback and takes ownership. + void set_line_callback(Callback1* const callback); + // Reloads the file line by line. + void Reload(); + // Indicates if the file was loaded successfully. + bool loaded_successfully() const; + + private: + const char* filename_; + std::unique_ptr > line_callback_; + bool loaded_successfully_; +}; +} // namespace operations_research +#endif // OR_TOOLS_BASE_FILELINEREADER_H_ diff --git a/thirdparty/linux/include/ortools/base/hash.h b/thirdparty/linux/include/ortools/base/hash.h new file mode 100644 index 0000000..56044a3 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/hash.h @@ -0,0 +1,149 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_HASH_H_ +#define OR_TOOLS_BASE_HASH_H_ + + +#include +#include +#include + +#include "ortools/base/basictypes.h" + +// In SWIG mode, we don't want anything besides these top-level includes. +#if !defined(SWIG) + +namespace operations_research { +// 32 bit version. +static inline void mix(uint32& a, uint32& b, uint32& c) { // NOLINT + a -= b; + a -= c; + a ^= (c >> 13); + b -= c; + b -= a; + b ^= (a << 8); + c -= a; + c -= b; + c ^= (b >> 13); + a -= b; + a -= c; + a ^= (c >> 12); + b -= c; + b -= a; + b ^= (a << 16); + c -= a; + c -= b; + c ^= (b >> 5); + a -= b; + a -= c; + a ^= (c >> 3); + b -= c; + b -= a; + b ^= (a << 10); + c -= a; + c -= b; + c ^= (b >> 15); +} + +// 64 bit version. +static inline void mix(uint64& a, uint64& b, uint64& c) { // NOLINT + a -= b; + a -= c; + a ^= (c >> 43); + b -= c; + b -= a; + b ^= (a << 9); + c -= a; + c -= b; + c ^= (b >> 8); + a -= b; + a -= c; + a ^= (c >> 38); + b -= c; + b -= a; + b ^= (a << 23); + c -= a; + c -= b; + c ^= (b >> 5); + a -= b; + a -= c; + a ^= (c >> 35); + b -= c; + b -= a; + b ^= (a << 49); + c -= a; + c -= b; + c ^= (b >> 11); + a -= b; + a -= c; + a ^= (c >> 12); + b -= c; + b -= a; + b ^= (a << 18); + c -= a; + c -= b; + c ^= (b >> 22); +} +inline uint32 Hash32NumWithSeed(uint32 num, uint32 c) { + uint32 b = 0x9e3779b9UL; // The golden ratio; an arbitrary value. + operations_research::mix(num, b, c); + return c; +} + +inline uint64 Hash64NumWithSeed(uint64 num, uint64 c) { + uint64 b = GG_ULONGLONG(0xe08c1d668b756f82); // More of the golden ratio. + operations_research::mix(num, b, c); + return c; +} +} // namespace operations_research + +// Support a few hash<> operators, in the hash namespace. +namespace std { +template +struct hash> { + size_t operator()(const std::pair& p) const { + size_t h1 = hash()(p.first); + size_t h2 = hash()(p.second); + // The decision below is at compile time + return (sizeof(h1) <= sizeof(uint32)) + ? // NOLINT + operations_research::Hash32NumWithSeed(h1, h2) + : operations_research::Hash64NumWithSeed(h1, h2); + } +}; + +template +struct hash> { + public: + size_t operator()(const std::array& t) const { + uint64 current = 71; + for (int index = 0; index < N; ++index) { + const T& elem = t[index]; + const uint64 new_hash = hash()(elem); + current = operations_research::Hash64NumWithSeed(current, new_hash); + } + return current; + } + // Less than operator for MSVC. + bool operator()(const std::array& a, const std::array& b) const { + return a < b; + } + static const size_t bucket_size = 4; // These are required by MSVC. + static const size_t min_buckets = 8; // 4 and 8 are defaults. +}; +} // namespace std + +#endif // SWIG + +#endif // OR_TOOLS_BASE_HASH_H_ diff --git a/thirdparty/linux/include/ortools/base/int_type.h b/thirdparty/linux/include/ortools/base/int_type.h new file mode 100755 index 0000000..3fa71a4 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/int_type.h @@ -0,0 +1,339 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// IntType is a simple template class mechanism for defining "logical" +// integer-like class types that support many of the same functionalities +// as native integer types, but which prevent assignment, construction, and +// other operations from other similar integer-like types. Essentially, the +// template class IntType (where ValueType assumes +// valid scalar types such as int, uint, int32, etc) has the additional +// property that it cannot be assigned to or constructed from other IntTypes +// or native integer types of equal or implicitly convertible type. +// +// The class is useful for preventing mingling of integer variables with +// different logical roles or units. Unfortunately, C++ provides relatively +// good type-safety for user-defined classes but not for integer types. It is +// essentially up to the user to use nice variable names and comments to prevent +// accidental mismatches, such as confusing a user-index with a group-index or a +// time-in-milliseconds with a time-in-seconds. The use of typedefs are limited +// in that regard as they do not enforce type-safety. +// +// USAGE ----------------------------------------------------------------------- +// +// DEFINE_INT_TYPE(IntTypeName, ValueType); +// +// where: +// IntTypeName: is the desired (unique) name for the "logical" integer type. +// ValueType: is one of the integral types: +// (int, int64, short, long, char, unsigned version). +// +// DISALLOWED OPERATIONS / TYPE-SAFETY ENFORCEMENT ----------------------------- +// +// Consider these definitions and variable declarations: +// DEFINE_INT_TYPE(GlobalDocID, int64); +// DEFINE_INT_TYPE(LocalDocID, int64); +// GlobalDocID global; +// LocalDocID local; +// +// The class IntType prevents: +// +// 1) Assignments of other IntTypes with different IntTypeNames. +// +// global = local; <-- Fails to compile! +// local = global; <-- Fails to compile! +// +// 2) Explicit/implicit conversion from an IntType to another IntType. +// +// LocalDocID l(global); <-- Fails to compile! +// LocalDocID l = global; <-- Fails to compile! +// +// void GetGlobalDoc(GlobalDocID global) { } +// GetGlobalDoc(global); <-- Compiles fine, types match! +// GetGlobalDoc(local); <-- Fails to compile! +// +// 3) Implicit conversion from an IntType to a native integer type. +// +// void GetGlobalDoc(int64 global) { ... +// GetGlobalDoc(global); <-- Fails to compile! +// GetGlobalDoc(local); <-- Fails to compile! +// +// void GetLocalDoc(int32 local) { ... +// GetLocalDoc(global); <-- Fails to compile! +// GetLocalDoc(local); <-- Fails to compile! +// +// +// SUPPORTED OPERATIONS -------------------------------------------------------- +// +// The following operators are supported: unary: ++ (both prefix and postfix), +// +, -, ! (logical not), ~ (one's complement); comparison: ==, !=, <, <=, >, +// >=; numerical: +, -, *, /; assignment: =, +=, -=, /=, *=; stream: <<. Each +// operator allows the same IntTypeName and the ValueType to be used on +// both left- and right-hand sides. +// +// It also supports an accessor value() returning the stored value as ValueType, +// and a templatized accessor value() method that serves as syntactic sugar +// for static_cast(var.value()). These accessors are useful when assigning +// the stored value into protocol buffer fields and using it as printf args. +// +// The class also defines a hash functor that allows the IntType to be used +// as key to hashable containers such as std::unordered_{map|set}. +// +// We suggest using the IntTypeIndexedContainer wrapper around STL +// std::vector (see int_type_indexed_std::vector.h) if an IntType is intended +// to be used as an index into these containers. These wrappers are +// indexed in a type-safe manner using IntTypes to ensure type-safety. +// +// NB: this implementation does not attempt to abide by or enforce dimensional +// analysis on these scalar types. +// +// EXAMPLES -------------------------------------------------------------------- +// +// DEFINE_INT_TYPE(GlobalDocID, int64); +// GlobalDocID global = 3; +// cout << global; <-- Prints 3 to stdout. +// +// for (GlobalDocID i(0); i < global; ++i) { +// cout << i; +// } <-- Print(ln)s 0 1 2 to stdout +// +// DEFINE_INT_TYPE(LocalDocID, int64); +// LocalDocID local; +// cout << local; <-- Prints 0 to stdout it default +// initializes the value to 0. +// +// local = 5; +// local *= 2; +// LocalDocID l(local); +// cout << l + local; <-- Prints 20 to stdout. +// +// GenericSearchRequest request; +// request.set_doc_id(global.value()); <-- Uses value() to extract the value +// from the IntType class. +// +// REMARKS --------------------------------------------------------------------- +// +// The following bad usage is permissible although discouraged. Essentially, it +// involves using the value*() accessors to extract the native integer type out +// of the IntType class. Keep in mind that the primary reason for the IntType +// class is to prevent *accidental* mingling of similar logical integer types -- +// and not type casting from one type to another. +// +// DEFINE_INT_TYPE(GlobalDocID, int64); +// DEFINE_INT_TYPE(LocalDocID, int64); +// GlobalDocID global; +// LocalDocID local; +// +// global = local.value(); <-- Compiles fine. +// +// void GetGlobalDoc(GlobalDocID global) { ... +// GetGlobalDoc(local.value()); <-- Compiles fine. +// +// void GetGlobalDoc(int64 global) { ... +// GetGlobalDoc(local.value()); <-- Compiles fine. + +#ifndef OR_TOOLS_BASE_INT_TYPE_H_ +#define OR_TOOLS_BASE_INT_TYPE_H_ + +#include +#include +#include +#include // NOLINT + +#include "ortools/base/macros.h" + +template +class IntType; + +// Defines the IntType using value_type and typedefs it to int_type_name. +// The struct int_type_name ## _tag_ trickery is needed to ensure that a new +// type is created per int_type_name. +#define DEFINE_INT_TYPE(int_type_name, value_type) \ + struct int_type_name##_tag_ {}; \ + typedef IntType int_type_name; + +// Holds a integral value (of type ValueType) and behaves as a +// ValueType by exposing assignment, unary, comparison, and arithmetic +// operators. +// +// The template parameter IntTypeName defines the name for the int type and must +// be unique within a binary (the convenient DEFINE_INT_TYPE macro at the end of +// the file generates a unique IntTypeName). The parameter ValueType defines +// the integer type value (see supported list above). +// +// This class is NOT thread-safe. +template +class IntType { + public: + typedef _ValueType ValueType; // for non-member operators + typedef IntType ThisType; // Syntactic sugar. + + public: + // Default c'tor initializing value_ to 0. + IntType() : value_(0) {} + // C'tor explicitly initializing from a ValueType. + explicit IntType(ValueType value) : value_(value) {} + // IntType uses the default copy constructor and destructor. + + // -- ACCESSORS -------------------------------------------------------------- + // The class provides a value() accessor returning the stored ValueType value_ + // as well as a templatized accessor that is just a syntactic sugar for + // static_cast(var.value()); + ValueType value() const { return value_; } + + template + ValType value() const { + return static_cast(value_); + } + + // -- UNARY OPERATORS -------------------------------------------------------- + ThisType& operator++() { // prefix ++ + ++value_; + return *this; + } + const ThisType operator++(int v) { // postfix ++ + ThisType temp(*this); + ++value_; + return temp; + } + ThisType& operator--() { // prefix -- + --value_; + return *this; + } + const ThisType operator--(int v) { // postfix -- + ThisType temp(*this); + --value_; + return temp; + } + + bool operator!() const { return value_ == 0; } + const ThisType operator+() const { return ThisType(value_); } + const ThisType operator-() const { return ThisType(-value_); } + const ThisType operator~() const { return ThisType(~value_); } + +// -- ASSIGNMENT OPERATORS --------------------------------------------------- +// We support the following assignment operators: =, +=, -=, *=, /=, <<=, >>= +// and %= for both ThisType and ValueType. +#define INT_TYPE_ASSIGNMENT_OP(op) \ + ThisType& operator op(const ThisType& arg_value) { \ + value_ op arg_value.value(); \ + return *this; \ + } \ + ThisType& operator op(ValueType arg_value) { \ + value_ op arg_value; \ + return *this; \ + } + INT_TYPE_ASSIGNMENT_OP(=); + INT_TYPE_ASSIGNMENT_OP(+=); + INT_TYPE_ASSIGNMENT_OP(-=); + INT_TYPE_ASSIGNMENT_OP(*=); + INT_TYPE_ASSIGNMENT_OP(/=); + INT_TYPE_ASSIGNMENT_OP(<<=); // NOLINT + INT_TYPE_ASSIGNMENT_OP(>>=); // NOLINT + INT_TYPE_ASSIGNMENT_OP(%=); +#undef INT_TYPE_ASSIGNMENT_OP + + private: + // The integer value of type ValueType. + ValueType value_; +}; + +// -- NON-MEMBER STREAM OPERATORS ---------------------------------------------- +// We provide the << operator, primarily for logging purposes. Currently, there +// seems to be no need for an >> operator. +template +std::ostream& operator<<(std::ostream& os, // NOLINT + IntType arg) { + return os << arg.value(); +} + +// -- NON-MEMBER ARITHMETIC OPERATORS ------------------------------------------ +// We support only the +, -, *, and / operators with the same IntType and +// ValueType types. The reason is to allow simple manipulation on these IDs +// when used as indices in std::vectors and arrays. +// +// NB: Although it is possible to do IntType * IntType and IntType / IntType, +// it is probably non-sensical from a dimensionality analysis perspective. +#define INT_TYPE_ARITHMETIC_OP(op) \ + template \ + static inline IntType operator op( \ + IntType id_1, \ + IntType id_2) { \ + id_1 op## = id_2.value(); \ + return id_1; \ + } \ + template \ + static inline IntType operator op( \ + IntType id, \ + typename IntType::ValueType arg_val) { \ + id op## = arg_val; \ + return id; \ + } \ + template \ + static inline IntType operator op( \ + typename IntType::ValueType arg_val, \ + IntType id) { \ + IntType obj(arg_val); \ + obj op## = id.value(); \ + return obj; \ + } +INT_TYPE_ARITHMETIC_OP(+); +INT_TYPE_ARITHMETIC_OP(-); +INT_TYPE_ARITHMETIC_OP(*); +INT_TYPE_ARITHMETIC_OP(/); +INT_TYPE_ARITHMETIC_OP(<<); // NOLINT +INT_TYPE_ARITHMETIC_OP(>>); // NOLINT +INT_TYPE_ARITHMETIC_OP(%); +#undef INT_TYPE_ARITHMETIC_OP + +// -- NON-MEMBER COMPARISON OPERATORS ------------------------------------------ +// Static inline comparison operators. We allow all comparison operators among +// the following types (OP \in [==, !=, <, <=, >, >=]: +// IntType OP IntType +// IntType OP ValueType +// ValueType OP IntType +#define INT_TYPE_COMPARISON_OP(op) \ + template \ + static inline bool operator op(IntType id_1, \ + IntType id_2) { \ + return id_1.value() op id_2.value(); \ + } \ + template \ + static inline bool operator op( \ + IntType id, \ + typename IntType::ValueType val) { \ + return id.value() op val; \ + } \ + template \ + static inline bool operator op( \ + typename IntType::ValueType val, \ + IntType id) { \ + return val op id.value(); \ + } +INT_TYPE_COMPARISON_OP(==); // NOLINT +INT_TYPE_COMPARISON_OP(!=); // NOLINT +INT_TYPE_COMPARISON_OP(<); // NOLINT +INT_TYPE_COMPARISON_OP(<=); // NOLINT +INT_TYPE_COMPARISON_OP(>); // NOLINT +INT_TYPE_COMPARISON_OP(>=); // NOLINT +#undef INT_TYPE_COMPARISON_OP + +namespace std { +template +struct hash > { + size_t operator()(const IntType& idx) const { + return hash()(idx.value()); + } +}; +} // namespace std + +#endif // OR_TOOLS_BASE_INT_TYPE_H_ diff --git a/thirdparty/linux/include/ortools/base/int_type_indexed_vector.h b/thirdparty/linux/include/ortools/base/int_type_indexed_vector.h new file mode 100755 index 0000000..a9ca0c2 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/int_type_indexed_vector.h @@ -0,0 +1,207 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file provides the ITIVector container that wraps around the STL +// std::vector. +// The wrapper restricts indexing to a pre-specified type-safe integer type or +// IntType (see base/int_type.h). It prevents accidental indexing +// by different "logical" integer-like types (e.g. another IntType) or native +// integer types. The wrapper is useful as C++ and the standard template +// library allow the user to mix "logical" integral indices that might have a +// different role. +// +// The container can only be indexed by an instance of an IntType class, which +// can be declared as: +// +// DEFINE_INT_TYPE(IntTypeName, IntTypeValueType); +// +// where IntTypeName is the desired name for the "logical" integer-like type +// and the ValueType is a supported native integer type such as int or +// uint64 (see base/int_type.h for details). +// +// The wrapper exposes all public methods of STL std::vector and behaves mostly +// as +// a pass-through. The only method modified to ensure type-safety is the +// operator [] and the at() method. +// +// EXAMPLES -------------------------------------------------------------------- +// +// DEFINE_INT_TYPE(PhysicalChildIndex, int32); +// ITIVector vec; +// +// PhysicalChildIndex physical_index; +// vec[physical_index] = ...; <-- index type match: compiles properly. +// vec.at(physical_index) = ...; <-- index type match: compiles properly. +// +// int32 physical_index; +// vec[physical_index] = ...; <-- fails to compile. +// vec.at(physical_index) = ...; <-- fails to compile. +// +// DEFINE_INT_TYPE(LogicalChildIndex, int32); +// int32 logical_index; +// vec[logical_index] = ...; <-- fails to compile. +// vec.at(logical_index) = ...; <-- fails to compile. +// +// N.B.: Since the iterators are not wrapped themselves, it's possible +// (but certainly not recommended) to perform arithmetic on them: +// +// *(vec.begin() + 0) = ...; + +#ifndef OR_TOOLS_BASE_INT_TYPE_INDEXED_VECTOR_H_ +#define OR_TOOLS_BASE_INT_TYPE_INDEXED_VECTOR_H_ + +#include +#include +#include + +#include "ortools/base/macros.h" +#include "ortools/base/int_type.h" + +// STL std::vector +// ------------------------------------------------------------------ +template > +class ITIVector : protected std::vector { + public: + typedef std::vector ParentType; + typedef typename ParentType::size_type size_type; + typedef typename ParentType::allocator_type allocator_type; + typedef typename ParentType::value_type value_type; + typedef typename ParentType::reference reference; + typedef typename ParentType::const_reference const_reference; + typedef typename ParentType::pointer pointer; + typedef typename ParentType::const_pointer const_pointer; + typedef typename ParentType::iterator iterator; + typedef typename ParentType::const_iterator const_iterator; + typedef typename ParentType::reverse_iterator reverse_iterator; + typedef typename ParentType::const_reverse_iterator const_reverse_iterator; + + public: + ITIVector() {} + explicit ITIVector(const allocator_type& a) : ParentType(a) {} + ITIVector(size_type n, const value_type& v = value_type(), + const allocator_type& a = allocator_type()) + : ParentType(n, v, a) {} + ITIVector(const ITIVector& x) : ParentType(x.get()) {} + template + ITIVector(InputIteratorType first, InputIteratorType last, + const allocator_type& a = allocator_type()) + : ParentType(first, last, a) {} + ~ITIVector() {} + + // -- Accessors -------------------------------------------------------------- + // This const accessor is useful in defining the comparison operators below. + const ParentType& get() const { return *this; } + // The mutable accessor is useful when using auxiliar methods relying on + // std::vector parameters such as JoinUsing(), strings::Split(), etc. Methods + // relying solely on iterators (e.g. STLDeleteElements) should work just fine + // without the need for mutable_get(). NB: It should be used only in this + // case and thus should not be abused to index the underlying std::vector + // without + // the appropriate IntType. + ParentType* mutable_get() { return this; } + + // -- Modified methods ------------------------------------------------------- + reference operator[](IntType i) { + return ParentType::operator[](i.template value()); + } + const_reference operator[](IntType i) const { + return ParentType::operator[](i.template value()); + } + reference at(IntType i) { return ParentType::at(i.template value()); } + const_reference at(IntType i) const { + return ParentType::at(i.template value()); + } + + // -- Pass-through methods to STL std::vector + // ------------------------------------- + ITIVector& operator=(const ITIVector& x) { + ParentType::operator=(x.get()); + return *this; + } + + void assign(size_type n, const value_type& val) { + ParentType::assign(n, val); + } + template + void assign(InputIt f, InputIt l) { + ParentType::assign(f, l); + } + + iterator begin() { return ParentType::begin(); } + const_iterator begin() const { return ParentType::begin(); } + iterator end() { return ParentType::end(); } + const_iterator end() const { return ParentType::end(); } + reverse_iterator rbegin() { return ParentType::rbegin(); } + const_reverse_iterator rbegin() const { return ParentType::rbegin(); } + reverse_iterator rend() { return ParentType::rend(); } + const_reverse_iterator rend() const { return ParentType::rend(); } + + size_type size() const { return ParentType::size(); } + size_type max_size() const { return ParentType::max_size(); } + + void resize(size_type new_size, value_type x = value_type()) { + ParentType::resize(new_size, x); + } + + size_type capacity() const { return ParentType::capacity(); } + bool empty() const { return ParentType::empty(); } + void reserve(size_type n) { ParentType::reserve(n); } + void push_back(const value_type& x) { ParentType::push_back(x); } + void pop_back() { ParentType::pop_back(); } + void swap(ITIVector& x) { ParentType::swap(*x.mutable_get()); } + void clear() { return ParentType::clear(); } + + reference front() { return ParentType::front(); } + const_reference front() const { return ParentType::front(); } + reference back() { return ParentType::back(); } + const_reference back() const { return ParentType::back(); } + pointer data() { return ParentType::data(); } + const_pointer data() const { return ParentType::data(); } + + iterator erase(iterator pos) { return ParentType::erase(pos); } + iterator erase(iterator first, iterator last) { + return ParentType::erase(first, last); + } + iterator insert(iterator pos, const value_type& x) { + return ParentType::insert(pos, x); + } + void insert(iterator pos, size_type n, const value_type& x) { + ParentType::insert(pos, n, x); + } + template + void insert(iterator pos, IIt first, IIt last) { + ParentType::insert(pos, first, last); + } +}; + +#define ITIVECTOR_COMPARISON_OP(op) \ + template \ + inline bool operator op(const ITIVector& x, \ + const ITIVector& y) { \ + return x.get() op y.get(); \ + } +ITIVECTOR_COMPARISON_OP(== ); // NOLINT +ITIVECTOR_COMPARISON_OP(!= ); // NOLINT +ITIVECTOR_COMPARISON_OP(< ); // NOLINT +ITIVECTOR_COMPARISON_OP(<= ); // NOLINT +ITIVECTOR_COMPARISON_OP(> ); // NOLINT +ITIVECTOR_COMPARISON_OP(>= ); // NOLINT +#undef ITIVECTOR_COMPARISON_OP + +template +inline void swap(ITIVector& x, + ITIVector& y) { + x.swap(y); +} + +#endif // OR_TOOLS_BASE_INT_TYPE_INDEXED_VECTOR_H_ diff --git a/thirdparty/linux/include/ortools/base/integral_types.h b/thirdparty/linux/include/ortools/base/integral_types.h new file mode 100644 index 0000000..56fe683 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/integral_types.h @@ -0,0 +1,126 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_INTEGRAL_TYPES_H_ +#define OR_TOOLS_BASE_INTEGRAL_TYPES_H_ + +#include // NOLINT + +#ifndef SWIG +// Standard typedefs +typedef signed char schar; +typedef signed char int8; +typedef short int16; // NOLINT +typedef int int32; +#ifdef COMPILER_MSVC +typedef __int64 int64; // NOLINT +#else +typedef long long int64; // NOLINT +#endif /* COMPILER_MSVC */ + +// NOTE: unsigned types are DANGEROUS in loops and other arithmetical +// places. Use the signed types unless your variable represents a bit +// pattern (eg a hash value) or you really need the extra bit. Do NOT +// use 'unsigned' to express "this value should always be positive"; +// use assertions for this. + +typedef unsigned char uint8; +typedef unsigned short uint16; // NOLINT +typedef unsigned int uint32; +#ifdef COMPILER_MSVC +typedef unsigned __int64 uint64; +#else +typedef unsigned long long uint64; // NOLINT +#endif /* COMPILER_MSVC */ + +// A type to represent a Unicode code-point value. As of Unicode 4.0, +// such values require up to 21 bits. +// (For type-checking on pointers, make this explicitly signed, +// and it should always be the signed version of whatever int32 is.) +typedef signed int char32; + +// A type to represent a natural machine word (for e.g. efficiently +// scanning through memory for checksums or index searching). Don't use +// this for storing normal integers. Ideally this would be just +// unsigned int, but our 64-bit architectures use the LP64 model +// (http://www.opengroup.org/public/tech/aspen/lp64_wp.htm), hence +// their ints are only 32 bits. We want to use the same fundamental +// type on all archs if possible to preserve *printf() compatability. +typedef unsigned long uword_t; // NOLINT + +// A signed natural machine word. In general you want to use "int" +// rather than "sword_t" +typedef long sword_t; // NOLINT + +#endif /* SWIG */ + +// long long macros to be used because gcc and vc++ use different suffixes, +// and different size specifiers in format strings +#undef GG_LONGLONG +#undef GG_ULONGLONG +#undef GG_LL_FORMAT + +#ifdef COMPILER_MSVC /* if Visual C++ */ + +// VC++ long long suffixes +#define GG_LONGLONG(x) x##I64 +#define GG_ULONGLONG(x) x##UI64 + +// Length modifier in printf format std::string for int64's (e.g. within %d) +#define GG_LL_FORMAT "I64" // As in printf("%I64d", ...) +#define GG_LL_FORMAT_W L"I64" + +#else /* not Visual C++ */ + +#define GG_LONGLONG(x) x##LL +#define GG_ULONGLONG(x) x##ULL +#define GG_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also. +#define GG_LL_FORMAT_W L"ll" + +#endif // COMPILER_MSVC + +static const uint8 kuint8max = static_cast(0xFF); +static const uint16 kuint16max = static_cast(0xFFFF); +static const uint32 kuint32max = static_cast(0xFFFFFFFF); +static const uint64 kuint64max = + static_cast(GG_LONGLONG(0xFFFFFFFFFFFFFFFF)); +static const int8 kint8min = static_cast(0x80); +static const int8 kint8max = static_cast(0x7F); +static const int16 kint16min = static_cast(0x8000); +static const int16 kint16max = static_cast(0x7FFF); +static const int32 kint32min = static_cast(0x80000000); +static const int32 kint32max = static_cast(0x7FFFFFFF); +static const int64 kint64min = + static_cast(GG_LONGLONG(0x8000000000000000)); +static const int64 kint64max = + static_cast(GG_LONGLONG(0x7FFFFFFFFFFFFFFF)); + +#ifdef STLPORT +#include +// int64 output not present in STL port. +inline std::ostream& operator<<(std::ostream& os, int64 i) { + char buffer[20]; + snprintf(buffer, sizeof(buffer), "%lld", i); + os << buffer; + return os; +} + +inline std::ostream& operator<<(std::ostream& os, uint64 i) { + char buffer[20]; + snprintf(buffer, sizeof(buffer), "%llu", i); + os << buffer; + return os; +} +#endif // STLPORT + +#endif // OR_TOOLS_BASE_INTEGRAL_TYPES_H_ diff --git a/thirdparty/linux/include/ortools/base/iterator_adaptors.h b/thirdparty/linux/include/ortools/base/iterator_adaptors.h new file mode 100644 index 0000000..25d9fde --- /dev/null +++ b/thirdparty/linux/include/ortools/base/iterator_adaptors.h @@ -0,0 +1,39 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_ITERATOR_ADAPTORS_H_ +#define OR_TOOLS_BASE_ITERATOR_ADAPTORS_H_ + +namespace gtl { + +template +class ReverseView { + public: + typedef typename Container::const_reverse_iterator const_it; + + ReverseView(const Container& c) : c_(c) {} + const_it begin() const { return c_.rbegin(); } + const_it end() const { return c_.rend(); } + + private: + const Container& c_; +}; + +template +ReverseView reversed_view(const Container& c) { + return ReverseView(c); +} + +} // namespace gtl + +#endif // OR_TOOLS_BASE_ITERATOR_ADAPTORS_H_ diff --git a/thirdparty/linux/include/ortools/base/jniutil.h b/thirdparty/linux/include/ortools/base/jniutil.h new file mode 100644 index 0000000..320b46b --- /dev/null +++ b/thirdparty/linux/include/ortools/base/jniutil.h @@ -0,0 +1,66 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_JNIUTIL_H_ +#define OR_TOOLS_BASE_JNIUTIL_H_ + +#include +#include +#include "ortools/base/logging.h" + +class JNIUtil { + public: + // Creates a Java jstring from a null-terminated UTF-8 encoded C String. + // The caller must delete the jstring reference. + static jstring MakeJString(JNIEnv* env, const char* cstr) { + if (cstr == NULL) return NULL; + return env->NewStringUTF(cstr); + } + + // Creates a null-terminated UTF-8 encoded C std::string from a jstring. + // The returned std::string should be "delete[]"-ed when no longer needed. + static char* MakeCString(JNIEnv* env, jstring str) { + if (str == NULL) return NULL; + jsize length = env->GetStringUTFLength(str); + const char* src = env->GetStringUTFChars(str, NULL); + char* dst = new char[length + 1]; + memcpy(dst, src, length); + dst[length] = '\0'; + env->ReleaseStringUTFChars(str, src); + return dst; + } + + // Creates a new char array from a jbyteArray. + // The caller must delete[] the returned array. + static char* MakeCharArray(JNIEnv* env, jbyteArray a, int* size) { + jsize n = env->GetArrayLength(a); + *size = n; + jbyte* jba = new jbyte[n]; + + env->GetByteArrayRegion(a, 0, n, jba); + // We make use of the fact that jbyte's are really just chars. + // If this changes (different VM, etc.) things will break. + return reinterpret_cast(jba); + } + + // Produces a jbyteArray from a char array. + static jbyteArray MakeJByteArray(JNIEnv* env, const char* a, int size) { + // Create empty array object + jbyteArray output = env->NewByteArray(size); + // Fill it + env->SetByteArrayRegion(output, 0, size, reinterpret_cast(a)); + return output; + } +}; + +#endif // OR_TOOLS_BASE_JNIUTIL_H_ diff --git a/thirdparty/linux/include/ortools/base/join.h b/thirdparty/linux/include/ortools/base/join.h new file mode 100644 index 0000000..e6e1a56 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/join.h @@ -0,0 +1,145 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_JOIN_H_ +#define OR_TOOLS_BASE_JOIN_H_ + +#include +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/stringpiece.h" + +// A buffer size large enough for all FastToBuffer functions. +const int kFastToBufferSize = 32; + +// Writes output to the beginning of the given buffer. Returns a pointer to the +// end of the std::string (i.e. to the NUL char). Buffer must be at least 12 bytes. +// Not actually fast, but maybe someday! +template +char* NumToBuffer(T i, char* buffer) { + std::stringstream ss; + ss << i; + const std::string s = ss.str(); + strcpy(buffer, s.c_str()); // NOLINT + return buffer + s.size(); +} + +struct AlphaNum { + StringPiece piece; + char digits[kFastToBufferSize]; + + // No bool ctor -- bools convert to an integral type. + // A bool ctor would also convert incoming pointers (bletch). + + AlphaNum(int32 i32) // NOLINT(runtime/explicit) + : piece(digits, NumToBuffer(i32, digits) - &digits[0]) {} + AlphaNum(uint32 u32) // NOLINT(runtime/explicit) + : piece(digits, NumToBuffer(u32, digits) - &digits[0]) {} + AlphaNum(long l) // NOLINT + : piece(digits, NumToBuffer(l, digits) - &digits[0]) {} + AlphaNum(unsigned long ul) // NOLINT + : piece(digits, NumToBuffer(ul, digits) - &digits[0]) {} + AlphaNum(int64 i64) // NOLINT(runtime/explicit) + : piece(digits, NumToBuffer(i64, digits) - &digits[0]) {} + AlphaNum(uint64 u64) // NOLINT(runtime/explicit) + : piece(digits, NumToBuffer(u64, digits) - &digits[0]) {} + AlphaNum(float f) // NOLINT(runtime/explicit) + : piece(digits, strlen(NumToBuffer(f, digits))) {} + AlphaNum(double f) // NOLINT(runtime/explicit) + : piece(digits, strlen(NumToBuffer(f, digits))) {} + AlphaNum(const char* c_str) : piece(c_str) {} // NOLINT(runtime/explicit) + AlphaNum(const StringPiece& pc) : piece(pc) {} // NOLINT(runtime/explicit) + AlphaNum(const std::string& s) : piece(s) {} // NOLINT(runtime/explicit) + + StringPiece::size_type size() const { return piece.size(); } + const char* data() const { return piece.data(); } + + private: + // Use ":" not ':' + AlphaNum(char c); // NOLINT(runtime/explicit) +}; + +extern AlphaNum gEmptyAlphaNum; + +std::string StrCat(const AlphaNum& a); +std::string StrCat(const AlphaNum& a, const AlphaNum& b); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d, const AlphaNum& e); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d, const AlphaNum& e, const AlphaNum& f); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d, const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d, const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d, const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h, const AlphaNum& i); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d, const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h, const AlphaNum& i, + const AlphaNum& j); +std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d, const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h, const AlphaNum& i, + const AlphaNum& j, const AlphaNum& k); + +void StrAppend(std::string* s, const AlphaNum& a); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, const AlphaNum& e); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, const AlphaNum& e, + const AlphaNum& f); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, const AlphaNum& e, + const AlphaNum& f, const AlphaNum& g); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, const AlphaNum& e, + const AlphaNum& f, const AlphaNum& g, const AlphaNum& h); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, const AlphaNum& e, + const AlphaNum& f, const AlphaNum& g, const AlphaNum& h, + const AlphaNum& i); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, const AlphaNum& e, + const AlphaNum& f, const AlphaNum& g, const AlphaNum& h, + const AlphaNum& i, const AlphaNum& j); +void StrAppend(std::string* s, const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, const AlphaNum& e, + const AlphaNum& f, const AlphaNum& g, const AlphaNum& h, + const AlphaNum& i, const AlphaNum& j, const AlphaNum& k); + +namespace strings { +template +std::string Join(const Iterable& elements, const std::string& separator) { + std::string out; + for (const auto& e : elements) { + if (!out.empty()) out += separator; + StrAppend(&out, e); + } + return out; +} +} // namespace strings + +#endif // OR_TOOLS_BASE_JOIN_H_ diff --git a/thirdparty/linux/include/ortools/base/logging.h b/thirdparty/linux/include/ortools/base/logging.h new file mode 100644 index 0000000..4e735b9 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/logging.h @@ -0,0 +1,172 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_LOGGING_H_ +#define OR_TOOLS_BASE_LOGGING_H_ + +#include +#include +#include // NOLINT +#include "ortools/base/commandlineflags.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/macros.h" + +DECLARE_int32(log_level); +DECLARE_bool(log_prefix); + +#if defined(_MSC_VER) +#pragma warning(disable : 4722) +#endif + +// Always-on checking +#define CHECK(x) \ + if (!(x)) \ + LogMessageFatal(__FILE__, __LINE__).stream() << "Check " \ + "failed: " #x +#define CHECK_LT(x, y) CHECK((x) < (y)) +#define CHECK_GT(x, y) CHECK((x) > (y)) +#define CHECK_LE(x, y) CHECK((x) <= (y)) +#define CHECK_GE(x, y) CHECK((x) >= (y)) +#define CHECK_EQ(x, y) CHECK((x) == (y)) +#define CHECK_NE(x, y) CHECK((x) != (y)) + +// Debug-only checking. +#ifdef NDEBUG +#define DCHECK(x) \ + while (false) CHECK(x) +#define DCHECK_LT(x, y) \ + while (false) CHECK((x) < (y)) +#define DCHECK_GT(x, y) \ + while (false) CHECK((x) > (y)) +#define DCHECK_LE(x, y) \ + while (false) CHECK((x) <= (y)) +#define DCHECK_GE(x, y) \ + while (false) CHECK((x) >= (y)) +#define DCHECK_EQ(x, y) \ + while (false) CHECK((x) == (y)) +#define DCHECK_NE(x, y) \ + while (false) CHECK((x) != (y)) +#else +#define DCHECK(x) CHECK(x) +#define DCHECK_LT(x, y) CHECK((x) < (y)) +#define DCHECK_GT(x, y) CHECK((x) > (y)) +#define DCHECK_LE(x, y) CHECK((x) <= (y)) +#define DCHECK_GE(x, y) CHECK((x) >= (y)) +#define DCHECK_EQ(x, y) CHECK((x) == (y)) +#define DCHECK_NE(x, y) CHECK((x) != (y)) +#endif // NDEBUG + +#define LOG_INFO LogMessage(__FILE__, __LINE__) +#define LOG_ERROR LOG_INFO +#define LOG_WARNING LOG_INFO +#define LOG_FATAL LogMessageFatal(__FILE__, __LINE__) +#define LOG_QFATAL LOG_FATAL + +#define VLOG(x) \ + if ((x) <= FLAGS_log_level) LOG_INFO.stream() + +#define VLOG_IS_ON(x) ((x) <= FLAGS_log_level) + +#define LOG(severity) LOG_##severity.stream() +#define LG LOG_INFO.stream() +#define LOG_IF(severity, condition) \ + !(condition) ? (void)0 : LogMessageVoidify() & LOG(severity) + +#ifdef NDEBUG +#define LOG_DFATAL LOG_ERROR +#define DFATAL ERROR +#define DLOG(severity) true ? (void)0 : LogMessageVoidify() & LOG(severity) +#define DLOG_IF(severity, condition) \ + (true || !(condition)) ? (void)0 : LogMessageVoidify() & LOG(severity) +#define DVLOG(x) \ + while (false && VLOG_IS_ON(x)) LogMessageVoidify() & LOG_INFO.stream() +#else +#define LOG_DFATAL LOG_FATAL +#define DFATAL FATAL +#define DLOG(severity) LOG(severity) +#define DLOG_IF(severity, condition) LOG_IF(severity, condition) +#define DVLOG VLOG +#endif + +// Poor man version of LOG_EVERY_N +#define LOG_EVERY_N(severity, n) LOG(severity) +#define LOG_EVERY_N_SEC(severity, n) LOG(severity) + +namespace operations_research { +class DateLogger { + public: + DateLogger(); + char* const HumanDate(); + + private: + char buffer_[9]; +}; +} // namespace operations_research + +class LogMessage { + public: + LogMessage(const char* file, int line) + : +#ifdef __ANDROID__ + log_stream_(std::cout) +#else + log_stream_(std::cerr) +#endif + { + if (FLAGS_log_prefix) { + log_stream_ << "[" << pretty_date_.HumanDate() << "] " << file << ":" + << line << ": "; + } + } + ~LogMessage() { log_stream_ << "\n"; } + std::ostream& stream() { return log_stream_; } + + protected: + std::ostream& log_stream_; + + private: + operations_research::DateLogger pretty_date_; + DISALLOW_COPY_AND_ASSIGN(LogMessage); +}; + +class LogMessageFatal : public LogMessage { + public: + LogMessageFatal(const char* file, int line) : LogMessage(file, line) {} + ~LogMessageFatal() { + log_stream_ << "\n"; + abort(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(LogMessageFatal); +}; + +// This class is used to explicitly ignore values in the conditional +// logging macros. This avoids compiler warnings like "value computed +// is not used" and "statement has no effect". +class LogMessageVoidify { + public: + LogMessageVoidify() {} + // This has to be an operator with a precedence lower than << but + // higher than "?:". See its usage. + void operator&(std::ostream&) {} +}; + +template +T&& CheckNotNull(T&& t) { + CHECK(t != nullptr); + return std::forward(t); +} +#define CHECK_NOTNULL(x) CheckNotNull((x)) + +#endif // OR_TOOLS_BASE_LOGGING_H_ diff --git a/thirdparty/linux/include/ortools/base/macros.h b/thirdparty/linux/include/ortools/base/macros.h new file mode 100644 index 0000000..329f25f --- /dev/null +++ b/thirdparty/linux/include/ortools/base/macros.h @@ -0,0 +1,53 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_MACROS_H_ +#define OR_TOOLS_BASE_MACROS_H_ + +#if (defined(COMPILER_GCC3) || defined(OS_MACOSX)) && !defined(SWIG) +#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#else // GCC +#define ATTRIBUTE_UNUSED +#endif // GCC + +#define COMPILE_ASSERT(x, msg) + +#ifdef NDEBUG +const bool DEBUG_MODE = false; +#else // NDEBUG +const bool DEBUG_MODE = true; +#endif // NDEBUG + +// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. +// It goes in the private: declarations in a class. +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through +// between switch labels. +#ifndef FALLTHROUGH_INTENDED +#define FALLTHROUGH_INTENDED \ + do { \ + } while (0) +#endif + +template +char(&ArraySizeHelper(T(&array)[N]))[N]; +#ifndef COMPILER_MSVC +template +char(&ArraySizeHelper(const T(&array)[N]))[N]; +#endif +#define arraysize(array) (sizeof(ArraySizeHelper(array))) + +#endif // OR_TOOLS_BASE_MACROS_H_ diff --git a/thirdparty/linux/include/ortools/base/map_util.h b/thirdparty/linux/include/ortools/base/map_util.h new file mode 100644 index 0000000..9b52aa1 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/map_util.h @@ -0,0 +1,177 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_MAP_UTIL_H_ +#define OR_TOOLS_BASE_MAP_UTIL_H_ + +#include +#include "ortools/base/logging.h" + +namespace operations_research { + +// Perform a lookup in a map or std::unordered_map. +// If the key is present in the map then the value associated with that +// key is returned, otherwise the value passed as a default is returned. +template +const typename Collection::value_type::second_type& FindWithDefault( + const Collection& collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return value; + } + return it->second; +} + +// Perform a lookup in a map or std::unordered_map. +// If the key is present a const pointer to the associated value is returned, +// otherwise a NULL pointer is returned. +template +const typename Collection::value_type::second_type* FindOrNull( + const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + return &it->second; +} + +// Perform a lookup in a map or std::unordered_map. +// Same as above but the returned pointer is not const and can be used to change +// the stored value. +template +typename Collection::value_type::second_type* FindOrNull( + Collection& collection, // NOLINT + const typename Collection::value_type::first_type& key) { + typename Collection::iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + return &it->second; +} + +// Perform a lookup in a map or std::unordered_map whose values are pointers. +// If the key is present a const pointer to the associated value is returned, +// otherwise a NULL pointer is returned. +// This function does not distinguish between a missing key and a key mapped +// to a NULL value. +template +const typename Collection::value_type::second_type FindPtrOrNull( + const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return 0; + } + return it->second; +} + +// Change the value associated with a particular key in a map or +// std::unordered_map. If the key is not present in the map the key and value +// are inserted, otherwise the value is updated to be a copy of the value +// provided. True indicates that an insert took place, false indicates an +// update. +template +bool InsertOrUpdate(Collection* const collection, const Key& key, + const Value& value) { + std::pair ret = + collection->insert(typename Collection::value_type(key, value)); + if (!ret.second) { + // update + ret.first->second = value; + return false; + } + return true; +} + +// Insert a new key and value into a map or std::unordered_map. +// If the key is not present in the map the key and value are +// inserted, otherwise nothing happens. True indicates that an insert +// took place, false indicates the key was already present. +template +bool InsertIfNotPresent(Collection* const collection, const Key& key, + const Value& value) { + std::pair ret = + collection->insert(typename Collection::value_type(key, value)); + return ret.second; +} + +// Inserts a new std::pair into a map or std::unordered_map. +// Insert a new key into a set or std::unordered_set. +// Dies if the key is already present. +template +void InsertOrDie(Collection* const collection, + const typename Collection::value_type& value) { + CHECK(collection->insert(value).second) << "duplicate value: " << value; +} + +// Inserts a new key/value into a map or std::unordered_map. +// Dies if the key is already present. +template +void InsertOrDie(Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& data) { + typedef typename Collection::value_type value_type; + CHECK(collection->insert(value_type(key, data)).second) + << "duplicate key: " << key; +} + +// Perform a lookup in map or std::unordered_map. +// If the key is present and value is non-NULL then a copy of the value +// associated with the key is made into *value. Returns whether key was present. +template +bool FindCopy(const Collection& collection, const Key& key, + Value* const value) { + typename Collection::const_iterator it = collection.find(key); + if (it == collection.end()) { + return false; + } + if (value) { + *value = it->second; + } + return true; +} + +// Test to see if a set, map, std::unordered_set or std::unordered_map contains +// a particular key. Returns true if the key is in the collection. +template +bool ContainsKey(const Collection& collection, const Key& key) { + typename Collection::const_iterator it = collection.find(key); + return it != collection.end(); +} + +template +const typename Collection::value_type::second_type& FindOrDie( + const Collection& collection, + const typename Collection::value_type::first_type& key) { + typename Collection::const_iterator it = collection.find(key); + CHECK(it != collection.end()) << "Map key not found: " << key; + return it->second; +} + +// Lookup a key in a map or std::unordered_map, insert it if it is not present. +// Returns a reference to the value associated with the key. +template +typename Collection::value_type::second_type& LookupOrInsert( + Collection* const collection, + const typename Collection::value_type::first_type& key, + const typename Collection::value_type::second_type& value) { + std::pair ret = + collection->insert(typename Collection::value_type(key, value)); + return ret.first->second; +} +} // namespace operations_research + +#endif // OR_TOOLS_BASE_MAP_UTIL_H_ diff --git a/thirdparty/linux/include/ortools/base/mathutil.h b/thirdparty/linux/include/ortools/base/mathutil.h new file mode 100644 index 0000000..318271f --- /dev/null +++ b/thirdparty/linux/include/ortools/base/mathutil.h @@ -0,0 +1,119 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_MATHUTIL_H_ +#define OR_TOOLS_BASE_MATHUTIL_H_ + +#include +#include +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/casts.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" + +namespace operations_research { +class MathUtil { + public: + // CeilOfRatio + // FloorOfRatio + // Returns the ceil (resp. floor) of the ratio of two integers. + // + // IntegralType: any integral type, whether signed or not. + // numerator: any integer: positive, negative, or zero. + // denominator: a non-zero integer, positive or negative. + template + static IntegralType CeilOfRatio(IntegralType numerator, + IntegralType denominator) { + DCHECK_NE(0, denominator); + const IntegralType rounded_toward_zero = numerator / denominator; + const IntegralType intermediate_product = rounded_toward_zero * denominator; + const bool needs_adjustment = + (rounded_toward_zero >= 0) && + ((denominator > 0 && numerator > intermediate_product) || + (denominator < 0 && numerator < intermediate_product)); + const IntegralType adjustment = static_cast(needs_adjustment); + const IntegralType ceil_of_ratio = rounded_toward_zero + adjustment; + return ceil_of_ratio; + } + template + static IntegralType FloorOfRatio(IntegralType numerator, + IntegralType denominator) { + DCHECK_NE(0, denominator); + const IntegralType rounded_toward_zero = numerator / denominator; + const IntegralType intermediate_product = rounded_toward_zero * denominator; + const bool needs_adjustment = + (rounded_toward_zero <= 0) && + ((denominator > 0 && numerator < intermediate_product) || + (denominator < 0 && numerator > intermediate_product)); + const IntegralType adjustment = static_cast(needs_adjustment); + const IntegralType floor_of_ratio = rounded_toward_zero - adjustment; + return floor_of_ratio; + } + + // Returns the greatest common divisor of two unsigned integers x and y. + static unsigned int GCD(unsigned int x, unsigned int y) { + while (y != 0) { + unsigned int r = x % y; + x = y; + y = r; + } + return x; + } + + // Returns the least common multiple of two unsigned integers. Returns zero + // if either is zero. + static unsigned int LeastCommonMultiple(unsigned int a, unsigned int b) { + if (a > b) { + return (a / MathUtil::GCD(a, b)) * b; + } else if (a < b) { + return (b / MathUtil::GCD(b, a)) * a; + } else { + return a; + } + } + + // Absolute value of x. + // Works correctly for unsigned types and + // for special floating point values. + // Note: 0.0 and -0.0 are not differentiated by Abs (Abs(0.0) is -0.0), + // which should be OK: see the comment for Max above. + template + static T Abs(const T x) { + return x > 0 ? x : -x; + } + + // Returns the square of x. + template + static T Square(const T x) { + return x * x; + } + + // Euclid's Algorithm. + // Returns: the greatest common divisor of two unsigned integers x and y. + static int64 GCD64(int64 x, int64 y) { + DCHECK_GE(x, 0); + DCHECK_GE(y, 0); + while (y != 0) { + int64 r = x % y; + x = y; + y = r; + } + return x; + } +}; +} // namespace operations_research + +#endif // OR_TOOLS_BASE_MATHUTIL_H_ diff --git a/thirdparty/linux/include/ortools/base/murmur.h b/thirdparty/linux/include/ortools/base/murmur.h new file mode 100644 index 0000000..7cfc1ce --- /dev/null +++ b/thirdparty/linux/include/ortools/base/murmur.h @@ -0,0 +1,28 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_MURMUR_H_ +#define OR_TOOLS_BASE_MURMUR_H_ + +#include "ortools/base/thorough_hash.h" + +namespace util_hash { +// In the or-tools project, MurmurHash64 is just a redirection towards +// ThoroughHash. Ideally, it is meant to be using the murmurhash +// algorithm described in http://murmurhash.googlepages.com. +inline uint64 MurmurHash64(const char *buf, const size_t len) { + return ::operations_research::ThoroughHash(buf, len); +} +} + +#endif // OR_TOOLS_BASE_MURMUR_H_ diff --git a/thirdparty/linux/include/ortools/base/mutex.h b/thirdparty/linux/include/ortools/base/mutex.h new file mode 100644 index 0000000..ca4a073 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/mutex.h @@ -0,0 +1,72 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_MUTEX_H_ +#define OR_TOOLS_BASE_MUTEX_H_ + +#include // NOLINT +#include // NOLINT + +#include "ortools/base/macros.h" + +namespace operations_research { +class Mutex { + public: + Mutex(); + ~Mutex(); + void Lock(); + void Unlock(); + bool TryLock(); + + friend class CondVar; + + private: + std::mutex real_mutex_; + DISALLOW_COPY_AND_ASSIGN(Mutex); +}; + +class MutexLock { + public: + explicit MutexLock(Mutex* const mutex) : mutex_(mutex) { + this->mutex_->Lock(); + } + + ~MutexLock() { this->mutex_->Unlock(); } + + private: + Mutex* const mutex_; + DISALLOW_COPY_AND_ASSIGN(MutexLock); +}; + +class CondVar { + public: + CondVar(); + ~CondVar(); + void Wait(Mutex* const mu); + void Signal(); + void SignalAll(); + + private: + std::condition_variable real_condition_; + DISALLOW_COPY_AND_ASSIGN(CondVar); +}; + +// Checking macros. +#define EXCLUSIVE_LOCK_FUNCTION(x) +#define UNLOCK_FUNCTION(x) +#define LOCKS_EXCLUDED(x) +#define EXCLUSIVE_LOCKS_REQUIRED(x) +#define NO_THREAD_SAFETY_ANALYSIS +#define GUARDED_BY(x) +} // namespace operations_research +#endif // OR_TOOLS_BASE_MUTEX_H_ diff --git a/thirdparty/linux/include/ortools/base/numbers.h b/thirdparty/linux/include/ortools/base/numbers.h new file mode 100644 index 0000000..eb476e5 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/numbers.h @@ -0,0 +1,34 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_NUMBERS_H_ +#define OR_TOOLS_BASE_NUMBERS_H_ + +#include +#include "ortools/base/integral_types.h" +#include "ortools/base/join.h" + +namespace operations_research { +// Convert strings to numerical values. +// Leading and trailing spaces are allowed. +// Values may be rounded on over- and underflow. +bool safe_strtof(const char* str, float* value); +bool safe_strtod(const char* str, double* value); +bool safe_strtof(const std::string& str, float* value); +bool safe_strtod(const std::string& str, double* value); +bool safe_strto64(const std::string& str, int64* value); +// Converting int to std::string. +inline std::string SimpleItoa(int i) { return StrCat(i); } +} // namespace operations_research + +#endif // OR_TOOLS_BASE_NUMBERS_H_ diff --git a/thirdparty/linux/include/ortools/base/port.h b/thirdparty/linux/include/ortools/base/port.h new file mode 100644 index 0000000..e142c08 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/port.h @@ -0,0 +1,34 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_PORT_H_ +#define OR_TOOLS_BASE_PORT_H_ + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() MUST_USE_RESULT; +// +#if defined(SWIG) +#define MUST_USE_RESULT +#elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +#define MUST_USE_RESULT +#endif + +#define PREDICT_FALSE(x) x +#define PREDICT_TRUE(x) x + +#endif // OR_TOOLS_BASE_PORT_H_ diff --git a/thirdparty/linux/include/ortools/base/python-swig.h b/thirdparty/linux/include/ortools/base/python-swig.h new file mode 100644 index 0000000..06431b0 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/python-swig.h @@ -0,0 +1,370 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Static part of SWIG-generated C++ wrapper for Python (_module_name.cc). +// +// This file should only be included in base.i inside Python-specific part: +// #ifdef SWIGPYTHON +// %{ +// #include "ortools/base/swig/python-swig.cc" +// %} +// #endif +// It has no XXX_H_ guard because SWIG protects all %include'd files to be used +// only once. + +#ifndef OR_TOOLS_BASE_PYTHON_SWIG_H_ +#define OR_TOOLS_BASE_PYTHON_SWIG_H_ + +#if PY_VERSION_HEX >= 0x03030000 // Py3.3+ +// Use Py3 unicode str() type for C++ strings. +#ifdef PyString_FromStringAndSize +#undef PyString_FromStringAndSize +#endif +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize + +#ifdef PyString_AsString +#undef PyString_AsString +#endif +#define PyString_AsString PyUnicode_AsUTF8 + +#ifdef PyString_AsStringAndSize +#undef PyString_AsStringAndSize +#endif +static inline int PyString_AsStringAndSize(PyObject* obj, char** buf, + Py_ssize_t* psize) { + if (PyUnicode_Check(obj)) { + *buf = PyUnicode_AsUTF8AndSize(obj, psize); + return *buf == NULL ? -1 : 0; + } else if (PyBytes_Check(obj)) { + return PyBytes_AsStringAndSize(obj, buf, psize); + } + PyErr_SetString(PyExc_TypeError, "Expecting str or bytes"); + return -1; +} +#endif // Py3.3+ + +template +inline bool PyObjAs(PyObject* pystr, T* cstr) { + T::undefined; // You need to define specialization PyObjAs +} +template +inline PyObject* PyObjFrom(const T& c) { + T::undefined; // You need to define specialization PyObjFrom +} + +#ifdef HAS_GLOBAL_STRING +template <> +inline bool PyObjAs(PyObject* pystr, ::std::string* cstr) { + char* buf; + Py_ssize_t len; +#if PY_VERSION_HEX >= 0x03030000 + if (PyUnicode_Check(pystr)) { + buf = PyUnicode_AsUTF8AndSize(pystr, &len); + if (!buf) return false; + } else // NOLINT +#endif + if (PyBytes_AsStringAndSize(pystr, &buf, &len) == -1) + return false; + if (cstr) cstr->assign(buf, len); + return true; +} +#endif +template +inline bool PyObjAs(PyObject* pystr, std::string* cstr) { + char* buf; + Py_ssize_t len; +#if PY_VERSION_HEX >= 0x03030000 + if (PyUnicode_Check(pystr)) { + buf = PyUnicode_AsUTF8AndSize(pystr, &len); + if (!buf) return false; + } else // NOLINT +#endif + if (PyBytes_AsStringAndSize(pystr, &buf, &len) == -1) + return false; + if (cstr) cstr->assign(buf, len); + return true; +} +#ifdef HAS_GLOBAL_STRING +template <> +inline PyObject* PyObjFrom(const ::std::string& c) { + return PyString_FromStringAndSize(c.data(), c.size()); +} +#endif +template <> +inline PyObject* PyObjFrom(const std::string& c) { + return PyString_FromStringAndSize(c.data(), c.size()); +} + +// Do numeric specialization. + +#include + +template <> +inline bool PyObjAs(PyObject* py, int* c) { + long i = PyInt_AsLong(py); // NOLINT + if (i == -1 && PyErr_Occurred()) // TypeError or OverflowError. + return false; // Not a Python int. + if (i < std::numeric_limits::min() || + i > std::numeric_limits::max()) + return false; // Not C int. + if (c) *c = static_cast(i); + return true; +} + +template <> +inline bool PyObjAs(PyObject* py, unsigned int* c) { + long i = PyInt_AsLong(py); // NOLINT + if (i == -1 && PyErr_Occurred()) return false; // Not a Python int. + if (i < 0 || i > std::numeric_limits::max()) return false; + if (c) *c = static_cast(i); + return true; +} + +template <> +inline bool PyObjAs(PyObject* py, long* c) { // NOLINT + long i = PyInt_AsLong(py); // NOLINT + if (i == -1 && PyErr_Occurred()) return false; // Not a Python int. + if (c) *c = i; + return true; +} + +template <> +inline bool PyObjAs(PyObject* py, long long* c) { // NOLINT + long long i; // NOLINT +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(py)) { + i = PyInt_AsLong(py); + } else { + if (!PyLong_Check(py)) return false; // Not a Python long. +#else + { +#endif + i = PyLong_AsLongLong(py); + if (i == -1 && PyErr_Occurred()) return false; // Not a C long long. + } + if (c) *c = i; + return true; +} + +template <> +inline bool PyObjAs(PyObject* py, unsigned long long* c) { // NOLINT + unsigned long long i; // NOLINT +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(py)) { + i = PyInt_AsUnsignedLongLongMask(py); + } else // NOLINT +#endif + { + if (!PyLong_Check(py)) return false; // Not a Python long. + i = PyLong_AsUnsignedLongLong(py); + if (i == (unsigned long long)-1 && PyErr_Occurred()) // NOLINT + return false; + } + if (c) *c = i; + return true; +} + +template <> +inline bool PyObjAs(PyObject* py, double* c) { + double d; + if (PyFloat_Check(py)) { + d = PyFloat_AsDouble(py); +#if PY_MAJOR_VERSION < 3 + } else if (PyInt_Check(py)) { + d = PyInt_AsLong(py); + } else if (!PyLong_Check(py)) { + return false; // float or int/long expected +#endif + } else { + d = PyLong_AsDouble(py); + if (d == -1.0 && PyErr_Occurred()) { + return false; // Overflow (or TypeError for PY3) + } + } + if (c) *c = d; + return true; +} + +template <> +inline PyObject* PyObjFrom(const double& c) { + return PyFloat_FromDouble(c); +} +template <> +inline bool PyObjAs(PyObject* py, float* c) { + double d; + if (!PyObjAs(py, &d)) return false; + if (c) *c = static_cast(d); + return true; +} + +template <> +inline PyObject* PyObjFrom(const float& c) { + return PyFloat_FromDouble(c); +} +template <> +inline bool PyObjAs(PyObject* py, bool* c) { + if (!PyBool_Check(py)) return false; // Not a Python bool. + if (c) *c = PyObject_Not(py) ? false : true; + return true; +} + +inline int SwigPyIntOrLong_Check(PyObject* o) { + return (PyLong_Check(o) +#if PY_MAJOR_VERSION <= 2 + || PyInt_Check(o) +#endif + ); // NOLINT +} + +inline PyObject* SwigString_FromString(const std::string& s) { + return PyString_FromStringAndSize(s.data(), s.size()); +} + +inline std::string SwigString_AsString(PyObject* o) { + return std::string(PyString_AsString(o)); +} + +// STL std::vector for common types + +namespace { // NOLINT + +template +struct vector_pusher { + typedef T* ptr; + static void push(std::vector* o, ptr e) { o->push_back(*e); } +}; + +template +struct vector_pusher { + typedef T* ptr; + static void push(std::vector* o, ptr e) { o->push_back(e); } +}; + +}; // namespace + +template +inline bool vector_input_helper(PyObject* seq, std::vector* out, + bool (*convert)(PyObject*, T* const)) { + PyObject* item, *it = PyObject_GetIter(seq); + if (!it) return false; + T elem; + while ((item = PyIter_Next(it))) { + bool success = convert(item, &elem); + Py_DECREF(item); + if (!success) { + Py_DECREF(it); + return false; + } + if (out) out->push_back(elem); + } + Py_DECREF(it); + return static_cast(!PyErr_Occurred()); +} + +template +inline bool vector_input_wrap_helper(PyObject* seq, std::vector* out, + swig_type_info* swig_Tp_type) { + PyObject* item, *it = PyObject_GetIter(seq); + if (!it) { + PyErr_SetString(PyExc_TypeError, "sequence expected"); + return false; + } + typename vector_pusher::ptr elem; + while ((item = PyIter_Next(it))) { + if (SWIG_ConvertPtr(item, reinterpret_cast(&elem), + swig_Tp_type, 0) == -1) { + Py_DECREF(it); + it = PyObject_Repr(item); + Py_DECREF(item); + const char* repr = it ? PyString_AsString(it) : "not"; + PyErr_Format(PyExc_TypeError, "'%s' expected, %s found", + SWIG_TypePrettyName(swig_Tp_type), repr); + Py_XDECREF(it); + return false; + } + Py_DECREF(item); + if (out) vector_pusher::push(out, elem); + } + Py_DECREF(it); + return true; +} + +// Helper function for turning a C++ std::vector (or any other instance that +// supports the std::vector-like iterator interface) into a Python list of +// Ts. +// The converter function converts a C++ object of type const T or const T& +// into the corresponding Python object. +template +inline PyObject* list_output_helper(const T* vec, Converter converter) { + if (vec == NULL) Py_RETURN_NONE; // Return a nice out-of-band value. + PyObject* lst = PyList_New(vec->size()); + if (lst == NULL) return NULL; + int i = 0; + for (typename T::const_reference pt : *vec) { + PyObject* obj = converter(pt); + if (!obj) { + Py_DECREF(lst); + return NULL; + } + PyList_SET_ITEM(lst, i++, obj); + } + return lst; +} + +template +struct OutConverter { + PyObject* operator()(const T x) const { + return SWIG_NewPointerObj((void*)x, type_, new_); // NOLINT + } + swig_type_info* type_; + int new_; + OutConverter(swig_type_info* type, int new_object) + : type_(type), new_(new_object) {} +}; + +template +inline PyObject* vector_output_helper(const std::vector* vec, + PyObject* (*converter)(const TR x)) { + return list_output_helper(vec, converter); +} + +template +inline PyObject* vector_output_helper(const std::vector* vec, + const OutConverter& converter) { + return list_output_helper(vec, converter); +} + +template +inline PyObject* vector_output_wrap_helper(const std::vector* vec, + swig_type_info* swig_Tp_type, + bool newobj = false) { +#if 1 + OutConverter converter(swig_Tp_type, newobj); + return vector_output_helper(vec, converter); +#else // Lambda version + auto converter = [](const T* x) { + return SWIG_NewPointerObj((void*)x, swig_Tp_type, newobj); // NOLINT + } return list_output_helper(vec, converter); +#endif +} + +#if PY_MAJOR_VERSION > 2 +/* SWIG 2's own C preprocessor macro for this is too strict. + * It requires a (x) parameter which doesn't work for the case where the + * function is being passed by & as a converter into a helper such as + * vector_output_helper above. */ +#undef PyInt_FromLong +#define PyInt_FromLong PyLong_FromLong +#endif + +#endif // OR_TOOLS_BASE_PYTHON_SWIG_H_ diff --git a/thirdparty/linux/include/ortools/base/random.h b/thirdparty/linux/include/ortools/base/random.h new file mode 100644 index 0000000..1a21525 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/random.h @@ -0,0 +1,109 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_RANDOM_H_ +#define OR_TOOLS_BASE_RANDOM_H_ + +#include +#include "ortools/base/basictypes.h" + +namespace operations_research { + +// ACM minimal standard random number generator. (Re-entrant.) +class ACMRandom { + public: + explicit ACMRandom(int32 seed) : seed_(seed) {} + + int32 Next(); + + // Returns a random value in [0..n-1]. If n == 0, always returns 0. + int32 Uniform(int32 n); + + int64 Next64(); + + float RndFloat() { + return Next() * 0.000000000465661273646; // x: x * (M-1) = 1 - eps + } + + // Returns a double in [0, 1). + double RndDouble() { + // Android does not provide ieee754.h and the associated types. + union { + double d; + int64 i; + } ieee_double; + ieee_double.i = Next64(); + ieee_double.i &= ~(1LL << 63); // Clear sign bit. + // The returned number will be between 0 and 1. Take into account the + // exponent offset. + ieee_double.i |= (1023LL << 52); + return ieee_double.d - static_cast(1.0); + } + + double RandDouble() { return RndDouble(); } + + double UniformDouble(double x) { return RandDouble() * x; } + + // Returns a double in [a, b). The distribution is uniform. + double UniformDouble(double a, double b) { return a + (b - a) * RndDouble(); } + + // Returns true with probability 1/n. If n=0, always returns true. + bool OneIn(int n) { return Uniform(n) == 0; } + + void Reset(int32 seed) { seed_ = seed; } + static int32 HostnamePidTimeSeed(); + static int32 DeterministicSeed(); + +// RandomNumberGenerator concept. Example: +// ACMRandom rand(my_seed); +// std::random_shuffle(myvec.begin(), myvec.end(), rand); +#if defined(_MSC_VER) + typedef __int64 difference_type; // NOLINT +#else + typedef long long difference_type; // NOLINT +#endif + int64 operator()(int64 val_max) { return Next64() % val_max; } + + private: + int32 seed_; +}; + +// This is meant to become an implementation of (or a wrapper around) +// http://www.cplusplus.com/reference/random/mt19937, but for now it is just +// using ACMRandom. +class MTRandom : public ACMRandom { + public: + explicit MTRandom(int32 seed) : ACMRandom(seed) {} + // MTRandom also supports a std::string seed. + explicit MTRandom(const std::string& str_seed) + : ACMRandom(GenerateInt32SeedFromString(str_seed)) {} + + MTRandom() : ACMRandom(ACMRandom::HostnamePidTimeSeed()) {} + uint64 Rand64() { return static_cast(Next64()); } + + private: + int32 GenerateInt32SeedFromString(const std::string& str) { + uint32 seed = 1234567; + for (size_t i = 0; i < str.size(); ++i) { + seed *= 1000003; // prime + seed += static_cast(str[i]); + } + return seed >> 1; // Will fit into an int32. + } +}; + +typedef ACMRandom RandomBase; + +} // namespace operations_research + +#endif // OR_TOOLS_BASE_RANDOM_H_ diff --git a/thirdparty/linux/include/ortools/base/recordio.h b/thirdparty/linux/include/ortools/base/recordio.h new file mode 100644 index 0000000..ae94349 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/recordio.h @@ -0,0 +1,135 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_RECORDIO_H_ +#define OR_TOOLS_BASE_RECORDIO_H_ + +#include +#include +#include "ortools/base/file.h" + +// This file defines some IO interfaces to compatible with Google +// IO specifications. +namespace recordio { +// This class appends a protocol buffer to a file in a binary format. +// The data written in the file follows the following format (sequentially): +// - MagicNumber (32 bits) to recognize this format. +// - Uncompressed data payload size (64 bits). +// - Compressed data payload size (64 bits), or 0 if the +// data is not compressed. +// - Payload, possibly compressed. See RecordWriter::Compress() +// and RecordReader::Uncompress. +class RecordWriter { + public: + // Magic number when reading and writing protocol buffers. + static const int kMagicNumber; + + explicit RecordWriter(File* const file); + + template + bool WriteProtocolMessage(const P& proto) { + std::string uncompressed_buffer; + proto.SerializeToString(&uncompressed_buffer); + const uint64 uncompressed_size = uncompressed_buffer.size(); + const std::string compressed_buffer = + use_compression_ ? Compress(uncompressed_buffer) : ""; + const uint64 compressed_size = compressed_buffer.size(); + if (file_->Write(&kMagicNumber, sizeof(kMagicNumber)) != + sizeof(kMagicNumber)) { + return false; + } + if (file_->Write(&uncompressed_size, sizeof(uncompressed_size)) != + sizeof(uncompressed_size)) { + return false; + } + if (file_->Write(&compressed_size, sizeof(compressed_size)) != + sizeof(compressed_size)) { + return false; + } + if (use_compression_) { + if (file_->Write(compressed_buffer.c_str(), compressed_size) != + compressed_size) { + return false; + } + } else { + if (file_->Write(uncompressed_buffer.c_str(), uncompressed_size) != + uncompressed_size) { + return false; + } + } + return true; + } + // Closes the underlying file. + bool Close(); + + void set_use_compression(bool use_compression); + + private: + std::string Compress(const std::string& input) const; + File* const file_; + bool use_compression_; +}; + +// This class reads a protocol buffer from a file. +// The format must be the one described in RecordWriter, above. +class RecordReader { + public: + explicit RecordReader(File* const file); + + template + bool ReadProtocolMessage(P* const proto) { + uint64 usize = 0; + uint64 csize = 0; + int magic_number = 0; + if (file_->Read(&magic_number, sizeof(magic_number)) != + sizeof(magic_number)) { + return false; + } + if (magic_number != RecordWriter::kMagicNumber) { + return false; + } + if (file_->Read(&usize, sizeof(usize)) != sizeof(usize)) { + return false; + } + if (file_->Read(&csize, sizeof(csize)) != sizeof(csize)) { + return false; + } + std::unique_ptr buffer(new char[usize + 1]); + if (csize != 0) { // The data is compressed. + std::unique_ptr compressed_buffer(new char[csize + 1]); + if (file_->Read(compressed_buffer.get(), csize) != csize) { + return false; + } + compressed_buffer[csize] = '\0'; + Uncompress(compressed_buffer.get(), csize, buffer.get(), usize); + } else { + if (file_->Read(buffer.get(), usize) != usize) { + return false; + } + } + proto->ParseFromArray(buffer.get(), usize); + return true; + } + + // Closes the underlying file. + bool Close(); + + private: + void Uncompress(const char* const source, uint64 source_size, + char* const output_buffer, uint64 output_size) const; + + File* const file_; +}; +} // namespace recordio + +#endif // OR_TOOLS_BASE_RECORDIO_H_ diff --git a/thirdparty/linux/include/ortools/base/small_map.h b/thirdparty/linux/include/ortools/base/small_map.h new file mode 100644 index 0000000..44c1081 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/small_map.h @@ -0,0 +1,20 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_SMALL_MAP_H_ +#define OR_TOOLS_BASE_SMALL_MAP_H_ + +template +class small_map : public T {}; + +#endif // OR_TOOLS_BASE_SMALL_MAP_H_ diff --git a/thirdparty/linux/include/ortools/base/small_ordered_set.h b/thirdparty/linux/include/ortools/base/small_ordered_set.h new file mode 100644 index 0000000..79e6339 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/small_ordered_set.h @@ -0,0 +1,20 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_SMALL_ORDERED_SET_H_ +#define OR_TOOLS_BASE_SMALL_ORDERED_SET_H_ + +template +class small_ordered_set : public T {}; + +#endif // OR_TOOLS_BASE_SMALL_ORDERED_SET_H_ diff --git a/thirdparty/linux/include/ortools/base/sparsetable.h b/thirdparty/linux/include/ortools/base/sparsetable.h new file mode 100644 index 0000000..64a20e5 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/sparsetable.h @@ -0,0 +1,71 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_SPARSETABLE_H_ +#define OR_TOOLS_BASE_SPARSETABLE_H_ + +#include +#include "ortools/base/logging.h" + +namespace operations_research { +// This class implements a simple block-based sparse std::vector. +template +class sparsetable { + public: + sparsetable() : size_(0) {} + + void resize(int new_size) { + CHECK_GE(new_size, 0); + size_ = new_size; + const int reduced_size = (size_ + kBlockSize - 1) / kBlockSize; + if (reduced_size != elements_.size()) { + elements_.resize(reduced_size); + masks_.resize(reduced_size, 0U); + } + } + + const T& get(int index) const { + DCHECK_GE(index, 0); + DCHECK_LT(index, size_); + DCHECK(test(index)); + return elements_[index / kBlockSize][index % kBlockSize]; + } + + void set(int index, const T& elem) { + const int offset = index / kBlockSize; + const int pos = index % kBlockSize; + if (elements_[offset].size() == 0) { + elements_[offset].resize(kBlockSize); + } + elements_[offset][index % kBlockSize] = elem; + masks_[offset] |= (1U << pos); + } + + bool test(int index) const { + const int offset = index / kBlockSize; + const int pos = index % kBlockSize; + return ((masks_[offset] & (1U << pos)) != 0); + } + + int size() const { return size_; } + + private: + static const int kBlockSize = 32; + + int size_; + std::vector > elements_; + std::vector masks_; +}; +} // namespace operations_research + +#endif // OR_TOOLS_BASE_SPARSETABLE_H_ diff --git a/thirdparty/linux/include/ortools/base/split.h b/thirdparty/linux/include/ortools/base/split.h new file mode 100644 index 0000000..13b0553 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/split.h @@ -0,0 +1,90 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_SPLIT_H_ +#define OR_TOOLS_BASE_SPLIT_H_ + +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/stringpiece.h" + +namespace strings { +std::vector Split(const std::string& full, const char* delim, int flags); + +std::vector Split(const std::string& full, char delim, int flags); + +// StringPiece version. Its advantages is that it avoids creating a lot of +// small strings. Note however that the full std::string must outlive the usage +// of the result. +// +// Hack: the int64 allow the C++ compiler to distinguish the two functions. It +// is possible to implement this more cleanly at the cost of more complexity. +std::vector Split(const std::string& full, const char* delim, + int64 flags); + +namespace delimiter { +inline const char* AnyOf(const char* x) { return x; } +} // namespace delimiter + +inline int SkipEmpty() { return 0xDEADBEEF; } + +} // namespace strings + +// Split a std::string using a nul-terminated list of character +// delimiters. For each component, parse using the provided +// parsing function and if successful, append it to 'result'. +// Return true if and only if all components parse successfully. +// If there are consecutive delimiters, this function skips over +// all of them. This function will correctly handle parsing +// strings that have embedded \0s. +template +bool SplitStringAndParse(StringPiece source, const std::string& delim, + bool (*parse)(const std::string& str, T* value), + std::vector* result); + +// We define here a very truncated version of the powerful strings::Split() +// function. As of 2013-04, it can only be used like this: +// const char* separators = ...; +// std::vector result = strings::Split( +// full, strings::delimiter::AnyOf(separators), strings::SkipEmpty()); +// +// TODO(user): The current interface has a really bug prone side effect because +// it can also be used without the AnyOf(). If separators contains only one +// character, this is fine, but if it contains more, then the meaning is +// different: Split() should interpret the whole std::string as a delimiter. Fix +// this. +// ###################### TEMPLATE INSTANTIATIONS BELOW ####################### +template +bool SplitStringAndParse(const std::string& source, const std::string& delim, + bool (*parse)(const std::string& str, T* value), + std::vector* result) { + CHECK(nullptr != parse); + CHECK(nullptr != result); + CHECK_GT(delim.size(), 0); + const std::vector pieces = + ::strings::Split(source, strings::delimiter::AnyOf(delim.c_str()), + static_cast(strings::SkipEmpty())); + T t; + for (StringPiece piece : pieces) { + if (!parse(piece.as_string(), &t)) return false; + result->push_back(t); + } + return true; +} + +#endif // OR_TOOLS_BASE_SPLIT_H_ diff --git a/thirdparty/linux/include/ortools/base/status.h b/thirdparty/linux/include/ortools/base/status.h new file mode 100644 index 0000000..8980bc9 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/status.h @@ -0,0 +1,65 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_STATUS_H_ +#define OR_TOOLS_BASE_STATUS_H_ + +#include +#include "ortools/base/logging.h" +#include "ortools/base/join.h" + +namespace util { + +namespace error { +enum Error { + INTERNAL = 1, + INVALID_ARGUMENT = 2, + DEADLINE_EXCEEDED = 3, +}; +} // namespace error + +struct Status { + enum { OK = 0 }; + Status() : error_code_(OK) {} + Status(int error_code) : error_code_(error_code) {} // NOLINT + Status(int error_code, const std::string& error_message) + : error_code_(error_code), error_message_(error_message) {} + Status(const Status& other) + : error_code_(other.error_code_), error_message_(other.error_message_) {} + + bool ok() const { return error_code_ == OK; } + + std::string ToString() const { + if (ok()) return "OK"; + return StrCat("ERROR #", error_code_, ": '", error_message_, "'"); + } + + std::string error_message() const { return error_message_; } + + void IgnoreError() const {} + + private: + int error_code_; + std::string error_message_; +}; + +inline std::ostream& operator<<(std::ostream& out, const Status& status) { + out << status.ToString(); + return out; +} + +} // namespace util + +#define CHECK_OK(status) CHECK_EQ("OK", (status).ToString()) + +#endif // OR_TOOLS_BASE_STATUS_H_ diff --git a/thirdparty/linux/include/ortools/base/statusor.h b/thirdparty/linux/include/ortools/base/statusor.h new file mode 100644 index 0000000..3dcdf10 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/statusor.h @@ -0,0 +1,53 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_STATUSOR_H_ +#define OR_TOOLS_BASE_STATUSOR_H_ + +#include "ortools/base/status.h" + +namespace util { + +// T should be a pointer type. Eg. StatusOr. +template +struct StatusOr { + // Non-explicit constructors, by design. + StatusOr(T value) : value_(value) { // NOLINT + CHECK(value != nullptr); // This enforces that T is a pointer type. + } + StatusOr(const Status& status) : status_(status) { // NOLINT + CHECK(!status_.ok()) << status.ToString(); + } + + // Copy constructor. + StatusOr(const StatusOr& other) + : value_(other.value_), status_(other.status_) {} + + bool ok() const { return value_ != nullptr; } + const T& ValueOrDie() const { + CHECK(ok()); + return value_; + } + + Status status() const { + return value_ != nullptr ? /*OK*/ Status() : status_; + } + + private: + T value_; + Status status_; +}; + +} // namespace util + +#endif // OR_TOOLS_BASE_STATUSOR_H_ diff --git a/thirdparty/linux/include/ortools/base/stl_util.h b/thirdparty/linux/include/ortools/base/stl_util.h new file mode 100644 index 0000000..348479e --- /dev/null +++ b/thirdparty/linux/include/ortools/base/stl_util.h @@ -0,0 +1,120 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_STL_UTIL_H_ +#define OR_TOOLS_BASE_STL_UTIL_H_ + +#include +#include + +namespace operations_research { + +// STLDeleteContainerPointers() +// For a range within a container of pointers, calls delete +// (non-array version) on these pointers. +// NOTE: for these three functions, we could just implement a DeleteObject +// functor and then call for_each() on the range and functor, but this +// requires us to pull in all of algorithm.h, which seems expensive. +// For hash_[multi]set, it is important that this deletes behind the iterator +// because the hash_set may call the hash function on the iterator when it is +// advanced, which could result in the hash function trying to deference a +// stale pointer. +template +void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) { + while (begin != end) { + ForwardIterator temp = begin; + ++begin; + delete *temp; + } +} + +// STLDeleteContainerPairSecondPointers() +// For a range within a container of pairs, calls delete +// (non-array version) on the SECOND item in the pairs. +// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator. +// Deleting the value does not always invalidate the iterator, but it may +// do so if the key is a pointer into the value object. +template +void STLDeleteContainerPairSecondPointers(ForwardIterator begin, + ForwardIterator end) { + while (begin != end) { + ForwardIterator temp = begin; + ++begin; + delete temp->second; + } +} + +inline void STLStringResizeUninitialized(std::string* s, size_t new_size) { + s->resize(new_size); +} + +// Return a mutable char* pointing to a std::string's internal buffer, +// which may not be null-terminated. Writing through this pointer will +// modify the std::string. +// +// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the +// next call to a std::string method that invalidates iterators. +// +// As of 2006-04, there is no standard-blessed way of getting a +// mutable reference to a std::string's internal buffer. However, issue 530 +// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) +// proposes this as the method. According to Matt Austern, this should +// already work on all current implementations. +inline char* string_as_array(std::string* str) { + return str->empty() ? NULL : &*str->begin(); +} + +// STLDeleteElements() deletes all the elements in an STL container and clears +// the container. This function is suitable for use with a std::vector, set, +// hash_set, or any other STL container which defines sensible begin(), end(), +// and clear() methods. +// +// If container is NULL, this function is a no-op. +// +// As an alternative to calling STLDeleteElements() directly, consider +// ElementDeleter (defined below), which ensures that your container's elements +// are deleted when the ElementDeleter goes out of scope. +template +void STLDeleteElements(T* container) { + if (!container) return; + STLDeleteContainerPointers(container->begin(), container->end()); + container->clear(); +} + +// Given an STL container consisting of (key, value) pairs, STLDeleteValues +// deletes all the "value" components and clears the container. Does nothing +// in the case it's given a NULL pointer. +template +void STLDeleteValues(T* v) { + if (!v) return; + for (typename T::iterator i = v->begin(); i != v->end(); ++i) { + delete i->second; + } + v->clear(); +} + +template +void STLClearObject(T* obj) { + T tmp; + tmp.swap(*obj); + obj->reserve(0); +} + +template +inline void STLSortAndRemoveDuplicates(T* v) { + std::sort(v->begin(), v->end()); + v->erase(std::unique(v->begin(), v->end()), v->end()); +} + +} // namespace operations_research +#endif // OR_TOOLS_BASE_STL_UTIL_H_ diff --git a/thirdparty/linux/include/ortools/base/stringpiece.h b/thirdparty/linux/include/ortools/base/stringpiece.h new file mode 100644 index 0000000..0de3c76 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/stringpiece.h @@ -0,0 +1,170 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// A std::string-like object that points to a sized piece of memory. +// +// Functions or methods may use const StringPiece& parameters to accept either +// a "const char*" or a "std::string" value that will be implicitly converted to +// a StringPiece. The implicit conversion means that it is often appropriate +// to include this .h file in other files rather than forward-declaring +// StringPiece as would be appropriate for most other Google classes. +// +// Systematic usage of StringPiece is encouraged as it will reduce unnecessary +// conversions from "const char*" to "std::string" and back again. + +#ifndef OR_TOOLS_BASE_STRINGPIECE_H_ +#define OR_TOOLS_BASE_STRINGPIECE_H_ + +#include + +#include +#include +#include +#include + +class StringPiece { + private: + const char* ptr_; + int length_; + + public: + // We provide non-explicit singleton constructors so users can pass + // in a "const char*" or a "std::string" wherever a "StringPiece" is + // expected. + StringPiece() : ptr_(NULL), length_(0) {} + StringPiece(const char* str) // NOLINT + : ptr_(str), + length_((str == NULL) ? 0 : static_cast(strlen(str))) {} + StringPiece(const std::string& str) // NOLINT + : ptr_(str.data()), + length_(static_cast(str.size())) {} + StringPiece(const char* offset, int len) : ptr_(offset), length_(len) {} + + // data() may return a pointer to a buffer with embedded NULs, and the + // returned buffer may or may not be null terminated. Therefore it is + // typically a mistake to pass data() to a routine that expects a NUL + // terminated std::string. + const char* data() const { return ptr_; } + int size() const { return length_; } + int length() const { return length_; } + bool empty() const { return length_ == 0; } + + void clear() { + ptr_ = NULL; + length_ = 0; + } + void set(const char* data, int len) { + ptr_ = data; + length_ = len; + } + void set(const char* str) { + ptr_ = str; + if (str != NULL) + length_ = static_cast(strlen(str)); + else + length_ = 0; + } + void set(const void* data, int len) { + ptr_ = reinterpret_cast(data); + length_ = len; + } + + char operator[](int i) const { return ptr_[i]; } + + void remove_prefix(int n) { + ptr_ += n; + length_ -= n; + } + + void remove_suffix(int n) { length_ -= n; } + + int compare(const StringPiece& x) const; + + std::string as_string() const { return std::string(data(), size()); } + // We also define ToString() here, since many other std::string-like + // interfaces name the routine that converts to a C++ std::string + // "ToString", and it's confusing to have the method that does that + // for a StringPiece be called "as_string()". We also leave the + // "as_string()" method defined here for existing code. + std::string ToString() const { return std::string(data(), size()); } + + void CopyToString(std::string* target) const; + void AppendToString(std::string* target) const; + + // Does "this" start with "x"? + bool starts_with(const StringPiece& x) const { + return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0)); + } + + // Does "this" end with "x"? + bool ends_with(const StringPiece& x) const { + return ((length_ >= x.length_) && + (memcmp(ptr_ + (length_ - x.length_), x.ptr_, x.length_) == 0)); + } + + // Standard STL container boilerplate. + typedef char value_type; + typedef const char* pointer; + typedef const char& reference; + typedef const char& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static const size_type npos; + typedef const char* const_iterator; + typedef const char* iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + iterator begin() const { return ptr_; } + iterator end() const { return ptr_ + length_; } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(ptr_ + length_); + } + const_reverse_iterator rend() const { return const_reverse_iterator(ptr_); } + // STL says return size_type, but Google says return int. + int max_size() const { return length_; } + int capacity() const { return length_; } + + int copy(char* buf, size_type n, size_type pos = 0) const; + + int find(const StringPiece& s, size_type pos = 0) const; + int find(char c, size_type pos = 0) const; + int rfind(const StringPiece& s, size_type pos = npos) const; + int rfind(char c, size_type pos = npos) const; + + StringPiece substr(size_type pos, size_type n = npos) const; +}; + +bool operator==(const StringPiece& x, const StringPiece& y); + +inline bool operator!=(const StringPiece& x, const StringPiece& y) { + return !(x == y); +} + +bool operator<(const StringPiece& x, const StringPiece& y); + +inline bool operator>(const StringPiece& x, const StringPiece& y) { + return y < x; +} + +inline bool operator<=(const StringPiece& x, const StringPiece& y) { + return !(x > y); +} + +inline bool operator>=(const StringPiece& x, const StringPiece& y) { + return !(x < y); +} + +// Allow StringPiece to be logged. +extern std::ostream& operator<<(std::ostream& o, const StringPiece& piece); + +#endif // OR_TOOLS_BASE_STRINGPIECE_H_ diff --git a/thirdparty/linux/include/ortools/base/stringpiece_utils.h b/thirdparty/linux/include/ortools/base/stringpiece_utils.h new file mode 100644 index 0000000..6378e18 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/stringpiece_utils.h @@ -0,0 +1,33 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_STRINGPIECE_UTILS_H_ +#define OR_TOOLS_BASE_STRINGPIECE_UTILS_H_ + +#include + +#include "ortools/base/stringpiece.h" + +namespace strings { +// Returns whether s begins with x. +inline bool StartsWith(StringPiece s, StringPiece x) { + return s.size() >= x.size() && memcmp(s.data(), x.data(), x.size()) == 0; +} + +// Returns whether s ends with x. +inline bool EndsWith(StringPiece s, StringPiece x) { + return s.size() >= x.size() && + memcmp(s.data() + (s.size() - x.size()), x.data(), x.size()) == 0; +} +} // namespace strings +#endif // OR_TOOLS_BASE_STRINGPIECE_UTILS_H_ diff --git a/thirdparty/linux/include/ortools/base/stringprintf.h b/thirdparty/linux/include/ortools/base/stringprintf.h new file mode 100644 index 0000000..ef1feb8 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/stringprintf.h @@ -0,0 +1,26 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_STRINGPRINTF_H_ +#define OR_TOOLS_BASE_STRINGPRINTF_H_ + +#include + +#include "ortools/base/stringpiece.h" + +namespace operations_research { +std::string StringPrintf(const char* const format, ...); +void SStringPrintf(std::string* const dst, const char* const format, ...); +void StringAppendF(std::string* const dst, const char* const format, ...); +} // namespace operations_research +#endif // OR_TOOLS_BASE_STRINGPRINTF_H_ diff --git a/thirdparty/linux/include/ortools/base/strongly_connected_components.h b/thirdparty/linux/include/ortools/base/strongly_connected_components.h new file mode 100644 index 0000000..5a069f0 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/strongly_connected_components.h @@ -0,0 +1,194 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + + +// This code computes the strongly connected components of a directed graph, +// and presents them sorted by reverse topological order. +// +// It implements an efficient version of Tarjan's strongly connected components +// algorithm published in: Tarjan, R. E. (1972), "Depth-first search and linear +// graph algorithms", SIAM Journal on Computing. +// +// A description can also be found here: +// http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm +// +// SIMPLE EXAMPLE: +// +// Fill a std::vector> graph; representing your graph adjacency +// lists. +// That is, graph[i] contains the nodes adjacent to node #i. The nodes must be +// integers in [0, num_nodes). Then just do: +// +// std::vector> components; +// FindStronglyConnectedComponents( +// static_cast(graph.size()), graph, &components); +// +// The nodes of each strongly connected components will be listed in each +// subvector of components. The components appear in reverse topological order: +// outgoing arcs from a component will only be towards earlier components. +// +// IMPORTANT: num_nodes will be the number of nodes of the graph. Its type +// is the type used internally by the algorithm. It is why it is better to +// convert it to int or even int32 rather than using size_t which takes 64 bits. + +#ifndef OR_TOOLS_BASE_STRONGLY_CONNECTED_COMPONENTS_H_ +#define OR_TOOLS_BASE_STRONGLY_CONNECTED_COMPONENTS_H_ + +#include +#include + +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" + +// Finds the strongly connected components of a directed graph. It is templated +// so it can be used in many contexts. See the simple example above for the +// easiest use case. +// +// The requirement of the different types are: +// - The type NodeIndex must be an integer type representing a node of the +// graph. The nodes must be in [0, num_nodes). It can be unsigned. +// - The type Graph must provide a [] operator such that the following code +// iterates over the adjacency list of the given node: +// for (const NodeIndex head : graph[node]) {} +// - The type SccOutput must implement the function: +// emplace_back(NodeIndex const* begin, NodeIndex const* end); +// It will be called with the connected components of the given graph as they +// are found (In the reverse topological order). +// +// More pratical details on the algorithm: +// - It deals properly with self-loop and duplicate nodes. +// - It is really fast! and work in O(nodes + edges). +// - Its memory usage is also bounded by O(nodes + edges) but in practice it +// uses less than the input graph. +template +void FindStronglyConnectedComponents(const NodeIndex num_nodes, + const Graph& graph, + SccOutput* components); + +// A simple custom output class that just counts the number of SCC. Not +// allocating many std::vectors can save both space and speed if your graph is +// large. +// +// Note: If this matters, you probably don't want to use +// std::vector> as +// an input either. See StaticGraph in ortools/graph/graph.h +// for an efficient graph data structure compatible with this algorithm. +template +struct SccCounterOutput { + int number_of_components = 0; + void emplace_back(NodeIndex const* b, NodeIndex const* e) { + ++number_of_components; + } + // This is just here so this class can transparently replace a code that + // use std::vector> as an SccOutput, and get its size with size(). + int size() const { return number_of_components; } +}; + +// This implementation is slightly different than a classical iterative version +// of Tarjan's strongly connected components algorithm. But basically it is +// still an iterative DFS. +// +// TODO(user): Possible optimizations: +// - Try to reserve the std::vectors which sizes are bounded by num_nodes. +// - Use an index rather than doing push_back(), pop_back() on them. +// - For a client needing many Scc computations one after another, it could be +// better to wrap this in a class so we don't need to allocate the stacks at +// each computation. +template +void FindStronglyConnectedComponents(const NodeIndex num_nodes, + const Graph& graph, + SccOutput* components) { + // Each node expanded by the DFS will be pushed on this stack. A node is only + // popped back when its strongly connected component has been explored and + // outputted. + std::vector scc_stack; + + // This is equivalent to the "low link" of a node in Tarjan's algorithm. + // Basically, scc_start_index.back() represent the 1-based index in scc_stack + // of the beginning of the current strongly connected component. All the + // nodes after this index will be on the same component. + std::vector scc_start_index; + + // Optimization. This will always be equal to scc_start_index.back() except + // when scc_stack is empty, in which case its value does not matter. + NodeIndex current_scc_start = 0; + + // Each node is assigned an index which changes 2 times in the algorithm: + // - Everyone starts with an index of 0 which means unexplored. + // - The first time they are explored by the DFS and pushed on scc_stack, they + // get their 1-based index on this stack. + // - Once they have been processed and outputted to components, they are said + // to be settled, and their index become kSettledIndex. + std::vector node_index(num_nodes, 0); + const NodeIndex kSettledIndex = std::numeric_limits::max(); + + // This is a well known way to do an efficient iterative DFS. Each time a node + // is explored, all its adjacent nodes are pushed on this stack. The iterative + // dfs processes the nodes one by one by popping them back from here. + std::vector node_to_process; + + // Loop over all the nodes not yet settled and start a DFS from each of them. + for (NodeIndex base_node = 0; base_node < num_nodes; ++base_node) { + if (node_index[base_node] != 0) continue; + DCHECK_EQ(0, node_to_process.size()); + node_to_process.push_back(base_node); + do { + const NodeIndex node = node_to_process.back(); + const NodeIndex index = node_index[node]; + if (index == 0) { + // We continue the dfs from this node and set its 1-based index. + scc_stack.push_back(node); + current_scc_start = scc_stack.size(); + node_index[node] = current_scc_start; + scc_start_index.push_back(current_scc_start); + + // Enqueue all its adjacent nodes. + NodeIndex min_head_index = kSettledIndex; + for (const NodeIndex head : graph[node]) { + const NodeIndex head_index = node_index[head]; + if (head_index == 0) { + node_to_process.push_back(head); + } else { + // Note that if head_index == kSettledIndex, nothing happens. + min_head_index = std::min(min_head_index, head_index); + } + } + + // Update the start of this strongly connected component. + // Note that scc_start_index can never be empty since it first element + // is 1 and by definition min_head_index is 1-based and can't be 0. + while (current_scc_start > min_head_index) { + scc_start_index.pop_back(); + current_scc_start = scc_start_index.back(); + } + } else { + node_to_process.pop_back(); + if (current_scc_start == index) { + // We found a strongly connected component. + components->emplace_back(&scc_stack[current_scc_start - 1], + &scc_stack[0] + scc_stack.size()); + for (int i = current_scc_start - 1; i < scc_stack.size(); ++i) { + node_index[scc_stack[i]] = kSettledIndex; + } + scc_stack.resize(current_scc_start - 1); + scc_start_index.pop_back(); + current_scc_start = + scc_start_index.empty() ? 0 : scc_start_index.back(); + } + } + } while (!node_to_process.empty()); + } +} + +#endif // OR_TOOLS_BASE_STRONGLY_CONNECTED_COMPONENTS_H_ diff --git a/thirdparty/linux/include/ortools/base/strtoint.h b/thirdparty/linux/include/ortools/base/strtoint.h new file mode 100644 index 0000000..0c3549d --- /dev/null +++ b/thirdparty/linux/include/ortools/base/strtoint.h @@ -0,0 +1,61 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_STRTOINT_H_ +#define OR_TOOLS_BASE_STRTOINT_H_ + +#include // For strtol* functions. +#include +#include "ortools/base/basictypes.h" + +namespace operations_research { +// Conversions to a 32-bit integer can pass the call to strto[u]l on 32-bit +// platforms, but need a little extra work on 64-bit platforms. +inline int32 strto32(const char* nptr, char** endptr, int base) { + return strtol(nptr, endptr, base); // NOLINT +} + +inline uint32 strtou32(const char* nptr, char** endptr, int base) { + return strtoul(nptr, endptr, base); // NOLINT +} + +// For now, long long is 64-bit on all the platforms we care about, so these +// functions can simply pass the call to strto[u]ll. +inline int64 strto64(const char* nptr, char** endptr, int base) { +#if defined(_MSC_VER) + return _strtoi64(nptr, endptr, base); // NOLINT +#else + return strtoll(nptr, endptr, base); // NOLINT +#endif // _MSC_VER +} + +inline uint64 strtou64(const char* nptr, char** endptr, int base) { +#if defined(_MSC_VER) + return _strtoui64(nptr, endptr, base); // NOLINT +#else + return strtoull(nptr, endptr, base); // NOLINT +#endif // _MSC_VER +} + +// Although it returns an int, atoi() is implemented in terms of strtol, and +// so has differing overflow and underflow behavior. atol is the same. +inline int32 atoi32(const char* nptr) { return strto32(nptr, NULL, 10); } + +inline int64 atoi64(const char* nptr) { return strto64(nptr, NULL, 10); } + +// Convenience versions of the above that take a std::string argument. +inline int32 atoi32(const std::string& s) { return atoi32(s.c_str()); } + +inline int64 atoi64(const std::string& s) { return atoi64(s.c_str()); } +} // namespace operations_research +#endif // OR_TOOLS_BASE_STRTOINT_H_ diff --git a/thirdparty/linux/include/ortools/base/strutil.h b/thirdparty/linux/include/ortools/base/strutil.h new file mode 100644 index 0000000..d0dfab9 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/strutil.h @@ -0,0 +1,33 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_STRUTIL_H_ +#define OR_TOOLS_BASE_STRUTIL_H_ + +#include +#include "ortools/base/stringpiece.h" + +using std::string; + +namespace operations_research { + +inline bool HasSuffixString(const StringPiece& str, const StringPiece& suffix) { + return str.ends_with(suffix); +} + +inline bool HasPrefixString(const StringPiece& str, const StringPiece& prefix) { + return str.starts_with(prefix); +} + +} // namespace operations_research +#endif // OR_TOOLS_BASE_STRUTIL_H_ diff --git a/thirdparty/linux/include/ortools/base/synchronization.h b/thirdparty/linux/include/ortools/base/synchronization.h new file mode 100644 index 0000000..1ca6d1e --- /dev/null +++ b/thirdparty/linux/include/ortools/base/synchronization.h @@ -0,0 +1,52 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_SYNCHRONIZATION_H_ +#define OR_TOOLS_BASE_SYNCHRONIZATION_H_ + +#include // NOLINT +#include // NOLINT + +#include "ortools/base/logging.h" + +namespace operations_research { +class Barrier { + public: + explicit Barrier(int num_threads) + : num_to_block_(num_threads), num_to_exit_(num_threads) {} + + bool Block() { + std::unique_lock mutex_lock(mutex_); + this->num_to_block_--; + CHECK_GE(this->num_to_block_, 0); + if (num_to_block_ > 0) { + while (num_to_block_ > 0) { + condition_.wait(mutex_lock); + } + } else { + condition_.notify_all(); + } + this->num_to_exit_--; + CHECK_GE(this->num_to_exit_, 0); + return this->num_to_exit_ == 0; + } + + private: + std::mutex mutex_; + std::condition_variable condition_; + int num_to_block_; + int num_to_exit_; + DISALLOW_COPY_AND_ASSIGN(Barrier); +}; +} // namespace operations_research +#endif // OR_TOOLS_BASE_SYNCHRONIZATION_H_ diff --git a/thirdparty/linux/include/ortools/base/sysinfo.h b/thirdparty/linux/include/ortools/base/sysinfo.h new file mode 100644 index 0000000..807a138 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/sysinfo.h @@ -0,0 +1,24 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_SYSINFO_H_ +#define OR_TOOLS_BASE_SYSINFO_H_ + +#include "ortools/base/basictypes.h" + +namespace operations_research { +// Returns the memory usage of the process. +int64 GetProcessMemoryUsage(); +} // namespace operations_research + +#endif // OR_TOOLS_BASE_SYSINFO_H_ diff --git a/thirdparty/linux/include/ortools/base/thorough_hash.h b/thirdparty/linux/include/ortools/base/thorough_hash.h new file mode 100644 index 0000000..5acd36b --- /dev/null +++ b/thirdparty/linux/include/ortools/base/thorough_hash.h @@ -0,0 +1,53 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_THOROUGH_HASH_H_ +#define OR_TOOLS_BASE_THOROUGH_HASH_H_ + +#include "ortools/base/integral_types.h" + +namespace operations_research { +inline uint64 MixTwoUInt64(uint64 fp1, uint64 fp2) { + // Two big prime numbers. + const uint64 kMul1 = 0xc6a4a7935bd1e995ULL; + const uint64 kMul2 = 0x228876a7198b743ULL; + uint64 a = fp1 * kMul1 + fp2 * kMul2; + // Note: The following line also makes sure we never return 0 or 1, because we + // will only add something to 'a' if there are any MSBs (the remaining bits + // after the shift) being 0, in which case wrapping around would not happen. + return a + (~a >> 47); +} + +// This should be better (collision-wise) than the default hash, without +// being much slower. It never returns 0 or 1. +inline uint64 ThoroughHash(const char* bytes, size_t len) { + // Some big prime numer. + uint64 fp = 0xa5b85c5e198ed849ULL; + const char* end = bytes + len; + while (bytes + 8 <= end) { + fp = MixTwoUInt64(fp, *(reinterpret_cast(bytes))); + bytes += 8; + } + // Note: we don't care about "consistency" (little or big endian) between + // the bulk and the suffix of the message. + uint64 last_bytes = 0; + while (bytes < end) { + last_bytes += *bytes; + last_bytes <<= 8; + bytes++; + } + return MixTwoUInt64(fp, last_bytes); +} +} // namespace operations_research + +#endif // OR_TOOLS_BASE_THOROUGH_HASH_H_ diff --git a/thirdparty/linux/include/ortools/base/threadpool.h b/thirdparty/linux/include/ortools/base/threadpool.h new file mode 100644 index 0000000..c1767dc --- /dev/null +++ b/thirdparty/linux/include/ortools/base/threadpool.h @@ -0,0 +1,45 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_THREADPOOL_H_ +#define OR_TOOLS_BASE_THREADPOOL_H_ + +#include // NOLINT +#include +#include +#include // NOLINT +#include +#include // NOLINT +#include + +namespace operations_research { +class ThreadPool { + public: + ThreadPool(const std::string& prefix, int num_threads); + ~ThreadPool(); + + void StartWorkers(); + void Schedule(std::function closure); + std::function GetNextTask(); + + private: + const int num_workers_; + std::list> tasks_; + std::mutex mutex_; + std::condition_variable condition_; + bool waiting_to_finish_; + bool started_; + std::vector all_workers_; +}; +} // namespace operations_research +#endif // OR_TOOLS_BASE_THREADPOOL_H_ diff --git a/thirdparty/linux/include/ortools/base/time_support.h b/thirdparty/linux/include/ortools/base/time_support.h new file mode 100644 index 0000000..4c08927 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/time_support.h @@ -0,0 +1,45 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_TIME_SUPPORT_H_ +#define OR_TOOLS_BASE_TIME_SUPPORT_H_ + +#include "ortools/base/integral_types.h" + +namespace base { + +// Ideally, this should be a super-fast implementation that isn't too +// unreliable: +// - It shouldn't take more than a few nanoseconds per call, on average. +// - It shouldn't be out of sync with the "real" time by more than a few +// milliseconds. +// It might be non-increasing though. This will depend on the implementation. +// +// The current implementation (below) is probably slower, and maybe not as +// reliable as that. +// TODO(user): implement it properly. +// One possible way to achieve this is to use the hardware cycle counter, +// coupled with automatic, periodic recalibration with the (reliable, but slow) +// system timer to avoid drifts. See +// http://en.wikipedia.org/wiki/Time_Stamp_Counter#Use. +int64 GetCurrentTimeNanos(); + +inline int64 Now() { return GetCurrentTimeNanos(); } + +inline double WallTime_Now() { return base::GetCurrentTimeNanos() * 1e-9; } + +} // namespace base + +inline double ToWallTime(int64 nanos) { return 1e-9 * nanos; } + +#endif // OR_TOOLS_BASE_TIME_SUPPORT_H_ diff --git a/thirdparty/linux/include/ortools/base/timer.h b/thirdparty/linux/include/ortools/base/timer.h new file mode 100644 index 0000000..5a39536 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/timer.h @@ -0,0 +1,105 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_TIMER_H_ +#define OR_TOOLS_BASE_TIMER_H_ + +#include "ortools/base/basictypes.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/time_support.h" + +class WallTimer { + public: + WallTimer() { Reset(); } + void Reset() { + running_ = false; + sum_ = 0; + } + // When Start() is called multiple times, only the most recent is used. + void Start() { + running_ = true; + start_ = base::GetCurrentTimeNanos(); + } + void Restart() { + sum_ = 0; + Start(); + } + void Stop() { + if (running_) { + sum_ += base::GetCurrentTimeNanos() - start_; + running_ = false; + } + } + double Get() const { return GetNanos() * 1e-9; } + int64 GetInMs() const { return GetNanos() / 1000000; } + int64 GetInUsec() const { return GetNanos() / 1000; } + + protected: + int64 GetNanos() const { + return running_ ? base::GetCurrentTimeNanos() - start_ + sum_ : sum_; + } + + private: + bool running_; + int64 start_; + int64 sum_; +}; + +// This is meant to measure the actual CPU usage time. +// TODO(user): implement it properly. +typedef WallTimer UserTimer; + +// This is meant to be a ultra-fast interface to the hardware cycle counter, +// without periodic recalibration, to be even faster than +// base::GetCurrentTimeNanos(). +// But this current implementation just uses GetCurrentTimeNanos(). +// TODO(user): implement it. +class CycleTimer : public WallTimer { + public: + // This actually returns a number of nanoseconds instead of the number + // of CPU cycles. + int64 GetCycles() const { return GetNanos(); } +}; + +// Conversion routines between CycleTimer::GetCycles and actual times. +class CycleTimerBase { + public: + static int64 SecondsToCycles(double s) { return static_cast(s * 1e9); } + static double CyclesToSeconds(int64 c) { return c * 1e-9; } + static int64 CyclesToMs(int64 c) { return c / 1000000; } + static int64 CyclesToUsec(int64 c) { return c / 1000; } +}; +typedef CycleTimerBase CycleTimerInstance; + +// A WallTimer clone meant to support SetClock(), for unit testing. But for now +// we just use WallTimer directly. +typedef WallTimer ClockTimer; + +class ScopedWallTime { + public: + // We do not own the pointer. The pointer must be valid for the duration + // of the existence of the ScopedWallTime instance. Not thread safe for + // aggregate_time. + explicit ScopedWallTime(double* aggregate_time); + ~ScopedWallTime(); + + private: + double* aggregate_time_; + + // When the instance was created. + WallTimer timer_; + + DISALLOW_COPY_AND_ASSIGN(ScopedWallTime); +}; +#endif // OR_TOOLS_BASE_TIMER_H_ diff --git a/thirdparty/linux/include/ortools/base/typeid.h b/thirdparty/linux/include/ortools/base/typeid.h new file mode 100644 index 0000000..7594389 --- /dev/null +++ b/thirdparty/linux/include/ortools/base/typeid.h @@ -0,0 +1,24 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BASE_TYPEID_H_ +#define OR_TOOLS_BASE_TYPEID_H_ + +namespace operations_research { +template +inline size_t FastTypeId() { + static char d; + return reinterpret_cast(&d); +} +} // namespace operations_research +#endif // OR_TOOLS_BASE_TYPEID_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_base.h b/thirdparty/linux/include/ortools/bop/bop_base.h new file mode 100644 index 0000000..99884a9 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_base.h @@ -0,0 +1,280 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_BOP_BASE_H_ +#define OR_TOOLS_BOP_BOP_BASE_H_ + +#include + +#include "ortools/base/basictypes.h" +#include "ortools/bop/bop_parameters.pb.h" +#include "ortools/bop/bop_solution.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/clause.h" +#include "ortools/sat/sat_base.h" +#include "ortools/util/stats.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { +namespace bop { + +// Forward declaration. +struct LearnedInfo; +class ProblemState; + +// Base class used to optimize a ProblemState. +// Optimizers implementing this class are used in a sort of portfolio and +// are run sequentially or concurrently. See for instance BopRandomLNSOptimizer. +class BopOptimizerBase { + public: + explicit BopOptimizerBase(const std::string& name); + virtual ~BopOptimizerBase(); + + // Returns the name given at construction. + const std::string& name() const { return name_; } + + // Returns true if this optimizer should be run on the given problem state. + // Some optimizer requires a feasible solution to run for instance. + // + // Note that a similar effect can be achieved if Optimize() returns ABORT + // right away. However, doing the later will lower the chance of this + // optimizer to be called again since it will count as a failure to improve + // the current state. + virtual bool ShouldBeRun(const ProblemState& problem_state) const = 0; + + // Return status of the Optimize() function below. + // + // TODO(user): To redesign, some are not needed anymore thanks to the + // problem state, e.g. IsOptimal(). + enum Status { + OPTIMAL_SOLUTION_FOUND, + SOLUTION_FOUND, + INFEASIBLE, + LIMIT_REACHED, + + // Some information was learned and the problem state will need to be + // updated. This will trigger a new optimization round. + // + // TODO(user): replace by learned_info->IsEmpty()? but we will need to clear + // the BopSolution there first. + INFORMATION_FOUND, + + // This optimizer didn't learn any information yet but can be called again + // on the same problem state to resume its work. + CONTINUE, + + // There is no need to call this optimizer again on the same problem state. + ABORT + }; + + // Tries to infer more information about the problem state, i.e. reduces the + // gap by increasing the lower bound or finding a better solution. + // Returns SOLUTION_FOUND when a new solution with a better objective cost is + // found before a time limit. + // The learned information is cleared and the filled with any new information + // about the problem, e.g. a new lower bound. + // + // Preconditions: ShouldBeRun() must returns true. + virtual Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, + LearnedInfo* learned_info, TimeLimit* time_limit) = 0; + + // Returns a std::string describing the status. + static std::string GetStatusString(Status status); + + protected: + const std::string name_; + + mutable StatsGroup stats_; +}; + +inline std::ostream& operator<<(std::ostream& os, + BopOptimizerBase::Status status) { + os << BopOptimizerBase::GetStatusString(status); + return os; +} + +// This class represents the current state of the problem with all the +// information that the solver learned about it at a given time. +class ProblemState { + public: + explicit ProblemState(const LinearBooleanProblem& problem); + + // Sets parameters, used for instance to get the tolerance, the gap limit... + void SetParameters(const BopParameters& parameters) { + parameters_ = parameters; + } + + const BopParameters& GetParameters() const { return parameters_; } + + // Sets an assignment preference for each variable. + // This is only used for warm start. + void set_assignment_preference(const std::vector& a) { + assignment_preference_ = a; + } + const std::vector assignment_preference() const { + return assignment_preference_; + } + + // Merges the learned information with the current problem state. For + // instance, if variables x, and y are fixed in the current state, and z is + // learned to be fixed, the result of the merge will be x, y, and z being + // fixed in the problem state. + // Note that the LP values contained in the learned information (if any) + // will replace the LP values of the problem state, whatever the cost is. + // Returns true when the merge has changed the problem state. + bool MergeLearnedInfo(const LearnedInfo& learned_info, + BopOptimizerBase::Status optimization_status); + + // Returns all the information learned so far. + // TODO(user): In the current implementation the learned information only + // contains binary clauses added since the last call to + // SynchronizationDone(). + // Add an iterator on the sat::BinaryClauseManager. + LearnedInfo GetLearnedInfo() const; + + // The stamp represents an upper bound on the number of times the problem + // state has been updated. If the stamp changed since last time one has + // checked the state, it's worth trying again as it might have changed + // (no guarantee). + static const int64 kInitialStampValue; + int64 update_stamp() const { return update_stamp_; } + + // Marks the problem state as optimal. + void MarkAsOptimal(); + + // Marks the problem state as infeasible. + void MarkAsInfeasible(); + + // Returns true when the current state is proved to be optimal. In such a case + // solution() returns the optimal solution. + bool IsOptimal() const { + return solution_.IsFeasible() && solution_.GetCost() == lower_bound(); + } + + // Returns true when the problem is proved to be infeasible. + bool IsInfeasible() const { return lower_bound() > upper_bound(); } + + // Returns true when the variable var is fixed in the current problem state. + // The value of the fixed variable is returned by GetVariableFixedValue(var). + bool IsVariableFixed(VariableIndex var) const { return is_fixed_[var]; } + const ITIVector& is_fixed() const { return is_fixed_; } + + // Returns the value of the fixed variable var. Should be only called on fixed + // variables (CHECKed). + bool GetVariableFixedValue(VariableIndex var) const { + return fixed_values_[var]; + } + const ITIVector& fixed_values() const { + return fixed_values_; + } + + // Returns the values of the LP relaxation of the problem. Returns an empty + // vector when the LP has not been populated. + const glop::DenseRow& lp_values() const { return lp_values_; } + + // Returns the solution to the current state problem. + // Note that the solution might not be feasible because until we find one, it + // will just be the all-false assignment. + const BopSolution& solution() const { return solution_; } + + // Returns the original problem. Note that the current problem might be + // different, e.g. fixed variables, but equivalent, i.e. a solution to one + // should be a solution to the other too. + const LinearBooleanProblem& original_problem() const { + return original_problem_; + } + + // Returns the current lower (resp. upper) bound of the objective cost. + // For internal use only: this is the unscaled version of the lower (resp. + // upper) bound, and so should be compared only to the unscaled cost given by + // solution.GetCost(). + int64 lower_bound() const { return lower_bound_; } + int64 upper_bound() const { return upper_bound_; } + + // Returns the scaled lower bound of the original problem. + double GetScaledLowerBound() const { + return (lower_bound() + original_problem_.objective().offset()) * + original_problem_.objective().scaling_factor(); + } + + // Returns the newly added binary clause since the last SynchronizationDone(). + const std::vector& NewlyAddedBinaryClauses() const; + + // Resets what is considered "new" information. This is meant to be called + // once all the optimize have been synchronized. + void SynchronizationDone(); + + private: + const LinearBooleanProblem& original_problem_; + BopParameters parameters_; + int64 update_stamp_; + ITIVector is_fixed_; + ITIVector fixed_values_; + glop::DenseRow lp_values_; + BopSolution solution_; + std::vector assignment_preference_; + + int64 lower_bound_; + int64 upper_bound_; + + // Manage the set of the problem binary clauses (including the learned ones). + sat::BinaryClauseManager binary_clause_manager_; + + DISALLOW_COPY_AND_ASSIGN(ProblemState); +}; + +// This struct represents what has been learned on the problem state by +// running an optimizer. The goal is then to merge the learned information +// with the problem state in order to get a more constrained problem to be used +// by the next called optimizer. +struct LearnedInfo { + explicit LearnedInfo(const LinearBooleanProblem& problem) + : fixed_literals(), + solution(problem, "AllZero"), + lower_bound(kint64min), + lp_values(), + binary_clauses() {} + + // Clears all just as if the object were a brand new one. This can be used + // to reduce the number of creation / deletion of objects. + void Clear() { + fixed_literals.clear(); + lower_bound = kint64min; + lp_values.clear(); + binary_clauses.clear(); + } + + // Vector of all literals that have been fixed. + std::vector fixed_literals; + + // New solution. Note that the solution might be infeasible. + BopSolution solution; + + // A lower bound (for multi-threading purpose). + int64 lower_bound; + + // An assignment for the relaxed linear programming problem (can be empty). + // This is meant to be the optimal LP solution, but can just be a feasible + // solution or any floating point assignment if the LP solver didn't solve + // the relaxed problem optimally. + glop::DenseRow lp_values; + + // New binary clauses. + std::vector binary_clauses; +}; + +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_BASE_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_fs.h b/thirdparty/linux/include/ortools/bop/bop_fs.h new file mode 100644 index 0000000..bfbb37e --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_fs.h @@ -0,0 +1,156 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_BOP_FS_H_ +#define OR_TOOLS_BOP_BOP_FS_H_ + +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/int_type.h" +#include "ortools/base/int_type_indexed_vector.h" +#include "ortools/bop/bop_base.h" +#include "ortools/bop/bop_parameters.pb.h" +#include "ortools/bop/bop_solution.h" +#include "ortools/bop/bop_types.h" +#include "ortools/bop/bop_util.h" +#include "ortools/glop/lp_solver.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { +namespace bop { + +// Tries to find a first solution using SAT and a given assignment preference. +// This optimizer will never run again once it has found a solution except if +// the policy is kNotGuided in which case it will be ran again. +class GuidedSatFirstSolutionGenerator : public BopOptimizerBase { + public: + // The different guiding heuristics + enum class Policy { + kNotGuided, // The default SAT solver. + kLpGuided, // Guided by the values of the linear relaxation. + kObjectiveGuided, // Guided by the objective coefficient. + kUserGuided, // Guided by the problem assignment_preference(). + }; + GuidedSatFirstSolutionGenerator(const std::string& name, Policy policy); + ~GuidedSatFirstSolutionGenerator() override; + + bool ShouldBeRun(const ProblemState& problem_state) const override; + + // Note that if the last call to Optimize() returned CONTINUE and if the + // problem didn't change, calling this will resume the solve from its last + // position. + Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, LearnedInfo* learned_info, + TimeLimit* time_limit) override; + + private: + BopOptimizerBase::Status SynchronizeIfNeeded( + const ProblemState& problem_state); + + const Policy policy_; + bool abort_; + int64 state_update_stamp_; + std::unique_ptr sat_solver_; +}; + + +// This class implements an optimizer that tries various random search +// strategies, each with a really low conflict limit. It can be used to generate +// a first solution or to improve an existing one. +// +// By opposition to all the other optimizers, this one doesn't return right away +// when a new solution is found. Instead, it continues to improve it as long as +// it has time. +// +// TODO(user): Coupled with some Local Search it might be used to diversify +// the solutions. To try. +class BopRandomFirstSolutionGenerator : public BopOptimizerBase { + public: + BopRandomFirstSolutionGenerator(const std::string& name, + const BopParameters& parameters, + sat::SatSolver* sat_propagator, + MTRandom* random); + ~BopRandomFirstSolutionGenerator() override; + + bool ShouldBeRun(const ProblemState& problem_state) const override; + Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, LearnedInfo* learned_info, + TimeLimit* time_limit) override; + + private: + BopOptimizerBase::Status SynchronizeIfNeeded( + const ProblemState& problem_state); + + int random_seed_; + MTRandom* random_; + sat::SatSolver* sat_propagator_; + uint32 sat_seed_; +}; + +// This class computes the linear relaxation of the state problem. +// Optimize() fills the relaxed values (possibly floating values) that can be +// used by other optimizers as BopSatLpFirstSolutionGenerator for instance, +// and the lower bound. +class LinearRelaxation : public BopOptimizerBase { + public: + LinearRelaxation(const BopParameters& parameters, const std::string& name); + ~LinearRelaxation() override; + + bool ShouldBeRun(const ProblemState& problem_state) const override; + Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, LearnedInfo* learned_info, + TimeLimit* time_limit) override; + + private: + BopOptimizerBase::Status SynchronizeIfNeeded( + const ProblemState& problem_state); + + // Runs Glop to solve the current lp_model_. + // Updates the time limit and returns the status of the solve. + // Note that when the solve is incremental, the preprocessor is deactivated, + // and the dual simplex is used. + glop::ProblemStatus Solve(bool incremental_solve, TimeLimit* time_limit); + + // Computes and returns a better best bound using strong branching, i.e. + // doing a what-if analysis on each variable v: compute the best bound when + // v is assigned to true, compute the best bound when v is assigned to false, + // and then use those best bounds to improve the overall best bound. + // As a side effect, it might fix some variables. + double ComputeLowerBoundUsingStrongBranching(LearnedInfo* learned_info, + TimeLimit* time_limit); + + // Returns true when the cost is worse than the cost of the current solution. + // If they are within the given tolerance, returns false. + bool CostIsWorseThanSolution(double scaled_cost, double tolerance) const; + + const BopParameters parameters_; + int64 state_update_stamp_; + bool lp_model_loaded_; + glop::LinearProgram lp_model_; + glop::LPSolver lp_solver_; + double scaling_; + double offset_; + int num_fixed_variables_; + bool problem_already_solved_; + double scaled_solution_cost_; +}; + +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_FS_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_lns.h b/thirdparty/linux/include/ortools/bop/bop_lns.h new file mode 100644 index 0000000..654d8a0 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_lns.h @@ -0,0 +1,182 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_BOP_LNS_H_ +#define OR_TOOLS_BOP_BOP_LNS_H_ + +#include +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/int_type.h" +#include "ortools/base/int_type_indexed_vector.h" +#include "ortools/bop/bop_base.h" +#include "ortools/bop/bop_parameters.pb.h" +#include "ortools/bop/bop_solution.h" +#include "ortools/bop/bop_types.h" +#include "ortools/bop/bop_util.h" +#include "ortools/glop/lp_solver.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/util/stats.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { +namespace bop { + +// Uses SAT to solve the full problem under the constraint that the new solution +// should be under a given Hamming distance of the current solution. +class BopCompleteLNSOptimizer : public BopOptimizerBase { + public: + BopCompleteLNSOptimizer(const std::string& name, + const BopConstraintTerms& objective_terms); + ~BopCompleteLNSOptimizer() final; + + private: + bool ShouldBeRun(const ProblemState& problem_state) const final; + Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, LearnedInfo* learned_info, + TimeLimit* time_limit) final; + + BopOptimizerBase::Status SynchronizeIfNeeded( + const ProblemState& problem_state, int num_relaxed_vars); + + int64 state_update_stamp_; + std::unique_ptr sat_solver_; + const BopConstraintTerms& objective_terms_; +}; + +// Interface of the different LNS neighborhood generation algorithm. +// +// NOTE(user): Using a sat_propagator as the output of the algorithm allows for +// a really simple and efficient interface for the generator that relies on it. +// However, if a generator don't rely on it at all, it may slow down a bit the +// code (to investigate). If this happens, we will probably need another +// function here and a way to select between which one to call. +class NeighborhoodGenerator { + public: + NeighborhoodGenerator() {} + virtual ~NeighborhoodGenerator() {} + + // Interface for the neighborhood generation. + // + // The difficulty will be in [0, 1] and is related to the asked neighborhood + // size (and thus local problem difficulty). A difficulty of 0.0 means empty + // neighborhood and a difficulty of 1.0 means the full problem. The algorithm + // should try to generate an neighborhood according to this difficulty, which + // will be dynamically adjusted depending on whether or not we can solve the + // subproblem. + // + // The given sat_propagator will be reset and then configured so that all the + // variables propagated on its trail should be fixed. That is, the + // neighborhood will correspond to the unassigned variables in the + // sat_propagator. Note that sat_propagator_.IsModelUnsat() will be checked + // after this is called so it is okay to abort if this happens. + // + // Preconditions: + // - The given sat_propagator_ should have the current problem loaded (with + // the constraint to find a better solution that any current solution). + // - The problem state must contains a feasible solution. + virtual void GenerateNeighborhood(const ProblemState& problem_state, + double difficulty, + sat::SatSolver* sat_propagator) = 0; +}; + +// A generic LNS optimizer which generates neighborhoods according to the given +// NeighborhoodGenerator and automatically adapt the neighborhood size depending +// on how easy it is to solve the associated problem. +class BopAdaptiveLNSOptimizer : public BopOptimizerBase { + public: + // Takes ownership of the given neighborhood_generator. + // The sat_propagator is assumed to contains the current problem. + BopAdaptiveLNSOptimizer(const std::string& name, bool use_lp_to_guide_sat, + NeighborhoodGenerator* neighborhood_generator, + sat::SatSolver* sat_propagator); + ~BopAdaptiveLNSOptimizer() final; + + private: + bool ShouldBeRun(const ProblemState& problem_state) const final; + Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, LearnedInfo* learned_info, + TimeLimit* time_limit) final; + + const bool use_lp_to_guide_sat_; + std::unique_ptr neighborhood_generator_; + sat::SatSolver* const sat_propagator_; + + // Adaptive neighborhood size logic. + // The values are kept from one run to the next. + LubyAdaptiveParameterValue adaptive_difficulty_; +}; + +// Generates a neighborhood by randomly fixing a subset of the objective +// variables that are currently at their lower cost. +class ObjectiveBasedNeighborhood : public NeighborhoodGenerator { + public: + ObjectiveBasedNeighborhood(const BopConstraintTerms* objective_terms, + MTRandom* random) + : objective_terms_(*objective_terms), random_(random) {} + ~ObjectiveBasedNeighborhood() final {} + + private: + void GenerateNeighborhood(const ProblemState& problem_state, + double difficulty, + sat::SatSolver* sat_propagator) final; + const BopConstraintTerms& objective_terms_; + MTRandom* random_; +}; + +// Generates a neighborhood by randomly selecting a subset of constraints and +// fixing the objective variables that are currently at their lower cost and +// not in the given subset of constraints. +class ConstraintBasedNeighborhood : public NeighborhoodGenerator { + public: + ConstraintBasedNeighborhood(const BopConstraintTerms* objective_terms, + MTRandom* random) + : objective_terms_(*objective_terms), random_(random) {} + ~ConstraintBasedNeighborhood() final {} + + private: + void GenerateNeighborhood(const ProblemState& problem_state, + double difficulty, + sat::SatSolver* sat_propagator) final; + const BopConstraintTerms& objective_terms_; + MTRandom* random_; +}; + +// Generates a neighborhood by taking a random local neighborhood in an +// undirected graph where the nodes are the variables and two nodes are linked +// if they appear in the same constraint. +class RelationGraphBasedNeighborhood : public NeighborhoodGenerator { + public: + RelationGraphBasedNeighborhood(const LinearBooleanProblem& problem, + MTRandom* random); + ~RelationGraphBasedNeighborhood() final {} + + private: + void GenerateNeighborhood(const ProblemState& problem_state, + double difficulty, + sat::SatSolver* sat_propagator) final; + + // TODO(user): reuse by_variable_matrix_ from the LS? Note however than we + // don't need the coefficients here. + ITIVector> columns_; + MTRandom* random_; +}; + +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_LNS_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_ls.h b/thirdparty/linux/include/ortools/bop/bop_ls.h new file mode 100644 index 0000000..7c5f443 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_ls.h @@ -0,0 +1,635 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file defines the needed classes to efficiently perform Local Search in +// Bop. +// Local Search is a technique used to locally improve an existing solution by +// flipping a limited number of variables. To be successful the produced +// solution has to satisfy all constraints of the problem and improve the +// objective cost. +// +// The class BopLocalSearchOptimizer is the only public interface for Local +// Search in Bop. For unit-testing purposes this file also contains the four +// internal classes AssignmentAndConstraintFeasibilityMaintainer, +// OneFlipConstraintRepairer, SatWrapper and LocalSearchAssignmentIterator. +// They are implementation details and should not be used outside of bop_ls. + +#ifndef OR_TOOLS_BOP_BOP_LS_H_ +#define OR_TOOLS_BOP_BOP_LS_H_ + +#include +#include + +#include "ortools/base/hash.h" +#include "ortools/bop/bop_base.h" +#include "ortools/bop/bop_solution.h" +#include "ortools/bop/bop_types.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/base/random.h" + +namespace operations_research { +namespace bop { + +// This class is used to ease the connection with the SAT solver. +// +// TODO(user): remove? the meat of the logic is used in just one place, so I am +// not sure having this extra layer improve the readability. +class SatWrapper { + public: + explicit SatWrapper(sat::SatSolver* sat_solver); + + // Returns the current state of the solver propagation trail. + std::vector FullSatTrail() const; + + // Returns true if the problem is UNSAT. + // Note that an UNSAT problem might not be marked as UNSAT at first because + // the SAT solver is not able to prove it; After some decisions / learned + // conflicts, the SAT solver might be able to prove UNSAT and so this will + // return true. + bool IsModelUnsat() const { return sat_solver_->IsModelUnsat(); } + + // Return the current solver VariablesAssignment. + const sat::VariablesAssignment& SatAssignment() const { + return sat_solver_->Assignment(); + } + + // Applies the decision that makes the given literal true and returns the + // number of decisions to backtrack due to conflicts if any. + // Two cases: + // - No conflicts: Returns 0 and fills the propagated_literals with the + // literals that have been propagated due to the decision including the + // the decision itself. + // - Conflicts: Returns the number of decisions to backtrack (the current + // decision included, i.e. returned value > 0) and fills the + // propagated_literals with the literals that the conflicts propagated. + // Note that the decision variable should not be already assigned in SAT. + int ApplyDecision(sat::Literal decision_literal, + std::vector* propagated_literals); + + // Backtracks the last decision if any. + void BacktrackOneLevel(); + + // Bactracks all the decisions. + void BacktrackAll(); + + // Extracts any new information learned during the search. + void ExtractLearnedInfo(LearnedInfo* info); + + // Returns a deterministic number that should be correlated with the time + // spent in the SAT wrapper. The order of magnitude should be close to the + // time in seconds. + double deterministic_time() const; + + private: + sat::SatSolver* sat_solver_; + DISALLOW_COPY_AND_ASSIGN(SatWrapper); +}; + +// Forward declaration. +class LocalSearchAssignmentIterator; + +// This class defines a Local Search optimizer. The goal is to find a new +// solution with a better cost than the given solution by iterating on all +// assignments that can be reached in max_num_decisions decisions or less. +// The bop parameter max_number_of_explored_assignments_per_try_in_ls can be +// used to specify the number of new assignments to iterate on each time the +// method Optimize() is called. Limiting that parameter allows to reduce the +// time spent in the Optimize() method at once, and still explore all the +// reachable assignments (if Optimize() is called enough times). +// Note that due to propagation, the number of variables with a different value +// in the new solution can be greater than max_num_decisions. +class LocalSearchOptimizer : public BopOptimizerBase { + public: + LocalSearchOptimizer(const std::string& name, int max_num_decisions, + sat::SatSolver* sat_propagator); + ~LocalSearchOptimizer() override; + + private: + bool ShouldBeRun(const ProblemState& problem_state) const override; + Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, LearnedInfo* learned_info, + TimeLimit* time_limit) override; + + int64 state_update_stamp_; + + // Maximum number of decisions the Local Search can take. + // Note that there is no limit on the number of changed variables due to + // propagation. + const int max_num_decisions_; + + // A wrapper around the given sat_propagator. + SatWrapper sat_wrapper_; + + // Iterator on all reachable assignments. + // Note that this iterator is only reset when Synchronize() is called, i.e. + // the iterator continues its iteration of the next assignments each time + // Optimize() is called until everything is explored or a solution is found. + std::unique_ptr assignment_iterator_; +}; + +//------------------------------------------------------------------------------ +// Implementation details. The declarations of those utility classes are in +// the .h for testing reasons. +//------------------------------------------------------------------------------ + +// Maintains some information on a sparse set of integers in [0, n). More +// specifically this class: +// - Allows to dynamically add/remove element from the set. +// - Has a backtracking support. +// - Maintains the number of elements in the set. +// - Maintains a superset of the elements of the set that contains all the +// modified elements. +template +class BacktrackableIntegerSet { + public: + BacktrackableIntegerSet() {} + + // Prepares the class for integers in [0, n) and initializes the set to the + // empty one. Note that this run in O(n). Once resized, it is better to call + // BacktrackAll() instead of this to clear the set. + void ClearAndResize(IntType n); + + // Changes the state of the given integer i to be either inside or outside the + // set. Important: this should only be called with the opposite state of the + // current one, otherwise size() will not be correct. + void ChangeState(IntType i, bool should_be_inside); + + // Returns the current number of elements in the set. + // Note that this is not its maximum size n. + int size() const { return size_; } + + // Returns a superset of the current set of integers. + const std::vector& Superset() const { return stack_; } + + // BacktrackOneLevel() backtracks to the state the class was in when the + // last AddBacktrackingLevel() was called. BacktrackAll() just restore the + // class to its state just after the last ClearAndResize(). + void AddBacktrackingLevel(); + void BacktrackOneLevel(); + void BacktrackAll(); + + private: + int size_; + + // Contains the elements whose status has been changed at least once. + std::vector stack_; + std::vector in_stack_; + + // Used for backtracking. Contains the size_ and the stack_.size() at the time + // of each call to AddBacktrackingLevel() that is not yet backtracked over. + std::vector saved_sizes_; + std::vector saved_stack_sizes_; +}; + +// A simple and efficient class to hash a given set of integers in [0, n). +// It uses O(n) memory and produces a good hash (random linear function). +template +class NonOrderedSetHasher { + public: + NonOrderedSetHasher() : random_("Random seed") {} + + // Initializes the NonOrderedSetHasher to hash sets of integer in [0, n). + void Initialize(int size) { + hashes_.resize(size); + for (IntType i(0); i < size; ++i) hashes_[i] = random_.Rand64(); + } + + // Ignores the given set element in all subsequent hash computation. Note that + // this will be reset by the next call to Initialize(). + void IgnoreElement(IntType e) { hashes_[e] = 0; } + + // Returns the hash of the given set. The hash is independent of the set + // order, but there must be no duplicate element in the set. This uses a + // simple random linear function which has really good hashing properties. + uint64 Hash(const std::vector& set) const { + uint64 hash = 0; + for (const IntType i : set) hash ^= hashes_[i]; + return hash; + } + + // The hash of a set is simply the XOR of all its elements. This allows + // to compute an hash incrementally or without the need of a std::vector<>. + uint64 Hash(IntType e) const { return hashes_[e]; } + + // Returns true if Initialize() has been called with a non-zero size. + bool IsInitialized() const { return !hashes_.empty(); } + + private: + MTRandom random_; + ITIVector hashes_; +}; + +// This class is used to incrementally maintain an assignment and the +// feasibility of the constraints of a given LinearBooleanProblem. +// +// The current assignment is initialized using a feasible reference solution, +// i.e. the reference solution satisfies all the constraints of the problem. +// The current assignment is updated using the Assign() method. +// +// Note that the current assignment is not a solution in the sense that it +// might not be feasible, ie. violates some constraints. +// +// The assignment can be accessed at any time using Assignment(). +// The set of infeasible constraints can be accessed at any time using +// PossiblyInfeasibleConstraints(). +// +// Note that this class is reversible, i.e. it is possible to backtrack to +// previously added backtracking levels. +// levels. Consider for instance variable a, b, c, and d. +// Method called Assigned after method call +// 1- Assign({a, b}) a b +// 2- AddBacktrackingLevel() a b | +// 3- Assign({c}) a b | c +// 4- Assign({d}) a b | c d +// 5- BacktrackOneLevel() a b +// 6- Assign({c}) a b c +// 7- BacktrackOneLevel() +class AssignmentAndConstraintFeasibilityMaintainer { + public: + // Note that the constraint indices used in this class are not the same as + // the one used in the given LinearBooleanProblem here. + explicit AssignmentAndConstraintFeasibilityMaintainer( + const LinearBooleanProblem& problem); + + // When we construct the problem, we treat the objective as one constraint. + // This is the index of this special "objective" constraint. + static const ConstraintIndex kObjectiveConstraint; + + // Sets a new reference solution and reverts all internal structures to their + // initial state. Note that the reference solution has to be feasible. + void SetReferenceSolution(const BopSolution& reference_solution); + + // Behaves exactly like SetReferenceSolution() where the passed reference + // is the current assignment held by this class. Note that the current + // assignment must be feasible (i.e. IsFeasible() is true). + void UseCurrentStateAsReference(); + + // Assigns all literals. That updates the assignment, the constraint values, + // and the infeasible constraints. + // Note that the assignment of those literals can be reverted thanks to + // AddBacktrackingLevel() and BacktrackOneLevel(). + // Note that a variable can't be assigned twice, even for the same literal. + void Assign(const std::vector& literals); + + // Adds a new backtracking level to specify the state that will be restored + // by BacktrackOneLevel(). + // See the example in the class comment. + void AddBacktrackingLevel(); + + // Backtracks internal structures to the previous level defined by + // AddBacktrackingLevel(). As a consequence the state will be exactly as + // before the previous call to AddBacktrackingLevel(). + // Note that backtracking the initial state has no effect. + void BacktrackOneLevel(); + void BacktrackAll(); + + // This returns the list of literal that appear in exactly all the current + // infeasible constraints (ignoring the objective) and correspond to a flip in + // a good direction for all the infeasible constraint. Performing this flip + // may repair the problem without any propagations. + // + // Important: The returned reference is only valid until the next + // PotentialOneFlipRepairs() call. + const std::vector& PotentialOneFlipRepairs(); + + // Returns true if there is no infeasible constraint in the current state. + bool IsFeasible() const { return infeasible_constraint_set_.size() == 0; } + + // Returns the *exact* number of infeasible constraints. + // Note that PossiblyInfeasibleConstraints() will potentially return a larger + // number of constraints. + int NumInfeasibleConstraints() const { + return infeasible_constraint_set_.size(); + } + + // Returns a superset of all the infeasible constraints in the current state. + const std::vector& PossiblyInfeasibleConstraints() const { + return infeasible_constraint_set_.Superset(); + } + + // Returns the number of constraints of the problem, objective included, + // i.e. the number of constraint in the problem + 1. + size_t NumConstraints() const { return constraint_lower_bounds_.size(); } + + // Returns the value of the var in the assignment. + // As the assignment is initialized with the reference solution, if the + // variable has not been assigned through Assign(), the returned value is + // the value of the variable in the reference solution. + bool Assignment(VariableIndex var) const { return assignment_.Value(var); } + + // Returns the current assignment. + const BopSolution& reference() const { return reference_; } + + // Returns the lower bound of the constraint. + int64 ConstraintLowerBound(ConstraintIndex constraint) const { + return constraint_lower_bounds_[constraint]; + } + + // Returns the upper bound of the constraint. + int64 ConstraintUpperBound(ConstraintIndex constraint) const { + return constraint_upper_bounds_[constraint]; + } + + // Returns the value of the constraint. The value is computed using the + // variable values in the assignment. Note that a constraint is feasible iff + // its value is between its two bounds (inclusive). + int64 ConstraintValue(ConstraintIndex constraint) const { + return constraint_values_[constraint]; + } + + // Returns true if the given constraint is currently feasible. + bool ConstraintIsFeasible(ConstraintIndex constraint) const { + const int64 value = ConstraintValue(constraint); + return value >= ConstraintLowerBound(constraint) && + value <= ConstraintUpperBound(constraint); + } + + std::string DebugString() const; + + private: + // This is lazily called by PotentialOneFlipRepairs() once. + void InitializeConstraintSetHasher(); + + // This is used by PotentialOneFlipRepairs(). It encodes a ConstraintIndex + // together with a "repair" direction depending on the bound that make a + // constraint infeasible. An "up" direction means that the constraint activity + // is lower than the lower bound and we need to make the activity move up to + // fix the infeasibility. + DEFINE_INT_TYPE(ConstraintIndexWithDirection, int32); + ConstraintIndexWithDirection FromConstraintIndex(ConstraintIndex index, + bool up) const { + return ConstraintIndexWithDirection(2 * index.value() + (up ? 1 : 0)); + } + + // Over constrains the objective cost by the given delta. This should only be + // called on a feasible reference solution and a fully backtracked state. + void MakeObjectiveConstraintInfeasible(int delta); + + // Local structure to represent the sparse matrix by variable used for fast + // update of the contraint values. + struct ConstraintEntry { + ConstraintEntry(ConstraintIndex c, int64 w) : constraint(c), weight(w) {} + ConstraintIndex constraint; + int64 weight; + }; + + ITIVector> + by_variable_matrix_; + ITIVector constraint_lower_bounds_; + ITIVector constraint_upper_bounds_; + + BopSolution assignment_; + BopSolution reference_; + + ITIVector constraint_values_; + BacktrackableIntegerSet infeasible_constraint_set_; + + // This contains the list of variable flipped in assignment_. + // flipped_var_trail_backtrack_levels_[i-1] is the index in flipped_var_trail_ + // of the first variable flipped after the i-th AddBacktrackingLevel() call. + std::vector flipped_var_trail_backtrack_levels_; + std::vector flipped_var_trail_; + + // Members used by PotentialOneFlipRepairs(). + std::vector tmp_potential_repairs_; + NonOrderedSetHasher constraint_set_hasher_; + std::unordered_map> hash_to_potential_repairs_; + + DISALLOW_COPY_AND_ASSIGN(AssignmentAndConstraintFeasibilityMaintainer); +}; + +// This class is an utility class used to select which infeasible constraint to +// repair and identify one variable to flip to actually repair the constraint. +// A constraint 'lb <= sum_i(w_i * x_i) <= ub', with 'lb' the lower bound, +// 'ub' the upper bound, 'w_i' the weight of the i-th term and 'x_i' the +// boolean variable appearing in the i-th term, is infeasible for a given +// assignment iff its value 'sum_i(w_i * x_i)' is outside of the bounds. +// Repairing-a-constraint-in-one-flip means making the constraint feasible by +// just flipping the value of one unassigned variable of the current assignment +// from the AssignmentAndConstraintFeasibilityMaintainer. +// For performance reasons, the pairs weight / variable (w_i, x_i) are stored +// in a sparse manner as a vector of terms (w_i, x_i). In the following the +// TermIndex term_index refers to the position of the term in the vector. +class OneFlipConstraintRepairer { + public: + // Note that the constraint indices used in this class follow the same + // convention as the one used in the + // AssignmentAndConstraintFeasibilityMaintainer. + // + // TODO(user): maybe merge the two classes? maintaining this implicit indices + // convention between the two classes sounds like a bad idea. + OneFlipConstraintRepairer( + const LinearBooleanProblem& problem, + const AssignmentAndConstraintFeasibilityMaintainer& maintainer, + const sat::VariablesAssignment& sat_assignment); + + static const ConstraintIndex kInvalidConstraint; + static const TermIndex kInitTerm; + static const TermIndex kInvalidTerm; + + // Returns the index of a constraint to repair. This will always return the + // index of a constraint that can be repaired in one flip if there is one. + // Note however that if there is only one possible candidate, it will be + // returned without checking that it can indeed be repaired in one flip. + // This is because the later check can be expensive, and is not needed in our + // context. + ConstraintIndex ConstraintToRepair() const; + + // Returns the index of the next term which repairs the constraint when the + // value of its variable is flipped. This method explores terms with an + // index strictly greater than start_term_index and then terms with an index + // smaller than or equal to init_term_index if any. + // Returns kInvalidTerm when no reparing terms are found. + // + // Note that if init_term_index == start_term_index, then all the terms will + // be explored. Both TermIndex arguments can take values in [-1, constraint + // size). + TermIndex NextRepairingTerm(ConstraintIndex constraint, + TermIndex init_term_index, + TermIndex start_term_index) const; + + // Returns true if the constraint is infeasible and if flipping the variable + // at the given index will repair it. + bool RepairIsValid(ConstraintIndex constraint, TermIndex term_index) const; + + // Returns the literal formed by the variable at the given constraint term and + // assigned to the opposite value of this variable in the current assignment. + sat::Literal GetFlip(ConstraintIndex constraint, TermIndex term_index) const; + + // Local structure to represent the sparse matrix by constraint used for fast + // lookups. + struct ConstraintTerm { + ConstraintTerm(VariableIndex v, int64 w) : var(v), weight(w) {} + VariableIndex var; + int64 weight; + }; + + private: + // Sorts the terms of each constraints in the by_constraint_matrix_ to iterate + // on most promising variables first. + void SortTermsOfEachConstraints(int num_variables); + + ITIVector > + by_constraint_matrix_; + const AssignmentAndConstraintFeasibilityMaintainer& maintainer_; + const sat::VariablesAssignment& sat_assignment_; + + DISALLOW_COPY_AND_ASSIGN(OneFlipConstraintRepairer); +}; + +// This class is used to iterate on all assignments that can be obtained by +// deliberately flipping 'n' variables from the reference solution, 'n' being +// smaller than or equal to max_num_decisions. +// Note that one deliberate variable flip may lead to many other flips due to +// constraint propagation, those additional flips are not counted in 'n'. +class LocalSearchAssignmentIterator { + public: + LocalSearchAssignmentIterator(const ProblemState& problem_state, + int max_num_decisions, + int max_num_broken_constraints, + SatWrapper* sat_wrapper); + ~LocalSearchAssignmentIterator(); + + // Parameters of the LS algorithm. + void UseTranspositionTable(bool v) { use_transposition_table_ = v; } + void UsePotentialOneFlipRepairs(bool v) { + use_potential_one_flip_repairs_ = v; + } + + // Synchronizes the iterator with the problem state, e.g. set fixed variables, + // set the reference solution. Call this only when a new solution has been + // found. This will restart the LS. + void Synchronize(const ProblemState& problem_state); + + // Synchronize the SatWrapper with our current search state. This needs to be + // called before calls to NextAssignment() if the underlying SatWrapper was + // used by someone else than this class. + void SynchronizeSatWrapper(); + + // Move to the next assignment. Returns false when the search is finished. + bool NextAssignment(); + + // Returns the last feasible assignment. + const BopSolution& LastReferenceAssignment() const { + return maintainer_.reference(); + } + + // Returns true if the current assignment has a better solution than the one + // passed to the last Synchronize() call. + bool BetterSolutionHasBeenFound() const { + return better_solution_has_been_found_; + } + + // Returns a deterministic number that should be correlated with the time + // spent in the iterator. The order of magnitude should be close to the time + // in seconds. + double deterministic_time() const; + + std::string DebugString() const; + + private: + // This is called when a better solution has been found to restore the search + // to the new "root" node. + void UseCurrentStateAsReference(); + + // See transposition_table_ below. + static const size_t kStoredMaxDecisions = 4; + + // Internal structure used to represent a node of the search tree during local + // search. + struct SearchNode { + SearchNode() + : constraint(OneFlipConstraintRepairer::kInvalidConstraint), + term_index(OneFlipConstraintRepairer::kInvalidTerm) {} + SearchNode(ConstraintIndex c, TermIndex t) : constraint(c), term_index(t) {} + ConstraintIndex constraint; + TermIndex term_index; + }; + + // Applies the decision. Automatically backtracks when SAT detects conflicts. + void ApplyDecision(sat::Literal literal); + + // Adds one more decision to repair infeasible constraints. + // Returns true in case of success. + bool GoDeeper(); + + // Backtracks and moves to the next decision in the search tree. + void Backtrack(); + + // Looks if the current decisions (in search_nodes_) plus the new one (given + // by l) lead to a position already present in transposition_table_. + bool NewStateIsInTranspositionTable(sat::Literal l); + + // Inserts the current set of decisions in transposition_table_. + void InsertInTranspositionTable(); + + // Initializes the given array with the current decisions in search_nodes_ and + // by filling the other positions with 0. + void InitializeTranspositionTableKey( + std::array* a); + + // Looks for the next repairing term in the given constraints while skipping + // the position already present in transposition_table_. A given TermIndex of + // -1 means that this is the first time we explore this constraint. + bool EnqueueNextRepairingTermIfAny(ConstraintIndex ct_to_repair, + TermIndex index); + + const int max_num_decisions_; + const int max_num_broken_constraints_; + bool better_solution_has_been_found_; + AssignmentAndConstraintFeasibilityMaintainer maintainer_; + SatWrapper* const sat_wrapper_; + OneFlipConstraintRepairer repairer_; + std::vector search_nodes_; + ITIVector initial_term_index_; + + // Temporary vector used by ApplyDecision(). + std::vector tmp_propagated_literals_; + + // For each set of explored decisions, we store it in this table so that we + // don't explore decisions (a, b) and later (b, a) for instance. The decisions + // are converted to int32, sorted and padded with 0 before beeing inserted + // here. + // + // TODO(user): We may still miss some equivalent states because it is possible + // that completely differents decisions lead to exactly the same state. + // However this is more time consuming to detect because we must apply the + // last decision first before trying to compare the states. + // + // TODO(user): Currently, we only store kStoredMaxDecisions or less decisions. + // Ideally, this should be related to the maximum number of decision in the + // LS, but that requires templating the whole LS optimizer. + bool use_transposition_table_; + std::unordered_set> transposition_table_; + + bool use_potential_one_flip_repairs_; + + // The number of explored nodes. + int64 num_nodes_; + + // The number of skipped nodes thanks to the transposition table. + int64 num_skipped_nodes_; + + // The overall number of better solution found. And the ones found by the + // use_potential_one_flip_repairs_ heuristic. + int64 num_improvements_; + int64 num_improvements_by_one_flip_repairs_; + int64 num_inspected_one_flip_repairs_; + + DISALLOW_COPY_AND_ASSIGN(LocalSearchAssignmentIterator); +}; + +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_LS_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_parameters.pb.h b/thirdparty/linux/include/ortools/bop/bop_parameters.pb.h new file mode 100644 index 0000000..e5534e8 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_parameters.pb.h @@ -0,0 +1,1822 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/bop/bop_parameters.proto + +#ifndef PROTOBUF_ortools_2fbop_2fbop_5fparameters_2eproto__INCLUDED +#define PROTOBUF_ortools_2fbop_2fbop_5fparameters_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { +namespace bop { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fbop_2fbop_5fparameters_2eproto(); +void protobuf_AssignDesc_ortools_2fbop_2fbop_5fparameters_2eproto(); +void protobuf_ShutdownFile_ortools_2fbop_2fbop_5fparameters_2eproto(); + +class BopOptimizerMethod; +class BopParameters; +class BopSolverOptimizerSet; + +enum BopOptimizerMethod_OptimizerType { + BopOptimizerMethod_OptimizerType_SAT_CORE_BASED = 0, + BopOptimizerMethod_OptimizerType_SAT_LINEAR_SEARCH = 15, + BopOptimizerMethod_OptimizerType_LINEAR_RELAXATION = 1, + BopOptimizerMethod_OptimizerType_LOCAL_SEARCH = 2, + BopOptimizerMethod_OptimizerType_RANDOM_FIRST_SOLUTION = 3, + BopOptimizerMethod_OptimizerType_RANDOM_CONSTRAINT_LNS = 4, + BopOptimizerMethod_OptimizerType_RANDOM_VARIABLE_LNS = 5, + BopOptimizerMethod_OptimizerType_COMPLETE_LNS = 7, + BopOptimizerMethod_OptimizerType_LP_FIRST_SOLUTION = 8, + BopOptimizerMethod_OptimizerType_OBJECTIVE_FIRST_SOLUTION = 9, + BopOptimizerMethod_OptimizerType_USER_GUIDED_FIRST_SOLUTION = 14, + BopOptimizerMethod_OptimizerType_RANDOM_CONSTRAINT_LNS_GUIDED_BY_LP = 11, + BopOptimizerMethod_OptimizerType_RANDOM_VARIABLE_LNS_GUIDED_BY_LP = 12, + BopOptimizerMethod_OptimizerType_RELATION_GRAPH_LNS = 16, + BopOptimizerMethod_OptimizerType_RELATION_GRAPH_LNS_GUIDED_BY_LP = 17 +}; +bool BopOptimizerMethod_OptimizerType_IsValid(int value); +const BopOptimizerMethod_OptimizerType BopOptimizerMethod_OptimizerType_OptimizerType_MIN = BopOptimizerMethod_OptimizerType_SAT_CORE_BASED; +const BopOptimizerMethod_OptimizerType BopOptimizerMethod_OptimizerType_OptimizerType_MAX = BopOptimizerMethod_OptimizerType_RELATION_GRAPH_LNS_GUIDED_BY_LP; +const int BopOptimizerMethod_OptimizerType_OptimizerType_ARRAYSIZE = BopOptimizerMethod_OptimizerType_OptimizerType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* BopOptimizerMethod_OptimizerType_descriptor(); +inline const ::std::string& BopOptimizerMethod_OptimizerType_Name(BopOptimizerMethod_OptimizerType value) { + return ::google::protobuf::internal::NameOfEnum( + BopOptimizerMethod_OptimizerType_descriptor(), value); +} +inline bool BopOptimizerMethod_OptimizerType_Parse( + const ::std::string& name, BopOptimizerMethod_OptimizerType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + BopOptimizerMethod_OptimizerType_descriptor(), name, value); +} +enum BopParameters_ThreadSynchronizationType { + BopParameters_ThreadSynchronizationType_NO_SYNCHRONIZATION = 0, + BopParameters_ThreadSynchronizationType_SYNCHRONIZE_ALL = 1, + BopParameters_ThreadSynchronizationType_SYNCHRONIZE_ON_RIGHT = 2 +}; +bool BopParameters_ThreadSynchronizationType_IsValid(int value); +const BopParameters_ThreadSynchronizationType BopParameters_ThreadSynchronizationType_ThreadSynchronizationType_MIN = BopParameters_ThreadSynchronizationType_NO_SYNCHRONIZATION; +const BopParameters_ThreadSynchronizationType BopParameters_ThreadSynchronizationType_ThreadSynchronizationType_MAX = BopParameters_ThreadSynchronizationType_SYNCHRONIZE_ON_RIGHT; +const int BopParameters_ThreadSynchronizationType_ThreadSynchronizationType_ARRAYSIZE = BopParameters_ThreadSynchronizationType_ThreadSynchronizationType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* BopParameters_ThreadSynchronizationType_descriptor(); +inline const ::std::string& BopParameters_ThreadSynchronizationType_Name(BopParameters_ThreadSynchronizationType value) { + return ::google::protobuf::internal::NameOfEnum( + BopParameters_ThreadSynchronizationType_descriptor(), value); +} +inline bool BopParameters_ThreadSynchronizationType_Parse( + const ::std::string& name, BopParameters_ThreadSynchronizationType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + BopParameters_ThreadSynchronizationType_descriptor(), name, value); +} +// =================================================================== + +class BopOptimizerMethod : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.bop.BopOptimizerMethod) */ { + public: + BopOptimizerMethod(); + virtual ~BopOptimizerMethod(); + + BopOptimizerMethod(const BopOptimizerMethod& from); + + inline BopOptimizerMethod& operator=(const BopOptimizerMethod& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const BopOptimizerMethod& default_instance(); + + void Swap(BopOptimizerMethod* other); + + // implements Message ---------------------------------------------- + + inline BopOptimizerMethod* New() const { return New(NULL); } + + BopOptimizerMethod* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BopOptimizerMethod& from); + void MergeFrom(const BopOptimizerMethod& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BopOptimizerMethod* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef BopOptimizerMethod_OptimizerType OptimizerType; + static const OptimizerType SAT_CORE_BASED = + BopOptimizerMethod_OptimizerType_SAT_CORE_BASED; + static const OptimizerType SAT_LINEAR_SEARCH = + BopOptimizerMethod_OptimizerType_SAT_LINEAR_SEARCH; + static const OptimizerType LINEAR_RELAXATION = + BopOptimizerMethod_OptimizerType_LINEAR_RELAXATION; + static const OptimizerType LOCAL_SEARCH = + BopOptimizerMethod_OptimizerType_LOCAL_SEARCH; + static const OptimizerType RANDOM_FIRST_SOLUTION = + BopOptimizerMethod_OptimizerType_RANDOM_FIRST_SOLUTION; + static const OptimizerType RANDOM_CONSTRAINT_LNS = + BopOptimizerMethod_OptimizerType_RANDOM_CONSTRAINT_LNS; + static const OptimizerType RANDOM_VARIABLE_LNS = + BopOptimizerMethod_OptimizerType_RANDOM_VARIABLE_LNS; + static const OptimizerType COMPLETE_LNS = + BopOptimizerMethod_OptimizerType_COMPLETE_LNS; + static const OptimizerType LP_FIRST_SOLUTION = + BopOptimizerMethod_OptimizerType_LP_FIRST_SOLUTION; + static const OptimizerType OBJECTIVE_FIRST_SOLUTION = + BopOptimizerMethod_OptimizerType_OBJECTIVE_FIRST_SOLUTION; + static const OptimizerType USER_GUIDED_FIRST_SOLUTION = + BopOptimizerMethod_OptimizerType_USER_GUIDED_FIRST_SOLUTION; + static const OptimizerType RANDOM_CONSTRAINT_LNS_GUIDED_BY_LP = + BopOptimizerMethod_OptimizerType_RANDOM_CONSTRAINT_LNS_GUIDED_BY_LP; + static const OptimizerType RANDOM_VARIABLE_LNS_GUIDED_BY_LP = + BopOptimizerMethod_OptimizerType_RANDOM_VARIABLE_LNS_GUIDED_BY_LP; + static const OptimizerType RELATION_GRAPH_LNS = + BopOptimizerMethod_OptimizerType_RELATION_GRAPH_LNS; + static const OptimizerType RELATION_GRAPH_LNS_GUIDED_BY_LP = + BopOptimizerMethod_OptimizerType_RELATION_GRAPH_LNS_GUIDED_BY_LP; + static inline bool OptimizerType_IsValid(int value) { + return BopOptimizerMethod_OptimizerType_IsValid(value); + } + static const OptimizerType OptimizerType_MIN = + BopOptimizerMethod_OptimizerType_OptimizerType_MIN; + static const OptimizerType OptimizerType_MAX = + BopOptimizerMethod_OptimizerType_OptimizerType_MAX; + static const int OptimizerType_ARRAYSIZE = + BopOptimizerMethod_OptimizerType_OptimizerType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + OptimizerType_descriptor() { + return BopOptimizerMethod_OptimizerType_descriptor(); + } + static inline const ::std::string& OptimizerType_Name(OptimizerType value) { + return BopOptimizerMethod_OptimizerType_Name(value); + } + static inline bool OptimizerType_Parse(const ::std::string& name, + OptimizerType* value) { + return BopOptimizerMethod_OptimizerType_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .operations_research.bop.BopOptimizerMethod.OptimizerType type = 1; + bool has_type() const; + void clear_type(); + static const int kTypeFieldNumber = 1; + ::operations_research::bop::BopOptimizerMethod_OptimizerType type() const; + void set_type(::operations_research::bop::BopOptimizerMethod_OptimizerType value); + + // @@protoc_insertion_point(class_scope:operations_research.bop.BopOptimizerMethod) + private: + inline void set_has_type(); + inline void clear_has_type(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + int type_; + friend void protobuf_AddDesc_ortools_2fbop_2fbop_5fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fbop_2fbop_5fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fbop_2fbop_5fparameters_2eproto(); + + void InitAsDefaultInstance(); + static BopOptimizerMethod* default_instance_; +}; +// ------------------------------------------------------------------- + +class BopSolverOptimizerSet : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.bop.BopSolverOptimizerSet) */ { + public: + BopSolverOptimizerSet(); + virtual ~BopSolverOptimizerSet(); + + BopSolverOptimizerSet(const BopSolverOptimizerSet& from); + + inline BopSolverOptimizerSet& operator=(const BopSolverOptimizerSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const BopSolverOptimizerSet& default_instance(); + + void Swap(BopSolverOptimizerSet* other); + + // implements Message ---------------------------------------------- + + inline BopSolverOptimizerSet* New() const { return New(NULL); } + + BopSolverOptimizerSet* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BopSolverOptimizerSet& from); + void MergeFrom(const BopSolverOptimizerSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BopSolverOptimizerSet* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .operations_research.bop.BopOptimizerMethod methods = 1; + int methods_size() const; + void clear_methods(); + static const int kMethodsFieldNumber = 1; + const ::operations_research::bop::BopOptimizerMethod& methods(int index) const; + ::operations_research::bop::BopOptimizerMethod* mutable_methods(int index); + ::operations_research::bop::BopOptimizerMethod* add_methods(); + ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopOptimizerMethod >* + mutable_methods(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopOptimizerMethod >& + methods() const; + + // @@protoc_insertion_point(class_scope:operations_research.bop.BopSolverOptimizerSet) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopOptimizerMethod > methods_; + friend void protobuf_AddDesc_ortools_2fbop_2fbop_5fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fbop_2fbop_5fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fbop_2fbop_5fparameters_2eproto(); + + void InitAsDefaultInstance(); + static BopSolverOptimizerSet* default_instance_; +}; +// ------------------------------------------------------------------- + +class BopParameters : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.bop.BopParameters) */ { + public: + BopParameters(); + virtual ~BopParameters(); + + BopParameters(const BopParameters& from); + + inline BopParameters& operator=(const BopParameters& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const BopParameters& default_instance(); + + void Swap(BopParameters* other); + + // implements Message ---------------------------------------------- + + inline BopParameters* New() const { return New(NULL); } + + BopParameters* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BopParameters& from); + void MergeFrom(const BopParameters& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BopParameters* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef BopParameters_ThreadSynchronizationType ThreadSynchronizationType; + static const ThreadSynchronizationType NO_SYNCHRONIZATION = + BopParameters_ThreadSynchronizationType_NO_SYNCHRONIZATION; + static const ThreadSynchronizationType SYNCHRONIZE_ALL = + BopParameters_ThreadSynchronizationType_SYNCHRONIZE_ALL; + static const ThreadSynchronizationType SYNCHRONIZE_ON_RIGHT = + BopParameters_ThreadSynchronizationType_SYNCHRONIZE_ON_RIGHT; + static inline bool ThreadSynchronizationType_IsValid(int value) { + return BopParameters_ThreadSynchronizationType_IsValid(value); + } + static const ThreadSynchronizationType ThreadSynchronizationType_MIN = + BopParameters_ThreadSynchronizationType_ThreadSynchronizationType_MIN; + static const ThreadSynchronizationType ThreadSynchronizationType_MAX = + BopParameters_ThreadSynchronizationType_ThreadSynchronizationType_MAX; + static const int ThreadSynchronizationType_ARRAYSIZE = + BopParameters_ThreadSynchronizationType_ThreadSynchronizationType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + ThreadSynchronizationType_descriptor() { + return BopParameters_ThreadSynchronizationType_descriptor(); + } + static inline const ::std::string& ThreadSynchronizationType_Name(ThreadSynchronizationType value) { + return BopParameters_ThreadSynchronizationType_Name(value); + } + static inline bool ThreadSynchronizationType_Parse(const ::std::string& name, + ThreadSynchronizationType* value) { + return BopParameters_ThreadSynchronizationType_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional double max_time_in_seconds = 1 [default = inf]; + bool has_max_time_in_seconds() const; + void clear_max_time_in_seconds(); + static const int kMaxTimeInSecondsFieldNumber = 1; + double max_time_in_seconds() const; + void set_max_time_in_seconds(double value); + + // optional double max_deterministic_time = 27 [default = inf]; + bool has_max_deterministic_time() const; + void clear_max_deterministic_time(); + static const int kMaxDeterministicTimeFieldNumber = 27; + double max_deterministic_time() const; + void set_max_deterministic_time(double value); + + // optional double lp_max_deterministic_time = 37 [default = 1]; + bool has_lp_max_deterministic_time() const; + void clear_lp_max_deterministic_time(); + static const int kLpMaxDeterministicTimeFieldNumber = 37; + double lp_max_deterministic_time() const; + void set_lp_max_deterministic_time(double value); + + // optional int32 max_number_of_consecutive_failing_optimizer_calls = 35; + bool has_max_number_of_consecutive_failing_optimizer_calls() const; + void clear_max_number_of_consecutive_failing_optimizer_calls(); + static const int kMaxNumberOfConsecutiveFailingOptimizerCallsFieldNumber = 35; + ::google::protobuf::int32 max_number_of_consecutive_failing_optimizer_calls() const; + void set_max_number_of_consecutive_failing_optimizer_calls(::google::protobuf::int32 value); + + // optional double relative_gap_limit = 28 [default = 0.0001]; + bool has_relative_gap_limit() const; + void clear_relative_gap_limit(); + static const int kRelativeGapLimitFieldNumber = 28; + double relative_gap_limit() const; + void set_relative_gap_limit(double value); + + // optional int32 max_num_decisions_in_ls = 2 [default = 4]; + bool has_max_num_decisions_in_ls() const; + void clear_max_num_decisions_in_ls(); + static const int kMaxNumDecisionsInLsFieldNumber = 2; + ::google::protobuf::int32 max_num_decisions_in_ls() const; + void set_max_num_decisions_in_ls(::google::protobuf::int32 value); + + // optional int32 max_num_broken_constraints_in_ls = 38 [default = 2147483647]; + bool has_max_num_broken_constraints_in_ls() const; + void clear_max_num_broken_constraints_in_ls(); + static const int kMaxNumBrokenConstraintsInLsFieldNumber = 38; + ::google::protobuf::int32 max_num_broken_constraints_in_ls() const; + void set_max_num_broken_constraints_in_ls(::google::protobuf::int32 value); + + // optional bool log_search_progress = 14 [default = false]; + bool has_log_search_progress() const; + void clear_log_search_progress(); + static const int kLogSearchProgressFieldNumber = 14; + bool log_search_progress() const; + void set_log_search_progress(bool value); + + // optional bool compute_estimated_impact = 3 [default = true]; + bool has_compute_estimated_impact() const; + void clear_compute_estimated_impact(); + static const int kComputeEstimatedImpactFieldNumber = 3; + bool compute_estimated_impact() const; + void set_compute_estimated_impact(bool value); + + // optional bool prune_search_tree = 4 [default = false]; + bool has_prune_search_tree() const; + void clear_prune_search_tree(); + static const int kPruneSearchTreeFieldNumber = 4; + bool prune_search_tree() const; + void set_prune_search_tree(bool value); + + // optional bool sort_constraints_by_num_terms = 5 [default = false]; + bool has_sort_constraints_by_num_terms() const; + void clear_sort_constraints_by_num_terms(); + static const int kSortConstraintsByNumTermsFieldNumber = 5; + bool sort_constraints_by_num_terms() const; + void set_sort_constraints_by_num_terms(bool value); + + // optional bool use_random_lns = 6 [default = true]; + bool has_use_random_lns() const; + void clear_use_random_lns(); + static const int kUseRandomLnsFieldNumber = 6; + bool use_random_lns() const; + void set_use_random_lns(bool value); + + // optional int32 random_seed = 7 [default = 0]; + bool has_random_seed() const; + void clear_random_seed(); + static const int kRandomSeedFieldNumber = 7; + ::google::protobuf::int32 random_seed() const; + void set_random_seed(::google::protobuf::int32 value); + + // optional int32 num_relaxed_vars = 8 [default = 10]; + bool has_num_relaxed_vars() const; + void clear_num_relaxed_vars(); + static const int kNumRelaxedVarsFieldNumber = 8; + ::google::protobuf::int32 num_relaxed_vars() const; + void set_num_relaxed_vars(::google::protobuf::int32 value); + + // optional int32 max_number_of_conflicts_in_random_lns = 9 [default = 2500]; + bool has_max_number_of_conflicts_in_random_lns() const; + void clear_max_number_of_conflicts_in_random_lns(); + static const int kMaxNumberOfConflictsInRandomLnsFieldNumber = 9; + ::google::protobuf::int32 max_number_of_conflicts_in_random_lns() const; + void set_max_number_of_conflicts_in_random_lns(::google::protobuf::int32 value); + + // optional int32 num_random_lns_tries = 10 [default = 1]; + bool has_num_random_lns_tries() const; + void clear_num_random_lns_tries(); + static const int kNumRandomLnsTriesFieldNumber = 10; + ::google::protobuf::int32 num_random_lns_tries() const; + void set_num_random_lns_tries(::google::protobuf::int32 value); + + // optional int64 max_number_of_backtracks_in_ls = 11 [default = 100000000]; + bool has_max_number_of_backtracks_in_ls() const; + void clear_max_number_of_backtracks_in_ls(); + static const int kMaxNumberOfBacktracksInLsFieldNumber = 11; + ::google::protobuf::int64 max_number_of_backtracks_in_ls() const; + void set_max_number_of_backtracks_in_ls(::google::protobuf::int64 value); + + // optional bool use_lp_lns = 12 [default = true]; + bool has_use_lp_lns() const; + void clear_use_lp_lns(); + static const int kUseLpLnsFieldNumber = 12; + bool use_lp_lns() const; + void set_use_lp_lns(bool value); + + // optional bool use_sat_to_choose_lns_neighbourhood = 15 [default = true]; + bool has_use_sat_to_choose_lns_neighbourhood() const; + void clear_use_sat_to_choose_lns_neighbourhood(); + static const int kUseSatToChooseLnsNeighbourhoodFieldNumber = 15; + bool use_sat_to_choose_lns_neighbourhood() const; + void set_use_sat_to_choose_lns_neighbourhood(bool value); + + // optional int32 max_number_of_conflicts_for_quick_check = 16 [default = 10]; + bool has_max_number_of_conflicts_for_quick_check() const; + void clear_max_number_of_conflicts_for_quick_check(); + static const int kMaxNumberOfConflictsForQuickCheckFieldNumber = 16; + ::google::protobuf::int32 max_number_of_conflicts_for_quick_check() const; + void set_max_number_of_conflicts_for_quick_check(::google::protobuf::int32 value); + + // optional bool use_symmetry = 17 [default = false]; + bool has_use_symmetry() const; + void clear_use_symmetry(); + static const int kUseSymmetryFieldNumber = 17; + bool use_symmetry() const; + void set_use_symmetry(bool value); + + // optional bool exploit_symmetry_in_sat_first_solution = 40 [default = false]; + bool has_exploit_symmetry_in_sat_first_solution() const; + void clear_exploit_symmetry_in_sat_first_solution(); + static const int kExploitSymmetryInSatFirstSolutionFieldNumber = 40; + bool exploit_symmetry_in_sat_first_solution() const; + void set_exploit_symmetry_in_sat_first_solution(bool value); + + // optional int32 max_number_of_conflicts_in_random_solution_generation = 20 [default = 500]; + bool has_max_number_of_conflicts_in_random_solution_generation() const; + void clear_max_number_of_conflicts_in_random_solution_generation(); + static const int kMaxNumberOfConflictsInRandomSolutionGenerationFieldNumber = 20; + ::google::protobuf::int32 max_number_of_conflicts_in_random_solution_generation() const; + void set_max_number_of_conflicts_in_random_solution_generation(::google::protobuf::int32 value); + + // optional int64 max_number_of_explored_assignments_per_try_in_ls = 21 [default = 10000]; + bool has_max_number_of_explored_assignments_per_try_in_ls() const; + void clear_max_number_of_explored_assignments_per_try_in_ls(); + static const int kMaxNumberOfExploredAssignmentsPerTryInLsFieldNumber = 21; + ::google::protobuf::int64 max_number_of_explored_assignments_per_try_in_ls() const; + void set_max_number_of_explored_assignments_per_try_in_ls(::google::protobuf::int64 value); + + // optional bool use_transposition_table_in_ls = 22 [default = true]; + bool has_use_transposition_table_in_ls() const; + void clear_use_transposition_table_in_ls(); + static const int kUseTranspositionTableInLsFieldNumber = 22; + bool use_transposition_table_in_ls() const; + void set_use_transposition_table_in_ls(bool value); + + // optional bool use_potential_one_flip_repairs_in_ls = 39 [default = false]; + bool has_use_potential_one_flip_repairs_in_ls() const; + void clear_use_potential_one_flip_repairs_in_ls(); + static const int kUsePotentialOneFlipRepairsInLsFieldNumber = 39; + bool use_potential_one_flip_repairs_in_ls() const; + void set_use_potential_one_flip_repairs_in_ls(bool value); + + // optional bool use_learned_binary_clauses_in_lp = 23 [default = true]; + bool has_use_learned_binary_clauses_in_lp() const; + void clear_use_learned_binary_clauses_in_lp(); + static const int kUseLearnedBinaryClausesInLpFieldNumber = 23; + bool use_learned_binary_clauses_in_lp() const; + void set_use_learned_binary_clauses_in_lp(bool value); + + // optional int32 number_of_solvers = 24 [default = 1]; + bool has_number_of_solvers() const; + void clear_number_of_solvers(); + static const int kNumberOfSolversFieldNumber = 24; + ::google::protobuf::int32 number_of_solvers() const; + void set_number_of_solvers(::google::protobuf::int32 value); + + // optional .operations_research.bop.BopParameters.ThreadSynchronizationType synchronization_type = 25 [default = NO_SYNCHRONIZATION]; + bool has_synchronization_type() const; + void clear_synchronization_type(); + static const int kSynchronizationTypeFieldNumber = 25; + ::operations_research::bop::BopParameters_ThreadSynchronizationType synchronization_type() const; + void set_synchronization_type(::operations_research::bop::BopParameters_ThreadSynchronizationType value); + + // repeated .operations_research.bop.BopSolverOptimizerSet solver_optimizer_sets = 26; + int solver_optimizer_sets_size() const; + void clear_solver_optimizer_sets(); + static const int kSolverOptimizerSetsFieldNumber = 26; + const ::operations_research::bop::BopSolverOptimizerSet& solver_optimizer_sets(int index) const; + ::operations_research::bop::BopSolverOptimizerSet* mutable_solver_optimizer_sets(int index); + ::operations_research::bop::BopSolverOptimizerSet* add_solver_optimizer_sets(); + ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopSolverOptimizerSet >* + mutable_solver_optimizer_sets(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopSolverOptimizerSet >& + solver_optimizer_sets() const; + + // optional string default_solver_optimizer_sets = 33 [default = "methods:{type:LOCAL_SEARCH } methods:{type:RANDOM_FIRST_SOLUTION } methods:{type:LINEAR_RELAXATION } methods:{type:LP_FIRST_SOLUTION } methods:{type:OBJECTIVE_FIRST_SOLUTION } methods:{type:USER_GUIDED_FIRST_SOLUTION } methods:{type:RANDOM_CONSTRAINT_LNS_GUIDED_BY_LP } methods:{type:RANDOM_VARIABLE_LNS_GUIDED_BY_LP } methods:{type:RELATION_GRAPH_LNS } methods:{type:RELATION_GRAPH_LNS_GUIDED_BY_LP } methods:{type:RANDOM_CONSTRAINT_LNS } methods:{type:RANDOM_VARIABLE_LNS } methods:{type:SAT_CORE_BASED } methods:{type:COMPLETE_LNS } "]; + bool has_default_solver_optimizer_sets() const; + void clear_default_solver_optimizer_sets(); + static const int kDefaultSolverOptimizerSetsFieldNumber = 33; + const ::std::string& default_solver_optimizer_sets() const; + void set_default_solver_optimizer_sets(const ::std::string& value); + void set_default_solver_optimizer_sets(const char* value); + void set_default_solver_optimizer_sets(const char* value, size_t size); + ::std::string* mutable_default_solver_optimizer_sets(); + ::std::string* release_default_solver_optimizer_sets(); + void set_allocated_default_solver_optimizer_sets(::std::string* default_solver_optimizer_sets); + + // optional bool use_lp_strong_branching = 29 [default = false]; + bool has_use_lp_strong_branching() const; + void clear_use_lp_strong_branching(); + static const int kUseLpStrongBranchingFieldNumber = 29; + bool use_lp_strong_branching() const; + void set_use_lp_strong_branching(bool value); + + // optional int32 decomposer_num_variables_threshold = 30 [default = 50]; + bool has_decomposer_num_variables_threshold() const; + void clear_decomposer_num_variables_threshold(); + static const int kDecomposerNumVariablesThresholdFieldNumber = 30; + ::google::protobuf::int32 decomposer_num_variables_threshold() const; + void set_decomposer_num_variables_threshold(::google::protobuf::int32 value); + + // optional int32 num_bop_solvers_used_by_decomposition = 31 [default = 1]; + bool has_num_bop_solvers_used_by_decomposition() const; + void clear_num_bop_solvers_used_by_decomposition(); + static const int kNumBopSolversUsedByDecompositionFieldNumber = 31; + ::google::protobuf::int32 num_bop_solvers_used_by_decomposition() const; + void set_num_bop_solvers_used_by_decomposition(::google::protobuf::int32 value); + + // optional double decomposed_problem_min_time_in_seconds = 36 [default = 0]; + bool has_decomposed_problem_min_time_in_seconds() const; + void clear_decomposed_problem_min_time_in_seconds(); + static const int kDecomposedProblemMinTimeInSecondsFieldNumber = 36; + double decomposed_problem_min_time_in_seconds() const; + void set_decomposed_problem_min_time_in_seconds(double value); + + // optional int32 guided_sat_conflicts_chunk = 34 [default = 1000]; + bool has_guided_sat_conflicts_chunk() const; + void clear_guided_sat_conflicts_chunk(); + static const int kGuidedSatConflictsChunkFieldNumber = 34; + ::google::protobuf::int32 guided_sat_conflicts_chunk() const; + void set_guided_sat_conflicts_chunk(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:operations_research.bop.BopParameters) + private: + inline void set_has_max_time_in_seconds(); + inline void clear_has_max_time_in_seconds(); + inline void set_has_max_deterministic_time(); + inline void clear_has_max_deterministic_time(); + inline void set_has_lp_max_deterministic_time(); + inline void clear_has_lp_max_deterministic_time(); + inline void set_has_max_number_of_consecutive_failing_optimizer_calls(); + inline void clear_has_max_number_of_consecutive_failing_optimizer_calls(); + inline void set_has_relative_gap_limit(); + inline void clear_has_relative_gap_limit(); + inline void set_has_max_num_decisions_in_ls(); + inline void clear_has_max_num_decisions_in_ls(); + inline void set_has_max_num_broken_constraints_in_ls(); + inline void clear_has_max_num_broken_constraints_in_ls(); + inline void set_has_log_search_progress(); + inline void clear_has_log_search_progress(); + inline void set_has_compute_estimated_impact(); + inline void clear_has_compute_estimated_impact(); + inline void set_has_prune_search_tree(); + inline void clear_has_prune_search_tree(); + inline void set_has_sort_constraints_by_num_terms(); + inline void clear_has_sort_constraints_by_num_terms(); + inline void set_has_use_random_lns(); + inline void clear_has_use_random_lns(); + inline void set_has_random_seed(); + inline void clear_has_random_seed(); + inline void set_has_num_relaxed_vars(); + inline void clear_has_num_relaxed_vars(); + inline void set_has_max_number_of_conflicts_in_random_lns(); + inline void clear_has_max_number_of_conflicts_in_random_lns(); + inline void set_has_num_random_lns_tries(); + inline void clear_has_num_random_lns_tries(); + inline void set_has_max_number_of_backtracks_in_ls(); + inline void clear_has_max_number_of_backtracks_in_ls(); + inline void set_has_use_lp_lns(); + inline void clear_has_use_lp_lns(); + inline void set_has_use_sat_to_choose_lns_neighbourhood(); + inline void clear_has_use_sat_to_choose_lns_neighbourhood(); + inline void set_has_max_number_of_conflicts_for_quick_check(); + inline void clear_has_max_number_of_conflicts_for_quick_check(); + inline void set_has_use_symmetry(); + inline void clear_has_use_symmetry(); + inline void set_has_exploit_symmetry_in_sat_first_solution(); + inline void clear_has_exploit_symmetry_in_sat_first_solution(); + inline void set_has_max_number_of_conflicts_in_random_solution_generation(); + inline void clear_has_max_number_of_conflicts_in_random_solution_generation(); + inline void set_has_max_number_of_explored_assignments_per_try_in_ls(); + inline void clear_has_max_number_of_explored_assignments_per_try_in_ls(); + inline void set_has_use_transposition_table_in_ls(); + inline void clear_has_use_transposition_table_in_ls(); + inline void set_has_use_potential_one_flip_repairs_in_ls(); + inline void clear_has_use_potential_one_flip_repairs_in_ls(); + inline void set_has_use_learned_binary_clauses_in_lp(); + inline void clear_has_use_learned_binary_clauses_in_lp(); + inline void set_has_number_of_solvers(); + inline void clear_has_number_of_solvers(); + inline void set_has_synchronization_type(); + inline void clear_has_synchronization_type(); + inline void set_has_default_solver_optimizer_sets(); + inline void clear_has_default_solver_optimizer_sets(); + inline void set_has_use_lp_strong_branching(); + inline void clear_has_use_lp_strong_branching(); + inline void set_has_decomposer_num_variables_threshold(); + inline void clear_has_decomposer_num_variables_threshold(); + inline void set_has_num_bop_solvers_used_by_decomposition(); + inline void clear_has_num_bop_solvers_used_by_decomposition(); + inline void set_has_decomposed_problem_min_time_in_seconds(); + inline void clear_has_decomposed_problem_min_time_in_seconds(); + inline void set_has_guided_sat_conflicts_chunk(); + inline void clear_has_guided_sat_conflicts_chunk(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[2]; + double max_time_in_seconds_; + double max_deterministic_time_; + double lp_max_deterministic_time_; + double relative_gap_limit_; + ::google::protobuf::int32 max_number_of_consecutive_failing_optimizer_calls_; + ::google::protobuf::int32 max_num_decisions_in_ls_; + ::google::protobuf::int32 max_num_broken_constraints_in_ls_; + bool log_search_progress_; + bool compute_estimated_impact_; + bool prune_search_tree_; + bool sort_constraints_by_num_terms_; + ::google::protobuf::int32 random_seed_; + ::google::protobuf::int32 num_relaxed_vars_; + ::google::protobuf::int32 max_number_of_conflicts_in_random_lns_; + ::google::protobuf::int32 num_random_lns_tries_; + ::google::protobuf::int64 max_number_of_backtracks_in_ls_; + bool use_random_lns_; + bool use_lp_lns_; + bool use_sat_to_choose_lns_neighbourhood_; + bool use_symmetry_; + ::google::protobuf::int32 max_number_of_conflicts_for_quick_check_; + ::google::protobuf::int64 max_number_of_explored_assignments_per_try_in_ls_; + ::google::protobuf::int32 max_number_of_conflicts_in_random_solution_generation_; + bool exploit_symmetry_in_sat_first_solution_; + bool use_transposition_table_in_ls_; + bool use_potential_one_flip_repairs_in_ls_; + bool use_learned_binary_clauses_in_lp_; + ::google::protobuf::int32 number_of_solvers_; + int synchronization_type_; + ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopSolverOptimizerSet > solver_optimizer_sets_; + static ::std::string* _default_default_solver_optimizer_sets_; + ::google::protobuf::internal::ArenaStringPtr default_solver_optimizer_sets_; + bool use_lp_strong_branching_; + ::google::protobuf::int32 decomposer_num_variables_threshold_; + double decomposed_problem_min_time_in_seconds_; + ::google::protobuf::int32 num_bop_solvers_used_by_decomposition_; + ::google::protobuf::int32 guided_sat_conflicts_chunk_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fbop_2fbop_5fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fbop_2fbop_5fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fbop_2fbop_5fparameters_2eproto(); + + void InitAsDefaultInstance(); + static BopParameters* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// BopOptimizerMethod + +// optional .operations_research.bop.BopOptimizerMethod.OptimizerType type = 1; +inline bool BopOptimizerMethod::has_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void BopOptimizerMethod::set_has_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void BopOptimizerMethod::clear_has_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void BopOptimizerMethod::clear_type() { + type_ = 0; + clear_has_type(); +} +inline ::operations_research::bop::BopOptimizerMethod_OptimizerType BopOptimizerMethod::type() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopOptimizerMethod.type) + return static_cast< ::operations_research::bop::BopOptimizerMethod_OptimizerType >(type_); +} +inline void BopOptimizerMethod::set_type(::operations_research::bop::BopOptimizerMethod_OptimizerType value) { + assert(::operations_research::bop::BopOptimizerMethod_OptimizerType_IsValid(value)); + set_has_type(); + type_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopOptimizerMethod.type) +} + +// ------------------------------------------------------------------- + +// BopSolverOptimizerSet + +// repeated .operations_research.bop.BopOptimizerMethod methods = 1; +inline int BopSolverOptimizerSet::methods_size() const { + return methods_.size(); +} +inline void BopSolverOptimizerSet::clear_methods() { + methods_.Clear(); +} +inline const ::operations_research::bop::BopOptimizerMethod& BopSolverOptimizerSet::methods(int index) const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopSolverOptimizerSet.methods) + return methods_.Get(index); +} +inline ::operations_research::bop::BopOptimizerMethod* BopSolverOptimizerSet::mutable_methods(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.bop.BopSolverOptimizerSet.methods) + return methods_.Mutable(index); +} +inline ::operations_research::bop::BopOptimizerMethod* BopSolverOptimizerSet::add_methods() { + // @@protoc_insertion_point(field_add:operations_research.bop.BopSolverOptimizerSet.methods) + return methods_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopOptimizerMethod >* +BopSolverOptimizerSet::mutable_methods() { + // @@protoc_insertion_point(field_mutable_list:operations_research.bop.BopSolverOptimizerSet.methods) + return &methods_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopOptimizerMethod >& +BopSolverOptimizerSet::methods() const { + // @@protoc_insertion_point(field_list:operations_research.bop.BopSolverOptimizerSet.methods) + return methods_; +} + +// ------------------------------------------------------------------- + +// BopParameters + +// optional double max_time_in_seconds = 1 [default = inf]; +inline bool BopParameters::has_max_time_in_seconds() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void BopParameters::set_has_max_time_in_seconds() { + _has_bits_[0] |= 0x00000001u; +} +inline void BopParameters::clear_has_max_time_in_seconds() { + _has_bits_[0] &= ~0x00000001u; +} +inline void BopParameters::clear_max_time_in_seconds() { + max_time_in_seconds_ = ::google::protobuf::internal::Infinity(); + clear_has_max_time_in_seconds(); +} +inline double BopParameters::max_time_in_seconds() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_time_in_seconds) + return max_time_in_seconds_; +} +inline void BopParameters::set_max_time_in_seconds(double value) { + set_has_max_time_in_seconds(); + max_time_in_seconds_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_time_in_seconds) +} + +// optional double max_deterministic_time = 27 [default = inf]; +inline bool BopParameters::has_max_deterministic_time() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void BopParameters::set_has_max_deterministic_time() { + _has_bits_[0] |= 0x00000002u; +} +inline void BopParameters::clear_has_max_deterministic_time() { + _has_bits_[0] &= ~0x00000002u; +} +inline void BopParameters::clear_max_deterministic_time() { + max_deterministic_time_ = ::google::protobuf::internal::Infinity(); + clear_has_max_deterministic_time(); +} +inline double BopParameters::max_deterministic_time() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_deterministic_time) + return max_deterministic_time_; +} +inline void BopParameters::set_max_deterministic_time(double value) { + set_has_max_deterministic_time(); + max_deterministic_time_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_deterministic_time) +} + +// optional double lp_max_deterministic_time = 37 [default = 1]; +inline bool BopParameters::has_lp_max_deterministic_time() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void BopParameters::set_has_lp_max_deterministic_time() { + _has_bits_[0] |= 0x00000004u; +} +inline void BopParameters::clear_has_lp_max_deterministic_time() { + _has_bits_[0] &= ~0x00000004u; +} +inline void BopParameters::clear_lp_max_deterministic_time() { + lp_max_deterministic_time_ = 1; + clear_has_lp_max_deterministic_time(); +} +inline double BopParameters::lp_max_deterministic_time() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.lp_max_deterministic_time) + return lp_max_deterministic_time_; +} +inline void BopParameters::set_lp_max_deterministic_time(double value) { + set_has_lp_max_deterministic_time(); + lp_max_deterministic_time_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.lp_max_deterministic_time) +} + +// optional int32 max_number_of_consecutive_failing_optimizer_calls = 35; +inline bool BopParameters::has_max_number_of_consecutive_failing_optimizer_calls() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void BopParameters::set_has_max_number_of_consecutive_failing_optimizer_calls() { + _has_bits_[0] |= 0x00000008u; +} +inline void BopParameters::clear_has_max_number_of_consecutive_failing_optimizer_calls() { + _has_bits_[0] &= ~0x00000008u; +} +inline void BopParameters::clear_max_number_of_consecutive_failing_optimizer_calls() { + max_number_of_consecutive_failing_optimizer_calls_ = 0; + clear_has_max_number_of_consecutive_failing_optimizer_calls(); +} +inline ::google::protobuf::int32 BopParameters::max_number_of_consecutive_failing_optimizer_calls() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_number_of_consecutive_failing_optimizer_calls) + return max_number_of_consecutive_failing_optimizer_calls_; +} +inline void BopParameters::set_max_number_of_consecutive_failing_optimizer_calls(::google::protobuf::int32 value) { + set_has_max_number_of_consecutive_failing_optimizer_calls(); + max_number_of_consecutive_failing_optimizer_calls_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_number_of_consecutive_failing_optimizer_calls) +} + +// optional double relative_gap_limit = 28 [default = 0.0001]; +inline bool BopParameters::has_relative_gap_limit() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void BopParameters::set_has_relative_gap_limit() { + _has_bits_[0] |= 0x00000010u; +} +inline void BopParameters::clear_has_relative_gap_limit() { + _has_bits_[0] &= ~0x00000010u; +} +inline void BopParameters::clear_relative_gap_limit() { + relative_gap_limit_ = 0.0001; + clear_has_relative_gap_limit(); +} +inline double BopParameters::relative_gap_limit() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.relative_gap_limit) + return relative_gap_limit_; +} +inline void BopParameters::set_relative_gap_limit(double value) { + set_has_relative_gap_limit(); + relative_gap_limit_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.relative_gap_limit) +} + +// optional int32 max_num_decisions_in_ls = 2 [default = 4]; +inline bool BopParameters::has_max_num_decisions_in_ls() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void BopParameters::set_has_max_num_decisions_in_ls() { + _has_bits_[0] |= 0x00000020u; +} +inline void BopParameters::clear_has_max_num_decisions_in_ls() { + _has_bits_[0] &= ~0x00000020u; +} +inline void BopParameters::clear_max_num_decisions_in_ls() { + max_num_decisions_in_ls_ = 4; + clear_has_max_num_decisions_in_ls(); +} +inline ::google::protobuf::int32 BopParameters::max_num_decisions_in_ls() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_num_decisions_in_ls) + return max_num_decisions_in_ls_; +} +inline void BopParameters::set_max_num_decisions_in_ls(::google::protobuf::int32 value) { + set_has_max_num_decisions_in_ls(); + max_num_decisions_in_ls_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_num_decisions_in_ls) +} + +// optional int32 max_num_broken_constraints_in_ls = 38 [default = 2147483647]; +inline bool BopParameters::has_max_num_broken_constraints_in_ls() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void BopParameters::set_has_max_num_broken_constraints_in_ls() { + _has_bits_[0] |= 0x00000040u; +} +inline void BopParameters::clear_has_max_num_broken_constraints_in_ls() { + _has_bits_[0] &= ~0x00000040u; +} +inline void BopParameters::clear_max_num_broken_constraints_in_ls() { + max_num_broken_constraints_in_ls_ = 2147483647; + clear_has_max_num_broken_constraints_in_ls(); +} +inline ::google::protobuf::int32 BopParameters::max_num_broken_constraints_in_ls() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_num_broken_constraints_in_ls) + return max_num_broken_constraints_in_ls_; +} +inline void BopParameters::set_max_num_broken_constraints_in_ls(::google::protobuf::int32 value) { + set_has_max_num_broken_constraints_in_ls(); + max_num_broken_constraints_in_ls_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_num_broken_constraints_in_ls) +} + +// optional bool log_search_progress = 14 [default = false]; +inline bool BopParameters::has_log_search_progress() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void BopParameters::set_has_log_search_progress() { + _has_bits_[0] |= 0x00000080u; +} +inline void BopParameters::clear_has_log_search_progress() { + _has_bits_[0] &= ~0x00000080u; +} +inline void BopParameters::clear_log_search_progress() { + log_search_progress_ = false; + clear_has_log_search_progress(); +} +inline bool BopParameters::log_search_progress() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.log_search_progress) + return log_search_progress_; +} +inline void BopParameters::set_log_search_progress(bool value) { + set_has_log_search_progress(); + log_search_progress_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.log_search_progress) +} + +// optional bool compute_estimated_impact = 3 [default = true]; +inline bool BopParameters::has_compute_estimated_impact() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void BopParameters::set_has_compute_estimated_impact() { + _has_bits_[0] |= 0x00000100u; +} +inline void BopParameters::clear_has_compute_estimated_impact() { + _has_bits_[0] &= ~0x00000100u; +} +inline void BopParameters::clear_compute_estimated_impact() { + compute_estimated_impact_ = true; + clear_has_compute_estimated_impact(); +} +inline bool BopParameters::compute_estimated_impact() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.compute_estimated_impact) + return compute_estimated_impact_; +} +inline void BopParameters::set_compute_estimated_impact(bool value) { + set_has_compute_estimated_impact(); + compute_estimated_impact_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.compute_estimated_impact) +} + +// optional bool prune_search_tree = 4 [default = false]; +inline bool BopParameters::has_prune_search_tree() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void BopParameters::set_has_prune_search_tree() { + _has_bits_[0] |= 0x00000200u; +} +inline void BopParameters::clear_has_prune_search_tree() { + _has_bits_[0] &= ~0x00000200u; +} +inline void BopParameters::clear_prune_search_tree() { + prune_search_tree_ = false; + clear_has_prune_search_tree(); +} +inline bool BopParameters::prune_search_tree() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.prune_search_tree) + return prune_search_tree_; +} +inline void BopParameters::set_prune_search_tree(bool value) { + set_has_prune_search_tree(); + prune_search_tree_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.prune_search_tree) +} + +// optional bool sort_constraints_by_num_terms = 5 [default = false]; +inline bool BopParameters::has_sort_constraints_by_num_terms() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void BopParameters::set_has_sort_constraints_by_num_terms() { + _has_bits_[0] |= 0x00000400u; +} +inline void BopParameters::clear_has_sort_constraints_by_num_terms() { + _has_bits_[0] &= ~0x00000400u; +} +inline void BopParameters::clear_sort_constraints_by_num_terms() { + sort_constraints_by_num_terms_ = false; + clear_has_sort_constraints_by_num_terms(); +} +inline bool BopParameters::sort_constraints_by_num_terms() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.sort_constraints_by_num_terms) + return sort_constraints_by_num_terms_; +} +inline void BopParameters::set_sort_constraints_by_num_terms(bool value) { + set_has_sort_constraints_by_num_terms(); + sort_constraints_by_num_terms_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.sort_constraints_by_num_terms) +} + +// optional bool use_random_lns = 6 [default = true]; +inline bool BopParameters::has_use_random_lns() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void BopParameters::set_has_use_random_lns() { + _has_bits_[0] |= 0x00000800u; +} +inline void BopParameters::clear_has_use_random_lns() { + _has_bits_[0] &= ~0x00000800u; +} +inline void BopParameters::clear_use_random_lns() { + use_random_lns_ = true; + clear_has_use_random_lns(); +} +inline bool BopParameters::use_random_lns() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.use_random_lns) + return use_random_lns_; +} +inline void BopParameters::set_use_random_lns(bool value) { + set_has_use_random_lns(); + use_random_lns_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.use_random_lns) +} + +// optional int32 random_seed = 7 [default = 0]; +inline bool BopParameters::has_random_seed() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void BopParameters::set_has_random_seed() { + _has_bits_[0] |= 0x00001000u; +} +inline void BopParameters::clear_has_random_seed() { + _has_bits_[0] &= ~0x00001000u; +} +inline void BopParameters::clear_random_seed() { + random_seed_ = 0; + clear_has_random_seed(); +} +inline ::google::protobuf::int32 BopParameters::random_seed() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.random_seed) + return random_seed_; +} +inline void BopParameters::set_random_seed(::google::protobuf::int32 value) { + set_has_random_seed(); + random_seed_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.random_seed) +} + +// optional int32 num_relaxed_vars = 8 [default = 10]; +inline bool BopParameters::has_num_relaxed_vars() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void BopParameters::set_has_num_relaxed_vars() { + _has_bits_[0] |= 0x00002000u; +} +inline void BopParameters::clear_has_num_relaxed_vars() { + _has_bits_[0] &= ~0x00002000u; +} +inline void BopParameters::clear_num_relaxed_vars() { + num_relaxed_vars_ = 10; + clear_has_num_relaxed_vars(); +} +inline ::google::protobuf::int32 BopParameters::num_relaxed_vars() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.num_relaxed_vars) + return num_relaxed_vars_; +} +inline void BopParameters::set_num_relaxed_vars(::google::protobuf::int32 value) { + set_has_num_relaxed_vars(); + num_relaxed_vars_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.num_relaxed_vars) +} + +// optional int32 max_number_of_conflicts_in_random_lns = 9 [default = 2500]; +inline bool BopParameters::has_max_number_of_conflicts_in_random_lns() const { + return (_has_bits_[0] & 0x00004000u) != 0; +} +inline void BopParameters::set_has_max_number_of_conflicts_in_random_lns() { + _has_bits_[0] |= 0x00004000u; +} +inline void BopParameters::clear_has_max_number_of_conflicts_in_random_lns() { + _has_bits_[0] &= ~0x00004000u; +} +inline void BopParameters::clear_max_number_of_conflicts_in_random_lns() { + max_number_of_conflicts_in_random_lns_ = 2500; + clear_has_max_number_of_conflicts_in_random_lns(); +} +inline ::google::protobuf::int32 BopParameters::max_number_of_conflicts_in_random_lns() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_number_of_conflicts_in_random_lns) + return max_number_of_conflicts_in_random_lns_; +} +inline void BopParameters::set_max_number_of_conflicts_in_random_lns(::google::protobuf::int32 value) { + set_has_max_number_of_conflicts_in_random_lns(); + max_number_of_conflicts_in_random_lns_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_number_of_conflicts_in_random_lns) +} + +// optional int32 num_random_lns_tries = 10 [default = 1]; +inline bool BopParameters::has_num_random_lns_tries() const { + return (_has_bits_[0] & 0x00008000u) != 0; +} +inline void BopParameters::set_has_num_random_lns_tries() { + _has_bits_[0] |= 0x00008000u; +} +inline void BopParameters::clear_has_num_random_lns_tries() { + _has_bits_[0] &= ~0x00008000u; +} +inline void BopParameters::clear_num_random_lns_tries() { + num_random_lns_tries_ = 1; + clear_has_num_random_lns_tries(); +} +inline ::google::protobuf::int32 BopParameters::num_random_lns_tries() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.num_random_lns_tries) + return num_random_lns_tries_; +} +inline void BopParameters::set_num_random_lns_tries(::google::protobuf::int32 value) { + set_has_num_random_lns_tries(); + num_random_lns_tries_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.num_random_lns_tries) +} + +// optional int64 max_number_of_backtracks_in_ls = 11 [default = 100000000]; +inline bool BopParameters::has_max_number_of_backtracks_in_ls() const { + return (_has_bits_[0] & 0x00010000u) != 0; +} +inline void BopParameters::set_has_max_number_of_backtracks_in_ls() { + _has_bits_[0] |= 0x00010000u; +} +inline void BopParameters::clear_has_max_number_of_backtracks_in_ls() { + _has_bits_[0] &= ~0x00010000u; +} +inline void BopParameters::clear_max_number_of_backtracks_in_ls() { + max_number_of_backtracks_in_ls_ = GOOGLE_LONGLONG(100000000); + clear_has_max_number_of_backtracks_in_ls(); +} +inline ::google::protobuf::int64 BopParameters::max_number_of_backtracks_in_ls() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_number_of_backtracks_in_ls) + return max_number_of_backtracks_in_ls_; +} +inline void BopParameters::set_max_number_of_backtracks_in_ls(::google::protobuf::int64 value) { + set_has_max_number_of_backtracks_in_ls(); + max_number_of_backtracks_in_ls_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_number_of_backtracks_in_ls) +} + +// optional bool use_lp_lns = 12 [default = true]; +inline bool BopParameters::has_use_lp_lns() const { + return (_has_bits_[0] & 0x00020000u) != 0; +} +inline void BopParameters::set_has_use_lp_lns() { + _has_bits_[0] |= 0x00020000u; +} +inline void BopParameters::clear_has_use_lp_lns() { + _has_bits_[0] &= ~0x00020000u; +} +inline void BopParameters::clear_use_lp_lns() { + use_lp_lns_ = true; + clear_has_use_lp_lns(); +} +inline bool BopParameters::use_lp_lns() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.use_lp_lns) + return use_lp_lns_; +} +inline void BopParameters::set_use_lp_lns(bool value) { + set_has_use_lp_lns(); + use_lp_lns_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.use_lp_lns) +} + +// optional bool use_sat_to_choose_lns_neighbourhood = 15 [default = true]; +inline bool BopParameters::has_use_sat_to_choose_lns_neighbourhood() const { + return (_has_bits_[0] & 0x00040000u) != 0; +} +inline void BopParameters::set_has_use_sat_to_choose_lns_neighbourhood() { + _has_bits_[0] |= 0x00040000u; +} +inline void BopParameters::clear_has_use_sat_to_choose_lns_neighbourhood() { + _has_bits_[0] &= ~0x00040000u; +} +inline void BopParameters::clear_use_sat_to_choose_lns_neighbourhood() { + use_sat_to_choose_lns_neighbourhood_ = true; + clear_has_use_sat_to_choose_lns_neighbourhood(); +} +inline bool BopParameters::use_sat_to_choose_lns_neighbourhood() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.use_sat_to_choose_lns_neighbourhood) + return use_sat_to_choose_lns_neighbourhood_; +} +inline void BopParameters::set_use_sat_to_choose_lns_neighbourhood(bool value) { + set_has_use_sat_to_choose_lns_neighbourhood(); + use_sat_to_choose_lns_neighbourhood_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.use_sat_to_choose_lns_neighbourhood) +} + +// optional int32 max_number_of_conflicts_for_quick_check = 16 [default = 10]; +inline bool BopParameters::has_max_number_of_conflicts_for_quick_check() const { + return (_has_bits_[0] & 0x00080000u) != 0; +} +inline void BopParameters::set_has_max_number_of_conflicts_for_quick_check() { + _has_bits_[0] |= 0x00080000u; +} +inline void BopParameters::clear_has_max_number_of_conflicts_for_quick_check() { + _has_bits_[0] &= ~0x00080000u; +} +inline void BopParameters::clear_max_number_of_conflicts_for_quick_check() { + max_number_of_conflicts_for_quick_check_ = 10; + clear_has_max_number_of_conflicts_for_quick_check(); +} +inline ::google::protobuf::int32 BopParameters::max_number_of_conflicts_for_quick_check() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_number_of_conflicts_for_quick_check) + return max_number_of_conflicts_for_quick_check_; +} +inline void BopParameters::set_max_number_of_conflicts_for_quick_check(::google::protobuf::int32 value) { + set_has_max_number_of_conflicts_for_quick_check(); + max_number_of_conflicts_for_quick_check_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_number_of_conflicts_for_quick_check) +} + +// optional bool use_symmetry = 17 [default = false]; +inline bool BopParameters::has_use_symmetry() const { + return (_has_bits_[0] & 0x00100000u) != 0; +} +inline void BopParameters::set_has_use_symmetry() { + _has_bits_[0] |= 0x00100000u; +} +inline void BopParameters::clear_has_use_symmetry() { + _has_bits_[0] &= ~0x00100000u; +} +inline void BopParameters::clear_use_symmetry() { + use_symmetry_ = false; + clear_has_use_symmetry(); +} +inline bool BopParameters::use_symmetry() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.use_symmetry) + return use_symmetry_; +} +inline void BopParameters::set_use_symmetry(bool value) { + set_has_use_symmetry(); + use_symmetry_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.use_symmetry) +} + +// optional bool exploit_symmetry_in_sat_first_solution = 40 [default = false]; +inline bool BopParameters::has_exploit_symmetry_in_sat_first_solution() const { + return (_has_bits_[0] & 0x00200000u) != 0; +} +inline void BopParameters::set_has_exploit_symmetry_in_sat_first_solution() { + _has_bits_[0] |= 0x00200000u; +} +inline void BopParameters::clear_has_exploit_symmetry_in_sat_first_solution() { + _has_bits_[0] &= ~0x00200000u; +} +inline void BopParameters::clear_exploit_symmetry_in_sat_first_solution() { + exploit_symmetry_in_sat_first_solution_ = false; + clear_has_exploit_symmetry_in_sat_first_solution(); +} +inline bool BopParameters::exploit_symmetry_in_sat_first_solution() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.exploit_symmetry_in_sat_first_solution) + return exploit_symmetry_in_sat_first_solution_; +} +inline void BopParameters::set_exploit_symmetry_in_sat_first_solution(bool value) { + set_has_exploit_symmetry_in_sat_first_solution(); + exploit_symmetry_in_sat_first_solution_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.exploit_symmetry_in_sat_first_solution) +} + +// optional int32 max_number_of_conflicts_in_random_solution_generation = 20 [default = 500]; +inline bool BopParameters::has_max_number_of_conflicts_in_random_solution_generation() const { + return (_has_bits_[0] & 0x00400000u) != 0; +} +inline void BopParameters::set_has_max_number_of_conflicts_in_random_solution_generation() { + _has_bits_[0] |= 0x00400000u; +} +inline void BopParameters::clear_has_max_number_of_conflicts_in_random_solution_generation() { + _has_bits_[0] &= ~0x00400000u; +} +inline void BopParameters::clear_max_number_of_conflicts_in_random_solution_generation() { + max_number_of_conflicts_in_random_solution_generation_ = 500; + clear_has_max_number_of_conflicts_in_random_solution_generation(); +} +inline ::google::protobuf::int32 BopParameters::max_number_of_conflicts_in_random_solution_generation() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_number_of_conflicts_in_random_solution_generation) + return max_number_of_conflicts_in_random_solution_generation_; +} +inline void BopParameters::set_max_number_of_conflicts_in_random_solution_generation(::google::protobuf::int32 value) { + set_has_max_number_of_conflicts_in_random_solution_generation(); + max_number_of_conflicts_in_random_solution_generation_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_number_of_conflicts_in_random_solution_generation) +} + +// optional int64 max_number_of_explored_assignments_per_try_in_ls = 21 [default = 10000]; +inline bool BopParameters::has_max_number_of_explored_assignments_per_try_in_ls() const { + return (_has_bits_[0] & 0x00800000u) != 0; +} +inline void BopParameters::set_has_max_number_of_explored_assignments_per_try_in_ls() { + _has_bits_[0] |= 0x00800000u; +} +inline void BopParameters::clear_has_max_number_of_explored_assignments_per_try_in_ls() { + _has_bits_[0] &= ~0x00800000u; +} +inline void BopParameters::clear_max_number_of_explored_assignments_per_try_in_ls() { + max_number_of_explored_assignments_per_try_in_ls_ = GOOGLE_LONGLONG(10000); + clear_has_max_number_of_explored_assignments_per_try_in_ls(); +} +inline ::google::protobuf::int64 BopParameters::max_number_of_explored_assignments_per_try_in_ls() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.max_number_of_explored_assignments_per_try_in_ls) + return max_number_of_explored_assignments_per_try_in_ls_; +} +inline void BopParameters::set_max_number_of_explored_assignments_per_try_in_ls(::google::protobuf::int64 value) { + set_has_max_number_of_explored_assignments_per_try_in_ls(); + max_number_of_explored_assignments_per_try_in_ls_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.max_number_of_explored_assignments_per_try_in_ls) +} + +// optional bool use_transposition_table_in_ls = 22 [default = true]; +inline bool BopParameters::has_use_transposition_table_in_ls() const { + return (_has_bits_[0] & 0x01000000u) != 0; +} +inline void BopParameters::set_has_use_transposition_table_in_ls() { + _has_bits_[0] |= 0x01000000u; +} +inline void BopParameters::clear_has_use_transposition_table_in_ls() { + _has_bits_[0] &= ~0x01000000u; +} +inline void BopParameters::clear_use_transposition_table_in_ls() { + use_transposition_table_in_ls_ = true; + clear_has_use_transposition_table_in_ls(); +} +inline bool BopParameters::use_transposition_table_in_ls() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.use_transposition_table_in_ls) + return use_transposition_table_in_ls_; +} +inline void BopParameters::set_use_transposition_table_in_ls(bool value) { + set_has_use_transposition_table_in_ls(); + use_transposition_table_in_ls_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.use_transposition_table_in_ls) +} + +// optional bool use_potential_one_flip_repairs_in_ls = 39 [default = false]; +inline bool BopParameters::has_use_potential_one_flip_repairs_in_ls() const { + return (_has_bits_[0] & 0x02000000u) != 0; +} +inline void BopParameters::set_has_use_potential_one_flip_repairs_in_ls() { + _has_bits_[0] |= 0x02000000u; +} +inline void BopParameters::clear_has_use_potential_one_flip_repairs_in_ls() { + _has_bits_[0] &= ~0x02000000u; +} +inline void BopParameters::clear_use_potential_one_flip_repairs_in_ls() { + use_potential_one_flip_repairs_in_ls_ = false; + clear_has_use_potential_one_flip_repairs_in_ls(); +} +inline bool BopParameters::use_potential_one_flip_repairs_in_ls() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.use_potential_one_flip_repairs_in_ls) + return use_potential_one_flip_repairs_in_ls_; +} +inline void BopParameters::set_use_potential_one_flip_repairs_in_ls(bool value) { + set_has_use_potential_one_flip_repairs_in_ls(); + use_potential_one_flip_repairs_in_ls_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.use_potential_one_flip_repairs_in_ls) +} + +// optional bool use_learned_binary_clauses_in_lp = 23 [default = true]; +inline bool BopParameters::has_use_learned_binary_clauses_in_lp() const { + return (_has_bits_[0] & 0x04000000u) != 0; +} +inline void BopParameters::set_has_use_learned_binary_clauses_in_lp() { + _has_bits_[0] |= 0x04000000u; +} +inline void BopParameters::clear_has_use_learned_binary_clauses_in_lp() { + _has_bits_[0] &= ~0x04000000u; +} +inline void BopParameters::clear_use_learned_binary_clauses_in_lp() { + use_learned_binary_clauses_in_lp_ = true; + clear_has_use_learned_binary_clauses_in_lp(); +} +inline bool BopParameters::use_learned_binary_clauses_in_lp() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.use_learned_binary_clauses_in_lp) + return use_learned_binary_clauses_in_lp_; +} +inline void BopParameters::set_use_learned_binary_clauses_in_lp(bool value) { + set_has_use_learned_binary_clauses_in_lp(); + use_learned_binary_clauses_in_lp_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.use_learned_binary_clauses_in_lp) +} + +// optional int32 number_of_solvers = 24 [default = 1]; +inline bool BopParameters::has_number_of_solvers() const { + return (_has_bits_[0] & 0x08000000u) != 0; +} +inline void BopParameters::set_has_number_of_solvers() { + _has_bits_[0] |= 0x08000000u; +} +inline void BopParameters::clear_has_number_of_solvers() { + _has_bits_[0] &= ~0x08000000u; +} +inline void BopParameters::clear_number_of_solvers() { + number_of_solvers_ = 1; + clear_has_number_of_solvers(); +} +inline ::google::protobuf::int32 BopParameters::number_of_solvers() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.number_of_solvers) + return number_of_solvers_; +} +inline void BopParameters::set_number_of_solvers(::google::protobuf::int32 value) { + set_has_number_of_solvers(); + number_of_solvers_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.number_of_solvers) +} + +// optional .operations_research.bop.BopParameters.ThreadSynchronizationType synchronization_type = 25 [default = NO_SYNCHRONIZATION]; +inline bool BopParameters::has_synchronization_type() const { + return (_has_bits_[0] & 0x10000000u) != 0; +} +inline void BopParameters::set_has_synchronization_type() { + _has_bits_[0] |= 0x10000000u; +} +inline void BopParameters::clear_has_synchronization_type() { + _has_bits_[0] &= ~0x10000000u; +} +inline void BopParameters::clear_synchronization_type() { + synchronization_type_ = 0; + clear_has_synchronization_type(); +} +inline ::operations_research::bop::BopParameters_ThreadSynchronizationType BopParameters::synchronization_type() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.synchronization_type) + return static_cast< ::operations_research::bop::BopParameters_ThreadSynchronizationType >(synchronization_type_); +} +inline void BopParameters::set_synchronization_type(::operations_research::bop::BopParameters_ThreadSynchronizationType value) { + assert(::operations_research::bop::BopParameters_ThreadSynchronizationType_IsValid(value)); + set_has_synchronization_type(); + synchronization_type_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.synchronization_type) +} + +// repeated .operations_research.bop.BopSolverOptimizerSet solver_optimizer_sets = 26; +inline int BopParameters::solver_optimizer_sets_size() const { + return solver_optimizer_sets_.size(); +} +inline void BopParameters::clear_solver_optimizer_sets() { + solver_optimizer_sets_.Clear(); +} +inline const ::operations_research::bop::BopSolverOptimizerSet& BopParameters::solver_optimizer_sets(int index) const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.solver_optimizer_sets) + return solver_optimizer_sets_.Get(index); +} +inline ::operations_research::bop::BopSolverOptimizerSet* BopParameters::mutable_solver_optimizer_sets(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.bop.BopParameters.solver_optimizer_sets) + return solver_optimizer_sets_.Mutable(index); +} +inline ::operations_research::bop::BopSolverOptimizerSet* BopParameters::add_solver_optimizer_sets() { + // @@protoc_insertion_point(field_add:operations_research.bop.BopParameters.solver_optimizer_sets) + return solver_optimizer_sets_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopSolverOptimizerSet >* +BopParameters::mutable_solver_optimizer_sets() { + // @@protoc_insertion_point(field_mutable_list:operations_research.bop.BopParameters.solver_optimizer_sets) + return &solver_optimizer_sets_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::bop::BopSolverOptimizerSet >& +BopParameters::solver_optimizer_sets() const { + // @@protoc_insertion_point(field_list:operations_research.bop.BopParameters.solver_optimizer_sets) + return solver_optimizer_sets_; +} + +// optional string default_solver_optimizer_sets = 33 [default = "methods:{type:LOCAL_SEARCH } methods:{type:RANDOM_FIRST_SOLUTION } methods:{type:LINEAR_RELAXATION } methods:{type:LP_FIRST_SOLUTION } methods:{type:OBJECTIVE_FIRST_SOLUTION } methods:{type:USER_GUIDED_FIRST_SOLUTION } methods:{type:RANDOM_CONSTRAINT_LNS_GUIDED_BY_LP } methods:{type:RANDOM_VARIABLE_LNS_GUIDED_BY_LP } methods:{type:RELATION_GRAPH_LNS } methods:{type:RELATION_GRAPH_LNS_GUIDED_BY_LP } methods:{type:RANDOM_CONSTRAINT_LNS } methods:{type:RANDOM_VARIABLE_LNS } methods:{type:SAT_CORE_BASED } methods:{type:COMPLETE_LNS } "]; +inline bool BopParameters::has_default_solver_optimizer_sets() const { + return (_has_bits_[0] & 0x40000000u) != 0; +} +inline void BopParameters::set_has_default_solver_optimizer_sets() { + _has_bits_[0] |= 0x40000000u; +} +inline void BopParameters::clear_has_default_solver_optimizer_sets() { + _has_bits_[0] &= ~0x40000000u; +} +inline void BopParameters::clear_default_solver_optimizer_sets() { + default_solver_optimizer_sets_.ClearToDefaultNoArena(_default_default_solver_optimizer_sets_); + clear_has_default_solver_optimizer_sets(); +} +inline const ::std::string& BopParameters::default_solver_optimizer_sets() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.default_solver_optimizer_sets) + return default_solver_optimizer_sets_.GetNoArena(_default_default_solver_optimizer_sets_); +} +inline void BopParameters::set_default_solver_optimizer_sets(const ::std::string& value) { + set_has_default_solver_optimizer_sets(); + default_solver_optimizer_sets_.SetNoArena(_default_default_solver_optimizer_sets_, value); + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.default_solver_optimizer_sets) +} +inline void BopParameters::set_default_solver_optimizer_sets(const char* value) { + set_has_default_solver_optimizer_sets(); + default_solver_optimizer_sets_.SetNoArena(_default_default_solver_optimizer_sets_, ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.bop.BopParameters.default_solver_optimizer_sets) +} +inline void BopParameters::set_default_solver_optimizer_sets(const char* value, size_t size) { + set_has_default_solver_optimizer_sets(); + default_solver_optimizer_sets_.SetNoArena(_default_default_solver_optimizer_sets_, + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.bop.BopParameters.default_solver_optimizer_sets) +} +inline ::std::string* BopParameters::mutable_default_solver_optimizer_sets() { + set_has_default_solver_optimizer_sets(); + // @@protoc_insertion_point(field_mutable:operations_research.bop.BopParameters.default_solver_optimizer_sets) + return default_solver_optimizer_sets_.MutableNoArena(_default_default_solver_optimizer_sets_); +} +inline ::std::string* BopParameters::release_default_solver_optimizer_sets() { + // @@protoc_insertion_point(field_release:operations_research.bop.BopParameters.default_solver_optimizer_sets) + clear_has_default_solver_optimizer_sets(); + return default_solver_optimizer_sets_.ReleaseNoArena(_default_default_solver_optimizer_sets_); +} +inline void BopParameters::set_allocated_default_solver_optimizer_sets(::std::string* default_solver_optimizer_sets) { + if (default_solver_optimizer_sets != NULL) { + set_has_default_solver_optimizer_sets(); + } else { + clear_has_default_solver_optimizer_sets(); + } + default_solver_optimizer_sets_.SetAllocatedNoArena(_default_default_solver_optimizer_sets_, default_solver_optimizer_sets); + // @@protoc_insertion_point(field_set_allocated:operations_research.bop.BopParameters.default_solver_optimizer_sets) +} + +// optional bool use_lp_strong_branching = 29 [default = false]; +inline bool BopParameters::has_use_lp_strong_branching() const { + return (_has_bits_[0] & 0x80000000u) != 0; +} +inline void BopParameters::set_has_use_lp_strong_branching() { + _has_bits_[0] |= 0x80000000u; +} +inline void BopParameters::clear_has_use_lp_strong_branching() { + _has_bits_[0] &= ~0x80000000u; +} +inline void BopParameters::clear_use_lp_strong_branching() { + use_lp_strong_branching_ = false; + clear_has_use_lp_strong_branching(); +} +inline bool BopParameters::use_lp_strong_branching() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.use_lp_strong_branching) + return use_lp_strong_branching_; +} +inline void BopParameters::set_use_lp_strong_branching(bool value) { + set_has_use_lp_strong_branching(); + use_lp_strong_branching_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.use_lp_strong_branching) +} + +// optional int32 decomposer_num_variables_threshold = 30 [default = 50]; +inline bool BopParameters::has_decomposer_num_variables_threshold() const { + return (_has_bits_[1] & 0x00000001u) != 0; +} +inline void BopParameters::set_has_decomposer_num_variables_threshold() { + _has_bits_[1] |= 0x00000001u; +} +inline void BopParameters::clear_has_decomposer_num_variables_threshold() { + _has_bits_[1] &= ~0x00000001u; +} +inline void BopParameters::clear_decomposer_num_variables_threshold() { + decomposer_num_variables_threshold_ = 50; + clear_has_decomposer_num_variables_threshold(); +} +inline ::google::protobuf::int32 BopParameters::decomposer_num_variables_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.decomposer_num_variables_threshold) + return decomposer_num_variables_threshold_; +} +inline void BopParameters::set_decomposer_num_variables_threshold(::google::protobuf::int32 value) { + set_has_decomposer_num_variables_threshold(); + decomposer_num_variables_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.decomposer_num_variables_threshold) +} + +// optional int32 num_bop_solvers_used_by_decomposition = 31 [default = 1]; +inline bool BopParameters::has_num_bop_solvers_used_by_decomposition() const { + return (_has_bits_[1] & 0x00000002u) != 0; +} +inline void BopParameters::set_has_num_bop_solvers_used_by_decomposition() { + _has_bits_[1] |= 0x00000002u; +} +inline void BopParameters::clear_has_num_bop_solvers_used_by_decomposition() { + _has_bits_[1] &= ~0x00000002u; +} +inline void BopParameters::clear_num_bop_solvers_used_by_decomposition() { + num_bop_solvers_used_by_decomposition_ = 1; + clear_has_num_bop_solvers_used_by_decomposition(); +} +inline ::google::protobuf::int32 BopParameters::num_bop_solvers_used_by_decomposition() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.num_bop_solvers_used_by_decomposition) + return num_bop_solvers_used_by_decomposition_; +} +inline void BopParameters::set_num_bop_solvers_used_by_decomposition(::google::protobuf::int32 value) { + set_has_num_bop_solvers_used_by_decomposition(); + num_bop_solvers_used_by_decomposition_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.num_bop_solvers_used_by_decomposition) +} + +// optional double decomposed_problem_min_time_in_seconds = 36 [default = 0]; +inline bool BopParameters::has_decomposed_problem_min_time_in_seconds() const { + return (_has_bits_[1] & 0x00000004u) != 0; +} +inline void BopParameters::set_has_decomposed_problem_min_time_in_seconds() { + _has_bits_[1] |= 0x00000004u; +} +inline void BopParameters::clear_has_decomposed_problem_min_time_in_seconds() { + _has_bits_[1] &= ~0x00000004u; +} +inline void BopParameters::clear_decomposed_problem_min_time_in_seconds() { + decomposed_problem_min_time_in_seconds_ = 0; + clear_has_decomposed_problem_min_time_in_seconds(); +} +inline double BopParameters::decomposed_problem_min_time_in_seconds() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.decomposed_problem_min_time_in_seconds) + return decomposed_problem_min_time_in_seconds_; +} +inline void BopParameters::set_decomposed_problem_min_time_in_seconds(double value) { + set_has_decomposed_problem_min_time_in_seconds(); + decomposed_problem_min_time_in_seconds_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.decomposed_problem_min_time_in_seconds) +} + +// optional int32 guided_sat_conflicts_chunk = 34 [default = 1000]; +inline bool BopParameters::has_guided_sat_conflicts_chunk() const { + return (_has_bits_[1] & 0x00000008u) != 0; +} +inline void BopParameters::set_has_guided_sat_conflicts_chunk() { + _has_bits_[1] |= 0x00000008u; +} +inline void BopParameters::clear_has_guided_sat_conflicts_chunk() { + _has_bits_[1] &= ~0x00000008u; +} +inline void BopParameters::clear_guided_sat_conflicts_chunk() { + guided_sat_conflicts_chunk_ = 1000; + clear_has_guided_sat_conflicts_chunk(); +} +inline ::google::protobuf::int32 BopParameters::guided_sat_conflicts_chunk() const { + // @@protoc_insertion_point(field_get:operations_research.bop.BopParameters.guided_sat_conflicts_chunk) + return guided_sat_conflicts_chunk_; +} +inline void BopParameters::set_guided_sat_conflicts_chunk(::google::protobuf::int32 value) { + set_has_guided_sat_conflicts_chunk(); + guided_sat_conflicts_chunk_ = value; + // @@protoc_insertion_point(field_set:operations_research.bop.BopParameters.guided_sat_conflicts_chunk) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace bop +} // namespace operations_research + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::operations_research::bop::BopOptimizerMethod_OptimizerType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::bop::BopOptimizerMethod_OptimizerType>() { + return ::operations_research::bop::BopOptimizerMethod_OptimizerType_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::bop::BopParameters_ThreadSynchronizationType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::bop::BopParameters_ThreadSynchronizationType>() { + return ::operations_research::bop::BopParameters_ThreadSynchronizationType_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fbop_2fbop_5fparameters_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/bop/bop_portfolio.h b/thirdparty/linux/include/ortools/bop/bop_portfolio.h new file mode 100644 index 0000000..557af1d --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_portfolio.h @@ -0,0 +1,202 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_BOP_PORTFOLIO_H_ +#define OR_TOOLS_BOP_BOP_PORTFOLIO_H_ + +#include "ortools/bop/bop_base.h" +#include "ortools/bop/bop_lns.h" +#include "ortools/bop/bop_parameters.pb.h" +#include "ortools/bop/bop_solution.h" +#include "ortools/bop/bop_types.h" +#include "ortools/glop/lp_solver.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/util/stats.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { +namespace bop { + +DEFINE_INT_TYPE(OptimizerIndex, int); +const OptimizerIndex kInvalidOptimizerIndex(-1); + +// Forward declaration. +class OptimizerSelector; + +// This class implements a portfolio optimizer. +// The portfolio currently includes all the following optimizers: +// - SAT_CORE_BASED +// - SAT_LINEAR_SEARCH +// - LINEAR_RELAXATION +// - LOCAL_SEARCH +// - RANDOM_FIRST_SOLUTION +// - RANDOM_CONSTRAINT_LNS +// - RANDOM_VARIABLE_LNS +// - COMPLETE_LNS +// - LP_FIRST_SOLUTION +// - OBJECTIVE_FIRST_SOLUTION +// - USER_GUIDED_FIRST_SOLUTION +// - FEASIBILITY_PUMP_FIRST_SOLUTION +// - RANDOM_CONSTRAINT_LNS_GUIDED_BY_LP +// - RANDOM_VARIABLE_LNS_GUIDED_BY_LP +// - RELATION_GRAPH_LNS +// - RELATION_GRAPH_LNS_GUIDED_BY_LP +// +// At each call of Optimize(), the portfolio optimizer selects the next +// optimizer to run and runs it. The selection is auto-adaptative, meaning that +// optimizers that succeeded more in the previous calls to Optimizer() are more +// likely to be selected. +class PortfolioOptimizer : public BopOptimizerBase { + public: + PortfolioOptimizer(const ProblemState& problem_state, + const BopParameters& parameters, + const BopSolverOptimizerSet& optimizer_set, + const std::string& name); + ~PortfolioOptimizer() override; + + bool ShouldBeRun(const ProblemState& problem_state) const override { + return true; + } + Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, LearnedInfo* learned_info, + TimeLimit* time_limit) override; + + private: + BopOptimizerBase::Status SynchronizeIfNeeded( + const ProblemState& problem_state); + void AddOptimizer(const LinearBooleanProblem& problem, + const BopParameters& parameters, + const BopOptimizerMethod& optimizer_method); + void CreateOptimizers(const LinearBooleanProblem& problem, + const BopParameters& parameters, + const BopSolverOptimizerSet& optimizer_set); + + std::unique_ptr random_; + int64 state_update_stamp_; + BopConstraintTerms objective_terms_; + std::unique_ptr selector_; + ITIVector optimizers_; + sat::SatSolver sat_propagator_; + BopParameters parameters_; + double lower_bound_; + double upper_bound_; + int number_of_consecutive_failing_optimizers_; +}; + +// This class is providing an adaptative selector for optimizers based on +// their past successes and deterministic time spent. +class OptimizerSelector { + public: + // Note that the list of optimizers is only used to get the names for + // debug purposes, the ownership of the optimizers is not transfered. + explicit OptimizerSelector( + const ITIVector& optimizers); + + // Selects the next optimizer to run based on the user defined order and + // history of success. Returns kInvalidOptimizerIndex if no optimizer is + // selectable and runnable (see the functions below). + // + // The optimizer is selected using the following algorithm (L being the + // sorted list of optimizers, and l the position of the last selected + // optimizer): + // a- If a new solution has been found by optimizer l, select the first + // optimizer l' in L, l' >= 0, that can run. + // b- If optimizer l didn't find a new solution, select the first + // optimizer l', with l' > l, such that its deterministic time spent + // since last solution is smaller than the deterministic time spent + // by any runnable optimizer in 1..l since last solution. + // If no such optimizer is available, go to option a. + OptimizerIndex SelectOptimizer(); + + // Updates the internal metrics to decide which optimizer to select. + // This method should be called each time the selected optimizer is run. + // + // The gain corresponds to the reward to assign to the solver; It could for + // instance be the difference in cost between the last and the current + // solution. + // + // The time spent corresponds to the time the optimizer spent; To make the + // behavior deterministic, it is recommanded to use the deterministic time + // instead of the elapsed time. + // + // The optimizers are sorted based on their score each time a new solution is + // found. + void UpdateScore(int64 gain, double time_spent); + + // Marks the given optimizer as not selectable until UpdateScore() is called + // with a positive gain. In which case, all optimizer will become selectable + // again. + void TemporarilyMarkOptimizerAsUnselectable(OptimizerIndex optimizer_index); + + // Sets whether or not an optimizer is "runnable". Like a non-selectable one, + // a non-runnable optimizer will never be returned by SelectOptimizer(). + // + // TODO(user): Maybe we should simply have the notion of selectability here + // and let the client handle the logic to decide what optimizer are selectable + // or not. + void SetOptimizerRunnability(OptimizerIndex optimizer_index, bool runable); + + // Returns statistics about the given optimizer. + std::string PrintStats(OptimizerIndex optimizer_index) const; + int NumCallsForOptimizer(OptimizerIndex optimizer_index) const; + + // Prints some debug information. Should not be used in production. + void DebugPrint() const; + + private: + // Updates internals when a solution has been found using the selected + // optimizer. + void NewSolutionFound(int64 gain); + + // Updates the deterministic time spent by the selected optimizer. + void UpdateDeterministicTime(double time_spent); + + // Sorts optimizers based on their scores. + void UpdateOrder(); + + struct RunInfo { + RunInfo(OptimizerIndex i, const std::string& n) + : optimizer_index(i), + name(n), + num_successes(0), + num_calls(0), + total_gain(0), + time_spent(0.0), + time_spent_since_last_solution(0), + runnable(true), + selectable(true), + score(0.0) {} + + bool RunnableAndSelectable() const { return runnable && selectable; } + + OptimizerIndex optimizer_index; + std::string name; + int num_successes; + int num_calls; + int64 total_gain; + double time_spent; + double time_spent_since_last_solution; + bool runnable; + bool selectable; + double score; + }; + + std::vector run_infos_; + ITIVector info_positions_; + int selected_index_; +}; + +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_PORTFOLIO_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_solution.h b/thirdparty/linux/include/ortools/bop/bop_solution.h new file mode 100644 index 0000000..dc8a884 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_solution.h @@ -0,0 +1,112 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_BOP_SOLUTION_H_ +#define OR_TOOLS_BOP_BOP_SOLUTION_H_ + +#include "ortools/bop/bop_types.h" +#include "ortools/sat/boolean_problem.h" +#include "ortools/sat/boolean_problem.pb.h" + +namespace operations_research { +namespace bop { +// A Bop solution is a boolean assignment for each variable of the +// problem. The cost value associated to the solution is the instantiation +// of the objective cost of the problem. +// Note that a solution might not be a feasible solution, i.e. might violate +// some constraints of the problem. The Check() method can be used to +// test the feasibility. +class BopSolution { + public: + BopSolution(const LinearBooleanProblem& problem, const std::string& name); + + void SetValue(VariableIndex var, bool value) { + recompute_cost_ = true; + recompute_is_feasible_ = true; + values_[var] = value; + } + + size_t Size() const { return values_.size(); } + bool Value(VariableIndex var) const { return values_[var]; } + const std::string& name() const { return name_; } + void set_name(const std::string& name) { name_ = name; } + + // Returns the objective cost of the solution. + // Note that this code is lazy but not incremental and might run in the + // problem size. Use with care during search. + int64 GetCost() const { + if (recompute_cost_) { + cost_ = ComputeCost(); + } + return cost_; + } + + // Returns the objective cost of the solution taking into account the problem + // cost scaling and offset. This is mainly useful for displaying the current + // problem cost, while internally, the algorithm works directly with the + // integer version of the cost returned by GetCost(). + double GetScaledCost() const { + return sat::AddOffsetAndScaleObjectiveValue(*problem_, + sat::Coefficient(GetCost())); + } + + // Returns true iff the solution is feasible. + // Note that this code is lazy but not incremental and might run in the + // problem size. Use with care during search. + bool IsFeasible() const { + if (recompute_is_feasible_) { + is_feasible_ = ComputeIsFeasible(); + } + return is_feasible_; + } + + // For range based iteration, i.e. for (const bool value : solution) {...}. + ITIVector::const_iterator begin() const { + return values_.begin(); + } + ITIVector::const_iterator end() const { + return values_.end(); + } + + // Returns true when the cost of the argument solution is strictly greater + // than the cost of the object. + // This is used to sort solutions. + bool operator<(const BopSolution& solution) const { + return IsFeasible() == solution.IsFeasible() + ? GetCost() < solution.GetCost() + : IsFeasible() > solution.IsFeasible(); + } + + private: + bool ComputeIsFeasible() const; + int64 ComputeCost() const; + + const LinearBooleanProblem* problem_; + std::string name_; + ITIVector values_; + + // Those are mutable because they behave as const values for a given solution + // but for performance reasons we want to be lazy on their computation, + // e.g. not compute the cost each time set_value() is called. + mutable bool recompute_cost_; + mutable bool recompute_is_feasible_; + mutable int64 cost_; + mutable bool is_feasible_; + + // Note that assign/copy are defined to allow usage of + // STL collections / algorithms. +}; + +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_SOLUTION_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_solver.h b/thirdparty/linux/include/ortools/bop/bop_solver.h new file mode 100644 index 0000000..00fab91 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_solver.h @@ -0,0 +1,104 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_BOP_SOLVER_H_ +#define OR_TOOLS_BOP_BOP_SOLVER_H_ + +// Solver for Boolean Optimization Problems built on top of the SAT solver. +// To optimize a problem the solver uses several optimization strategies like +// Local Search (LS), Large Neighborhood Search (LNS), and Linear +// Programming (LP). See bop_parameters.proto to tune the strategies. +// +// Note that the BopSolver usage is limited to: +// - Boolean variables, +// - Linear constraints and linear optimization objective, +// - Integral weights for both constraints and objective, +// - Minimization. +// To deal with maximization, integral variables and floating weights, one can +// use the bop::IntegralSolver. +// +// Usage example: +// const LinearBooleanProblem problem = BuildProblem(); +// BopSolver bop_solver(problem); +// BopParameters bop_parameters; +// bop_parameters.set_max_deterministic_time(10); +// bop_solver.SetParameters(bop_parameters); +// const BopSolveStatus solve_status = bop_solver.Solve(); +// if (solve_status == BopSolveStatus::OPTIMAL_SOLUTION_FOUND) { ... } + +#include +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/int_type.h" +#include "ortools/base/int_type_indexed_vector.h" +#include "ortools/bop/bop_base.h" +#include "ortools/bop/bop_parameters.pb.h" +#include "ortools/bop/bop_solution.h" +#include "ortools/bop/bop_types.h" +#include "ortools/glop/lp_solver.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/util/stats.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { +namespace bop { +// Solver of Boolean Optimization Problems based on Local Search. +class BopSolver { + public: + explicit BopSolver(const LinearBooleanProblem& problem); + virtual ~BopSolver(); + + // Parameters management. + void SetParameters(const BopParameters& parameters) { + parameters_ = parameters; + } + + // Returns the status of the optimization. + BopSolveStatus Solve(); + BopSolveStatus Solve(const BopSolution& first_solution); + + // Runs the solver with an external time limit. + BopSolveStatus SolveWithTimeLimit(TimeLimit* time_limit); + BopSolveStatus SolveWithTimeLimit(const BopSolution& first_solution, + TimeLimit* time_limit); + + const BopSolution& best_solution() const { return problem_state_.solution(); } + bool GetSolutionValue(VariableIndex var_id) const { + return problem_state_.solution().Value(var_id); + } + + // Returns the scaled best bound. + // In case of minimization (resp. maximization), the best bound is defined as + // the lower bound (resp. upper bound). + double GetScaledBestBound() const; + double GetScaledGap() const; + + private: + void UpdateParameters(); + BopSolveStatus InternalMonothreadSolver(TimeLimit* time_limit); + BopSolveStatus InternalMultithreadSolver(TimeLimit* time_limit); + + const LinearBooleanProblem& problem_; + ProblemState problem_state_; + BopParameters parameters_; + + mutable StatsGroup stats_; +}; +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_SOLVER_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_types.h b/thirdparty/linux/include/ortools/bop/bop_types.h new file mode 100644 index 0000000..fa82a76 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_types.h @@ -0,0 +1,89 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_BOP_TYPES_H_ +#define OR_TOOLS_BOP_BOP_TYPES_H_ + +#include "ortools/base/basictypes.h" +#include "ortools/base/int_type.h" +#include "ortools/base/int_type_indexed_vector.h" + +namespace operations_research { +namespace bop { +DEFINE_INT_TYPE(ConstraintIndex, int); +DEFINE_INT_TYPE(EntryIndex, int); +DEFINE_INT_TYPE(SearchIndex, int); +DEFINE_INT_TYPE(TermIndex, int); +DEFINE_INT_TYPE(VariableIndex, int); +DEFINE_INT_TYPE(SolverTimeStamp, int64); + +// Status of the solve of Bop. +enum class BopSolveStatus { + // The solver found the proven optimal solution. + OPTIMAL_SOLUTION_FOUND, + + // The solver found a solution, but it is not proven to be the optimal + // solution. + FEASIBLE_SOLUTION_FOUND, + + // The solver didn't find any solution. + NO_SOLUTION_FOUND, + + // The problem is infeasible. + INFEASIBLE_PROBLEM, + + // The problem is invalid. + INVALID_PROBLEM +}; + +inline std::string GetSolveStatusString(BopSolveStatus status) { + switch (status) { + case BopSolveStatus::OPTIMAL_SOLUTION_FOUND: + return "OPTIMAL_SOLUTION_FOUND"; + case BopSolveStatus::FEASIBLE_SOLUTION_FOUND: + return "FEASIBLE_SOLUTION_FOUND"; + case BopSolveStatus::NO_SOLUTION_FOUND: + return "NO_SOLUTION_FOUND"; + case BopSolveStatus::INFEASIBLE_PROBLEM: + return "INFEASIBLE_PROBLEM"; + case BopSolveStatus::INVALID_PROBLEM: + return "INVALID_PROBLEM"; + } + // Fallback. We don't use "default:" so the compiler will return an error + // if we forgot one enum case above. + return "UNKNOWN Status"; +} +inline std::ostream& operator<<(std::ostream& os, BopSolveStatus status) { + os << GetSolveStatusString(status); + return os; +} + +// TODO(user): Remove. +DEFINE_INT_TYPE(SparseIndex, int); +struct BopConstraintTerm { + BopConstraintTerm(VariableIndex _var_id, int64 _weight) + : var_id(_var_id), search_id(0), weight(_weight) {} + + VariableIndex var_id; + SearchIndex search_id; + int64 weight; + + bool operator<(const BopConstraintTerm& other) const { + return search_id < other.search_id; + } +}; +typedef ITIVector BopConstraintTerms; + +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_TYPES_H_ diff --git a/thirdparty/linux/include/ortools/bop/bop_util.h b/thirdparty/linux/include/ortools/bop/bop_util.h new file mode 100644 index 0000000..bc774e1 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/bop_util.h @@ -0,0 +1,90 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_BOP_UTIL_H_ +#define OR_TOOLS_BOP_BOP_UTIL_H_ + +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/bop/bop_base.h" +#include "ortools/bop/bop_solution.h" +#include "ortools/sat/sat_solver.h" + +namespace operations_research { +namespace bop { +// Loads the problem state into the sat_solver. If the problem has already been +// loaded in the sat_solver, fixed variables and objective bounds are updated. +// Returns the status of the load: +// - CONTINUE: State problem successfully loaded. +// - OPTIMAL_SOLUTION_FOUND: Solution is proved optimal. +// If a feasible solution exists, this load function imposes the solution +// to be strictly better. Then when SAT proves the problem is UNSAT, that +// actually means that the current solution is optimal. +// - INFEASIBLE: The problem is proved to be infeasible. +// Note that the sat_solver will be backtracked to the root level in order +// to add new constraints. +BopOptimizerBase::Status LoadStateProblemToSatSolver( + const ProblemState& problem_state, sat::SatSolver* sat_solver); + +// Extracts from the sat solver any new information about the problem. Note that +// the solver is not const because this function clears what is considered +// "new". +void ExtractLearnedInfoFromSatSolver(sat::SatSolver* solver, LearnedInfo* info); + +void SatAssignmentToBopSolution(const sat::VariablesAssignment& assignment, + BopSolution* solution); + +class AdaptiveParameterValue { + public: + // Initial value is in [0..1]. + explicit AdaptiveParameterValue(double initial_value); + + void Reset(); + void Increase(); + void Decrease(); + + double value() const { return value_; } + + private: + double value_; + int num_changes_; +}; + +class LubyAdaptiveParameterValue { + public: + // Initial value is in [0..1]. + explicit LubyAdaptiveParameterValue(double initial_value); + + void Reset(); + + void IncreaseParameter(); + void DecreaseParameter(); + + double GetParameterValue() const; + + void UpdateLuby(); + bool BoostLuby(); + int luby_value() const { return luby_value_; } + + private: + int luby_id_; + int luby_boost_; + int luby_value_; + + std::vector difficulties_; +}; +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_BOP_UTIL_H_ diff --git a/thirdparty/linux/include/ortools/bop/complete_optimizer.h b/thirdparty/linux/include/ortools/bop/complete_optimizer.h new file mode 100644 index 0000000..83cf663 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/complete_optimizer.h @@ -0,0 +1,73 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains some BopOptimizerBase implementations that are "complete" +// solvers. That is, they work on the full problem, and can solve the problem +// (and prove optimality) by themselves. Moreover, they can be run for short +// period of time and resumed later from the state they where left off. +// +// The idea is that it is worthwhile spending some time in these algorithms, +// because in some situation they can improve the current upper/lower bound or +// even solve the problem to optimality. +// +// Note(user): The GuidedSatFirstSolutionGenerator can also be used as a +// complete SAT solver provided that we keep running it after it has found a +// first solution. This is the default behavior of the kNotGuided policy. + +#ifndef OR_TOOLS_BOP_COMPLETE_OPTIMIZER_H_ +#define OR_TOOLS_BOP_COMPLETE_OPTIMIZER_H_ + +#include + +#include "ortools/bop/bop_base.h" +#include "ortools/bop/bop_solution.h" +#include "ortools/bop/bop_types.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/encoding.h" +#include "ortools/sat/sat_solver.h" + +namespace operations_research { +namespace bop { + +// TODO(user): Merge this with the code in sat/optimization.cc +class SatCoreBasedOptimizer : public BopOptimizerBase { + public: + explicit SatCoreBasedOptimizer(const std::string& name); + ~SatCoreBasedOptimizer() override; + + protected: + bool ShouldBeRun(const ProblemState& problem_state) const override; + Status Optimize(const BopParameters& parameters, + const ProblemState& problem_state, LearnedInfo* learned_info, + TimeLimit* time_limit) override; + + private: + BopOptimizerBase::Status SynchronizeIfNeeded( + const ProblemState& problem_state); + sat::SatSolver::Status SolveWithAssumptions(); + + int64 state_update_stamp_; + bool initialized_; + bool assumptions_already_added_; + sat::SatSolver solver_; + sat::Coefficient offset_; + sat::Coefficient lower_bound_; + sat::Coefficient upper_bound_; + sat::Coefficient stratified_lower_bound_; + std::deque repository_; + std::vector nodes_; +}; + +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_COMPLETE_OPTIMIZER_H_ diff --git a/thirdparty/linux/include/ortools/bop/integral_solver.h b/thirdparty/linux/include/ortools/bop/integral_solver.h new file mode 100644 index 0000000..2aedd46 --- /dev/null +++ b/thirdparty/linux/include/ortools/bop/integral_solver.h @@ -0,0 +1,75 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_BOP_INTEGRAL_SOLVER_H_ +#define OR_TOOLS_BOP_INTEGRAL_SOLVER_H_ + +#include "ortools/base/port.h" +#include "ortools/bop/bop_parameters.pb.h" +#include "ortools/bop/bop_types.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { +namespace bop { +// This class implements an Integer Programming solver, i.e. the solver solves +// problems with both integral and boolean variables, linear constraint and +// linear objective function. +class IntegralSolver { + public: + IntegralSolver(); + ~IntegralSolver() {} + + // Sets the solver parameters. + // See the proto for an extensive documentation. + void SetParameters(const BopParameters& parameters) { + parameters_ = parameters; + } + BopParameters parameters() const { return parameters_; } + + // Solves the given linear program and returns the solve status. + BopSolveStatus Solve(const glop::LinearProgram& linear_problem) + MUST_USE_RESULT; + BopSolveStatus SolveWithTimeLimit(const glop::LinearProgram& linear_problem, + TimeLimit* time_limit) MUST_USE_RESULT; + + // Same as Solve() but starts from the given solution. + // TODO(user): Change the API to accept a partial solution instead since the + // underlying solver supports it. + BopSolveStatus Solve(const glop::LinearProgram& linear_problem, + const glop::DenseRow& initial_solution) MUST_USE_RESULT; + BopSolveStatus SolveWithTimeLimit(const glop::LinearProgram& linear_problem, + const glop::DenseRow& initial_solution, + TimeLimit* time_limit) MUST_USE_RESULT; + + // Returns the objective value of the solution with its offset. + glop::Fractional objective_value() const { return objective_value_; } + + // Returns the best bound found so far. + glop::Fractional best_bound() const { return best_bound_; } + + // Returns the solution values. Note that the values only make sense when a + // solution is found. + const glop::DenseRow& variable_values() const { return variable_values_; } + + private: + BopParameters parameters_; + glop::DenseRow variable_values_; + glop::Fractional objective_value_; + glop::Fractional best_bound_; + + DISALLOW_COPY_AND_ASSIGN(IntegralSolver); +}; +} // namespace bop +} // namespace operations_research +#endif // OR_TOOLS_BOP_INTEGRAL_SOLVER_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/assignment.pb.h b/thirdparty/linux/include/ortools/constraint_solver/assignment.pb.h new file mode 100644 index 0000000..3bbaf70 --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/assignment.pb.h @@ -0,0 +1,1356 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/constraint_solver/assignment.proto + +#ifndef PROTOBUF_ortools_2fconstraint_5fsolver_2fassignment_2eproto__INCLUDED +#define PROTOBUF_ortools_2fconstraint_5fsolver_2fassignment_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); +void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); +void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + +class AssignmentProto; +class IntVarAssignment; +class IntervalVarAssignment; +class SequenceVarAssignment; +class WorkerInfo; + +// =================================================================== + +class IntVarAssignment : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.IntVarAssignment) */ { + public: + IntVarAssignment(); + virtual ~IntVarAssignment(); + + IntVarAssignment(const IntVarAssignment& from); + + inline IntVarAssignment& operator=(const IntVarAssignment& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const IntVarAssignment& default_instance(); + + void Swap(IntVarAssignment* other); + + // implements Message ---------------------------------------------- + + inline IntVarAssignment* New() const { return New(NULL); } + + IntVarAssignment* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const IntVarAssignment& from); + void MergeFrom(const IntVarAssignment& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(IntVarAssignment* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string var_id = 1; + void clear_var_id(); + static const int kVarIdFieldNumber = 1; + const ::std::string& var_id() const; + void set_var_id(const ::std::string& value); + void set_var_id(const char* value); + void set_var_id(const char* value, size_t size); + ::std::string* mutable_var_id(); + ::std::string* release_var_id(); + void set_allocated_var_id(::std::string* var_id); + + // optional int64 min = 2; + void clear_min(); + static const int kMinFieldNumber = 2; + ::google::protobuf::int64 min() const; + void set_min(::google::protobuf::int64 value); + + // optional int64 max = 3; + void clear_max(); + static const int kMaxFieldNumber = 3; + ::google::protobuf::int64 max() const; + void set_max(::google::protobuf::int64 value); + + // optional bool active = 4; + void clear_active(); + static const int kActiveFieldNumber = 4; + bool active() const; + void set_active(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.IntVarAssignment) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr var_id_; + ::google::protobuf::int64 min_; + ::google::protobuf::int64 max_; + bool active_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + + void InitAsDefaultInstance(); + static IntVarAssignment* default_instance_; +}; +// ------------------------------------------------------------------- + +class IntervalVarAssignment : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.IntervalVarAssignment) */ { + public: + IntervalVarAssignment(); + virtual ~IntervalVarAssignment(); + + IntervalVarAssignment(const IntervalVarAssignment& from); + + inline IntervalVarAssignment& operator=(const IntervalVarAssignment& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const IntervalVarAssignment& default_instance(); + + void Swap(IntervalVarAssignment* other); + + // implements Message ---------------------------------------------- + + inline IntervalVarAssignment* New() const { return New(NULL); } + + IntervalVarAssignment* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const IntervalVarAssignment& from); + void MergeFrom(const IntervalVarAssignment& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(IntervalVarAssignment* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string var_id = 1; + void clear_var_id(); + static const int kVarIdFieldNumber = 1; + const ::std::string& var_id() const; + void set_var_id(const ::std::string& value); + void set_var_id(const char* value); + void set_var_id(const char* value, size_t size); + ::std::string* mutable_var_id(); + ::std::string* release_var_id(); + void set_allocated_var_id(::std::string* var_id); + + // optional int64 start_min = 2; + void clear_start_min(); + static const int kStartMinFieldNumber = 2; + ::google::protobuf::int64 start_min() const; + void set_start_min(::google::protobuf::int64 value); + + // optional int64 start_max = 3; + void clear_start_max(); + static const int kStartMaxFieldNumber = 3; + ::google::protobuf::int64 start_max() const; + void set_start_max(::google::protobuf::int64 value); + + // optional int64 duration_min = 4; + void clear_duration_min(); + static const int kDurationMinFieldNumber = 4; + ::google::protobuf::int64 duration_min() const; + void set_duration_min(::google::protobuf::int64 value); + + // optional int64 duration_max = 5; + void clear_duration_max(); + static const int kDurationMaxFieldNumber = 5; + ::google::protobuf::int64 duration_max() const; + void set_duration_max(::google::protobuf::int64 value); + + // optional int64 end_min = 6; + void clear_end_min(); + static const int kEndMinFieldNumber = 6; + ::google::protobuf::int64 end_min() const; + void set_end_min(::google::protobuf::int64 value); + + // optional int64 end_max = 7; + void clear_end_max(); + static const int kEndMaxFieldNumber = 7; + ::google::protobuf::int64 end_max() const; + void set_end_max(::google::protobuf::int64 value); + + // optional int64 performed_min = 8; + void clear_performed_min(); + static const int kPerformedMinFieldNumber = 8; + ::google::protobuf::int64 performed_min() const; + void set_performed_min(::google::protobuf::int64 value); + + // optional int64 performed_max = 9; + void clear_performed_max(); + static const int kPerformedMaxFieldNumber = 9; + ::google::protobuf::int64 performed_max() const; + void set_performed_max(::google::protobuf::int64 value); + + // optional bool active = 10; + void clear_active(); + static const int kActiveFieldNumber = 10; + bool active() const; + void set_active(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.IntervalVarAssignment) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr var_id_; + ::google::protobuf::int64 start_min_; + ::google::protobuf::int64 start_max_; + ::google::protobuf::int64 duration_min_; + ::google::protobuf::int64 duration_max_; + ::google::protobuf::int64 end_min_; + ::google::protobuf::int64 end_max_; + ::google::protobuf::int64 performed_min_; + ::google::protobuf::int64 performed_max_; + bool active_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + + void InitAsDefaultInstance(); + static IntervalVarAssignment* default_instance_; +}; +// ------------------------------------------------------------------- + +class SequenceVarAssignment : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.SequenceVarAssignment) */ { + public: + SequenceVarAssignment(); + virtual ~SequenceVarAssignment(); + + SequenceVarAssignment(const SequenceVarAssignment& from); + + inline SequenceVarAssignment& operator=(const SequenceVarAssignment& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SequenceVarAssignment& default_instance(); + + void Swap(SequenceVarAssignment* other); + + // implements Message ---------------------------------------------- + + inline SequenceVarAssignment* New() const { return New(NULL); } + + SequenceVarAssignment* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SequenceVarAssignment& from); + void MergeFrom(const SequenceVarAssignment& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(SequenceVarAssignment* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string var_id = 1; + void clear_var_id(); + static const int kVarIdFieldNumber = 1; + const ::std::string& var_id() const; + void set_var_id(const ::std::string& value); + void set_var_id(const char* value); + void set_var_id(const char* value, size_t size); + ::std::string* mutable_var_id(); + ::std::string* release_var_id(); + void set_allocated_var_id(::std::string* var_id); + + // repeated int32 forward_sequence = 2; + int forward_sequence_size() const; + void clear_forward_sequence(); + static const int kForwardSequenceFieldNumber = 2; + ::google::protobuf::int32 forward_sequence(int index) const; + void set_forward_sequence(int index, ::google::protobuf::int32 value); + void add_forward_sequence(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + forward_sequence() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_forward_sequence(); + + // repeated int32 backward_sequence = 3; + int backward_sequence_size() const; + void clear_backward_sequence(); + static const int kBackwardSequenceFieldNumber = 3; + ::google::protobuf::int32 backward_sequence(int index) const; + void set_backward_sequence(int index, ::google::protobuf::int32 value); + void add_backward_sequence(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + backward_sequence() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_backward_sequence(); + + // repeated int32 unperformed = 4; + int unperformed_size() const; + void clear_unperformed(); + static const int kUnperformedFieldNumber = 4; + ::google::protobuf::int32 unperformed(int index) const; + void set_unperformed(int index, ::google::protobuf::int32 value); + void add_unperformed(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + unperformed() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_unperformed(); + + // optional bool active = 5; + void clear_active(); + static const int kActiveFieldNumber = 5; + bool active() const; + void set_active(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.SequenceVarAssignment) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr var_id_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > forward_sequence_; + mutable int _forward_sequence_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > backward_sequence_; + mutable int _backward_sequence_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > unperformed_; + mutable int _unperformed_cached_byte_size_; + bool active_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + + void InitAsDefaultInstance(); + static SequenceVarAssignment* default_instance_; +}; +// ------------------------------------------------------------------- + +class WorkerInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.WorkerInfo) */ { + public: + WorkerInfo(); + virtual ~WorkerInfo(); + + WorkerInfo(const WorkerInfo& from); + + inline WorkerInfo& operator=(const WorkerInfo& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const WorkerInfo& default_instance(); + + void Swap(WorkerInfo* other); + + // implements Message ---------------------------------------------- + + inline WorkerInfo* New() const { return New(NULL); } + + WorkerInfo* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const WorkerInfo& from); + void MergeFrom(const WorkerInfo& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(WorkerInfo* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 worker_id = 1; + void clear_worker_id(); + static const int kWorkerIdFieldNumber = 1; + ::google::protobuf::int32 worker_id() const; + void set_worker_id(::google::protobuf::int32 value); + + // optional string bns = 2; + void clear_bns(); + static const int kBnsFieldNumber = 2; + const ::std::string& bns() const; + void set_bns(const ::std::string& value); + void set_bns(const char* value); + void set_bns(const char* value, size_t size); + ::std::string* mutable_bns(); + ::std::string* release_bns(); + void set_allocated_bns(::std::string* bns); + + // @@protoc_insertion_point(class_scope:operations_research.WorkerInfo) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr bns_; + ::google::protobuf::int32 worker_id_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + + void InitAsDefaultInstance(); + static WorkerInfo* default_instance_; +}; +// ------------------------------------------------------------------- + +class AssignmentProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.AssignmentProto) */ { + public: + AssignmentProto(); + virtual ~AssignmentProto(); + + AssignmentProto(const AssignmentProto& from); + + inline AssignmentProto& operator=(const AssignmentProto& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const AssignmentProto& default_instance(); + + void Swap(AssignmentProto* other); + + // implements Message ---------------------------------------------- + + inline AssignmentProto* New() const { return New(NULL); } + + AssignmentProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const AssignmentProto& from); + void MergeFrom(const AssignmentProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(AssignmentProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .operations_research.IntVarAssignment int_var_assignment = 1; + int int_var_assignment_size() const; + void clear_int_var_assignment(); + static const int kIntVarAssignmentFieldNumber = 1; + const ::operations_research::IntVarAssignment& int_var_assignment(int index) const; + ::operations_research::IntVarAssignment* mutable_int_var_assignment(int index); + ::operations_research::IntVarAssignment* add_int_var_assignment(); + ::google::protobuf::RepeatedPtrField< ::operations_research::IntVarAssignment >* + mutable_int_var_assignment(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::IntVarAssignment >& + int_var_assignment() const; + + // repeated .operations_research.IntervalVarAssignment interval_var_assignment = 2; + int interval_var_assignment_size() const; + void clear_interval_var_assignment(); + static const int kIntervalVarAssignmentFieldNumber = 2; + const ::operations_research::IntervalVarAssignment& interval_var_assignment(int index) const; + ::operations_research::IntervalVarAssignment* mutable_interval_var_assignment(int index); + ::operations_research::IntervalVarAssignment* add_interval_var_assignment(); + ::google::protobuf::RepeatedPtrField< ::operations_research::IntervalVarAssignment >* + mutable_interval_var_assignment(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::IntervalVarAssignment >& + interval_var_assignment() const; + + // repeated .operations_research.SequenceVarAssignment sequence_var_assignment = 6; + int sequence_var_assignment_size() const; + void clear_sequence_var_assignment(); + static const int kSequenceVarAssignmentFieldNumber = 6; + const ::operations_research::SequenceVarAssignment& sequence_var_assignment(int index) const; + ::operations_research::SequenceVarAssignment* mutable_sequence_var_assignment(int index); + ::operations_research::SequenceVarAssignment* add_sequence_var_assignment(); + ::google::protobuf::RepeatedPtrField< ::operations_research::SequenceVarAssignment >* + mutable_sequence_var_assignment(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::SequenceVarAssignment >& + sequence_var_assignment() const; + + // optional .operations_research.IntVarAssignment objective = 3; + bool has_objective() const; + void clear_objective(); + static const int kObjectiveFieldNumber = 3; + const ::operations_research::IntVarAssignment& objective() const; + ::operations_research::IntVarAssignment* mutable_objective(); + ::operations_research::IntVarAssignment* release_objective(); + void set_allocated_objective(::operations_research::IntVarAssignment* objective); + + // optional .operations_research.WorkerInfo worker_info = 4; + bool has_worker_info() const; + void clear_worker_info(); + static const int kWorkerInfoFieldNumber = 4; + const ::operations_research::WorkerInfo& worker_info() const; + ::operations_research::WorkerInfo* mutable_worker_info(); + ::operations_research::WorkerInfo* release_worker_info(); + void set_allocated_worker_info(::operations_research::WorkerInfo* worker_info); + + // optional bool is_valid = 5; + void clear_is_valid(); + static const int kIsValidFieldNumber = 5; + bool is_valid() const; + void set_is_valid(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.AssignmentProto) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::RepeatedPtrField< ::operations_research::IntVarAssignment > int_var_assignment_; + ::google::protobuf::RepeatedPtrField< ::operations_research::IntervalVarAssignment > interval_var_assignment_; + ::google::protobuf::RepeatedPtrField< ::operations_research::SequenceVarAssignment > sequence_var_assignment_; + ::operations_research::IntVarAssignment* objective_; + ::operations_research::WorkerInfo* worker_info_; + bool is_valid_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fassignment_2eproto(); + + void InitAsDefaultInstance(); + static AssignmentProto* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// IntVarAssignment + +// optional string var_id = 1; +inline void IntVarAssignment::clear_var_id() { + var_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& IntVarAssignment::var_id() const { + // @@protoc_insertion_point(field_get:operations_research.IntVarAssignment.var_id) + return var_id_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void IntVarAssignment::set_var_id(const ::std::string& value) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.IntVarAssignment.var_id) +} +inline void IntVarAssignment::set_var_id(const char* value) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.IntVarAssignment.var_id) +} +inline void IntVarAssignment::set_var_id(const char* value, size_t size) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.IntVarAssignment.var_id) +} +inline ::std::string* IntVarAssignment::mutable_var_id() { + + // @@protoc_insertion_point(field_mutable:operations_research.IntVarAssignment.var_id) + return var_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* IntVarAssignment::release_var_id() { + // @@protoc_insertion_point(field_release:operations_research.IntVarAssignment.var_id) + + return var_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void IntVarAssignment::set_allocated_var_id(::std::string* var_id) { + if (var_id != NULL) { + + } else { + + } + var_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), var_id); + // @@protoc_insertion_point(field_set_allocated:operations_research.IntVarAssignment.var_id) +} + +// optional int64 min = 2; +inline void IntVarAssignment::clear_min() { + min_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntVarAssignment::min() const { + // @@protoc_insertion_point(field_get:operations_research.IntVarAssignment.min) + return min_; +} +inline void IntVarAssignment::set_min(::google::protobuf::int64 value) { + + min_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntVarAssignment.min) +} + +// optional int64 max = 3; +inline void IntVarAssignment::clear_max() { + max_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntVarAssignment::max() const { + // @@protoc_insertion_point(field_get:operations_research.IntVarAssignment.max) + return max_; +} +inline void IntVarAssignment::set_max(::google::protobuf::int64 value) { + + max_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntVarAssignment.max) +} + +// optional bool active = 4; +inline void IntVarAssignment::clear_active() { + active_ = false; +} +inline bool IntVarAssignment::active() const { + // @@protoc_insertion_point(field_get:operations_research.IntVarAssignment.active) + return active_; +} +inline void IntVarAssignment::set_active(bool value) { + + active_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntVarAssignment.active) +} + +// ------------------------------------------------------------------- + +// IntervalVarAssignment + +// optional string var_id = 1; +inline void IntervalVarAssignment::clear_var_id() { + var_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& IntervalVarAssignment::var_id() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.var_id) + return var_id_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void IntervalVarAssignment::set_var_id(const ::std::string& value) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.var_id) +} +inline void IntervalVarAssignment::set_var_id(const char* value) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.IntervalVarAssignment.var_id) +} +inline void IntervalVarAssignment::set_var_id(const char* value, size_t size) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.IntervalVarAssignment.var_id) +} +inline ::std::string* IntervalVarAssignment::mutable_var_id() { + + // @@protoc_insertion_point(field_mutable:operations_research.IntervalVarAssignment.var_id) + return var_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* IntervalVarAssignment::release_var_id() { + // @@protoc_insertion_point(field_release:operations_research.IntervalVarAssignment.var_id) + + return var_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void IntervalVarAssignment::set_allocated_var_id(::std::string* var_id) { + if (var_id != NULL) { + + } else { + + } + var_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), var_id); + // @@protoc_insertion_point(field_set_allocated:operations_research.IntervalVarAssignment.var_id) +} + +// optional int64 start_min = 2; +inline void IntervalVarAssignment::clear_start_min() { + start_min_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntervalVarAssignment::start_min() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.start_min) + return start_min_; +} +inline void IntervalVarAssignment::set_start_min(::google::protobuf::int64 value) { + + start_min_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.start_min) +} + +// optional int64 start_max = 3; +inline void IntervalVarAssignment::clear_start_max() { + start_max_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntervalVarAssignment::start_max() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.start_max) + return start_max_; +} +inline void IntervalVarAssignment::set_start_max(::google::protobuf::int64 value) { + + start_max_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.start_max) +} + +// optional int64 duration_min = 4; +inline void IntervalVarAssignment::clear_duration_min() { + duration_min_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntervalVarAssignment::duration_min() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.duration_min) + return duration_min_; +} +inline void IntervalVarAssignment::set_duration_min(::google::protobuf::int64 value) { + + duration_min_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.duration_min) +} + +// optional int64 duration_max = 5; +inline void IntervalVarAssignment::clear_duration_max() { + duration_max_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntervalVarAssignment::duration_max() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.duration_max) + return duration_max_; +} +inline void IntervalVarAssignment::set_duration_max(::google::protobuf::int64 value) { + + duration_max_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.duration_max) +} + +// optional int64 end_min = 6; +inline void IntervalVarAssignment::clear_end_min() { + end_min_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntervalVarAssignment::end_min() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.end_min) + return end_min_; +} +inline void IntervalVarAssignment::set_end_min(::google::protobuf::int64 value) { + + end_min_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.end_min) +} + +// optional int64 end_max = 7; +inline void IntervalVarAssignment::clear_end_max() { + end_max_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntervalVarAssignment::end_max() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.end_max) + return end_max_; +} +inline void IntervalVarAssignment::set_end_max(::google::protobuf::int64 value) { + + end_max_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.end_max) +} + +// optional int64 performed_min = 8; +inline void IntervalVarAssignment::clear_performed_min() { + performed_min_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntervalVarAssignment::performed_min() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.performed_min) + return performed_min_; +} +inline void IntervalVarAssignment::set_performed_min(::google::protobuf::int64 value) { + + performed_min_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.performed_min) +} + +// optional int64 performed_max = 9; +inline void IntervalVarAssignment::clear_performed_max() { + performed_max_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 IntervalVarAssignment::performed_max() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.performed_max) + return performed_max_; +} +inline void IntervalVarAssignment::set_performed_max(::google::protobuf::int64 value) { + + performed_max_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.performed_max) +} + +// optional bool active = 10; +inline void IntervalVarAssignment::clear_active() { + active_ = false; +} +inline bool IntervalVarAssignment::active() const { + // @@protoc_insertion_point(field_get:operations_research.IntervalVarAssignment.active) + return active_; +} +inline void IntervalVarAssignment::set_active(bool value) { + + active_ = value; + // @@protoc_insertion_point(field_set:operations_research.IntervalVarAssignment.active) +} + +// ------------------------------------------------------------------- + +// SequenceVarAssignment + +// optional string var_id = 1; +inline void SequenceVarAssignment::clear_var_id() { + var_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& SequenceVarAssignment::var_id() const { + // @@protoc_insertion_point(field_get:operations_research.SequenceVarAssignment.var_id) + return var_id_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SequenceVarAssignment::set_var_id(const ::std::string& value) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.SequenceVarAssignment.var_id) +} +inline void SequenceVarAssignment::set_var_id(const char* value) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.SequenceVarAssignment.var_id) +} +inline void SequenceVarAssignment::set_var_id(const char* value, size_t size) { + + var_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.SequenceVarAssignment.var_id) +} +inline ::std::string* SequenceVarAssignment::mutable_var_id() { + + // @@protoc_insertion_point(field_mutable:operations_research.SequenceVarAssignment.var_id) + return var_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* SequenceVarAssignment::release_var_id() { + // @@protoc_insertion_point(field_release:operations_research.SequenceVarAssignment.var_id) + + return var_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SequenceVarAssignment::set_allocated_var_id(::std::string* var_id) { + if (var_id != NULL) { + + } else { + + } + var_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), var_id); + // @@protoc_insertion_point(field_set_allocated:operations_research.SequenceVarAssignment.var_id) +} + +// repeated int32 forward_sequence = 2; +inline int SequenceVarAssignment::forward_sequence_size() const { + return forward_sequence_.size(); +} +inline void SequenceVarAssignment::clear_forward_sequence() { + forward_sequence_.Clear(); +} +inline ::google::protobuf::int32 SequenceVarAssignment::forward_sequence(int index) const { + // @@protoc_insertion_point(field_get:operations_research.SequenceVarAssignment.forward_sequence) + return forward_sequence_.Get(index); +} +inline void SequenceVarAssignment::set_forward_sequence(int index, ::google::protobuf::int32 value) { + forward_sequence_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.SequenceVarAssignment.forward_sequence) +} +inline void SequenceVarAssignment::add_forward_sequence(::google::protobuf::int32 value) { + forward_sequence_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.SequenceVarAssignment.forward_sequence) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SequenceVarAssignment::forward_sequence() const { + // @@protoc_insertion_point(field_list:operations_research.SequenceVarAssignment.forward_sequence) + return forward_sequence_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SequenceVarAssignment::mutable_forward_sequence() { + // @@protoc_insertion_point(field_mutable_list:operations_research.SequenceVarAssignment.forward_sequence) + return &forward_sequence_; +} + +// repeated int32 backward_sequence = 3; +inline int SequenceVarAssignment::backward_sequence_size() const { + return backward_sequence_.size(); +} +inline void SequenceVarAssignment::clear_backward_sequence() { + backward_sequence_.Clear(); +} +inline ::google::protobuf::int32 SequenceVarAssignment::backward_sequence(int index) const { + // @@protoc_insertion_point(field_get:operations_research.SequenceVarAssignment.backward_sequence) + return backward_sequence_.Get(index); +} +inline void SequenceVarAssignment::set_backward_sequence(int index, ::google::protobuf::int32 value) { + backward_sequence_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.SequenceVarAssignment.backward_sequence) +} +inline void SequenceVarAssignment::add_backward_sequence(::google::protobuf::int32 value) { + backward_sequence_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.SequenceVarAssignment.backward_sequence) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SequenceVarAssignment::backward_sequence() const { + // @@protoc_insertion_point(field_list:operations_research.SequenceVarAssignment.backward_sequence) + return backward_sequence_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SequenceVarAssignment::mutable_backward_sequence() { + // @@protoc_insertion_point(field_mutable_list:operations_research.SequenceVarAssignment.backward_sequence) + return &backward_sequence_; +} + +// repeated int32 unperformed = 4; +inline int SequenceVarAssignment::unperformed_size() const { + return unperformed_.size(); +} +inline void SequenceVarAssignment::clear_unperformed() { + unperformed_.Clear(); +} +inline ::google::protobuf::int32 SequenceVarAssignment::unperformed(int index) const { + // @@protoc_insertion_point(field_get:operations_research.SequenceVarAssignment.unperformed) + return unperformed_.Get(index); +} +inline void SequenceVarAssignment::set_unperformed(int index, ::google::protobuf::int32 value) { + unperformed_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.SequenceVarAssignment.unperformed) +} +inline void SequenceVarAssignment::add_unperformed(::google::protobuf::int32 value) { + unperformed_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.SequenceVarAssignment.unperformed) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SequenceVarAssignment::unperformed() const { + // @@protoc_insertion_point(field_list:operations_research.SequenceVarAssignment.unperformed) + return unperformed_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SequenceVarAssignment::mutable_unperformed() { + // @@protoc_insertion_point(field_mutable_list:operations_research.SequenceVarAssignment.unperformed) + return &unperformed_; +} + +// optional bool active = 5; +inline void SequenceVarAssignment::clear_active() { + active_ = false; +} +inline bool SequenceVarAssignment::active() const { + // @@protoc_insertion_point(field_get:operations_research.SequenceVarAssignment.active) + return active_; +} +inline void SequenceVarAssignment::set_active(bool value) { + + active_ = value; + // @@protoc_insertion_point(field_set:operations_research.SequenceVarAssignment.active) +} + +// ------------------------------------------------------------------- + +// WorkerInfo + +// optional int32 worker_id = 1; +inline void WorkerInfo::clear_worker_id() { + worker_id_ = 0; +} +inline ::google::protobuf::int32 WorkerInfo::worker_id() const { + // @@protoc_insertion_point(field_get:operations_research.WorkerInfo.worker_id) + return worker_id_; +} +inline void WorkerInfo::set_worker_id(::google::protobuf::int32 value) { + + worker_id_ = value; + // @@protoc_insertion_point(field_set:operations_research.WorkerInfo.worker_id) +} + +// optional string bns = 2; +inline void WorkerInfo::clear_bns() { + bns_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& WorkerInfo::bns() const { + // @@protoc_insertion_point(field_get:operations_research.WorkerInfo.bns) + return bns_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void WorkerInfo::set_bns(const ::std::string& value) { + + bns_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.WorkerInfo.bns) +} +inline void WorkerInfo::set_bns(const char* value) { + + bns_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.WorkerInfo.bns) +} +inline void WorkerInfo::set_bns(const char* value, size_t size) { + + bns_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.WorkerInfo.bns) +} +inline ::std::string* WorkerInfo::mutable_bns() { + + // @@protoc_insertion_point(field_mutable:operations_research.WorkerInfo.bns) + return bns_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* WorkerInfo::release_bns() { + // @@protoc_insertion_point(field_release:operations_research.WorkerInfo.bns) + + return bns_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void WorkerInfo::set_allocated_bns(::std::string* bns) { + if (bns != NULL) { + + } else { + + } + bns_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), bns); + // @@protoc_insertion_point(field_set_allocated:operations_research.WorkerInfo.bns) +} + +// ------------------------------------------------------------------- + +// AssignmentProto + +// repeated .operations_research.IntVarAssignment int_var_assignment = 1; +inline int AssignmentProto::int_var_assignment_size() const { + return int_var_assignment_.size(); +} +inline void AssignmentProto::clear_int_var_assignment() { + int_var_assignment_.Clear(); +} +inline const ::operations_research::IntVarAssignment& AssignmentProto::int_var_assignment(int index) const { + // @@protoc_insertion_point(field_get:operations_research.AssignmentProto.int_var_assignment) + return int_var_assignment_.Get(index); +} +inline ::operations_research::IntVarAssignment* AssignmentProto::mutable_int_var_assignment(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.AssignmentProto.int_var_assignment) + return int_var_assignment_.Mutable(index); +} +inline ::operations_research::IntVarAssignment* AssignmentProto::add_int_var_assignment() { + // @@protoc_insertion_point(field_add:operations_research.AssignmentProto.int_var_assignment) + return int_var_assignment_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::IntVarAssignment >* +AssignmentProto::mutable_int_var_assignment() { + // @@protoc_insertion_point(field_mutable_list:operations_research.AssignmentProto.int_var_assignment) + return &int_var_assignment_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::IntVarAssignment >& +AssignmentProto::int_var_assignment() const { + // @@protoc_insertion_point(field_list:operations_research.AssignmentProto.int_var_assignment) + return int_var_assignment_; +} + +// repeated .operations_research.IntervalVarAssignment interval_var_assignment = 2; +inline int AssignmentProto::interval_var_assignment_size() const { + return interval_var_assignment_.size(); +} +inline void AssignmentProto::clear_interval_var_assignment() { + interval_var_assignment_.Clear(); +} +inline const ::operations_research::IntervalVarAssignment& AssignmentProto::interval_var_assignment(int index) const { + // @@protoc_insertion_point(field_get:operations_research.AssignmentProto.interval_var_assignment) + return interval_var_assignment_.Get(index); +} +inline ::operations_research::IntervalVarAssignment* AssignmentProto::mutable_interval_var_assignment(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.AssignmentProto.interval_var_assignment) + return interval_var_assignment_.Mutable(index); +} +inline ::operations_research::IntervalVarAssignment* AssignmentProto::add_interval_var_assignment() { + // @@protoc_insertion_point(field_add:operations_research.AssignmentProto.interval_var_assignment) + return interval_var_assignment_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::IntervalVarAssignment >* +AssignmentProto::mutable_interval_var_assignment() { + // @@protoc_insertion_point(field_mutable_list:operations_research.AssignmentProto.interval_var_assignment) + return &interval_var_assignment_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::IntervalVarAssignment >& +AssignmentProto::interval_var_assignment() const { + // @@protoc_insertion_point(field_list:operations_research.AssignmentProto.interval_var_assignment) + return interval_var_assignment_; +} + +// repeated .operations_research.SequenceVarAssignment sequence_var_assignment = 6; +inline int AssignmentProto::sequence_var_assignment_size() const { + return sequence_var_assignment_.size(); +} +inline void AssignmentProto::clear_sequence_var_assignment() { + sequence_var_assignment_.Clear(); +} +inline const ::operations_research::SequenceVarAssignment& AssignmentProto::sequence_var_assignment(int index) const { + // @@protoc_insertion_point(field_get:operations_research.AssignmentProto.sequence_var_assignment) + return sequence_var_assignment_.Get(index); +} +inline ::operations_research::SequenceVarAssignment* AssignmentProto::mutable_sequence_var_assignment(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.AssignmentProto.sequence_var_assignment) + return sequence_var_assignment_.Mutable(index); +} +inline ::operations_research::SequenceVarAssignment* AssignmentProto::add_sequence_var_assignment() { + // @@protoc_insertion_point(field_add:operations_research.AssignmentProto.sequence_var_assignment) + return sequence_var_assignment_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::SequenceVarAssignment >* +AssignmentProto::mutable_sequence_var_assignment() { + // @@protoc_insertion_point(field_mutable_list:operations_research.AssignmentProto.sequence_var_assignment) + return &sequence_var_assignment_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::SequenceVarAssignment >& +AssignmentProto::sequence_var_assignment() const { + // @@protoc_insertion_point(field_list:operations_research.AssignmentProto.sequence_var_assignment) + return sequence_var_assignment_; +} + +// optional .operations_research.IntVarAssignment objective = 3; +inline bool AssignmentProto::has_objective() const { + return !_is_default_instance_ && objective_ != NULL; +} +inline void AssignmentProto::clear_objective() { + if (GetArenaNoVirtual() == NULL && objective_ != NULL) delete objective_; + objective_ = NULL; +} +inline const ::operations_research::IntVarAssignment& AssignmentProto::objective() const { + // @@protoc_insertion_point(field_get:operations_research.AssignmentProto.objective) + return objective_ != NULL ? *objective_ : *default_instance_->objective_; +} +inline ::operations_research::IntVarAssignment* AssignmentProto::mutable_objective() { + + if (objective_ == NULL) { + objective_ = new ::operations_research::IntVarAssignment; + } + // @@protoc_insertion_point(field_mutable:operations_research.AssignmentProto.objective) + return objective_; +} +inline ::operations_research::IntVarAssignment* AssignmentProto::release_objective() { + // @@protoc_insertion_point(field_release:operations_research.AssignmentProto.objective) + + ::operations_research::IntVarAssignment* temp = objective_; + objective_ = NULL; + return temp; +} +inline void AssignmentProto::set_allocated_objective(::operations_research::IntVarAssignment* objective) { + delete objective_; + objective_ = objective; + if (objective) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:operations_research.AssignmentProto.objective) +} + +// optional .operations_research.WorkerInfo worker_info = 4; +inline bool AssignmentProto::has_worker_info() const { + return !_is_default_instance_ && worker_info_ != NULL; +} +inline void AssignmentProto::clear_worker_info() { + if (GetArenaNoVirtual() == NULL && worker_info_ != NULL) delete worker_info_; + worker_info_ = NULL; +} +inline const ::operations_research::WorkerInfo& AssignmentProto::worker_info() const { + // @@protoc_insertion_point(field_get:operations_research.AssignmentProto.worker_info) + return worker_info_ != NULL ? *worker_info_ : *default_instance_->worker_info_; +} +inline ::operations_research::WorkerInfo* AssignmentProto::mutable_worker_info() { + + if (worker_info_ == NULL) { + worker_info_ = new ::operations_research::WorkerInfo; + } + // @@protoc_insertion_point(field_mutable:operations_research.AssignmentProto.worker_info) + return worker_info_; +} +inline ::operations_research::WorkerInfo* AssignmentProto::release_worker_info() { + // @@protoc_insertion_point(field_release:operations_research.AssignmentProto.worker_info) + + ::operations_research::WorkerInfo* temp = worker_info_; + worker_info_ = NULL; + return temp; +} +inline void AssignmentProto::set_allocated_worker_info(::operations_research::WorkerInfo* worker_info) { + delete worker_info_; + worker_info_ = worker_info; + if (worker_info) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:operations_research.AssignmentProto.worker_info) +} + +// optional bool is_valid = 5; +inline void AssignmentProto::clear_is_valid() { + is_valid_ = false; +} +inline bool AssignmentProto::is_valid() const { + // @@protoc_insertion_point(field_get:operations_research.AssignmentProto.is_valid) + return is_valid_; +} +inline void AssignmentProto::set_is_valid(bool value) { + + is_valid_ = value; + // @@protoc_insertion_point(field_set:operations_research.AssignmentProto.is_valid) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fconstraint_5fsolver_2fassignment_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/constraint_solver/constraint_solver.h b/thirdparty/linux/include/ortools/constraint_solver/constraint_solver.h new file mode 100644 index 0000000..dc18eff --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/constraint_solver.h @@ -0,0 +1,5388 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// Declaration of the core objects for the constraint solver. +// +// The literature around constraint programming is extremely dense but one +// can find some basic introductions in the following links: +// - http://en.wikipedia.org/wiki/Constraint_programming +// - http://kti.mff.cuni.cz/~bartak/constraints/index.html +// +// Here is a very simple Constraint Programming problem: +// +// Knowing that we see 56 legs and 20 heads, how many pheasants and rabbits +// are we looking at? +// +// Here is some simple Constraint Programming code to find out: +// +// void pheasant() { +// Solver s("pheasant"); +// IntVar* const p = s.MakeIntVar(0, 20, "pheasant")); +// IntVar* const r = s.MakeIntVar(0, 20, "rabbit")); +// IntExpr* const legs = s.MakeSum(s.MakeProd(p, 2), s.MakeProd(r, 4)); +// IntExpr* const heads = s.MakeSum(p, r); +// Constraint* const ct_legs = s.MakeEquality(legs, 56); +// Constraint* const ct_heads = s.MakeEquality(heads, 20); +// s.AddConstraint(ct_legs); +// s.AddConstraint(ct_heads); +// DecisionBuilder* const db = s.MakePhase(p, r, +// Solver::CHOOSE_FIRST_UNBOUND, +// Solver::ASSIGN_MIN_VALUE); +// s.NewSearch(db); +// CHECK(s.NextSolution()); +// LOG(INFO) << "rabbits -> " << r->Value() << ", pheasants -> " +// << p->Value(); +// LOG(INFO) << s.DebugString(); +// s.EndSearch(); +// } +// +// which outputs: +// +// rabbits -> 8, pheasants -> 12 +// Solver(name = "pheasant", +// state = OUTSIDE_SEARCH, +// branches = 0, +// fails = 0, +// decisions = 0 +// propagation loops = 11, +// demons Run = 25, +// Run time = 0 ms) +// +// + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ortools/base/commandlineflags.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/stringprintf.h" +#include "ortools/base/sysinfo.h" +#include "ortools/base/timer.h" +#include "ortools/base/map_util.h" +#include "ortools/base/hash.h" +#include "ortools/constraint_solver/solver_parameters.pb.h" +#include "ortools/util/piecewise_linear_function.h" +#include "ortools/util/sorted_interval_list.h" +#include "ortools/util/tuple_set.h" +#include "ortools/base/random.h" + +class File; + + +namespace operations_research { + +class Assignment; +class AssignmentProto; +class BaseObject; +class CpArgument; +class CpConstraint; +class CpIntegerExpression; +class CpIntervalVariable; +class CpModelLoader; +class CpModel; +class CpSequenceVariable; +class CastConstraint; +class Constraint; +class Decision; +class DecisionBuilder; +class DecisionVisitor; +class Demon; +class DemonProfiler; +class LocalSearchProfiler; +class Dimension; +class DisjunctiveConstraint; +class ExpressionCache; +class IntExpr; +class IntTupleSet; +class IntVar; +class IntVarAssignment; +class IntVarElement; +class IntervalVar; +class IntervalVarAssignment; +class IntervalVarElement; +class LocalSearchFilter; +class LocalSearchOperator; +class LocalSearchPhaseParameters; +class ModelCache; +class ModelVisitor; +class NoGoodManager; +class NoGoodTerm; +class OptimizeVar; +class Pack; +class PropagationBaseObject; +class PropagationMonitor; +class LocalSearchMonitor; +class Queue; +class RevBitMatrix; +class RevBitSet; +class Search; +class SearchLimit; +class SearchLimitParameters; +class SearchMonitor; +class SequenceVar; +class SequenceVarAssignment; +class SolutionCollector; +class SolutionPool; +class Solver; +class ConstraintSolverParameters; +class SymmetryBreaker; +struct StateInfo; +struct Trail; +template +class SimpleRevFIFO; + +// This struct holds all parameters for the default search. +// DefaultPhaseParameters is only used by Solver::MakeDefaultPhase methods. +// Note this is for advanced users only. +struct DefaultPhaseParameters { + public: + enum VariableSelection { + CHOOSE_MAX_SUM_IMPACT = 0, + CHOOSE_MAX_AVERAGE_IMPACT = 1, + CHOOSE_MAX_VALUE_IMPACT = 2, + }; + + enum ValueSelection { + SELECT_MIN_IMPACT = 0, + SELECT_MAX_IMPACT = 1, + }; + + enum DisplayLevel { NONE = 0, NORMAL = 1, VERBOSE = 2 }; + + // This parameter describes how the next variable to instantiate + // will be chosen. + VariableSelection var_selection_schema; + + // This parameter describes which value to select for a given var. + ValueSelection value_selection_schema; + + // Maximum number of intervals the initialization of impacts will scan + // per variable. + int initialization_splits; + + // The default phase will run heuristic periodically. This parameter + // indicates if we should run all heuristics, or a randomly selected + // one. + bool run_all_heuristics; + + // The distance in nodes between each run of the heuristics. A + // negative or null value will mean that we will not run heuristics + // at all. + int heuristic_period; + + // The failure limit for each heuristic that we run. + int heuristic_num_failures_limit; + + // Whether to keep the impact from the first search for other searches + // or to recompute the impact for each new search. + bool persistent_impact; + + // Seed used to initialize the random part in some heuristics. + int random_seed; + + // Automatic Restart Size. When diving down, the size of the search + // space disminishes. We maintain the minimal log of the size of the search + // space with the following behavior: + // - A failure is ignored (no null size). + // - A solution has a size of 1 (and a log of 0). + // Then when backtracking, if the current log of the size of the search space + // is greater than the minimizal log size recorded + 'restart_log_size', then + // the search is restarted from scratch. A parameter < 0 means no restart. + // A parameter of 0 indicates that we restart after each failure. + double restart_log_size; + + // This represents the amount of information displayed by the default search. + // NONE means no display, VERBOSE means extra information. + DisplayLevel display_level; + + // Should we use Nogoods when restarting. The default is false. + bool use_no_goods; + + // Should we use last conflict method. The default is false. + bool use_last_conflict; + + // When defined, this override the default impact based decision builder. + DecisionBuilder* decision_builder; + + DefaultPhaseParameters(); +}; + +///////////////////////////////////////////////////////////////////// +// +// Solver Class +// +// A solver represent the main computation engine. It implements the whole +// range of Constraint Programming protocols: +// - Reversibility +// - Propagation +// - Search +// +// Usually, a Constraint Programming code consists of +// - the creation of the Solver, +// - the creation of the decision variables of the model, +// - the creation of the constraints of the model and their addition to the +// solver() through the AddConstraint() method, +// - the creation of the main DecisionBuilder class, +// - the launch of the solve method with the above-created decision builder. +// +// For the time being, Solver is not MT_SAFE, nor MT_HOT. +///////////////////////////////////////////////////////////////////// +// +class Solver { + public: + // Holds semantic information stating that the 'expression' has been + // cast into 'variable' using the Var() method, and that + // 'maintainer' is responsible for maintaining the equality between + // 'variable' and 'expression'. + struct IntegerCastInfo { + IntegerCastInfo() + : variable(nullptr), expression(nullptr), maintainer(nullptr) {} + IntegerCastInfo(IntVar* const v, IntExpr* const e, Constraint* const c) + : variable(v), expression(e), maintainer(c) {} + IntVar* variable; + IntExpr* expression; + Constraint* maintainer; + }; + + // Number of priorities for demons. + static const int kNumPriorities = 3; + + // This enum describes the strategy used to select the next branching + // variable at each node during the search. + enum IntVarStrategy { + // The default behavior is CHOOSE_FIRST_UNBOUND. + INT_VAR_DEFAULT, + + // The simple selection is CHOOSE_FIRST_UNBOUND. + INT_VAR_SIMPLE, + + // Select the first unbound variable. + // Variables are considered in the order of the vector of IntVars used + // to create the selector. + CHOOSE_FIRST_UNBOUND, + + // Randomly select one of the remaining unbound variables. + CHOOSE_RANDOM, + + // Among unbound variables, select the variable with the smallest size, + // i.e. the smallest number of possible values. + // In case of tie, the selected variables is the one with the lowest min + // value. + // In case of tie, the first one is selected, first being defined by the + // order in the vector of IntVars used to create the selector. + CHOOSE_MIN_SIZE_LOWEST_MIN, + + // Among unbound variables, select the variable with the smallest size, + // i.e. the smallest number of possible values. + // In case of tie, the selected variables is the one with the highest min + // value. + // In case of tie, the first one is selected, first being defined by the + // order in the vector of IntVars used to create the selector. + CHOOSE_MIN_SIZE_HIGHEST_MIN, + + // Among unbound variables, select the variable with the smallest size, + // i.e. the smallest number of possible values. + // In case of tie, the selected variables is the one with the lowest max + // value. + // In case of tie, the first one is selected, first being defined by the + // order in the vector of IntVars used to create the selector. + CHOOSE_MIN_SIZE_LOWEST_MAX, + + // Among unbound variables, select the variable with the smallest size, + // i.e. the smallest number of possible values. + // In case of tie, the selected variables is the one with the highest max + // value. + // In case of tie, the first one is selected, first being defined by the + // order in the vector of IntVars used to create the selector. + CHOOSE_MIN_SIZE_HIGHEST_MAX, + + // Among unbound variables, select the variable with the smallest minimal + // value. + // In case of tie, the first one is selected, first being defined by the + // order in the vector of IntVars used to create the selector. + CHOOSE_LOWEST_MIN, + + // Among unbound variables, select the variable with the highest maximal + // value. + // In case of tie, the first one is selected, first being defined by the + // order in the vector of IntVars used to create the selector. + CHOOSE_HIGHEST_MAX, + + // Among unbound variables, select the variable with the smallest size. + // In case of tie, the first one is selected, first being defined by the + // order in the vector of IntVars used to create the selector. + CHOOSE_MIN_SIZE, + + // Among unbound variables, select the variable with the highest size. + // In case of tie, the first one is selected, first being defined by the + // order in the vector of IntVars used to create the selector. + CHOOSE_MAX_SIZE, + + // Among unbound variables, select the variable with the largest + // gap between the first and the second values of the domain. + CHOOSE_MAX_REGRET_ON_MIN, + + // Selects the next unbound variable on a path, the path being defined by + // the variables: var[i] corresponds to the index of the next of i. + CHOOSE_PATH, + }; + // TODO(user): add HIGHEST_MIN and LOWEST_MAX. + + // This enum describes the strategy used to select the next variable value to + // set. + enum IntValueStrategy { + // The default behavior is ASSIGN_MIN_VALUE. + INT_VALUE_DEFAULT, + + // The simple selection is ASSIGN_MIN_VALUE. + INT_VALUE_SIMPLE, + + // Selects the min value of the selected variable. + ASSIGN_MIN_VALUE, + + // Selects the max value of the selected variable. + ASSIGN_MAX_VALUE, + + // Selects randomly one of the possible values of the selected variable. + ASSIGN_RANDOM_VALUE, + + // Selects the first possible value which is the closest to the center + // of the domain of the selected variable. + // The center is defined as (min + max) / 2. + ASSIGN_CENTER_VALUE, + + // Split the domain in two around the center, and choose the lower + // part first. + SPLIT_LOWER_HALF, + + // Split the domain in two around the center, and choose the lower + // part first. + SPLIT_UPPER_HALF, + }; + + // This enum is used by Solver::MakePhase to specify how to select variables + // and values during the search. + // In Solver::MakePhase(const std::vector&, IntVarStrategy, + // IntValueStrategy), variables are selected first, and then the associated + // value. + // In Solver::MakePhase(const std::vector& vars, IndexEvaluator2, + // EvaluatorStrategy), the selection is done scanning every pair + // . The next selected pair is then the best among + // all possibilities, i.e. the pair with the smallest evaluation. + // As this is costly, two options are offered: static or dynamic evaluation. + enum EvaluatorStrategy { + // Pairs are compared at the first call of the selector, and results are + // cached. Next calls to the selector use the previous computation, and so + // are not up-to-date, e.g. some pairs may not be possible + // anymore due to propagation since the first to call. + CHOOSE_STATIC_GLOBAL_BEST, + + // Pairs are compared each time a variable is selected. That way all pairs + // are relevant and evaluation is accurate. + // This strategy runs in O(number-of-pairs) at each variable selection, + // versus O(1) in the static version. + CHOOSE_DYNAMIC_GLOBAL_BEST, + }; + + // Used for scheduling. Not yet implemented. + enum SequenceStrategy { + SEQUENCE_DEFAULT, + SEQUENCE_SIMPLE, + CHOOSE_MIN_SLACK_RANK_FORWARD, + CHOOSE_RANDOM_RANK_FORWARD, + }; + + // This enum describes the straregy used to select the next interval variable + // and its value to be fixed. + enum IntervalStrategy { + // The default is INTERVAL_SET_TIMES_FORWARD. + INTERVAL_DEFAULT, + // The simple is INTERVAL_SET_TIMES_FORWARD. + INTERVAL_SIMPLE, + // Selects the variable with the lowest starting time of all variables, + // and fixes its starting time to this lowest value. + INTERVAL_SET_TIMES_FORWARD, + // Selects the variable with the highest ending time of all variables, + // and fixes the ending time to this highest values. + INTERVAL_SET_TIMES_BACKWARD + }; + + // This enum is used in Solver::MakeOperator to specify the neighborhood to + // create. + enum LocalSearchOperators { + // Operator which reverves a sub-chain of a path. It is called TwoOpt + // because it breaks two arcs on the path; resulting paths are called + // two-optimal. + // Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 + // (where (1, 5) are first and last nodes of the path and can therefore not + // be moved): + // 1 -> [3 -> 2] -> 4 -> 5 + // 1 -> [4 -> 3 -> 2] -> 5 + // 1 -> 2 -> [4 -> 3] -> 5 + TWOOPT, + + // Relocate: OROPT and RELOCATE. + // Operator which moves a sub-chain of a path to another position; the + // specified chain length is the fixed length of the chains being moved. + // When this length is 1, the operator simply moves a node to another + // position. + // Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5, for a chain length + // of 2 (where (1, 5) are first and last nodes of the path and can + // therefore not be moved): + // 1 -> 4 -> [2 -> 3] -> 5 + // 1 -> [3 -> 4] -> 2 -> 5 + // + // Using Relocate with chain lengths of 1, 2 and 3 together is equivalent to + // the OrOpt operator on a path. The OrOpt operator is a limited version of + // 3Opt (breaks 3 arcs on a path). + OROPT, + + // Relocate neighborhood with length of 1 (see OROPT comment). + RELOCATE, + + // Operator which exchanges the positions of two nodes. + // Possible neighbors for the path 1 -> 2 -> 3 -> 4 -> 5 + // (where (1, 5) are first and last nodes of the path and can therefore not + // be moved): + // 1 -> [3] -> [2] -> 4 -> 5 + // 1 -> [4] -> 3 -> [2] -> 5 + // 1 -> 2 -> [4] -> [3] -> 5 + EXCHANGE, + + // Operator which cross exchanges the starting chains of 2 paths, including + // exchanging the whole paths. + // First and last nodes are not moved. + // Possible neighbors for the paths 1 -> 2 -> 3 -> 4 -> 5 and 6 -> 7 -> 8 + // (where (1, 5) and (6, 8) are first and last nodes of the paths and can + // therefore not be moved): + // 1 -> [7] -> 3 -> 4 -> 5 6 -> [2] -> 8 + // 1 -> [7] -> 4 -> 5 6 -> [2 -> 3] -> 8 + // 1 -> [7] -> 5 6 -> [2 -> 3 -> 4] -> 8 + CROSS, + + // Operator which inserts an inactive node into a path. + // Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive + // (where 1 and 4 are first and last nodes of the path) are: + // 1 -> [5] -> 2 -> 3 -> 4 + // 1 -> 2 -> [5] -> 3 -> 4 + // 1 -> 2 -> 3 -> [5] -> 4 + MAKEACTIVE, + + // Operator which makes path nodes inactive. + // Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are first + // and last nodes of the path) are: + // 1 -> 3 -> 4 with 2 inactive + // 1 -> 2 -> 4 with 3 inactive + MAKEINACTIVE, + + // Operator which makes a "chain" of path nodes inactive. + // Possible neighbors for the path 1 -> 2 -> 3 -> 4 (where 1 and 4 are first + // and last nodes of the path) are: + // 1 -> 3 -> 4 with 2 inactive + // 1 -> 2 -> 4 with 3 inactive + // 1 -> 4 with 2 and 3 inactive + MAKECHAININACTIVE, + + // Operator which replaces an active node by an inactive one. + // Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive + // (where 1 and 4 are first and last nodes of the path) are: + // 1 -> [5] -> 3 -> 4 with 2 inactive + // 1 -> 2 -> [5] -> 4 with 3 inactive + SWAPACTIVE, + + // Operator which makes an inactive node active and an active one inactive. + // It is similar to SwapActiveOperator excepts that it tries to insert the + // inactive node in all possible positions instead of just the position of + // the node made inactive. + // Possible neighbors for the path 1 -> 2 -> 3 -> 4 with 5 inactive + // (where 1 and 4 are first and last nodes of the path) are: + // 1 -> [5] -> 3 -> 4 with 2 inactive + // 1 -> 3 -> [5] -> 4 with 2 inactive + // 1 -> [5] -> 2 -> 4 with 3 inactive + // 1 -> 2 -> [5] -> 4 with 3 inactive + EXTENDEDSWAPACTIVE, + + // Operator which relaxes two sub-chains of three consecutive arcs each. + // Each sub-chain is defined by a start node and the next three arcs. Those + // six arcs are relaxed to build a new neighbor. + // PATHLNS explores all possible pairs of starting nodes and so defines + // n^2 neighbors, n being the number of nodes. + // Note that the two sub-chains can be part of the same path; they even may + // overlap. + PATHLNS, + + // Operator which relaxes one entire path and all unactive nodes, thus + // defining num_paths neighbors. + FULLPATHLNS, + + // Operator which relaxes all inactive nodes and one sub-chain of six + // consecutive arcs. That way the path can be improve by inserting inactive + // nodes or swaping arcs. + UNACTIVELNS, + + // Operator which defines one neighbor per variable. Each neighbor tries to + // increment by one the value of the corresponding variable. When a new + // solution is found the neighborhood is rebuilt from scratch, i.e. tries + // to increment values in the variable order. + // Consider for instance variables x and y. x is incremented 1 by 1 to its + // max, and when it is not possible to increment x anymore, y is incremented + // once. If this is a solution, then next neighbor tries to increment x. + INCREMENT, + + // Operator which defines a neighborhood to decrement values. + // The behavior is the same as INCREMENT, except values are decremented + // instead of incremented. + DECREMENT, + + // Operator which defines one neighbor per variable. Each neighbor relaxes + // one variable. + // When a new solution is found the neighborhood is rebuilt from scratch. + // Consider for instance variables x and y. First x is relaxed and the + // solver is looking for the best possible solution (with only x relaxed). + // Then y is relaxed, and the solver is looking for a new solution. + // If a new solution is found, then the next variable to be relaxed is x. + SIMPLELNS + }; + + // This enum is used in Solver::MakeOperator associated with an evaluator + // to specify the neighborhood to create. + enum EvaluatorLocalSearchOperators { + // Lin–Kernighan local search. + // While the accumulated local gain is positive, perform a 2opt or a 3opt + // move followed by a series of 2opt moves. Return a neighbor for which the + // global gain is positive. + LK, + + // Sliding TSP operator. + // Uses an exact dynamic programming algorithm to solve the TSP + // corresponding to path sub-chains. + // For a subchain 1 -> 2 -> 3 -> 4 -> 5 -> 6, solves the TSP on + // nodes A, 2, 3, 4, 5, where A is a merger of nodes 1 and 6 such that + // cost(A,i) = cost(1,i) and cost(i,A) = cost(i,6). + TSPOPT, + + // TSP-base LNS. + // Randomly merge consecutive nodes until n "meta"-nodes remain and solve + // the corresponding TSP. + // This is an "unlimited" neighborhood which must be stopped by search + // limits. To force diversification, the operator iteratively forces each + // node to serve as base of a meta-node. + TSPLNS + }; + + // This enum is used in Solver::MakeLocalSearchObjectiveFilter. It specifies + // the behavior of the objective filter to create. The goal is to define + // under which condition a move is accepted based on the current objective + // value. + enum LocalSearchFilterBound { + // Move is accepted when the current objective value >= objective.Min. + GE, + // Move is accepted when the current objective value <= objective.Max. + LE, + // Move is accepted when the current objective value is in the interval + // objective.Min .. objective.Max. + EQ + }; + + // This enum is used in Solver::MakeLocalSearchObjectiveFilter. It specifies + // the operation used in the objective to build the corresponding filter. + enum LocalSearchOperation { + // The objective is the sum of the variables defined in + // Solver::MakeLocalSearchObjectiveFilter. + SUM, + + // The objective is the product of the variables defined in + // Solver::MakeLocalSearchObjectiveFilter. + PROD, + + // The objective is the max of the variables defined in + // Solver::MakeLocalSearchObjectiveFilter. + MAX, + + // The objective is the min of the variables defined in + // Solver::MakeLocalSearchObjectiveFilter. + MIN + }; + + // This enum represents the three possible priorities for a demon in the + // Solver queue. + // Note this is for advanced users only. + enum DemonPriority { + // DELAYED_PRIORITY is the lowest priority: Demons will be processed after + // VAR_PRIORITY and NORMAL_PRIORITY demons. + DELAYED_PRIORITY = 0, + + // VAR_PRIORITY is between DELAYED_PRIORITY and NORMAL_PRIORITY. + VAR_PRIORITY = 1, + + // NORMAL_PRIORITY is the highest priority: Demons will be processed first. + NORMAL_PRIORITY = 2, + }; + + // This enum is used in Solver::MakeIntervalVarRelation to specify the + // temporal relation between the two intervals t1 and t2. + enum BinaryIntervalRelation { + // t1 ends after t2 end, i.e. End(t1) >= End(t2) + delay. + ENDS_AFTER_END, + + // t1 ends after t2 start, i.e. End(t1) >= Start(t2) + delay. + ENDS_AFTER_START, + + // t1 ends at t2 end, i.e. End(t1) == End(t2) + delay. + ENDS_AT_END, + + // t1 ends at t2 start, i.e. End(t1) == Start(t2) + delay. + ENDS_AT_START, + + // t1 starts after t2 end, i.e. Start(t1) >= End(t2) + delay. + STARTS_AFTER_END, + + // t1 starts after t2 start, i.e. Start(t1) >= Start(t2) + delay. + STARTS_AFTER_START, + + // t1 starts at t2 end, i.e. Start(t1) == End(t2) + delay. + STARTS_AT_END, + + // t1 starts at t2 start, i.e. Start(t1) == Start(t2) + delay. + STARTS_AT_START, + + // STARTS_AT_START and ENDS_AT_END at the same time. + // t1 starts at t2 start, i.e. Start(t1) == Start(t2) + delay. + // t1 ends at t2 end, i.e. End(t1) == End(t2). + STAYS_IN_SYNC + }; + + // This enum is used in Solver::MakeIntervalVarRelation to specify the + // temporal relation between an interval t and an integer d. + enum UnaryIntervalRelation { + // t ends after d, i.e. End(t) >= d. + ENDS_AFTER, + + // t ends at d, i.e. End(t) == d. + ENDS_AT, + + // t ends before d, i.e. End(t) <= d. + ENDS_BEFORE, + + // t starts after d, i.e. Start(t) >= d. + STARTS_AFTER, + + // t starts at d, i.e. Start(t) == d. + STARTS_AT, + + // t starts before d, i.e. Start(t) <= d. + STARTS_BEFORE, + + // STARTS_BEFORE and ENDS_AFTER at the same time, i.e. d is in t. + // t starts before d, i.e. Start(t) <= d. + // t ends after d, i.e. End(t) >= d. + CROSS_DATE, + + // STARTS_AFTER or ENDS_BEFORE, i.e. d is not in t. + // t starts after d, i.e. Start(t) >= d. + // t ends before d, i.e. End(t) <= d. + AVOID_DATE + }; + + // The Solver is responsible for creating the search tree. Thanks to the + // DecisionBuilder, it creates a new decision with two branches at each node: + // left and right. + // The DecisionModification enum is used to specify how the branch selector + // should behave. + enum DecisionModification { + // Keeps the default behavior, i.e. apply left branch first, and then right + // branch in case of backtracking. + NO_CHANGE, + + // Right branches are ignored. This is used to make the code faster when + // backtrack makes no sense or is not useful. + // This is faster as there is no need to create one new node per decision. + KEEP_LEFT, + + // Left branches are ignored. This is used to make the code faster when + // backtrack makes no sense or is not useful. + // This is faster as there is no need to create one new node per decision. + KEEP_RIGHT, + + // Backtracks to the previous decisions, i.e. left and right branches are + // not applied. + KILL_BOTH, + + // Applies right branch first. Left branch will be applied in case of + // backtracking. + SWITCH_BRANCHES + }; + + // This enum is used internally in private methods Solver::PushState and + // Solver::PopState to tag states in the search tree. + enum MarkerType { SENTINEL, SIMPLE_MARKER, CHOICE_POINT, REVERSIBLE_ACTION }; + + // This enum represents the state of the solver w.r.t. the search. + enum SolverState { + OUTSIDE_SEARCH, // Before search, after search. + IN_ROOT_NODE, // Executing the root node. + IN_SEARCH, // Executing the search code. + AT_SOLUTION, // After successful NextSolution and before EndSearch. + NO_MORE_SOLUTIONS, // After failed NextSolution and before EndSearch. + PROBLEM_INFEASIBLE // After search, the model is infeasible. + }; + + // Callback typedefs + typedef std::function IndexEvaluator1; + typedef std::function IndexEvaluator2; + typedef std::function IndexEvaluator3; + + typedef std::function IndexFilter1; + + typedef std::function Int64ToIntVar; + + typedef std::function& vars, + int64 first_unbound, int64 last_unbound)> + VariableIndexSelector; + + typedef std::function VariableValueSelector; + typedef std::function VariableValueComparator; + typedef std::function ObjectiveWatcher; + typedef std::function BranchSelector; + // TODO(user): wrap in swig. + typedef std::function Action; + typedef std::function Closure; + +// TODO(user): Remove all these SWIG protected code, move to .i. +#ifndef SWIG + typedef std::function + IntegerExpressionBuilder; + typedef std::function + ConstraintBuilder; + typedef std::function + IntervalVariableBuilder; + typedef std::function + SequenceVariableBuilder; +#endif // SWIG + + // Solver API + explicit Solver(const std::string& modelname); + Solver(const std::string& modelname, const ConstraintSolverParameters& parameters); + ~Solver(); + + // Stored Parameters. + ConstraintSolverParameters parameters() const { return parameters_; } + // Create a ConstraintSolverParameters proto with all the default values. + static ConstraintSolverParameters DefaultSolverParameters(); + + // reversibility + + // SaveValue() will save the value of the corresponding object. It must be + // called before modifying the object. The value will be restored upon + // backtrack. + template + void SaveValue(T* o) { + InternalSaveValue(o); + } + + // Registers the given object as being reversible. By calling this method, the + // caller gives ownership of the object to the solver, which will delete it + // when there is a backtrack out of the current state. + // + // Returns the argument for convenience: this way, the caller may directly + // invoke a constructor in the argument, without having to store the pointer + // first. + // + // This function is only for users that define their own subclasses of + // BaseObject: for all subclasses predefined in the library, the corresponding + // factory methods (e.g., MakeIntVar(...), MakeAllDifferent(...) already take + // care of the registration. + template + T* RevAlloc(T* object) { + return reinterpret_cast(SafeRevAlloc(object)); + } + + // Like RevAlloc() above, but for an array of objects: the array + // must have been allocated with the new[] operator. The entire array + // will be deleted when backtracking out of the current state. + // + // This method is valid for arrays of int, int64, uint64, bool, + // BaseObject*, IntVar*, IntExpr*, and Constraint*. + template + T* RevAllocArray(T* object) { + return reinterpret_cast(SafeRevAllocArray(object)); + } + + // propagation + + // Adds the constraint 'c' to the model. + // + // After calling this method, and until there is a backtrack that undoes the + // addition, any assignment of variables to values must satisfy the given + // constraint in order to be considered feasible. There are two fairly + // different use cases: + // + // - the most common use case is modeling: the given constraint is really part + // of the problem that the user is trying to solve. In this use case, + // AddConstraint is called outside of search (i.e., with state() == + // OUTSIDE_SEARCH). Most users should only use AddConstraint in this way. + // In this case, the constraint will belong to the model forever: it cannot + // not be removed by backtracking. + // + // - a rarer use case is that 'c' is not a real constraint of the model. It + // may be a constraint generated by a branching decision (a constraint whose + // goal is to restrict the search space), a symmetry breaking constraint (a + // constraint that does restrict the search space, but in a way that cannot + // have an impact on the quality of the solutions in the subtree), or an + // inferred constraint that, while having no semantic value to the model (it + // does not restrict the set of solutions), is worth having because we believe + // it may strengthen the propagation. In these cases, it happens that the + // constraint is added during the search (i.e., with state() == + // IN_SEARCH or state() == IN_ROOT_NODE). When a constraint is + // added during a search, it applies only to the subtree of the search tree + // rooted at the current node, and will be automatically removed by + // bracktracking. + // + // This method does not take ownership of the constraint. If the constraint + // has been created by any factory method (Solver::MakeXXX), it will + // automatically be deleted. However, power users who implement their own + // constraints should do: solver.AddConstraint(solver.RevAlloc(new + // MyConstraint(...)); + void AddConstraint(Constraint* const c); + // Adds the constraint 'c' to the solver and marks it as a cast + // constraint, that is, a constraint created calling Var() on an + // expression. This is used internally. + void AddCastConstraint(CastConstraint* const c, IntVar* const target_var, + IntExpr* const casted_expression); + + // @{ + // Solves the problem using the given DecisionBuilder and returns true if a + // solution was found and accepted. + // + // These methods are the ones most users should use to search for a solution. + // Note that the definition of 'solution' is subtle. A solution here is + // defined as a leaf of the search tree with respect to the given decision + // builder for which there is no failure. What this means is that, contrary to + // intuition, a solution may not have all variables of the model bound. It is + // the responsibility of the decision builder to keep returning decisions + // until all variables are indeed bound. The most extreme counterexample is + // calling Solve with a trivial decision builder whose Next() method always + // returns nullptr. In this case, Solve immediately returns 'true', since not + // assigning any variable to any value is a solution, unless the root node + // propagation discovers that the model is infeasible. + // + // This function must be called either from outside of search, + // or from within the Next() method of a decision builder. + // + // Solve will terminate whenever any of the following event arise: + // * A search monitor asks the solver to terminate the search by calling + // solver()->FinishCurrentSearch(). + // * A solution is found that is accepted by all search monitors, and none of + // the search monitors decides to search for another one. + // + // Upon search termination, there will be a series of backtracks all the way + // to the top level. This means that a user cannot expect to inspect the + // solution by querying variables after a call to Solve(): all the information + // will be lost. In order to do something with the solution, the user must + // either: + // * Use a search monitor that can process such a leaf. See, in particular, + // the SolutionCollector class. + // * Do not use Solve. Instead, use the more fine-grained approach using + // methods NewSearch(...), NextSolution(), and EndSearch(). + // + // @param db The decision builder that will generate the search tree. + // @param monitors A vector of search monitors that will be notified of + // various events during the search. In their reaction to these events, such + // monitors may influence the search. + bool Solve(DecisionBuilder* const db, + const std::vector& monitors); + bool Solve(DecisionBuilder* const db); + bool Solve(DecisionBuilder* const db, SearchMonitor* const m1); + bool Solve(DecisionBuilder* const db, SearchMonitor* const m1, + SearchMonitor* const m2); + bool Solve(DecisionBuilder* const db, SearchMonitor* const m1, + SearchMonitor* const m2, SearchMonitor* const m3); + bool Solve(DecisionBuilder* const db, SearchMonitor* const m1, + SearchMonitor* const m2, SearchMonitor* const m3, + SearchMonitor* const m4); + // @} + + // @{ + // Decomposed search. + // The code for a top level search should look like + // solver->NewSearch(db); + // while (solver->NextSolution()) { + // //.. use the current solution + // } + // solver()->EndSearch(); + + void NewSearch(DecisionBuilder* const db, + const std::vector& monitors); + void NewSearch(DecisionBuilder* const db); + void NewSearch(DecisionBuilder* const db, SearchMonitor* const m1); + void NewSearch(DecisionBuilder* const db, SearchMonitor* const m1, + SearchMonitor* const m2); + void NewSearch(DecisionBuilder* const db, SearchMonitor* const m1, + SearchMonitor* const m2, SearchMonitor* const m3); + void NewSearch(DecisionBuilder* const db, SearchMonitor* const m1, + SearchMonitor* const m2, SearchMonitor* const m3, + SearchMonitor* const m4); + + bool NextSolution(); + void RestartSearch(); + void EndSearch(); + // @} + + // SolveAndCommit using a decision builder and up to three + // search monitors, usually one for the objective, one for the limits + // and one to collect solutions. + // + // The difference between a SolveAndCommit() and a Solve() method + // call is the fact that SolveAndCommit will not backtrack all + // modifications at the end of the search. This method is only + // usable during the Next() method of a decision builder. + bool SolveAndCommit(DecisionBuilder* const db, + const std::vector& monitors); + bool SolveAndCommit(DecisionBuilder* const db); + bool SolveAndCommit(DecisionBuilder* const db, SearchMonitor* const m1); + bool SolveAndCommit(DecisionBuilder* const db, SearchMonitor* const m1, + SearchMonitor* const m2); + bool SolveAndCommit(DecisionBuilder* const db, SearchMonitor* const m1, + SearchMonitor* const m2, SearchMonitor* const m3); + + // Checks whether the given assignment satisfies all the relevant constraints. + bool CheckAssignment(Assignment* const assignment); + + // Checks whether adding this constraint will lead to an immediate + // failure. It will return false if the model is already + // inconsistent, or if adding the constraint makes it inconsistent. + bool CheckConstraint(Constraint* const constraint); + + // State of the solver. + SolverState state() const { return state_; } + + // Abandon the current branch in the search tree. A backtrack will follow. + void Fail(); + + // Exports the model to protobuf. This code will be called + // from inside the solver during the start of the search. + CpModel ExportModel() const; + // Exports the model to protobuf. Search monitors are useful to pass + // the objective and limits to the protobuf. + CpModel ExportModelWithSearchMonitors( + const std::vector& monitors) const; + // Exports the model to protobuf. Search monitors are useful to pass + // the objective and limits to the protobuf. + CpModel ExportModelWithSearchMonitorsAndDecisionBuilder( + const std::vector& monitors, + DecisionBuilder* const db) const; + // Loads the model into the solver, and returns true upon success. + bool LoadModel(const CpModel& proto); + // Loads the model into the solver, appends search monitors to monitors, + // and returns true upon success. + bool LoadModelWithSearchMonitors(const CpModel& proto, + std::vector* monitors); + // Upgrades the model to the latest version. + static bool UpgradeModel(CpModel* const proto); + // Get read only load context. LoadModel() or LoadModelWithSearchMonitors() + // must have beed called before. + const CpModelLoader* model_loader() const { return model_loader_.get(); } + +#if !defined(SWIG) + // Collects decision variables. + // All decision variables will be collected in 4 groups: + // - Main integer decision variables. + // - Secondary integer variables (that are derived integer variables that + // should be fixed like times of tasks after the order has been fixed). + // - Sequence variables. + // - Interval variables. + // + // From these 4 groups, one could write a decision builder: + // solver.Compose( + // solver.MakeDefaultPhase(primary_integer_variables), + // solver.MakePhase(sequence_variables, Solver::SEQUENCE_DEFAULT), + // solver.MakePhase(interval_variables, Solver::INTERVAL_DEFAULT), + // solver.MakePhase(secondary_integer_variables, Solver::INT_VAR_DEFAULT); + bool CollectDecisionVariables( + std::vector* const primary_integer_variables, + std::vector* const secondary_integer_variables, + std::vector* const sequence_variables, + std::vector* const interval_variables); + + ConstraintBuilder GetConstraintBuilder(const std::string& tag) const; + IntegerExpressionBuilder GetIntegerExpressionBuilder(const std::string& tag) const; + IntervalVariableBuilder GetIntervalVariableBuilder(const std::string& tag) const; + SequenceVariableBuilder GetSequenceVariableBuilder(const std::string& tag) const; +#endif // SWIG + +#if !defined(SWIG) + // When SaveValue() is not the best way to go, one can create a reversible + // action that will be called upon backtrack. The "fast" parameter + // indicates whether we need restore all values saved through SaveValue() + // before calling this method. + void AddBacktrackAction(Action a, bool fast); +#endif // !defined(SWIG) + + // misc debug std::string. + std::string DebugString() const; + + // Current memory usage in bytes + static int64 MemoryUsage(); + + + // The wall_time() in ms since the creation of the solver. + int64 wall_time() const; + + // The number of branches explored since the creation of the solver. + int64 branches() const { return branches_; } + + // The number of solutions found since the start of the search. + int64 solutions() const; + + // The number of demons executed during search for a given priority. + int64 demon_runs(DemonPriority p) const { return demon_runs_[p]; } + + // The number of failures encountered since the creation of the solver. + int64 failures() const { return fails_; } + + // The number of neighbors created. + int64 neighbors() const { return neighbors_; } + + // The number of filtered neighbors (neighbors accepted by filters). + int64 filtered_neighbors() const { return filtered_neighbors_; } + + // The number of accepted neighbors. + int64 accepted_neighbors() const { return accepted_neighbors_; } + + // The stamp indicates how many moves in the search tree we have performed. + // It is useful to detect if we need to update same lazy structures. + uint64 stamp() const; + + // The fail_stamp() is incremented after each backtrack. + uint64 fail_stamp() const; + + // ---------- Make Factory ---------- + + // All factories (MakeXXX methods) encapsulate creation of objects + // through RevAlloc(). Hence, the Solver used for allocating the + // returned object will retain ownership of the allocated memory. + // Destructors are called upon backtrack, or when the Solver is + // itself destructed. + + // ----- Int Variables and Constants ----- + + // MakeIntVar will create the best range based int var for the bounds given. + IntVar* MakeIntVar(int64 vmin, int64 vmax, const std::string& name); + + // MakeIntVar will create a variable with the given sparse domain. + IntVar* MakeIntVar(const std::vector& values, const std::string& name); + + // MakeIntVar will create a variable with the given sparse domain. + IntVar* MakeIntVar(const std::vector& values, const std::string& name); + + // MakeIntVar will create the best range based int var for the bounds given. + IntVar* MakeIntVar(int64 vmin, int64 vmax); + + // MakeIntVar will create a variable with the given sparse domain. + IntVar* MakeIntVar(const std::vector& values); + + // MakeIntVar will create a variable with the given sparse domain. + IntVar* MakeIntVar(const std::vector& values); + + // MakeBoolVar will create a variable with a {0, 1} domain. + IntVar* MakeBoolVar(const std::string& name); + + // MakeBoolVar will create a variable with a {0, 1} domain. + IntVar* MakeBoolVar(); + + // IntConst will create a constant expression. + IntVar* MakeIntConst(int64 val, const std::string& name); + + // IntConst will create a constant expression. + IntVar* MakeIntConst(int64 val); + + // This method will append the vector vars with 'var_count' variables + // having bounds vmin and vmax and having name "name" where is + // the index of the variable. + void MakeIntVarArray(int var_count, int64 vmin, int64 vmax, + const std::string& name, std::vector* vars); + // This method will append the vector vars with 'var_count' variables + // having bounds vmin and vmax and having no names. + void MakeIntVarArray(int var_count, int64 vmin, int64 vmax, + std::vector* vars); + // Same but allocates an array and returns it. + IntVar** MakeIntVarArray(int var_count, int64 vmin, int64 vmax, + const std::string& name); + + // This method will append the vector vars with 'var_count' boolean + // variables having name "name" where is the index of the + // variable. + void MakeBoolVarArray(int var_count, const std::string& name, + std::vector* vars); + // This method will append the vector vars with 'var_count' boolean + // variables having no names. + void MakeBoolVarArray(int var_count, std::vector* vars); + // Same but allocates an array and returns it. + IntVar** MakeBoolVarArray(int var_count, const std::string& name); + + // ----- Integer Expressions ----- + + // left + right. + IntExpr* MakeSum(IntExpr* const left, IntExpr* const right); + // expr + value. + IntExpr* MakeSum(IntExpr* const expr, int64 value); + // sum of all vars. + IntExpr* MakeSum(const std::vector& vars); + + // scalar product + IntExpr* MakeScalProd(const std::vector& vars, + const std::vector& coefs); + // scalar product + IntExpr* MakeScalProd(const std::vector& vars, + const std::vector& coefs); + + // left - right + IntExpr* MakeDifference(IntExpr* const left, IntExpr* const right); + // value - expr + IntExpr* MakeDifference(int64 value, IntExpr* const expr); + // -expr + IntExpr* MakeOpposite(IntExpr* const expr); + + // left * right + IntExpr* MakeProd(IntExpr* const left, IntExpr* const right); + // expr * value + IntExpr* MakeProd(IntExpr* const expr, int64 value); + + // expr / value (integer division) + IntExpr* MakeDiv(IntExpr* const expr, int64 value); + // numerator / denominator (integer division). Terms need to be positive. + IntExpr* MakeDiv(IntExpr* const numerator, IntExpr* const denominator); + + // |expr| + IntExpr* MakeAbs(IntExpr* const expr); + // expr * expr + IntExpr* MakeSquare(IntExpr* const expr); + // expr ^ n (n > 0) + IntExpr* MakePower(IntExpr* const expr, int64 n); + + // vals[expr] + IntExpr* MakeElement(const std::vector& vals, IntVar* const index); + // vals[expr] + IntExpr* MakeElement(const std::vector& vals, IntVar* const index); + + // Function-based element. The constraint takes ownership of + // callback The callback must be able to cope with any possible + // value in the domain of 'index' (potentially negative ones too). + IntExpr* MakeElement(IndexEvaluator1 values, IntVar* const index); + // Function based element. The constraint takes ownership of + // callback. The callback must be monotonic. It must be able to + // cope with any possible value in the domain of 'index' + // (potentially negative ones too). Furtermore, monotonicity is not + // checked. Thus giving a non monotonic function, or specifying an + // incorrect increasing parameter will result in undefined behavior. + IntExpr* MakeMonotonicElement(IndexEvaluator1 values, bool increasing, + IntVar* const index); + // 2D version of function-based element expression, values(expr1, expr2). + IntExpr* MakeElement(IndexEvaluator2 values, IntVar* const index1, + IntVar* const index2); + + // vars[expr] + IntExpr* MakeElement(const std::vector& vars, IntVar* const index); + +#if !defined(SWIG) + // vars(argument) + IntExpr* MakeElement(Int64ToIntVar vars, int64 range_start, int64 range_end, + IntVar* argument); +#endif // SWIG + + // Returns the expression expr such that vars[expr] == value. + // It assumes that vars are all different. + IntExpr* MakeIndexExpression(const std::vector& vars, int64 value); + + // Special cases with arrays of size two. + Constraint* MakeIfThenElseCt(IntVar* const condition, + IntExpr* const then_expr, + IntExpr* const else_expr, + IntVar* const target_var); + + // std::min(vars) + IntExpr* MakeMin(const std::vector& vars); + // std::min (left, right) + IntExpr* MakeMin(IntExpr* const left, IntExpr* const right); + // std::min(expr, val) + IntExpr* MakeMin(IntExpr* const expr, int64 val); + // std::min(expr, val) + IntExpr* MakeMin(IntExpr* const expr, int val); + + // std::max(vars) + IntExpr* MakeMax(const std::vector& vars); + // std::max(left, right) + IntExpr* MakeMax(IntExpr* const left, IntExpr* const right); + // std::max(expr, val) + IntExpr* MakeMax(IntExpr* const expr, int64 val); + // std::max(expr, val) + IntExpr* MakeMax(IntExpr* const expr, int val); + + // convex piecewise function. + IntExpr* MakeConvexPiecewiseExpr(IntExpr* e, int64 early_cost, + int64 early_date, int64 late_date, + int64 late_cost); + + // Semi continuous Expression (x <= 0 -> f(x) = 0; x > 0 -> f(x) = ax + b) + // a >= 0 and b >= 0 + IntExpr* MakeSemiContinuousExpr(IntExpr* const e, int64 fixed_charge, + int64 step); + + // General piecewise-linear function expression, built from f(x) where f is + // piecewise-linear. The resulting expression is f(expr). + // TODO(user): Investigate if we can merge all three piecewise linear + // expressions. +#ifndef SWIG + IntExpr* MakePiecewiseLinearExpr(IntExpr* expr, + const PiecewiseLinearFunction& f); +#endif + + // Modulo expression x % mod (with the python convention for modulo). + IntExpr* MakeModulo(IntExpr* const x, int64 mod); + + // Modulo expression x % mod (with the python convention for modulo). + IntExpr* MakeModulo(IntExpr* const x, IntExpr* const mod); + + // Conditional Expr condition ? expression : value + IntExpr* MakeConditionalExpression(IntVar* const condition, + IntExpr* const expression, int64 value); + + // ----- Constraints ----- + // This constraint always succeeds. + Constraint* MakeTrueConstraint(); + // This constraint always fails. + Constraint* MakeFalseConstraint(); + Constraint* MakeFalseConstraint(const std::string& explanation); + + // b == (v == c) + Constraint* MakeIsEqualCstCt(IntExpr* const v, int64 c, IntVar* const b); + // status var of (v == c) + IntVar* MakeIsEqualCstVar(IntExpr* const var, int64 value); + // b == (v1 == v2) + Constraint* MakeIsEqualCt(IntExpr* const v1, IntExpr* v2, IntVar* const b); + // status var of (v1 == v2) + IntVar* MakeIsEqualVar(IntExpr* const var, IntExpr* v2); + // left == right + Constraint* MakeEquality(IntExpr* const left, IntExpr* const right); + // expr == value + Constraint* MakeEquality(IntExpr* const expr, int64 value); + // expr == value + Constraint* MakeEquality(IntExpr* const expr, int value); + + // b == (v != c) + Constraint* MakeIsDifferentCstCt(IntExpr* const v, int64 c, IntVar* const b); + // status var of (v != c) + IntVar* MakeIsDifferentCstVar(IntExpr* const v, int64 c); + // status var of (v1 != v2) + IntVar* MakeIsDifferentVar(IntExpr* const v1, IntExpr* const v2); + // b == (v1 != v2) + Constraint* MakeIsDifferentCt(IntExpr* const v1, IntExpr* const v2, + IntVar* const b); + // left != right + Constraint* MakeNonEquality(IntExpr* const left, IntExpr* const right); + // expr != value + Constraint* MakeNonEquality(IntExpr* const expr, int64 value); + // expr != value + Constraint* MakeNonEquality(IntExpr* const expr, int value); + + // b == (v <= c) + Constraint* MakeIsLessOrEqualCstCt(IntExpr* const v, int64 c, + IntVar* const b); + // status var of (v <= c) + IntVar* MakeIsLessOrEqualCstVar(IntExpr* const v, int64 c); + // status var of (left <= right) + IntVar* MakeIsLessOrEqualVar(IntExpr* const left, IntExpr* const right); + // b == (left <= right) + Constraint* MakeIsLessOrEqualCt(IntExpr* const left, IntExpr* const right, + IntVar* const b); + // left <= right + Constraint* MakeLessOrEqual(IntExpr* const left, IntExpr* const right); + // expr <= value + Constraint* MakeLessOrEqual(IntExpr* const expr, int64 value); + // expr <= value + Constraint* MakeLessOrEqual(IntExpr* const expr, int value); + + // b == (v >= c) + Constraint* MakeIsGreaterOrEqualCstCt(IntExpr* const v, int64 c, + IntVar* const b); + // status var of (v >= c) + IntVar* MakeIsGreaterOrEqualCstVar(IntExpr* const v, int64 c); + // status var of (left >= right) + IntVar* MakeIsGreaterOrEqualVar(IntExpr* const left, IntExpr* const right); + // b == (left >= right) + Constraint* MakeIsGreaterOrEqualCt(IntExpr* const left, IntExpr* const right, + IntVar* const b); + // left >= right + Constraint* MakeGreaterOrEqual(IntExpr* const left, IntExpr* const right); + // expr >= value + Constraint* MakeGreaterOrEqual(IntExpr* const expr, int64 value); + // expr >= value + Constraint* MakeGreaterOrEqual(IntExpr* const expr, int value); + + // b == (v > c) + Constraint* MakeIsGreaterCstCt(IntExpr* const v, int64 c, IntVar* const b); + // status var of (v > c) + IntVar* MakeIsGreaterCstVar(IntExpr* const v, int64 c); + // status var of (left > right) + IntVar* MakeIsGreaterVar(IntExpr* const left, IntExpr* const right); + // b == (left > right) + Constraint* MakeIsGreaterCt(IntExpr* const left, IntExpr* const right, + IntVar* const b); + // left > right + Constraint* MakeGreater(IntExpr* const left, IntExpr* const right); + // expr > value + Constraint* MakeGreater(IntExpr* const expr, int64 value); + // expr > value + Constraint* MakeGreater(IntExpr* const expr, int value); + + // b == (v < c) + Constraint* MakeIsLessCstCt(IntExpr* const v, int64 c, IntVar* const b); + // status var of (v < c) + IntVar* MakeIsLessCstVar(IntExpr* const v, int64 c); + // status var of (left < right) + IntVar* MakeIsLessVar(IntExpr* const left, IntExpr* const right); + // b == (left < right) + Constraint* MakeIsLessCt(IntExpr* const left, IntExpr* const right, + IntVar* const b); + // left < right + Constraint* MakeLess(IntExpr* const left, IntExpr* const right); + // expr < value + Constraint* MakeLess(IntExpr* const expr, int64 value); + // expr < value + Constraint* MakeLess(IntExpr* const expr, int value); + + // Variation on arrays. + Constraint* MakeSumLessOrEqual(const std::vector& vars, int64 cst); + Constraint* MakeSumGreaterOrEqual(const std::vector& vars, + int64 cst); + Constraint* MakeSumEquality(const std::vector& vars, int64 cst); + Constraint* MakeSumEquality(const std::vector& vars, + IntVar* const var); + Constraint* MakeScalProdEquality(const std::vector& vars, + const std::vector& coefficients, + int64 cst); + Constraint* MakeScalProdEquality(const std::vector& vars, + const std::vector& coefficients, + int64 cst); + Constraint* MakeScalProdEquality(const std::vector& vars, + const std::vector& coefficients, + IntVar* const target); + Constraint* MakeScalProdEquality(const std::vector& vars, + const std::vector& coefficients, + IntVar* const target); + Constraint* MakeScalProdGreaterOrEqual(const std::vector& vars, + const std::vector& coefficients, + int64 cst); + Constraint* MakeScalProdGreaterOrEqual(const std::vector& vars, + const std::vector& coefficients, + int64 cst); + Constraint* MakeScalProdLessOrEqual(const std::vector& vars, + const std::vector& coefficients, + int64 cst); + Constraint* MakeScalProdLessOrEqual(const std::vector& vars, + const std::vector& coefficients, + int64 cst); + + Constraint* MakeMinEquality(const std::vector& vars, + IntVar* const var); + Constraint* MakeMaxEquality(const std::vector& vars, + IntVar* const var); + + Constraint* MakeElementEquality(const std::vector& vals, + IntVar* const index, IntVar* const target); + Constraint* MakeElementEquality(const std::vector& vals, + IntVar* const index, IntVar* const target); + Constraint* MakeElementEquality(const std::vector& vars, + IntVar* const index, IntVar* const target); + Constraint* MakeElementEquality(const std::vector& vars, + IntVar* const index, int64 target); + // Creates the constraint abs(var) == abs_var. + Constraint* MakeAbsEquality(IntVar* const var, IntVar* const abs_var); + // This constraint is a special case of the element constraint with + // an array of integer variables where the variables are all + // different and the index variable is constrained such that + // vars[index] == target. + Constraint* MakeIndexOfConstraint(const std::vector& vars, + IntVar* const index, int64 target); + + // This method is a specialized case of the MakeConstraintDemon + // method to call the InitiatePropagate of the constraint 'ct'. + Demon* MakeConstraintInitialPropagateCallback(Constraint* const ct); + // This method is a specialized case of the MakeConstraintDemon + // method to call the InitiatePropagate of the constraint 'ct' with + // low priority. + Demon* MakeDelayedConstraintInitialPropagateCallback(Constraint* const ct); +#if !defined(SWIG) + // Creates a demon from a callback. + Demon* MakeActionDemon(Action action); +#endif // !defined(SWIG) + // Creates a demon from a closure. + Demon* MakeClosureDemon(Closure closure); + + // ----- Between and related constraints ----- + + // (l <= v <= u) + Constraint* MakeBetweenCt(IntExpr* const v, int64 l, int64 u); + + // (v < l || v > u) + // This constraint is lazy as it will not make holes in the domain of + // variables. It will propagate only when expr->Min() >= l + // or expr->Max() <= u. + Constraint* MakeNotBetweenCt(IntExpr* const v, int64 l, int64 u); + + // b == (l <= v <= u) + Constraint* MakeIsBetweenCt(IntExpr* const v, int64 l, int64 u, + IntVar* const b); + IntVar* MakeIsBetweenVar(IntExpr* const v, int64 l, int64 u); + + // ----- Member and related constraints ----- + + // v in set. Propagation is lazy, i.e. this constraint does not + // creates holes in the domain of the variable. + Constraint* MakeMemberCt(IntExpr* const v, const std::vector& values); + Constraint* MakeMemberCt(IntExpr* const v, const std::vector& values); + + // v not in set. + Constraint* MakeNotMemberCt(IntExpr* const v, + const std::vector& values); + Constraint* MakeNotMemberCt(IntExpr* const v, const std::vector& values); + + // v should not be in the list of forbidden intervals [start[i]..end[i]]. + Constraint* MakeNotMemberCt(IntExpr* const v, std::vector starts, + std::vector ends); + // v should not be in the list of forbidden intervals [start[i]..end[i]]. + Constraint* MakeNotMemberCt(IntExpr* const v, std::vector starts, + std::vector ends); +#if !defined(SWIG) + // v should not be in the list of forbidden intervals. + Constraint* MakeNotMemberCt(IntExpr* v, SortedDisjointIntervalList intervals); +#endif // !defined(SWIG) + + // b == (v in set) + Constraint* MakeIsMemberCt(IntExpr* const v, const std::vector& values, + IntVar* const b); + Constraint* MakeIsMemberCt(IntExpr* const v, const std::vector& values, + IntVar* const b); + IntVar* MakeIsMemberVar(IntExpr* const v, const std::vector& values); + IntVar* MakeIsMemberVar(IntExpr* const v, const std::vector& values); + + // |{i | v[i] == value}| <= count + Constraint* MakeAtMost(std::vector v, int64 value, int64 count); + // |{i | v[i] == value}| == count + Constraint* MakeCount(const std::vector& v, int64 value, + int64 count); + // |{i | v[i] == value}| == count + Constraint* MakeCount(const std::vector& v, int64 value, + IntVar* const count); + + // Aggregated version of count: |{i | v[i] == values[j]}| == cards[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& values, + const std::vector& cards); + // Aggregated version of count: |{i | v[i] == values[j]}| == cards[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& values, + const std::vector& cards); + // Aggregated version of count: |{i | v[i] == j}| == cards[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& cards); + // Aggregated version of count with bounded cardinalities: + // forall j in 0 .. card_size - 1: card_min <= |{i | v[i] == j}| <= card_max + Constraint* MakeDistribute(const std::vector& vars, int64 card_min, + int64 card_max, int64 card_size); + // Aggregated version of count with bounded cardinalities: + // forall j in 0 .. card_size - 1: + // card_min[j] <= |{i | v[i] == j}| <= card_max[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& card_min, + const std::vector& card_max); + // Aggregated version of count with bounded cardinalities: + // forall j in 0 .. card_size - 1: + // card_min[j] <= |{i | v[i] == j}| <= card_max[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& card_min, + const std::vector& card_max); + // Aggregated version of count with bounded cardinalities: + // forall j in 0 .. card_size - 1: + // card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max); + // Aggregated version of count with bounded cardinalities: + // forall j in 0 .. card_size - 1: + // card_min[j] <= |{i | v[i] == values[j]}| <= card_max[j] + Constraint* MakeDistribute(const std::vector& vars, + const std::vector& values, + const std::vector& card_min, + const std::vector& card_max); + + // Deviation constraint: + // sum_i |n * vars[i] - total_sum| <= deviation_var and + // sum_i vars[i] == total_sum + // n = #vars + Constraint* MakeDeviation(const std::vector& vars, + IntVar* const deviation_var, int64 total_sum); + + // All variables are pairwise different. This corresponds to the + // stronger version of the propagation algorithm. + Constraint* MakeAllDifferent(const std::vector& vars); + + // All variables are pairwise different. If 'stronger_propagation' + // is true, stronger, and potentially slower propagation will + // occur. This API will be deprecated in the future. + Constraint* MakeAllDifferent(const std::vector& vars, + bool stronger_propagation); + + // All variables are pairwise different, unless they are assigned to + // the escape value. + Constraint* MakeAllDifferentExcept(const std::vector& vars, + int64 escape_value); + // TODO(user): Do we need a version with an array of escape + // values. + + // Creates a constraint binding the arrays of variables "vars" and + // "sorted_vars": sorted_vars[0] must be equal to the minimum of all + // variables in vars, and so on: the value of sorted_vars[i] must be + // equal to the i-th value of variables invars. + // + // This constraint propagate in both directions: from "vars" to + // "sorted_vars" and vice-versa. + // + // Behind the scenes, this constraint maintains that: + // - sorted is always increasing. + // - whatever the values of vars, there exists a permutation that + // injects its values into the sorted variables. + // + // For more info, please have a look at: + // https://mpi-inf.mpg.de/~mehlhorn/ftp/Mehlhorn-Thiel.pdf + Constraint* MakeSortingConstraint(const std::vector& vars, + const std::vector& sorted); + // TODO(user): Add void MakeSortedArray(const std::vector& vars, + // std::vector* const sorted); + + // Creates a constraint that enforces that left is lexicographically less + // than right. + Constraint* MakeLexicalLess(const std::vector& left, + const std::vector& right); + + // Creates a constraint that enforces that left is lexicographically less + // or equal than right. + Constraint* MakeLexicalLessOrEqual(const std::vector& left, + const std::vector& right); + + // Creates a constraint that enforces that 'left' and 'right' both + // represent permutations of [0..left.size()-1], and that 'right' is + // the inverse permutation of 'left', i.e. for all i in + // [0..left.size()-1], right[left[i]] = i. + Constraint* MakeInversePermutationConstraint( + const std::vector& left, const std::vector& right); + + // Creates a constraint that binds the index variable to the index of the + // first variable with the maximum value. + Constraint* MakeIndexOfFirstMaxValueConstraint( + IntVar* index, const std::vector& vars); + + // Creates a constraint that binds the index variable to the index of the + // first variable with the minimum value. + Constraint* MakeIndexOfFirstMinValueConstraint( + IntVar* index, const std::vector& vars); + + // Creates a constraint that states that all variables in the first + // vector are different from all variables from the second + // group. Thus the set of values in the first vector does not + // intersect the set of values in the second vector. + Constraint* MakeNullIntersect(const std::vector& first_vars, + const std::vector& second_vars); + + // Creates a constraint that states that all variables in the first + // vector are different from all variables from the second group, + // unless they are assigned to the escape value. Thus the set of + // values in the first vector minus the escape value does not + // intersect the set of values in the second vector. + Constraint* MakeNullIntersectExcept(const std::vector& first_vars, + const std::vector& second_vars, + int64 escape_value); + + // TODO(user): Implement MakeAllNullIntersect taking an array of + // variable vectors. + + // Prevent cycles, nexts variables representing the next in the chain. + // Active variables indicate if the corresponding next variable is active; + // this could be useful to model unperformed nodes in a routing problem. + // A callback can be added to specify sink values (by default sink values + // are values >= vars.size()). Ownership of the callback is passed to the + // constraint. + // If assume_paths is either not specified or true, the constraint assumes the + // 'next' variables represent paths (and performs a faster propagation); + // otherwise the constraint assumes the 'next' variables represent a forest. + Constraint* MakeNoCycle(const std::vector& nexts, + const std::vector& active, + IndexFilter1 sink_handler = nullptr); + Constraint* MakeNoCycle(const std::vector& nexts, + const std::vector& active, + IndexFilter1 sink_handler, bool assume_paths); + + // Force the nexts() variable to create a complete hamiltonian path. + Constraint* MakeCircuit(const std::vector& nexts); + + // Force the nexts() variable to create a complete hamiltonian path + // for those that do not loop upon themselves. + Constraint* MakeSubCircuit(const std::vector& nexts); + + // Creates a constraint which accumulates values along a path such that: + // cumuls[next[i]] = cumuls[i] + transits[i]. + // Active variables indicate if the corresponding next variable is active; + // this could be useful to model unperformed nodes in a routing problem. + Constraint* MakePathCumul(const std::vector& nexts, + const std::vector& active, + const std::vector& cumuls, + const std::vector& transits); + // Delayed version of the same constraint: propagation on the nexts variables + // is delayed until all constraints have propagated. + // TODO(user): Merge with other path-cumuls constraints. + Constraint* MakeDelayedPathCumul(const std::vector& nexts, + const std::vector& active, + const std::vector& cumuls, + const std::vector& transits); + // Creates a constraint which accumulates values along a path such that: + // cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]). + // Active variables indicate if the corresponding next variable is active; + // this could be useful to model unperformed nodes in a routing problem. + // Ownership of transit_evaluator is taken and it must be a repeatable + // callback. + Constraint* MakePathCumul(const std::vector& nexts, + const std::vector& active, + const std::vector& cumuls, + IndexEvaluator2 transit_evaluator); + + // Creates a constraint which accumulates values along a path such that: + // cumuls[next[i]] = cumuls[i] + transit_evaluator(i, next[i]) + slacks[i]. + // Active variables indicate if the corresponding next variable is active; + // this could be useful to model unperformed nodes in a routing problem. + // Ownership of transit_evaluator is taken and it must be a repeatable + // callback. + Constraint* MakePathCumul(const std::vector& nexts, + const std::vector& active, + const std::vector& cumuls, + const std::vector& slacks, + IndexEvaluator2 transit_evaluator); + // Constraint enforcing that status[i] is true iff there's a path defined on + // next variables from sources[i] to sinks[i]. + // TODO(user): Only does checking on WhenBound events on next variables. + // Check whether more propagation is needed. + Constraint* MakePathConnected(std::vector nexts, + std::vector sources, + std::vector sinks, + std::vector status); +#ifndef SWIG + // Contraint enforcing, for each pair (i,j) in precedences, i to be before j + // in paths defined by next variables. + // TODO(user): This constraint does not make holes in variable domains; + // the implementation can easily be modified to do that; evaluate the the + // impact on models solved with local search. + Constraint* MakePathPrecedenceConstraint( + std::vector nexts, + const std::vector>& precedences); + // Same precedence constraint as above but will force i to be before j if + // the sum of transits on the path from i to j is strictly positive. + Constraint* MakePathTransitPrecedenceConstraint( + std::vector nexts, std::vector transits, + const std::vector>& precedences); +#endif + // This constraint maps the domain of 'var' onto the array of + // variables 'vars'. That is + // for all i in [0 .. size - 1]: vars[i] == 1 <=> var->Contains(i); + Constraint* MakeMapDomain(IntVar* const var, + const std::vector& vars); + + // This method creates a constraint where the graph of the relation + // between the variables is given in extension. There are 'arity' + // variables involved in the relation and the graph is given by a + // integer tuple set. + Constraint* MakeAllowedAssignments(const std::vector& vars, + const IntTupleSet& tuples); + + // This constraint create a finite automaton that will check the + // sequence of variables vars. It uses a transition table called + // 'transitions'. Each transition is a triple + // (current_state, variable_value, new_state). + // The initial state is given, and the set of accepted states is decribed + // by 'final_states'. These states are hidden inside the constraint. + // Only the transitions (i.e. the variables) are visible. + Constraint* MakeTransitionConstraint(const std::vector& vars, + const IntTupleSet& transitions, + int64 initial_state, + const std::vector& final_states); + + // This constraint create a finite automaton that will check the + // sequence of variables vars. It uses a transition table called + // 'transitions'. Each transition is a triple + // (current_state, variable_value, new_state). + // The initial state is given, and the set of accepted states is decribed + // by 'final_states'. These states are hidden inside the constraint. + // Only the transitions (i.e. the variables) are visible. + Constraint* MakeTransitionConstraint(const std::vector& vars, + const IntTupleSet& transitions, + int64 initial_state, + const std::vector& final_states); + +#if defined(SWIGPYTHON) + // Compatibility layer for python API. + Constraint* MakeAllowedAssignments( + const std::vector& vars, + const std::vector>& raw_tuples) { + IntTupleSet tuples(vars.size()); + tuples.InsertAll(raw_tuples); + return MakeAllowedAssignments(vars, tuples); + } + + Constraint* MakeTransitionConstraint( + const std::vector& vars, + const std::vector>& raw_transitions, + int64 initial_state, const std::vector& final_states) { + IntTupleSet transitions(3); + transitions.InsertAll(raw_transitions); + return MakeTransitionConstraint(vars, transitions, initial_state, + final_states); + } +#endif + + // This constraint states that all the boxes must not overlap. + // The coordinates of box i are : + // (x_vars[i], y_vars[i]), + // (x_vars[i], y_vars[i] + y_size[i]), + // (x_vars[i] + x_size[i], y_vars[i]), + // (x_vars[i] + x_size[i], y_vars[i] + y_size[i]). + // The sizes must be non negative. Boxes with one zero dimension can be pushed + // like any box. + Constraint* MakeNonOverlappingBoxesConstraint( + const std::vector& x_vars, const std::vector& y_vars, + const std::vector& x_size, const std::vector& y_size); + Constraint* MakeNonOverlappingBoxesConstraint( + const std::vector& x_vars, const std::vector& y_vars, + const std::vector& x_size, const std::vector& y_size); + Constraint* MakeNonOverlappingBoxesConstraint( + const std::vector& x_vars, const std::vector& y_vars, + const std::vector& x_size, const std::vector& y_size); + + // This constraint states that all the boxes must not overlap. + // The coordinates of box i are : + // (x_vars[i], y_vars[i]), + // (x_vars[i], y_vars[i] + y_size[i]), + // (x_vars[i] + x_size[i], y_vars[i]), + // (x_vars[i] + x_size[i], y_vars[i] + y_size[i]). + // The sizes must be positive. + // Boxes with one zero dimension can be placed anywhere. + Constraint* MakeNonOverlappingNonStrictBoxesConstraint( + const std::vector& x_vars, const std::vector& y_vars, + const std::vector& x_size, const std::vector& y_size); + Constraint* MakeNonOverlappingNonStrictBoxesConstraint( + const std::vector& x_vars, const std::vector& y_vars, + const std::vector& x_size, const std::vector& y_size); + Constraint* MakeNonOverlappingNonStrictBoxesConstraint( + const std::vector& x_vars, const std::vector& y_vars, + const std::vector& x_size, const std::vector& y_size); + + // ----- Packing constraint ----- + + // This constraint packs all variables onto 'number_of_bins' + // variables. For any given variable, a value of 'number_of_bins' + // indicates that the variable is not assigned to any bin. + // Dimensions, i.e. cumulative constraints on this packing can be + // added directly from the pack class. + Pack* MakePack(const std::vector& vars, int number_of_bins); + + // ----- scheduling objects ----- + + // Creates an interval var with a fixed duration. The duration must + // be greater than 0. If optional is true, then the interval can be + // performed or unperformed. If optional is false, then the interval + // is always performed. + IntervalVar* MakeFixedDurationIntervalVar(int64 start_min, int64 start_max, + int64 duration, bool optional, + const std::string& name); + + // This method fills the vector with 'count' interval var built with + // the corresponding parameters. + void MakeFixedDurationIntervalVarArray( + int count, int64 start_min, int64 start_max, int64 duration, + bool optional, const std::string& name, + std::vector* const array); + + // Creates a performed interval var with a fixed duration. The duration must + // be greater than 0. + IntervalVar* MakeFixedDurationIntervalVar(IntVar* const start_variable, + int64 duration, const std::string& name); + + // Creates an interval var with a fixed duration, and performed var. + // The duration must be greater than 0. + IntervalVar* MakeFixedDurationIntervalVar(IntVar* const start_variable, + int64 duration, + IntVar* const performed_var, + const std::string& name); + + // This method fills the vector with 'count' interval var built with + // the corresponding start variables. + void MakeFixedDurationIntervalVarArray( + const std::vector& start_variables, int64 duration, + const std::string& name, std::vector* const array); + + // This method fills the vector with interval variables built with + // the corresponding start variables. + void MakeFixedDurationIntervalVarArray( + const std::vector& start_variables, + const std::vector& durations, const std::string& name, + std::vector* const array); + // This method fills the vector with interval variables built with + // the corresponding start variables. + void MakeFixedDurationIntervalVarArray( + const std::vector& start_variables, + const std::vector& durations, const std::string& name, + std::vector* const array); + + // This method fills the vector with interval variables built with + // the corresponding start and performed variables. + void MakeFixedDurationIntervalVarArray( + const std::vector& start_variables, + const std::vector& durations, + const std::vector& performed_variables, const std::string& name, + std::vector* const array); + + // This method fills the vector with interval variables built with + // the corresponding start and performed variables. + void MakeFixedDurationIntervalVarArray( + const std::vector& start_variables, + const std::vector& durations, + const std::vector& performed_variables, const std::string& name, + std::vector* const array); + + // Creates a fixed and performed interval. + IntervalVar* MakeFixedInterval(int64 start, int64 duration, + const std::string& name); + + // Creates an interval var by specifying the bounds on start, + // duration, and end. + IntervalVar* MakeIntervalVar(int64 start_min, int64 start_max, + int64 duration_min, int64 duration_max, + int64 end_min, int64 end_max, bool optional, + const std::string& name); + + // This method fills the vector with 'count' interval var built with + // the corresponding parameters. + void MakeIntervalVarArray(int count, int64 start_min, int64 start_max, + int64 duration_min, int64 duration_max, + int64 end_min, int64 end_max, bool optional, + const std::string& name, + std::vector* const array); + + // Creates an interval var that is the mirror image of the given one, that is, + // the interval var obtained by reversing the axis. + IntervalVar* MakeMirrorInterval(IntervalVar* const interval_var); + + // Creates an interval var with a fixed duration whose start is + // synchronized with the start of another interval, with a given + // offset. The performed status is also in sync with the performed + // status of the given interval variable. + IntervalVar* MakeFixedDurationStartSyncedOnStartIntervalVar( + IntervalVar* const interval_var, int64 duration, int64 offset); + + // Creates an interval var with a fixed duration whose start is + // synchronized with the end of another interval, with a given + // offset. The performed status is also in sync with the performed + // status of the given interval variable. + IntervalVar* MakeFixedDurationStartSyncedOnEndIntervalVar( + IntervalVar* const interval_var, int64 duration, int64 offset); + + // Creates an interval var with a fixed duration whose end is + // synchronized with the start of another interval, with a given + // offset. The performed status is also in sync with the performed + // status of the given interval variable. + IntervalVar* MakeFixedDurationEndSyncedOnStartIntervalVar( + IntervalVar* const interval_var, int64 duration, int64 offset); + + // Creates an interval var with a fixed duration whose end is + // synchronized with the end of another interval, with a given + // offset. The performed status is also in sync with the performed + // status of the given interval variable. + IntervalVar* MakeFixedDurationEndSyncedOnEndIntervalVar( + IntervalVar* const interval_var, int64 duration, int64 offset); + + // Creates and returns an interval variable that wraps around the given one, + // relaxing the min start and end. Relaxing means making unbounded when + // optional. If the variable is non optional, this methods returns + // interval_var. + // + // More precisely, such an interval variable behaves as follows: + // * When the underlying must be performed, the returned interval variable + // behaves exactly as the underlying; + // * When the underlying may or may not be performed, the returned interval + // variable behaves like the underlying, except that it is unbounded on + // the min side; + // * When the underlying cannot be performed, the returned interval variable + // is of duration 0 and must be performed in an interval unbounded on both + // sides. + // + // This is very useful to implement propagators that may only modify + // the start max or end max. + IntervalVar* MakeIntervalRelaxedMin(IntervalVar* const interval_var); + + // Creates and returns an interval variable that wraps around the given one, + // relaxing the max start and end. Relaxing means making unbounded when + // optional. If the variable is non optional, this methods returns + // interval_var. + // + // More precisely, such an interval variable behaves as follows: + // * When the underlying must be performed, the returned interval variable + // behaves exactly as the underlying; + // * When the underlying may or may not be performed, the returned interval + // variable behaves like the underlying, except that it is unbounded on + // the max side; + // * When the underlying cannot be performed, the returned interval variable + // is of duration 0 and must be performed in an interval unbounded on both + // sides. + // + // This is very useful to implement propagators that may only modify + // the start min or end min. + IntervalVar* MakeIntervalRelaxedMax(IntervalVar* const interval_var); + + // ----- scheduling constraints ----- + + // This method creates a relation between an interval var and a + // date. + Constraint* MakeIntervalVarRelation(IntervalVar* const t, + UnaryIntervalRelation r, int64 d); + + // This method creates a relation between two interval vars. + Constraint* MakeIntervalVarRelation(IntervalVar* const t1, + BinaryIntervalRelation r, + IntervalVar* const t2); + + // This method creates a relation between two interval vars. + // The given delay is added to the second interval. + // i.e.: t1 STARTS_AFTER_END of t2 with a delay of 2 + // means t1 will start at least two units of time after the end of t2. + Constraint* MakeIntervalVarRelationWithDelay(IntervalVar* const t1, + BinaryIntervalRelation r, + IntervalVar* const t2, + int64 delay); + + // This constraint implements a temporal disjunction between two + // interval vars t1 and t2. 'alt' indicates which alternative was + // chosen (alt == 0 is equivalent to t1 before t2). + Constraint* MakeTemporalDisjunction(IntervalVar* const t1, + IntervalVar* const t2, IntVar* const alt); + + // This constraint implements a temporal disjunction between two + // interval vars. + Constraint* MakeTemporalDisjunction(IntervalVar* const t1, + IntervalVar* const t2); + + // This constraint forces all interval vars into an non overlapping + // sequence. Intervals with zero duration can be scheduled anywhere. + DisjunctiveConstraint* MakeDisjunctiveConstraint( + const std::vector& intervals, const std::string& name); + + // This constraint forces all interval vars into an non-overlapping + // sequence. Intervals with zero durations cannot overlap with over intervals. + DisjunctiveConstraint* MakeStrictDisjunctiveConstraint( + const std::vector& intervals, const std::string& name); + + // This constraint forces that, for any integer t, the sum of the demands + // corresponding to an interval containing t does not exceed the given + // capacity. + // + // Intervals and demands should be vectors of equal size. + // + // Demands should only contain non-negative values. Zero values are supported, + // and the corresponding intervals are filtered out, as they neither impact + // nor are impacted by this constraint. + Constraint* MakeCumulative(const std::vector& intervals, + const std::vector& demands, int64 capacity, + const std::string& name); + + // This constraint forces that, for any integer t, the sum of the demands + // corresponding to an interval containing t does not exceed the given + // capacity. + // + // Intervals and demands should be vectors of equal size. + // + // Demands should only contain non-negative values. Zero values are supported, + // and the corresponding intervals are filtered out, as they neither impact + // nor are impacted by this constraint. + Constraint* MakeCumulative(const std::vector& intervals, + const std::vector& demands, int64 capacity, + const std::string& name); + + // This constraint forces that, for any integer t, the sum of the demands + // corresponding to an interval containing t does not exceed the given + // capacity. + // + // Intervals and demands should be vectors of equal size. + // + // Demands should only contain non-negative values. Zero values are supported, + // and the corresponding intervals are filtered out, as they neither impact + // nor are impacted by this constraint. + Constraint* MakeCumulative(const std::vector& intervals, + const std::vector& demands, + IntVar* const capacity, const std::string& name); + + // This constraint forces that, for any integer t, the sum of the demands + // corresponding to an interval containing t does not exceed the given + // capacity. + // + // Intervals and demands should be vectors of equal size. + // + // Demands should only contain non-negative values. Zero values are supported, + // and the corresponding intervals are filtered out, as they neither impact + // nor are impacted by this constraint. + Constraint* MakeCumulative(const std::vector& intervals, + const std::vector& demands, + IntVar* const capacity, const std::string& name); + + // This constraint enforces that, for any integer t, the sum of demands + // corresponding to an interval containing t does not exceed the given + // capacity. + // + // Intervals and demands should be vectors of equal size. + // + // Demands should be positive. + Constraint* MakeCumulative(const std::vector& intervals, + const std::vector& demands, + int64 capacity, const std::string& name); + + // This constraint enforces that, for any integer t, the sum of demands + // corresponding to an interval containing t does not exceed the given + // capacity. + // + // Intervals and demands should be vectors of equal size. + // + // Demands should be positive. + Constraint* MakeCumulative(const std::vector& intervals, + const std::vector& demands, + IntVar* const capacity, const std::string& name); + + // This constraint states that the target_var is the convex hull of + // the intervals. If none of the interval variables is performed, + // then the target var is unperformed too. Also, if the target + // variable is unperformed, then all the intervals variables are + // unperformed too. + Constraint* MakeCover(const std::vector& intervals, + IntervalVar* const target_var); + + // This constraints states that the two interval variables are equal. + Constraint* MakeEquality(IntervalVar* const left, IntervalVar* const right); + + // ----- Assignments ----- + + // This method creates an empty assignment. + Assignment* MakeAssignment(); + + // This method creates an assignment which is a copy of 'a'. + Assignment* MakeAssignment(const Assignment* const a); + + // ----- Solution Collectors ----- + + // Collect the first solution of the search. + SolutionCollector* MakeFirstSolutionCollector( + const Assignment* const assignment); + // Collect the first solution of the search. The variables will need to + // be added later. + SolutionCollector* MakeFirstSolutionCollector(); + + // Collect the last solution of the search. + SolutionCollector* MakeLastSolutionCollector( + const Assignment* const assignment); + // Collect the last solution of the search. The variables will need to + // be added later. + SolutionCollector* MakeLastSolutionCollector(); + + // Collect the solution corresponding to the optimal value of the objective + // of 'a'; if 'a' does not have an objective no solution is collected. This + // collector only collects one solution corresponding to the best objective + // value (the first one found). + SolutionCollector* MakeBestValueSolutionCollector( + const Assignment* const assignment, bool maximize); + // Collect the solution corresponding to the optimal value of the + // objective of 'a'; if 'a' does not have an objective no solution + // is collected. This collector only collects one solution + // corresponding to the best objective value (the first one + // found). The variables will need to be added later. + SolutionCollector* MakeBestValueSolutionCollector(bool maximize); + + // Collect all solutions of the search. + SolutionCollector* MakeAllSolutionCollector( + const Assignment* const assignment); + // Collect all solutions of the search. The variables will need to + // be added later. + SolutionCollector* MakeAllSolutionCollector(); + + // ----- Objective ----- + + // Creates a minimization objective. + OptimizeVar* MakeMinimize(IntVar* const v, int64 step); + + // Creates a maximization objective. + OptimizeVar* MakeMaximize(IntVar* const v, int64 step); + + // Creates a objective with a given sense (true = maximization). + OptimizeVar* MakeOptimize(bool maximize, IntVar* const v, int64 step); + + // Creates a minimization weighted objective. The actual objective is + // scalar_prod(vars, weights). + OptimizeVar* MakeWeightedMinimize(const std::vector& vars, + const std::vector& weights, + int64 step); + + // Creates a minimization weighted objective. The actual objective is + // scalar_prod(vars, weights). + OptimizeVar* MakeWeightedMinimize(const std::vector& vars, + const std::vector& weights, + int64 step); + + // Creates a maximization weigthed objective. + OptimizeVar* MakeWeightedMaximize(const std::vector& vars, + const std::vector& weights, + int64 step); + + // Creates a maximization weigthed objective. + OptimizeVar* MakeWeightedMaximize(const std::vector& vars, + const std::vector& weights, + int64 step); + + // Creates a weighted objective with a given sense (true = maximization). + OptimizeVar* MakeWeightedOptimize(bool maximize, + const std::vector& vars, + const std::vector& weights, + int64 step); + + // Creates a weighted objective with a given sense (true = maximization). + OptimizeVar* MakeWeightedOptimize(bool maximize, + const std::vector& vars, + const std::vector& weights, + int64 step); + + // ----- Meta-heuristics ----- + // Search monitors which try to get the search out of local optima. + + // Creates a Tabu Search monitor. + // In the context of local search the behavior is similar to MakeOptimize(), + // creating an objective in a given sense. The behavior differs once a local + // optimum is reached: thereafter solutions which degrade the value of the + // objective are allowed if they are not "tabu". A solution is "tabu" if it + // doesn't respect the following rules: + // - improving the best solution found so far + // - variables in the "keep" list must keep their value, variables in the + // "forbid" list must not take the value they have in the list. + // Variables with new values enter the tabu lists after each new solution + // found and leave the lists after a given number of iterations (called + // tenure). Only the variables passed to the method can enter the lists. + // The tabu criterion is softened by the tabu factor which gives the number + // of "tabu" violations which is tolerated; a factor of 1 means no violations + // allowed, a factor of 0 means all violations allowed. + + SearchMonitor* MakeTabuSearch(bool maximize, IntVar* const v, int64 step, + const std::vector& vars, + int64 keep_tenure, int64 forbid_tenure, + double tabu_factor); + + // Creates a Tabu Search monitor based on the solution value of the objective. + // In the context of local search the behavior is similar to MakeOptimize(), + // creating an objective in a given sense. The behavior differs once a local + // optimum is reached: thereafter solutions which degrade the value of the + // objective are allowed if they are not "tabu". A solution is "tabu" if it + // doesn't respect the following rules: + // - improving the best solution found so far + // - objective value must be different from the last considered solutions. + SearchMonitor* MakeObjectiveTabuSearch(bool maximize, IntVar* const v, + int64 step, int64 forbid_tenure); + + // Creates a Simulated Annealing monitor. + // TODO(user): document behavior + SearchMonitor* MakeSimulatedAnnealing(bool maximize, IntVar* const v, + int64 step, int64 initial_temperature); + + // Creates a Guided Local Search monitor. + // Description here: http://en.wikipedia.org/wiki/Guided_Local_Search + SearchMonitor* MakeGuidedLocalSearch(bool maximize, IntVar* const objective, + IndexEvaluator2 objective_function, + int64 step, + const std::vector& vars, + double penalty_factor); + SearchMonitor* MakeGuidedLocalSearch( + bool maximize, IntVar* const objective, + IndexEvaluator3 objective_function, int64 step, + const std::vector& vars, + const std::vector& secondary_vars, double penalty_factor); + + // ----- Restart Search ----- + + // This search monitor will restart the search periodically. + // At the iteration n, it will restart after scale_factor * Luby(n) failures + // where Luby is the Luby Strategy (i.e. 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8...). + SearchMonitor* MakeLubyRestart(int scale_factor); + + // This search monitor will restart the search periodically after 'frequency' + // failures. + SearchMonitor* MakeConstantRestart(int frequency); + + // ----- Search Limit ----- + + // Creates a search limit that constrains the running time given in + // milliseconds. + SearchLimit* MakeTimeLimit(int64 time_in_ms); + + // Creates a search limit that constrains the number of branches + // explored in the search tree. + SearchLimit* MakeBranchesLimit(int64 branches); + + // Creates a search limit that constrains the number of failures + // that can happen when exploring the search tree. + SearchLimit* MakeFailuresLimit(int64 failures); + + // Creates a search limit that constrains the number of solutions found + // during the search. + SearchLimit* MakeSolutionsLimit(int64 solutions); + + // Limits the search with the 'time', 'branches', 'failures' and + // 'solutions' limits. + SearchLimit* MakeLimit(int64 time, int64 branches, int64 failures, + int64 solutions); + // Version reducing calls to wall timer by estimating number of remaining + // calls. + SearchLimit* MakeLimit(int64 time, int64 branches, int64 failures, + int64 solutions, bool smart_time_check); + // Creates a search limit which can either apply cumulatively or + // search-by-search. + SearchLimit* MakeLimit(int64 time, int64 branches, int64 failures, + int64 solutions, bool smart_time_check, + bool cumulative); + // Creates a search limit from its protobuf description + SearchLimit* MakeLimit(const SearchLimitParameters& proto); + + // Creates a search limit proto containing default values. + SearchLimitParameters MakeDefaultSearchLimitParameters() const; + + // Creates a search limit that is reached when either of the underlying limit + // is reached. That is, the returned limit is more stringent than both + // argument limits. + SearchLimit* MakeLimit(SearchLimit* const limit_1, + SearchLimit* const limit_2); + + void UpdateLimits(int64 time, int64 branches, int64 failures, int64 solutions, + SearchLimit* limit); + // Returns 'time' limit of search limit + int64 GetTime(SearchLimit* limit); + + // Callback-based search limit. Search stops when limiter returns true; if + // this happens at a leaf the corresponding solution will be rejected. + SearchLimit* MakeCustomLimit(std::function limiter); + + // ----- No Goods ----- + + // Creates a non-reversible nogood manager to store and use nogoods + // during search. Nogoods are defined by the NoGood class. It can be + // used during search with restart to avoid revisiting the same + // portion of the search tree. + NoGoodManager* MakeNoGoodManager(); + + // ----- Tree Monitor ----- + // Creates a tree monitor that outputs a detailed overview of the + // decision phase in cpviz format. The XML data is written to files + // file_tree and file_visualization as the search finishes. + SearchMonitor* MakeTreeMonitor(const std::vector& vars, + const std::string& file_tree, + const std::string& file_visualization); + + // Creates a tree monitor that outputs a detailed overview of the + // decision phase in cpviz format. The XML data is written to files + // file_config, file_tree and file_visualization as the search + // finishes. + SearchMonitor* MakeTreeMonitor(const std::vector& vars, + const std::string& file_config, + const std::string& file_tree, + const std::string& file_visualization); + +#if !defined(SWIG) + // Creates a tree monitor that outputs a detailed overview of the + // decision phase in cpviz format. The XML data is copied to tree_xml + // and visualization_xml as the search finishes. The tree monitor does + // not take ownership of either std::string. + SearchMonitor* MakeTreeMonitor(const std::vector& vars, + std::string* const tree_xml, + std::string* const visualization_xml); + + // Creates a tree monitor that outputs a detailed overview of the + // decision phase in cpviz format. The XML data is copied to config_xml, + // tree_xml and visualization_xml as the search finishes. The tree monitor + // does not take ownership of these strings. + SearchMonitor* MakeTreeMonitor(const std::vector& vars, + std::string* const config_xml, + std::string* const tree_xml, + std::string* const visualization_xml); + +#endif // #if !defined(SWIG) + + // TODO(user): DEPRECATE API of MakeSearchLog(.., IntVar* var,..). + + // ----- Search Log ----- + // The SearchMonitors below will display a periodic search log + // on LOG(INFO) every branch_count branches explored. + + SearchMonitor* MakeSearchLog(int branch_count); + + // At each solution, this monitor also display the objective value. + SearchMonitor* MakeSearchLog(int branch_count, IntVar* const objective); + + // At each solution, this monitor will also display result of @p + // display_callback. + SearchMonitor* MakeSearchLog(int branch_count, + std::function display_callback); + + // At each solution, this monitor will display the objective value and the + // result of @p display_callback. + SearchMonitor* MakeSearchLog(int branch_count, IntVar* objective, + std::function display_callback); + + // OptimizeVar Search Logs + // At each solution, this monitor will also display the objective->Print(). + + SearchMonitor* MakeSearchLog(int branch_count, OptimizeVar* const objective); + + // Creates a search monitor that will also print the result of the + // display callback. + SearchMonitor* MakeSearchLog(int branch_count, OptimizeVar* const objective, + std::function display_callback); + + + // ----- Search Trace ------ + + // Creates a search monitor that will trace precisely the behavior of the + // search. Use this only for low level debugging. + SearchMonitor* MakeSearchTrace(const std::string& prefix); + + // ----- Callback-based search monitors ----- + SearchMonitor* MakeEnterSearchCallback(std::function callback); + SearchMonitor* MakeExitSearchCallback(std::function callback); + SearchMonitor* MakeAtSolutionCallback(std::function callback); + + // ----- ModelVisitor ----- + + // Prints the model. + ModelVisitor* MakePrintModelVisitor(); + // Displays some nice statistics on the model. + ModelVisitor* MakeStatisticsModelVisitor(); +#if !defined(SWIG) + // Compute the number of constraints a variable is attached to. + ModelVisitor* MakeVariableDegreeVisitor( + std::unordered_map* const map); +#endif + + // ----- Symmetry Breaking ----- + + SearchMonitor* MakeSymmetryManager( + const std::vector& visitors); + SearchMonitor* MakeSymmetryManager(SymmetryBreaker* const v1); + SearchMonitor* MakeSymmetryManager(SymmetryBreaker* const v1, + SymmetryBreaker* const v2); + SearchMonitor* MakeSymmetryManager(SymmetryBreaker* const v1, + SymmetryBreaker* const v2, + SymmetryBreaker* const v3); + SearchMonitor* MakeSymmetryManager(SymmetryBreaker* const v1, + SymmetryBreaker* const v2, + SymmetryBreaker* const v3, + SymmetryBreaker* const v4); + + // ----- Search Decicions and Decision Builders ----- + + // ----- Decisions ----- + Decision* MakeAssignVariableValue(IntVar* const var, int64 value); + Decision* MakeVariableLessOrEqualValue(IntVar* const var, int64 value); + Decision* MakeVariableGreaterOrEqualValue(IntVar* const var, int64 value); + Decision* MakeSplitVariableDomain(IntVar* const var, int64 value, + bool start_with_lower_half); + Decision* MakeAssignVariableValueOrFail(IntVar* const var, int64 value); + Decision* MakeAssignVariablesValues(const std::vector& vars, + const std::vector& values); + Decision* MakeFailDecision(); +#if !defined(SWIG) + Decision* MakeDecision(Action apply, Action refute); +#endif // !defined(SWIG) + + // Creates a decision builder which sequentially composes decision builders. + // At each leaf of a decision builder, the next decision builder is therefore + // called. For instance, Compose(db1, db2) will result in the following tree: + // d1 tree | + // / | \ | + // db1 leaves | + // / | \ | + // db2 tree db2 tree db2 tree | + DecisionBuilder* Compose(DecisionBuilder* const db1, + DecisionBuilder* const db2); + DecisionBuilder* Compose(DecisionBuilder* const db1, + DecisionBuilder* const db2, + DecisionBuilder* const db3); + DecisionBuilder* Compose(DecisionBuilder* const db1, + DecisionBuilder* const db2, + DecisionBuilder* const db3, + DecisionBuilder* const db4); + DecisionBuilder* Compose(const std::vector& dbs); + + // Creates a decision builder which will create a search tree where each + // decision builder is called from the top of the search tree. For instance + // the decision builder Try(db1, db2) will entirely explore the search tree + // of db1 then the one of db2, resulting in the following search tree: + // Tree root | + // / \ | + // db1 tree db2 tree | + // + // This is very handy to try a decision builder which partially explores the + // search space and if it fails to try another decision builder. + // + // TODO(user): The search tree can be balanced by using binary + // "Try"-builders "recursively". For instance, Try(a,b,c,d) will give a tree + // unbalanced to the right, whereas Try(Try(a,b), Try(b,c)) will give a + // balanced tree. Investigate if we should only provide the binary version + // and/or if we should balance automatically. + DecisionBuilder* Try(DecisionBuilder* const db1, DecisionBuilder* const db2); + DecisionBuilder* Try(DecisionBuilder* const db1, DecisionBuilder* const db2, + DecisionBuilder* const db3); + DecisionBuilder* Try(DecisionBuilder* const db1, DecisionBuilder* const db2, + DecisionBuilder* const db3, DecisionBuilder* const db4); + DecisionBuilder* Try(const std::vector& dbs); + + // Phases on IntVar arrays. + // TODO(user): name each of them differently, and document them (and do that + // for all other functions that have several homonyms in this .h). + DecisionBuilder* MakePhase(const std::vector& vars, + IntVarStrategy var_str, IntValueStrategy val_str); + DecisionBuilder* MakePhase(const std::vector& vars, + IndexEvaluator1 var_evaluator, + IntValueStrategy val_str); + + DecisionBuilder* MakePhase(const std::vector& vars, + IntVarStrategy var_str, IndexEvaluator2 val_eval); + + DecisionBuilder* MakePhase( + const std::vector& vars, IntVarStrategy var_str, + // var_val1_val2_comparator(var, val1, val2) is true iff assigning value + // "val1" to variable "var" is better than assigning value "val2". + VariableValueComparator var_val1_val2_comparator); + + DecisionBuilder* MakePhase(const std::vector& vars, + IndexEvaluator1 var_evaluator, + IndexEvaluator2 val_eval); + + DecisionBuilder* MakePhase(const std::vector& vars, + IntVarStrategy var_str, IndexEvaluator2 val_eval, + IndexEvaluator1 tie_breaker); + + DecisionBuilder* MakePhase(const std::vector& vars, + IndexEvaluator1 var_evaluator, + IndexEvaluator2 val_eval, + IndexEvaluator1 tie_breaker); + + DecisionBuilder* MakeDefaultPhase(const std::vector& vars); + DecisionBuilder* MakeDefaultPhase(const std::vector& vars, + const DefaultPhaseParameters& parameters); + + // shortcuts for small arrays. + DecisionBuilder* MakePhase(IntVar* const v0, IntVarStrategy var_str, + IntValueStrategy val_str); + DecisionBuilder* MakePhase(IntVar* const v0, IntVar* const v1, + IntVarStrategy var_str, IntValueStrategy val_str); + DecisionBuilder* MakePhase(IntVar* const v0, IntVar* const v1, + IntVar* const v2, IntVarStrategy var_str, + IntValueStrategy val_str); + DecisionBuilder* MakePhase(IntVar* const v0, IntVar* const v1, + IntVar* const v2, IntVar* const v3, + IntVarStrategy var_str, IntValueStrategy val_str); + + // ----- Scheduling Decisions ----- + + // Returns a decision that tries to schedule a task at a given time. + // On the Apply branch, it will set that interval var as performed and set + // its start to 'est'. On the Refute branch, it will just update the + // 'marker' to 'est' + 1. This decision is used in the + // INTERVAL_SET_TIMES_FORWARD strategy. + Decision* MakeScheduleOrPostpone(IntervalVar* const var, int64 est, + int64* const marker); + + // Returns a decision that tries to schedule a task at a given time. + // On the Apply branch, it will set that interval var as performed and set + // its end to 'est'. On the Refute branch, it will just update the + // 'marker' to 'est' - 1. This decision is used in the + // INTERVAL_SET_TIMES_BACKWARD strategy. + Decision* MakeScheduleOrExpedite(IntervalVar* const var, int64 est, + int64* const marker); + + // Returns a decision that tries to rank first the ith interval var + // in the sequence variable. + Decision* MakeRankFirstInterval(SequenceVar* const sequence, int index); + + // Returns a decision that tries to rank last the ith interval var + // in the sequence variable. + Decision* MakeRankLastInterval(SequenceVar* const sequence, int index); + + // Returns a decision builder which assigns values to variables which + // minimize the values returned by the evaluator. The arguments passed to the + // evaluator callback are the indices of the variables in vars and the values + // of these variables. Ownership of the callback is passed to the decision + // builder. + DecisionBuilder* MakePhase(const std::vector& vars, + IndexEvaluator2 evaluator, EvaluatorStrategy str); + + // Returns a decision builder which assigns values to variables + // which minimize the values returned by the evaluator. In case of + // tie breaks, the second callback is used to choose the best index + // in the array of equivalent pairs with equivalent evaluations. The + // arguments passed to the evaluator callback are the indices of the + // variables in vars and the values of these variables. Ownership of + // the callback is passed to the decision builder. + DecisionBuilder* MakePhase(const std::vector& vars, + IndexEvaluator2 evaluator, + IndexEvaluator1 tie_breaker, + EvaluatorStrategy str); + + // Scheduling phases. + + DecisionBuilder* MakePhase(const std::vector& intervals, + IntervalStrategy str); + + DecisionBuilder* MakePhase(const std::vector& sequences, + SequenceStrategy str); + + // Returns a decision builder for which the left-most leaf corresponds + // to assignment, the rest of the tree being explored using 'db'. + DecisionBuilder* MakeDecisionBuilderFromAssignment( + Assignment* const assignment, DecisionBuilder* const db, + const std::vector& vars); + + // Returns a decision builder that will add the given constraint to + // the model. + DecisionBuilder* MakeConstraintAdder(Constraint* const ct); + + // SolveOnce will collapse a search tree described by a decision + // builder 'db' and a set of monitors and wrap it into a single point. + // If there are no solutions to this nested tree, then SolveOnce will + // fail. If there is a solution, it will find it and returns nullptr. + DecisionBuilder* MakeSolveOnce(DecisionBuilder* const db); + DecisionBuilder* MakeSolveOnce(DecisionBuilder* const db, + SearchMonitor* const monitor1); + DecisionBuilder* MakeSolveOnce(DecisionBuilder* const db, + SearchMonitor* const monitor1, + SearchMonitor* const monitor2); + DecisionBuilder* MakeSolveOnce(DecisionBuilder* const db, + SearchMonitor* const monitor1, + SearchMonitor* const monitor2, + SearchMonitor* const monitor3); + DecisionBuilder* MakeSolveOnce(DecisionBuilder* const db, + SearchMonitor* const monitor1, + SearchMonitor* const monitor2, + SearchMonitor* const monitor3, + SearchMonitor* const monitor4); + DecisionBuilder* MakeSolveOnce(DecisionBuilder* const db, + const std::vector& monitors); + + // NestedOptimize will collapse a search tree described by a + // decision builder 'db' and a set of monitors and wrap it into a + // single point. If there are no solutions to this nested tree, then + // NestedOptimize will fail. If there are solutions, it will find + // the best as described by the mandatory objective in the solution, + // as well as the optimization direction, instantiate all variables + // to this solution, and returns nullptr. + DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, + Assignment* const solution, bool maximize, + int64 step); + DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, + Assignment* const solution, bool maximize, + int64 step, + SearchMonitor* const monitor1); + DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, + Assignment* const solution, bool maximize, + int64 step, SearchMonitor* const monitor1, + SearchMonitor* const monitor2); + DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, + Assignment* const solution, bool maximize, + int64 step, SearchMonitor* const monitor1, + SearchMonitor* const monitor2, + SearchMonitor* const monitor3); + DecisionBuilder* MakeNestedOptimize(DecisionBuilder* const db, + Assignment* const solution, bool maximize, + int64 step, SearchMonitor* const monitor1, + SearchMonitor* const monitor2, + SearchMonitor* const monitor3, + SearchMonitor* const monitor4); + DecisionBuilder* MakeNestedOptimize( + DecisionBuilder* const db, Assignment* const solution, bool maximize, + int64 step, const std::vector& monitors); + + // Returns a DecisionBuilder which restores an Assignment + // (calls void Assignment::Restore()) + DecisionBuilder* MakeRestoreAssignment(Assignment* assignment); + + // Returns a DecisionBuilder which stores an Assignment + // (calls void Assignment::Store()) + DecisionBuilder* MakeStoreAssignment(Assignment* assignment); + + // ----- Local Search Operators ----- + + LocalSearchOperator* MakeOperator(const std::vector& vars, + LocalSearchOperators op); + LocalSearchOperator* MakeOperator(const std::vector& vars, + const std::vector& secondary_vars, + LocalSearchOperators op); + // TODO(user): Make the callback an IndexEvaluator2 when there are no + // secondary variables. + LocalSearchOperator* MakeOperator(const std::vector& vars, + IndexEvaluator3 evaluator, + EvaluatorLocalSearchOperators op); + LocalSearchOperator* MakeOperator(const std::vector& vars, + const std::vector& secondary_vars, + IndexEvaluator3 evaluator, + EvaluatorLocalSearchOperators op); + + // Creates a large neighborhood search operator which creates fragments (set + // of relaxed variables) with up to number_of_variables random variables + // (sampling with replacement is performed meaning that at most + // number_of_variables variables are selected). Warning: this operator will + // always return neighbors; using it without a search limit will result in a + // non-ending search. + // Optionally a random seed can be specified. + LocalSearchOperator* MakeRandomLnsOperator(const std::vector& vars, + int number_of_variables); + LocalSearchOperator* MakeRandomLnsOperator(const std::vector& vars, + int number_of_variables, + int32 seed); + + // Creates a local search operator that tries to move the assignment of some + // variables toward a target. The target is given as an Assignment. This + // operator generates neighbors in which the only difference compared to the + // current state is that one variable that belongs to the target assignment is + // set to its target value. + LocalSearchOperator* MakeMoveTowardTargetOperator(const Assignment& target); + + // Creates a local search operator that tries to move the assignment of some + // variables toward a target. The target is given either as two vectors: a + // vector of variables and a vector of associated target values. The two + // vectors should be of the same length. This operator generates neighbors in + // which the only difference compared to the current state is that one + // variable that belongs to the given vector is set to its target value. + LocalSearchOperator* MakeMoveTowardTargetOperator( + const std::vector& variables, + const std::vector& target_values); + + // Creates a local search operator which concatenates a vector of operators. + // Each operator from the vector is called sequentially. By default, when a + // neighbor is found the neighborhood exploration restarts from the last + // active operator (the one which produced the neighbor). + // This can be overriden by setting restart to true to force the exploration + // to start from the first operator in the vector. + // The default behavior can also be overriden using an evaluation callback to + // set the order in which the operators are explored (the callback is called + // in LocalSearchOperator::Start()). The first argument of the callback is + // the index of the operator which produced the last move, the second + // argument is the index of the operator to be evaluated. + // Ownership of the callback is taken by ConcatenateOperators. + // + // Example: + // + // const int kPriorities = {10, 100, 10, 0}; + // int64 Evaluate(int active_operator, int current_operator) { + // return kPriorities[current_operator]; + // } + // + // LocalSearchOperator* concat = + // solver.ConcatenateOperators(operators, + // NewPermanentCallback(&Evaluate)); + // + // The elements of the vector operators will be sorted by increasing priority + // and explored in that order (tie-breaks are handled by keeping the relative + // operator order in the vector). This would result in the following order: + // operators[3], operators[0], operators[2], operators[1]. + // + LocalSearchOperator* ConcatenateOperators( + const std::vector& ops); + LocalSearchOperator* ConcatenateOperators( + const std::vector& ops, bool restart); + LocalSearchOperator* ConcatenateOperators( + const std::vector& ops, + std::function evaluator); + // Randomized version of local search concatenator; calls a random operator at + // each call to MakeNextNeighbor(). + LocalSearchOperator* RandomConcatenateOperators( + const std::vector& ops); + + // Randomized version of local search concatenator; calls a random operator at + // each call to MakeNextNeighbor(). The provided seed is used to init + // the random number generator. + LocalSearchOperator* RandomConcatenateOperators( + const std::vector& ops, int32 seed); + + // Creates a local search operator that wraps another local search + // operator and limits the number of neighbors explored (i.e. calls + // to MakeNextNeighbor from the current solution (between two calls + // to Start()). When this limit is reached, MakeNextNeighbor() + // returns false. The counter is cleared when Start() is called. + LocalSearchOperator* MakeNeighborhoodLimit(LocalSearchOperator* const op, + int64 limit); + + // Local Search decision builders factories. + // Local search is used to improve a given solution. This initial solution + // can be specified either by an Assignment or by a DecisionBulder, and the + // corresponding variables, the initial solution being the first solution + // found by the DecisionBuilder. + // The LocalSearchPhaseParameters parameter holds the actual definition of + // the local search phase: + // - a local search operator used to explore the neighborhood of the current + // solution, + // - a decision builder to instantiate unbound variables once a neighbor has + // been defined; in the case of LNS-based operators instantiates fragment + // variables; search monitors can be added to this sub-search by wrapping + // the decision builder with MakeSolveOnce. + // - a search limit specifying how long local search looks for neighbors + // before accepting one; the last neighbor is always taken and in the case + // of a greedy search, this corresponds to the best local neighbor; + // first-accept (which is the default behavior) can be modeled using a + // solution found limit of 1, + // - a vector of local search filters used to speed up the search by pruning + // unfeasible neighbors. + // Metaheuristics can be added by defining specialized search monitors; + // currently down/up-hill climbing is available through OptimizeVar, as well + // as Guided Local Search, Tabu Search and Simulated Annealing. + // + // TODO(user): Make a variant which runs a local search after each + // solution found in a dfs + + DecisionBuilder* MakeLocalSearchPhase( + Assignment* const assignment, + LocalSearchPhaseParameters* const parameters); + DecisionBuilder* MakeLocalSearchPhase( + const std::vector& vars, DecisionBuilder* const first_solution, + LocalSearchPhaseParameters* const parameters); + DecisionBuilder* MakeLocalSearchPhase( + const std::vector& vars, + DecisionBuilder* const first_solution, + LocalSearchPhaseParameters* const parameters); + + // Solution Pool. + SolutionPool* MakeDefaultSolutionPool(); + + // Local Search Phase Parameters + LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters( + LocalSearchOperator* const ls_operator, + DecisionBuilder* const sub_decision_builder); + LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters( + LocalSearchOperator* const ls_operator, + DecisionBuilder* const sub_decision_builder, SearchLimit* const limit); + LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters( + LocalSearchOperator* const ls_operator, + DecisionBuilder* const sub_decision_builder, SearchLimit* const limit, + const std::vector& filters); + + LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters( + SolutionPool* const pool, LocalSearchOperator* const ls_operator, + DecisionBuilder* const sub_decision_builder); + LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters( + SolutionPool* const pool, LocalSearchOperator* const ls_operator, + DecisionBuilder* const sub_decision_builder, SearchLimit* const limit); + LocalSearchPhaseParameters* MakeLocalSearchPhaseParameters( + SolutionPool* const pool, LocalSearchOperator* const ls_operator, + DecisionBuilder* const sub_decision_builder, SearchLimit* const limit, + const std::vector& filters); + + // Local Search Filters + LocalSearchFilter* MakeVariableDomainFilter(); + LocalSearchFilter* MakeLocalSearchObjectiveFilter( + const std::vector& vars, IndexEvaluator2 values, + IntVar* const objective, Solver::LocalSearchFilterBound filter_enum, + Solver::LocalSearchOperation op_enum); + LocalSearchFilter* MakeLocalSearchObjectiveFilter( + const std::vector& vars, IndexEvaluator2 values, + ObjectiveWatcher delta_objective_callback, IntVar* const objective, + Solver::LocalSearchFilterBound filter_enum, + Solver::LocalSearchOperation op_enum); + LocalSearchFilter* MakeLocalSearchObjectiveFilter( + const std::vector& vars, + const std::vector& secondary_vars, + Solver::IndexEvaluator3 values, IntVar* const objective, + Solver::LocalSearchFilterBound filter_enum, + Solver::LocalSearchOperation op_enum); + LocalSearchFilter* MakeLocalSearchObjectiveFilter( + const std::vector& vars, + const std::vector& secondary_vars, + Solver::IndexEvaluator3 values, ObjectiveWatcher delta_objective_callback, + IntVar* const objective, Solver::LocalSearchFilterBound filter_enum, + Solver::LocalSearchOperation op_enum); + + // Performs PeriodicCheck on the top-level search; can be called from a nested + // solve to check top-level limits for instance. + void TopPeriodicCheck(); + // Returns a percentage representing the propress of the search before + // reaching the limits of the top-level search (can be called from a nested + // solve). + int TopProgressPercent(); + + // The PushState and PopState methods manipulates the states + // of the reversible objects. They are visible only because they + // are useful to write unitary tests. + void PushState(); + void PopState(); + + // Gets the search depth of the current active search. Returns -1 in + // case there are no active search opened. + int SearchDepth() const; + + // Gets the search left depth of the current active search. Returns -1 in + // case there are no active search opened. + int SearchLeftDepth() const; + + // Gets the number of nested searches. It returns 0 outside search, + // 1 during the top level search, 2 or more in case of nested searches. + int SolveDepth() const; + + // Sets the given branch selector on the current active search. + void SetBranchSelector(BranchSelector bs); + + // Creates a decision builder that will set the branch selector. + DecisionBuilder* MakeApplyBranchSelector(BranchSelector bs); + + // All-in-one SaveAndSetValue. + template + void SaveAndSetValue(T* adr, T val) { + if (*adr != val) { + InternalSaveValue(adr); + *adr = val; + } + } + + // All-in-one SaveAndAdd_value. + template + void SaveAndAdd(T* adr, T val) { + if (val != 0) { + InternalSaveValue(adr); + (*adr) += val; + } + } + + // Returns a random value between 0 and 'size' - 1; + int64 Rand64(int64 size) { return random_.Next64() % size; } + + // Returns a random value between 0 and 'size' - 1; + int32 Rand32(int32 size) { return random_.Next() % size; } + + // Reseed the solver random generator. + void ReSeed(int32 seed) { random_.Reset(seed); } + + // Exports the profiling information in a human readable overview. + // The parameter profile_level used to create the solver must be + // set to true. + void ExportProfilingOverview(const std::string& filename); + + // Returns local search profiling information in a human readable format. + // TODO(user): Add a profiling protocol buffer and merge demon and local + // search profiles. + std::string LocalSearchProfile() const; + + // Returns true whether the current search has been + // created using a Solve() call instead of a NewSearch one. It + // returns false if the solver is not in search at all. + bool CurrentlyInSolve() const; + + // Counts the number of constraints that have been added + // to the solver before the search. + int constraints() const { return constraints_list_.size(); } + + // Accepts the given model visitor. + void Accept(ModelVisitor* const visitor) const; + // Accepts the given model visitor. + void Accept(ModelVisitor* const visitor, + const std::vector& monitors) const; + void Accept(ModelVisitor* const visitor, + const std::vector& monitors, + DecisionBuilder* const db) const; + + Decision* balancing_decision() const { return balancing_decision_.get(); } + +// Internal +#if !defined(SWIG) + void set_fail_intercept(std::function fail_intercept) { + fail_intercept_ = std::move(fail_intercept); + } +#endif // SWIG + void clear_fail_intercept() { fail_intercept_ = nullptr; } + // Access to demon profiler. + DemonProfiler* demon_profiler() const { return demon_profiler_; } + // Returns whether the object has been named or not. + bool HasName(const PropagationBaseObject* object) const; + // Adds a new demon and wraps it inside a DemonProfiler if necessary. + Demon* RegisterDemon(Demon* const d); + // Registers a new IntExpr and wraps it inside a TraceIntExpr if necessary. + IntExpr* RegisterIntExpr(IntExpr* const expr); + // Registers a new IntVar and wraps it inside a TraceIntVar if necessary. + IntVar* RegisterIntVar(IntVar* const var); + // Registers a new IntervalVar and wraps it inside a TraceIntervalVar + // if necessary. + IntervalVar* RegisterIntervalVar(IntervalVar* const var); + + // Returns the active search, nullptr outside search. + Search* ActiveSearch() const; + // Returns the cache of the model. + ModelCache* Cache() const; + // Returns whether we are instrumenting demons. + bool InstrumentsDemons() const; + // Returns whether we are profiling the solver. + bool IsProfilingEnabled() const; + // Returns whether we are profiling local search. + bool IsLocalSearchProfilingEnabled() const; + // Returns whether we are tracing variables. + bool InstrumentsVariables() const; + // Returns whether all variables should be named. + bool NameAllVariables() const; + // Returns the name of the model. + std::string model_name() const; + // Returns the propagation monitor. + PropagationMonitor* GetPropagationMonitor() const; + // Adds the propagation monitor to the solver. This is called internally when + // a propagation monitor is passed to the Solve() or NewSearch() method. + void AddPropagationMonitor(PropagationMonitor* const monitor); + // Returns the local search monitor. + LocalSearchMonitor* GetLocalSearchMonitor() const; + // Adds the local search monitor to the solver. This is called internally when + // a propagation monitor is passed to the Solve() or NewSearch() method. + void AddLocalSearchMonitor(LocalSearchMonitor* monitor); + + // Unsafe temporary vector. It is used to avoid leaks in operations + // that need storage and that may fail. See IntVar::SetValues() for + // instance. It is not locked; do not use in a multi-threaded or reentrant + // setup. + std::vector tmp_vector_; + + friend class BaseIntExpr; + friend class Constraint; + friend class DemonProfiler; + friend class FindOneNeighbor; + friend class IntVar; + friend class PropagationBaseObject; + friend class Queue; + friend class SearchMonitor; + friend class SearchLimit; + friend class RoutingModel; + friend class LocalSearchProfiler; + +#if !defined(SWIG) + friend void InternalSaveBooleanVarValue(Solver* const, IntVar* const); + template + friend class SimpleRevFIFO; + template + friend class RevImmutableMultiMap; + + // Returns true if expr represents either boolean_var or 1 - + // boolean_var. In that case, it fills sub_var and is_negated to be + // true if the expression is 1 - boolean_var -- equivalent to + // not(boolean_var). + bool IsBooleanVar(IntExpr* const expr, IntVar** sub_var, + bool* is_negated) const; + + // Returns true if expr represents a product of a expr and a + // constant. In that case, it fills sub_expr and coefficient with + // these, and returns true. In the other case, it fills sub_expr + // with expr, coefficient with 1, and returns false. + bool IsProduct(IntExpr* const expr, IntExpr** sub_expr, int64* coefficient); +#endif // !defined(SWIG) + + // Internal. If the variables is the result of expr->Var(), this + // method returns expr, nullptr otherwise. + IntExpr* CastExpression(const IntVar* const var) const; + + // Tells the solver to kill or restart the current search. + void FinishCurrentSearch(); + void RestartCurrentSearch(); + + // These methods are only useful for the SWIG wrappers, which need a way + // to externally cause the Solver to fail. + void ShouldFail() { should_fail_ = true; } + void CheckFail() { + if (!should_fail_) return; + should_fail_ = false; + Fail(); + } + + private: + void Init(); // Initialization. To be called by the constructors only. + void PushState(MarkerType t, const StateInfo& info); + MarkerType PopState(StateInfo* info); + void PushSentinel(int magic_code); + void BacktrackToSentinel(int magic_code); + void ProcessConstraints(); + bool BacktrackOneLevel(Decision** fd); + void JumpToSentinelWhenNested(); + void JumpToSentinel(); + void check_alloc_state(); + void FreezeQueue(); + void EnqueueVar(Demon* const d); + void EnqueueDelayedDemon(Demon* const d); + void ExecuteAll(const SimpleRevFIFO& demons); + void EnqueueAll(const SimpleRevFIFO& demons); + void UnfreezeQueue(); + void reset_action_on_fail(); + void set_action_on_fail(Action a); + void set_variable_to_clean_on_fail(IntVar* v); + + void InternalSaveValue(int* valptr); + void InternalSaveValue(int64* valptr); + void InternalSaveValue(uint64* valptr); + void InternalSaveValue(double* valptr); + void InternalSaveValue(bool* valptr); + void InternalSaveValue(void** valptr); + void InternalSaveValue(int64** valptr) { + InternalSaveValue(reinterpret_cast(valptr)); + } + + BaseObject* SafeRevAlloc(BaseObject* ptr); + + int* SafeRevAllocArray(int* ptr); + int64* SafeRevAllocArray(int64* ptr); + uint64* SafeRevAllocArray(uint64* ptr); + double* SafeRevAllocArray(double* ptr); + BaseObject** SafeRevAllocArray(BaseObject** ptr); + IntVar** SafeRevAllocArray(IntVar** ptr); + IntExpr** SafeRevAllocArray(IntExpr** ptr); + Constraint** SafeRevAllocArray(Constraint** ptr); + // UnsafeRevAlloc is used internally for cells in SimpleRevFIFO + // and other structures like this. + void* UnsafeRevAllocAux(void* ptr); + template + T* UnsafeRevAlloc(T* ptr) { + return reinterpret_cast( + UnsafeRevAllocAux(reinterpret_cast(ptr))); + } + void** UnsafeRevAllocArrayAux(void** ptr); + template + T** UnsafeRevAllocArray(T** ptr) { + return reinterpret_cast( + UnsafeRevAllocArrayAux(reinterpret_cast(ptr))); + } + + void InitCachedIntConstants(); + void InitCachedConstraint(); + void InitBuilders(); + // Registers a constraint builder. + void RegisterBuilder(const std::string& tag, ConstraintBuilder builder); + // Registers an integer expression builder. + void RegisterBuilder(const std::string& tag, IntegerExpressionBuilder builder); + // Registers an interval variable builder. + void RegisterBuilder(const std::string& tag, IntervalVariableBuilder builder); + // Registers a sequence variable builder. + void RegisterBuilder(const std::string& tag, SequenceVariableBuilder builder); + void DeleteBuilders(); + + // Returns the Search object that is at the bottom of the search stack. This + // is to be contrasted with ActiveSearch(), which returns the search at the + // top of the stack. + Search* TopLevelSearch() const { return searches_.at(1); } + // Returns the Search object which is the parent of the active search, i.e. + // the search below the top of the stack. If the active search is at the + // bottom of the stack, returns the active search. + Search* ParentSearch() const { + const size_t search_size = searches_.size(); + DCHECK_GT(search_size, 1); + return searches_[search_size - 2]; + } + + // Naming + std::string GetName(const PropagationBaseObject* object); + void SetName(const PropagationBaseObject* object, const std::string& name); + + // Variable indexing (note that indexing is not reversible). + // Returns a new index for an IntVar. + int GetNewIntVarIndex() { return num_int_vars_++; } + + // Internal. + bool IsADifference(IntExpr* expr, IntExpr** const left, + IntExpr** const right); + + const std::string name_; + const ConstraintSolverParameters parameters_; + std::unordered_map propagation_object_names_; + std::unordered_map cast_information_; + std::unordered_set cast_constraints_; + const std::string empty_name_; + std::unique_ptr queue_; + std::unique_ptr trail_; + std::vector constraints_list_; + std::vector additional_constraints_list_; + std::vector additional_constraints_parent_list_; + SolverState state_; + int64 branches_; + int64 fails_; + int64 decisions_; + int64 demon_runs_[kNumPriorities]; + int64 neighbors_; + int64 filtered_neighbors_; + int64 accepted_neighbors_; + std::unique_ptr timer_; + std::vector searches_; + ACMRandom random_; + uint64 fail_stamp_; + std::unique_ptr balancing_decision_; + // intercept failures + std::function fail_intercept_; + // Demon monitor + DemonProfiler* const demon_profiler_; + // Local search profiler monitor + LocalSearchProfiler* const local_search_profiler_; + + // interval of constants cached, inclusive: + enum { MIN_CACHED_INT_CONST = -8, MAX_CACHED_INT_CONST = 8 }; + IntVar* cached_constants_[MAX_CACHED_INT_CONST + 1 - MIN_CACHED_INT_CONST]; + + // Cached constraints. + Constraint* true_constraint_; + Constraint* false_constraint_; + + std::unique_ptr fail_decision_; + int constraint_index_; + int additional_constraint_index_; + int num_int_vars_; + + // Support for model loading. + std::unordered_map expression_builders_; + std::unordered_map constraint_builders_; + std::unordered_map interval_builders_; + std::unordered_map sequence_builders_; + std::unique_ptr model_loader_; + + std::unique_ptr model_cache_; + std::unique_ptr propagation_monitor_; + PropagationMonitor* print_trace_; + std::unique_ptr local_search_monitor_; + int anonymous_variable_index_; + bool should_fail_; + + DISALLOW_COPY_AND_ASSIGN(Solver); +}; + +std::ostream& operator<<(std::ostream& out, const Solver* const s); // NOLINT + +// ---------- Misc ---------- + +// This method returns 0. It is useful when 0 can be cast either as +// a pointer or as an integer value and thus lead to an ambiguous +// function call. +inline int64 Zero() { return 0LL; } + +///////////////////////////////////////////////////////////////////// +// +// Useful Search and Modeling Objects +// +///////////////////////////////////////////////////////////////////// + +// A BaseObject is the root of all reversibly allocated objects. +// A DebugString method and the associated << operator are implemented +// as a convenience. + +class BaseObject { + public: + BaseObject() {} + virtual ~BaseObject() {} + virtual std::string DebugString() const { return "BaseObject"; } + + private: + DISALLOW_COPY_AND_ASSIGN(BaseObject); +}; + +std::ostream& operator<<(std::ostream& out, const BaseObject* o); // NOLINT + +// The PropagationBaseObject is a subclass of BaseObject that is also +// friend to the Solver class. It allows accessing methods useful when +// writing new constraints or new expressions. +class PropagationBaseObject : public BaseObject { + public: + explicit PropagationBaseObject(Solver* const s) : solver_(s) {} + ~PropagationBaseObject() override {} + + std::string DebugString() const override { + if (name().empty()) { + return "PropagationBaseObject"; + } else { + return StringPrintf("PropagationBaseObject: %s", name().c_str()); + } + } + Solver* solver() const { return solver_; } + // This method freezes the propagation queue. It is useful when you + // need to apply multiple modifications at once. + void FreezeQueue() { solver_->FreezeQueue(); } + + // This method unfreezes the propagation queue. All modifications + // that happened when the queue was frozen will be processed. + void UnfreezeQueue() { solver_->UnfreezeQueue(); } + + // This method pushes the demon onto the propagation queue. It will + // be processed directly if the queue is empty. It will be enqueued + // according to its priority otherwise. + void EnqueueDelayedDemon(Demon* const d) { solver_->EnqueueDelayedDemon(d); } + void EnqueueVar(Demon* const d) { solver_->EnqueueVar(d); } + void ExecuteAll(const SimpleRevFIFO& demons); + void EnqueueAll(const SimpleRevFIFO& demons); + +#if !defined(SWIG) + // This method sets a callback that will be called if a failure + // happens during the propagation of the queue. + void set_action_on_fail(Solver::Action a) { + solver_->set_action_on_fail(std::move(a)); + } +#endif // SWIG + + // This methods clears the failure callback. + void reset_action_on_fail() { solver_->reset_action_on_fail(); } + + // Shortcut for variable cleaner. + void set_variable_to_clean_on_fail(IntVar* v) { + solver_->set_variable_to_clean_on_fail(v); + } + + // Object naming. + virtual std::string name() const; + void set_name(const std::string& name); + // Returns whether the object has been named or not. + bool HasName() const; + // Returns a base name for automatic naming. + virtual std::string BaseName() const; + + private: + Solver* const solver_; + DISALLOW_COPY_AND_ASSIGN(PropagationBaseObject); +}; + +// A Decision represents a choice point in the search tree. The two main +// methods are Apply() to go left, or Refute() to go right. +class Decision : public BaseObject { + public: + Decision() {} + ~Decision() override {} + + // Apply will be called first when the decision is executed. + virtual void Apply(Solver* const s) = 0; + + // Refute will be called after a backtrack. + virtual void Refute(Solver* const s) = 0; + + std::string DebugString() const override { return "Decision"; } + // Accepts the given visitor. + virtual void Accept(DecisionVisitor* const visitor) const; + + private: + DISALLOW_COPY_AND_ASSIGN(Decision); +}; + +// A DecisionVisitor is used to inspect a decision. +// It contains virtual methods for all type of 'declared' decisions. +class DecisionVisitor : public BaseObject { + public: + DecisionVisitor() {} + ~DecisionVisitor() override {} + virtual void VisitSetVariableValue(IntVar* const var, int64 value); + virtual void VisitSplitVariableDomain(IntVar* const var, int64 value, + bool start_with_lower_half); + virtual void VisitScheduleOrPostpone(IntervalVar* const var, int64 est); + virtual void VisitScheduleOrExpedite(IntervalVar* const var, int64 est); + virtual void VisitRankFirstInterval(SequenceVar* const sequence, int index); + virtual void VisitRankLastInterval(SequenceVar* const sequence, int index); + virtual void VisitUnknownDecision(); + + private: + DISALLOW_COPY_AND_ASSIGN(DecisionVisitor); +}; + +// A DecisionBuilder is responsible for creating the search tree. The +// important method is Next(), which returns the next decision to execute. +class DecisionBuilder : public BaseObject { + public: + DecisionBuilder() {} + ~DecisionBuilder() override {} + // This is the main method of the decision builder class. It must + // return a decision (an instance of the class Decision). If it + // returns nullptr, this means that the decision builder has finished + // its work. + virtual Decision* Next(Solver* const s) = 0; + std::string DebugString() const override; +#if !defined(SWIG) + // This method will be called at the start of the search. It asks + // the decision builder if it wants to append search monitors to the + // list of active monitors for this search. Please note there are no + // checks at this point for duplication. + virtual void AppendMonitors(Solver* const solver, + std::vector* const extras); + virtual void Accept(ModelVisitor* const visitor) const; +#endif + + private: + DISALLOW_COPY_AND_ASSIGN(DecisionBuilder); +}; + +// A Demon is the base element of a propagation queue. It is the main +// object responsible for implementing the actual propagation +// of the constraint and pruning the inconsistent values in the domains +// of the variables. The main concept is that demons are listeners that are +// attached to the variables and listen to their modifications. +// There are two methods: +// - Run() is the actual method called when the demon is processed. +// - priority() returns its priority. Standard priorities are slow, normal +// or fast. "immediate" is reserved for variables and is treated separately. +class Demon : public BaseObject { + public: + // This indicates the priority of a demon. Immediate demons are treated + // separately and corresponds to variables. + Demon() : stamp_(GG_ULONGLONG(0)) {} + ~Demon() override {} + + // This is the main callback of the demon. + virtual void Run(Solver* const s) = 0; + + // This method returns the priority of the demon. Usually a demon is + // fast, slow or normal. Immediate demons are reserved for internal + // use to maintain variables. + virtual Solver::DemonPriority priority() const; + + std::string DebugString() const override; + + // This method inhibits the demon in the search tree below the + // current position. + void inhibit(Solver* const s); + + // This method un-inhibits the demon that was inhibited. + void desinhibit(Solver* const s); + + private: + friend class Queue; + void set_stamp(int64 stamp) { stamp_ = stamp; } + uint64 stamp() const { return stamp_; } + uint64 stamp_; + DISALLOW_COPY_AND_ASSIGN(Demon); +}; + +// Model visitor. +class ModelVisitor : public BaseObject { + public: + // Constraint and Expression types. + static const char kAbs[]; + static const char kAbsEqual[]; + static const char kAllDifferent[]; + static const char kAllowedAssignments[]; + static const char kAtMost[]; + static const char kIndexOf[]; + static const char kBetween[]; + static const char kConditionalExpr[]; + static const char kCircuit[]; + static const char kConvexPiecewise[]; + static const char kCountEqual[]; + static const char kCover[]; + static const char kCumulative[]; + static const char kDeviation[]; + static const char kDifference[]; + static const char kDisjunctive[]; + static const char kDistribute[]; + static const char kDivide[]; + static const char kDurationExpr[]; + static const char kElement[]; + static const char kElementEqual[]; + static const char kEndExpr[]; + static const char kEquality[]; + static const char kFalseConstraint[]; + static const char kGlobalCardinality[]; + static const char kGreater[]; + static const char kGreaterOrEqual[]; + static const char kIntegerVariable[]; + static const char kIntervalBinaryRelation[]; + static const char kIntervalDisjunction[]; + static const char kIntervalUnaryRelation[]; + static const char kIntervalVariable[]; + static const char kInversePermutation[]; + static const char kIsBetween[]; + static const char kIsDifferent[]; + static const char kIsEqual[]; + static const char kIsGreater[]; + static const char kIsGreaterOrEqual[]; + static const char kIsLess[]; + static const char kIsLessOrEqual[]; + static const char kIsMember[]; + static const char kLess[]; + static const char kLessOrEqual[]; + static const char kLexLess[]; + static const char kLinkExprVar[]; + static const char kMapDomain[]; + static const char kMax[]; + static const char kMaxEqual[]; + static const char kMember[]; + static const char kMin[]; + static const char kMinEqual[]; + static const char kModulo[]; + static const char kNoCycle[]; + static const char kNonEqual[]; + static const char kNotBetween[]; + static const char kNotMember[]; + static const char kNullIntersect[]; + static const char kOpposite[]; + static const char kPack[]; + static const char kPathCumul[]; + static const char kDelayedPathCumul[]; + static const char kPerformedExpr[]; + static const char kPower[]; + static const char kProduct[]; + static const char kScalProd[]; + static const char kScalProdEqual[]; + static const char kScalProdGreaterOrEqual[]; + static const char kScalProdLessOrEqual[]; + static const char kSemiContinuous[]; + static const char kSequenceVariable[]; + static const char kSortingConstraint[]; + static const char kSquare[]; + static const char kStartExpr[]; + static const char kSum[]; + static const char kSumEqual[]; + static const char kSumGreaterOrEqual[]; + static const char kSumLessOrEqual[]; + static const char kTrace[]; + static const char kTransition[]; + static const char kTrueConstraint[]; + static const char kVarBoundWatcher[]; + static const char kVarValueWatcher[]; + + // Extension names: + static const char kCountAssignedItemsExtension[]; + static const char kCountUsedBinsExtension[]; + static const char kInt64ToBoolExtension[]; + static const char kInt64ToInt64Extension[]; + static const char kObjectiveExtension[]; + static const char kSearchLimitExtension[]; + static const char kUsageEqualVariableExtension[]; + + static const char kUsageLessConstantExtension[]; + static const char kVariableGroupExtension[]; + static const char kVariableUsageLessConstantExtension[]; + static const char kWeightedSumOfAssignedEqualVariableExtension[]; + + // argument names: + static const char kActiveArgument[]; + static const char kAssumePathsArgument[]; + static const char kBranchesLimitArgument[]; + static const char kCapacityArgument[]; + static const char kCardsArgument[]; + static const char kCoefficientsArgument[]; + static const char kCountArgument[]; + static const char kCumulativeArgument[]; + static const char kCumulsArgument[]; + static const char kDemandsArgument[]; + static const char kDurationMaxArgument[]; + static const char kDurationMinArgument[]; + static const char kEarlyCostArgument[]; + static const char kEarlyDateArgument[]; + static const char kEndMaxArgument[]; + static const char kEndMinArgument[]; + static const char kEndsArgument[]; + static const char kExpressionArgument[]; + static const char kFailuresLimitArgument[]; + static const char kFinalStatesArgument[]; + static const char kFixedChargeArgument[]; + static const char kIndex2Argument[]; + static const char kIndexArgument[]; + static const char kInitialState[]; + static const char kIntervalArgument[]; + static const char kIntervalsArgument[]; + static const char kLateCostArgument[]; + static const char kLateDateArgument[]; + static const char kLeftArgument[]; + static const char kMaxArgument[]; + static const char kMaximizeArgument[]; + static const char kMinArgument[]; + static const char kModuloArgument[]; + static const char kNextsArgument[]; + static const char kOptionalArgument[]; + static const char kPartialArgument[]; + static const char kPositionXArgument[]; + static const char kPositionYArgument[]; + static const char kRangeArgument[]; + static const char kRelationArgument[]; + static const char kRightArgument[]; + static const char kSequenceArgument[]; + static const char kSequencesArgument[]; + static const char kSizeArgument[]; + static const char kSizeXArgument[]; + static const char kSizeYArgument[]; + static const char kSmartTimeCheckArgument[]; + static const char kSolutionLimitArgument[]; + static const char kStartMaxArgument[]; + static const char kStartMinArgument[]; + static const char kStartsArgument[]; + static const char kStepArgument[]; + static const char kTargetArgument[]; + static const char kTimeLimitArgument[]; + static const char kTransitsArgument[]; + static const char kTuplesArgument[]; + static const char kValueArgument[]; + static const char kValuesArgument[]; + static const char kVariableArgument[]; + static const char kVarsArgument[]; + static const char kEvaluatorArgument[]; + + // Operations. + static const char kMirrorOperation[]; + static const char kRelaxedMaxOperation[]; + static const char kRelaxedMinOperation[]; + static const char kSumOperation[]; + static const char kDifferenceOperation[]; + static const char kProductOperation[]; + static const char kStartSyncOnStartOperation[]; + static const char kStartSyncOnEndOperation[]; + static const char kTraceOperation[]; + + ~ModelVisitor() override; + + // ----- Virtual methods for visitors ----- + + // Begin/End visit element. + virtual void BeginVisitModel(const std::string& solver_name); + virtual void EndVisitModel(const std::string& solver_name); + virtual void BeginVisitConstraint(const std::string& type_name, + const Constraint* const constraint); + virtual void EndVisitConstraint(const std::string& type_name, + const Constraint* const constraint); + virtual void BeginVisitExtension(const std::string& type); + virtual void EndVisitExtension(const std::string& type); + virtual void BeginVisitIntegerExpression(const std::string& type_name, + const IntExpr* const expr); + virtual void EndVisitIntegerExpression(const std::string& type_name, + const IntExpr* const expr); + virtual void VisitIntegerVariable(const IntVar* const variable, + IntExpr* const delegate); + virtual void VisitIntegerVariable(const IntVar* const variable, + const std::string& operation, int64 value, + IntVar* const delegate); + virtual void VisitIntervalVariable(const IntervalVar* const variable, + const std::string& operation, int64 value, + IntervalVar* const delegate); + virtual void VisitSequenceVariable(const SequenceVar* const sequence); + + // Visit integer arguments. + virtual void VisitIntegerArgument(const std::string& arg_name, int64 value); + virtual void VisitIntegerArrayArgument(const std::string& arg_name, + const std::vector& values); + virtual void VisitIntegerMatrixArgument(const std::string& arg_name, + const IntTupleSet& tuples); + + // Visit integer expression argument. + virtual void VisitIntegerExpressionArgument(const std::string& arg_name, + IntExpr* const argument); + + virtual void VisitIntegerVariableArrayArgument( + const std::string& arg_name, const std::vector& arguments); + + // Visit interval argument. + virtual void VisitIntervalArgument(const std::string& arg_name, + IntervalVar* const argument); + + virtual void VisitIntervalArrayArgument( + const std::string& arg_name, const std::vector& argument); + // Visit sequence argument. + virtual void VisitSequenceArgument(const std::string& arg_name, + SequenceVar* const argument); + + virtual void VisitSequenceArrayArgument( + const std::string& arg_name, const std::vector& argument); +// Helpers. +#if !defined(SWIG) + virtual void VisitIntegerVariableEvaluatorArgument( + const std::string& arg_name, const Solver::Int64ToIntVar& arguments); + + // Using SWIG on callbacks is troublesome, so we hide these methods during + // the wrapping. + void VisitInt64ToBoolExtension(Solver::IndexFilter1 callback, int64 index_min, + int64 index_max); + void VisitInt64ToInt64Extension(const Solver::IndexEvaluator1& callback, + int64 index_min, int64 index_max); + // Expands function as array when index min is 0. + void VisitInt64ToInt64AsArray(const Solver::IndexEvaluator1& callback, + const std::string& arg_name, int64 index_max); +#endif // #if !defined(SWIG) +}; + +// A constraint is the main modeling object. It provides two methods: +// - Post() is responsible for creating the demons and attaching them to +// immediate demons(). +// - InitialPropagate() is called once just after Post and performs +// the initial propagation. The subsequent propagations will be performed +// by the demons Posted during the post() method. +class Constraint : public PropagationBaseObject { + public: + explicit Constraint(Solver* const solver) : PropagationBaseObject(solver) {} + ~Constraint() override {} + + // This method is called when the constraint is processed by the + // solver. Its main usage is to attach demons to variables. + virtual void Post() = 0; + + // This method performs the initial propagation of the + // constraint. It is called just after the post. + virtual void InitialPropagate() = 0; + std::string DebugString() const override; + + // Calls Post and then Propagate to initialize the constraints. This + // is usually done in the root node. + void PostAndPropagate(); + + // Accepts the given visitor. + virtual void Accept(ModelVisitor* const visitor) const; + + // Is the constraint created by a cast from expression to integer variable? + bool IsCastConstraint() const; + + // Creates a Boolean variable representing the status of the constraint (false + // = constraint is violated, true = constraint is satisfied). It returns + // nullptr if the constraint does not support this API. + virtual IntVar* Var(); + + private: + DISALLOW_COPY_AND_ASSIGN(Constraint); +}; + +// Cast constraints are special channeling constraints designed +// to keep a variable in sync with an expression. They are +// created internally when Var() is called on a subclass of IntExpr. +class CastConstraint : public Constraint { + public: + CastConstraint(Solver* const solver, IntVar* const target_var) + : Constraint(solver), target_var_(target_var) { + CHECK(target_var != nullptr); + } + ~CastConstraint() override {} + + IntVar* target_var() const { return target_var_; } + + protected: + IntVar* const target_var_; +}; + +// A search monitor is a simple set of callbacks to monitor all search events +class SearchMonitor : public BaseObject { + public: + static const int kNoProgress = -1; + + explicit SearchMonitor(Solver* const s) : solver_(s) {} + ~SearchMonitor() override {} + // Beginning of the search. + virtual void EnterSearch(); + + // Restart the search. + virtual void RestartSearch(); + + // End of the search. + virtual void ExitSearch(); + + // Before calling DecisionBuilder::Next. + virtual void BeginNextDecision(DecisionBuilder* const b); + + // After calling DecisionBuilder::Next, along with the returned decision. + virtual void EndNextDecision(DecisionBuilder* const b, Decision* const d); + + // Before applying the decision. + virtual void ApplyDecision(Decision* const d); + + // Before refuting the decision. + virtual void RefuteDecision(Decision* const d); + + // Just after refuting or applying the decision, apply is true after Apply. + // This is called only if the Apply() or Refute() methods have not failed. + virtual void AfterDecision(Decision* const d, bool apply); + + // Just when the failure occurs. + virtual void BeginFail(); + + // After completing the backtrack. + virtual void EndFail(); + + // Before the initial propagation. + virtual void BeginInitialPropagation(); + + // After the initial propagation. + virtual void EndInitialPropagation(); + + // This method is called when a solution is found. It asserts whether the + // solution is valid. A value of false indicates that the solution + // should be discarded. + virtual bool AcceptSolution(); + + // This method is called when a valid solution is found. If the + // return value is true, then search will resume after. If the result + // is false, then search will stop there. + virtual bool AtSolution(); + + // When the search tree is finished. + virtual void NoMoreSolutions(); + + // When a local optimum is reached. If 'true' is returned, the last solution + // is discarded and the search proceeds with the next one. + virtual bool LocalOptimum(); + + // + virtual bool AcceptDelta(Assignment* delta, Assignment* deltadelta); + + // After accepting a neighbor during local search. + virtual void AcceptNeighbor(); + + Solver* solver() const { return solver_; } + + // Periodic call to check limits in long running methods. + virtual void PeriodicCheck(); + + // Returns a percentage representing the propress of the search before + // reaching limits. + virtual int ProgressPercent() { return kNoProgress; } + + // Accepts the given model visitor. + virtual void Accept(ModelVisitor* const visitor) const; + + // Registers itself on the solver such that it gets notified of the search + // and propagation events. + virtual void Install(); + + private: + Solver* const solver_; + DISALLOW_COPY_AND_ASSIGN(SearchMonitor); +}; + +// This class adds reversibility to a POD type. +// It contains the stamp optimization. i.e. the SaveValue call is done +// only once per node of the search tree. Please note that actual +// stamps always starts at 1, thus an initial value of 0 will always +// trigger the first SaveValue. +template +class Rev { + public: + explicit Rev(const T& val) : stamp_(0), value_(val) {} + + const T& Value() const { return value_; } + + void SetValue(Solver* const s, const T& val) { + if (val != value_) { + if (stamp_ < s->stamp()) { + s->SaveValue(&value_); + stamp_ = s->stamp(); + } + value_ = val; + } + } + + private: + uint64 stamp_; + T value_; +}; + +// Subclass of Rev which adds numerical operations. +template +class NumericalRev : public Rev { + public: + explicit NumericalRev(const T& val) : Rev(val) {} + + void Add(Solver* const s, const T& to_add) { + this->SetValue(s, this->Value() + to_add); + } + + void Incr(Solver* const s) { Add(s, 1); } + + void Decr(Solver* const s) { Add(s, -1); } +}; + +// Reversible array of POD types. +// It contains the stamp optimization. i.e. the SaveValue call is done only +// once per node of the search tree. +// Please note that actual stamps always starts at 1, thus an initial value of +// 0 will always trigger the first SaveValue. +template +class RevArray { + public: + RevArray(int size, const T& val) + : stamps_(new uint64[size]), values_(new T[size]), size_(size) { + for (int i = 0; i < size; ++i) { + stamps_[i] = 0; + values_[i] = val; + } + } + + ~RevArray() {} + + int64 size() const { return size_; } + + const T& Value(int index) const { return values_[index]; } + +#if !defined(SWIG) + const T& operator[](int index) const { return values_[index]; } +#endif + + void SetValue(Solver* const s, int index, const T& val) { + DCHECK_LT(index, size_); + if (val != values_[index]) { + if (stamps_[index] < s->stamp()) { + s->SaveValue(&values_[index]); + stamps_[index] = s->stamp(); + } + values_[index] = val; + } + } + + private: + std::unique_ptr stamps_; + std::unique_ptr values_; + const int size_; +}; + +// Subclass of RevArray which adds numerical operations. +template +class NumericalRevArray : public RevArray { + public: + NumericalRevArray(int size, const T& val) : RevArray(size, val) {} + + void Add(Solver* const s, int index, const T& to_add) { + this->SetValue(s, index, this->Value(index) + to_add); + } + + void Incr(Solver* const s, int index) { Add(s, index, 1); } + + void Decr(Solver* const s, int index) { Add(s, index, -1); } +}; + +// The class IntExpr is the base of all integer expressions in +// constraint programming. +// It contains the basic protocol for an expression: +// - setting and modifying its bound +// - querying if it is bound +// - listening to events modifying its bounds +// - casting it into a variable (instance of IntVar) +class IntExpr : public PropagationBaseObject { + public: + explicit IntExpr(Solver* const s) : PropagationBaseObject(s) {} + ~IntExpr() override {} + + virtual int64 Min() const = 0; + virtual void SetMin(int64 m) = 0; + virtual int64 Max() const = 0; + virtual void SetMax(int64 m) = 0; + + // By default calls Min() and Max(), but can be redefined when Min and Max + // code can be factorized. + virtual void Range(int64* l, int64* u) { + *l = Min(); + *u = Max(); + } + // This method sets both the min and the max of the expression. + virtual void SetRange(int64 l, int64 u) { + SetMin(l); + SetMax(u); + } + + // This method sets the value of the expression. + virtual void SetValue(int64 v) { SetRange(v, v); } + + // Returns true if the min and the max of the expression are equal. + virtual bool Bound() const { return (Min() == Max()); } + + // Returns true if the expression is indeed a variable. + virtual bool IsVar() const { return false; } + + // Creates a variable from the expression. + virtual IntVar* Var() = 0; + + // Creates a variable from the expression and set the name of the + // resulting var. If the expression is already a variable, then it + // will set the name of the expression, possibly overwriting it. + // This is just a shortcut to Var() followed by set_name(). + IntVar* VarWithName(const std::string& name); + + // Attach a demon that will watch the min or the max of the expression. + virtual void WhenRange(Demon* d) = 0; + // Attach a demon that will watch the min or the max of the expression. + void WhenRange(Solver::Closure closure) { + WhenRange(solver()->MakeClosureDemon(std::move(closure))); + } + +#if !defined(SWIG) + // Attach a demon that will watch the min or the max of the expression. + void WhenRange(Solver::Action action) { + WhenRange(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + + // Accepts the given visitor. + virtual void Accept(ModelVisitor* const visitor) const; + + private: + DISALLOW_COPY_AND_ASSIGN(IntExpr); +}; + +// The class Iterator has two direct subclasses. HoleIterators +// iterates over all holes, that is value removed between the +// current min and max of the variable since the last time the +// variable was processed in the queue. DomainIterators iterates +// over all elements of the variable domain. Both iterators are not +// robust to domain changes. Hole iterators can also report values outside +// the current min and max of the variable. + +// HoleIterators should only be called from a demon attached to the +// variable that has created this iterator. + +// IntVar* current_var; +// std::unique_ptr it(current_var->MakeHoleIterator(false)); +// for (const int64 hole : InitAndGetValues(it)) { +// // use the hole +// } + +class IntVarIterator : public BaseObject { + public: + ~IntVarIterator() override {} + + // This method must be called before each loop. + virtual void Init() = 0; + + // This method indicates if we can call Value() or not. + virtual bool Ok() const = 0; + + // This method returns the current value of the iterator. + virtual int64 Value() const = 0; + + // This method moves the iterator to the next value. + virtual void Next() = 0; + + // Pretty Print. + std::string DebugString() const override { return "IntVar::Iterator"; } +}; + +#ifndef SWIG +// Utility class to encapsulate an IntVarIterator and use it in a range-based +// loop. See the code snippet above IntVarIterator. +// +// It contains DEBUG_MODE-enabled code that DCHECKs that the +// same iterator instance isn't being iterated on in multiple places +// simultaneously. +class InitAndGetValues { + public: + explicit InitAndGetValues(IntVarIterator* it) + : it_(it), begin_was_called_(false) { + it_->Init(); + } + struct Iterator; + Iterator begin() { + if (DEBUG_MODE) { + DCHECK(!begin_was_called_); + begin_was_called_ = true; + } + return Iterator::Begin(it_); + } + Iterator end() { return Iterator::End(it_); } + + struct Iterator { + // These are the only way to construct an Iterator. + static Iterator Begin(IntVarIterator* it) { + return Iterator(it, /*is_end=*/false); + } + static Iterator End(IntVarIterator* it) { + return Iterator(it, /*is_end=*/true); + } + + int64 operator*() const { + DCHECK(it_->Ok()); + return it_->Value(); + } + Iterator& operator++() { + DCHECK(it_->Ok()); + it_->Next(); + return *this; + } + bool operator!=(const Iterator& other) const { + DCHECK(other.it_ == it_); + DCHECK(other.is_end_); + return it_->Ok(); + } + + private: + Iterator(IntVarIterator* it, bool is_end) : it_(it), is_end_(is_end) {} + + IntVarIterator* const it_; + const bool is_end_; + }; + + private: + IntVarIterator* const it_; + bool begin_was_called_; +}; +#endif // SWIG + +// The class IntVar is a subset of IntExpr. In addition to the +// IntExpr protocol, it offers persistence, removing values from the domains, +// and a finer model for events. +class IntVar : public IntExpr { + public: + explicit IntVar(Solver* const s); + IntVar(Solver* const s, const std::string& name); + ~IntVar() override {} + + bool IsVar() const override { return true; } + IntVar* Var() override { return this; } + + // This method returns the value of the variable. This method checks + // before that the variable is bound. + virtual int64 Value() const = 0; + + // This method removes the value 'v' from the domain of the variable. + virtual void RemoveValue(int64 v) = 0; + + // This method removes the interval 'l' .. 'u' from the domain of + // the variable. It assumes that 'l' <= 'u'. + virtual void RemoveInterval(int64 l, int64 u) = 0; + + // This method remove the values from the domain of the variable. + virtual void RemoveValues(const std::vector& values); + + // This method intersects the current domain with the values in the array. + virtual void SetValues(const std::vector& values); + + // This method attaches a demon that will be awakened when the + // variable is bound. + virtual void WhenBound(Demon* d) = 0; + // This method attaches a closure that will be awakened when the + // variable is bound. + void WhenBound(Solver::Closure closure) { + WhenBound(solver()->MakeClosureDemon(std::move(closure))); + } + +#if !defined(SWIG) + // This method attaches an action that will be awakened when the + // variable is bound. + void WhenBound(Solver::Action action) { + WhenBound(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + + // This method attaches a demon that will watch any domain + // modification of the domain of the variable. + virtual void WhenDomain(Demon* d) = 0; + // This method attaches a closure that will watch any domain + // modification of the domain of the variable. + void WhenDomain(Solver::Closure closure) { + WhenDomain(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + // This method attaches an action that will watch any domain + // modification of the domain of the variable. + void WhenDomain(Solver::Action action) { + WhenDomain(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + + // This method returns the number of values in the domain of the variable. + virtual uint64 Size() const = 0; + + // This method returns whether the value 'v' is in the domain of the variable. + virtual bool Contains(int64 v) const = 0; + + // Creates a hole iterator. When 'reversible' is false, the returned object is + // created on the normal C++ heap and the solver does NOT take ownership of + // the object. + virtual IntVarIterator* MakeHoleIterator(bool reversible) const = 0; + + // Creates a domain iterator. When 'reversible' is false, the returned object + // is created on the normal C++ heap and the solver does NOT take ownership of + // the object. + virtual IntVarIterator* MakeDomainIterator(bool reversible) const = 0; + + // Returns the previous min. + virtual int64 OldMin() const = 0; + + // Returns the previous max. + virtual int64 OldMax() const = 0; + + virtual int VarType() const; + + // Accepts the given visitor. + void Accept(ModelVisitor* const visitor) const override; + + // IsEqual + virtual IntVar* IsEqual(int64 constant) = 0; + virtual IntVar* IsDifferent(int64 constant) = 0; + virtual IntVar* IsGreaterOrEqual(int64 constant) = 0; + virtual IntVar* IsLessOrEqual(int64 constant) = 0; + + // Returns the index of the variable. + int index() const { return index_; } + + private: + const int index_; + DISALLOW_COPY_AND_ASSIGN(IntVar); +}; + +// ---------- Solution Collectors ---------- + +// This class is the root class of all solution collectors. +// It implements a basic query API to be used independently +// from the collector used. +class SolutionCollector : public SearchMonitor { + public: + SolutionCollector(Solver* const s, const Assignment* assignment); + explicit SolutionCollector(Solver* const s); + ~SolutionCollector() override; + + // Add API. + void Add(IntVar* const var); + void Add(const std::vector& vars); + void Add(IntervalVar* const var); + void Add(const std::vector& vars); + void Add(SequenceVar* const var); + void Add(const std::vector& vars); + void AddObjective(IntVar* const objective); + + // Beginning of the search. + void EnterSearch() override; + + // Returns how many solutions were stored during the search. + int solution_count() const; + + // Returns the nth solution. + Assignment* solution(int n) const; + + // Returns the wall time in ms for the nth solution. + int64 wall_time(int n) const; + + // Returns the number of branches when the nth solution was found. + int64 branches(int n) const; + + // Returns the number of failures encountered at the time of the nth + // solution. + int64 failures(int n) const; + + // Returns the objective value of the nth solution. + int64 objective_value(int n) const; + + // This is a short-cut to get the Value of 'var' in the nth solution. + int64 Value(int n, IntVar* const var) const; + + // This is a short-cut to get the StartValue of 'var' in the nth solution. + int64 StartValue(int n, IntervalVar* const var) const; + + // This is a short-cut to get the EndValue of 'var' in the nth solution. + int64 EndValue(int n, IntervalVar* const var) const; + + // This is a short-cut to get the DurationValue of 'var' in the nth solution. + int64 DurationValue(int n, IntervalVar* const var) const; + + // This is a short-cut to get the PerformedValue of 'var' in the nth solution. + int64 PerformedValue(int n, IntervalVar* const var) const; + + // This is a short-cut to get the ForwardSequence of 'var' in the + // nth solution. The forward sequence is the list of ranked interval + // variables starting from the start of the sequence. + const std::vector& ForwardSequence(int n, SequenceVar* const var) const; + // This is a short-cut to get the BackwardSequence of 'var' in the + // nth solution. The backward sequence is the list of ranked interval + // variables starting from the end of the sequence. + const std::vector& BackwardSequence(int n, SequenceVar* const var) const; + // This is a short-cut to get the list of unperformed of 'var' in the + // nth solution. + const std::vector& Unperformed(int n, SequenceVar* const var) const; + + protected: + // Push the current state as a new solution. + void PushSolution(); + // Remove and delete the last popped solution. + void PopSolution(); + + void check_index(int n) const; + std::unique_ptr prototype_; + std::vector solutions_; + std::vector recycle_solutions_; + std::vector times_; + std::vector branches_; + std::vector failures_; + std::vector objective_values_; + + private: + DISALLOW_COPY_AND_ASSIGN(SolutionCollector); +}; + +// TODO(user): Refactor this into an Objective class: +// - print methods for AtNode and AtSolution. +// - support for weighted objective and lexicographical objective. + +// ---------- Objective Management ---------- + +// This class encapsulates an objective. It requires the direction +// (minimize or maximize), the variable to optimize, and the +// improvement step. +class OptimizeVar : public SearchMonitor { + public: + OptimizeVar(Solver* const s, bool maximize, IntVar* const a, int64 step); + ~OptimizeVar() override; + + // Returns the best value found during search. + int64 best() const { return best_; } + + // Returns the variable that is optimized. + IntVar* Var() const { return var_; } + // Internal methods. + void EnterSearch() override; + void BeginNextDecision(DecisionBuilder* const db) override; + void RefuteDecision(Decision* const d) override; + bool AtSolution() override; + bool AcceptSolution() override; + virtual std::string Print() const; + std::string DebugString() const override; + void Accept(ModelVisitor* const visitor) const override; + + void ApplyBound(); + + protected: + IntVar* const var_; + int64 step_; + int64 best_; + bool maximize_; + bool found_initial_solution_; + + private: + DISALLOW_COPY_AND_ASSIGN(OptimizeVar); +}; + +// ---------- Search Limits ---------- + +// Base class of all search limits. +class SearchLimit : public SearchMonitor { + public: + explicit SearchLimit(Solver* const s) : SearchMonitor(s), crossed_(false) {} + ~SearchLimit() override; + + // Returns true if the limit has been crossed. + bool crossed() const { return crossed_; } + + // This method is called to check the status of the limit. A return + // value of true indicates that we have indeed crossed the limit. In + // that case, this method will not be called again and the remaining + // search will be discarded. + virtual bool Check() = 0; + + // This method is called when the search limit is initialized. + virtual void Init() = 0; + + // Copy a limit. Warning: leads to a direct (no check) downcasting of 'limit' + // so one needs to be sure both SearchLimits are of the same type. + virtual void Copy(const SearchLimit* const limit) = 0; + + // Allocates a clone of the limit. + virtual SearchLimit* MakeClone() const = 0; + + // Internal methods. + void EnterSearch() override; + void BeginNextDecision(DecisionBuilder* const b) override; + void PeriodicCheck() override; + void RefuteDecision(Decision* const d) override; + std::string DebugString() const override { + return StringPrintf("SearchLimit(crossed = %i)", crossed_); + } + + private: + void TopPeriodicCheck(); + + bool crossed_; + DISALLOW_COPY_AND_ASSIGN(SearchLimit); +}; + +// ---------- NoGood Recorder ------ + +// Nogoods are used to store negative information collected during +// search. They are by definition non reversible. + +// ----- No Good ---- + +// A nogood is a conjunction of unary constraints that represents a +// state that must not be visited during search. For instance, if X +// and Y are variables, (X == 5) && (Y != 3) is a nogood that forbids +// all part of the search tree where X is 5 and Y is not 3. +class NoGood { + public: + ~NoGood(); + // Creates a term var == value. + void AddIntegerVariableEqualValueTerm(IntVar* const var, int64 value); + // Creates a term var != value. + void AddIntegerVariableNotEqualValueTerm(IntVar* const var, int64 value); + // Applies the nogood. That is if there is only one undecided term and + // all remaining terms are always true, then the opposite of this + // term is added to the solver. It returns true if the nogood is + // still active and needs to be reevaluated. + bool Apply(Solver* const solver); + // Pretty print. + std::string DebugString() const; + // TODO(user) : support interval variables and more types of constraints. + + private: + std::vector terms_; +}; + +// ----- Base class of no good manager ----- + +// A no good recorder is used to store a set of no goods in a non +// reversible way during search. It will actively propagate nogoods, +// that is if all its terms minus one are always true, then it will +// apply the reverse of this term during the search. +class NoGoodManager : public SearchMonitor { + public: + explicit NoGoodManager(Solver* const s) : SearchMonitor(s) {} + ~NoGoodManager() override {} + + // ----- User API ----- + + // Clear all stored nogoods. + virtual void Clear() = 0; + // NoGood factory. Create an empty nogood. + NoGood* MakeNoGood(); + // Add one nogood to the recorder. Ownership is transfered to the recorder. + virtual void AddNoGood(NoGood* const nogood) = 0; + // Returns the number of nogoods added to the recorder. + virtual int NoGoodCount() const = 0; + // Pretty Print. + std::string DebugString() const override = 0; + + // Internal methods that link search events to the recorder API. + void EnterSearch() override; + void BeginNextDecision(DecisionBuilder* const db) override; + bool AcceptSolution() override; + + private: + // ----- Implementor API ----- + + // Initialize data structures. + virtual void Init() = 0; + // Applies the nogood. + virtual void Apply() = 0; + + DISALLOW_COPY_AND_ASSIGN(NoGoodManager); +}; + +// ---------- Interval Var ---------- + +// Interval variables are often used in scheduling. The main characteristics +// of an IntervalVar are the start position, duration, and end +// date. All these characteristics can be queried and set, and demons can +// be posted on their modifications. +// +// An important aspect is optionality: an IntervalVar can be performed or not. +// If unperformed, then it simply does not exist, and its characteristics +// cannot be accessed any more. An interval var is automatically marked +// as unperformed when it is not consistent anymore (start greater +// than end, duration < 0...) +class IntervalVar : public PropagationBaseObject { + public: + // The smallest acceptable value to be returned by StartMin() + static const int64 kMinValidValue; + // The largest acceptable value to be returned by EndMax() + static const int64 kMaxValidValue; + IntervalVar(Solver* const solver, const std::string& name) + : PropagationBaseObject(solver) { + set_name(name); + } + ~IntervalVar() override {} + + // These methods query, set and watch the start position of the + // interval var. + virtual int64 StartMin() const = 0; + virtual int64 StartMax() const = 0; + virtual void SetStartMin(int64 m) = 0; + virtual void SetStartMax(int64 m) = 0; + virtual void SetStartRange(int64 mi, int64 ma) = 0; + virtual int64 OldStartMin() const = 0; + virtual int64 OldStartMax() const = 0; + virtual void WhenStartRange(Demon* const d) = 0; + void WhenStartRange(Solver::Closure closure) { + WhenStartRange(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + void WhenStartRange(Solver::Action action) { + WhenStartRange(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + virtual void WhenStartBound(Demon* const d) = 0; + void WhenStartBound(Solver::Closure closure) { + WhenStartBound(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + void WhenStartBound(Solver::Action action) { + WhenStartBound(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + + // These methods query, set and watch the duration of the interval var. + virtual int64 DurationMin() const = 0; + virtual int64 DurationMax() const = 0; + virtual void SetDurationMin(int64 m) = 0; + virtual void SetDurationMax(int64 m) = 0; + virtual void SetDurationRange(int64 mi, int64 ma) = 0; + virtual int64 OldDurationMin() const = 0; + virtual int64 OldDurationMax() const = 0; + virtual void WhenDurationRange(Demon* const d) = 0; + void WhenDurationRange(Solver::Closure closure) { + WhenDurationRange(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + void WhenDurationRange(Solver::Action action) { + WhenDurationRange(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + virtual void WhenDurationBound(Demon* const d) = 0; + void WhenDurationBound(Solver::Closure closure) { + WhenDurationBound(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + void WhenDurationBound(Solver::Action action) { + WhenDurationBound(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + + // These methods query, set and watch the end position of the interval var. + virtual int64 EndMin() const = 0; + virtual int64 EndMax() const = 0; + virtual void SetEndMin(int64 m) = 0; + virtual void SetEndMax(int64 m) = 0; + virtual void SetEndRange(int64 mi, int64 ma) = 0; + virtual int64 OldEndMin() const = 0; + virtual int64 OldEndMax() const = 0; + virtual void WhenEndRange(Demon* const d) = 0; + void WhenEndRange(Solver::Closure closure) { + WhenEndRange(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + void WhenEndRange(Solver::Action action) { + WhenEndRange(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + virtual void WhenEndBound(Demon* const d) = 0; + void WhenEndBound(Solver::Closure closure) { + WhenEndBound(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + void WhenEndBound(Solver::Action action) { + WhenEndBound(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + + // These methods query, set and watches the performed status of the + // interval var. + virtual bool MustBePerformed() const = 0; + virtual bool MayBePerformed() const = 0; + bool CannotBePerformed() const { return !MayBePerformed(); } + bool IsPerformedBound() const { + return MustBePerformed() || !MayBePerformed(); + } + virtual void SetPerformed(bool val) = 0; + virtual bool WasPerformedBound() const = 0; + virtual void WhenPerformedBound(Demon* const d) = 0; + void WhenPerformedBound(Solver::Closure closure) { + WhenPerformedBound(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + void WhenPerformedBound(Solver::Action action) { + WhenPerformedBound(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + + // Attaches a demon awakened when anything about this interval changes. + void WhenAnything(Demon* const d); + // Attaches a closure awakened when anything about this interval changes. + void WhenAnything(Solver::Closure closure) { + WhenAnything(solver()->MakeClosureDemon(std::move(closure))); + } +#if !defined(SWIG) + // Attaches an action awakened when anything about this interval changes. + void WhenAnything(Solver::Action action) { + WhenAnything(solver()->MakeActionDemon(std::move(action))); + } +#endif // SWIG + + // These methods create expressions encapsulating the start, end + // and duration of the interval var. Please note that these must not + // be used if the interval var is unperformed. + virtual IntExpr* StartExpr() = 0; + virtual IntExpr* DurationExpr() = 0; + virtual IntExpr* EndExpr() = 0; + virtual IntExpr* PerformedExpr() = 0; + // These methods create expressions encapsulating the start, end + // and duration of the interval var. If the interval var is + // unperformed, they will return the unperformed_value. + virtual IntExpr* SafeStartExpr(int64 unperformed_value) = 0; + virtual IntExpr* SafeDurationExpr(int64 unperformed_value) = 0; + virtual IntExpr* SafeEndExpr(int64 unperformed_value) = 0; + + // Accepts the given visitor. + virtual void Accept(ModelVisitor* const visitor) const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(IntervalVar); +}; + +// ----- SequenceVar ----- + +// A sequence variable is a variable which domain is a set of possible +// orderings of the interval variables. It allows ordering tasks. It +// has two sets of methods: ComputePossibleFirstsAndLasts() which +// returns the list of interval variables thant can be ranked first or +// lasts, and RankFirst/RankNotFirst/RankLast/RankNotLast which can be +// used to create the search decision. +class SequenceVar : public PropagationBaseObject { + public: + SequenceVar(Solver* const s, const std::vector& intervals, + const std::vector& nexts, const std::string& name); + + ~SequenceVar() override; + + std::string DebugString() const override; + +#if !defined(SWIG) + // Returns the minimum and maximum duration of combined interval + // vars in the sequence. + void DurationRange(int64* const dmin, int64* const dmax) const; + + // Returns the minimum start min and the maximum end max of all + // interval vars in the sequence. + void HorizonRange(int64* const hmin, int64* const hmax) const; + + // Returns the minimum start min and the maximum end max of all + // unranked interval vars in the sequence. + void ActiveHorizonRange(int64* const hmin, int64* const hmax) const; + + // Compute statistics on the sequence. + void ComputeStatistics(int* const ranked, int* const not_ranked, + int* const unperformed) const; +#endif // !defined(SWIG) + + // Ranks the index_th interval var first of all unranked interval + // vars. After that, it will no longer be considered ranked. + void RankFirst(int index); + + // Indicates that the index_th interval var will not be ranked first + // of all currently unranked interval vars. + void RankNotFirst(int index); + + // Ranks the index_th interval var first of all unranked interval + // vars. After that, it will no longer be considered ranked. + void RankLast(int index); + + // Indicates that the index_th interval var will not be ranked first + // of all currently unranked interval vars. + void RankNotLast(int index); + + // Computes the set of indices of interval variables that can be + // ranked first in the set of unranked activities. + void ComputePossibleFirstsAndLasts(std::vector* const possible_firsts, + std::vector* const possible_lasts); + + // Applies the following sequence of ranks, ranks first, then rank + // last. rank_first and rank_last represents different directions. + // rank_first[0] corresponds to the first interval of the sequence. + // rank_last[0] corresponds to the last interval of the sequence. + // All intervals in the unperformed vector will be marked as such. + void RankSequence(const std::vector& rank_firsts, + const std::vector& rank_lasts, + const std::vector& unperformed); + + // Clears 'rank_first' and 'rank_last', and fills them with the + // intervals in the order of the ranks. If all variables are ranked, + // 'rank_first' will contain all variables, and 'rank_last' will + // contain none. + // 'unperformed' will contains all such interval variables. + // rank_first and rank_last represents different directions. + // rank_first[0] corresponds to the first interval of the sequence. + // rank_last[0] corresponds to the last interval of the sequence. + void FillSequence(std::vector* const rank_first, + std::vector* const rank_lasts, + std::vector* const unperformed) const; + + // Returns the index_th interval of the sequence. + IntervalVar* Interval(int index) const; + + // Returns the next of the index_th interval of the sequence. + IntVar* Next(int index) const; + + // Returns the number of interval vars in the sequence. + int64 size() const { return intervals_.size(); } + + // Accepts the given visitor. + virtual void Accept(ModelVisitor* const visitor) const; + + private: + int ComputeForwardFrontier(); + int ComputeBackwardFrontier(); + void UpdatePrevious() const; + + const std::vector intervals_; + const std::vector nexts_; + mutable std::vector previous_; +}; + +// --------- Assignments ---------------------------- + +// ---------- Assignment Elements ---------- + +// ----- AssignmentElement ----- + +class AssignmentElement { + public: + AssignmentElement() : activated_(true) {} + + void Activate() { activated_ = true; } + void Deactivate() { activated_ = false; } + bool Activated() const { return activated_; } + + private: + bool activated_; +}; + +// ----- IntVarElement ----- + +class IntVarElement : public AssignmentElement { + public: + IntVarElement(); + explicit IntVarElement(IntVar* const var); + void Reset(IntVar* const var); + IntVarElement* Clone(); + void Copy(const IntVarElement& element); + IntVar* Var() const { return var_; } + void Store() { + min_ = var_->Min(); + max_ = var_->Max(); + } + void Restore() { + if (var_ != nullptr) { + var_->SetRange(min_, max_); + } + } + void LoadFromProto(const IntVarAssignment& int_var_assignment_proto); + void WriteToProto(IntVarAssignment* int_var_assignment_proto) const; + + int64 Min() const { return min_; } + void SetMin(int64 m) { min_ = m; } + int64 Max() const { return max_; } + void SetMax(int64 m) { max_ = m; } + int64 Value() const { + DCHECK_EQ(min_, max_); + // Getting the value from an unbound int var assignment element. + return min_; + } + bool Bound() const { return (max_ == min_); } + void SetRange(int64 l, int64 u) { + min_ = l; + max_ = u; + } + void SetValue(int64 v) { + min_ = v; + max_ = v; + } + std::string DebugString() const; + + bool operator==(const IntVarElement& element) const; + bool operator!=(const IntVarElement& element) const { + return !(*this == element); + } + + private: + IntVar* var_; + int64 min_; + int64 max_; +}; + +// ----- IntervalVarElement ----- + +class IntervalVarElement : public AssignmentElement { + public: + IntervalVarElement(); + explicit IntervalVarElement(IntervalVar* const var); + void Reset(IntervalVar* const var); + IntervalVarElement* Clone(); + void Copy(const IntervalVarElement& element); + IntervalVar* Var() const { return var_; } + void Store(); + void Restore(); + void LoadFromProto( + const IntervalVarAssignment& interval_var_assignment_proto); + void WriteToProto(IntervalVarAssignment* interval_var_assignment_proto) const; + + int64 StartMin() const { return start_min_; } + int64 StartMax() const { return start_max_; } + int64 StartValue() const { + CHECK_EQ(start_max_, start_min_); + return start_max_; + } + int64 DurationMin() const { return duration_min_; } + int64 DurationMax() const { return duration_max_; } + int64 DurationValue() const { + CHECK_EQ(duration_max_, duration_min_); + return duration_max_; + } + int64 EndMin() const { return end_min_; } + int64 EndMax() const { return end_max_; } + int64 EndValue() const { + CHECK_EQ(end_max_, end_min_); + return end_max_; + } + int64 PerformedMin() const { return performed_min_; } + int64 PerformedMax() const { return performed_max_; } + int64 PerformedValue() const { + CHECK_EQ(performed_max_, performed_min_); + return performed_max_; + } + void SetStartMin(int64 m) { start_min_ = m; } + void SetStartMax(int64 m) { start_max_ = m; } + void SetStartRange(int64 mi, int64 ma) { + start_min_ = mi; + start_max_ = ma; + } + void SetStartValue(int64 v) { + start_min_ = v; + start_max_ = v; + } + void SetDurationMin(int64 m) { duration_min_ = m; } + void SetDurationMax(int64 m) { duration_max_ = m; } + void SetDurationRange(int64 mi, int64 ma) { + duration_min_ = mi; + duration_max_ = ma; + } + void SetDurationValue(int64 v) { + duration_min_ = v; + duration_max_ = v; + } + void SetEndMin(int64 m) { end_min_ = m; } + void SetEndMax(int64 m) { end_max_ = m; } + void SetEndRange(int64 mi, int64 ma) { + end_min_ = mi; + end_max_ = ma; + } + void SetEndValue(int64 v) { + end_min_ = v; + end_max_ = v; + } + void SetPerformedMin(int64 m) { performed_min_ = m; } + void SetPerformedMax(int64 m) { performed_max_ = m; } + void SetPerformedRange(int64 mi, int64 ma) { + performed_min_ = mi; + performed_max_ = ma; + } + void SetPerformedValue(int64 v) { + performed_min_ = v; + performed_max_ = v; + } + std::string DebugString() const; + bool operator==(const IntervalVarElement& element) const; + bool operator!=(const IntervalVarElement& element) const { + return !(*this == element); + } + + private: + int64 start_min_; + int64 start_max_; + int64 duration_min_; + int64 duration_max_; + int64 end_min_; + int64 end_max_; + int64 performed_min_; + int64 performed_max_; + IntervalVar* var_; +}; + +// ----- SequenceVarElement ----- + +// The SequenceVarElement stores a partial representation of ranked +// interval variables in the underlying sequence variable. +// This representation consists of three vectors: +// - the forward sequence. That is the list of interval variables +// ranked first in the sequence. The first element of the backward +// sequence is the first interval in the sequence variable. +// - the backward sequence. That is the list of interval variables +// ranked last in the sequence. The first element of the backward +// sequence is the last interval in the sequence variable. +// - The list of unperformed interval variables. +// Furthermore, if all performed variables are ranked, then by +// convention, the forward_sequence will contain all such variables +// and the backward_sequence will be empty. +class SequenceVarElement : public AssignmentElement { + public: + SequenceVarElement(); + explicit SequenceVarElement(SequenceVar* const var); + void Reset(SequenceVar* const var); + SequenceVarElement* Clone(); + void Copy(const SequenceVarElement& element); + SequenceVar* Var() const { return var_; } + void Store(); + void Restore(); + void LoadFromProto( + const SequenceVarAssignment& sequence_var_assignment_proto); + void WriteToProto(SequenceVarAssignment* sequence_var_assignment_proto) const; + + const std::vector& ForwardSequence() const; + const std::vector& BackwardSequence() const; + const std::vector& Unperformed() const; + void SetSequence(const std::vector& forward_sequence, + const std::vector& backward_sequence, + const std::vector& unperformed); + void SetForwardSequence(const std::vector& forward_sequence); + void SetBackwardSequence(const std::vector& backward_sequence); + void SetUnperformed(const std::vector& unperformed); + + std::string DebugString() const; + + bool operator==(const SequenceVarElement& element) const; + bool operator!=(const SequenceVarElement& element) const { + return !(*this == element); + } + + private: + bool CheckClassInvariants(); + + SequenceVar* var_; + std::vector forward_sequence_; + std::vector backward_sequence_; + std::vector unperformed_; +}; + +// ----- Assignment element container ----- + +template +class AssignmentContainer { + public: + AssignmentContainer() {} + E* Add(V* var) { + CHECK(var != nullptr); + int index = -1; + if (!Find(var, &index)) { + return FastAdd(var); + } else { + return &elements_[index]; + } + } + // Adds element without checking its presence in the container. + E* FastAdd(V* var) { + DCHECK(var != nullptr); + elements_.emplace_back(var); + return &elements_.back(); + } + // Advanced usage: Adds element at a given position; position has to have + // been allocated with AssignmentContainer::Resize() beforehand. + E* AddAtPosition(V* var, int position) { + elements_[position].Reset(var); + return &elements_[position]; + } + void Clear() { + elements_.clear(); + if (!elements_map_.empty()) { // 2x speedup on or-tools. + elements_map_.clear(); + } + } + // Advanced usage: Resizes the container, potentially adding elements with + // null variables. + void Resize(size_t size) { elements_.resize(size); } + bool Empty() const { return elements_.empty(); } + // Copies intersection of containers. + void Copy(const AssignmentContainer& container) { + for (int i = 0; i < container.elements_.size(); ++i) { + const E& element = container.elements_[i]; + const V* const var = element.Var(); + int index = -1; + if (i < elements_.size() && elements_[i].Var() == var) { + index = i; + } else if (!Find(var, &index)) { + continue; + } + DCHECK_GE(index, 0); + E* const local_element = &elements_[index]; + local_element->Copy(element); + if (element.Activated()) { + local_element->Activate(); + } else { + local_element->Deactivate(); + } + } + } + bool Contains(const V* const var) const { + int index; + return Find(var, &index); + } + E* MutableElement(const V* const var) { + E* const element = MutableElementOrNull(var); + DCHECK(element != nullptr) << "Unknown variable " << var->DebugString() + << " in solution"; + return element; + } + E* MutableElementOrNull(const V* const var) { + int index = -1; + if (Find(var, &index)) { + return MutableElement(index); + } + return nullptr; + } + const E& Element(const V* const var) const { + const E* const element = ElementPtrOrNull(var); + DCHECK(element != nullptr) << "Unknown variable " << var->DebugString() + << " in solution"; + return *element; + } + const E* ElementPtrOrNull(const V* const var) const { + int index = -1; + if (Find(var, &index)) { + return &Element(index); + } + return nullptr; + } + const std::vector& elements() const { return elements_; } + E* MutableElement(int index) { return &elements_[index]; } + const E& Element(int index) const { return elements_[index]; } + int Size() const { return elements_.size(); } + void Store() { + for (E& element : elements_) { + element.Store(); + } + } + void Restore() { + for (E& element : elements_) { + if (element.Activated()) { + element.Restore(); + } + } + } + + // Returns true if this and 'container' both represent the same V* -> E map. + // Runs in linear time; requires that the == operator on the type E is well + // defined. + bool operator==(const AssignmentContainer& container) const { + // We may not have any work to do + if (Size() != container.Size()) { + return false; + } + // The == should be order-independent + EnsureMapIsUpToDate(); + // Do not use the hash_map::== operator! It does not just compare content, + // but also how the map is hashed (e.g., number of buckets). This is not + // what we want. + for (const E& element : container.elements_) { + const int position = FindWithDefault(elements_map_, element.Var(), -1); + if (position < 0 || elements_[position] != element) { + return false; + } + } + return true; + } + bool operator!=(const AssignmentContainer& container) const { + return !(*this == container); + } + + private: + void EnsureMapIsUpToDate() const { + std::unordered_map* map = + const_cast*>(&elements_map_); + for (int i = map->size(); i < elements_.size(); ++i) { + (*map)[elements_[i].Var()] = i; + } + } + bool Find(const V* const var, int* index) const { + // This threshold was determined from microbenchmarks on Nehalem platform. + const size_t kMaxSizeForLinearAccess = 11; + if (Size() <= kMaxSizeForLinearAccess) { + // Look for 'var' in the container by performing a linear search, avoiding + // the access to (and creation of) the elements hash table. + for (int i = 0; i < elements_.size(); ++i) { + if (var == elements_[i].Var()) { + *index = i; + return true; + } + } + return false; + } else { + EnsureMapIsUpToDate(); + DCHECK_EQ(elements_map_.size(), elements_.size()); + return FindCopy(elements_map_, var, index); + } + } + + std::vector elements_; + std::unordered_map elements_map_; +}; + +// ----- Assignment ----- + +// An Assignment is a variable -> domains mapping, used +// to report solutions to the user. +class Assignment : public PropagationBaseObject { + public: + typedef AssignmentContainer IntContainer; + typedef AssignmentContainer + IntervalContainer; + typedef AssignmentContainer + SequenceContainer; + + explicit Assignment(Solver* const s); + explicit Assignment(const Assignment* const copy); + ~Assignment() override; + + void Clear(); + bool Empty() const { + return int_var_container_.Empty() && interval_var_container_.Empty() && + sequence_var_container_.Empty(); + } + int Size() const { + return NumIntVars() + NumIntervalVars() + NumSequenceVars(); + } + int NumIntVars() const { return int_var_container_.Size(); } + int NumIntervalVars() const { return interval_var_container_.Size(); } + int NumSequenceVars() const { return sequence_var_container_.Size(); } + void Store(); + void Restore(); + + // Loads an assignment from a file; does not add variables to the + // assignment (only the variables contained in the assignment are modified). + bool Load(const std::string& filename); +#if !defined(SWIG) + bool Load(File* file); +#endif // #if !defined(SWIG) + void Load(const AssignmentProto& proto); + // Saves the assignment to a file. + bool Save(const std::string& filename) const; +#if !defined(SWIG) + bool Save(File* file) const; +#endif // #if !defined(SWIG) + void Save(AssignmentProto* const proto) const; + + void AddObjective(IntVar* const v); + IntVar* Objective() const; + bool HasObjective() const { return (objective_element_.Var() != nullptr); } + int64 ObjectiveMin() const; + int64 ObjectiveMax() const; + int64 ObjectiveValue() const; + bool ObjectiveBound() const; + void SetObjectiveMin(int64 m); + void SetObjectiveMax(int64 m); + void SetObjectiveValue(int64 value); + void SetObjectiveRange(int64 l, int64 u); + + IntVarElement* Add(IntVar* const v); + void Add(const std::vector& v); + // Adds without checking if variable has been previously added. + IntVarElement* FastAdd(IntVar* const v); + int64 Min(const IntVar* const v) const; + int64 Max(const IntVar* const v) const; + int64 Value(const IntVar* const v) const; + bool Bound(const IntVar* const v) const; + void SetMin(const IntVar* const v, int64 m); + void SetMax(const IntVar* const v, int64 m); + void SetRange(const IntVar* const v, int64 l, int64 u); + void SetValue(const IntVar* const v, int64 value); + + IntervalVarElement* Add(IntervalVar* const v); + void Add(const std::vector& vars); + // Adds without checking if variable has been previously added. + IntervalVarElement* FastAdd(IntervalVar* const v); + int64 StartMin(const IntervalVar* const v) const; + int64 StartMax(const IntervalVar* const v) const; + int64 StartValue(const IntervalVar* const v) const; + int64 DurationMin(const IntervalVar* const v) const; + int64 DurationMax(const IntervalVar* const v) const; + int64 DurationValue(const IntervalVar* const c) const; + int64 EndMin(const IntervalVar* const v) const; + int64 EndMax(const IntervalVar* const v) const; + int64 EndValue(const IntervalVar* const v) const; + int64 PerformedMin(const IntervalVar* const v) const; + int64 PerformedMax(const IntervalVar* const v) const; + int64 PerformedValue(const IntervalVar* const v) const; + void SetStartMin(const IntervalVar* const v, int64 m); + void SetStartMax(const IntervalVar* const v, int64 m); + void SetStartRange(const IntervalVar* const v, int64 mi, int64 ma); + void SetStartValue(const IntervalVar* const v, int64 value); + void SetDurationMin(const IntervalVar* const v, int64 m); + void SetDurationMax(const IntervalVar* const v, int64 m); + void SetDurationRange(const IntervalVar* const v, int64 mi, int64 ma); + void SetDurationValue(const IntervalVar* const v, int64 value); + void SetEndMin(const IntervalVar* const v, int64 m); + void SetEndMax(const IntervalVar* const v, int64 m); + void SetEndRange(const IntervalVar* const v, int64 mi, int64 ma); + void SetEndValue(const IntervalVar* const v, int64 value); + void SetPerformedMin(const IntervalVar* const v, int64 m); + void SetPerformedMax(const IntervalVar* const v, int64 m); + void SetPerformedRange(const IntervalVar* const v, int64 mi, int64 ma); + void SetPerformedValue(const IntervalVar* const v, int64 value); + + SequenceVarElement* Add(SequenceVar* const v); + void Add(const std::vector& vars); + // Adds without checking if variable has been previously added. + SequenceVarElement* FastAdd(SequenceVar* const v); + const std::vector& ForwardSequence(const SequenceVar* const v) const; + const std::vector& BackwardSequence(const SequenceVar* const v) const; + const std::vector& Unperformed(const SequenceVar* const v) const; + void SetSequence(const SequenceVar* const v, + const std::vector& forward_sequence, + const std::vector& backward_sequence, + const std::vector& unperformed); + void SetForwardSequence(const SequenceVar* const v, + const std::vector& forward_sequence); + void SetBackwardSequence(const SequenceVar* const v, + const std::vector& backward_sequence); + void SetUnperformed(const SequenceVar* const v, + const std::vector& unperformed); + + void Activate(const IntVar* const v); + void Deactivate(const IntVar* const v); + bool Activated(const IntVar* const v) const; + + void Activate(const IntervalVar* const v); + void Deactivate(const IntervalVar* const v); + bool Activated(const IntervalVar* const v) const; + + void Activate(const SequenceVar* const v); + void Deactivate(const SequenceVar* const v); + bool Activated(const SequenceVar* const v) const; + + void ActivateObjective(); + void DeactivateObjective(); + bool ActivatedObjective() const; + + std::string DebugString() const override; + + bool Contains(const IntVar* const var) const; + bool Contains(const IntervalVar* const var) const; + bool Contains(const SequenceVar* const var) const; + // Copies the intersection of the two assignments to the current assignment. + void Copy(const Assignment* assignment); + + // TODO(user): Add iterators on elements to avoid exposing container class. + const IntContainer& IntVarContainer() const { return int_var_container_; } + IntContainer* MutableIntVarContainer() { return &int_var_container_; } + const IntervalContainer& IntervalVarContainer() const { + return interval_var_container_; + } + IntervalContainer* MutableIntervalVarContainer() { + return &interval_var_container_; + } + const SequenceContainer& SequenceVarContainer() const { + return sequence_var_container_; + } + SequenceContainer* MutableSequenceVarContainer() { + return &sequence_var_container_; + } + bool operator==(const Assignment& assignment) const { + return int_var_container_ == assignment.int_var_container_ && + interval_var_container_ == assignment.interval_var_container_ && + sequence_var_container_ == assignment.sequence_var_container_ && + objective_element_ == assignment.objective_element_; + } + bool operator!=(const Assignment& assignment) const { + return !(*this == assignment); + } + + private: + IntContainer int_var_container_; + IntervalContainer interval_var_container_; + SequenceContainer sequence_var_container_; + IntVarElement objective_element_; + DISALLOW_COPY_AND_ASSIGN(Assignment); +}; + +std::ostream& operator<<(std::ostream& out, + const Assignment& assignment); // NOLINT + +// ---------- Pack Constraint ---------- + +class Pack : public Constraint { + public: + Pack(Solver* const s, const std::vector& vars, int number_of_bins); + + ~Pack() override; + + // ----- Public API ----- + + // Dimensions are additional constraints than can restrict what is + // possible with the pack constraint. It can be used to set capacity + // limits, to count objects per bin, to compute unassigned + // penalties... + + // This dimension imposes that for all bins b, the weighted sum + // (weights[i]) of all objects i assigned to 'b' is less or equal + // 'bounds[b]'. + void AddWeightedSumLessOrEqualConstantDimension( + const std::vector& weights, const std::vector& bounds); + + // This dimension imposes that for all bins b, the weighted sum + // (weights->Run(i)) of all objects i assigned to 'b' is less or + // equal to 'bounds[b]'. Ownership of the callback is transfered to + // the pack constraint. + void AddWeightedSumLessOrEqualConstantDimension( + Solver::IndexEvaluator1 weights, const std::vector& bounds); + + // This dimension imposes that for all bins b, the weighted sum + // (weights->Run(i, b) of all objects i assigned to 'b' is less or + // equal to 'bounds[b]'. Ownership of the callback is transfered to + // the pack constraint. + void AddWeightedSumLessOrEqualConstantDimension( + Solver::IndexEvaluator2 weights, const std::vector& bounds); + + // This dimension imposes that for all bins b, the weighted sum + // (weights[i]) of all objects i assigned to 'b' is equal to loads[b]. + void AddWeightedSumEqualVarDimension(const std::vector& weights, + const std::vector& loads); + + // This dimension imposes that for all bins b, the weighted sum + // (weights->Run(i, b)) of all objects i assigned to 'b' is equal to loads[b]. + void AddWeightedSumEqualVarDimension(Solver::IndexEvaluator2 weights, + const std::vector& loads); + + // This dimension imposes: + // forall b in bins, + // sum (i in items: weight[i] * is_assigned(i, b)) <= capacities[b] + // where is_assigned(i, b) is true if and only if item i is assigned + // to the bin b. + // + // This can be used to model shapes of items by linking variables of + // the same item on parallel dimensions with an allowed assignment + // constraint. + void AddSumVariableWeightsLessOrEqualConstantDimension( + const std::vector& weights, + const std::vector& capacities); + + // This dimension enforces that cost_var == sum of weights[i] for + // all objects 'i' assigned to a bin. + void AddWeightedSumOfAssignedDimension(const std::vector& weights, + IntVar* const cost_var); + + // This dimension links 'count_var' to the actual number of bins used in the + // pack. + void AddCountUsedBinDimension(IntVar* const count_var); + + // This dimension links 'count_var' to the actual number of items + // assigned to a bin in the pack. + void AddCountAssignedItemsDimension(IntVar* const count_var); + // ----- Internal API ----- + + void Post() override; + void ClearAll(); + void PropagateDelayed(); + void InitialPropagate() override; + void Propagate(); + void OneDomain(int var_index); + std::string DebugString() const override; + bool IsUndecided(int var_index, int bin_index) const; + void SetImpossible(int var_index, int bin_index); + void Assign(int var_index, int bin_index); + bool IsAssignedStatusKnown(int var_index) const; + bool IsPossible(int var_index, int bin_index) const; + IntVar* AssignVar(int var_index, int bin_index) const; + void SetAssigned(int var_index); + void SetUnassigned(int var_index); + void RemoveAllPossibleFromBin(int bin_index); + void AssignAllPossibleToBin(int bin_index); + void AssignFirstPossibleToBin(int bin_index); + void AssignAllRemainingItems(); + void UnassignAllRemainingItems(); + // Accepts the given visitor. + void Accept(ModelVisitor* const visitor) const override; + + private: + bool IsInProcess() const; + const std::vector vars_; + const int bins_; + std::vector dims_; + std::unique_ptr unprocessed_; + std::vector> forced_; + std::vector> removed_; + std::vector holes_; + uint64 stamp_; + Demon* demon_; + std::vector> to_set_; + std::vector> to_unset_; + bool in_process_; +}; + +// ----- Disjunctive Constraint ----- + +class DisjunctiveConstraint : public Constraint { + public: + DisjunctiveConstraint(Solver* const s, + const std::vector& intervals, + const std::string& name); + ~DisjunctiveConstraint() override; + + // Creates a sequence variable from the constraint. + virtual SequenceVar* MakeSequenceVar() = 0; + + // Add a transition time between intervals. It forces the distance between + // the end of interval a and start of interval b that follows it to be at + // least transit_evaluator(a, b). This function must always return + // a positive or null value. + void SetTransitionTime(Solver::IndexEvaluator2 transit_evaluator); + + int64 TransitionTime(int before_index, int after_index) { + DCHECK(transition_time_); + return transition_time_(before_index, after_index); + } + +#if !defined(SWIG) + virtual const std::vector& nexts() const = 0; + virtual const std::vector& actives() const = 0; + virtual const std::vector& time_cumuls() const = 0; + virtual const std::vector& time_slacks() const = 0; +#endif + + protected: + const std::vector intervals_; + Solver::IndexEvaluator2 transition_time_; + + private: + DISALLOW_COPY_AND_ASSIGN(DisjunctiveConstraint); +}; + +// ----- SolutionPool ----- + +// This class is used to manage a pool of solutions. It can transform +// a single point local search into a multi point local search. +class SolutionPool : public BaseObject { + public: + SolutionPool() {} + ~SolutionPool() override {} + + // This method is called to initialize the solution pool with the assignment + // from the local search. + virtual void Initialize(Assignment* const assignment) = 0; + + // This method is called when a new solution has been accepted by the local + // search. + virtual void RegisterNewSolution(Assignment* const assignment) = 0; + + // This method is called when the local search starts a new neighborhood to + // initialize the default assignment. + virtual void GetNextSolution(Assignment* const assignment) = 0; + + // This method checks if the local solution needs to be updated with + // an external one. + virtual bool SyncNeeded(Assignment* const local_assignment) = 0; +}; +} // namespace operations_research +#endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/constraint_solveri.h b/thirdparty/linux/include/ortools/constraint_solver/constraint_solveri.h new file mode 100644 index 0000000..2d2a419 --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/constraint_solveri.h @@ -0,0 +1,2784 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Collection of objects used to extend the Constraint Solver library. +// +// This file contains a set of objects that simplifies writing extensions +// of the library. +// +// The main objects that define extensions are: +// - BaseIntExpr, the base class of all expressions that are not variables. +// - SimpleRevFIFO, a reversible FIFO list with templatized values. +// A reversible data structure is a data structure that reverts its +// modifications when the search is going up in the search tree, usually +// after a failure occurs. +// - RevImmutableMultiMap, a reversible immutable multimap. +// - MakeConstraintDemon and MakeDelayedConstraintDemon to wrap methods +// of a constraint as a demon. +// - RevSwitch, a reversible flip-once switch. +// - SmallRevBitSet, RevBitSet, and RevBitMatrix: reversible 1D or 2D +// bitsets. +// - LocalSearchOperator, IntVarLocalSearchOperator, ChangeValue and +// PathOperator, to create new local search operators. +// - LocalSearchFilter and IntVarLocalSearchFilter, to create new local +// search filters. +// - BaseLns, to write Large Neighborhood Search operators. +// - SymmetryBreaker, to describe model symmetries that will be broken during +// search using the 'Symmetry Breaking During Search' framework +// see Gent, I. P., Harvey, W., & Kelsey, T. (2002). +// Groups and Constraints: Symmetry Breaking During Search. +// Principles and Practice of Constraint Programming CP2002 +// (Vol. 2470, pp. 415-430). Springer. Retrieved from +// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.11.1442. +// +// Then, there are some internal classes that are used throughout the solver +// and exposed in this file: +// - SearchLog, the root class of all periodic outputs during search. +// - ModelCache, A caching layer to avoid creating twice the same object. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ortools/base/commandlineflags.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/sysinfo.h" +#include "ortools/base/timer.h" +#include "ortools/base/join.h" +#include "ortools/base/map_util.h" +#include "ortools/base/hash.h" +#include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/model.pb.h" +#include "ortools/util/bitset.h" +#include "ortools/util/tuple_set.h" +#include "ortools/util/vector_map.h" + +class WallTimer; + +namespace operations_research { +class CPArgumentProto; +class CPConstraintProto; +class CPIntegerExpressionProto; +class CPIntervalVariableProto; + +// This is the base class for all expressions that are not variables. +// It provides a basic 'CastToVar()' implementation. +// +// The class of expressions represent two types of objects: variables +// and subclasses of BaseIntExpr. Variables are stateful objects that +// provide a rich API (remove values, WhenBound...). On the other hand, +// subclasses of BaseIntExpr represent range-only stateless objects. +// That is, std::min(A + B) is recomputed each time as std::min(A) + std::min(B). +// +// Furthermore, sometimes, the propagation on an expression is not complete, +// and Min(), Max() are not monotonic with respect to SetMin() and SetMax(). +// For instance, if A is a var with domain [0 .. 5], and B another variable +// with domain [0 .. 5], then Plus(A, B) has domain [0, 10]. +// +// If we apply SetMax(Plus(A, B), 4)), we will deduce that both A +// and B have domain [0 .. 4]. In that case, Max(Plus(A, B)) is 8 +// and not 4. To get back monotonicity, we 'cast' the expression +// into a variable using the Var() method (that will call CastToVar() +// internally). The resulting variable will be stateful and monotonic. +// +// Finally, one should never store a pointer to a IntExpr, or +// BaseIntExpr in the code. The safe code should always call Var() on an +// expression built by the solver, and store the object as an IntVar*. +// This is a consequence of the stateless nature of the expressions that +// makes the code error-prone. +class BaseIntExpr : public IntExpr { + public: + explicit BaseIntExpr(Solver* const s) : IntExpr(s), var_(nullptr) {} + ~BaseIntExpr() override {} + + IntVar* Var() override; + virtual IntVar* CastToVar(); + + private: + IntVar* var_; +}; + +// This enum is used internally to do dynamic typing on subclasses of integer +// variables. +enum VarTypes { + UNSPECIFIED, + DOMAIN_INT_VAR, + BOOLEAN_VAR, + CONST_VAR, + VAR_ADD_CST, + VAR_TIMES_CST, + CST_SUB_VAR, + OPP_VAR, + TRACE_VAR +}; + +// ----- utility classes ----- + +// This class represent a reversible FIFO structure. +// The main difference w.r.t a standard FIFO structure is that a Solver is +// given as parameter to the modifiers such that the solver can store the +// backtrack information +// Iterator's traversing order should not be changed, as some algorithm +// depend on it to be consistent. +// It's main use is to store a list of demons in the various classes of +// variables. +#ifndef SWIG +template +class SimpleRevFIFO { + private: + enum { CHUNK_SIZE = 16 }; // TODO(user): could be an extra template param + struct Chunk { + T data_[CHUNK_SIZE]; + const Chunk* const next_; + explicit Chunk(const Chunk* next) : next_(next) {} + }; + + public: + // This iterator is not stable with respect to deletion. + class Iterator { + public: + explicit Iterator(const SimpleRevFIFO* l) + : chunk_(l->chunks_), value_(l->Last()) {} + bool ok() const { return (value_ != nullptr); } + T operator*() const { return *value_; } + void operator++() { + ++value_; + if (value_ == chunk_->data_ + CHUNK_SIZE) { + chunk_ = chunk_->next_; + value_ = chunk_ ? chunk_->data_ : nullptr; + } + } + + private: + const Chunk* chunk_; + const T* value_; + }; + + SimpleRevFIFO() : chunks_(nullptr), pos_(0) {} + + void Push(Solver* const s, T val) { + if (pos_.Value() == 0) { + Chunk* const chunk = s->UnsafeRevAlloc(new Chunk(chunks_)); + s->SaveAndSetValue(reinterpret_cast(&chunks_), + reinterpret_cast(chunk)); + pos_.SetValue(s, CHUNK_SIZE - 1); + } else { + pos_.Decr(s); + } + chunks_->data_[pos_.Value()] = val; + } + + // Pushes the var on top if is not a duplicate of the current top object. + void PushIfNotTop(Solver* const s, T val) { + if (chunks_ == nullptr || LastValue() != val) { + Push(s, val); + } + } + + // Returns the last item of the FIFO. + const T* Last() const { + return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; + } + + T* MutableLast() { return chunks_ ? &chunks_->data_[pos_.Value()] : nullptr; } + + // Returns the last value in the FIFO. + const T& LastValue() const { + DCHECK(chunks_); + return chunks_->data_[pos_.Value()]; + } + + // Sets the last value in the FIFO. + void SetLastValue(const T& v) { + DCHECK(Last()); + chunks_->data_[pos_.Value()] = v; + } + + private: + Chunk* chunks_; + NumericalRev pos_; +}; + +// ---------- Reversible Hash Table ---------- + +// ----- Hash functions ----- +// TODO(user): use murmurhash. +inline uint64 Hash1(uint64 value) { + value = (~value) + (value << 21); // value = (value << 21) - value - 1; + value ^= value >> 24; + value += (value << 3) + (value << 8); // value * 265 + value ^= value >> 14; + value += (value << 2) + (value << 4); // value * 21 + value ^= value >> 28; + value += (value << 31); + return value; +} + +inline uint64 Hash1(uint32 value) { + uint64 a = value; + a = (a + 0x7ed55d16) + (a << 12); + a = (a ^ 0xc761c23c) ^ (a >> 19); + a = (a + 0x165667b1) + (a << 5); + a = (a + 0xd3a2646c) ^ (a << 9); + a = (a + 0xfd7046c5) + (a << 3); + a = (a ^ 0xb55a4f09) ^ (a >> 16); + return a; +} + +inline uint64 Hash1(int64 value) { return Hash1(static_cast(value)); } + +inline uint64 Hash1(int value) { return Hash1(static_cast(value)); } + +inline uint64 Hash1(void* const ptr) { +#if defined(ARCH_K8) || defined(__powerpc64__) || defined(__aarch64__) + return Hash1(bit_cast(ptr)); +#else + return Hash1(bit_cast(ptr)); +#endif +} + +template +uint64 Hash1(const std::vector& ptrs) { + if (ptrs.empty()) { + return 0; + } else if (ptrs.size() == 1) { + return Hash1(ptrs[0]); + } else { + uint64 hash = Hash1(ptrs[0]); + for (int i = 1; i < ptrs.size(); ++i) { + hash = hash * i + Hash1(ptrs[i]); + } + return hash; + } +} + +inline uint64 Hash1(const std::vector& ptrs) { + if (ptrs.empty()) { + return 0; + } else if (ptrs.size() == 1) { + return Hash1(ptrs[0]); + } else { + uint64 hash = Hash1(ptrs[0]); + for (int i = 1; i < ptrs.size(); ++i) { + hash = hash * i + Hash1(ptrs[i]); + } + return hash; + } +} + +// ----- Immutable Multi Map ----- + +// Reversible Immutable MultiMap class. +// Represents an immutable multi-map that backtracks with the solver. +template +class RevImmutableMultiMap { + public: + RevImmutableMultiMap(Solver* const solver, int initial_size) + : solver_(solver), + array_(solver->UnsafeRevAllocArray(new Cell*[initial_size])), + size_(initial_size), + num_items_(0) { + memset(array_, 0, sizeof(*array_) * size_.Value()); + } + + ~RevImmutableMultiMap() {} + + int num_items() const { return num_items_.Value(); } + + // Returns true if the multi-map contains at least one instance of 'key'. + bool ContainsKey(const K& key) const { + uint64 code = Hash1(key) % size_.Value(); + Cell* tmp = array_[code]; + while (tmp) { + if (tmp->key() == key) { + return true; + } + tmp = tmp->next(); + } + return false; + } + + // Returns one value attached to 'key', or 'defaut_value' if 'key' + // is not in the multi-map. The actual value returned if more than one + // values is attached to the same key is not specified. + const V& FindWithDefault(const K& key, const V& default_value) const { + uint64 code = Hash1(key) % size_.Value(); + Cell* tmp = array_[code]; + while (tmp) { + if (tmp->key() == key) { + return tmp->value(); + } + tmp = tmp->next(); + } + return default_value; + } + + // Inserts (key, value) in the multi-map. + void Insert(const K& key, const V& value) { + const int position = Hash1(key) % size_.Value(); + Cell* const cell = + solver_->UnsafeRevAlloc(new Cell(key, value, array_[position])); + solver_->SaveAndSetValue(reinterpret_cast(&array_[position]), + reinterpret_cast(cell)); + num_items_.Incr(solver_); + if (num_items_.Value() > 2 * size_.Value()) { + Double(); + } + } + + private: + class Cell { + public: + Cell(const K& key, const V& value, Cell* const next) + : key_(key), value_(value), next_(next) {} + + void SetRevNext(Solver* const solver, Cell* const next) { + solver->SaveAndSetValue(reinterpret_cast(&next_), + reinterpret_cast(next)); + } + + Cell* next() const { return next_; } + + const K& key() const { return key_; } + + const V& value() const { return value_; } + + private: + const K key_; + const V value_; + Cell* next_; + }; + + void Double() { + Cell** const old_cell_array = array_; + const int old_size = size_.Value(); + size_.SetValue(solver_, size_.Value() * 2); + solver_->SaveAndSetValue( + reinterpret_cast(&array_), + reinterpret_cast( + solver_->UnsafeRevAllocArray(new Cell*[size_.Value()]))); + memset(array_, 0, size_.Value() * sizeof(*array_)); + for (int i = 0; i < old_size; ++i) { + Cell* tmp = old_cell_array[i]; + while (tmp != nullptr) { + Cell* const to_reinsert = tmp; + tmp = tmp->next(); + const uint64 new_position = Hash1(to_reinsert->key()) % size_.Value(); + to_reinsert->SetRevNext(solver_, array_[new_position]); + solver_->SaveAndSetValue( + reinterpret_cast(&array_[new_position]), + reinterpret_cast(to_reinsert)); + } + } + } + + Solver* const solver_; + Cell** array_; + NumericalRev size_; + NumericalRev num_items_; +}; + +// A reversible switch that can switch once from false to true. +class RevSwitch { + public: + RevSwitch() : value_(false) {} + + bool Switched() const { return value_; } + + void Switch(Solver* const solver) { solver->SaveAndSetValue(&value_, true); } + + private: + bool value_; +}; + +// This class represents a small reversible bitset (size <= 64). +// This class is useful to maintain supports. +class SmallRevBitSet { + public: + explicit SmallRevBitSet(int64 size); + // Sets the 'pos' bit. + void SetToOne(Solver* const solver, int64 pos); + // Erases the 'pos' bit. + void SetToZero(Solver* const solver, int64 pos); + // Returns the number of bits set to one. + int64 Cardinality() const; + // Is bitset null? + bool IsCardinalityZero() const { return bits_.Value() == GG_ULONGLONG(0); } + // Does it contains only one bit set? + bool IsCardinalityOne() const { + return (bits_.Value() != 0) && !(bits_.Value() & (bits_.Value() - 1)); + } + // Gets the index of the first bit set starting from 0. + // It returns -1 if the bitset is empty. + int64 GetFirstOne() const; + + private: + Rev bits_; +}; + +// This class represents a reversible bitset. +// This class is useful to maintain supports. +class RevBitSet { + public: + explicit RevBitSet(int64 size); + ~RevBitSet(); + + // Sets the 'pos' bit. + void SetToOne(Solver* const solver, int64 pos); + // Erases the 'pos' bit. + void SetToZero(Solver* const solver, int64 pos); + // Returns whether the 'pos' bit is set. + bool IsSet(int64 pos) const; + // Returns the number of bits set to one. + int64 Cardinality() const; + // Is bitset null? + bool IsCardinalityZero() const; + // Does it contains only one bit set? + bool IsCardinalityOne() const; + // Gets the index of the first bit set starting from start. + // It returns -1 if the bitset is empty after start. + int64 GetFirstBit(int start) const; + // Cleans all bits. + void ClearAll(Solver* const solver); + + friend class RevBitMatrix; + + private: + // Save the offset's part of the bitset. + void Save(Solver* const solver, int offset); + const int64 size_; + const int64 length_; + uint64* bits_; + uint64* stamps_; +}; + +// Matrix version of the RevBitSet class. +class RevBitMatrix : private RevBitSet { + public: + RevBitMatrix(int64 rows, int64 columns); + ~RevBitMatrix(); + + // Sets the 'column' bit in the 'row' row. + void SetToOne(Solver* const solver, int64 row, int64 column); + // Erases the 'column' bit in the 'row' row. + void SetToZero(Solver* const solver, int64 row, int64 column); + // Returns whether the 'column' bit in the 'row' row is set. + bool IsSet(int64 row, int64 column) const { + DCHECK_GE(row, 0); + DCHECK_LT(row, rows_); + DCHECK_GE(column, 0); + DCHECK_LT(column, columns_); + return RevBitSet::IsSet(row * columns_ + column); + } + // Returns the number of bits set to one in the 'row' row. + int64 Cardinality(int row) const; + // Is bitset of row 'row' null? + bool IsCardinalityZero(int row) const; + // Does the 'row' bitset contains only one bit set? + bool IsCardinalityOne(int row) const; + // Returns the first bit in the row 'row' which position is >= 'start'. + // It returns -1 if there are none. + int64 GetFirstBit(int row, int start) const; + // Cleans all bits. + void ClearAll(Solver* const solver); + + private: + const int64 rows_; + const int64 columns_; +}; + +// @{ +// These methods represent generic demons that will call back a +// method on the constraint during their Run method. +// This way, all propagation methods are members of the constraint class, +// and demons are just proxies with a priority of NORMAL_PRIORITY. + +// Demon proxy to a method on the constraint with no arguments. +template +class CallMethod0 : public Demon { + public: + CallMethod0(T* const ct, void (T::*method)(), const std::string& name) + : constraint_(ct), method_(method), name_(name) {} + + ~CallMethod0() override {} + + void Run(Solver* const s) override { (constraint_->*method_)(); } + + std::string DebugString() const override { + return "CallMethod_" + name_ + "(" + constraint_->DebugString() + ")"; + } + + private: + T* const constraint_; + void (T::*const method_)(); + const std::string name_; +}; + +template +Demon* MakeConstraintDemon0(Solver* const s, T* const ct, void (T::*method)(), + const std::string& name) { + return s->RevAlloc(new CallMethod0(ct, method, name)); +} + +template +std::string ParameterDebugString(P param) { + return StrCat(param); +} + +// Support limited to pointers to classes which define DebugString(). +template +std::string ParameterDebugString(P* param) { + return param->DebugString(); +} + +// Demon proxy to a method on the constraint with one argument. +template +class CallMethod1 : public Demon { + public: + CallMethod1(T* const ct, void (T::*method)(P), const std::string& name, P param1) + : constraint_(ct), method_(method), name_(name), param1_(param1) {} + + ~CallMethod1() override {} + + void Run(Solver* const s) override { (constraint_->*method_)(param1_); } + + std::string DebugString() const override { + return StrCat("CallMethod_", name_, "(", constraint_->DebugString(), + ", ", ParameterDebugString(param1_), ")"); + } + + private: + T* const constraint_; + void (T::*const method_)(P); + const std::string name_; + P param1_; +}; + +template +Demon* MakeConstraintDemon1(Solver* const s, T* const ct, void (T::*method)(P), + const std::string& name, P param1) { + return s->RevAlloc(new CallMethod1(ct, method, name, param1)); +} + +// Demon proxy to a method on the constraint with two arguments. +template +class CallMethod2 : public Demon { + public: + CallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name, + P param1, Q param2) + : constraint_(ct), + method_(method), + name_(name), + param1_(param1), + param2_(param2) {} + + ~CallMethod2() override {} + + void Run(Solver* const s) override { + (constraint_->*method_)(param1_, param2_); + } + + std::string DebugString() const override { + return StrCat(StrCat("CallMethod_", name_), + StrCat("(", constraint_->DebugString()), + StrCat(", ", ParameterDebugString(param1_)), + StrCat(", ", ParameterDebugString(param2_), ")")); + } + + private: + T* const constraint_; + void (T::*const method_)(P, Q); + const std::string name_; + P param1_; + Q param2_; +}; + +template +Demon* MakeConstraintDemon2(Solver* const s, T* const ct, + void (T::*method)(P, Q), const std::string& name, + P param1, Q param2) { + return s->RevAlloc( + new CallMethod2(ct, method, name, param1, param2)); +} +// Demon proxy to a method on the constraint with three arguments. +template +class CallMethod3 : public Demon { + public: + CallMethod3(T* const ct, void (T::*method)(P, Q, R), const std::string& name, + P param1, Q param2, R param3) + : constraint_(ct), + method_(method), + name_(name), + param1_(param1), + param2_(param2), + param3_(param3) {} + + ~CallMethod3() override {} + + void Run(Solver* const s) override { + (constraint_->*method_)(param1_, param2_, param3_); + } + + std::string DebugString() const override { + return StrCat(StrCat("CallMethod_", name_), + StrCat("(", constraint_->DebugString()), + StrCat(", ", ParameterDebugString(param1_)), + StrCat(", ", ParameterDebugString(param2_)), + StrCat(", ", ParameterDebugString(param3_), ")")); + } + + private: + T* const constraint_; + void (T::*const method_)(P, Q, R); + const std::string name_; + P param1_; + Q param2_; + R param3_; +}; + +template +Demon* MakeConstraintDemon3(Solver* const s, T* const ct, + void (T::*method)(P, Q, R), const std::string& name, + P param1, Q param2, R param3) { + return s->RevAlloc( + new CallMethod3(ct, method, name, param1, param2, param3)); +} +// @} + +// @{ +// These methods represents generic demons that will call back a +// method on the constraint during their Run method. This demon will +// have a priority DELAYED_PRIORITY. + +// Low-priority demon proxy to a method on the constraint with no arguments. +template +class DelayedCallMethod0 : public Demon { + public: + DelayedCallMethod0(T* const ct, void (T::*method)(), const std::string& name) + : constraint_(ct), method_(method), name_(name) {} + + ~DelayedCallMethod0() override {} + + void Run(Solver* const s) override { (constraint_->*method_)(); } + + Solver::DemonPriority priority() const override { + return Solver::DELAYED_PRIORITY; + } + + std::string DebugString() const override { + return "DelayedCallMethod_" + name_ + "(" + constraint_->DebugString() + + ")"; + } + + private: + T* const constraint_; + void (T::*const method_)(); + const std::string name_; +}; + +template +Demon* MakeDelayedConstraintDemon0(Solver* const s, T* const ct, + void (T::*method)(), const std::string& name) { + return s->RevAlloc(new DelayedCallMethod0(ct, method, name)); +} + +// Low-priority demon proxy to a method on the constraint with one argument. +template +class DelayedCallMethod1 : public Demon { + public: + DelayedCallMethod1(T* const ct, void (T::*method)(P), const std::string& name, + P param1) + : constraint_(ct), method_(method), name_(name), param1_(param1) {} + + ~DelayedCallMethod1() override {} + + void Run(Solver* const s) override { (constraint_->*method_)(param1_); } + + Solver::DemonPriority priority() const override { + return Solver::DELAYED_PRIORITY; + } + + std::string DebugString() const override { + return StrCat("DelayedCallMethod_", name_, "(", + constraint_->DebugString(), ", ", + ParameterDebugString(param1_), ")"); + } + + private: + T* const constraint_; + void (T::*const method_)(P); + const std::string name_; + P param1_; +}; + +template +Demon* MakeDelayedConstraintDemon1(Solver* const s, T* const ct, + void (T::*method)(P), const std::string& name, + P param1) { + return s->RevAlloc(new DelayedCallMethod1(ct, method, name, param1)); +} + +// Low-priority demon proxy to a method on the constraint with two arguments. +template +class DelayedCallMethod2 : public Demon { + public: + DelayedCallMethod2(T* const ct, void (T::*method)(P, Q), const std::string& name, + P param1, Q param2) + : constraint_(ct), + method_(method), + name_(name), + param1_(param1), + param2_(param2) {} + + ~DelayedCallMethod2() override {} + + void Run(Solver* const s) override { + (constraint_->*method_)(param1_, param2_); + } + + Solver::DemonPriority priority() const override { + return Solver::DELAYED_PRIORITY; + } + + std::string DebugString() const override { + return StrCat(StrCat("DelayedCallMethod_", name_), + StrCat("(", constraint_->DebugString()), + StrCat(", ", ParameterDebugString(param1_)), + StrCat(", ", ParameterDebugString(param2_), ")")); + } + + private: + T* const constraint_; + void (T::*const method_)(P, Q); + const std::string name_; + P param1_; + Q param2_; +}; + +template +Demon* MakeDelayedConstraintDemon2(Solver* const s, T* const ct, + void (T::*method)(P, Q), const std::string& name, + P param1, Q param2) { + return s->RevAlloc( + new DelayedCallMethod2(ct, method, name, param1, param2)); +} +// @} + +#endif // !defined(SWIG) + +// ---------- Local search operators ---------- + +// The base class for all local search operators. +// +// A local search operator is an object that defines the neighborhood of a +// solution. In other words, a neighborhood is the set of solutions which can +// be reached from a given solution using an operator. +// +// The behavior of the LocalSearchOperator class is similar to iterators. +// The operator is synchronized with an assignment (gives the +// current values of the variables); this is done in the Start() method. +// +// Then one can iterate over the neighbors using the MakeNextNeighbor method. +// This method returns an assignment which represents the incremental changes +// to the current solution. It also returns a second assignment representing the +// changes to the last solution defined by the neighborhood operator; this +// assignment is empty if the neighborhood operator cannot track this +// information. +// +// TODO(user): rename Start to Synchronize ? +// TODO(user): decouple the iterating from the defining of a neighbor. +class LocalSearchOperator : public BaseObject { + public: + LocalSearchOperator() {} + ~LocalSearchOperator() override {} + virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) = 0; + virtual void Start(const Assignment* assignment) = 0; +}; + +// ----- Base operator class for operators manipulating variables ----- + +template +class VarLocalSearchOperator : public LocalSearchOperator { + public: + VarLocalSearchOperator() : activated_(), was_activated_(), cleared_(true) {} + VarLocalSearchOperator(std::vector vars, Handler var_handler) + : activated_(), + was_activated_(), + cleared_(true), + var_handler_(var_handler) {} + ~VarLocalSearchOperator() override {} + // This method should not be overridden. Override OnStart() instead which is + // called before exiting this method. + void Start(const Assignment* assignment) override { + const int size = Size(); + CHECK_LE(size, assignment->Size()) + << "Assignment contains fewer variables than operator"; + for (int i = 0; i < size; ++i) { + activated_.Set(i, var_handler_.ValueFromAssignent(*assignment, vars_[i], + i, &values_[i])); + } + old_values_ = values_; + was_activated_.SetContentFromBitsetOfSameSize(activated_); + OnStart(); + } + virtual bool IsIncremental() const { return false; } + int Size() const { return vars_.size(); } + // Returns the value in the current assignment of the variable of given index. + const Val& Value(int64 index) const { + DCHECK_LT(index, vars_.size()); + return values_[index]; + } + // Returns the variable of given index. + V* Var(int64 index) const { return vars_[index]; } + virtual bool SkipUnchanged(int index) const { return false; } + const Val& OldValue(int64 index) const { return old_values_[index]; } + void SetValue(int64 index, const Val& value) { + values_[index] = value; + MarkChange(index); + } + bool Activated(int64 index) const { return activated_[index]; } + void Activate(int64 index) { + activated_.Set(index); + MarkChange(index); + } + void Deactivate(int64 index) { + activated_.Clear(index); + MarkChange(index); + } + bool ApplyChanges(Assignment* delta, Assignment* deltadelta) const { + for (const int64 index : changes_.PositionsSetAtLeastOnce()) { + V* var = Var(index); + const Val& value = Value(index); + const bool activated = activated_[index]; + if (!activated) { + if (!cleared_ && delta_changes_[index] && IsIncremental()) { + deltadelta->FastAdd(var)->Deactivate(); + } + delta->FastAdd(var)->Deactivate(); + } else if (value != OldValue(index) || !SkipUnchanged(index)) { + if (!cleared_ && delta_changes_[index] && IsIncremental()) { + var_handler_.AddToAssignment(var, value, index, deltadelta); + } + var_handler_.AddToAssignment(var, value, index, delta); + } + } + return true; + } + void RevertChanges(bool incremental) { + cleared_ = false; + delta_changes_.SparseClearAll(); + if (incremental && IsIncremental()) return; + cleared_ = true; + for (const int64 index : changes_.PositionsSetAtLeastOnce()) { + values_[index] = old_values_[index]; + var_handler_.OnRevertChanges(index); + activated_.CopyBucket(was_activated_, index); + } + changes_.SparseClearAll(); + } + void AddVars(const std::vector& vars) { + if (!vars.empty()) { + vars_.insert(vars_.end(), vars.begin(), vars.end()); + const int64 size = Size(); + values_.resize(size); + old_values_.resize(size); + activated_.Resize(size); + was_activated_.Resize(size); + changes_.ClearAndResize(size); + delta_changes_.ClearAndResize(size); + var_handler_.OnAddVars(); + } + } + + // Called by Start() after synchronizing the operator with the current + // assignment. Should be overridden instead of Start() to avoid calling + // VarLocalSearchOperator::Start explicitly. + virtual void OnStart() {} + + // OnStart() should really be protected, but then SWIG doesn't see it. So we + // make it public, but only subclasses should access to it (to override it). + protected: + void MarkChange(int64 index) { + delta_changes_.Set(index); + changes_.Set(index); + } + + std::vector vars_; + std::vector values_; + std::vector old_values_; + Bitset64<> activated_; + Bitset64<> was_activated_; + SparseBitset<> changes_; + SparseBitset<> delta_changes_; + bool cleared_; + Handler var_handler_; +}; + +// ----- Base operator class for operators manipulating IntVars ----- + +class IntVarLocalSearchHandler { + public: + void AddToAssignment(IntVar* var, int64 value, int64 index, + Assignment* assignment) const { + assignment->FastAdd(var)->SetValue(value); + } + bool ValueFromAssignent(const Assignment& assignment, IntVar* var, + int64 index, int64* value) { + const Assignment::IntContainer& container = assignment.IntVarContainer(); + const IntVarElement* element = &(container.Element(index)); + if (element->Var() != var) { + CHECK(container.Contains(var)) + << "Assignment does not contain operator variable " << var; + element = &(container.Element(var)); + } + *value = element->Value(); + return element->Activated(); + } + void OnRevertChanges(int64 index) {} + void OnAddVars() {} +}; + +// Specialization of LocalSearchOperator built from an array of IntVars +// which specifies the scope of the operator. +// This class also takes care of storing current variable values in Start(), +// keeps track of changes done by the operator and builds the delta. +// The Deactivate() method can be used to perform Large Neighborhood Search. + +#ifdef SWIG +// Unfortunately, we must put this code here and not in +// */constraint_solver.i, because it must be parsed by SWIG before the +// derived C++ class. +// TODO(user): find a way to move this code back to the .i file, where it +// belongs. +// In python, we use a whitelist to expose the API. This whitelist must also +// be extended here. +#if defined(SWIGPYTHON) +%unignore VarLocalSearchOperator::Size; +%unignore VarLocalSearchOperator::Value; +%unignore VarLocalSearchOperator::OldValue; +%unignore VarLocalSearchOperator::SetValue; +%feature("director") VarLocalSearchOperator::IsIncremental; +%feature("director") VarLocalSearchOperator::OnStart; +%unignore VarLocalSearchOperator::IsIncremental; +%unignore VarLocalSearchOperator::OnStart; +#endif // SWIGPYTHON + +// clang-format off +%rename(IntVarLocalSearchOperatorTemplate) + VarLocalSearchOperator; +%template(IntVarLocalSearchOperatorTemplate) + VarLocalSearchOperator; +// clang-format on +#endif // SWIG + +class IntVarLocalSearchOperator + : public VarLocalSearchOperator { + public: + IntVarLocalSearchOperator() {} + explicit IntVarLocalSearchOperator(const std::vector& vars) + : VarLocalSearchOperator( + vars, IntVarLocalSearchHandler()) { + AddVars(vars); + } + ~IntVarLocalSearchOperator() override {} + // Redefines MakeNextNeighbor to export a simpler interface. The calls to + // ApplyChanges() and RevertChanges() are factored in this method, hiding both + // delta and deltadelta from subclasses which only need to override + // MakeOneNeighbor(). + // Therefore this method should not be overridden. Override MakeOneNeighbor() + // instead. + bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override; + + protected: + // Creates a new neighbor. It returns false when the neighborhood is + // completely explored. + // TODO(user): make it pure virtual, implies porting all apps overriding + // MakeNextNeighbor() in a subclass of IntVarLocalSearchOperator. + virtual bool MakeOneNeighbor(); +}; + +// ----- SequenceVarLocalSearchOperator ----- + +class SequenceVarLocalSearchOperator; + +class SequenceVarLocalSearchHandler { + public: + SequenceVarLocalSearchHandler() : op_(nullptr) {} + SequenceVarLocalSearchHandler(const SequenceVarLocalSearchHandler& other) + : op_(other.op_) {} + explicit SequenceVarLocalSearchHandler(SequenceVarLocalSearchOperator* op) + : op_(op) {} + void AddToAssignment(SequenceVar* var, const std::vector& value, + int64 index, Assignment* assignment) const; + bool ValueFromAssignent(const Assignment& assignment, SequenceVar* var, + int64 index, std::vector* value); + void OnRevertChanges(int64 index); + void OnAddVars(); + + private: + SequenceVarLocalSearchOperator* const op_; +}; + +#ifdef SWIG +// Unfortunately, we must put this code here and not in +// */constraint_solver.i, because it must be parsed by SWIG before the +// derived C++ class. +// TODO(user): find a way to move this code back to the .i file, where it +// belongs. +// clang-format off +%rename(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator< + SequenceVar, std::vector, SequenceVarLocalSearchHandler>; +%template(SequenceVarLocalSearchOperatorTemplate) VarLocalSearchOperator< + SequenceVar, std::vector, SequenceVarLocalSearchHandler>; +// clang-format on +#endif + +typedef VarLocalSearchOperator, + SequenceVarLocalSearchHandler> + SequenceVarLocalSearchOperatorTemplate; + +class SequenceVarLocalSearchOperator + : public SequenceVarLocalSearchOperatorTemplate { + public: + SequenceVarLocalSearchOperator() {} + explicit SequenceVarLocalSearchOperator(const std::vector& vars) + : SequenceVarLocalSearchOperatorTemplate( + vars, SequenceVarLocalSearchHandler(this)) { + AddVars(vars); + } + ~SequenceVarLocalSearchOperator() override {} + // Returns the value in the current assignment of the variable of given index. + const std::vector& Sequence(int64 index) const { return Value(index); } + const std::vector& OldSequence(int64 index) const { + return OldValue(index); + } + void SetForwardSequence(int64 index, const std::vector& value) { + SetValue(index, value); + } + void SetBackwardSequence(int64 index, const std::vector& value) { + backward_values_[index] = value; + MarkChange(index); + } + + protected: + friend class SequenceVarLocalSearchHandler; + + std::vector > backward_values_; +}; + +inline void SequenceVarLocalSearchHandler::AddToAssignment( + SequenceVar* var, const std::vector& value, int64 index, + Assignment* assignment) const { + SequenceVarElement* const element = assignment->FastAdd(var); + element->SetForwardSequence(value); + element->SetBackwardSequence(op_->backward_values_[index]); +} + +inline bool SequenceVarLocalSearchHandler::ValueFromAssignent( + const Assignment& assignment, SequenceVar* var, int64 index, + std::vector* value) { + const Assignment::SequenceContainer& container = + assignment.SequenceVarContainer(); + const SequenceVarElement* element = &(container.Element(index)); + if (element->Var() != var) { + CHECK(container.Contains(var)) + << "Assignment does not contain operator variable " << var; + element = &(container.Element(var)); + } + const std::vector& element_value = element->ForwardSequence(); + CHECK_GE(var->size(), element_value.size()); + op_->backward_values_[index].clear(); + *value = element_value; + return element->Activated(); +} + +inline void SequenceVarLocalSearchHandler::OnRevertChanges(int64 index) { + op_->backward_values_[index].clear(); +} + +inline void SequenceVarLocalSearchHandler::OnAddVars() { + op_->backward_values_.resize(op_->Size()); +} + +// ----- Base Large Neighborhood Search operator class ---- + +// This is the base class for building an Lns operator. An Lns fragment is a +// collection of variables which will be relaxed. Fragments are built with +// NextFragment(), which returns false if there are no more fragments to build. +// Optionally one can override InitFragments, which is called from +// LocalSearchOperator::Start to initialize fragment data. +// +// Here's a sample relaxing one variable at a time: +// +// class OneVarLns : public BaseLns { +// public: +// OneVarLns(const std::vector& vars) : BaseLns(vars), index_(0) {} +// virtual ~OneVarLns() {} +// virtual void InitFragments() { index_ = 0; } +// virtual bool NextFragment() { +// const int size = Size(); +// if (index_ < size) { +// AppendToFragment(index_); +// ++index_; +// return true; +// } else { +// return false; +// } +// } +// +// private: +// int index_; +// }; +class BaseLns : public IntVarLocalSearchOperator { + public: + explicit BaseLns(const std::vector& vars); + ~BaseLns() override; + virtual void InitFragments(); + virtual bool NextFragment() = 0; + void AppendToFragment(int index); + int FragmentSize() const; + + protected: + // This method should not be overridden. Override NextFragment() instead. + bool MakeOneNeighbor() override; + + private: + // This method should not be overridden. Override InitFragments() instead. + void OnStart() override; + std::vector fragment_; +}; + +// ----- ChangeValue Operators ----- + +// Defines operators which change the value of variables; +// each neighbor corresponds to *one* modified variable. +// Sub-classes have to define ModifyValue which determines what the new +// variable value is going to be (given the current value and the variable). +class ChangeValue : public IntVarLocalSearchOperator { + public: + explicit ChangeValue(const std::vector& vars); + ~ChangeValue() override; + virtual int64 ModifyValue(int64 index, int64 value) = 0; + + protected: + // This method should not be overridden. Override ModifyValue() instead. + bool MakeOneNeighbor() override; + + private: + void OnStart() override; + + int index_; +}; + +// ----- Path-based Operators ----- + +// Base class of the local search operators dedicated to path modifications +// (a path is a set of nodes linked together by arcs). +// This family of neighborhoods supposes they are handling next variables +// representing the arcs (var[i] represents the node immediately after i on +// a path). +// Several services are provided: +// - arc manipulators (SetNext(), ReverseChain(), MoveChain()) +// - path inspectors (Next(), IsPathEnd()) +// - path iterators: operators need a given number of nodes to define a +// neighbor; this class provides the iteration on a given number of (base) +// nodes which can be used to define a neighbor (through the BaseNode method) +// Subclasses only need to override MakeNeighbor to create neighbors using +// the services above (no direct manipulation of assignments). +class PathOperator : public IntVarLocalSearchOperator { + public: + // Builds an instance of PathOperator from next and path variables. + // 'number_of_base_nodes' is the number of nodes needed to define a + // neighbor. 'start_empty_path_class' is a callback returning an index such + // that if + // c1 = start_empty_path_class(StartNode(p1)), + // c2 = start_empty_path_class(StartNode(p2)), + // p1 and p2 are path indices, + // then if c1 == c2, p1 and p2 are equivalent if they are empty. + // This is used to remove neighborhood symmetries on equivalent empty paths; + // for instance if a node cannot be moved to an empty path, then all moves + // moving the same node to equivalent empty paths will be skipped. + // 'start_empty_path_class' can be nullptr in which case no symmetries will be + // removed. + PathOperator(const std::vector& next_vars, + const std::vector& path_vars, int number_of_base_nodes, + std::function start_empty_path_class); + ~PathOperator() override {} + virtual bool MakeNeighbor() = 0; + + // TODO(user): Make the following methods protected. + bool SkipUnchanged(int index) const override; + + // Returns the index of the node after the node of index node_index in the + // current assignment. + int64 Next(int64 node_index) const { + DCHECK(!IsPathEnd(node_index)); + return Value(node_index); + } + + // Returns the index of the path to which the node of index node_index + // belongs in the current assignment. + int64 Path(int64 node_index) const { + return ignore_path_vars_ ? 0LL : Value(node_index + number_of_nexts_); + } + + // Number of next variables. + int number_of_nexts() const { return number_of_nexts_; } + + protected: + // This method should not be overridden. Override MakeNeighbor() instead. + bool MakeOneNeighbor() override; + + // Returns the index of the variable corresponding to the ith base node. + int64 BaseNode(int i) const { return base_nodes_[i]; } + // Returns the index of the variable corresponding to the current path + // of the ith base node. + int64 StartNode(int i) const { return path_starts_[base_paths_[i]]; } + // Returns the vector of path start nodes. + const std::vector& path_starts() const { return path_starts_; } + // Returns the class of the current path of the ith base node. + int PathClass(int i) const { + return start_empty_path_class_ != nullptr + ? start_empty_path_class_(StartNode(i)) + : StartNode(i); + } + + // When the operator is being synchronized with a new solution (when Start() + // is called), returns true to restart the exploration of the neighborhood + // from the start of the last paths explored; returns false to restart the + // exploration at the last nodes visited. + // This is used to avoid restarting on base nodes which have changed paths, + // leading to potentially skipping neighbors. + // TODO(user): remove this when automatic detection of such cases in done. + virtual bool RestartAtPathStartOnSynchronize() { return false; } + // Returns true if a base node has to be on the same path as the "previous" + // base node (base node of index base_index - 1). + // Useful to limit neighborhood exploration to nodes on the same path. + // TODO(user): ideally this should be OnSamePath(int64 node1, int64 node2); + // it's currently way more complicated to implement. + virtual bool OnSamePathAsPreviousBase(int64 base_index) { return false; } + // Returns the index of the node to which the base node of index base_index + // must be set to when it reaches the end of a path. + // By default, it is set to the start of the current path. + // When this method is called, one can only assume that base nodes with + // indices < base_index have their final position. + virtual int64 GetBaseNodeRestartPosition(int base_index) { + return StartNode(base_index); + } + + int64 OldNext(int64 node_index) const { + DCHECK(!IsPathEnd(node_index)); + return OldValue(node_index); + } + + int64 OldPath(int64 node_index) const { + return ignore_path_vars_ ? 0LL : OldValue(node_index + number_of_nexts_); + } + + // Moves the chain starting after the node before_chain and ending at the node + // chain_end after the node destination + bool MoveChain(int64 before_chain, int64 chain_end, int64 destination); + + // Reverses the chain starting after before_chain and ending before + // after_chain + bool ReverseChain(int64 before_chain, int64 after_chain, int64* chain_last); + + bool MakeActive(int64 node, int64 destination); + bool MakeChainInactive(int64 before_chain, int64 chain_end); + + // Sets the to to be the node after from + void SetNext(int64 from, int64 to, int64 path) { + DCHECK_LT(from, number_of_nexts_); + SetValue(from, to); + if (!ignore_path_vars_) { + DCHECK_LT(from + number_of_nexts_, Size()); + SetValue(from + number_of_nexts_, path); + } + } + + // Returns true if i is the last node on the path; defined by the fact that + // i outside the range of the variable array + bool IsPathEnd(int64 i) const { return i >= number_of_nexts_; } + + // Returns true if node is inactive + bool IsInactive(int64 i) const { return !IsPathEnd(i) && inactives_[i]; } + + // Returns true if operator needs to restart its initial position at each + // call to Start() + virtual bool InitPosition() const { return false; } + // Reset the position of the operator to its position when Start() was last + // called; this can be used to let an operator iterate more than once over + // the paths. + void ResetPosition() { just_started_ = true; } + + const int number_of_nexts_; + const bool ignore_path_vars_; + + private: + void OnStart() override; + // Called by OnStart() after initializing node information. Should be + // overriden instead of OnStart() to avoid calling PathOperator::OnStart + // explicitly. + virtual void OnNodeInitialization() {} + // Returns true if two nodes are on the same path in the current assignment. + bool OnSamePath(int64 node1, int64 node2) const; + + bool CheckEnds() const { + const int base_node_size = base_nodes_.size(); + for (int i = base_node_size - 1; i >= 0; --i) { + if (base_nodes_[i] != end_nodes_[i]) { + return true; + } + } + return false; + } + bool IncrementPosition(); + void InitializePathStarts(); + void InitializeInactives(); + void InitializeBaseNodes(); + bool CheckChainValidity(int64 chain_start, int64 chain_end, + int64 exclude) const; + void Synchronize(); + + std::vector base_nodes_; + std::vector end_nodes_; + std::vector base_paths_; + std::vector path_starts_; + std::vector inactives_; + bool just_started_; + bool first_start_; + std::function start_empty_path_class_; +}; + +// Simple PathOperator wrapper that also stores the current previous nodes, +// and is thus able to provide the "Prev" and "IsPathStart" functions. +class PathWithPreviousNodesOperator : public PathOperator { + public: + PathWithPreviousNodesOperator( + const std::vector& vars, + const std::vector& secondary_vars, int number_of_base_nodes, + std::function start_empty_path_class); + ~PathWithPreviousNodesOperator() override {} + + bool IsPathStart(int64 node_index) const { return prevs_[node_index] == -1; } + + int64 Prev(int64 node_index) const { + DCHECK(!IsPathStart(node_index)); + return prevs_[node_index]; + } + + std::string DebugString() const override { + return "PathWithPreviousNodesOperator"; + } + + protected: + void OnNodeInitialization() override; // Initializes the "prevs_" array. + + private: + std::vector prevs_; +}; + +// ----- Operator Factories ------ + +template +LocalSearchOperator* MakeLocalSearchOperator( + Solver* solver, const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class); + +// Classes to which this template function can be applied to as of 04/2014. +// Usage: LocalSearchOperator* op = MakeLocalSearchOperator(...); +class TwoOpt; +class Relocate; +class Exchange; +class Cross; +class MakeActiveOperator; +class MakeInactiveOperator; +class MakeChainInactiveOperator; +class SwapActiveOperator; +class ExtendedSwapActiveOperator; +class MakeActiveAndRelocate; +class RelocateAndMakeActiveOperator; +class RelocateAndMakeInactiveOperator; + +// ----- Local Search Filters ------ + +// For fast neighbor pruning +class LocalSearchFilter : public BaseObject { + public: + // Accepts a "delta" given the assignment with which the filter has been + // synchronized; the delta holds the variables which have been modified and + // their new value. + // Sample: supposing one wants to maintain a[0,1] + b[0,1] <= 1, + // for the assignment (a,1), (b,0), the delta (b,1) will be rejected + // but the delta (a,0) will be accepted. + virtual bool Accept(const Assignment* delta, + const Assignment* deltadelta) = 0; + + // Synchronizes the filter with the current solution, delta being the + // difference with the solution passed to the previous call to Synchronize() + // or IncrementalSynchronize(). 'delta' can be used to incrementally + // synchronizing the filter with the new solution by only considering the + // changes in delta. + virtual void Synchronize(const Assignment* assignment, + const Assignment* delta) = 0; + virtual bool IsIncremental() const { return false; } +}; + +// ----- IntVarLocalSearchFilter ----- + +class IntVarLocalSearchFilter : public LocalSearchFilter { + public: + explicit IntVarLocalSearchFilter(const std::vector& vars); + ~IntVarLocalSearchFilter() override; + // This method should not be overridden. Override OnSynchronize() instead + // which is called before exiting this method. + void Synchronize(const Assignment* assignment, + const Assignment* delta) override; + + bool FindIndex(IntVar* const var, int64* index) const { + DCHECK(index != nullptr); + const int var_index = var->index(); + *index = (var_index < var_index_to_index_.size()) + ? var_index_to_index_[var_index] + : kUnassigned; + return *index != kUnassigned; + } + + // Add variables to "track" to the filter. + void AddVars(const std::vector& vars); + int Size() const { return vars_.size(); } + IntVar* Var(int index) const { return vars_[index]; } + int64 Value(int index) const { + DCHECK(IsVarSynced(index)); + return values_[index]; + } + bool IsVarSynced(int index) const { return var_synced_[index]; } + + protected: + virtual void OnSynchronize(const Assignment* delta) {} + void SynchronizeOnAssignment(const Assignment* assignment); + + private: + std::vector vars_; + std::vector values_; + std::vector var_synced_; + std::vector var_index_to_index_; + static const int kUnassigned; +}; + +// ---------- PropagationMonitor ---------- + +class PropagationMonitor : public SearchMonitor { + public: + explicit PropagationMonitor(Solver* const solver); + ~PropagationMonitor() override; + + // Propagation events. + virtual void BeginConstraintInitialPropagation( + Constraint* const constraint) = 0; + virtual void EndConstraintInitialPropagation( + Constraint* const constraint) = 0; + virtual void BeginNestedConstraintInitialPropagation( + Constraint* const parent, Constraint* const nested) = 0; + virtual void EndNestedConstraintInitialPropagation( + Constraint* const parent, Constraint* const nested) = 0; + virtual void RegisterDemon(Demon* const demon) = 0; + virtual void BeginDemonRun(Demon* const demon) = 0; + virtual void EndDemonRun(Demon* const demon) = 0; + virtual void StartProcessingIntegerVariable(IntVar* const var) = 0; + virtual void EndProcessingIntegerVariable(IntVar* const var) = 0; + virtual void PushContext(const std::string& context) = 0; + virtual void PopContext() = 0; + // IntExpr modifiers. + virtual void SetMin(IntExpr* const expr, int64 new_min) = 0; + virtual void SetMax(IntExpr* const expr, int64 new_max) = 0; + virtual void SetRange(IntExpr* const expr, int64 new_min, int64 new_max) = 0; + // IntVar modifiers. + virtual void SetMin(IntVar* const var, int64 new_min) = 0; + virtual void SetMax(IntVar* const var, int64 new_max) = 0; + virtual void SetRange(IntVar* const var, int64 new_min, int64 new_max) = 0; + virtual void RemoveValue(IntVar* const var, int64 value) = 0; + virtual void SetValue(IntVar* const var, int64 value) = 0; + virtual void RemoveInterval(IntVar* const var, int64 imin, int64 imax) = 0; + virtual void SetValues(IntVar* const var, + const std::vector& values) = 0; + virtual void RemoveValues(IntVar* const var, + const std::vector& values) = 0; + // IntervalVar modifiers. + virtual void SetStartMin(IntervalVar* const var, int64 new_min) = 0; + virtual void SetStartMax(IntervalVar* const var, int64 new_max) = 0; + virtual void SetStartRange(IntervalVar* const var, int64 new_min, + int64 new_max) = 0; + virtual void SetEndMin(IntervalVar* const var, int64 new_min) = 0; + virtual void SetEndMax(IntervalVar* const var, int64 new_max) = 0; + virtual void SetEndRange(IntervalVar* const var, int64 new_min, + int64 new_max) = 0; + virtual void SetDurationMin(IntervalVar* const var, int64 new_min) = 0; + virtual void SetDurationMax(IntervalVar* const var, int64 new_max) = 0; + virtual void SetDurationRange(IntervalVar* const var, int64 new_min, + int64 new_max) = 0; + virtual void SetPerformed(IntervalVar* const var, bool value) = 0; + // SequenceVar modifiers + virtual void RankFirst(SequenceVar* const var, int index) = 0; + virtual void RankNotFirst(SequenceVar* const var, int index) = 0; + virtual void RankLast(SequenceVar* const var, int index) = 0; + virtual void RankNotLast(SequenceVar* const var, int index) = 0; + virtual void RankSequence(SequenceVar* const var, + const std::vector& rank_first, + const std::vector& rank_last, + const std::vector& unperformed) = 0; + // Install itself on the solver. + void Install() override; +}; + +// ---------- LocalSearchMonitor ---------- + +class LocalSearchMonitor : public SearchMonitor { + // TODO(user): Add monitoring of local search filters. + public: + explicit LocalSearchMonitor(Solver* const solver); + ~LocalSearchMonitor() override; + + // Local search operator events. + virtual void BeginOperatorStart() = 0; + virtual void EndOperatorStart() = 0; + virtual void BeginMakeNextNeighbor(const LocalSearchOperator* op) = 0; + virtual void EndMakeNextNeighbor(const LocalSearchOperator* op, + bool neighbor_found, const Assignment* delta, + const Assignment* deltadelta) = 0; + virtual void BeginFilterNeighbor(const LocalSearchOperator* op) = 0; + virtual void EndFilterNeighbor(const LocalSearchOperator* op, + bool neighbor_found) = 0; + virtual void BeginAcceptNeighbor(const LocalSearchOperator* op) = 0; + virtual void EndAcceptNeighbor(const LocalSearchOperator* op, + bool neighbor_found) = 0; + virtual void BeginFiltering(const LocalSearchFilter* filter) = 0; + virtual void EndFiltering(const LocalSearchFilter* filter, bool reject) = 0; + + // Install itself on the solver. + void Install() override; +}; + +// ----- Boolean Variable ----- + +class BooleanVar : public IntVar { + public: + static const int kUnboundBooleanVarValue; + + explicit BooleanVar(Solver* const s, const std::string& name = "") + : IntVar(s, name), value_(kUnboundBooleanVarValue) {} + + ~BooleanVar() override {} + + int64 Min() const override { return (value_ == 1); } + void SetMin(int64 m) override; + int64 Max() const override { return (value_ != 0); } + void SetMax(int64 m) override; + void SetRange(int64 l, int64 u) override; + bool Bound() const override { return (value_ != kUnboundBooleanVarValue); } + int64 Value() const override { + CHECK_NE(value_, kUnboundBooleanVarValue) << "variable is not bound"; + return value_; + } + void RemoveValue(int64 v) override; + void RemoveInterval(int64 l, int64 u) override; + void WhenBound(Demon* d) override; + void WhenRange(Demon* d) override { WhenBound(d); } + void WhenDomain(Demon* d) override { WhenBound(d); } + uint64 Size() const override; + bool Contains(int64 v) const override; + IntVarIterator* MakeHoleIterator(bool reversible) const override; + IntVarIterator* MakeDomainIterator(bool reversible) const override; + std::string DebugString() const override; + int VarType() const override { return BOOLEAN_VAR; } + + IntVar* IsEqual(int64 constant) override; + IntVar* IsDifferent(int64 constant) override; + IntVar* IsGreaterOrEqual(int64 constant) override; + IntVar* IsLessOrEqual(int64 constant) override; + + virtual void RestoreValue() = 0; + std::string BaseName() const override { return "BooleanVar"; } + + int RawValue() const { return value_; } + + protected: + int value_; + SimpleRevFIFO bound_demons_; + SimpleRevFIFO delayed_bound_demons_; +}; + +// ---------- SymmetryBreaker ---------- + +class SymmetryManager; + +// A symmetry breaker is an object that will visit a decision and +// create the 'symmetrical' decision in return. +// Each symmetry breaker represents one class of symmetry. +class SymmetryBreaker : public DecisionVisitor { + public: + SymmetryBreaker() + : symmetry_manager_(nullptr), index_in_symmetry_manager_(-1) {} + ~SymmetryBreaker() override {} + + void AddIntegerVariableEqualValueClause(IntVar* const var, int64 value); + void AddIntegerVariableGreaterOrEqualValueClause(IntVar* const var, + int64 value); + void AddIntegerVariableLessOrEqualValueClause(IntVar* const var, int64 value); + + private: + friend class SymmetryManager; + void set_symmetry_manager_and_index(SymmetryManager* manager, int index) { + CHECK(symmetry_manager_ == nullptr); + CHECK_EQ(-1, index_in_symmetry_manager_); + symmetry_manager_ = manager; + index_in_symmetry_manager_ = index; + } + SymmetryManager* symmetry_manager() const { return symmetry_manager_; } + int index_in_symmetry_manager() const { return index_in_symmetry_manager_; } + + SymmetryManager* symmetry_manager_; + // Index of the symmetry breaker when used inside the symmetry manager. + int index_in_symmetry_manager_; +}; + +// ---------- Search Log --------- + +// The base class of all search logs that periodically outputs information when +// the search is running. +class SearchLog : public SearchMonitor { + public: + SearchLog(Solver* const s, OptimizeVar* const obj, IntVar* const var, + std::function display_callback, int period); + ~SearchLog() override; + void EnterSearch() override; + void ExitSearch() override; + bool AtSolution() override; + void BeginFail() override; + void NoMoreSolutions() override; + void ApplyDecision(Decision* const decision) override; + void RefuteDecision(Decision* const decision) override; + void OutputDecision(); + void Maintain(); + void BeginInitialPropagation() override; + void EndInitialPropagation() override; + std::string DebugString() const override; + + protected: + /* Bottleneck function used for all UI related output. */ + virtual void OutputLine(const std::string& line); + + private: + static std::string MemoryUsage(); + + const int period_; + std::unique_ptr timer_; + IntVar* const var_; + OptimizeVar* const obj_; + std::function display_callback_; + int nsol_; + int64 tick_; + int64 objective_min_; + int64 objective_max_; + int min_right_depth_; + int max_depth_; + int sliding_min_depth_; + int sliding_max_depth_; +}; + +// Implements a complete cache for model elements: expressions and +// constraints. Caching is based on the signatures of the elements, as +// well as their types. This class is used internally to avoid creating +// duplicate objects. +class ModelCache { + public: + enum VoidConstraintType { + VOID_FALSE_CONSTRAINT = 0, + VOID_TRUE_CONSTRAINT, + VOID_CONSTRAINT_MAX, + }; + + enum VarConstantConstraintType { + VAR_CONSTANT_EQUALITY = 0, + VAR_CONSTANT_GREATER_OR_EQUAL, + VAR_CONSTANT_LESS_OR_EQUAL, + VAR_CONSTANT_NON_EQUALITY, + VAR_CONSTANT_CONSTRAINT_MAX, + }; + + enum VarConstantConstantConstraintType { + VAR_CONSTANT_CONSTANT_BETWEEN = 0, + VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX, + }; + + enum ExprExprConstraintType { + EXPR_EXPR_EQUALITY = 0, + EXPR_EXPR_GREATER, + EXPR_EXPR_GREATER_OR_EQUAL, + EXPR_EXPR_LESS, + EXPR_EXPR_LESS_OR_EQUAL, + EXPR_EXPR_NON_EQUALITY, + EXPR_EXPR_CONSTRAINT_MAX, + }; + + enum ExprExpressionType { + EXPR_OPPOSITE = 0, + EXPR_ABS, + EXPR_SQUARE, + EXPR_EXPRESSION_MAX, + }; + + enum ExprExprExpressionType { + EXPR_EXPR_DIFFERENCE = 0, + EXPR_EXPR_PROD, + EXPR_EXPR_DIV, + EXPR_EXPR_MAX, + EXPR_EXPR_MIN, + EXPR_EXPR_SUM, + EXPR_EXPR_IS_LESS, + EXPR_EXPR_IS_LESS_OR_EQUAL, + EXPR_EXPR_IS_EQUAL, + EXPR_EXPR_IS_NOT_EQUAL, + EXPR_EXPR_EXPRESSION_MAX, + }; + + enum ExprExprConstantExpressionType { + EXPR_EXPR_CONSTANT_CONDITIONAL = 0, + EXPR_EXPR_CONSTANT_EXPRESSION_MAX, + }; + + enum ExprConstantExpressionType { + EXPR_CONSTANT_DIFFERENCE = 0, + EXPR_CONSTANT_DIVIDE, + EXPR_CONSTANT_PROD, + EXPR_CONSTANT_MAX, + EXPR_CONSTANT_MIN, + EXPR_CONSTANT_SUM, + EXPR_CONSTANT_IS_EQUAL, + EXPR_CONSTANT_IS_NOT_EQUAL, + EXPR_CONSTANT_IS_GREATER_OR_EQUAL, + EXPR_CONSTANT_IS_LESS_OR_EQUAL, + EXPR_CONSTANT_EXPRESSION_MAX, + }; + enum VarConstantConstantExpressionType { + VAR_CONSTANT_CONSTANT_SEMI_CONTINUOUS = 0, + VAR_CONSTANT_CONSTANT_EXPRESSION_MAX, + }; + + enum VarConstantArrayExpressionType { + VAR_CONSTANT_ARRAY_ELEMENT = 0, + VAR_CONSTANT_ARRAY_EXPRESSION_MAX, + }; + + enum VarArrayConstantArrayExpressionType { + VAR_ARRAY_CONSTANT_ARRAY_SCAL_PROD = 0, + VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX, + }; + + enum VarArrayExpressionType { + VAR_ARRAY_MAX = 0, + VAR_ARRAY_MIN, + VAR_ARRAY_SUM, + VAR_ARRAY_EXPRESSION_MAX, + }; + + enum VarArrayConstantExpressionType { + VAR_ARRAY_CONSTANT_INDEX = 0, + VAR_ARRAY_CONSTANT_EXPRESSION_MAX, + }; + + explicit ModelCache(Solver* const solver); + virtual ~ModelCache(); + + virtual void Clear() = 0; + + // Void constraints. + + virtual Constraint* FindVoidConstraint(VoidConstraintType type) const = 0; + + virtual void InsertVoidConstraint(Constraint* const ct, + VoidConstraintType type) = 0; + + // Var Constant Constraints. + virtual Constraint* FindVarConstantConstraint( + IntVar* const var, int64 value, VarConstantConstraintType type) const = 0; + + virtual void InsertVarConstantConstraint(Constraint* const ct, + IntVar* const var, int64 value, + VarConstantConstraintType type) = 0; + + // Var Constant Constant Constraints. + + virtual Constraint* FindVarConstantConstantConstraint( + IntVar* const var, int64 value1, int64 value2, + VarConstantConstantConstraintType type) const = 0; + + virtual void InsertVarConstantConstantConstraint( + Constraint* const ct, IntVar* const var, int64 value1, int64 value2, + VarConstantConstantConstraintType type) = 0; + + // Expr Expr Constraints. + + virtual Constraint* FindExprExprConstraint( + IntExpr* const expr1, IntExpr* const expr2, + ExprExprConstraintType type) const = 0; + + virtual void InsertExprExprConstraint(Constraint* const ct, + IntExpr* const expr1, + IntExpr* const expr2, + ExprExprConstraintType type) = 0; + + // Expr Expressions. + + virtual IntExpr* FindExprExpression(IntExpr* const expr, + ExprExpressionType type) const = 0; + + virtual void InsertExprExpression(IntExpr* const expression, + IntExpr* const expr, + ExprExpressionType type) = 0; + + // Expr Constant Expressions. + + virtual IntExpr* FindExprConstantExpression( + IntExpr* const expr, int64 value, + ExprConstantExpressionType type) const = 0; + + virtual void InsertExprConstantExpression( + IntExpr* const expression, IntExpr* const var, int64 value, + ExprConstantExpressionType type) = 0; + + // Expr Expr Expressions. + + virtual IntExpr* FindExprExprExpression( + IntExpr* const var1, IntExpr* const var2, + ExprExprExpressionType type) const = 0; + + virtual void InsertExprExprExpression(IntExpr* const expression, + IntExpr* const var1, + IntExpr* const var2, + ExprExprExpressionType type) = 0; + + // Expr Expr Constant Expressions. + + virtual IntExpr* FindExprExprConstantExpression( + IntExpr* const var1, IntExpr* const var2, int64 constant, + ExprExprConstantExpressionType type) const = 0; + + virtual void InsertExprExprConstantExpression( + IntExpr* const expression, IntExpr* const var1, IntExpr* const var2, + int64 constant, ExprExprConstantExpressionType type) = 0; + + // Var Constant Constant Expressions. + + virtual IntExpr* FindVarConstantConstantExpression( + IntVar* const var, int64 value1, int64 value2, + VarConstantConstantExpressionType type) const = 0; + + virtual void InsertVarConstantConstantExpression( + IntExpr* const expression, IntVar* const var, int64 value1, int64 value2, + VarConstantConstantExpressionType type) = 0; + + // Var Constant Array Expressions. + + virtual IntExpr* FindVarConstantArrayExpression( + IntVar* const var, const std::vector& values, + VarConstantArrayExpressionType type) const = 0; + + virtual void InsertVarConstantArrayExpression( + IntExpr* const expression, IntVar* const var, + const std::vector& values, + VarConstantArrayExpressionType type) = 0; + + // Var Array Expressions. + + virtual IntExpr* FindVarArrayExpression( + const std::vector& vars, VarArrayExpressionType type) const = 0; + + virtual void InsertVarArrayExpression(IntExpr* const expression, + const std::vector& vars, + VarArrayExpressionType type) = 0; + + // Var Array Constant Array Expressions. + + virtual IntExpr* FindVarArrayConstantArrayExpression( + const std::vector& vars, const std::vector& values, + VarArrayConstantArrayExpressionType type) const = 0; + + virtual void InsertVarArrayConstantArrayExpression( + IntExpr* const expression, const std::vector& var, + const std::vector& values, + VarArrayConstantArrayExpressionType type) = 0; + + // Var Array Constant Expressions. + + virtual IntExpr* FindVarArrayConstantExpression( + const std::vector& vars, int64 value, + VarArrayConstantExpressionType type) const = 0; + + virtual void InsertVarArrayConstantExpression( + IntExpr* const expression, const std::vector& var, int64 value, + VarArrayConstantExpressionType type) = 0; + + Solver* solver() const; + + private: + Solver* const solver_; +}; + +// Argument Holder: useful when visiting a model. +#if !defined(SWIG) +class ArgumentHolder { + public: + // Type of the argument. + const std::string& TypeName() const; + void SetTypeName(const std::string& type_name); + + // Setters. + void SetIntegerArgument(const std::string& arg_name, int64 value); + void SetIntegerArrayArgument(const std::string& arg_name, + const std::vector& values); + void SetIntegerMatrixArgument(const std::string& arg_name, + const IntTupleSet& values); + void SetIntegerExpressionArgument(const std::string& arg_name, + IntExpr* const expr); + void SetIntegerVariableArrayArgument(const std::string& arg_name, + const std::vector& vars); + void SetIntervalArgument(const std::string& arg_name, IntervalVar* const var); + void SetIntervalArrayArgument(const std::string& arg_name, + const std::vector& vars); + void SetSequenceArgument(const std::string& arg_name, SequenceVar* const var); + void SetSequenceArrayArgument(const std::string& arg_name, + const std::vector& vars); + + // Checks if arguments exist. + bool HasIntegerExpressionArgument(const std::string& arg_name) const; + bool HasIntegerVariableArrayArgument(const std::string& arg_name) const; + + // Getters. + int64 FindIntegerArgumentWithDefault(const std::string& arg_name, int64 def) const; + int64 FindIntegerArgumentOrDie(const std::string& arg_name) const; + const std::vector& FindIntegerArrayArgumentOrDie( + const std::string& arg_name) const; + const IntTupleSet& FindIntegerMatrixArgumentOrDie( + const std::string& arg_name) const; + + IntExpr* FindIntegerExpressionArgumentOrDie(const std::string& arg_name) const; + const std::vector& FindIntegerVariableArrayArgumentOrDie( + const std::string& arg_name) const; + + private: + std::string type_name_; + std::unordered_map integer_argument_; + std::unordered_map > integer_array_argument_; + std::unordered_map matrix_argument_; + std::unordered_map integer_expression_argument_; + std::unordered_map interval_argument_; + std::unordered_map sequence_argument_; + std::unordered_map > integer_variable_array_argument_; + std::unordered_map > interval_array_argument_; + std::unordered_map > sequence_array_argument_; +}; + +// Model Parser + +class ModelParser : public ModelVisitor { + public: + ModelParser(); + + ~ModelParser() override; + + // Header/footers. + void BeginVisitModel(const std::string& solver_name) override; + void EndVisitModel(const std::string& solver_name) override; + void BeginVisitConstraint(const std::string& type_name, + const Constraint* const constraint) override; + void EndVisitConstraint(const std::string& type_name, + const Constraint* const constraint) override; + void BeginVisitIntegerExpression(const std::string& type_name, + const IntExpr* const expr) override; + void EndVisitIntegerExpression(const std::string& type_name, + const IntExpr* const expr) override; + void VisitIntegerVariable(const IntVar* const variable, + IntExpr* const delegate) override; + void VisitIntegerVariable(const IntVar* const variable, + const std::string& operation, int64 value, + IntVar* const delegate) override; + void VisitIntervalVariable(const IntervalVar* const variable, + const std::string& operation, int64 value, + IntervalVar* const delegate) override; + void VisitSequenceVariable(const SequenceVar* const variable) override; + // Integer arguments + void VisitIntegerArgument(const std::string& arg_name, int64 value) override; + void VisitIntegerArrayArgument(const std::string& arg_name, + const std::vector& values) override; + void VisitIntegerMatrixArgument(const std::string& arg_name, + const IntTupleSet& values) override; + // Variables. + void VisitIntegerExpressionArgument(const std::string& arg_name, + IntExpr* const argument) override; + void VisitIntegerVariableArrayArgument( + const std::string& arg_name, const std::vector& arguments) override; + // Visit interval argument. + void VisitIntervalArgument(const std::string& arg_name, + IntervalVar* const argument) override; + void VisitIntervalArrayArgument( + const std::string& arg_name, + const std::vector& arguments) override; + // Visit sequence argument. + void VisitSequenceArgument(const std::string& arg_name, + SequenceVar* const argument) override; + void VisitSequenceArrayArgument( + const std::string& arg_name, + const std::vector& arguments) override; + + protected: + void PushArgumentHolder(); + void PopArgumentHolder(); + ArgumentHolder* Top() const; + + private: + std::vector holders_; +}; +#endif // SWIG + +// ---------- CpModelLoader ----------- + +// The class CpModelLoader is responsible for reading a protocol +// buffer representing a CP model and creating the corresponding CP +// model with the expressions and constraints. It should not be used directly. +class CpModelLoader { + public: + explicit CpModelLoader(Solver* const solver) : solver_(solver) {} + ~CpModelLoader() {} + + Solver* solver() const { return solver_; } + + // Returns stored integer expression. + IntExpr* IntegerExpression(int index) const; + // Returns the number of stored integer expressions. + int NumIntegerExpressions() const { return expressions_.size(); } + // Returns stored interval variable. + IntervalVar* IntervalVariable(int index) const; + // Returns the number of stored interval variables. + int NumIntervalVariables() const { return intervals_.size(); } + + +#if !defined(SWIG) + // Internal, do not use. + + // Builds integer expression from proto and stores it. It returns + // true upon success. + bool BuildFromProto(const CpIntegerExpression& proto); + // Builds constraint from proto and returns it. + Constraint* BuildFromProto(const CpConstraint& proto); + // Builds interval variable from proto and stores it. It returns + // true upon success. + bool BuildFromProto(const CpIntervalVariable& proto); + // Builds sequence variable from proto and stores it. It returns + // true upon success. + bool BuildFromProto(const CpSequenceVariable& proto); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + int64* to_fill); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + IntExpr** to_fill); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + std::vector* to_fill); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + IntTupleSet* to_fill); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + std::vector* to_fill); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + IntervalVar** to_fill); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + std::vector* to_fill); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + SequenceVar** to_fill); + + bool ScanOneArgument(int type_index, const CpArgument& arg_proto, + std::vector* to_fill); + + template + bool ScanArguments(const std::string& type, const P& proto, A* to_fill) { + const int index = tags_.Index(type); + for (int i = 0; i < proto.arguments_size(); ++i) { + if (ScanOneArgument(index, proto.arguments(i), to_fill)) { + return true; + } + } + return false; + } + + int TagIndex(const std::string& tag) const { return tags_.Index(tag); } + + void AddTag(const std::string& tag) { tags_.Add(tag); } + + // TODO(user): Use. + void SetSequenceVariable(int index, SequenceVar* const var) {} +#endif // !defined(SWIG) + + private: + Solver* const solver_; + std::vector expressions_; + std::vector intervals_; + std::vector sequences_; + VectorMap tags_; +}; + +#if !defined(SWIG) +// ----- Utility Class for Callbacks ----- + +template +class ArrayWithOffset : public BaseObject { + public: + ArrayWithOffset(int64 index_min, int64 index_max) + : index_min_(index_min), + index_max_(index_max), + values_(new T[index_max - index_min + 1]) { + DCHECK_LE(index_min, index_max); + } + + ~ArrayWithOffset() override {} + + virtual T Evaluate(int64 index) const { + DCHECK_GE(index, index_min_); + DCHECK_LE(index, index_max_); + return values_[index - index_min_]; + } + + void SetValue(int64 index, T value) { + DCHECK_GE(index, index_min_); + DCHECK_LE(index, index_max_); + values_[index - index_min_] = value; + } + + std::string DebugString() const override { return "ArrayWithOffset"; } + + private: + const int64 index_min_; + const int64 index_max_; + std::unique_ptr values_; +}; + +template +std::function MakeFunctionFromProto(CpModelLoader* const builder, + const CpExtension& proto, + int tag_index) { + DCHECK_EQ(tag_index, proto.type_index()); + Solver* const solver = builder->solver(); + int64 index_min = 0; + CHECK(builder->ScanArguments(ModelVisitor::kMinArgument, proto, &index_min)); + int64 index_max = 0; + CHECK(builder->ScanArguments(ModelVisitor::kMaxArgument, proto, &index_max)); + std::vector values; + CHECK(builder->ScanArguments(ModelVisitor::kValuesArgument, proto, &values)); + ArrayWithOffset* const array = + solver->RevAlloc(new ArrayWithOffset(index_min, index_max)); + for (int i = index_min; i <= index_max; ++i) { + array->SetValue(i, values[i - index_min]); + } + return [array](int64 index) { return array->Evaluate(index); }; +} +#endif // SWIG + +// This class is a reversible growing array. In can grow in both +// directions, and even accept negative indices. The objects stored +// have a type T. As it relies on the solver for reversibility, these +// objects can be up-casted to 'C' when using Solver::SaveValue(). +template +class RevGrowingArray { + public: + explicit RevGrowingArray(int64 block_size) + : block_size_(block_size), block_offset_(0) { + CHECK_GT(block_size, 0); + } + + ~RevGrowingArray() { + for (int i = 0; i < elements_.size(); ++i) { + delete[] elements_[i]; + } + } + + T At(int64 index) const { + const int64 block_index = ComputeBlockIndex(index); + const int64 relative_index = block_index - block_offset_; + if (relative_index < 0 || relative_index >= elements_.size()) { + return T(); + } + const T* block = elements_[relative_index]; + return block != nullptr ? block[index - block_index * block_size_] : T(); + } + + void RevInsert(Solver* const solver, int64 index, T value) { + const int64 block_index = ComputeBlockIndex(index); + T* const block = GetOrCreateBlock(block_index); + const int64 residual = index - block_index * block_size_; + solver->SaveAndSetValue(reinterpret_cast(&block[residual]), + reinterpret_cast(value)); + } + + private: + T* NewBlock() const { + T* const result = new T[block_size_]; + for (int i = 0; i < block_size_; ++i) { + result[i] = T(); + } + return result; + } + + T* GetOrCreateBlock(int block_index) { + if (elements_.size() == 0) { + block_offset_ = block_index; + GrowUp(block_index); + } else if (block_index < block_offset_) { + GrowDown(block_index); + } else if (block_index - block_offset_ >= elements_.size()) { + GrowUp(block_index); + } + T* block = elements_[block_index - block_offset_]; + if (block == nullptr) { + block = NewBlock(); + elements_[block_index - block_offset_] = block; + } + return block; + } + + int64 ComputeBlockIndex(int64 value) const { + return value >= 0 ? value / block_size_ + : (value - block_size_ + 1) / block_size_; + } + + void GrowUp(int64 block_index) { + elements_.resize(block_index - block_offset_ + 1); + } + + void GrowDown(int64 block_index) { + const int64 delta = block_offset_ - block_index; + block_offset_ = block_index; + DCHECK_GT(delta, 0); + elements_.insert(elements_.begin(), delta, nullptr); + } + + const int64 block_size_; + std::vector elements_; + int block_offset_; +}; + +// ----- RevIntSet ----- + +// This is a special class to represent a 'residual' set of T. T must +// be an integer type. You fill it at first, and then during search, +// you can efficiently remove an element, and query the removed +// elements. +template +class RevIntSet { + public: + static const int kNoInserted = -1; + + // Capacity is the fixed size of the set (it cannot grow). + explicit RevIntSet(int capacity) + : elements_(new T[capacity]), + num_elements_(0), + capacity_(capacity), + position_(new int[capacity]), + delete_position_(true) { + for (int i = 0; i < capacity; ++i) { + position_[i] = kNoInserted; + } + } + + // Capacity is the fixed size of the set (it cannot grow). + RevIntSet(int capacity, int* shared_positions, int shared_positions_size) + : elements_(new T[capacity]), + num_elements_(0), + capacity_(capacity), + position_(shared_positions), + delete_position_(false) { + for (int i = 0; i < shared_positions_size; ++i) { + position_[i] = kNoInserted; + } + } + + ~RevIntSet() { + if (delete_position_) { + delete[] position_; + } + } + + int Size() const { return num_elements_.Value(); } + + int Capacity() const { return capacity_; } + + T Element(int i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i, num_elements_.Value()); + return elements_[i]; + } + + T RemovedElement(int i) const { + DCHECK_GE(i, 0); + DCHECK_LT(i + num_elements_.Value(), capacity_); + return elements_[i + num_elements_.Value()]; + } + + void Insert(Solver* const solver, const T& elt) { + const int position = num_elements_.Value(); + DCHECK_LT(position, capacity_); // Valid. + DCHECK(NotAlreadyInserted(elt)); + elements_[position] = elt; + position_[elt] = position; + num_elements_.Incr(solver); + } + + void Remove(Solver* const solver, const T& value_index) { + num_elements_.Decr(solver); + SwapTo(value_index, num_elements_.Value()); + } + + void Restore(Solver* const solver, const T& value_index) { + SwapTo(value_index, num_elements_.Value()); + num_elements_.Incr(solver); + } + + void Clear(Solver* const solver) { num_elements_.SetValue(solver, 0); } + + // Iterators on the indices. + typedef const T* const_iterator; + const_iterator begin() const { return elements_.get(); } + const_iterator end() const { return elements_.get() + num_elements_.Value(); } + + private: + // Used in DCHECK. + bool NotAlreadyInserted(const T& elt) { + for (int i = 0; i < num_elements_.Value(); ++i) { + if (elt == elements_[i]) { + return false; + } + } + return true; + } + + void SwapTo(T value_index, int next_position) { + const int current_position = position_[value_index]; + if (current_position != next_position) { + const T next_value_index = elements_[next_position]; + elements_[current_position] = next_value_index; + elements_[next_position] = value_index; + position_[value_index] = next_position; + position_[next_value_index] = current_position; + } + } + + // Set of elements. + std::unique_ptr elements_; + // Number of elements in the set. + NumericalRev num_elements_; + // Number of elements in the set. + const int capacity_; + // Reverse mapping. + int* position_; + // Does the set owns the position array. + const bool delete_position_; +}; + +// ----- RevPartialSequence ----- + +class RevPartialSequence { + public: + explicit RevPartialSequence(const std::vector& items) + : elements_(items), + first_ranked_(0), + last_ranked_(items.size() - 1), + size_(items.size()), + position_(new int[size_]) { + for (int i = 0; i < size_; ++i) { + elements_[i] = items[i]; + position_[i] = i; + } + } + + explicit RevPartialSequence(int size) + : elements_(size), + first_ranked_(0), + last_ranked_(size - 1), + size_(size), + position_(new int[size_]) { + for (int i = 0; i < size_; ++i) { + elements_[i] = i; + position_[i] = i; + } + } + + ~RevPartialSequence() {} + + int NumFirstRanked() const { return first_ranked_.Value(); } + + int NumLastRanked() const { return size_ - 1 - last_ranked_.Value(); } + + int Size() const { return size_; } + +#if !defined(SWIG) + const int& operator[](int index) const { + DCHECK_GE(index, 0); + DCHECK_LT(index, size_); + return elements_[index]; + } +#endif + + void RankFirst(Solver* const solver, int elt) { + DCHECK_LE(first_ranked_.Value(), last_ranked_.Value()); + SwapTo(elt, first_ranked_.Value()); + first_ranked_.Incr(solver); + } + + void RankLast(Solver* const solver, int elt) { + DCHECK_LE(first_ranked_.Value(), last_ranked_.Value()); + SwapTo(elt, last_ranked_.Value()); + last_ranked_.Decr(solver); + } + + bool IsRanked(int elt) const { + const int position = position_[elt]; + return (position < first_ranked_.Value() || + position > last_ranked_.Value()); + } + + std::string DebugString() const { + std::string result = "["; + for (int i = 0; i < first_ranked_.Value(); ++i) { + StrAppend(&result, elements_[i]); + if (i != first_ranked_.Value() - 1) { + result.append("-"); + } + } + result.append("|"); + for (int i = first_ranked_.Value(); i <= last_ranked_.Value(); ++i) { + StrAppend(&result, elements_[i]); + if (i != last_ranked_.Value()) { + result.append("-"); + } + } + result.append("|"); + for (int i = last_ranked_.Value() + 1; i < size_; ++i) { + StrAppend(&result, elements_[i]); + if (i != size_ - 1) { + result.append("-"); + } + } + result.append("]"); + return result; + } + + private: + void SwapTo(int elt, int next_position) { + const int current_position = position_[elt]; + if (current_position != next_position) { + const int next_elt = elements_[next_position]; + elements_[current_position] = next_elt; + elements_[next_position] = elt; + position_[elt] = next_position; + position_[next_elt] = current_position; + } + } + + // Set of elements. + std::vector elements_; + // Position of the element after the last element ranked from the start. + NumericalRev first_ranked_; + // Position of the element before the last element ranked from the end. + NumericalRev last_ranked_; + // Number of elements in the sequence. + const int size_; + // Reverse mapping. + std::unique_ptr position_; +}; + +// This class represents a reversible bitset. It is meant to represent a set of +// active bits. It does not offer direct access, but just methods that can +// reversibly substract another bitset, or check if the current active bitset +// intersects with another bitset. +class UnsortedNullableRevBitset { + public: + // Size is the number of bits to store in the bitset. + explicit UnsortedNullableRevBitset(int bit_size); + + ~UnsortedNullableRevBitset() {} + + // This methods overwrites the active bitset with the mask. This method should + // be called only once. + void Init(Solver* const solver, const std::vector& mask); + + // This method substracts the mask from the active bitset. It returns true if + // the active bitset was changed in the process. + bool RevSubtract(Solver* const solver, const std::vector& mask); + + // This method ANDs the mask with the active bitset. It returns true if + // the active bitset was changed in the process. + bool RevAnd(Solver* const solver, const std::vector& mask); + + // This method returns the number of non null 64 bit words in the bitset + // representation. + int ActiveWordSize() const { return active_words_.Size(); } + + // This method returns true if the active bitset is null. + bool Empty() const { return active_words_.Size() == 0; } + + // This method returns true iff the mask and the active bitset have a non + // null intersection. support_index is used as an accelerator: + // - The first word tested to check the intersection will be the + // '*support_index'th one. + // - If the intersection is not null, the support_index will be filled with + // the index of the word that does intersect with the mask. This can be + // reused later to speed-up the check. + bool Intersects(const std::vector& mask, int* support_index); + + // Returns the number of bits given in the constructor of the bitset. + int64 bit_size() const { return bit_size_; } + // Returns the number of 64 bit words used to store the bitset. + int64 word_size() const { return word_size_; } + // Returns the set of active word indices. + const RevIntSet& active_words() const { return active_words_; } + + private: + void CleanUpActives(Solver* const solver); + + const int64 bit_size_; + const int64 word_size_; + RevArray bits_; + RevIntSet active_words_; + std::vector to_remove_; +}; + +// ---------- Helpers ---------- + +// ----- On integer vectors ----- + +template +bool IsArrayConstant(const std::vector& values, const T& value) { + for (int i = 0; i < values.size(); ++i) { + if (values[i] != value) { + return false; + } + } + return true; +} + +template +bool IsArrayBoolean(const std::vector& values) { + for (int i = 0; i < values.size(); ++i) { + if (values[i] != 0 && values[i] != 1) { + return false; + } + } + return true; +} + +template +bool AreAllOnes(const std::vector& values) { + return IsArrayConstant(values, T(1)); +} + +template +bool AreAllNull(const std::vector& values) { + return IsArrayConstant(values, T(0)); +} + +template +bool AreAllGreaterOrEqual(const std::vector& values, const T& value) { + for (const T& current_value : values) { + if (current_value < value) { + return false; + } + } + return true; +} + +template +bool AreAllLessOrEqual(const std::vector& values, const T& value) { + for (const T& current_value : values) { + if (current_value > value) { + return false; + } + } + return true; +} + +template +bool AreAllPositive(const std::vector& values) { + return AreAllGreaterOrEqual(values, T(0)); +} + +template +bool AreAllNegative(const std::vector& values) { + return AreAllLessOrEqual(values, T(0)); +} + +template +bool AreAllStrictlyPositive(const std::vector& values) { + return AreAllGreaterOrEqual(values, T(1)); +} + +template +bool AreAllStrictlyNegative(const std::vector& values) { + return AreAllLessOrEqual(values, T(-1)); +} + +template +bool IsIncreasingContiguous(const std::vector& values) { + for (int i = 0; i < values.size() - 1; ++i) { + if (values[i + 1] != values[i] + 1) { + return false; + } + } + return true; +} + +template +bool IsIncreasing(const std::vector& values) { + for (int i = 0; i < values.size() - 1; ++i) { + if (values[i + 1] < values[i]) { + return false; + } + } + return true; +} + +// ----- On integer variable vector ----- + +template +bool IsArrayInRange(const std::vector& vars, T range_min, + T range_max) { + for (int i = 0; i < vars.size(); ++i) { + if (vars[i]->Min() < range_min || vars[i]->Max() > range_max) { + return false; + } + } + return true; +} + +inline bool AreAllBound(const std::vector& vars) { + for (int i = 0; i < vars.size(); ++i) { + if (!vars[i]->Bound()) { + return false; + } + } + return true; +} + +inline bool AreAllBooleans(const std::vector& vars) { + return IsArrayInRange(vars, 0, 1); +} + +// Returns true if all the variables are assigned to a single value, +// or if their corresponding value is null. +template +bool AreAllBoundOrNull(const std::vector& vars, + const std::vector& values) { + for (int i = 0; i < vars.size(); ++i) { + if (values[i] != 0 && !vars[i]->Bound()) { + return false; + } + } + return true; +} + +// Returns true if all variables are assigned to 'value'. +inline bool AreAllBoundTo(const std::vector& vars, int64 value) { + for (int i = 0; i < vars.size(); ++i) { + if (!vars[i]->Bound() || vars[i]->Min() != value) { + return false; + } + } + return true; +} + +inline int64 MaxVarArray(const std::vector& vars) { + DCHECK(!vars.empty()); + int64 result = kint64min; + for (int i = 0; i < vars.size(); ++i) { + // The std::max is needed for compilation on MSVC. + result = std::max(result, vars[i]->Max()); + } + return result; +} + +inline int64 MinVarArray(const std::vector& vars) { + DCHECK(!vars.empty()); + int64 result = kint64max; + for (int i = 0; i < vars.size(); ++i) { + // The std::min is needed for compilation on MSVC. + result = std::min(result, vars[i]->Min()); + } + return result; +} + +inline void FillValues(const std::vector& vars, + std::vector* const values) { + values->clear(); + values->resize(vars.size()); + for (int i = 0; i < vars.size(); ++i) { + (*values)[i] = vars[i]->Value(); + } +} + +// ----- Arithmetic operations ----- + +inline int64 PosIntDivUp(int64 e, int64 v) { + DCHECK_GT(v, 0); + if (e >= 0) { + return e % v == 0 ? e / v : e / v + 1; + } else { + return -(-e / v); + } +} + +inline int64 PosIntDivDown(int64 e, int64 v) { + DCHECK_GT(v, 0); + if (e >= 0) { + return e / v; + } else { + return e % v == 0 ? e / v : e / v - 1; + } +} + +// ----- Vector of integer manipulations ----- +std::vector ToInt64Vector(const std::vector& input); +} // namespace operations_research + +#endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVERI_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/demon_profiler.pb.h b/thirdparty/linux/include/ortools/constraint_solver/demon_profiler.pb.h new file mode 100644 index 0000000..e63997b --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/demon_profiler.pb.h @@ -0,0 +1,587 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/constraint_solver/demon_profiler.proto + +#ifndef PROTOBUF_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto__INCLUDED +#define PROTOBUF_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); +void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); +void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); + +class ConstraintRuns; +class DemonRuns; + +// =================================================================== + +class DemonRuns : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.DemonRuns) */ { + public: + DemonRuns(); + virtual ~DemonRuns(); + + DemonRuns(const DemonRuns& from); + + inline DemonRuns& operator=(const DemonRuns& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DemonRuns& default_instance(); + + void Swap(DemonRuns* other); + + // implements Message ---------------------------------------------- + + inline DemonRuns* New() const { return New(NULL); } + + DemonRuns* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DemonRuns& from); + void MergeFrom(const DemonRuns& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(DemonRuns* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string demon_id = 1; + void clear_demon_id(); + static const int kDemonIdFieldNumber = 1; + const ::std::string& demon_id() const; + void set_demon_id(const ::std::string& value); + void set_demon_id(const char* value); + void set_demon_id(const char* value, size_t size); + ::std::string* mutable_demon_id(); + ::std::string* release_demon_id(); + void set_allocated_demon_id(::std::string* demon_id); + + // repeated int64 start_time = 2; + int start_time_size() const; + void clear_start_time(); + static const int kStartTimeFieldNumber = 2; + ::google::protobuf::int64 start_time(int index) const; + void set_start_time(int index, ::google::protobuf::int64 value); + void add_start_time(::google::protobuf::int64 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& + start_time() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* + mutable_start_time(); + + // repeated int64 end_time = 3; + int end_time_size() const; + void clear_end_time(); + static const int kEndTimeFieldNumber = 3; + ::google::protobuf::int64 end_time(int index) const; + void set_end_time(int index, ::google::protobuf::int64 value); + void add_end_time(::google::protobuf::int64 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& + end_time() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* + mutable_end_time(); + + // optional int64 failures = 4; + void clear_failures(); + static const int kFailuresFieldNumber = 4; + ::google::protobuf::int64 failures() const; + void set_failures(::google::protobuf::int64 value); + + // @@protoc_insertion_point(class_scope:operations_research.DemonRuns) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr demon_id_; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 > start_time_; + mutable int _start_time_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 > end_time_; + mutable int _end_time_cached_byte_size_; + ::google::protobuf::int64 failures_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); + + void InitAsDefaultInstance(); + static DemonRuns* default_instance_; +}; +// ------------------------------------------------------------------- + +class ConstraintRuns : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.ConstraintRuns) */ { + public: + ConstraintRuns(); + virtual ~ConstraintRuns(); + + ConstraintRuns(const ConstraintRuns& from); + + inline ConstraintRuns& operator=(const ConstraintRuns& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ConstraintRuns& default_instance(); + + void Swap(ConstraintRuns* other); + + // implements Message ---------------------------------------------- + + inline ConstraintRuns* New() const { return New(NULL); } + + ConstraintRuns* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ConstraintRuns& from); + void MergeFrom(const ConstraintRuns& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(ConstraintRuns* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string constraint_id = 1; + void clear_constraint_id(); + static const int kConstraintIdFieldNumber = 1; + const ::std::string& constraint_id() const; + void set_constraint_id(const ::std::string& value); + void set_constraint_id(const char* value); + void set_constraint_id(const char* value, size_t size); + ::std::string* mutable_constraint_id(); + ::std::string* release_constraint_id(); + void set_allocated_constraint_id(::std::string* constraint_id); + + // repeated int64 initial_propagation_start_time = 2; + int initial_propagation_start_time_size() const; + void clear_initial_propagation_start_time(); + static const int kInitialPropagationStartTimeFieldNumber = 2; + ::google::protobuf::int64 initial_propagation_start_time(int index) const; + void set_initial_propagation_start_time(int index, ::google::protobuf::int64 value); + void add_initial_propagation_start_time(::google::protobuf::int64 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& + initial_propagation_start_time() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* + mutable_initial_propagation_start_time(); + + // repeated int64 initial_propagation_end_time = 3; + int initial_propagation_end_time_size() const; + void clear_initial_propagation_end_time(); + static const int kInitialPropagationEndTimeFieldNumber = 3; + ::google::protobuf::int64 initial_propagation_end_time(int index) const; + void set_initial_propagation_end_time(int index, ::google::protobuf::int64 value); + void add_initial_propagation_end_time(::google::protobuf::int64 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& + initial_propagation_end_time() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* + mutable_initial_propagation_end_time(); + + // optional int64 failures = 4; + void clear_failures(); + static const int kFailuresFieldNumber = 4; + ::google::protobuf::int64 failures() const; + void set_failures(::google::protobuf::int64 value); + + // repeated .operations_research.DemonRuns demons = 5; + int demons_size() const; + void clear_demons(); + static const int kDemonsFieldNumber = 5; + const ::operations_research::DemonRuns& demons(int index) const; + ::operations_research::DemonRuns* mutable_demons(int index); + ::operations_research::DemonRuns* add_demons(); + ::google::protobuf::RepeatedPtrField< ::operations_research::DemonRuns >* + mutable_demons(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::DemonRuns >& + demons() const; + + // @@protoc_insertion_point(class_scope:operations_research.ConstraintRuns) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr constraint_id_; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 > initial_propagation_start_time_; + mutable int _initial_propagation_start_time_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 > initial_propagation_end_time_; + mutable int _initial_propagation_end_time_cached_byte_size_; + ::google::protobuf::int64 failures_; + ::google::protobuf::RepeatedPtrField< ::operations_research::DemonRuns > demons_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto(); + + void InitAsDefaultInstance(); + static ConstraintRuns* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// DemonRuns + +// optional string demon_id = 1; +inline void DemonRuns::clear_demon_id() { + demon_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& DemonRuns::demon_id() const { + // @@protoc_insertion_point(field_get:operations_research.DemonRuns.demon_id) + return demon_id_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void DemonRuns::set_demon_id(const ::std::string& value) { + + demon_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.DemonRuns.demon_id) +} +inline void DemonRuns::set_demon_id(const char* value) { + + demon_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.DemonRuns.demon_id) +} +inline void DemonRuns::set_demon_id(const char* value, size_t size) { + + demon_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.DemonRuns.demon_id) +} +inline ::std::string* DemonRuns::mutable_demon_id() { + + // @@protoc_insertion_point(field_mutable:operations_research.DemonRuns.demon_id) + return demon_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* DemonRuns::release_demon_id() { + // @@protoc_insertion_point(field_release:operations_research.DemonRuns.demon_id) + + return demon_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void DemonRuns::set_allocated_demon_id(::std::string* demon_id) { + if (demon_id != NULL) { + + } else { + + } + demon_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), demon_id); + // @@protoc_insertion_point(field_set_allocated:operations_research.DemonRuns.demon_id) +} + +// repeated int64 start_time = 2; +inline int DemonRuns::start_time_size() const { + return start_time_.size(); +} +inline void DemonRuns::clear_start_time() { + start_time_.Clear(); +} +inline ::google::protobuf::int64 DemonRuns::start_time(int index) const { + // @@protoc_insertion_point(field_get:operations_research.DemonRuns.start_time) + return start_time_.Get(index); +} +inline void DemonRuns::set_start_time(int index, ::google::protobuf::int64 value) { + start_time_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.DemonRuns.start_time) +} +inline void DemonRuns::add_start_time(::google::protobuf::int64 value) { + start_time_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.DemonRuns.start_time) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& +DemonRuns::start_time() const { + // @@protoc_insertion_point(field_list:operations_research.DemonRuns.start_time) + return start_time_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* +DemonRuns::mutable_start_time() { + // @@protoc_insertion_point(field_mutable_list:operations_research.DemonRuns.start_time) + return &start_time_; +} + +// repeated int64 end_time = 3; +inline int DemonRuns::end_time_size() const { + return end_time_.size(); +} +inline void DemonRuns::clear_end_time() { + end_time_.Clear(); +} +inline ::google::protobuf::int64 DemonRuns::end_time(int index) const { + // @@protoc_insertion_point(field_get:operations_research.DemonRuns.end_time) + return end_time_.Get(index); +} +inline void DemonRuns::set_end_time(int index, ::google::protobuf::int64 value) { + end_time_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.DemonRuns.end_time) +} +inline void DemonRuns::add_end_time(::google::protobuf::int64 value) { + end_time_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.DemonRuns.end_time) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& +DemonRuns::end_time() const { + // @@protoc_insertion_point(field_list:operations_research.DemonRuns.end_time) + return end_time_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* +DemonRuns::mutable_end_time() { + // @@protoc_insertion_point(field_mutable_list:operations_research.DemonRuns.end_time) + return &end_time_; +} + +// optional int64 failures = 4; +inline void DemonRuns::clear_failures() { + failures_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 DemonRuns::failures() const { + // @@protoc_insertion_point(field_get:operations_research.DemonRuns.failures) + return failures_; +} +inline void DemonRuns::set_failures(::google::protobuf::int64 value) { + + failures_ = value; + // @@protoc_insertion_point(field_set:operations_research.DemonRuns.failures) +} + +// ------------------------------------------------------------------- + +// ConstraintRuns + +// optional string constraint_id = 1; +inline void ConstraintRuns::clear_constraint_id() { + constraint_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& ConstraintRuns::constraint_id() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintRuns.constraint_id) + return constraint_id_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void ConstraintRuns::set_constraint_id(const ::std::string& value) { + + constraint_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.ConstraintRuns.constraint_id) +} +inline void ConstraintRuns::set_constraint_id(const char* value) { + + constraint_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.ConstraintRuns.constraint_id) +} +inline void ConstraintRuns::set_constraint_id(const char* value, size_t size) { + + constraint_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.ConstraintRuns.constraint_id) +} +inline ::std::string* ConstraintRuns::mutable_constraint_id() { + + // @@protoc_insertion_point(field_mutable:operations_research.ConstraintRuns.constraint_id) + return constraint_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* ConstraintRuns::release_constraint_id() { + // @@protoc_insertion_point(field_release:operations_research.ConstraintRuns.constraint_id) + + return constraint_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void ConstraintRuns::set_allocated_constraint_id(::std::string* constraint_id) { + if (constraint_id != NULL) { + + } else { + + } + constraint_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), constraint_id); + // @@protoc_insertion_point(field_set_allocated:operations_research.ConstraintRuns.constraint_id) +} + +// repeated int64 initial_propagation_start_time = 2; +inline int ConstraintRuns::initial_propagation_start_time_size() const { + return initial_propagation_start_time_.size(); +} +inline void ConstraintRuns::clear_initial_propagation_start_time() { + initial_propagation_start_time_.Clear(); +} +inline ::google::protobuf::int64 ConstraintRuns::initial_propagation_start_time(int index) const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintRuns.initial_propagation_start_time) + return initial_propagation_start_time_.Get(index); +} +inline void ConstraintRuns::set_initial_propagation_start_time(int index, ::google::protobuf::int64 value) { + initial_propagation_start_time_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.ConstraintRuns.initial_propagation_start_time) +} +inline void ConstraintRuns::add_initial_propagation_start_time(::google::protobuf::int64 value) { + initial_propagation_start_time_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.ConstraintRuns.initial_propagation_start_time) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& +ConstraintRuns::initial_propagation_start_time() const { + // @@protoc_insertion_point(field_list:operations_research.ConstraintRuns.initial_propagation_start_time) + return initial_propagation_start_time_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* +ConstraintRuns::mutable_initial_propagation_start_time() { + // @@protoc_insertion_point(field_mutable_list:operations_research.ConstraintRuns.initial_propagation_start_time) + return &initial_propagation_start_time_; +} + +// repeated int64 initial_propagation_end_time = 3; +inline int ConstraintRuns::initial_propagation_end_time_size() const { + return initial_propagation_end_time_.size(); +} +inline void ConstraintRuns::clear_initial_propagation_end_time() { + initial_propagation_end_time_.Clear(); +} +inline ::google::protobuf::int64 ConstraintRuns::initial_propagation_end_time(int index) const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintRuns.initial_propagation_end_time) + return initial_propagation_end_time_.Get(index); +} +inline void ConstraintRuns::set_initial_propagation_end_time(int index, ::google::protobuf::int64 value) { + initial_propagation_end_time_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.ConstraintRuns.initial_propagation_end_time) +} +inline void ConstraintRuns::add_initial_propagation_end_time(::google::protobuf::int64 value) { + initial_propagation_end_time_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.ConstraintRuns.initial_propagation_end_time) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& +ConstraintRuns::initial_propagation_end_time() const { + // @@protoc_insertion_point(field_list:operations_research.ConstraintRuns.initial_propagation_end_time) + return initial_propagation_end_time_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* +ConstraintRuns::mutable_initial_propagation_end_time() { + // @@protoc_insertion_point(field_mutable_list:operations_research.ConstraintRuns.initial_propagation_end_time) + return &initial_propagation_end_time_; +} + +// optional int64 failures = 4; +inline void ConstraintRuns::clear_failures() { + failures_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 ConstraintRuns::failures() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintRuns.failures) + return failures_; +} +inline void ConstraintRuns::set_failures(::google::protobuf::int64 value) { + + failures_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintRuns.failures) +} + +// repeated .operations_research.DemonRuns demons = 5; +inline int ConstraintRuns::demons_size() const { + return demons_.size(); +} +inline void ConstraintRuns::clear_demons() { + demons_.Clear(); +} +inline const ::operations_research::DemonRuns& ConstraintRuns::demons(int index) const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintRuns.demons) + return demons_.Get(index); +} +inline ::operations_research::DemonRuns* ConstraintRuns::mutable_demons(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.ConstraintRuns.demons) + return demons_.Mutable(index); +} +inline ::operations_research::DemonRuns* ConstraintRuns::add_demons() { + // @@protoc_insertion_point(field_add:operations_research.ConstraintRuns.demons) + return demons_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::DemonRuns >* +ConstraintRuns::mutable_demons() { + // @@protoc_insertion_point(field_mutable_list:operations_research.ConstraintRuns.demons) + return &demons_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::DemonRuns >& +ConstraintRuns::demons() const { + // @@protoc_insertion_point(field_list:operations_research.ConstraintRuns.demons) + return demons_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fconstraint_5fsolver_2fdemon_5fprofiler_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/constraint_solver/hybrid.h b/thirdparty/linux/include/ortools/constraint_solver/hybrid.h new file mode 100644 index 0000000..5647a8a --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/hybrid.h @@ -0,0 +1,40 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_HYBRID_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_HYBRID_H_ + +#include "ortools/constraint_solver/constraint_solver.h" + +namespace operations_research { +class MPSolver; + +// ----- Simplex Connection ----- +SearchMonitor* MakeSimplexConnection(Solver* const solver, + std::function builder, + std::function modifier, + std::function runner, + int simplex_frequency); + +// ----- Linear Relaxation Constraint ----- + +// Creates a search monitor that will maintain a linear relaxation +// of the problem. Every 'simplex_frequency' nodes explored in the +// search tree, this linear relaxation will be called and the +// resulting optimal solution found by the simplex will be used to +// prune the objective of the constraint programming model. +SearchMonitor* MakeSimplexConstraint(Solver* const solver, + int simplex_frequency); +} // namespace operations_research + +#endif // OR_TOOLS_CONSTRAINT_SOLVER_HYBRID_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/model.pb.h b/thirdparty/linux/include/ortools/constraint_solver/model.pb.h new file mode 100644 index 0000000..49b2a5b --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/model.pb.h @@ -0,0 +1,2785 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/constraint_solver/model.proto + +#ifndef PROTOBUF_ortools_2fconstraint_5fsolver_2fmodel_2eproto__INCLUDED +#define PROTOBUF_ortools_2fconstraint_5fsolver_2fmodel_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ortools/constraint_solver/search_limit.pb.h" +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); +void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); +void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + +class CpArgument; +class CpConstraint; +class CpExtension; +class CpIntegerExpression; +class CpIntegerMatrix; +class CpIntervalVariable; +class CpModel; +class CpObjective; +class CpSequenceVariable; +class CpVariableGroup; + +enum CpArgument_Type { + CpArgument_Type_UNDEFINED = 0, + CpArgument_Type_INTEGER_VALUE = 1, + CpArgument_Type_INTEGER_ARRAY = 2, + CpArgument_Type_EXPRESSION = 3, + CpArgument_Type_EXPRESSION_ARRAY = 4, + CpArgument_Type_INTERVAL = 5, + CpArgument_Type_INTERVAL_ARRAY = 6, + CpArgument_Type_SEQUENCE = 7, + CpArgument_Type_SEQUENCE_ARRAY = 8, + CpArgument_Type_INTEGER_MATRIX = 9, + CpArgument_Type_CpArgument_Type_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + CpArgument_Type_CpArgument_Type_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +bool CpArgument_Type_IsValid(int value); +const CpArgument_Type CpArgument_Type_Type_MIN = CpArgument_Type_UNDEFINED; +const CpArgument_Type CpArgument_Type_Type_MAX = CpArgument_Type_INTEGER_MATRIX; +const int CpArgument_Type_Type_ARRAYSIZE = CpArgument_Type_Type_MAX + 1; + +const ::google::protobuf::EnumDescriptor* CpArgument_Type_descriptor(); +inline const ::std::string& CpArgument_Type_Name(CpArgument_Type value) { + return ::google::protobuf::internal::NameOfEnum( + CpArgument_Type_descriptor(), value); +} +inline bool CpArgument_Type_Parse( + const ::std::string& name, CpArgument_Type* value) { + return ::google::protobuf::internal::ParseNamedEnum( + CpArgument_Type_descriptor(), name, value); +} +// =================================================================== + +class CpIntegerMatrix : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpIntegerMatrix) */ { + public: + CpIntegerMatrix(); + virtual ~CpIntegerMatrix(); + + CpIntegerMatrix(const CpIntegerMatrix& from); + + inline CpIntegerMatrix& operator=(const CpIntegerMatrix& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpIntegerMatrix& default_instance(); + + void Swap(CpIntegerMatrix* other); + + // implements Message ---------------------------------------------- + + inline CpIntegerMatrix* New() const { return New(NULL); } + + CpIntegerMatrix* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpIntegerMatrix& from); + void MergeFrom(const CpIntegerMatrix& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpIntegerMatrix* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 rows = 1; + void clear_rows(); + static const int kRowsFieldNumber = 1; + ::google::protobuf::int32 rows() const; + void set_rows(::google::protobuf::int32 value); + + // optional int32 columns = 2; + void clear_columns(); + static const int kColumnsFieldNumber = 2; + ::google::protobuf::int32 columns() const; + void set_columns(::google::protobuf::int32 value); + + // repeated int64 values = 3; + int values_size() const; + void clear_values(); + static const int kValuesFieldNumber = 3; + ::google::protobuf::int64 values(int index) const; + void set_values(int index, ::google::protobuf::int64 value); + void add_values(::google::protobuf::int64 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& + values() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* + mutable_values(); + + // @@protoc_insertion_point(class_scope:operations_research.CpIntegerMatrix) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int32 rows_; + ::google::protobuf::int32 columns_; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 > values_; + mutable int _values_cached_byte_size_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpIntegerMatrix* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpArgument : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpArgument) */ { + public: + CpArgument(); + virtual ~CpArgument(); + + CpArgument(const CpArgument& from); + + inline CpArgument& operator=(const CpArgument& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpArgument& default_instance(); + + void Swap(CpArgument* other); + + // implements Message ---------------------------------------------- + + inline CpArgument* New() const { return New(NULL); } + + CpArgument* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpArgument& from); + void MergeFrom(const CpArgument& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpArgument* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef CpArgument_Type Type; + static const Type UNDEFINED = + CpArgument_Type_UNDEFINED; + static const Type INTEGER_VALUE = + CpArgument_Type_INTEGER_VALUE; + static const Type INTEGER_ARRAY = + CpArgument_Type_INTEGER_ARRAY; + static const Type EXPRESSION = + CpArgument_Type_EXPRESSION; + static const Type EXPRESSION_ARRAY = + CpArgument_Type_EXPRESSION_ARRAY; + static const Type INTERVAL = + CpArgument_Type_INTERVAL; + static const Type INTERVAL_ARRAY = + CpArgument_Type_INTERVAL_ARRAY; + static const Type SEQUENCE = + CpArgument_Type_SEQUENCE; + static const Type SEQUENCE_ARRAY = + CpArgument_Type_SEQUENCE_ARRAY; + static const Type INTEGER_MATRIX = + CpArgument_Type_INTEGER_MATRIX; + static inline bool Type_IsValid(int value) { + return CpArgument_Type_IsValid(value); + } + static const Type Type_MIN = + CpArgument_Type_Type_MIN; + static const Type Type_MAX = + CpArgument_Type_Type_MAX; + static const int Type_ARRAYSIZE = + CpArgument_Type_Type_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Type_descriptor() { + return CpArgument_Type_descriptor(); + } + static inline const ::std::string& Type_Name(Type value) { + return CpArgument_Type_Name(value); + } + static inline bool Type_Parse(const ::std::string& name, + Type* value) { + return CpArgument_Type_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional int32 argument_index = 1; + void clear_argument_index(); + static const int kArgumentIndexFieldNumber = 1; + ::google::protobuf::int32 argument_index() const; + void set_argument_index(::google::protobuf::int32 value); + + // optional int64 integer_value = 2; + void clear_integer_value(); + static const int kIntegerValueFieldNumber = 2; + ::google::protobuf::int64 integer_value() const; + void set_integer_value(::google::protobuf::int64 value); + + // repeated int64 integer_array = 3; + int integer_array_size() const; + void clear_integer_array(); + static const int kIntegerArrayFieldNumber = 3; + ::google::protobuf::int64 integer_array(int index) const; + void set_integer_array(int index, ::google::protobuf::int64 value); + void add_integer_array(::google::protobuf::int64 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& + integer_array() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* + mutable_integer_array(); + + // optional int32 integer_expression_index = 4; + void clear_integer_expression_index(); + static const int kIntegerExpressionIndexFieldNumber = 4; + ::google::protobuf::int32 integer_expression_index() const; + void set_integer_expression_index(::google::protobuf::int32 value); + + // repeated int32 integer_expression_array = 5; + int integer_expression_array_size() const; + void clear_integer_expression_array(); + static const int kIntegerExpressionArrayFieldNumber = 5; + ::google::protobuf::int32 integer_expression_array(int index) const; + void set_integer_expression_array(int index, ::google::protobuf::int32 value); + void add_integer_expression_array(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + integer_expression_array() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_integer_expression_array(); + + // optional int32 interval_index = 6; + void clear_interval_index(); + static const int kIntervalIndexFieldNumber = 6; + ::google::protobuf::int32 interval_index() const; + void set_interval_index(::google::protobuf::int32 value); + + // repeated int32 interval_array = 7; + int interval_array_size() const; + void clear_interval_array(); + static const int kIntervalArrayFieldNumber = 7; + ::google::protobuf::int32 interval_array(int index) const; + void set_interval_array(int index, ::google::protobuf::int32 value); + void add_interval_array(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + interval_array() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_interval_array(); + + // optional int32 sequence_index = 8; + void clear_sequence_index(); + static const int kSequenceIndexFieldNumber = 8; + ::google::protobuf::int32 sequence_index() const; + void set_sequence_index(::google::protobuf::int32 value); + + // repeated int32 sequence_array = 9; + int sequence_array_size() const; + void clear_sequence_array(); + static const int kSequenceArrayFieldNumber = 9; + ::google::protobuf::int32 sequence_array(int index) const; + void set_sequence_array(int index, ::google::protobuf::int32 value); + void add_sequence_array(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + sequence_array() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_sequence_array(); + + // optional .operations_research.CpIntegerMatrix integer_matrix = 10; + bool has_integer_matrix() const; + void clear_integer_matrix(); + static const int kIntegerMatrixFieldNumber = 10; + const ::operations_research::CpIntegerMatrix& integer_matrix() const; + ::operations_research::CpIntegerMatrix* mutable_integer_matrix(); + ::operations_research::CpIntegerMatrix* release_integer_matrix(); + void set_allocated_integer_matrix(::operations_research::CpIntegerMatrix* integer_matrix); + + // optional .operations_research.CpArgument.Type type = 11; + void clear_type(); + static const int kTypeFieldNumber = 11; + ::operations_research::CpArgument_Type type() const; + void set_type(::operations_research::CpArgument_Type value); + + // @@protoc_insertion_point(class_scope:operations_research.CpArgument) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int64 integer_value_; + ::google::protobuf::int32 argument_index_; + ::google::protobuf::int32 integer_expression_index_; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 > integer_array_; + mutable int _integer_array_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > integer_expression_array_; + mutable int _integer_expression_array_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > interval_array_; + mutable int _interval_array_cached_byte_size_; + ::google::protobuf::int32 interval_index_; + ::google::protobuf::int32 sequence_index_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > sequence_array_; + mutable int _sequence_array_cached_byte_size_; + ::operations_research::CpIntegerMatrix* integer_matrix_; + int type_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpArgument* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpExtension : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpExtension) */ { + public: + CpExtension(); + virtual ~CpExtension(); + + CpExtension(const CpExtension& from); + + inline CpExtension& operator=(const CpExtension& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpExtension& default_instance(); + + void Swap(CpExtension* other); + + // implements Message ---------------------------------------------- + + inline CpExtension* New() const { return New(NULL); } + + CpExtension* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpExtension& from); + void MergeFrom(const CpExtension& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpExtension* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 type_index = 1; + void clear_type_index(); + static const int kTypeIndexFieldNumber = 1; + ::google::protobuf::int32 type_index() const; + void set_type_index(::google::protobuf::int32 value); + + // repeated .operations_research.CpArgument arguments = 2; + int arguments_size() const; + void clear_arguments(); + static const int kArgumentsFieldNumber = 2; + const ::operations_research::CpArgument& arguments(int index) const; + ::operations_research::CpArgument* mutable_arguments(int index); + ::operations_research::CpArgument* add_arguments(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* + mutable_arguments(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& + arguments() const; + + // @@protoc_insertion_point(class_scope:operations_research.CpExtension) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument > arguments_; + ::google::protobuf::int32 type_index_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpExtension* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpIntegerExpression : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpIntegerExpression) */ { + public: + CpIntegerExpression(); + virtual ~CpIntegerExpression(); + + CpIntegerExpression(const CpIntegerExpression& from); + + inline CpIntegerExpression& operator=(const CpIntegerExpression& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpIntegerExpression& default_instance(); + + void Swap(CpIntegerExpression* other); + + // implements Message ---------------------------------------------- + + inline CpIntegerExpression* New() const { return New(NULL); } + + CpIntegerExpression* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpIntegerExpression& from); + void MergeFrom(const CpIntegerExpression& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpIntegerExpression* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 index = 1; + void clear_index(); + static const int kIndexFieldNumber = 1; + ::google::protobuf::int32 index() const; + void set_index(::google::protobuf::int32 value); + + // optional int32 type_index = 2; + void clear_type_index(); + static const int kTypeIndexFieldNumber = 2; + ::google::protobuf::int32 type_index() const; + void set_type_index(::google::protobuf::int32 value); + + // optional string name = 3; + void clear_name(); + static const int kNameFieldNumber = 3; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .operations_research.CpArgument arguments = 4; + int arguments_size() const; + void clear_arguments(); + static const int kArgumentsFieldNumber = 4; + const ::operations_research::CpArgument& arguments(int index) const; + ::operations_research::CpArgument* mutable_arguments(int index); + ::operations_research::CpArgument* add_arguments(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* + mutable_arguments(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& + arguments() const; + + // repeated .operations_research.CpExtension extensions = 5; + int extensions_size() const; + void clear_extensions(); + static const int kExtensionsFieldNumber = 5; + const ::operations_research::CpExtension& extensions(int index) const; + ::operations_research::CpExtension* mutable_extensions(int index); + ::operations_research::CpExtension* add_extensions(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension >* + mutable_extensions(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension >& + extensions() const; + + // @@protoc_insertion_point(class_scope:operations_research.CpIntegerExpression) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int32 index_; + ::google::protobuf::int32 type_index_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument > arguments_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension > extensions_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpIntegerExpression* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpIntervalVariable : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpIntervalVariable) */ { + public: + CpIntervalVariable(); + virtual ~CpIntervalVariable(); + + CpIntervalVariable(const CpIntervalVariable& from); + + inline CpIntervalVariable& operator=(const CpIntervalVariable& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpIntervalVariable& default_instance(); + + void Swap(CpIntervalVariable* other); + + // implements Message ---------------------------------------------- + + inline CpIntervalVariable* New() const { return New(NULL); } + + CpIntervalVariable* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpIntervalVariable& from); + void MergeFrom(const CpIntervalVariable& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpIntervalVariable* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 index = 1; + void clear_index(); + static const int kIndexFieldNumber = 1; + ::google::protobuf::int32 index() const; + void set_index(::google::protobuf::int32 value); + + // optional int32 type_index = 2; + void clear_type_index(); + static const int kTypeIndexFieldNumber = 2; + ::google::protobuf::int32 type_index() const; + void set_type_index(::google::protobuf::int32 value); + + // optional string name = 3; + void clear_name(); + static const int kNameFieldNumber = 3; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .operations_research.CpArgument arguments = 4; + int arguments_size() const; + void clear_arguments(); + static const int kArgumentsFieldNumber = 4; + const ::operations_research::CpArgument& arguments(int index) const; + ::operations_research::CpArgument* mutable_arguments(int index); + ::operations_research::CpArgument* add_arguments(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* + mutable_arguments(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& + arguments() const; + + // @@protoc_insertion_point(class_scope:operations_research.CpIntervalVariable) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int32 index_; + ::google::protobuf::int32 type_index_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument > arguments_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpIntervalVariable* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpSequenceVariable : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpSequenceVariable) */ { + public: + CpSequenceVariable(); + virtual ~CpSequenceVariable(); + + CpSequenceVariable(const CpSequenceVariable& from); + + inline CpSequenceVariable& operator=(const CpSequenceVariable& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpSequenceVariable& default_instance(); + + void Swap(CpSequenceVariable* other); + + // implements Message ---------------------------------------------- + + inline CpSequenceVariable* New() const { return New(NULL); } + + CpSequenceVariable* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpSequenceVariable& from); + void MergeFrom(const CpSequenceVariable& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpSequenceVariable* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 index = 1; + void clear_index(); + static const int kIndexFieldNumber = 1; + ::google::protobuf::int32 index() const; + void set_index(::google::protobuf::int32 value); + + // optional int32 type_index = 2; + void clear_type_index(); + static const int kTypeIndexFieldNumber = 2; + ::google::protobuf::int32 type_index() const; + void set_type_index(::google::protobuf::int32 value); + + // optional string name = 3; + void clear_name(); + static const int kNameFieldNumber = 3; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .operations_research.CpArgument arguments = 4; + int arguments_size() const; + void clear_arguments(); + static const int kArgumentsFieldNumber = 4; + const ::operations_research::CpArgument& arguments(int index) const; + ::operations_research::CpArgument* mutable_arguments(int index); + ::operations_research::CpArgument* add_arguments(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* + mutable_arguments(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& + arguments() const; + + // @@protoc_insertion_point(class_scope:operations_research.CpSequenceVariable) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int32 index_; + ::google::protobuf::int32 type_index_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument > arguments_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpSequenceVariable* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpConstraint : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpConstraint) */ { + public: + CpConstraint(); + virtual ~CpConstraint(); + + CpConstraint(const CpConstraint& from); + + inline CpConstraint& operator=(const CpConstraint& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpConstraint& default_instance(); + + void Swap(CpConstraint* other); + + // implements Message ---------------------------------------------- + + inline CpConstraint* New() const { return New(NULL); } + + CpConstraint* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpConstraint& from); + void MergeFrom(const CpConstraint& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpConstraint* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 index = 1; + void clear_index(); + static const int kIndexFieldNumber = 1; + ::google::protobuf::int32 index() const; + void set_index(::google::protobuf::int32 value); + + // optional int32 type_index = 2; + void clear_type_index(); + static const int kTypeIndexFieldNumber = 2; + ::google::protobuf::int32 type_index() const; + void set_type_index(::google::protobuf::int32 value); + + // optional string name = 3; + void clear_name(); + static const int kNameFieldNumber = 3; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .operations_research.CpArgument arguments = 4; + int arguments_size() const; + void clear_arguments(); + static const int kArgumentsFieldNumber = 4; + const ::operations_research::CpArgument& arguments(int index) const; + ::operations_research::CpArgument* mutable_arguments(int index); + ::operations_research::CpArgument* add_arguments(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* + mutable_arguments(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& + arguments() const; + + // repeated .operations_research.CpExtension extensions = 5; + int extensions_size() const; + void clear_extensions(); + static const int kExtensionsFieldNumber = 5; + const ::operations_research::CpExtension& extensions(int index) const; + ::operations_research::CpExtension* mutable_extensions(int index); + ::operations_research::CpExtension* add_extensions(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension >* + mutable_extensions(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension >& + extensions() const; + + // @@protoc_insertion_point(class_scope:operations_research.CpConstraint) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int32 index_; + ::google::protobuf::int32 type_index_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument > arguments_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension > extensions_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpConstraint* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpObjective : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpObjective) */ { + public: + CpObjective(); + virtual ~CpObjective(); + + CpObjective(const CpObjective& from); + + inline CpObjective& operator=(const CpObjective& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpObjective& default_instance(); + + void Swap(CpObjective* other); + + // implements Message ---------------------------------------------- + + inline CpObjective* New() const { return New(NULL); } + + CpObjective* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpObjective& from); + void MergeFrom(const CpObjective& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpObjective* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool maximize = 1; + void clear_maximize(); + static const int kMaximizeFieldNumber = 1; + bool maximize() const; + void set_maximize(bool value); + + // optional int64 step = 2; + void clear_step(); + static const int kStepFieldNumber = 2; + ::google::protobuf::int64 step() const; + void set_step(::google::protobuf::int64 value); + + // optional int32 objective_index = 3; + void clear_objective_index(); + static const int kObjectiveIndexFieldNumber = 3; + ::google::protobuf::int32 objective_index() const; + void set_objective_index(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:operations_research.CpObjective) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int64 step_; + bool maximize_; + ::google::protobuf::int32 objective_index_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpObjective* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpVariableGroup : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpVariableGroup) */ { + public: + CpVariableGroup(); + virtual ~CpVariableGroup(); + + CpVariableGroup(const CpVariableGroup& from); + + inline CpVariableGroup& operator=(const CpVariableGroup& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpVariableGroup& default_instance(); + + void Swap(CpVariableGroup* other); + + // implements Message ---------------------------------------------- + + inline CpVariableGroup* New() const { return New(NULL); } + + CpVariableGroup* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpVariableGroup& from); + void MergeFrom(const CpVariableGroup& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpVariableGroup* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .operations_research.CpArgument arguments = 1; + int arguments_size() const; + void clear_arguments(); + static const int kArgumentsFieldNumber = 1; + const ::operations_research::CpArgument& arguments(int index) const; + ::operations_research::CpArgument* mutable_arguments(int index); + ::operations_research::CpArgument* add_arguments(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* + mutable_arguments(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& + arguments() const; + + // optional string type = 2; + void clear_type(); + static const int kTypeFieldNumber = 2; + const ::std::string& type() const; + void set_type(const ::std::string& value); + void set_type(const char* value); + void set_type(const char* value, size_t size); + ::std::string* mutable_type(); + ::std::string* release_type(); + void set_allocated_type(::std::string* type); + + // @@protoc_insertion_point(class_scope:operations_research.CpVariableGroup) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument > arguments_; + ::google::protobuf::internal::ArenaStringPtr type_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpVariableGroup* default_instance_; +}; +// ------------------------------------------------------------------- + +class CpModel : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.CpModel) */ { + public: + CpModel(); + virtual ~CpModel(); + + CpModel(const CpModel& from); + + inline CpModel& operator=(const CpModel& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CpModel& default_instance(); + + void Swap(CpModel* other); + + // implements Message ---------------------------------------------- + + inline CpModel* New() const { return New(NULL); } + + CpModel* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CpModel& from); + void MergeFrom(const CpModel& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CpModel* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string model = 1; + void clear_model(); + static const int kModelFieldNumber = 1; + const ::std::string& model() const; + void set_model(const ::std::string& value); + void set_model(const char* value); + void set_model(const char* value, size_t size); + ::std::string* mutable_model(); + ::std::string* release_model(); + void set_allocated_model(::std::string* model); + + // optional int32 version = 2; + void clear_version(); + static const int kVersionFieldNumber = 2; + ::google::protobuf::int32 version() const; + void set_version(::google::protobuf::int32 value); + + // repeated string tags = 3; + int tags_size() const; + void clear_tags(); + static const int kTagsFieldNumber = 3; + const ::std::string& tags(int index) const; + ::std::string* mutable_tags(int index); + void set_tags(int index, const ::std::string& value); + void set_tags(int index, const char* value); + void set_tags(int index, const char* value, size_t size); + ::std::string* add_tags(); + void add_tags(const ::std::string& value); + void add_tags(const char* value); + void add_tags(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& tags() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_tags(); + + // repeated .operations_research.CpIntegerExpression expressions = 4; + int expressions_size() const; + void clear_expressions(); + static const int kExpressionsFieldNumber = 4; + const ::operations_research::CpIntegerExpression& expressions(int index) const; + ::operations_research::CpIntegerExpression* mutable_expressions(int index); + ::operations_research::CpIntegerExpression* add_expressions(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntegerExpression >* + mutable_expressions(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntegerExpression >& + expressions() const; + + // repeated .operations_research.CpIntervalVariable intervals = 5; + int intervals_size() const; + void clear_intervals(); + static const int kIntervalsFieldNumber = 5; + const ::operations_research::CpIntervalVariable& intervals(int index) const; + ::operations_research::CpIntervalVariable* mutable_intervals(int index); + ::operations_research::CpIntervalVariable* add_intervals(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntervalVariable >* + mutable_intervals(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntervalVariable >& + intervals() const; + + // repeated .operations_research.CpSequenceVariable sequences = 6; + int sequences_size() const; + void clear_sequences(); + static const int kSequencesFieldNumber = 6; + const ::operations_research::CpSequenceVariable& sequences(int index) const; + ::operations_research::CpSequenceVariable* mutable_sequences(int index); + ::operations_research::CpSequenceVariable* add_sequences(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpSequenceVariable >* + mutable_sequences(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpSequenceVariable >& + sequences() const; + + // repeated .operations_research.CpConstraint constraints = 7; + int constraints_size() const; + void clear_constraints(); + static const int kConstraintsFieldNumber = 7; + const ::operations_research::CpConstraint& constraints(int index) const; + ::operations_research::CpConstraint* mutable_constraints(int index); + ::operations_research::CpConstraint* add_constraints(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpConstraint >* + mutable_constraints(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpConstraint >& + constraints() const; + + // optional .operations_research.CpObjective objective = 8; + bool has_objective() const; + void clear_objective(); + static const int kObjectiveFieldNumber = 8; + const ::operations_research::CpObjective& objective() const; + ::operations_research::CpObjective* mutable_objective(); + ::operations_research::CpObjective* release_objective(); + void set_allocated_objective(::operations_research::CpObjective* objective); + + // optional .operations_research.SearchLimitParameters search_limit = 9; + bool has_search_limit() const; + void clear_search_limit(); + static const int kSearchLimitFieldNumber = 9; + const ::operations_research::SearchLimitParameters& search_limit() const; + ::operations_research::SearchLimitParameters* mutable_search_limit(); + ::operations_research::SearchLimitParameters* release_search_limit(); + void set_allocated_search_limit(::operations_research::SearchLimitParameters* search_limit); + + // repeated .operations_research.CpVariableGroup variable_groups = 10; + int variable_groups_size() const; + void clear_variable_groups(); + static const int kVariableGroupsFieldNumber = 10; + const ::operations_research::CpVariableGroup& variable_groups(int index) const; + ::operations_research::CpVariableGroup* mutable_variable_groups(int index); + ::operations_research::CpVariableGroup* add_variable_groups(); + ::google::protobuf::RepeatedPtrField< ::operations_research::CpVariableGroup >* + mutable_variable_groups(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::CpVariableGroup >& + variable_groups() const; + + // optional string license_text = 11; + void clear_license_text(); + static const int kLicenseTextFieldNumber = 11; + const ::std::string& license_text() const; + void set_license_text(const ::std::string& value); + void set_license_text(const char* value); + void set_license_text(const char* value, size_t size); + ::std::string* mutable_license_text(); + ::std::string* release_license_text(); + void set_allocated_license_text(::std::string* license_text); + + // @@protoc_insertion_point(class_scope:operations_research.CpModel) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr model_; + ::google::protobuf::RepeatedPtrField< ::std::string> tags_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntegerExpression > expressions_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntervalVariable > intervals_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpSequenceVariable > sequences_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpConstraint > constraints_; + ::operations_research::CpObjective* objective_; + ::operations_research::SearchLimitParameters* search_limit_; + ::google::protobuf::RepeatedPtrField< ::operations_research::CpVariableGroup > variable_groups_; + ::google::protobuf::internal::ArenaStringPtr license_text_; + ::google::protobuf::int32 version_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fmodel_2eproto(); + + void InitAsDefaultInstance(); + static CpModel* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// CpIntegerMatrix + +// optional int32 rows = 1; +inline void CpIntegerMatrix::clear_rows() { + rows_ = 0; +} +inline ::google::protobuf::int32 CpIntegerMatrix::rows() const { + // @@protoc_insertion_point(field_get:operations_research.CpIntegerMatrix.rows) + return rows_; +} +inline void CpIntegerMatrix::set_rows(::google::protobuf::int32 value) { + + rows_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpIntegerMatrix.rows) +} + +// optional int32 columns = 2; +inline void CpIntegerMatrix::clear_columns() { + columns_ = 0; +} +inline ::google::protobuf::int32 CpIntegerMatrix::columns() const { + // @@protoc_insertion_point(field_get:operations_research.CpIntegerMatrix.columns) + return columns_; +} +inline void CpIntegerMatrix::set_columns(::google::protobuf::int32 value) { + + columns_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpIntegerMatrix.columns) +} + +// repeated int64 values = 3; +inline int CpIntegerMatrix::values_size() const { + return values_.size(); +} +inline void CpIntegerMatrix::clear_values() { + values_.Clear(); +} +inline ::google::protobuf::int64 CpIntegerMatrix::values(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpIntegerMatrix.values) + return values_.Get(index); +} +inline void CpIntegerMatrix::set_values(int index, ::google::protobuf::int64 value) { + values_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.CpIntegerMatrix.values) +} +inline void CpIntegerMatrix::add_values(::google::protobuf::int64 value) { + values_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.CpIntegerMatrix.values) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& +CpIntegerMatrix::values() const { + // @@protoc_insertion_point(field_list:operations_research.CpIntegerMatrix.values) + return values_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* +CpIntegerMatrix::mutable_values() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpIntegerMatrix.values) + return &values_; +} + +// ------------------------------------------------------------------- + +// CpArgument + +// optional int32 argument_index = 1; +inline void CpArgument::clear_argument_index() { + argument_index_ = 0; +} +inline ::google::protobuf::int32 CpArgument::argument_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.argument_index) + return argument_index_; +} +inline void CpArgument::set_argument_index(::google::protobuf::int32 value) { + + argument_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpArgument.argument_index) +} + +// optional int64 integer_value = 2; +inline void CpArgument::clear_integer_value() { + integer_value_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 CpArgument::integer_value() const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.integer_value) + return integer_value_; +} +inline void CpArgument::set_integer_value(::google::protobuf::int64 value) { + + integer_value_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpArgument.integer_value) +} + +// repeated int64 integer_array = 3; +inline int CpArgument::integer_array_size() const { + return integer_array_.size(); +} +inline void CpArgument::clear_integer_array() { + integer_array_.Clear(); +} +inline ::google::protobuf::int64 CpArgument::integer_array(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.integer_array) + return integer_array_.Get(index); +} +inline void CpArgument::set_integer_array(int index, ::google::protobuf::int64 value) { + integer_array_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.CpArgument.integer_array) +} +inline void CpArgument::add_integer_array(::google::protobuf::int64 value) { + integer_array_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.CpArgument.integer_array) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& +CpArgument::integer_array() const { + // @@protoc_insertion_point(field_list:operations_research.CpArgument.integer_array) + return integer_array_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* +CpArgument::mutable_integer_array() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpArgument.integer_array) + return &integer_array_; +} + +// optional int32 integer_expression_index = 4; +inline void CpArgument::clear_integer_expression_index() { + integer_expression_index_ = 0; +} +inline ::google::protobuf::int32 CpArgument::integer_expression_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.integer_expression_index) + return integer_expression_index_; +} +inline void CpArgument::set_integer_expression_index(::google::protobuf::int32 value) { + + integer_expression_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpArgument.integer_expression_index) +} + +// repeated int32 integer_expression_array = 5; +inline int CpArgument::integer_expression_array_size() const { + return integer_expression_array_.size(); +} +inline void CpArgument::clear_integer_expression_array() { + integer_expression_array_.Clear(); +} +inline ::google::protobuf::int32 CpArgument::integer_expression_array(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.integer_expression_array) + return integer_expression_array_.Get(index); +} +inline void CpArgument::set_integer_expression_array(int index, ::google::protobuf::int32 value) { + integer_expression_array_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.CpArgument.integer_expression_array) +} +inline void CpArgument::add_integer_expression_array(::google::protobuf::int32 value) { + integer_expression_array_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.CpArgument.integer_expression_array) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +CpArgument::integer_expression_array() const { + // @@protoc_insertion_point(field_list:operations_research.CpArgument.integer_expression_array) + return integer_expression_array_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +CpArgument::mutable_integer_expression_array() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpArgument.integer_expression_array) + return &integer_expression_array_; +} + +// optional int32 interval_index = 6; +inline void CpArgument::clear_interval_index() { + interval_index_ = 0; +} +inline ::google::protobuf::int32 CpArgument::interval_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.interval_index) + return interval_index_; +} +inline void CpArgument::set_interval_index(::google::protobuf::int32 value) { + + interval_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpArgument.interval_index) +} + +// repeated int32 interval_array = 7; +inline int CpArgument::interval_array_size() const { + return interval_array_.size(); +} +inline void CpArgument::clear_interval_array() { + interval_array_.Clear(); +} +inline ::google::protobuf::int32 CpArgument::interval_array(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.interval_array) + return interval_array_.Get(index); +} +inline void CpArgument::set_interval_array(int index, ::google::protobuf::int32 value) { + interval_array_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.CpArgument.interval_array) +} +inline void CpArgument::add_interval_array(::google::protobuf::int32 value) { + interval_array_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.CpArgument.interval_array) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +CpArgument::interval_array() const { + // @@protoc_insertion_point(field_list:operations_research.CpArgument.interval_array) + return interval_array_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +CpArgument::mutable_interval_array() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpArgument.interval_array) + return &interval_array_; +} + +// optional int32 sequence_index = 8; +inline void CpArgument::clear_sequence_index() { + sequence_index_ = 0; +} +inline ::google::protobuf::int32 CpArgument::sequence_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.sequence_index) + return sequence_index_; +} +inline void CpArgument::set_sequence_index(::google::protobuf::int32 value) { + + sequence_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpArgument.sequence_index) +} + +// repeated int32 sequence_array = 9; +inline int CpArgument::sequence_array_size() const { + return sequence_array_.size(); +} +inline void CpArgument::clear_sequence_array() { + sequence_array_.Clear(); +} +inline ::google::protobuf::int32 CpArgument::sequence_array(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.sequence_array) + return sequence_array_.Get(index); +} +inline void CpArgument::set_sequence_array(int index, ::google::protobuf::int32 value) { + sequence_array_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.CpArgument.sequence_array) +} +inline void CpArgument::add_sequence_array(::google::protobuf::int32 value) { + sequence_array_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.CpArgument.sequence_array) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +CpArgument::sequence_array() const { + // @@protoc_insertion_point(field_list:operations_research.CpArgument.sequence_array) + return sequence_array_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +CpArgument::mutable_sequence_array() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpArgument.sequence_array) + return &sequence_array_; +} + +// optional .operations_research.CpIntegerMatrix integer_matrix = 10; +inline bool CpArgument::has_integer_matrix() const { + return !_is_default_instance_ && integer_matrix_ != NULL; +} +inline void CpArgument::clear_integer_matrix() { + if (GetArenaNoVirtual() == NULL && integer_matrix_ != NULL) delete integer_matrix_; + integer_matrix_ = NULL; +} +inline const ::operations_research::CpIntegerMatrix& CpArgument::integer_matrix() const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.integer_matrix) + return integer_matrix_ != NULL ? *integer_matrix_ : *default_instance_->integer_matrix_; +} +inline ::operations_research::CpIntegerMatrix* CpArgument::mutable_integer_matrix() { + + if (integer_matrix_ == NULL) { + integer_matrix_ = new ::operations_research::CpIntegerMatrix; + } + // @@protoc_insertion_point(field_mutable:operations_research.CpArgument.integer_matrix) + return integer_matrix_; +} +inline ::operations_research::CpIntegerMatrix* CpArgument::release_integer_matrix() { + // @@protoc_insertion_point(field_release:operations_research.CpArgument.integer_matrix) + + ::operations_research::CpIntegerMatrix* temp = integer_matrix_; + integer_matrix_ = NULL; + return temp; +} +inline void CpArgument::set_allocated_integer_matrix(::operations_research::CpIntegerMatrix* integer_matrix) { + delete integer_matrix_; + integer_matrix_ = integer_matrix; + if (integer_matrix) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:operations_research.CpArgument.integer_matrix) +} + +// optional .operations_research.CpArgument.Type type = 11; +inline void CpArgument::clear_type() { + type_ = 0; +} +inline ::operations_research::CpArgument_Type CpArgument::type() const { + // @@protoc_insertion_point(field_get:operations_research.CpArgument.type) + return static_cast< ::operations_research::CpArgument_Type >(type_); +} +inline void CpArgument::set_type(::operations_research::CpArgument_Type value) { + + type_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpArgument.type) +} + +// ------------------------------------------------------------------- + +// CpExtension + +// optional int32 type_index = 1; +inline void CpExtension::clear_type_index() { + type_index_ = 0; +} +inline ::google::protobuf::int32 CpExtension::type_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpExtension.type_index) + return type_index_; +} +inline void CpExtension::set_type_index(::google::protobuf::int32 value) { + + type_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpExtension.type_index) +} + +// repeated .operations_research.CpArgument arguments = 2; +inline int CpExtension::arguments_size() const { + return arguments_.size(); +} +inline void CpExtension::clear_arguments() { + arguments_.Clear(); +} +inline const ::operations_research::CpArgument& CpExtension::arguments(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpExtension.arguments) + return arguments_.Get(index); +} +inline ::operations_research::CpArgument* CpExtension::mutable_arguments(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpExtension.arguments) + return arguments_.Mutable(index); +} +inline ::operations_research::CpArgument* CpExtension::add_arguments() { + // @@protoc_insertion_point(field_add:operations_research.CpExtension.arguments) + return arguments_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* +CpExtension::mutable_arguments() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpExtension.arguments) + return &arguments_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& +CpExtension::arguments() const { + // @@protoc_insertion_point(field_list:operations_research.CpExtension.arguments) + return arguments_; +} + +// ------------------------------------------------------------------- + +// CpIntegerExpression + +// optional int32 index = 1; +inline void CpIntegerExpression::clear_index() { + index_ = 0; +} +inline ::google::protobuf::int32 CpIntegerExpression::index() const { + // @@protoc_insertion_point(field_get:operations_research.CpIntegerExpression.index) + return index_; +} +inline void CpIntegerExpression::set_index(::google::protobuf::int32 value) { + + index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpIntegerExpression.index) +} + +// optional int32 type_index = 2; +inline void CpIntegerExpression::clear_type_index() { + type_index_ = 0; +} +inline ::google::protobuf::int32 CpIntegerExpression::type_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpIntegerExpression.type_index) + return type_index_; +} +inline void CpIntegerExpression::set_type_index(::google::protobuf::int32 value) { + + type_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpIntegerExpression.type_index) +} + +// optional string name = 3; +inline void CpIntegerExpression::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& CpIntegerExpression::name() const { + // @@protoc_insertion_point(field_get:operations_research.CpIntegerExpression.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpIntegerExpression::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.CpIntegerExpression.name) +} +inline void CpIntegerExpression::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.CpIntegerExpression.name) +} +inline void CpIntegerExpression::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.CpIntegerExpression.name) +} +inline ::std::string* CpIntegerExpression::mutable_name() { + + // @@protoc_insertion_point(field_mutable:operations_research.CpIntegerExpression.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CpIntegerExpression::release_name() { + // @@protoc_insertion_point(field_release:operations_research.CpIntegerExpression.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpIntegerExpression::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.CpIntegerExpression.name) +} + +// repeated .operations_research.CpArgument arguments = 4; +inline int CpIntegerExpression::arguments_size() const { + return arguments_.size(); +} +inline void CpIntegerExpression::clear_arguments() { + arguments_.Clear(); +} +inline const ::operations_research::CpArgument& CpIntegerExpression::arguments(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpIntegerExpression.arguments) + return arguments_.Get(index); +} +inline ::operations_research::CpArgument* CpIntegerExpression::mutable_arguments(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpIntegerExpression.arguments) + return arguments_.Mutable(index); +} +inline ::operations_research::CpArgument* CpIntegerExpression::add_arguments() { + // @@protoc_insertion_point(field_add:operations_research.CpIntegerExpression.arguments) + return arguments_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* +CpIntegerExpression::mutable_arguments() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpIntegerExpression.arguments) + return &arguments_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& +CpIntegerExpression::arguments() const { + // @@protoc_insertion_point(field_list:operations_research.CpIntegerExpression.arguments) + return arguments_; +} + +// repeated .operations_research.CpExtension extensions = 5; +inline int CpIntegerExpression::extensions_size() const { + return extensions_.size(); +} +inline void CpIntegerExpression::clear_extensions() { + extensions_.Clear(); +} +inline const ::operations_research::CpExtension& CpIntegerExpression::extensions(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpIntegerExpression.extensions) + return extensions_.Get(index); +} +inline ::operations_research::CpExtension* CpIntegerExpression::mutable_extensions(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpIntegerExpression.extensions) + return extensions_.Mutable(index); +} +inline ::operations_research::CpExtension* CpIntegerExpression::add_extensions() { + // @@protoc_insertion_point(field_add:operations_research.CpIntegerExpression.extensions) + return extensions_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension >* +CpIntegerExpression::mutable_extensions() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpIntegerExpression.extensions) + return &extensions_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension >& +CpIntegerExpression::extensions() const { + // @@protoc_insertion_point(field_list:operations_research.CpIntegerExpression.extensions) + return extensions_; +} + +// ------------------------------------------------------------------- + +// CpIntervalVariable + +// optional int32 index = 1; +inline void CpIntervalVariable::clear_index() { + index_ = 0; +} +inline ::google::protobuf::int32 CpIntervalVariable::index() const { + // @@protoc_insertion_point(field_get:operations_research.CpIntervalVariable.index) + return index_; +} +inline void CpIntervalVariable::set_index(::google::protobuf::int32 value) { + + index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpIntervalVariable.index) +} + +// optional int32 type_index = 2; +inline void CpIntervalVariable::clear_type_index() { + type_index_ = 0; +} +inline ::google::protobuf::int32 CpIntervalVariable::type_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpIntervalVariable.type_index) + return type_index_; +} +inline void CpIntervalVariable::set_type_index(::google::protobuf::int32 value) { + + type_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpIntervalVariable.type_index) +} + +// optional string name = 3; +inline void CpIntervalVariable::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& CpIntervalVariable::name() const { + // @@protoc_insertion_point(field_get:operations_research.CpIntervalVariable.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpIntervalVariable::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.CpIntervalVariable.name) +} +inline void CpIntervalVariable::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.CpIntervalVariable.name) +} +inline void CpIntervalVariable::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.CpIntervalVariable.name) +} +inline ::std::string* CpIntervalVariable::mutable_name() { + + // @@protoc_insertion_point(field_mutable:operations_research.CpIntervalVariable.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CpIntervalVariable::release_name() { + // @@protoc_insertion_point(field_release:operations_research.CpIntervalVariable.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpIntervalVariable::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.CpIntervalVariable.name) +} + +// repeated .operations_research.CpArgument arguments = 4; +inline int CpIntervalVariable::arguments_size() const { + return arguments_.size(); +} +inline void CpIntervalVariable::clear_arguments() { + arguments_.Clear(); +} +inline const ::operations_research::CpArgument& CpIntervalVariable::arguments(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpIntervalVariable.arguments) + return arguments_.Get(index); +} +inline ::operations_research::CpArgument* CpIntervalVariable::mutable_arguments(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpIntervalVariable.arguments) + return arguments_.Mutable(index); +} +inline ::operations_research::CpArgument* CpIntervalVariable::add_arguments() { + // @@protoc_insertion_point(field_add:operations_research.CpIntervalVariable.arguments) + return arguments_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* +CpIntervalVariable::mutable_arguments() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpIntervalVariable.arguments) + return &arguments_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& +CpIntervalVariable::arguments() const { + // @@protoc_insertion_point(field_list:operations_research.CpIntervalVariable.arguments) + return arguments_; +} + +// ------------------------------------------------------------------- + +// CpSequenceVariable + +// optional int32 index = 1; +inline void CpSequenceVariable::clear_index() { + index_ = 0; +} +inline ::google::protobuf::int32 CpSequenceVariable::index() const { + // @@protoc_insertion_point(field_get:operations_research.CpSequenceVariable.index) + return index_; +} +inline void CpSequenceVariable::set_index(::google::protobuf::int32 value) { + + index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpSequenceVariable.index) +} + +// optional int32 type_index = 2; +inline void CpSequenceVariable::clear_type_index() { + type_index_ = 0; +} +inline ::google::protobuf::int32 CpSequenceVariable::type_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpSequenceVariable.type_index) + return type_index_; +} +inline void CpSequenceVariable::set_type_index(::google::protobuf::int32 value) { + + type_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpSequenceVariable.type_index) +} + +// optional string name = 3; +inline void CpSequenceVariable::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& CpSequenceVariable::name() const { + // @@protoc_insertion_point(field_get:operations_research.CpSequenceVariable.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpSequenceVariable::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.CpSequenceVariable.name) +} +inline void CpSequenceVariable::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.CpSequenceVariable.name) +} +inline void CpSequenceVariable::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.CpSequenceVariable.name) +} +inline ::std::string* CpSequenceVariable::mutable_name() { + + // @@protoc_insertion_point(field_mutable:operations_research.CpSequenceVariable.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CpSequenceVariable::release_name() { + // @@protoc_insertion_point(field_release:operations_research.CpSequenceVariable.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpSequenceVariable::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.CpSequenceVariable.name) +} + +// repeated .operations_research.CpArgument arguments = 4; +inline int CpSequenceVariable::arguments_size() const { + return arguments_.size(); +} +inline void CpSequenceVariable::clear_arguments() { + arguments_.Clear(); +} +inline const ::operations_research::CpArgument& CpSequenceVariable::arguments(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpSequenceVariable.arguments) + return arguments_.Get(index); +} +inline ::operations_research::CpArgument* CpSequenceVariable::mutable_arguments(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpSequenceVariable.arguments) + return arguments_.Mutable(index); +} +inline ::operations_research::CpArgument* CpSequenceVariable::add_arguments() { + // @@protoc_insertion_point(field_add:operations_research.CpSequenceVariable.arguments) + return arguments_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* +CpSequenceVariable::mutable_arguments() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpSequenceVariable.arguments) + return &arguments_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& +CpSequenceVariable::arguments() const { + // @@protoc_insertion_point(field_list:operations_research.CpSequenceVariable.arguments) + return arguments_; +} + +// ------------------------------------------------------------------- + +// CpConstraint + +// optional int32 index = 1; +inline void CpConstraint::clear_index() { + index_ = 0; +} +inline ::google::protobuf::int32 CpConstraint::index() const { + // @@protoc_insertion_point(field_get:operations_research.CpConstraint.index) + return index_; +} +inline void CpConstraint::set_index(::google::protobuf::int32 value) { + + index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpConstraint.index) +} + +// optional int32 type_index = 2; +inline void CpConstraint::clear_type_index() { + type_index_ = 0; +} +inline ::google::protobuf::int32 CpConstraint::type_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpConstraint.type_index) + return type_index_; +} +inline void CpConstraint::set_type_index(::google::protobuf::int32 value) { + + type_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpConstraint.type_index) +} + +// optional string name = 3; +inline void CpConstraint::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& CpConstraint::name() const { + // @@protoc_insertion_point(field_get:operations_research.CpConstraint.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpConstraint::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.CpConstraint.name) +} +inline void CpConstraint::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.CpConstraint.name) +} +inline void CpConstraint::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.CpConstraint.name) +} +inline ::std::string* CpConstraint::mutable_name() { + + // @@protoc_insertion_point(field_mutable:operations_research.CpConstraint.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CpConstraint::release_name() { + // @@protoc_insertion_point(field_release:operations_research.CpConstraint.name) + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpConstraint::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.CpConstraint.name) +} + +// repeated .operations_research.CpArgument arguments = 4; +inline int CpConstraint::arguments_size() const { + return arguments_.size(); +} +inline void CpConstraint::clear_arguments() { + arguments_.Clear(); +} +inline const ::operations_research::CpArgument& CpConstraint::arguments(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpConstraint.arguments) + return arguments_.Get(index); +} +inline ::operations_research::CpArgument* CpConstraint::mutable_arguments(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpConstraint.arguments) + return arguments_.Mutable(index); +} +inline ::operations_research::CpArgument* CpConstraint::add_arguments() { + // @@protoc_insertion_point(field_add:operations_research.CpConstraint.arguments) + return arguments_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* +CpConstraint::mutable_arguments() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpConstraint.arguments) + return &arguments_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& +CpConstraint::arguments() const { + // @@protoc_insertion_point(field_list:operations_research.CpConstraint.arguments) + return arguments_; +} + +// repeated .operations_research.CpExtension extensions = 5; +inline int CpConstraint::extensions_size() const { + return extensions_.size(); +} +inline void CpConstraint::clear_extensions() { + extensions_.Clear(); +} +inline const ::operations_research::CpExtension& CpConstraint::extensions(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpConstraint.extensions) + return extensions_.Get(index); +} +inline ::operations_research::CpExtension* CpConstraint::mutable_extensions(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpConstraint.extensions) + return extensions_.Mutable(index); +} +inline ::operations_research::CpExtension* CpConstraint::add_extensions() { + // @@protoc_insertion_point(field_add:operations_research.CpConstraint.extensions) + return extensions_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension >* +CpConstraint::mutable_extensions() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpConstraint.extensions) + return &extensions_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpExtension >& +CpConstraint::extensions() const { + // @@protoc_insertion_point(field_list:operations_research.CpConstraint.extensions) + return extensions_; +} + +// ------------------------------------------------------------------- + +// CpObjective + +// optional bool maximize = 1; +inline void CpObjective::clear_maximize() { + maximize_ = false; +} +inline bool CpObjective::maximize() const { + // @@protoc_insertion_point(field_get:operations_research.CpObjective.maximize) + return maximize_; +} +inline void CpObjective::set_maximize(bool value) { + + maximize_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpObjective.maximize) +} + +// optional int64 step = 2; +inline void CpObjective::clear_step() { + step_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 CpObjective::step() const { + // @@protoc_insertion_point(field_get:operations_research.CpObjective.step) + return step_; +} +inline void CpObjective::set_step(::google::protobuf::int64 value) { + + step_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpObjective.step) +} + +// optional int32 objective_index = 3; +inline void CpObjective::clear_objective_index() { + objective_index_ = 0; +} +inline ::google::protobuf::int32 CpObjective::objective_index() const { + // @@protoc_insertion_point(field_get:operations_research.CpObjective.objective_index) + return objective_index_; +} +inline void CpObjective::set_objective_index(::google::protobuf::int32 value) { + + objective_index_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpObjective.objective_index) +} + +// ------------------------------------------------------------------- + +// CpVariableGroup + +// repeated .operations_research.CpArgument arguments = 1; +inline int CpVariableGroup::arguments_size() const { + return arguments_.size(); +} +inline void CpVariableGroup::clear_arguments() { + arguments_.Clear(); +} +inline const ::operations_research::CpArgument& CpVariableGroup::arguments(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpVariableGroup.arguments) + return arguments_.Get(index); +} +inline ::operations_research::CpArgument* CpVariableGroup::mutable_arguments(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpVariableGroup.arguments) + return arguments_.Mutable(index); +} +inline ::operations_research::CpArgument* CpVariableGroup::add_arguments() { + // @@protoc_insertion_point(field_add:operations_research.CpVariableGroup.arguments) + return arguments_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >* +CpVariableGroup::mutable_arguments() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpVariableGroup.arguments) + return &arguments_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpArgument >& +CpVariableGroup::arguments() const { + // @@protoc_insertion_point(field_list:operations_research.CpVariableGroup.arguments) + return arguments_; +} + +// optional string type = 2; +inline void CpVariableGroup::clear_type() { + type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& CpVariableGroup::type() const { + // @@protoc_insertion_point(field_get:operations_research.CpVariableGroup.type) + return type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpVariableGroup::set_type(const ::std::string& value) { + + type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.CpVariableGroup.type) +} +inline void CpVariableGroup::set_type(const char* value) { + + type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.CpVariableGroup.type) +} +inline void CpVariableGroup::set_type(const char* value, size_t size) { + + type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.CpVariableGroup.type) +} +inline ::std::string* CpVariableGroup::mutable_type() { + + // @@protoc_insertion_point(field_mutable:operations_research.CpVariableGroup.type) + return type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CpVariableGroup::release_type() { + // @@protoc_insertion_point(field_release:operations_research.CpVariableGroup.type) + + return type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpVariableGroup::set_allocated_type(::std::string* type) { + if (type != NULL) { + + } else { + + } + type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type); + // @@protoc_insertion_point(field_set_allocated:operations_research.CpVariableGroup.type) +} + +// ------------------------------------------------------------------- + +// CpModel + +// optional string model = 1; +inline void CpModel::clear_model() { + model_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& CpModel::model() const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.model) + return model_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpModel::set_model(const ::std::string& value) { + + model_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.CpModel.model) +} +inline void CpModel::set_model(const char* value) { + + model_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.CpModel.model) +} +inline void CpModel::set_model(const char* value, size_t size) { + + model_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.CpModel.model) +} +inline ::std::string* CpModel::mutable_model() { + + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.model) + return model_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CpModel::release_model() { + // @@protoc_insertion_point(field_release:operations_research.CpModel.model) + + return model_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpModel::set_allocated_model(::std::string* model) { + if (model != NULL) { + + } else { + + } + model_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), model); + // @@protoc_insertion_point(field_set_allocated:operations_research.CpModel.model) +} + +// optional int32 version = 2; +inline void CpModel::clear_version() { + version_ = 0; +} +inline ::google::protobuf::int32 CpModel::version() const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.version) + return version_; +} +inline void CpModel::set_version(::google::protobuf::int32 value) { + + version_ = value; + // @@protoc_insertion_point(field_set:operations_research.CpModel.version) +} + +// repeated string tags = 3; +inline int CpModel::tags_size() const { + return tags_.size(); +} +inline void CpModel::clear_tags() { + tags_.Clear(); +} +inline const ::std::string& CpModel::tags(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.tags) + return tags_.Get(index); +} +inline ::std::string* CpModel::mutable_tags(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.tags) + return tags_.Mutable(index); +} +inline void CpModel::set_tags(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:operations_research.CpModel.tags) + tags_.Mutable(index)->assign(value); +} +inline void CpModel::set_tags(int index, const char* value) { + tags_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:operations_research.CpModel.tags) +} +inline void CpModel::set_tags(int index, const char* value, size_t size) { + tags_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:operations_research.CpModel.tags) +} +inline ::std::string* CpModel::add_tags() { + // @@protoc_insertion_point(field_add_mutable:operations_research.CpModel.tags) + return tags_.Add(); +} +inline void CpModel::add_tags(const ::std::string& value) { + tags_.Add()->assign(value); + // @@protoc_insertion_point(field_add:operations_research.CpModel.tags) +} +inline void CpModel::add_tags(const char* value) { + tags_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:operations_research.CpModel.tags) +} +inline void CpModel::add_tags(const char* value, size_t size) { + tags_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:operations_research.CpModel.tags) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +CpModel::tags() const { + // @@protoc_insertion_point(field_list:operations_research.CpModel.tags) + return tags_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +CpModel::mutable_tags() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpModel.tags) + return &tags_; +} + +// repeated .operations_research.CpIntegerExpression expressions = 4; +inline int CpModel::expressions_size() const { + return expressions_.size(); +} +inline void CpModel::clear_expressions() { + expressions_.Clear(); +} +inline const ::operations_research::CpIntegerExpression& CpModel::expressions(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.expressions) + return expressions_.Get(index); +} +inline ::operations_research::CpIntegerExpression* CpModel::mutable_expressions(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.expressions) + return expressions_.Mutable(index); +} +inline ::operations_research::CpIntegerExpression* CpModel::add_expressions() { + // @@protoc_insertion_point(field_add:operations_research.CpModel.expressions) + return expressions_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntegerExpression >* +CpModel::mutable_expressions() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpModel.expressions) + return &expressions_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntegerExpression >& +CpModel::expressions() const { + // @@protoc_insertion_point(field_list:operations_research.CpModel.expressions) + return expressions_; +} + +// repeated .operations_research.CpIntervalVariable intervals = 5; +inline int CpModel::intervals_size() const { + return intervals_.size(); +} +inline void CpModel::clear_intervals() { + intervals_.Clear(); +} +inline const ::operations_research::CpIntervalVariable& CpModel::intervals(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.intervals) + return intervals_.Get(index); +} +inline ::operations_research::CpIntervalVariable* CpModel::mutable_intervals(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.intervals) + return intervals_.Mutable(index); +} +inline ::operations_research::CpIntervalVariable* CpModel::add_intervals() { + // @@protoc_insertion_point(field_add:operations_research.CpModel.intervals) + return intervals_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntervalVariable >* +CpModel::mutable_intervals() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpModel.intervals) + return &intervals_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpIntervalVariable >& +CpModel::intervals() const { + // @@protoc_insertion_point(field_list:operations_research.CpModel.intervals) + return intervals_; +} + +// repeated .operations_research.CpSequenceVariable sequences = 6; +inline int CpModel::sequences_size() const { + return sequences_.size(); +} +inline void CpModel::clear_sequences() { + sequences_.Clear(); +} +inline const ::operations_research::CpSequenceVariable& CpModel::sequences(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.sequences) + return sequences_.Get(index); +} +inline ::operations_research::CpSequenceVariable* CpModel::mutable_sequences(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.sequences) + return sequences_.Mutable(index); +} +inline ::operations_research::CpSequenceVariable* CpModel::add_sequences() { + // @@protoc_insertion_point(field_add:operations_research.CpModel.sequences) + return sequences_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpSequenceVariable >* +CpModel::mutable_sequences() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpModel.sequences) + return &sequences_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpSequenceVariable >& +CpModel::sequences() const { + // @@protoc_insertion_point(field_list:operations_research.CpModel.sequences) + return sequences_; +} + +// repeated .operations_research.CpConstraint constraints = 7; +inline int CpModel::constraints_size() const { + return constraints_.size(); +} +inline void CpModel::clear_constraints() { + constraints_.Clear(); +} +inline const ::operations_research::CpConstraint& CpModel::constraints(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.constraints) + return constraints_.Get(index); +} +inline ::operations_research::CpConstraint* CpModel::mutable_constraints(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.constraints) + return constraints_.Mutable(index); +} +inline ::operations_research::CpConstraint* CpModel::add_constraints() { + // @@protoc_insertion_point(field_add:operations_research.CpModel.constraints) + return constraints_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpConstraint >* +CpModel::mutable_constraints() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpModel.constraints) + return &constraints_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpConstraint >& +CpModel::constraints() const { + // @@protoc_insertion_point(field_list:operations_research.CpModel.constraints) + return constraints_; +} + +// optional .operations_research.CpObjective objective = 8; +inline bool CpModel::has_objective() const { + return !_is_default_instance_ && objective_ != NULL; +} +inline void CpModel::clear_objective() { + if (GetArenaNoVirtual() == NULL && objective_ != NULL) delete objective_; + objective_ = NULL; +} +inline const ::operations_research::CpObjective& CpModel::objective() const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.objective) + return objective_ != NULL ? *objective_ : *default_instance_->objective_; +} +inline ::operations_research::CpObjective* CpModel::mutable_objective() { + + if (objective_ == NULL) { + objective_ = new ::operations_research::CpObjective; + } + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.objective) + return objective_; +} +inline ::operations_research::CpObjective* CpModel::release_objective() { + // @@protoc_insertion_point(field_release:operations_research.CpModel.objective) + + ::operations_research::CpObjective* temp = objective_; + objective_ = NULL; + return temp; +} +inline void CpModel::set_allocated_objective(::operations_research::CpObjective* objective) { + delete objective_; + objective_ = objective; + if (objective) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:operations_research.CpModel.objective) +} + +// optional .operations_research.SearchLimitParameters search_limit = 9; +inline bool CpModel::has_search_limit() const { + return !_is_default_instance_ && search_limit_ != NULL; +} +inline void CpModel::clear_search_limit() { + if (GetArenaNoVirtual() == NULL && search_limit_ != NULL) delete search_limit_; + search_limit_ = NULL; +} +inline const ::operations_research::SearchLimitParameters& CpModel::search_limit() const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.search_limit) + return search_limit_ != NULL ? *search_limit_ : *default_instance_->search_limit_; +} +inline ::operations_research::SearchLimitParameters* CpModel::mutable_search_limit() { + + if (search_limit_ == NULL) { + search_limit_ = new ::operations_research::SearchLimitParameters; + } + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.search_limit) + return search_limit_; +} +inline ::operations_research::SearchLimitParameters* CpModel::release_search_limit() { + // @@protoc_insertion_point(field_release:operations_research.CpModel.search_limit) + + ::operations_research::SearchLimitParameters* temp = search_limit_; + search_limit_ = NULL; + return temp; +} +inline void CpModel::set_allocated_search_limit(::operations_research::SearchLimitParameters* search_limit) { + delete search_limit_; + search_limit_ = search_limit; + if (search_limit) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:operations_research.CpModel.search_limit) +} + +// repeated .operations_research.CpVariableGroup variable_groups = 10; +inline int CpModel::variable_groups_size() const { + return variable_groups_.size(); +} +inline void CpModel::clear_variable_groups() { + variable_groups_.Clear(); +} +inline const ::operations_research::CpVariableGroup& CpModel::variable_groups(int index) const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.variable_groups) + return variable_groups_.Get(index); +} +inline ::operations_research::CpVariableGroup* CpModel::mutable_variable_groups(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.variable_groups) + return variable_groups_.Mutable(index); +} +inline ::operations_research::CpVariableGroup* CpModel::add_variable_groups() { + // @@protoc_insertion_point(field_add:operations_research.CpModel.variable_groups) + return variable_groups_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::CpVariableGroup >* +CpModel::mutable_variable_groups() { + // @@protoc_insertion_point(field_mutable_list:operations_research.CpModel.variable_groups) + return &variable_groups_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::CpVariableGroup >& +CpModel::variable_groups() const { + // @@protoc_insertion_point(field_list:operations_research.CpModel.variable_groups) + return variable_groups_; +} + +// optional string license_text = 11; +inline void CpModel::clear_license_text() { + license_text_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& CpModel::license_text() const { + // @@protoc_insertion_point(field_get:operations_research.CpModel.license_text) + return license_text_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpModel::set_license_text(const ::std::string& value) { + + license_text_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.CpModel.license_text) +} +inline void CpModel::set_license_text(const char* value) { + + license_text_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.CpModel.license_text) +} +inline void CpModel::set_license_text(const char* value, size_t size) { + + license_text_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.CpModel.license_text) +} +inline ::std::string* CpModel::mutable_license_text() { + + // @@protoc_insertion_point(field_mutable:operations_research.CpModel.license_text) + return license_text_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CpModel::release_license_text() { + // @@protoc_insertion_point(field_release:operations_research.CpModel.license_text) + + return license_text_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CpModel::set_allocated_license_text(::std::string* license_text) { + if (license_text != NULL) { + + } else { + + } + license_text_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), license_text); + // @@protoc_insertion_point(field_set_allocated:operations_research.CpModel.license_text) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::operations_research::CpArgument_Type> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::CpArgument_Type>() { + return ::operations_research::CpArgument_Type_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fconstraint_5fsolver_2fmodel_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/constraint_solver/routing.h b/thirdparty/linux/include/ortools/constraint_solver/routing.h new file mode 100644 index 0000000..d1ce0be --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/routing.h @@ -0,0 +1,2216 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// The vehicle routing library lets one model and solve generic vehicle routing +// problems ranging from the Traveling Salesman Problem to more complex +// problems such as the Capacitated Vehicle Routing Problem with Time Windows. +// +// The objective of a vehicle routing problem is to build routes covering a set +// of nodes minimizing the overall cost of the routes (usually proportional to +// the sum of the lengths of each segment of the routes) while respecting some +// problem-specific constraints (such as the length of a route). A route is +// equivalent to a path connecting nodes, starting/ending at specific +// starting/ending nodes. +// +// The term "vehicle routing" is historical and the category of problems solved +// is not limited to the routing of vehicles: any problem involving finding +// routes visiting a given number of nodes optimally falls under this category +// of problems, such as finding the optimal sequence in a playlist. +// The literature around vehicle routing problems is extremely dense but one +// can find some basic introductions in the following links: +// - http://en.wikipedia.org/wiki/Travelling_salesman_problem +// - http://www.tsp.gatech.edu/history/index.html +// - http://en.wikipedia.org/wiki/Vehicle_routing_problem +// +// The vehicle routing library is a vertical layer above the constraint +// programming library (ortools/constraint_programming:cp). +// One has access to all underlying constrained variables of the vehicle +// routing model which can therefore be enriched by adding any constraint +// available in the constraint programming library. +// +// There are two sets of variables available: +// - path variables: +// * "next(i)" variables representing the immediate successor of the node +// corresponding to i; use IndexToNode() to get the node corresponding to +// a "next" variable value; note that node indices are strongly typed +// integers (cf. ortools/base/int_type.h); +// * "vehicle(i)" variables representing the vehicle route to which the +// node corresponding to i belongs; +// * "active(i)" boolean variables, true if the node corresponding to i is +// visited and false if not; this can be false when nodes are either +// optional or part of a disjunction; +// * The following relationships hold for all i: +// active(i) == 0 <=> next(i) == i <=> vehicle(i) == -1, +// next(i) == j => vehicle(j) == vehicle(i). +// - dimension variables, used when one is accumulating quantities along routes, +// such as weight or volume carried, distance or time: +// * "cumul(i,d)" variables representing the quantity of dimension d when +// arriving at the node corresponding to i; +// * "transit(i,d)" variables representing the quantity of dimension d added +// after visiting the node corresponding to i. +// * The following relationship holds for all (i,d): +// next(i) == j => cumul(j,d) == cumul(i,d) + transit(i,d). +// Solving the vehicle routing problems is mainly done using approximate methods +// (namely local search, +// cf. http://en.wikipedia.org/wiki/Local_search_(optimization) ), potentially +// combined with exact techniques based on dynamic programming and exhaustive +// tree search. +// TODO(user): Add a section on costs (vehicle arc costs, span costs, +// disjunctions costs). +// +// Advanced tips: Flags are available to tune the search used to solve routing +// problems. Here is a quick overview of the ones one might want to modify: +// - Limiting the search for solutions: +// * routing_solution_limit (default: kint64max): stop the search after +// finding 'routing_solution_limit' improving solutions; +// * routing_time_limit (default: kint64max): stop the search after +// 'routing_time_limit' milliseconds; +// - Customizing search: +// * routing_first_solution (default: select the first node with an unbound +// successor and connect it to the first available node): selects the +// heuristic to build a first solution which will then be improved by local +// search; possible values are GlobalCheapestArc (iteratively connect two +// nodes which produce the cheapest route segment), LocalCheapestArc (select +// the first node with an unbound successor and connect it to the node +// which produces the cheapest route segment), PathCheapestArc (starting +// from a route "start" node, connect it to the node which produces the +// cheapest route segment, then extend the route by iterating on the last +// node added to the route). +// * Local search neighborhoods: +// - routing_no_lns (default: false): forbids the use of Large Neighborhood +// Search (LNS); LNS can find good solutions but is usually very slow. +// Refer to the description of PATHLNS in the LocalSearchOperators enum +// in constraint_solver.h for more information. +// - routing_no_tsp (default: true): forbids the use of exact methods to +// solve "sub"-traveling salesman problems (TSPs) of the current model +// (such as sub-parts of a route, or one route in a multiple route +// problem). Uses dynamic programming to solve such TSPs with a maximum +// size (in number of nodes) up to cp_local_search_tsp_opt_size (flag with +// a default value of 13 nodes). It is not activated by default because it +// can slow down the search. +// * Meta-heuristics: used to guide the search out of local minima found by +// local search. Note that, in general, a search with metaheuristics +// activated never stops, therefore one must specify a search limit. +// Several types of metaheuristics are provided: +// - routing_guided_local_search (default: false): activates guided local +// search (cf. http://en.wikipedia.org/wiki/Guided_Local_Search); +// this is generally the most efficient metaheuristic for vehicle +// routing; +// - routing_simulated_annealing (default: false): activates simulated +// annealing (cf. http://en.wikipedia.org/wiki/Simulated_annealing); +// - routing_tabu_search (default: false): activates tabu search (cf. +// http://en.wikipedia.org/wiki/Tabu_search). +// +// Code sample: +// Here is a simple example solving a traveling salesman problem given a cost +// function callback (returns the cost of a route segment): +// +// - Define a custom distance/cost function from a node to another; in this +// example just returns the sum of the node indices (note the conversion from +// the strongly-typed indices to integers): +// +// int64 MyDistance(RoutingModel::NodeIndex from, +// RoutingModel::NodeIndex to) { +// return (from + to).value(); +// } +// +// - Create a routing model for a given problem size (int number of nodes) and +// number of routes (here, 1): +// +// RoutingModel routing(...number of nodes..., 1); +// +// - Set the cost function by passing a permanent callback to the distance +// accessor here. The callback has the following signature: +// ResultCallback2. +// +// routing.SetArcCostEvaluatorOfAllVehicles( +// NewPermanentCallback(MyDistance)); +// +// - Find a solution using Solve(), returns a solution if any (owned by +// routing): +// +// const Assignment* solution = routing.Solve(); +// CHECK(solution != nullptr); +// +// - Inspect the solution cost and route (only one route here): +// +// LOG(INFO) << "Cost " << solution->ObjectiveValue(); +// const int route_number = 0; +// for (int64 node = routing.Start(route_number); +// !routing.IsEnd(node); +// node = solution->Value(routing.NextVar(node))) { +// LOG(INFO) << routing.IndexToNode(node); +// } +// +// +// Keywords: Vehicle Routing, Traveling Salesman Problem, TSP, VRP, CVRPTW, PDP. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "ortools/base/callback.h" +#include "ortools/base/commandlineflags.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/int_type_indexed_vector.h" +#include "ortools/base/hash.h" +#include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/constraint_solveri.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" +#include "ortools/constraint_solver/routing_types.h" +#include "ortools/graph/graph.h" +#include "ortools/util/range_query_function.h" +#include "ortools/util/sorted_interval_list.h" +#include "ortools/base/adjustable_priority_queue-inl.h" +#include "ortools/base/adjustable_priority_queue.h" + + +namespace operations_research { + +class IntVarFilteredDecisionBuilder; +class LocalSearchOperator; +class RoutingDimension; +#ifndef SWIG +class SweepArranger; +#endif +struct SweepNode; + +class RoutingModel { + public: + // Status of the search. + enum Status { + // Problem not solved yet (before calling RoutingModel::Solve()). + ROUTING_NOT_SOLVED, + // Problem solved successfully after calling RoutingModel::Solve(). + ROUTING_SUCCESS, + // No solution found to the problem after calling RoutingModel::Solve(). + ROUTING_FAIL, + // Time limit reached before finding a solution with RoutingModel::Solve(). + ROUTING_FAIL_TIMEOUT, + // Model, model parameters or flags are not valid. + ROUTING_INVALID + }; + + typedef RoutingNodeIndex NodeIndex; + typedef RoutingCostClassIndex CostClassIndex; + typedef RoutingDimensionIndex DimensionIndex; + typedef RoutingDisjunctionIndex DisjunctionIndex; + typedef RoutingVehicleClassIndex VehicleClassIndex; + typedef RoutingNodeEvaluator2 NodeEvaluator2; + typedef RoutingTransitEvaluator2 TransitEvaluator2; + +// TODO(user): Remove all SWIG guards by adding the @ignore in .i. +#if !defined(SWIG) + typedef RoutingNodePair NodePair; + typedef RoutingNodePairs NodePairs; +#endif // SWIG + +#if !defined(SWIG) + // What follows is relevant for models with time/state dependent transits. + // Such transits, say from node A to node B, are functions f: int64->int64 + // of the cumuls of a dimension. The user is free to implement the abstract + // RangeIntToIntFunction interface, but it is expected that the implementation + // of each method is quite fast. For performance-related reasons, + // StateDependentTransit keeps an additional pointer to a + // RangeMinMaxIndexFunction, with similar functionality to + // RangeIntToIntFunction, for g(x) = f(x)+x, where f is the transit from A to + // B. In most situations the best solutions are problem-specific, but in case + // of doubt the user may use the MakeStateDependentTransit function from the + // routing library, which works out-of-the-box, with very good running time, + // but memory inefficient in some situations. + struct StateDependentTransit { + RangeIntToIntFunction* transit; // f(x) + RangeMinMaxIndexFunction* transit_plus_identity; // g(x) = f(x) + x + }; + typedef ResultCallback2 + VariableNodeEvaluator2; + typedef std::function + VariableIndexEvaluator2; +#endif // SWIG + +#if !defined(SWIG) + struct CostClass { + // arc_cost_evaluator->Run(from, to) is the transit cost of arc + // from->to. This may never be nullptr. + NodeEvaluator2* arc_cost_evaluator; + + // SUBTLE: + // The vehicle's fixed cost is skipped on purpose here, because we + // can afford to do so: + // - We don't really care about creating "strict" equivalence classes; + // all we care about is to: + // 1) compress the space of cost callbacks so that + // we can cache them more efficiently. + // 2) have a smaller IntVar domain thanks to using a "cost class var" + // instead of the vehicle var, so that we reduce the search space. + // Both of these are an incentive for *fewer* cost classes. Ignoring + // the fixed costs can only be good in that regard. + // - The fixed costs are only needed when evaluating the cost of the + // first arc of the route, in which case we know the vehicle, since we + // have the route's start node. + + // Only dimensions that have non-zero cost evaluator and a non-zero cost + // coefficient (in this cost class) are listed here. Since we only need + // their transit evaluator (the raw version that takes var index, not Node + // Index) and their span cost coefficient, we just store those. + // This is sorted by the natural operator < (and *not* by DimensionIndex). + struct DimensionCost { + int64 transit_evaluator_class; + int64 cost_coefficient; + const RoutingDimension* dimension; + bool operator<(const DimensionCost& cost) const { + if (transit_evaluator_class != cost.transit_evaluator_class) { + return transit_evaluator_class < cost.transit_evaluator_class; + } + return cost_coefficient < cost.cost_coefficient; + } + }; + std::vector + dimension_transit_evaluator_class_and_cost_coefficient; + + explicit CostClass(NodeEvaluator2* arc_cost_evaluator) + : arc_cost_evaluator(arc_cost_evaluator) { + CHECK(arc_cost_evaluator != nullptr); + } + + // Comparator for STL containers and algorithms. + static bool LessThan(const CostClass& a, const CostClass& b) { + if (a.arc_cost_evaluator != b.arc_cost_evaluator) { + return a.arc_cost_evaluator < b.arc_cost_evaluator; + } + return a.dimension_transit_evaluator_class_and_cost_coefficient < + b.dimension_transit_evaluator_class_and_cost_coefficient; + } + }; + + struct VehicleClass { + // The cost class of the vehicle. + CostClassIndex cost_class_index; + // Contrarily to CostClass, here we need strict equivalence. + int64 fixed_cost; + // Vehicle start and end nodes. Currently if two vehicles have different + // start/end nodes which are "physically" located at the same place, these + // two vehicles will be considered as non-equivalent. + // TODO(user): Find equivalent start/end nodes wrt dimensions and + // callbacks. + RoutingModel::NodeIndex start; + RoutingModel::NodeIndex end; + // Bounds of cumul variables at start and end vehicle nodes. + // dimension_{start,end}_cumuls_{min,max}[d] is the bound for dimension d. + ITIVector dimension_start_cumuls_min; + ITIVector dimension_start_cumuls_max; + ITIVector dimension_end_cumuls_min; + ITIVector dimension_end_cumuls_max; + ITIVector dimension_capacities; + // dimension_evaluators[d]->Run(from, to) is the transit value of arc + // from->to for a dimension d. + ITIVector dimension_evaluator_classes; + // Fingerprint of unvisitable non-start/end nodes. + uint64 unvisitable_nodes_fprint; + + // Comparator for STL containers and algorithms. + static bool LessThan(const VehicleClass& a, const VehicleClass& b); + }; +#endif // defined(SWIG) + + // Constants with an index of the first node (to be used in for loops for + // iteration), and a special index to signalize an invalid/unused value. + static const NodeIndex kFirstNode; + static const NodeIndex kInvalidNodeIndex; + + // Constant used to express the "no disjunction" index, returned when a node + // does not appear in any disjunction. + static const DisjunctionIndex kNoDisjunction; + + // Constant used to express the "no dimension" index, returned when a + // dimension name does not correspond to an actual dimension. + static const DimensionIndex kNoDimension; + + // In the following constructors, the versions which do not take + // RoutingModelParameters are equivalent to passing DefaultModelParameters. + // A depot is the start and end node of the route of a vehicle. + // Constructor taking a single depot node which is used as the start and + // end node for all vehicles. + RoutingModel(int nodes, int vehicles, NodeIndex depot); + RoutingModel(int nodes, int vehicles, NodeIndex depot, + const RoutingModelParameters& parameters); + // Constructor taking a vector of (start node, end node) pairs for each + // vehicle route. Used to model multiple depots. + RoutingModel(int nodes, int vehicles, + const std::vector >& start_end); + RoutingModel(int nodes, int vehicles, + const std::vector >& start_end, + const RoutingModelParameters& parameters); + // Constructor taking vectors of start nodes and end nodes for each + // vehicle route. Used to model multiple depots. + // TODO(user): added to simplify SWIG wrapping. Remove when swigging + // std::vector > is ok. + RoutingModel(int nodes, int vehicles, const std::vector& starts, + const std::vector& ends); + RoutingModel(int nodes, int vehicles, const std::vector& starts, + const std::vector& ends, + const RoutingModelParameters& parameters); + ~RoutingModel(); + + static RoutingModelParameters DefaultModelParameters(); + static RoutingSearchParameters DefaultSearchParameters(); + + // Model creation + + // Methods to add dimensions to routes; dimensions represent quantities + // accumulated at nodes along the routes. They represent quantities such as + // weights or volumes carried along the route, or distance or times. + // Quantities at a node are represented by "cumul" variables and the increase + // or decrease of quantities between nodes are represented by "transit" + // variables. These variables are linked as follows: + // if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i) + // where slack is a positive slack variable (can represent waiting times for + // a time dimension). + // Setting the value of fix_start_cumul_to_zero to true will force the "cumul" + // variable of the start node of all vehicles to be equal to 0. + + // Creates a dimension where the transit variable is constrained to be + // equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the + // slack variable and 'capacity' is the upper bound of the cumul variables. + // 'name' is the name used to reference the dimension; this name is used to + // get cumul and transit variables from the routing model. + // Returns false if a dimension with the same name has already been created + // (and doesn't create the new dimension). + // Takes ownership of the callback 'evaluator'. + bool AddDimension(NodeEvaluator2* evaluator, int64 slack_max, int64 capacity, + bool fix_start_cumul_to_zero, const std::string& name); + bool AddDimensionWithVehicleTransits( + const std::vector& evaluators, int64 slack_max, + int64 capacity, bool fix_start_cumul_to_zero, const std::string& name); + // Takes ownership of both 'evaluator' and 'vehicle_capacity' callbacks. + bool AddDimensionWithVehicleCapacity(NodeEvaluator2* evaluator, + int64 slack_max, + std::vector vehicle_capacities, + bool fix_start_cumul_to_zero, + const std::string& name); + bool AddDimensionWithVehicleTransitAndCapacity( + const std::vector& evaluators, int64 slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::string& name); + // Creates a dimension where the transit variable is constrained to be + // equal to 'value'; 'capacity' is the upper bound of the cumul variables. + // 'name' is the name used to reference the dimension; this name is used to + // get cumul and transit variables from the routing model. + // Returns false if a dimension with the same name has already been created + // (and doesn't create the new dimension). + bool AddConstantDimensionWithSlack(int64 value, int64 capacity, + int64 slack_max, + bool fix_start_cumul_to_zero, + const std::string& name); + bool AddConstantDimension(int64 value, int64 capacity, + bool fix_start_cumul_to_zero, const std::string& name) { + return AddConstantDimensionWithSlack(value, capacity, 0, + fix_start_cumul_to_zero, name); + } + // Creates a dimension where the transit variable is constrained to be + // equal to 'values[i]' for node i; 'capacity' is the upper bound of + // the cumul variables. 'name' is the name used to reference the dimension; + // this name is used to get cumul and transit variables from the routing + // model. + // Returns false if a dimension with the same name has already been created + // (and doesn't create the new dimension). + bool AddVectorDimension(std::vector values, int64 capacity, + bool fix_start_cumul_to_zero, const std::string& name); + // Creates a dimension where the transit variable is constrained to be + // equal to 'values[i][next(i)]' for node i; 'capacity' is the upper bound of + // the cumul variables. 'name' is the name used to reference the dimension; + // this name is used to get cumul and transit variables from the routing + // model. + // Returns false if a dimension with the same name has already been created + // (and doesn't create the new dimension). + bool AddMatrixDimension(std::vector > values, + int64 capacity, bool fix_start_cumul_to_zero, + const std::string& name); +#if !defined(SWIG) + // Creates a dimension with transits depending on the cumuls of another + // dimension. 'pure_transits' are the per-vehicle fixed transits as above. + // 'dependent_transits' is a vector containing for each vehicle a function + // taking two nodes and returning a function taking a dimension cumul value + // and returning a transit value. 'base_dimension' indicates the dimension + // from which the cumul variable is taken. If 'base_dimension' is nullptr, + // then the newly created dimension is self-based. + bool AddDimensionDependentDimensionWithVehicleCapacity( + const std::vector& pure_transits, + const std::vector& dependent_transits, + const RoutingDimension* base_dimension, int64 slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::string& name) { + return AddDimensionDependentDimensionWithVehicleCapacityInternal( + pure_transits, dependent_transits, base_dimension, slack_max, + std::move(vehicle_capacities), fix_start_cumul_to_zero, name); + } + // As above, but pure_transits are taken to be zero evaluators. + bool AddDimensionDependentDimensionWithVehicleCapacity( + const std::vector& transits, + const RoutingDimension* base_dimension, int64 slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::string& name); + // Homogeneous versions of the functions above. + bool AddDimensionDependentDimensionWithVehicleCapacity( + VariableNodeEvaluator2* transits, const RoutingDimension* base_dimension, + int64 slack_max, int64 vehicle_capacity, bool fix_start_cumul_to_zero, + const std::string& name); + bool AddDimensionDependentDimensionWithVehicleCapacity( + NodeEvaluator2* pure_transits, VariableNodeEvaluator2* dependent_transits, + const RoutingDimension* base_dimension, int64 slack_max, + int64 vehicle_capacity, bool fix_start_cumul_to_zero, const std::string& name); + // Creates a cached StateDependentTransit from an std::function. + static RoutingModel::StateDependentTransit MakeStateDependentTransit( + const std::function& f, int64 domain_start, + int64 domain_end); +#endif // SWIG + // Outputs the names of all dimensions added to the routing engine. + // TODO(user): rename. + std::vector<::std::string> GetAllDimensionNames() const; + // Returns true if a dimension exists for a given dimension name. + bool HasDimension(const std::string& dimension_name) const; + // Returns a dimension from its name. Dies if the dimension does not exist. + const RoutingDimension& GetDimensionOrDie(const std::string& dimension_name) const; + // Returns a dimension from its name. Returns nullptr if the dimension does + // not exist. + RoutingDimension* GetMutableDimension(const std::string& dimension_name) const; + // Set the given dimension as "primary constrained". As of August 2013, this + // is only used by ArcIsMoreConstrainedThanArc(). + // "dimension" must be the name of an existing dimension, or be empty, in + // which case there will not be a primary dimension after this call. + void SetPrimaryConstrainedDimension(const std::string& dimension_name) { + DCHECK(dimension_name.empty() || HasDimension(dimension_name)); + primary_constrained_dimension_ = dimension_name; + } + // Get the primary constrained dimension, or an empty std::string if it is unset. + const std::string& GetPrimaryConstrainedDimension() const { + return primary_constrained_dimension_; + } + // Constrains all nodes to be active (to belong to a route). + void AddAllActive(); + // Adds a disjunction constraint on the nodes: exactly one of the nodes is + // active. Start and end nodes of any vehicle cannot be part of a disjunction. + void AddDisjunction(const std::vector& nodes); + // Adds a penalized disjunction constraint on the nodes: at most one of the + // nodes is active; if none are active a penalty cost is applied (this cost + // is added to the global cost function). + // This is equivalent to adding the constraint: + // p + Sum(i)active[i] == 1, where p is a boolean variable + // and the following cost to the cost function: + // p * penalty. + // "penalty" must be positive to make the disjunction optional; a negative + // penalty will force one node of the disjunction to be performed, and + // therefore p == 0. + // Note: passing a vector with a single node will model an optional node + // with a penalty cost if it is not visited. + void AddDisjunction(const std::vector& nodes, int64 penalty); + // Same as above except that instead of allowing at most one of the nodes to + // be active, the maximum number of active nodes is max_cardinality. + void AddDisjunction(const std::vector& nodes, int64 penalty, + int64 max_cardinality); + // Returns the indices of the disjunctions to which a node belongs. + const std::vector& GetDisjunctionIndicesFromNode( + NodeIndex node) const { + return GetDisjunctionIndicesFromVariableIndex(NodeToIndex(node)); + } + const std::vector& GetDisjunctionIndicesFromVariableIndex( + int64 index) const { + return node_to_disjunctions_[index]; + } + // Calls f for each variable index of nodes in the same disjunctions as the + // node corresponding to the variable index 'index'; only disjunctions of + // cardinality 'cardinality' are considered. + template + void ForEachNodeInDisjunctionWithMaxCardinalityFromIndex( + int64 index, int64 max_cardinality, F f) const { + for (const DisjunctionIndex disjunction : + GetDisjunctionIndicesFromVariableIndex(index)) { + if (disjunctions_[disjunction].value.max_cardinality == max_cardinality) { + for (const int node : disjunctions_[disjunction].nodes) { + f(node); + } + } + } + } +#if !defined(SWIGPYTHON) + // Returns the variable indices of the nodes in the disjunction of index + // 'index'. + const std::vector& GetDisjunctionIndices(DisjunctionIndex index) const { + return disjunctions_[index].nodes; + } +#endif // !defined(SWIGPYTHON) + // Returns the penalty of the node disjunction of index 'index'. + int64 GetDisjunctionPenalty(DisjunctionIndex index) const { + return disjunctions_[index].value.penalty; + } + // Returns the maximum number of possible active nodes of the node disjunction + // of index 'index'. + int64 GetDisjunctionMaxCardinality(DisjunctionIndex index) const { + return disjunctions_[index].value.max_cardinality; + } + // Returns the number of node disjunctions in the model. + int GetNumberOfDisjunctions() const { return disjunctions_.size(); } + // Returns the list of all perfect binary disjunctions, as pairs of variable + // indices: a disjunction is "perfect" when its variables do not appear in + // any other disjunction. Each pair is sorted (lowest variable index first), + // and the output vector is also sorted (lowest pairs first). + std::vector > GetPerfectBinaryDisjunctions() const; + // SPECIAL: Makes the solver ignore all the disjunctions whose active + // variables are all trivially zero (i.e. Max() == 0), by setting their + // max_cardinality to 0. + // This can be useful when using the BaseBinaryDisjunctionNeighborhood + // operators, in the context of arc-based routing. + void IgnoreDisjunctionsAlreadyForcedToZero(); + + // Adds a soft contraint to force a set of nodes to be on the same vehicle. + // If all nodes are not on the same vehicle, each extra vehicle used adds + // 'cost' to the cost function. + void AddSoftSameVehicleConstraint(const std::vector& nodes, + int64 cost); + + // Notifies that node1 and node2 form a pair of nodes which should belong + // to the same route. This methods helps the search find better solutions, + // especially in the local search phase. + // It should be called each time you have an equality constraint linking + // the vehicle variables of two node (including for instance pickup and + // delivery problems): + // Solver* const solver = routing.solver(); + // solver->AddConstraint(solver->MakeEquality( + // routing.VehicleVar(routing.NodeToIndex(node1)), + // routing.VehicleVar(routing.NodeToIndex(node2)))); + // solver->AddPickupAndDelivery(node1, node2); + // + // TODO(user): Remove this when model introspection detects linked nodes. + void AddPickupAndDelivery(NodeIndex node1, NodeIndex node2) { + pickup_delivery_pairs_.push_back( + {{NodeToIndex(node1)}, {NodeToIndex(node2)}}); + } +#ifndef SWIG + // Returns pickup and delivery pairs currently in the model. + const NodePairs& GetPickupAndDeliveryPairs() const { + return pickup_delivery_pairs_; + } +#endif + // Get the "unperformed" penalty of a node. This is only well defined if the + // node is only part of a single Disjunction involving only itself, and that + // disjunction has a penalty. In all other cases, including forced active + // nodes, this returns 0. + int64 UnperformedPenalty(int64 var_index) const; + // Same as above except that it returns default_value instead of 0 when + // penalty is not well defined (default value is passed as first argument to + // simplify the usage of the method in a callback). + int64 UnperformedPenaltyOrValue(int64 default_value, int64 var_index) const; + // Returns the variable index of the first starting or ending node of all + // routes. If all routes start and end at the same node (single depot), this + // is the node returned. + int64 GetDepot() const; + + // Sets the cost function of the model such that the cost of a segment of a + // route between node 'from' and 'to' is evaluator(from, to), whatever the + // route or vehicle performing the route. + // Takes ownership of the callback 'evaluator'. + void SetArcCostEvaluatorOfAllVehicles(NodeEvaluator2* evaluator); + // Sets the cost function for a given vehicle route. + // Takes ownership of the callback 'evaluator'. + void SetArcCostEvaluatorOfVehicle(NodeEvaluator2* evaluator, int vehicle); + // Sets the fixed cost of all vehicle routes. It is equivalent to calling + // SetFixedCostOfVehicle on all vehicle routes. + void SetFixedCostOfAllVehicles(int64 cost); + // Sets the fixed cost of one vehicle route. + void SetFixedCostOfVehicle(int64 cost, int vehicle); + // Returns the route fixed cost taken into account if the route of the + // vehicle is not empty, aka there's at least one node on the route other than + // the first and last nodes. + int64 GetFixedCostOfVehicle(int vehicle) const; + +// Search +// Gets/sets the evaluator used when the first solution heuristic is set to +// ROUTING_EVALUATOR_STRATEGY (variant of ROUTING_PATH_CHEAPEST_ARC using +// 'evaluator' to sort node segments). +#ifndef SWIG + const Solver::IndexEvaluator2& first_solution_evaluator() const { + return first_solution_evaluator_; + } +#endif + // Takes ownership of evaluator. + void SetFirstSolutionEvaluator(Solver::IndexEvaluator2 evaluator) { + first_solution_evaluator_ = std::move(evaluator); + } + // Adds a local search operator to the set of operators used to solve the + // vehicle routing problem. + void AddLocalSearchOperator(LocalSearchOperator* ls_operator); + // Adds a search monitor to the search used to solve the routing model. + void AddSearchMonitor(SearchMonitor* const monitor); + // Adds a callback called each time a solution is found during the search. + // This is a shortcut to creating a monitor to call the callback on + // AtSolution() and adding it with AddSearchMonitor. + void AddAtSolutionCallback(std::function callback); + // Adds a variable to minimize in the solution finalizer. The solution + // finalizer is called each time a solution is found during the search and + // allows to instantiate secondary variables (such as dimension cumul + // variables). + void AddVariableMinimizedByFinalizer(IntVar* var); + // Adds a variable to maximize in the solution finalizer (see above for + // information on the solution finalizer). + void AddVariableMaximizedByFinalizer(IntVar* var); + // Closes the current routing model; after this method is called, no + // modification to the model can be done, but RoutesToAssignment becomes + // available. Note that CloseModel() is automatically called by Solve() and + // other methods that produce solution. + // This is equivalent to calling + // CloseModelWithParameters(DefaultSearchParameters()). + void CloseModel(); + // Same as above taking search parameters (as of 10/2015 some the parameters + // have to be set when closing the model). + void CloseModelWithParameters( + const RoutingSearchParameters& search_parameters); + // Solves the current routing model; closes the current model. + // This is equivalent to calling + // SolveWithParameters(DefaultSearchParameters()) + // or + // SolveFromAssignmentWithParameters(assignment, DefaultSearchParameters()). + const Assignment* Solve(const Assignment* assignment = nullptr); + // Solves the current routing model with the given parameters. + const Assignment* SolveWithParameters( + const RoutingSearchParameters& search_parameters); + const Assignment* SolveFromAssignmentWithParameters( + const Assignment* assignment, + const RoutingSearchParameters& search_parameters); + // Computes a lower bound to the routing problem solving a linear assignment + // problem. The routing model must be closed before calling this method. + // Note that problems with node disjunction constraints (including optional + // nodes) and non-homogenous costs are not supported (the method returns 0 in + // these cases). + // TODO(user): Add support for non-homogeneous costs and disjunctions. + int64 ComputeLowerBound(); + // Returns the current status of the routing model. + Status status() const { return status_; } + // Applies a lock chain to the next search. 'locks' represents an ordered + // vector of nodes representing a partial route which will be fixed during the + // next search; it will constrain next variables such that: + // next[locks[i]] == locks[i+1]. + // Returns the next variable at the end of the locked chain; this variable is + // not locked. An assignment containing the locks can be obtained by calling + // PreAssignment(). + IntVar* ApplyLocks(const std::vector& locks); + // Applies lock chains to all vehicles to the next search, such that locks[p] + // is the lock chain for route p. Returns false if the locks do not contain + // valid routes; expects that the routes do not contain the depots, + // i.e. there are empty vectors in place of empty routes. + // If close_routes is set to true, adds the end nodes to the route of each + // vehicle and deactivates other nodes. + // An assignment containing the locks can be obtained by calling + // PreAssignment(). + bool ApplyLocksToAllVehicles( + const std::vector >& locks, bool close_routes); + // Returns an assignment used to fix some of the variables of the problem. + // In practice, this assignment locks partial routes of the problem. This + // can be used in the context of locking the parts of the routes which have + // already been driven in online routing problems. + const Assignment* const PreAssignment() const { return preassignment_; } + Assignment* MutablePreAssignment() { return preassignment_; } + // Writes the current solution to a file containing an AssignmentProto. + // Returns false if the file cannot be opened or if there is no current + // solution. + bool WriteAssignment(const std::string& file_name) const; + // Reads an assignment from a file and returns the current solution. + // Returns nullptr if the file cannot be opened or if the assignment is not + // valid. + Assignment* ReadAssignment(const std::string& file_name); + // Restores an assignment as a solution in the routing model and returns the + // new solution. Returns nullptr if the assignment is not valid. + Assignment* RestoreAssignment(const Assignment& solution); + // Restores the routes as the current solution. Returns nullptr if + // the solution cannot be restored (routes do not contain a valid + // solution). Note that calling this method will run the solver to + // assign values to the dimension variables; this may take + // considerable amount of time, especially when using dimensions + // with slack. + Assignment* ReadAssignmentFromRoutes( + const std::vector >& routes, + bool ignore_inactive_nodes); + // Fills an assignment from a specification of the routes of the + // vehicles. The routes are specified as lists of nodes that appear + // on the routes of the vehicles. The indices of the outer vector in + // 'routes' correspond to vehicles IDs, the inner vector contain the + // nodes on the routes for the given vehicle. The inner vectors must + // not contain the start and end nodes, as these are determined by + // the routing model. Sets the value of NextVars in the assignment, + // adding the variables to the assignment if necessary. The method + // does not touch other variables in the assignment. The method can + // only be called after the model is closed. With + // ignore_inactive_nodes set to false, this method will fail (return + // nullptr) in case some of the route contain nodes that are + // deactivated in the model; when set to true, these nodes will be + // skipped. Returns true if routes were successfully + // loaded. However, such assignment still might not be a valid + // solution to the routing problem due to more complex constraints; + // it is advisible to call solver()->CheckSolution() afterwards. + bool RoutesToAssignment(const std::vector >& routes, + bool ignore_inactive_nodes, bool close_routes, + Assignment* const assignment) const; + // Converts the solution in the given assignment to routes for all vehicles. + // Expects that assignment contains a valid solution (i.e. routes for all + // vehicles end with an end node for that vehicle). + void AssignmentToRoutes( + const Assignment& assignment, + std::vector >* const routes) const; + // Returns a compacted version of the given assignment, in which all vehicles + // with id lower or equal to some N have non-empty routes, and all vehicles + // with id greater than N have empty routes. Does not take ownership of the + // returned object. + // If found, the cost of the compact assignment is the same as in the + // original assignment and it preserves the values of 'active' variables. + // Returns nullptr if a compact assignment was not found. + // This method only works in homogenous mode, and it only swaps equivalent + // vehicles (vehicles with the same start and end nodes). When creating the + // compact assignment, the empty plan is replaced by the route assigned to the + // compatible vehicle with the highest id. Note that with more complex + // constraints on vehicle variables, this method might fail even if a compact + // solution exists. + // This method changes the vehicle and dimension variables as necessary. + // While compacting the solution, only basic checks on vehicle variables are + // performed; if one of these checks fails no attempts to repair it are made + // (instead, the method returns nullptr). + Assignment* CompactAssignment(const Assignment& assignment) const; + // Same as CompactAssignment() but also checks the validity of the final + // compact solution; if it is not valid, no attempts to repair it are made + // (instead, the method returns nullptr). + Assignment* CompactAndCheckAssignment(const Assignment& assignment) const; + // Adds an extra variable to the vehicle routing assignment. + void AddToAssignment(IntVar* const var); + void AddIntervalToAssignment(IntervalVar* const interval); +#ifndef SWIG + // TODO(user): Revisit if coordinates are added to the RoutingModel class. + void SetSweepArranger(SweepArranger* sweep_arranger) { + sweep_arranger_.reset(sweep_arranger); + } + // Returns the sweep arranger to be used by routing heuristics. + SweepArranger* sweep_arranger() const { return sweep_arranger_.get(); } +#endif + // Adds a custom local search filter to the list of filters used to speed up + // local search by pruning unfeasible variable assignments. + // Calling this method after the routing model has been closed (CloseModel() + // or Solve() has been called) has no effect. + // The routing model does not take ownership of the filter. + void AddLocalSearchFilter(LocalSearchFilter* filter) { + CHECK(filter != nullptr); + if (closed_) { + LOG(WARNING) << "Model is closed, filter addition will be ignored."; + } + extra_filters_.push_back(filter); + } + + // Model inspection. + // Returns the variable index of the starting node of a vehicle route. + int64 Start(int vehicle) const { return starts_[vehicle]; } + // Returns the variable index of the ending node of a vehicle route. + int64 End(int vehicle) const { return ends_[vehicle]; } + // Returns true if 'index' represents the first node of a route. + bool IsStart(int64 index) const; + // Returns true if 'index' represents the last node of a route. + bool IsEnd(int64 index) const { return index >= Size(); } + // Assignment inspection + // Returns the variable index of the node directly after the node + // corresponding to 'index' in 'assignment'. + int64 Next(const Assignment& assignment, int64 index) const; + // Returns true if the route of 'vehicle' is non empty in 'assignment'. + bool IsVehicleUsed(const Assignment& assignment, int vehicle) const; +// Variables +#if !defined(SWIGPYTHON) + // Returns all next variables of the model, such that Nexts(i) is the next + // variable of the node corresponding to i. + const std::vector& Nexts() const { return nexts_; } + // Returns all vehicle variables of the model, such that VehicleVars(i) is + // the vehicle variable of the node corresponding to i. + const std::vector& VehicleVars() const { return vehicle_vars_; } +#endif // !defined(SWIGPYTHON) + // Returns the next variable of the node corresponding to index. Note that + // NextVar(index) == index is equivalent to ActiveVar(index) == 0. + IntVar* NextVar(int64 index) const { return nexts_[index]; } + // Returns the active variable of the node corresponding to index. + IntVar* ActiveVar(int64 index) const { return active_[index]; } + // Returns the vehicle variable of the node corresponding to index. Note that + // VehicleVar(index) == -1 is equivalent to ActiveVar(index) == 0. + IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; } + // Returns the global cost variable which is being minimized. + IntVar* CostVar() const { return cost_; } + // Returns the cost of the transit arc between two nodes for a given vehicle. + // Input are variable indices of node. This returns 0 if vehicle < 0. + int64 GetArcCostForVehicle(int64 from_index, int64 to_index, int64 vehicle); + // Whether costs are homogeneous across all vehicles. + bool CostsAreHomogeneousAcrossVehicles() const { + return costs_are_homogeneous_across_vehicles_; + } + // Returns the cost of the segment between two nodes supposing all vehicle + // costs are the same (returns the cost for the first vehicle otherwise). + int64 GetHomogeneousCost(int64 from_index, int64 to_index) { + return GetArcCostForVehicle(from_index, to_index, /*vehicle=*/0); + } + // Returns the cost of the arc in the context of the first solution strategy. + // This is typically a simplification of the actual cost; see the .cc. + int64 GetArcCostForFirstSolution(int64 from_index, int64 to_index); + // Returns the cost of the segment between two nodes for a given cost + // class. Input are variable indices of nodes and the cost class. + // Unlike GetArcCostForVehicle(), if cost_class is kNoCost, then the + // returned cost won't necessarily be zero: only some of the components + // of the cost that depend on the cost class will be omited. See the code + // for details. + int64 GetArcCostForClass(int64 from_index, int64 to_index, + int64 /*CostClassIndex*/ cost_class_index); + // Get the cost class index of the given vehicle. + CostClassIndex GetCostClassIndexOfVehicle(int64 vehicle) const { + DCHECK(closed_); + return cost_class_index_of_vehicle_[vehicle]; + } + // Returns the number of different cost classes in the model. + int GetCostClassesCount() const { return cost_classes_.size(); } + // Ditto, minus the 'always zero', built-in cost class. + int GetNonZeroCostClassesCount() const { + return std::max(0, GetCostClassesCount() - 1); + } + VehicleClassIndex GetVehicleClassIndexOfVehicle(int64 vehicle) const { + DCHECK(closed_); + return vehicle_class_index_of_vehicle_[vehicle]; + } + // Returns the number of different vehicle classes in the model. + int GetVehicleClassesCount() const { return vehicle_classes_.size(); } + // Returns variable indices of nodes constrained to be on the same route. + const std::vector& GetSameVehicleIndicesOfIndex(int node) const { + DCHECK(closed_); + return same_vehicle_groups_[same_vehicle_group_[node]]; + } + // Returns whether the arc from->to1 is more constrained than from->to2, + // taking into account, in order: + // - whether the destination node isn't an end node + // - whether the destination node is mandatory + // - whether the destination node is bound to the same vehicle as the source + // - the "primary constrained" dimension (see SetPrimaryConstrainedDimension) + // It then breaks ties using, in order: + // - the arc cost (taking unperformed penalties into account) + // - the size of the vehicle vars of "to1" and "to2" (lowest size wins) + // - the value: the lowest value of the indices to1 and to2 wins. + // See the .cc for details. + // The more constrained arc is typically preferable when building a + // first solution. This method is intended to be used as a callback for the + // BestValueByComparisonSelector value selector. + // Args: + // from: the variable index of the source node + // to1: the variable index of the first candidate destination node. + // to2: the variable index of the second candidate destination node. + bool ArcIsMoreConstrainedThanArc(int64 from, int64 to1, int64 to2); + // Print some debugging information about an assignment, including the + // feasible intervals of the CumulVar for dimension "dimension_to_print" + // at each step of the routes. + // If "dimension_to_print" is omitted, all dimensions will be printed. + std::string DebugOutputAssignment(const Assignment& solution_assignment, + const std::string& dimension_to_print) const; + + // Returns the underlying constraint solver. Can be used to add extra + // constraints and/or modify search algoithms. + Solver* solver() const { return solver_.get(); } + + // Sizes and indices + // Returns the number of nodes in the model. + int nodes() const { return nodes_; } + // Returns the number of vehicle routes in the model. + int vehicles() const { return vehicles_; } + // Returns the number of next variables in the model. + int64 Size() const { return nodes_ + vehicles_ - start_end_count_; } + // Returns the node index from an index value resulting from a next variable. + NodeIndex IndexToNode(int64 index) const; + // Returns the variable index from a node value. + // Should not be used for nodes at the start / end of a route, + // because of node multiplicity. These cases return -1, which is + // considered a failure case. Clients who need start and end + // variable indices should use RoutingModel::Start and RoutingModel::End. + int64 NodeToIndex(NodeIndex node) const; + // Returns true if the node can be safely converted to variable index. All + // nodes that are not end of a route are safe. + bool HasIndex(NodeIndex node) const; + + // Returns statistics on first solution search, number of decisions sent to + // filters, number of decisions rejected by filters. + int64 GetNumberOfDecisionsInFirstSolution( + const RoutingSearchParameters& search_parameters) const; + int64 GetNumberOfRejectsInFirstSolution( + const RoutingSearchParameters& search_parameters) const; + + // Internal only: initializes the builders used to build a solver model from + // CpModels. + static void InitializeBuilders(Solver* solver); + + // DEPRECATED METHODS. + // Don't use these methods; instead use their proposed replacement (in + // comments). + // TODO(user): only keep those for the open-source export. + void SetCost(NodeEvaluator2* e); // SetArcCostEvaluatorOfAllVehicles() + // SetArcCostEvaluatorOfVehicle() + void SetVehicleCost(int v, NodeEvaluator2* e); + int64 GetRouteFixedCost() const; // GetFixedCostOfVehicle() + void SetRouteFixedCost(int64 c); // SetFixedCostOfAllVehicles() + int64 GetVehicleFixedCost(int v) const; // GetFixedCostOfVehicle() + void SetVehicleFixedCost(int v, int64 c); // SetFixedCostOfVehicle() + bool homogeneous_costs() const; // CostsAreHomogeneousAcrossVehicles() + int GetVehicleCostCount() const; // GetNonZeroCostClassesCount() + int64 GetCost(int64 i, int64 j, int64 v); // GetArcCostForVehicle() + int64 GetVehicleClassCost(int64 i, int64 j, int64 c); // GetArcCostForClass() + + // All the methods below are replaced by public methods of the + // RoutingDimension class. See that class. + void SetDimensionTransitCost(const std::string& d, int64 c); + int64 GetDimensionTransitCost(const std::string& d) const; + void SetDimensionSpanCost(const std::string& d, int64 c); + int64 GetDimensionSpanCost(const std::string& d) const; + int64 GetTransitValue(const std::string& d, int64 from, int64 to, + int64 vehicle) const; +#ifndef SWIG + const std::vector& CumulVars(const std::string& dimension_name) const; +#endif + // All the methods below are replaced by public methods with the same name + // on the RoutingDimension class. See those. + IntVar* CumulVar(int64 index, const std::string& dimension_name) const; + IntVar* TransitVar(int64 index, const std::string& dimension_name) const; + IntVar* SlackVar(int64 index, const std::string& dimension_name) const; + void SetCumulVarSoftUpperBound(NodeIndex, const std::string&, int64, int64); + bool HasCumulVarSoftUpperBound(NodeIndex, const std::string&) const; + int64 GetCumulVarSoftUpperBound(NodeIndex, const std::string&) const; + int64 GetCumulVarSoftUpperBoundCoefficient(NodeIndex, const std::string&) const; + void SetStartCumulVarSoftUpperBound(int, const std::string&, int64, int64); + bool HasStartCumulVarSoftUpperBound(int, const std::string&) const; + int64 GetStartCumulVarSoftUpperBound(int, const std::string&) const; + int64 GetStartCumulVarSoftUpperBoundCoefficient(int, const std::string&) const; + void SetEndCumulVarSoftUpperBound(int, const std::string&, int64, int64); + bool HasEndCumulVarSoftUpperBound(int, const std::string&) const; + int64 GetEndCumulVarSoftUpperBound(int, const std::string&) const; + int64 GetEndCumulVarSoftUpperBoundCoefficient(int, const std::string&) const; + + // The next few members are in the public section only for testing purposes. + // TODO(user): Find a way to test and restrict the access at the same time. + // + // MakeGuidedSlackFinalizer creates a DecisionBuilder for the slacks of a + // dimension using a callback to choose which values to start with. + // The finalizer works only when all next variables in the model have + // been fixed. It has the following two characteristics: + // 1. It follows the routes defined by the nexts variables when choosing a + // variable to make a decision on. + // 2. When it comes to choose a value for the slack of node i, the decision + // builder first calls the callback with argument i, and supposingly the + // returned value is x it creates decisions slack[i] = x, slack[i] = x + 1, + // slack[i] = x - 1, slack[i] = x + 2, etc. + DecisionBuilder* MakeGuidedSlackFinalizer( + const RoutingDimension* dimension, + std::function initializer); +#ifndef SWIG + // TODO(user): MakeGreedyDescentLSOperator is too general for routing.h. + // Perhaps move it to constraint_solver.h. + // MakeGreedyDescentLSOperator creates a local search operator that tries to + // improve the initial assignment by moving a logarithmically decreasing step + // away in each possible dimension. + static std::unique_ptr MakeGreedyDescentLSOperator( + std::vector variables); +#endif // __SWIG__ + // MakeSelfDependentDimensionFinalizer is a finalizer for the slacks of a + // self-dependent dimension. It makes an extensive use of the caches of the + // state dependent transits. + // In detail, MakeSelfDependentDimensionFinalizer returns a composition of a + // local search decision builder with a greedy descent operator for the cumul + // of the start of each route and a guided slack finalizer. Provided there are + // no time windows and the maximum slacks are large enough, once the cumul of + // the start of route is fixed, the guided finalizer can find optimal values + // of the slacks for the rest of the route in time proportional to the length + // of the route. Therefore the composed finalizer generally works in time + // O(log(t)*n*m), where t is the latest possible departute time, n is the + // number of nodes in the network and m is the number of vehicles. + DecisionBuilder* MakeSelfDependentDimensionFinalizer( + const RoutingDimension* dimension); + + private: + // Local search move operator usable in routing. + enum RoutingLocalSearchOperator { + RELOCATE = 0, + RELOCATE_PAIR, + RELOCATE_NEIGHBORS, + EXCHANGE, + CROSS, + CROSS_EXCHANGE, + TWO_OPT, + OR_OPT, + LIN_KERNIGHAN, + TSP_OPT, + MAKE_ACTIVE, + RELOCATE_AND_MAKE_ACTIVE, + MAKE_ACTIVE_AND_RELOCATE, + MAKE_INACTIVE, + MAKE_CHAIN_INACTIVE, + SWAP_ACTIVE, + EXTENDED_SWAP_ACTIVE, + NODE_PAIR_SWAP, + PATH_LNS, + FULL_PATH_LNS, + TSP_LNS, + INACTIVE_LNS, + LOCAL_SEARCH_OPERATOR_COUNTER + }; + + // Structure storing a value for a set of nodes. Is used to store data for + // node disjunctions (nodes, max_cardinality and penalty when unperformed). + template + struct ValuedNodes { + std::vector nodes; + T value; + }; + struct DisjunctionValues { + int64 penalty; + int64 max_cardinality; + }; + typedef ValuedNodes Disjunction; + + // Storage of a cost cache element corresponding to a cost arc ending at + // node 'index' and on the cost class 'cost_class'. + struct CostCacheElement { + // This is usually an int64, but using an int here decreases the RAM usage, + // and should be fine since in practice we never have more than 1<<31 vars. + // Note(user): on 2013-11, microbenchmarks on the arc costs callbacks + // also showed a 2% speed-up thanks to using int rather than int64. + int index; + CostClassIndex cost_class_index; + int64 cost; + }; + + // Internal methods. + void Initialize(); + void SetStartEnd( + const std::vector >& start_end); + void AddDisjunctionInternal(const std::vector& nodes, + int64 penalty, int64 max_cardinality); + void AddNoCycleConstraintInternal(); + bool AddDimensionWithCapacityInternal( + const std::vector& evaluators, int64 slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::string& dimension_name); + bool AddDimensionDependentDimensionWithVehicleCapacityInternal( + const std::vector& pure_transits, + const std::vector& dependent_transits, + const RoutingDimension* base_dimension, int64 slack_max, + std::vector vehicle_capacities, bool fix_start_cumul_to_zero, + const std::string& name); + bool InitializeDimensionInternal( + const std::vector& evaluators, + const std::vector& state_dependent_evaluators, + int64 slack_max, bool fix_start_cumul_to_zero, + RoutingDimension* dimension); + DimensionIndex GetDimensionIndex(const std::string& dimension_name) const; + uint64 GetFingerprintOfEvaluator(NodeEvaluator2* evaluator, + bool fingerprint_arc_cost_evaluators) const; + void ComputeCostClasses(const RoutingSearchParameters& parameters); + void ComputeVehicleClasses(); + int64 GetArcCostForClassInternal(int64 from_index, int64 to_index, + CostClassIndex cost_class_index); + void AppendHomogeneousArcCosts(const RoutingSearchParameters& parameters, + int node_index, + std::vector* cost_elements); + void AppendArcCosts(const RoutingSearchParameters& parameters, int node_index, + std::vector* cost_elements); + Assignment* DoRestoreAssignment(); + static const CostClassIndex kCostClassIndexOfZeroCost; + int64 SafeGetCostClassInt64OfVehicle(int64 vehicle) const { + DCHECK_LT(0, vehicles_); + return (vehicle >= 0 ? GetCostClassIndexOfVehicle(vehicle) + : kCostClassIndexOfZeroCost) + .value(); + } + int64 GetDimensionTransitCostSum(int64 i, int64 j, + const CostClass& cost_class) const; + // Returns nullptr if no penalty cost, otherwise returns penalty variable. + IntVar* CreateDisjunction(DisjunctionIndex disjunction); + // Returns the cost variable related to the soft same vehicle constraint of + // index 'index'. + IntVar* CreateSameVehicleCost(int index); + // Returns the first active node in nodes starting from index + 1. + int FindNextActive(int index, const std::vector& nodes) const; + + // Checks that all nodes on the route starting at start_index (using the + // solution stored in assignment) can be visited by the given vehicle. + bool RouteCanBeUsedByVehicle(const Assignment& assignment, int start_index, + int vehicle) const; + // Replaces the route of unused_vehicle with the route of active_vehicle in + // compact_assignment. Expects that unused_vehicle is a vehicle with an empty + // route and that the route of active_vehicle is non-empty. Also expects that + // 'assignment' contains the original assignment, from which + // compact_assignment was created. + // Returns true if the vehicles were successfully swapped; otherwise, returns + // false. + bool ReplaceUnusedVehicle(int unused_vehicle, int active_vehicle, + Assignment* compact_assignment) const; + + NodeEvaluator2* NewCachedCallback(NodeEvaluator2* callback); + VariableNodeEvaluator2* NewCachedStateDependentCallback( + VariableNodeEvaluator2* callback); + void QuietCloseModel(); + void QuietCloseModelWithParameters( + const RoutingSearchParameters& parameters) { + if (!closed_) { + CloseModelWithParameters(parameters); + } + } + // See CompactAssignment. Checks the final solution if + // check_compact_assignement is true. + Assignment* CompactAssignmentInternal(const Assignment& assignment, + bool check_compact_assignment) const; + // Check that current search parameters are valid. If not, the status of the + // solver is set to ROUTING_INVALID. + bool ValidateSearchParameters( + const RoutingSearchParameters& search_parameters); + // Sets up search objects, such as decision builders and monitors. + void SetupSearch(const RoutingSearchParameters& search_parameters); + // Set of auxiliary methods used to setup the search. + // TODO(user): Document each auxiliary method. + Assignment* GetOrCreateAssignment(); + SearchLimit* GetOrCreateLimit(); + SearchLimit* GetOrCreateLocalSearchLimit(); + SearchLimit* GetOrCreateLargeNeighborhoodSearchLimit(); + LocalSearchOperator* CreateInsertionOperator(); + LocalSearchOperator* CreateMakeInactiveOperator(); + void CreateNeighborhoodOperators(); + LocalSearchOperator* GetNeighborhoodOperators( + const RoutingSearchParameters& search_parameters) const; + const std::vector& GetOrCreateLocalSearchFilters(); + const std::vector& GetOrCreateFeasibilityFilters(); + DecisionBuilder* CreateSolutionFinalizer(); + void CreateFirstSolutionDecisionBuilders( + const RoutingSearchParameters& search_parameters); + DecisionBuilder* GetFirstSolutionDecisionBuilder( + const RoutingSearchParameters& search_parameters) const; + IntVarFilteredDecisionBuilder* GetFilteredFirstSolutionDecisionBuilderOrNull( + const RoutingSearchParameters& parameters) const; + LocalSearchPhaseParameters* CreateLocalSearchParameters( + const RoutingSearchParameters& search_parameters); + DecisionBuilder* CreateLocalSearchDecisionBuilder( + const RoutingSearchParameters& search_parameters); + void SetupDecisionBuilders(const RoutingSearchParameters& search_parameters); + void SetupMetaheuristics(const RoutingSearchParameters& search_parameters); + void SetupAssignmentCollector(); + void SetupTrace(const RoutingSearchParameters& search_parameters); + void SetupSearchMonitors(const RoutingSearchParameters& search_parameters); + bool UsesLightPropagation( + const RoutingSearchParameters& search_parameters) const; + + int64 GetArcCostForCostClassInternal(int64 i, int64 j, int64 cost_class); + int GetVehicleStartClass(int64 start) const; + + void InitSameVehicleGroups(int number_of_groups) { + same_vehicle_group_.assign(Size(), 0); + same_vehicle_groups_.assign(number_of_groups, {}); + } + void SetSameVehicleGroup(int index, int group) { + same_vehicle_group_[index] = group; + same_vehicle_groups_[group].push_back(index); + } + + // Model + std::unique_ptr solver_; + int nodes_; + int vehicles_; + Constraint* no_cycle_constraint_; + // Decision variables: indexed by int64 var index. + std::vector nexts_; + std::vector vehicle_vars_; + std::vector active_; + // is_bound_to_end_[i] will be true iff the path starting at var #i is fully + // bound and reaches the end of a route, i.e. either: + // - IsEnd(i) is true + // - or nexts_[i] is bound and is_bound_to_end_[nexts_[i].Value()] is true. + std::vector is_bound_to_end_; + RevSwitch is_bound_to_end_ct_added_; + // Dimensions + std::unordered_map dimension_name_to_index_; + ITIVector dimensions_; + std::string primary_constrained_dimension_; + // Costs + IntVar* cost_; + std::vector transit_cost_of_vehicle_; + std::vector fixed_cost_of_vehicle_; + std::vector cost_class_index_of_vehicle_; +#ifndef SWIG + ITIVector cost_classes_; +#endif // SWIG + bool costs_are_homogeneous_across_vehicles_; + bool cache_callbacks_; + std::vector cost_cache_; // Index by source index. + std::vector vehicle_class_index_of_vehicle_; +#ifndef SWIG + ITIVector vehicle_classes_; +#endif // SWIG + std::function vehicle_start_class_callback_; + // Cached callbacks + std::unordered_map + cached_node_callbacks_; + std::unordered_map + cached_state_dependent_callbacks_; + // Disjunctions + ITIVector disjunctions_; + std::vector > node_to_disjunctions_; + // Same vehicle costs + std::vector > same_vehicle_costs_; + // Pickup and delivery + NodePairs pickup_delivery_pairs_; + // Same vehicle group to which a node belongs. + std::vector same_vehicle_group_; + // Same vehicle node groups. + std::vector > same_vehicle_groups_; + // Index management + std::vector index_to_node_; + ITIVector node_to_index_; + std::vector index_to_vehicle_; + std::vector starts_; + std::vector ends_; + int start_end_count_; + // Model status + bool closed_; + Status status_; + + // Search data + std::vector first_solution_decision_builders_; + std::vector + first_solution_filtered_decision_builders_; + Solver::IndexEvaluator2 first_solution_evaluator_; + std::vector local_search_operators_; + std::vector monitors_; + SolutionCollector* collect_assignments_; + DecisionBuilder* solve_db_; + DecisionBuilder* improve_db_; + DecisionBuilder* restore_assignment_; + Assignment* assignment_; + Assignment* preassignment_; + std::vector extra_vars_; + std::vector extra_intervals_; + std::vector extra_operators_; + std::vector filters_; + std::vector feasibility_filters_; + std::vector extra_filters_; + std::vector variables_maximized_by_finalizer_; + std::vector variables_minimized_by_finalizer_; +#ifndef SWIG + std::unique_ptr sweep_arranger_; +#endif + + SearchLimit* limit_; + SearchLimit* ls_limit_; + SearchLimit* lns_limit_; + + // Callbacks to be deleted + std::unordered_set owned_node_callbacks_; + std::unordered_set + owned_state_dependent_callbacks_; + + friend class RoutingDimension; + friend class RoutingModelInspector; + + DISALLOW_COPY_AND_ASSIGN(RoutingModel); +}; + +// Routing model visitor. +class RoutingModelVisitor : public BaseObject { + public: + // Constraint types. + static const char kLightElement[]; + static const char kLightElement2[]; +}; + +// Dimensions represent quantities accumulated at nodes along the routes. They +// represent quantities such as weights or volumes carried along the route, or +// distance or times. +// +// Quantities at a node are represented by "cumul" variables and the increase +// or decrease of quantities between nodes are represented by "transit" +// variables. These variables are linked as follows: +// +// if j == next(i), +// cumuls(j) = cumuls(i) + transits(i) + slacks(i) + state_dependent_transits(i) +// +// where slack is a positive slack variable (can represent waiting times for +// a time dimension), and state_dependent_transits is a non-purely functional +// version of transits_. Favour transits over state_dependent_transits when +// possible, because purely functional callbacks allow more optimisations and +// make the model faster and easier to solve. +class RoutingDimension { + public: + ~RoutingDimension(); + // Returns the model on which the dimension was created. + RoutingModel* model() const { return model_; } + // Returns the transition value for a given pair of nodes (as var index); + // this value is the one taken by the corresponding transit variable when + // the 'next' variable for 'from_index' is bound to 'to_index'. + int64 GetTransitValue(int64 from_index, int64 to_index, int64 vehicle) const; + // Same as above but taking a vehicle class of the dimension instead of a + // vehicle (the class of a vehicle can be obtained with vehicle_to_class()). + int64 GetTransitValueFromClass(int64 from_index, int64 to_index, + int64 vehicle_class) const { + return class_evaluators_[vehicle_class](from_index, to_index); + } + // Get the cumul, transit and slack variables for the given node (given as + // int64 var index). + IntVar* CumulVar(int64 index) const { return cumuls_[index]; } + IntVar* TransitVar(int64 index) const { return transits_[index]; } + IntVar* FixedTransitVar(int64 index) const { return fixed_transits_[index]; } + IntVar* SlackVar(int64 index) const { return slacks_[index]; } +#if !defined(SWIGPYTHON) + // Like CumulVar(), TransitVar(), SlackVar() but return the whole variable + // vectors instead (indexed by int64 var index). + const std::vector& cumuls() const { return cumuls_; } + const std::vector& transits() const { return transits_; } + const std::vector& slacks() const { return slacks_; } +#if !defined(SWIGCSHARP) && !defined(SWIGJAVA) + // Returns forbidden intervals for each node. + const std::vector& forbidden_intervals() const { + return forbidden_intervals_; + } + // Returns the capacities for all vehicles. + const std::vector& vehicle_capacities() const { + return vehicle_capacities_; + } + // Returns the callback evaluating the transit value between two node indices + // for a given vehicle. + const RoutingModel::TransitEvaluator2& transit_evaluator(int vehicle) const { + return class_evaluators_[vehicle_to_class_[vehicle]]; + } + int vehicle_to_class(int vehicle) const { return vehicle_to_class_[vehicle]; } +#endif // !defined(SWIGCSHARP) && !defined(SWIGJAVA) +#endif // !defined(SWIGPYTHON) + // Sets an upper bound on the dimension span on a given vehicle. This is the + // preferred way to limit the "length" of the route of a vehicle according to + // a dimension. + void SetSpanUpperBoundForVehicle(int64 upper_bound, int vehicle); + // Sets a cost proportional to the dimension span on a given vehicle, + // or on all vehicles at once. "coefficient" must be nonnegative. + // This is handy to model costs proportional to idle time when the dimension + // represents time. + // The cost for a vehicle is + // span_cost = coefficient * (dimension end value - dimension start value). + void SetSpanCostCoefficientForVehicle(int64 coefficient, int vehicle); + void SetSpanCostCoefficientForAllVehicles(int64 coefficient); + // Sets a cost proportional to the *global* dimension span, that is the + // difference between the largest value of route end cumul variables and + // the smallest value of route start cumul variables. + // In other words: + // global_span_cost = + // coefficient * (Max(dimension end value) - Min(dimension start value)). + void SetGlobalSpanCostCoefficient(int64 coefficient); + +#ifndef SWIG + // Sets a piecewise linear cost on the cumul variable of a given node. + // If f is a piecewsie linear function, the resulting cost at node n will be + // f(CumulVar(n)). + // As of 3/2017, only non-decreasing positive cost functions are supported. + void SetCumulVarPiecewiseLinearCost(RoutingModel::NodeIndex node, + const PiecewiseLinearFunction& cost); + // Same as SetCumulVarPiecewiseLinearCost applied to vehicle start node, + void SetStartCumulVarPiecewiseLinearCost(int vehicle, + const PiecewiseLinearFunction& cost); + // Same as SetCumulVarPiecewiseLinearCost applied to vehicle end node, + void SetEndCumulVarPiecewiseLinearCost(int vehicle, + const PiecewiseLinearFunction& cost); + // Same as above but using a variable index. + void SetCumulVarPiecewiseLinearCostFromIndex( + int64 index, const PiecewiseLinearFunction& cost); + // Returns true if a piecewise linear cost has been set for a given node. + bool HasCumulVarPiecewiseLinearCost(RoutingModel::NodeIndex node) const; + // Returns true if a piecewise linear cost has been set for a given vehicle + // start node. + bool HasStartCumulVarPiecewiseLinearCost(int vehicle) const; + // Returns true if a piecewise linear cost has been set for a given vehicle + // end node. + bool HasEndCumulVarPiecewiseLinearCost(int vehicle) const; + // Returns true if a piecewise linear cost has been set for a given variable + // index. + bool HasCumulVarPiecewiseLinearCostFromIndex(int64 index) const; + // Returns the piecewise linear cost of a cumul variable for a given node. + const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCost( + RoutingModel::NodeIndex node) const; + // Returns the piecewise linear cost of a cumul variable for a given vehicle + // start node. + const PiecewiseLinearFunction* GetStartCumulVarPiecewiseLinearCost( + int vehicle) const; + // Returns the piecewise linear cost of a cumul variable for a given vehicle + // end node. + const PiecewiseLinearFunction* GetEndCumulVarPiecewiseLinearCost( + int vehicle) const; + // Returns the piecewise linear cost of a cumul variable for a given variable + // index. + const PiecewiseLinearFunction* GetCumulVarPiecewiseLinearCostFromIndex( + int64 index) const; +#endif + + // Sets a soft upper bound to the cumul variable of a given node. If the + // value of the cumul variable is greater than the bound, a cost proportional + // to the difference between this value and the bound is added to the cost + // function of the model: + // cumulVar <= upper_bound -> cost = 0 + // cumulVar > upper_bound -> cost = coefficient * (cumulVar - upper_bound). + // This is also handy to model tardiness costs when the dimension represents + // time. + void SetCumulVarSoftUpperBound(RoutingModel::NodeIndex node, + int64 upper_bound, int64 coefficient); + // Same as SetCumulVarSoftUpperBound applied to vehicle start node, + void SetStartCumulVarSoftUpperBound(int vehicle, int64 upper_bound, + int64 coefficient); + // Same as SetCumulVarSoftUpperBound applied to vehicle end node, + void SetEndCumulVarSoftUpperBound(int vehicle, int64 upper_bound, + int64 coefficient); + // Same as SetCumulVarSoftUpperBound but using a variable index. + void SetCumulVarSoftUpperBoundFromIndex(int64 index, int64 upper_bound, + int64 coefficient); + // Returns true if a soft upper bound has been set for a given node. + bool HasCumulVarSoftUpperBound(RoutingModel::NodeIndex node) const; + // Returns true if a soft upper bound has been set for a given vehicle start + // node. + bool HasStartCumulVarSoftUpperBound(int vehicle) const; + // Returns true if a soft upper bound has been set for a given vehicle end + // node. + bool HasEndCumulVarSoftUpperBound(int vehicle) const; + // Returns true if a soft upper bound has been set for a given variable index. + bool HasCumulVarSoftUpperBoundFromIndex(int64 index) const; + // Returns the soft upper bound of a cumul variable for a given node. The + // "hard" upper bound of the variable is returned if no soft upper bound has + // been set. + int64 GetCumulVarSoftUpperBound(RoutingModel::NodeIndex node) const; + // Returns the soft upper bound of a cumul variable for a given vehicle start + // node. The "hard" upper bound of the variable is returned if no soft upper + // bound has been set. + int64 GetStartCumulVarSoftUpperBound(int vehicle) const; + // Returns the soft upper bound of a cumul variable for a given vehicle end + // node. The "hard" upper bound of the variable is returned if no soft upper + // bound has been set. + int64 GetEndCumulVarSoftUpperBound(int vehicle) const; + // Returns the soft upper bound of a cumul variable for a given variable + // index. The "hard" upper bound of the variable is returned if no soft upper + // bound has been set. + int64 GetCumulVarSoftUpperBoundFromIndex(int64 index) const; + // Returns the cost coefficient of the soft upper bound of a cumul variable + // for a given node. If no soft upper bound has been set, 0 is returned. + int64 GetCumulVarSoftUpperBoundCoefficient( + RoutingModel::NodeIndex node) const; + // Returns the cost coefficient of the soft upper bound of a cumul variable + // for a given vehicle start node. If no soft upper bound has been set, 0 is + // returned. + int64 GetStartCumulVarSoftUpperBoundCoefficient(int vehicle) const; + // Returns the cost coefficient of the soft upper bound of a cumul variable + // for a given vehicle end node. If no soft upper bound has been set, 0 is + // returned. + int64 GetEndCumulVarSoftUpperBoundCoefficient(int vehicle) const; + // Returns the cost coefficient of the soft upper bound of a cumul variable + // for a variable index. If no soft upper bound has been set, 0 is returned. + int64 GetCumulVarSoftUpperBoundCoefficientFromIndex(int64 index) const; + + // Sets a soft lower bound to the cumul variable of a given node. If the + // value of the cumul variable is less than the bound, a cost proportional + // to the difference between this value and the bound is added to the cost + // function of the model: + // cumulVar > lower_bound -> cost = 0 + // cumulVar <= lower_bound -> cost = coefficient * (lower_bound - cumulVar). + // This is also handy to model earliness costs when the dimension represents + // time. + // Note: Using soft lower and upper bounds or span costs together is, as of + // 6/2014, not well supported in the sense that an optimal schedule is not + // guaranteed. + void SetCumulVarSoftLowerBound(RoutingModel::NodeIndex node, + int64 lower_bound, int64 coefficient); + // Same as SetCumulVarSoftLowerBound applied to vehicle start node, + void SetStartCumulVarSoftLowerBound(int vehicle, int64 lower_bound, + int64 coefficient); + // Same as SetCumulVarSoftLowerBound applied to vehicle end node, + void SetEndCumulVarSoftLowerBound(int vehicle, int64 lower_bound, + int64 coefficient); + // Same as SetCumulVarSoftLowerBound but using a variable index. + void SetCumulVarSoftLowerBoundFromIndex(int64 index, int64 lower_bound, + int64 coefficient); + // Returns true if a soft lower bound has been set for a given node. + bool HasCumulVarSoftLowerBound(RoutingModel::NodeIndex node) const; + // Returns true if a soft lower bound has been set for a given vehicle start + // node. + bool HasStartCumulVarSoftLowerBound(int vehicle) const; + // Returns true if a soft lower bound has been set for a given vehicle end + // node. + bool HasEndCumulVarSoftLowerBound(int vehicle) const; + // Returns true if a soft lower bound has been set for a given variable index. + bool HasCumulVarSoftLowerBoundFromIndex(int64 index) const; + // Returns the soft lower bound of a cumul variable for a given node. The + // "hard" lower bound of the variable is returned if no soft lower bound has + // been set. + int64 GetCumulVarSoftLowerBound(RoutingModel::NodeIndex node) const; + // Returns the soft lower bound of a cumul variable for a given vehicle start + // node. The "hard" lower bound of the variable is returned if no soft lower + // bound has been set. + int64 GetStartCumulVarSoftLowerBound(int vehicle) const; + // Returns the soft lower bound of a cumul variable for a given vehicle end + // node. The "hard" lower bound of the variable is returned if no soft lower + // bound has been set. + int64 GetEndCumulVarSoftLowerBound(int vehicle) const; + // Returns the soft lower bound of a cumul variable for a given variable + // index. The "hard" lower bound of the variable is returned if no soft lower + // bound has been set. + int64 GetCumulVarSoftLowerBoundFromIndex(int64 index) const; + // Returns the cost coefficient of the soft lower bound of a cumul variable + // for a given node. If no soft lower bound has been set, 0 is returned. + int64 GetCumulVarSoftLowerBoundCoefficient( + RoutingModel::NodeIndex node) const; + // Returns the cost coefficient of the soft lower bound of a cumul variable + // for a given vehicle start node. If no soft lower bound has been set, 0 is + // returned. + int64 GetStartCumulVarSoftLowerBoundCoefficient(int vehicle) const; + // Returns the cost coefficient of the soft lower bound of a cumul variable + // for a given vehicle end node. If no soft lower bound has been set, 0 is + // returned. + int64 GetEndCumulVarSoftLowerBoundCoefficient(int vehicle) const; + // Returns the cost coefficient of the soft lower bound of a cumul variable + // for a variable index. If no soft lower bound has been set, 0 is returned. + int64 GetCumulVarSoftLowerBoundCoefficientFromIndex(int64 index) const; + // Sets the breaks for a given vehicle. Breaks are represented by + // IntervalVars. They may interrupt transits between nodes and increase + // the value of corresponding slack variables. However an interval cannot + // overlap the cumul variable of a node (the interval must either be before + // or after the node). + void SetBreakIntervalsOfVehicle(std::vector breaks, + int vehicle); + // Returns the parent in the dependency tree if any or nullptr otherwise. + const RoutingDimension* base_dimension() const { return base_dimension_; } + // It makes sense to use the function only for self-dependent dimension. + // For such dimensions the value of the slack of a node determines the + // transition cost of the next transit. Provided that + // 1. cumul[node] is fixed, + // 2. next[node] and next[next[node]] (if exists) are fixed, + // the value of slack[node] for which cumul[next[node]] + transit[next[node]] + // is minimized can be found in O(1) using this function. + int64 ShortestTransitionSlack(int64 node) const; + + // Returns the name of the dimension. + const std::string& name() const { return name_; } + + // Accessors. +#ifndef SWIG + const ReverseArcListGraph& GetPrecedenceGraph() const { + return precedence_graph_; + } +#endif + + int64 GetSpanUpperBoundForVehicle(int vehicle) const { + return vehicle_span_upper_bounds_[vehicle]; + } +#ifndef SWIG + const std::vector& vehicle_span_upper_bounds() const { + return vehicle_span_upper_bounds_; + } +#endif // SWIG + int64 GetSpanCostCoefficientForVehicle(int vehicle) const { + return vehicle_span_cost_coefficients_[vehicle]; + } +#ifndef SWIG + const std::vector& vehicle_span_cost_coefficients() const { + return vehicle_span_cost_coefficients_; + } +#endif // SWIG + int64 global_span_cost_coefficient() const { + return global_span_cost_coefficient_; + } + + private: + struct SoftBound { + SoftBound() : var(nullptr), bound(0), coefficient(0) {} + IntVar* var; + int64 bound; + int64 coefficient; + }; + + struct PiecewiseLinearCost { + PiecewiseLinearCost() : var(nullptr), cost(nullptr) {} + IntVar* var; + PiecewiseLinearFunction* cost; + }; + + class SelfBased {}; + RoutingDimension(RoutingModel* model, std::vector vehicle_capacities, + const std::string& name, const RoutingDimension* base_dimension); + RoutingDimension(RoutingModel* model, std::vector vehicle_capacities, + const std::string& name, SelfBased); + void Initialize( + const std::vector& transit_evaluators, + const std::vector& + state_dependent_node_evaluators, + int64 slack_max); + void InitializeCumuls(); + void InitializeTransits( + const std::vector& transit_evaluators, + const std::vector& + state_dependent_transit_evaluators, + int64 slack_max); + // Sets up the cost variables related to cumul soft upper bounds. + void SetupCumulVarSoftUpperBoundCosts( + std::vector* cost_elements) const; + // Sets up the cost variables related to cumul soft lower bounds. + void SetupCumulVarSoftLowerBoundCosts( + std::vector* cost_elements) const; + void SetupCumulVarPiecewiseLinearCosts( + std::vector* cost_elements) const; + // Sets up the cost variables related to the global span and per-vehicle span + // costs (only for the "slack" part of the latter). + void SetupGlobalSpanCost(std::vector* cost_elements) const; + void SetupSlackAndDependentTransitCosts( + std::vector* cost_elements) const; + // Finalize the model of the dimension. + void CloseModel(bool use_light_propagation); + + std::vector cumuls_; + std::vector forbidden_intervals_; + std::vector capacity_vars_; + const std::vector vehicle_capacities_; + std::vector transits_; + std::vector fixed_transits_; + // "transit_evaluators_" does the indexing by vehicle, while + // "class_evaluators_" does the de-duplicated ownership. + std::vector class_evaluators_; + std::vector vehicle_to_class_; +#ifndef SWIG + ReverseArcListGraph precedence_graph_; +#endif + + // The transits of a dimension may depend on its cumuls or the cumuls of + // another dimension. There can be no cycles, except for self loops, a typical + // example for this is a time dimension. + const RoutingDimension* const base_dimension_; + + // "state_dependent_transit_evaluators_" does the indexing by vehicle, while + // "state_dependent_class_evaluators_" does the de-duplicated ownership. + std::vector + state_dependent_class_evaluators_; + std::vector state_dependent_vehicle_to_class_; + + std::vector slacks_; + std::vector dependent_transits_; + std::vector vehicle_span_upper_bounds_; + int64 global_span_cost_coefficient_; + std::vector vehicle_span_cost_coefficients_; + std::vector cumul_var_soft_upper_bound_; + std::vector cumul_var_soft_lower_bound_; + std::vector cumul_var_piecewise_linear_cost_; + RoutingModel* const model_; + const std::string name_; + + friend class RoutingModel; + friend class RoutingModelInspector; + + DISALLOW_COPY_AND_ASSIGN(RoutingDimension); +}; + + +#ifndef SWIG +// Class to arrange nodes by by their distance and their angles from the +// depot. Used in the Sweep first solution heuristic. +class SweepArranger { + public: + explicit SweepArranger(const ITIVector >& points); + virtual ~SweepArranger() {} + void ArrangeNodes(std::vector* nodes); + void SetSectors(int sectors) { sectors_ = sectors; } + + private: + ITIVector coordinates_; + int sectors_; + + DISALLOW_COPY_AND_ASSIGN(SweepArranger); +}; +#endif + +// Routing Search + +// Decision builders building a solution using local search filters to evaluate +// its feasibility. This is very fast but can eventually fail when the solution +// is restored if filters did not detect all infeasiblities. +// More details: +// Using local search filters to build a solution. The approach is pretty +// straight-forward: have a general assignment storing the current solution, +// build delta assigment representing possible extensions to the current +// solution and validate them with filters. +// The tricky bit comes from using the assignment and filter APIs in a way +// which avoids the lazy creation of internal hash_maps between variables +// and indices. + +// Generic filter-based decision builder applied to IntVars. +// TODO(user): Eventually move this to the core CP solver library +// when the code is mature enough. +class IntVarFilteredDecisionBuilder : public DecisionBuilder { + public: + IntVarFilteredDecisionBuilder(Solver* solver, + const std::vector& vars, + const std::vector& filters); + ~IntVarFilteredDecisionBuilder() override {} + Decision* Next(Solver* solver) override; + // Virtual method to redefine to build a solution. + virtual bool BuildSolution() = 0; + // Returns statistics on search, number of decisions sent to filters, number + // of decisions rejected by filters. + int64 number_of_decisions() const { return number_of_decisions_; } + int64 number_of_rejects() const { return number_of_rejects_; } + + protected: + // Commits the modifications to the current solution if these modifications + // are "filter-feasible", returns false otherwise; in any case discards + // all modifications. + bool Commit(); + // Modifies the current solution by setting the variable of index 'index' to + // value 'value'. + void SetValue(int64 index, int64 value) { + if (!is_in_delta_[index]) { + delta_->FastAdd(vars_[index])->SetValue(value); + delta_indices_.push_back(index); + is_in_delta_[index] = true; + } else { + delta_->SetValue(vars_[index], value); + } + } + // Returns the value of the variable of index 'index' in the last committed + // solution. + int64 Value(int64 index) const { + return assignment_->IntVarContainer().Element(index).Value(); + } + // Returns true if the variable of index 'index' is in the current solution. + bool Contains(int64 index) const { + return assignment_->IntVarContainer().Element(index).Var() != nullptr; + } + // Returns the number of variables the decision builder is trying to + // instantiate. + int Size() const { return vars_.size(); } + // Returns the variable of index 'index'. + IntVar* Var(int64 index) const { return vars_[index]; } + + private: + // Sets all variables currently bound to their value in the current solution. + void SetValuesFromDomains(); + // Synchronizes filters with an assignment (the current solution). + void SynchronizeFilters(); + // Checks if filters accept a given modification to the current solution + // (represented by delta). + bool FilterAccept(); + + const std::vector vars_; + Assignment* const assignment_; + Assignment* const delta_; + std::vector delta_indices_; + std::vector is_in_delta_; + const Assignment* const empty_; + std::vector filters_; + // Stats on search + int64 number_of_decisions_; + int64 number_of_rejects_; +}; + +// Filter-based decision builder dedicated to routing. +class RoutingFilteredDecisionBuilder : public IntVarFilteredDecisionBuilder { + public: + RoutingFilteredDecisionBuilder( + RoutingModel* model, const std::vector& filters); + ~RoutingFilteredDecisionBuilder() override {} + RoutingModel* model() const { return model_; } + // Initializes the current solution with empty or partial vehicle routes. + bool InitializeRoutes(); + // Returns the end of the start chain of vehicle, + int GetStartChainEnd(int vehicle) const { return start_chain_ends_[vehicle]; } + // Make nodes in the same disjunction as 'node' unperformed. 'node' is a + // variable index corresponding to a node. + void MakeDisjunctionNodesUnperformed(int64 node); + // Make all unassigned nodes unperformed. + void MakeUnassignedNodesUnperformed(); + + private: + RoutingModel* const model_; + std::vector start_chain_ends_; +}; + +class CheapestInsertionFilteredDecisionBuilder + : public RoutingFilteredDecisionBuilder { + public: + // Takes ownership of evaluator. + CheapestInsertionFilteredDecisionBuilder( + RoutingModel* model, + ResultCallback3* evaluator, + ResultCallback1* penalty_evaluator, + const std::vector& filters); + ~CheapestInsertionFilteredDecisionBuilder() override {} + + protected: + typedef std::pair ValuedPosition; + // Inserts 'node' just after 'predecessor', and just before 'successor', + // resulting in the following subsequence: predecessor -> node -> successor. + // If 'node' is part of a disjunction, other nodes of the disjunction are made + // unperformed. + void InsertBetween(int64 node, int64 predecessor, int64 successor); + // Helper method to the ComputeEvaluatorSortedPositions* methods. Finds all + // possible insertion positions of node 'node_to_insert' in the partial route + // starting at node 'start' and adds them to 'valued_position', a list of + // unsorted pairs of (cost, position to insert the node). + void AppendEvaluatedPositionsAfter( + int64 node_to_insert, int64 start, int64 next_after_start, int64 vehicle, + std::vector* valued_positions); + // Returns the cost of unperforming node 'node_to_insert'. Returns kint64max + // if penalty callback is null or if the node cannot be unperformed. + int64 GetUnperformedValue(int64 node_to_insert) const; + + std::unique_ptr > evaluator_; + std::unique_ptr > penalty_evaluator_; +}; + +// Filter-based decision builder which builds a solution by inserting +// nodes at their cheapest position on any route; potentially several routes can +// be built in parallel. The cost of a position is computed from an arc-based +// cost callback. The node selected for insertion is the one which minimizes +// insertion cost. If a non null penalty evaluator is passed, making nodes +// unperformed is also taken into account with the corresponding penalty cost. +class GlobalCheapestInsertionFilteredDecisionBuilder + : public CheapestInsertionFilteredDecisionBuilder { + public: + // Takes ownership of evaluators. + GlobalCheapestInsertionFilteredDecisionBuilder( + RoutingModel* model, + ResultCallback3* evaluator, + ResultCallback1* penalty_evaluator, + const std::vector& filters); + ~GlobalCheapestInsertionFilteredDecisionBuilder() override {} + bool BuildSolution() override; + + private: + class PairEntry; + class NodeEntry; + typedef std::unordered_set PairEntries; + typedef std::unordered_set NodeEntries; + + // Inserts all non-inserted pickup and delivery pairs. Maintains a priority + // queue of possible pair insertions, which is incrementally updated when a + // pair insertion is committed. Incrementality is obtained by updating pair + // insertion positions on the four newly modified route arcs: after the pickup + // insertion position, after the pickup position, after the delivery insertion + // position and after the delivery position. + void InsertPairs(); + // Inserts all non-inserted individual nodes. Maintains a priority queue of + // possible insertions, which is incrementally updated when an insertion is + // committed. Incrementality is obtained by updating insertion positions on + // the two newly modified route arcs: after the node insertion position and + // after the node position. + void InsertNodes(); + // Initializes the priority queue and the pair entries with the current state + // of the solution. + void InitializePairPositions( + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + // Updates all pair entries inserting a node after node "insert_after" and + // updates the priority queue accordingly. + void UpdatePairPositions(int vehicle, int64 insert_after, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries) { + UpdatePickupPositions(vehicle, insert_after, priority_queue, + pickup_to_entries, delivery_to_entries); + UpdateDeliveryPositions(vehicle, insert_after, priority_queue, + pickup_to_entries, delivery_to_entries); + } + // Updates all pair entries inserting their pickup node after node + // "insert_after" and updates the priority queue accordingly. + void UpdatePickupPositions(int vehicle, int64 pickup_insert_after, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + // Updates all pair entries inserting their delivery node after node + // "insert_after" and updates the priority queue accordingly. + void UpdateDeliveryPositions( + int vehicle, int64 delivery_insert_after, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + // Deletes an entry, removing it from the priority queue and the appropriate + // pickup and delivery entry sets. + void DeletePairEntry(PairEntry* entry, + AdjustablePriorityQueue* priority_queue, + std::vector* pickup_to_entries, + std::vector* delivery_to_entries); + // Initializes the priority queue and the node entries with the current state + // of the solution. + void InitializePositions(AdjustablePriorityQueue* priority_queue, + std::vector* position_to_node_entries); + // Updates all node entries inserting a node after node "insert_after" and + // updates the priority queue accordingly. + void UpdatePositions(int vehicle, int64 insert_after, + AdjustablePriorityQueue* priority_queue, + std::vector* node_entries); + // Deletes an entry, removing it from the priority queue and the appropriate + // node entry sets. + void DeleteNodeEntry(NodeEntry* entry, + AdjustablePriorityQueue* priority_queue, + std::vector* node_entries); +}; + +// Filter-base decision builder which builds a solution by inserting +// nodes at their cheapest position. The cost of a position is computed +// an arc-based cost callback. Node selected for insertion are considered in +// the order they were created in the model. +class LocalCheapestInsertionFilteredDecisionBuilder + : public CheapestInsertionFilteredDecisionBuilder { + public: + // Takes ownership of evaluator. + LocalCheapestInsertionFilteredDecisionBuilder( + RoutingModel* model, + ResultCallback3* evaluator, + const std::vector& filters); + ~LocalCheapestInsertionFilteredDecisionBuilder() override {} + bool BuildSolution() override; + + private: + // Computes the possible insertion positions of 'node' and sorts them + // according to the current cost evaluator. + // 'node' is a variable index corresponding to a node, 'sorted_positions' is a + // vector of variable indices corresponding to nodes after which 'node' can be + // inserted. + void ComputeEvaluatorSortedPositions(int64 node, + std::vector* sorted_positions); + // Like ComputeEvaluatorSortedPositions, subject to the additional + // restrictions that the node may only be inserted after node 'start' on the + // route. For convenience, this method also needs the node that is right after + // 'start' on the route. + void ComputeEvaluatorSortedPositionsOnRouteAfter( + int64 node, int64 start, int64 next_after_start, + std::vector* sorted_positions); +}; + +// Filtered-base decision builder based on the addition heuristic, extending +// a path from its start node with the cheapest arc. +class CheapestAdditionFilteredDecisionBuilder + : public RoutingFilteredDecisionBuilder { + public: + CheapestAdditionFilteredDecisionBuilder( + RoutingModel* model, const std::vector& filters); + ~CheapestAdditionFilteredDecisionBuilder() override {} + bool BuildSolution() override; + + private: + class PartialRoutesAndLargeVehicleIndicesFirst { + public: + explicit PartialRoutesAndLargeVehicleIndicesFirst( + const CheapestAdditionFilteredDecisionBuilder& builder) + : builder_(builder) {} + bool operator()(int vehicle1, int vehicle2) const; + + private: + const CheapestAdditionFilteredDecisionBuilder& builder_; + }; + // Returns a sorted vector of nodes which can come next in the route after + // node 'from'. + // 'from' is a variable index corresponding to a node, 'sorted_nexts' is a + // vector of variable indices corresponding to nodes which can follow 'from'. + virtual void SortPossibleNexts(int64 from, + std::vector* sorted_nexts) = 0; +}; + +// A CheapestAdditionFilteredDecisionBuilder where the notion of 'cheapest arc' +// comes from an arc evaluator. +class EvaluatorCheapestAdditionFilteredDecisionBuilder + : public CheapestAdditionFilteredDecisionBuilder { + public: + // Takes ownership of evaluator. + EvaluatorCheapestAdditionFilteredDecisionBuilder( + RoutingModel* model, + ResultCallback2* evaluator, + const std::vector& filters); + ~EvaluatorCheapestAdditionFilteredDecisionBuilder() override {} + + private: + // Next nodes are sorted according to the current evaluator. + void SortPossibleNexts(int64 from, std::vector* sorted_nexts) override; + + std::unique_ptr > evaluator_; +}; + +// A CheapestAdditionFilteredDecisionBuilder where the notion of 'cheapest arc' +// comes from an arc comparator. +class ComparatorCheapestAdditionFilteredDecisionBuilder + : public CheapestAdditionFilteredDecisionBuilder { + public: + // Takes ownership of evaluator. + ComparatorCheapestAdditionFilteredDecisionBuilder( + RoutingModel* model, Solver::VariableValueComparator comparator, + const std::vector& filters); + ~ComparatorCheapestAdditionFilteredDecisionBuilder() override {} + + private: + // Next nodes are sorted according to the current comparator. + void SortPossibleNexts(int64 from, std::vector* sorted_nexts) override; + + Solver::VariableValueComparator comparator_; +}; + +// Filter-based decision builder which builds a solution by using +// Clarke & Wright's Savings heuristic. For each pair of nodes, the savings +// value is the difference between the cost of two routes visiting one node each +// and one route visiting both nodes. Routes are built sequentially, each route +// being initialized from the pair with the best avalaible savings value then +// extended by selecting the nodes with best savings on both ends of the partial +// route. +// Cost is based on the arc cost function of the routing model and cost classes +// are taken into account. +class SavingsFilteredDecisionBuilder : public RoutingFilteredDecisionBuilder { + public: + // If savings_neighbors > 0 then for each node only its 'saving_neighbors' + // neighbors leading to the smallest arc costs are considered. + SavingsFilteredDecisionBuilder( + RoutingModel* model, int64 saving_neighbors, + const std::vector& filters); + ~SavingsFilteredDecisionBuilder() override {} + bool BuildSolution() override; + + private: + typedef std::pair Saving; + + // Computes saving values for all node pairs and vehicle cost classes. The + // saving index attached to each saving value is an index used to + // store and recover the node pair to which the value is linked (cf. the + // index conversion methods below). + std::vector ComputeSavings() const; + // Builds a saving from a saving value, a cost class and two nodes. + Saving BuildSaving(int64 saving, int cost_class, int before_node, + int after_node) const { + return std::make_pair( + saving, cost_class * size_squared_ + before_node * Size() + after_node); + } + // Returns the cost class from a saving. + int64 GetCostClassFromSaving(const Saving& saving) const { + return saving.second / size_squared_; + } + // Returns the "before node" from a saving. + int64 GetBeforeNodeFromSaving(const Saving& saving) const { + return (saving.second % size_squared_) / Size(); + } + // Returns the "after node" from a saving. + int64 GetAfterNodeFromSaving(const Saving& saving) const { + return (saving.second % size_squared_) % Size(); + } + // Returns the saving value from a saving. + int64 GetSavingValue(const Saving& saving) const { return saving.first; } + + const int64 saving_neighbors_; + int64 size_squared_; +}; + +// Christofides addition heuristic. Initially created to solve TSPs, extended to +// support any model by extending routes as much as possible following the path +// found by the heuristic, before starting a new route. + +class ChristofidesFilteredDecisionBuilder + : public RoutingFilteredDecisionBuilder { + public: + ChristofidesFilteredDecisionBuilder( + RoutingModel* model, const std::vector& filters); + ~ChristofidesFilteredDecisionBuilder() override {} + bool BuildSolution() override; +}; + +// Routing filters + +class RoutingLocalSearchFilter : public IntVarLocalSearchFilter { + public: + RoutingLocalSearchFilter(const std::vector& nexts, + std::function objective_callback); + ~RoutingLocalSearchFilter() override {} + virtual void InjectObjectiveValue(int64 objective_value); + + protected: + bool CanPropagateObjectiveValue() const { + return objective_callback_ != nullptr; + } + void PropagateObjectiveValue(int64 objective_value); + + int64 injected_objective_value_; + + private: + std::function objective_callback_; +}; + +// Generic path-based filter class. + +class BasePathFilter : public RoutingLocalSearchFilter { + public: + BasePathFilter(const std::vector& nexts, int next_domain_size, + std::function objective_callback); + ~BasePathFilter() override {} + bool Accept(const Assignment* delta, const Assignment* deltadelta) override; + void OnSynchronize(const Assignment* delta) override; + + protected: + static const int64 kUnassigned; + + int64 GetNext(int64 node) const { + return (new_nexts_[node] == kUnassigned) + ? (IsVarSynced(node) ? Value(node) : kUnassigned) + : new_nexts_[node]; + } + int NumPaths() const { return starts_.size(); } + int64 Start(int i) const { return starts_[i]; } + int GetPath(int64 node) const { return paths_[node]; } + + private: + virtual void OnBeforeSynchronizePaths() {} + virtual void OnAfterSynchronizePaths() {} + virtual void OnSynchronizePathFromStart(int64 start) {} + virtual void InitializeAcceptPath() {} + virtual bool AcceptPath(int64 path_start, int64 chain_start, + int64 chain_end) = 0; + virtual bool FinalizeAcceptPath() { return true; } + // Detects path starts, used to track which node belongs to which path. + void ComputePathStarts(std::vector* path_starts, + std::vector* index_to_path); + bool HavePathsChanged(); + void SynchronizeFullAssignment(); + void UpdateAllRanks(); + void UpdatePathRanksFromStart(int start); + + std::vector node_path_starts_; + std::vector starts_; + std::vector paths_; + std::vector new_nexts_; + std::vector delta_touched_; + SparseBitset<> touched_paths_; + SparseBitset<> touched_path_nodes_; + std::vector ranks_; +}; + +#if !defined(SWIG) +RoutingLocalSearchFilter* MakeNodeDisjunctionFilter( + const RoutingModel& routing_model, + std::function objective_callback); +RoutingLocalSearchFilter* MakePathCumulFilter( + const RoutingModel& routing_model, const RoutingDimension& dimension, + std::function objective_callback); +RoutingLocalSearchFilter* MakeNodePrecedenceFilter( + const RoutingModel& routing_model, const RoutingModel::NodePairs& pairs); +RoutingLocalSearchFilter* MakeVehicleVarFilter( + const RoutingModel& routing_model); +#endif +} // namespace operations_research +#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/routing_enums.pb.h b/thirdparty/linux/include/ortools/constraint_solver/routing_enums.pb.h new file mode 100644 index 0000000..8d58d43 --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/routing_enums.pb.h @@ -0,0 +1,376 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/constraint_solver/routing_enums.proto + +#ifndef PROTOBUF_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto__INCLUDED +#define PROTOBUF_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); +void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); +void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); + +class FirstSolutionStrategy; +class LocalSearchMetaheuristic; + +enum FirstSolutionStrategy_Value { + FirstSolutionStrategy_Value_AUTOMATIC = 0, + FirstSolutionStrategy_Value_PATH_CHEAPEST_ARC = 3, + FirstSolutionStrategy_Value_PATH_MOST_CONSTRAINED_ARC = 4, + FirstSolutionStrategy_Value_EVALUATOR_STRATEGY = 5, + FirstSolutionStrategy_Value_SAVINGS = 10, + FirstSolutionStrategy_Value_SWEEP = 11, + FirstSolutionStrategy_Value_CHRISTOFIDES = 13, + FirstSolutionStrategy_Value_ALL_UNPERFORMED = 6, + FirstSolutionStrategy_Value_BEST_INSERTION = 7, + FirstSolutionStrategy_Value_PARALLEL_CHEAPEST_INSERTION = 8, + FirstSolutionStrategy_Value_LOCAL_CHEAPEST_INSERTION = 9, + FirstSolutionStrategy_Value_GLOBAL_CHEAPEST_ARC = 1, + FirstSolutionStrategy_Value_LOCAL_CHEAPEST_ARC = 2, + FirstSolutionStrategy_Value_FIRST_UNBOUND_MIN_VALUE = 12, + FirstSolutionStrategy_Value_FirstSolutionStrategy_Value_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + FirstSolutionStrategy_Value_FirstSolutionStrategy_Value_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +bool FirstSolutionStrategy_Value_IsValid(int value); +const FirstSolutionStrategy_Value FirstSolutionStrategy_Value_Value_MIN = FirstSolutionStrategy_Value_AUTOMATIC; +const FirstSolutionStrategy_Value FirstSolutionStrategy_Value_Value_MAX = FirstSolutionStrategy_Value_CHRISTOFIDES; +const int FirstSolutionStrategy_Value_Value_ARRAYSIZE = FirstSolutionStrategy_Value_Value_MAX + 1; + +const ::google::protobuf::EnumDescriptor* FirstSolutionStrategy_Value_descriptor(); +inline const ::std::string& FirstSolutionStrategy_Value_Name(FirstSolutionStrategy_Value value) { + return ::google::protobuf::internal::NameOfEnum( + FirstSolutionStrategy_Value_descriptor(), value); +} +inline bool FirstSolutionStrategy_Value_Parse( + const ::std::string& name, FirstSolutionStrategy_Value* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FirstSolutionStrategy_Value_descriptor(), name, value); +} +enum LocalSearchMetaheuristic_Value { + LocalSearchMetaheuristic_Value_AUTOMATIC = 0, + LocalSearchMetaheuristic_Value_GREEDY_DESCENT = 1, + LocalSearchMetaheuristic_Value_GUIDED_LOCAL_SEARCH = 2, + LocalSearchMetaheuristic_Value_SIMULATED_ANNEALING = 3, + LocalSearchMetaheuristic_Value_TABU_SEARCH = 4, + LocalSearchMetaheuristic_Value_OBJECTIVE_TABU_SEARCH = 5, + LocalSearchMetaheuristic_Value_LocalSearchMetaheuristic_Value_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + LocalSearchMetaheuristic_Value_LocalSearchMetaheuristic_Value_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +bool LocalSearchMetaheuristic_Value_IsValid(int value); +const LocalSearchMetaheuristic_Value LocalSearchMetaheuristic_Value_Value_MIN = LocalSearchMetaheuristic_Value_AUTOMATIC; +const LocalSearchMetaheuristic_Value LocalSearchMetaheuristic_Value_Value_MAX = LocalSearchMetaheuristic_Value_OBJECTIVE_TABU_SEARCH; +const int LocalSearchMetaheuristic_Value_Value_ARRAYSIZE = LocalSearchMetaheuristic_Value_Value_MAX + 1; + +const ::google::protobuf::EnumDescriptor* LocalSearchMetaheuristic_Value_descriptor(); +inline const ::std::string& LocalSearchMetaheuristic_Value_Name(LocalSearchMetaheuristic_Value value) { + return ::google::protobuf::internal::NameOfEnum( + LocalSearchMetaheuristic_Value_descriptor(), value); +} +inline bool LocalSearchMetaheuristic_Value_Parse( + const ::std::string& name, LocalSearchMetaheuristic_Value* value) { + return ::google::protobuf::internal::ParseNamedEnum( + LocalSearchMetaheuristic_Value_descriptor(), name, value); +} +// =================================================================== + +class FirstSolutionStrategy : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.FirstSolutionStrategy) */ { + public: + FirstSolutionStrategy(); + virtual ~FirstSolutionStrategy(); + + FirstSolutionStrategy(const FirstSolutionStrategy& from); + + inline FirstSolutionStrategy& operator=(const FirstSolutionStrategy& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FirstSolutionStrategy& default_instance(); + + void Swap(FirstSolutionStrategy* other); + + // implements Message ---------------------------------------------- + + inline FirstSolutionStrategy* New() const { return New(NULL); } + + FirstSolutionStrategy* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FirstSolutionStrategy& from); + void MergeFrom(const FirstSolutionStrategy& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FirstSolutionStrategy* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef FirstSolutionStrategy_Value Value; + static const Value AUTOMATIC = + FirstSolutionStrategy_Value_AUTOMATIC; + static const Value PATH_CHEAPEST_ARC = + FirstSolutionStrategy_Value_PATH_CHEAPEST_ARC; + static const Value PATH_MOST_CONSTRAINED_ARC = + FirstSolutionStrategy_Value_PATH_MOST_CONSTRAINED_ARC; + static const Value EVALUATOR_STRATEGY = + FirstSolutionStrategy_Value_EVALUATOR_STRATEGY; + static const Value SAVINGS = + FirstSolutionStrategy_Value_SAVINGS; + static const Value SWEEP = + FirstSolutionStrategy_Value_SWEEP; + static const Value CHRISTOFIDES = + FirstSolutionStrategy_Value_CHRISTOFIDES; + static const Value ALL_UNPERFORMED = + FirstSolutionStrategy_Value_ALL_UNPERFORMED; + static const Value BEST_INSERTION = + FirstSolutionStrategy_Value_BEST_INSERTION; + static const Value PARALLEL_CHEAPEST_INSERTION = + FirstSolutionStrategy_Value_PARALLEL_CHEAPEST_INSERTION; + static const Value LOCAL_CHEAPEST_INSERTION = + FirstSolutionStrategy_Value_LOCAL_CHEAPEST_INSERTION; + static const Value GLOBAL_CHEAPEST_ARC = + FirstSolutionStrategy_Value_GLOBAL_CHEAPEST_ARC; + static const Value LOCAL_CHEAPEST_ARC = + FirstSolutionStrategy_Value_LOCAL_CHEAPEST_ARC; + static const Value FIRST_UNBOUND_MIN_VALUE = + FirstSolutionStrategy_Value_FIRST_UNBOUND_MIN_VALUE; + static inline bool Value_IsValid(int value) { + return FirstSolutionStrategy_Value_IsValid(value); + } + static const Value Value_MIN = + FirstSolutionStrategy_Value_Value_MIN; + static const Value Value_MAX = + FirstSolutionStrategy_Value_Value_MAX; + static const int Value_ARRAYSIZE = + FirstSolutionStrategy_Value_Value_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Value_descriptor() { + return FirstSolutionStrategy_Value_descriptor(); + } + static inline const ::std::string& Value_Name(Value value) { + return FirstSolutionStrategy_Value_Name(value); + } + static inline bool Value_Parse(const ::std::string& name, + Value* value) { + return FirstSolutionStrategy_Value_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:operations_research.FirstSolutionStrategy) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); + + void InitAsDefaultInstance(); + static FirstSolutionStrategy* default_instance_; +}; +// ------------------------------------------------------------------- + +class LocalSearchMetaheuristic : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.LocalSearchMetaheuristic) */ { + public: + LocalSearchMetaheuristic(); + virtual ~LocalSearchMetaheuristic(); + + LocalSearchMetaheuristic(const LocalSearchMetaheuristic& from); + + inline LocalSearchMetaheuristic& operator=(const LocalSearchMetaheuristic& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const LocalSearchMetaheuristic& default_instance(); + + void Swap(LocalSearchMetaheuristic* other); + + // implements Message ---------------------------------------------- + + inline LocalSearchMetaheuristic* New() const { return New(NULL); } + + LocalSearchMetaheuristic* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const LocalSearchMetaheuristic& from); + void MergeFrom(const LocalSearchMetaheuristic& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(LocalSearchMetaheuristic* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef LocalSearchMetaheuristic_Value Value; + static const Value AUTOMATIC = + LocalSearchMetaheuristic_Value_AUTOMATIC; + static const Value GREEDY_DESCENT = + LocalSearchMetaheuristic_Value_GREEDY_DESCENT; + static const Value GUIDED_LOCAL_SEARCH = + LocalSearchMetaheuristic_Value_GUIDED_LOCAL_SEARCH; + static const Value SIMULATED_ANNEALING = + LocalSearchMetaheuristic_Value_SIMULATED_ANNEALING; + static const Value TABU_SEARCH = + LocalSearchMetaheuristic_Value_TABU_SEARCH; + static const Value OBJECTIVE_TABU_SEARCH = + LocalSearchMetaheuristic_Value_OBJECTIVE_TABU_SEARCH; + static inline bool Value_IsValid(int value) { + return LocalSearchMetaheuristic_Value_IsValid(value); + } + static const Value Value_MIN = + LocalSearchMetaheuristic_Value_Value_MIN; + static const Value Value_MAX = + LocalSearchMetaheuristic_Value_Value_MAX; + static const int Value_ARRAYSIZE = + LocalSearchMetaheuristic_Value_Value_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Value_descriptor() { + return LocalSearchMetaheuristic_Value_descriptor(); + } + static inline const ::std::string& Value_Name(Value value) { + return LocalSearchMetaheuristic_Value_Name(value); + } + static inline bool Value_Parse(const ::std::string& name, + Value* value) { + return LocalSearchMetaheuristic_Value_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:operations_research.LocalSearchMetaheuristic) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto(); + + void InitAsDefaultInstance(); + static LocalSearchMetaheuristic* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// FirstSolutionStrategy + +// ------------------------------------------------------------------- + +// LocalSearchMetaheuristic + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::operations_research::FirstSolutionStrategy_Value> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::FirstSolutionStrategy_Value>() { + return ::operations_research::FirstSolutionStrategy_Value_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::LocalSearchMetaheuristic_Value> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::LocalSearchMetaheuristic_Value>() { + return ::operations_research::LocalSearchMetaheuristic_Value_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fconstraint_5fsolver_2frouting_5fenums_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/constraint_solver/routing_flags.h b/thirdparty/linux/include/ortools/constraint_solver/routing_flags.h new file mode 100644 index 0000000..4ec623e --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/routing_flags.h @@ -0,0 +1,84 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FLAGS_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FLAGS_H_ + +#include + +#include "ortools/base/commandlineflags.h" +#include "ortools/constraint_solver/routing_parameters.pb.h" + +// --- Routing search flags --- + +// Neighborhood activation/deactivation +DECLARE_bool(routing_no_lns); +DECLARE_bool(routing_no_fullpathlns); +DECLARE_bool(routing_no_relocate); +DECLARE_bool(routing_no_relocate_neighbors); +DECLARE_bool(routing_no_exchange); +DECLARE_bool(routing_no_cross); +DECLARE_bool(routing_no_2opt); +DECLARE_bool(routing_no_oropt); +DECLARE_bool(routing_no_make_active); +DECLARE_bool(routing_no_lkh); +DECLARE_bool(routing_no_tsp); +DECLARE_bool(routing_no_tsplns); +DECLARE_bool(routing_use_chain_make_inactive); +DECLARE_bool(routing_use_extended_swap_active); + +// Meta-heuristics +DECLARE_bool(routing_guided_local_search); +DECLARE_double(routing_guided_local_search_lambda_coefficient); +DECLARE_bool(routing_simulated_annealing); +DECLARE_bool(routing_tabu_search); +DECLARE_bool(routing_objective_tabu_search); + +// Search limits +DECLARE_int64(routing_solution_limit); +DECLARE_int64(routing_time_limit); +DECLARE_int64(routing_lns_time_limit); + +// Search control +DECLARE_string(routing_first_solution); +DECLARE_bool(routing_use_filtered_first_solutions); +DECLARE_bool(routing_dfs); +DECLARE_int64(routing_optimization_step); + +// Propagation control +DECLARE_bool(routing_use_light_propagation); + +// Cache settings. +DECLARE_bool(routing_cache_callbacks); +DECLARE_int64(routing_max_cache_size); + +// Misc +DECLARE_bool(routing_fingerprint_arc_cost_evaluators); +DECLARE_bool(routing_trace); +DECLARE_bool(routing_profile); + +// --- Routing model flags --- +DECLARE_bool(routing_use_homogeneous_costs); +DECLARE_bool(routing_gzip_compress_trail); + +namespace operations_research { + +// Builds routing search parameters from flags. +RoutingModelParameters BuildModelParametersFromFlags(); + +// Builds routing search parameters from flags. +RoutingSearchParameters BuildSearchParametersFromFlags(); + +} // namespace operations_research + +#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_FLAGS_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/routing_neighborhoods.h b/thirdparty/linux/include/ortools/constraint_solver/routing_neighborhoods.h new file mode 100644 index 0000000..b4a5a8e --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/routing_neighborhoods.h @@ -0,0 +1,313 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_NEIGHBORHOODS_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_NEIGHBORHOODS_H_ + +#include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/constraint_solveri.h" +#include "ortools/constraint_solver/routing_types.h" + +namespace operations_research { + +// Relocate neighborhood which moves chains of neighbors. +// The operator starts by relocating a node n after a node m, then continues +// moving nodes which were after n as long as the "cost" added is less than +// the "cost" of the arc (m, n). If the new chain doesn't respect the domain of +// next variables, it will try reordering the nodes. +// Possible neighbors for path 1 -> A -> B -> C -> D -> E -> 2 (where (1, 2) are +// first and last nodes of the path and can therefore not be moved, A must +// be performed before B, and A, D and E are located at the same place): +// 1 -> A -> C -> [B] -> D -> E -> 2 +// 1 -> A -> C -> D -> [B] -> E -> 2 +// 1 -> A -> C -> D -> E -> [B] -> 2 +// 1 -> A -> B -> D -> [C] -> E -> 2 +// 1 -> A -> B -> D -> E -> [C] -> 2 +// 1 -> A -> [D] -> [E] -> B -> C -> 2 +// 1 -> A -> B -> [D] -> [E] -> C -> 2 +// 1 -> A -> [E] -> B -> C -> D -> 2 +// 1 -> A -> B -> [E] -> C -> D -> 2 +// 1 -> A -> B -> C -> [E] -> D -> 2 +// This operator is extremely useful to move chains of nodes which are located +// at the same place (for instance nodes part of a same stop). +// TODO(user): Consider merging with standard Relocate in local_search.cc. +class MakeRelocateNeighborsOperator : public PathWithPreviousNodesOperator { + public: + MakeRelocateNeighborsOperator( + const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + RoutingTransitEvaluator2 arc_evaluator); + ~MakeRelocateNeighborsOperator() override {} + + bool MakeNeighbor() override; + std::string DebugString() const override { return "RelocateNeighbors"; } + + private: + // Moves a chain starting after 'before_chain' and ending at 'chain_end' + // after node 'destination'. Tries to repair the resulting solution by + // checking if the new arc created after 'destination' is compatible with + // NextVar domains, and moves the 'destination' down the path if the solution + // is inconsistent. Iterates the process on the new arcs created before + // the node 'destination' (if destination was moved). + bool MoveChainAndRepair(int64 before_chain, int64 chain_end, + int64 destination); + + // Moves node after 'before_to_move' down the path until a position is found + // where NextVar domains are not violated, it it exists. Stops when reaching + // position after 'up_to'. + int64 Reposition(int64 before_to_move, int64 up_to); + + RoutingTransitEvaluator2 arc_evaluator_; +}; + +// Pair-based neighborhood operators, designed to move nodes by pairs (pairs +// are static and given). These neighborhoods are very useful for Pickup and +// Delivery problems where pickup and delivery nodes must remain on the same +// route. +// TODO(user): Add option to prune neighbords where the order of node pairs +// is violated (ie precedence between pickup and delivery nodes). +// TODO(user): Move this to local_search.cc if it's generic enough. +// TODO(user): Detect pairs automatically by parsing the constraint model; +// we could then get rid of the pair API in the RoutingModel +// class. + +// Operator which inserts pairs of inactive nodes into a path. +// Possible neighbors for the path 1 -> 2 -> 3 with pair (A, B) inactive +// (where 1 and 3 are first and last nodes of the path) are: +// 1 -> [A] -> [B] -> 2 -> 3 +// 1 -> [B] -> 2 -> [A] -> 3 +// 1 -> [A] -> 2 -> [B] -> 3 +// 1 -> 2 -> [A] -> [B] -> 3 +// Note that this operator does not expicitely insert the nodes of a pair one +// after the other which forbids the following solutions: +// 1 -> [B] -> [A] -> 2 -> 3 +// 1 -> 2 -> [B] -> [A] -> 3 +// which can only be obtained by inserting A after B. +class MakePairActiveOperator : public PathOperator { + public: + MakePairActiveOperator(const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + const RoutingNodePairs& pairs); + ~MakePairActiveOperator() override {} + bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override; + bool MakeNeighbor() override; + std::string DebugString() const override { return "MakePairActive"; } + + protected: + bool OnSamePathAsPreviousBase(int64 base_index) override { + // Both base nodes have to be on the same path since they represent the + // nodes after which unactive node pairs will be moved. + return true; + } + + int64 GetBaseNodeRestartPosition(int base_index) override; + + // Required to ensure that after synchronization the operator is in a state + // compatible with GetBaseNodeRestartPosition. + bool RestartAtPathStartOnSynchronize() override { return true; } + + private: + void OnNodeInitialization() override; + + int inactive_pair_; + RoutingNodePairs pairs_; +}; + +// Operator which makes pairs of active nodes inactive. +class MakePairInactiveOperator : public PathWithPreviousNodesOperator { + public: + MakePairInactiveOperator(const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + const RoutingNodePairs& node_pairs); + + bool MakeNeighbor() override; + std::string DebugString() const override { return "MakePairInActive"; } + + private: + std::vector pairs_; +}; + +// Operator which moves a pair of nodes to another position where the first +// node of the pair must be before the second node on the same path. +// Possible neighbors for the path 1 -> A -> B -> 2 -> 3 (where (1, 3) are +// first and last nodes of the path and can therefore not be moved, and (A, B) +// is a pair of nodes): +// 1 -> [A] -> 2 -> [B] -> 3 +// 1 -> 2 -> [A] -> [B] -> 3 +class PairRelocateOperator : public PathOperator { + public: + PairRelocateOperator(const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + const RoutingNodePairs& node_pairs); + ~PairRelocateOperator() override {} + + bool MakeNeighbor() override; + std::string DebugString() const override { return "PairRelocateOperator"; } + + protected: + bool OnSamePathAsPreviousBase(int64 base_index) override { + // Both destination nodes must be on the same path. + return base_index == kPairSecondNodeDestination; + } + int64 GetBaseNodeRestartPosition(int base_index) override; + + private: + void OnNodeInitialization() override; + bool RestartAtPathStartOnSynchronize() override { return true; } + + std::vector pairs_; + std::vector prevs_; + std::vector is_first_; + static const int kPairFirstNode = 0; + static const int kPairFirstNodeDestination = 1; + static const int kPairSecondNodeDestination = 2; +}; + +// Operator which inserts inactive nodes into a path and makes a pair of +// active nodes inactive. +class NodePairSwapActiveOperator : public PathWithPreviousNodesOperator { + public: + NodePairSwapActiveOperator(const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + const RoutingNodePairs& node_pairs); + ~NodePairSwapActiveOperator() override {} + + bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override; + bool MakeNeighbor() override; + std::string DebugString() const override { return "NodePairSwapActiveOperator"; } + + private: + void OnNodeInitialization() override; + + int inactive_node_; + std::vector pairs_; +}; + +// Operator which inserts pairs of inactive nodes into a path and makes an +// active node inactive. +// There are two versions: +// - one which makes inactive the node being replaced by the first node of the +// pair (with swap_first true); +// - one which makes inactive the node being replaced by the second node of the +// pair (with swap_first false). +template +class PairNodeSwapActiveOperator : public PathOperator { + public: + PairNodeSwapActiveOperator(const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + const RoutingNodePairs& node_pairs); + ~PairNodeSwapActiveOperator() override {} + + bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override; + bool MakeNeighbor() override; + std::string DebugString() const override { return "PairNodeSwapActiveOperator"; } + + protected: + bool OnSamePathAsPreviousBase(int64 base_index) override { + // Both base nodes have to be on the same path since they represent the + // nodes after which unactive node pairs will be moved. + return true; + } + + int64 GetBaseNodeRestartPosition(int base_index) override; + + // Required to ensure that after synchronization the operator is in a state + // compatible with GetBaseNodeRestartPosition. + bool RestartAtPathStartOnSynchronize() override { return true; } + + private: + void OnNodeInitialization() override; + + int inactive_pair_; + RoutingNodePairs pairs_; +}; + +// ========================================================================== +// Section: Implementations of the template classes declared above. + +template +PairNodeSwapActiveOperator::PairNodeSwapActiveOperator( + const std::vector& vars, + const std::vector& secondary_vars, + std::function start_empty_path_class, + const RoutingNodePairs& node_pairs) + : PathOperator(vars, secondary_vars, 2, std::move(start_empty_path_class)), + inactive_pair_(0), + pairs_(node_pairs) {} + +template +int64 PairNodeSwapActiveOperator::GetBaseNodeRestartPosition( + int base_index) { + // Base node 1 must be after base node 0 if they are both on the same path. + if (base_index == 0 || StartNode(base_index) != StartNode(base_index - 1)) { + return StartNode(base_index); + } else { + return BaseNode(base_index - 1); + } +} + +template +void PairNodeSwapActiveOperator::OnNodeInitialization() { + for (int i = 0; i < pairs_.size(); ++i) { + if (IsInactive(pairs_[i].first[0]) && IsInactive(pairs_[i].second[0])) { + inactive_pair_ = i; + return; + } + } + inactive_pair_ = pairs_.size(); +} + +template +bool PairNodeSwapActiveOperator::MakeNextNeighbor( + Assignment* delta, Assignment* deltadelta) { + while (inactive_pair_ < pairs_.size()) { + if (!IsInactive(pairs_[inactive_pair_].first[0]) || + !IsInactive(pairs_[inactive_pair_].second[0]) || + !PathOperator::MakeNextNeighbor(delta, deltadelta)) { + ResetPosition(); + ++inactive_pair_; + } else { + return true; + } + } + return false; +} + +template +bool PairNodeSwapActiveOperator::MakeNeighbor() { + const int64 base = BaseNode(0); + if (IsPathEnd(base)) { + return false; + } + const int64 pair_first = pairs_[inactive_pair_].first[0]; + const int64 pair_second = pairs_[inactive_pair_].second[0]; + if (swap_first) { + return MakeActive(pair_second, BaseNode(1)) && + MakeActive(pair_first, base) && + MakeChainInactive(pair_first, Next(pair_first)); + } else { + return MakeActive(pair_second, BaseNode(1)) && + MakeActive(pair_first, base) && + MakeChainInactive(pair_second, Next(pair_second)); + } +} + +} // namespace operations_research + +#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_NEIGHBORHOODS_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/routing_parameters.pb.h b/thirdparty/linux/include/ortools/constraint_solver/routing_parameters.pb.h new file mode 100644 index 0000000..ebc7540 --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/routing_parameters.pb.h @@ -0,0 +1,1131 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/constraint_solver/routing_parameters.proto + +#ifndef PROTOBUF_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto__INCLUDED +#define PROTOBUF_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ortools/constraint_solver/routing_enums.pb.h" +#include "ortools/constraint_solver/solver_parameters.pb.h" +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); +void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); +void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + +class RoutingModelParameters; +class RoutingSearchParameters; +class RoutingSearchParameters_LocalSearchNeighborhoodOperators; + +// =================================================================== + +class RoutingSearchParameters_LocalSearchNeighborhoodOperators : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators) */ { + public: + RoutingSearchParameters_LocalSearchNeighborhoodOperators(); + virtual ~RoutingSearchParameters_LocalSearchNeighborhoodOperators(); + + RoutingSearchParameters_LocalSearchNeighborhoodOperators(const RoutingSearchParameters_LocalSearchNeighborhoodOperators& from); + + inline RoutingSearchParameters_LocalSearchNeighborhoodOperators& operator=(const RoutingSearchParameters_LocalSearchNeighborhoodOperators& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RoutingSearchParameters_LocalSearchNeighborhoodOperators& default_instance(); + + void Swap(RoutingSearchParameters_LocalSearchNeighborhoodOperators* other); + + // implements Message ---------------------------------------------- + + inline RoutingSearchParameters_LocalSearchNeighborhoodOperators* New() const { return New(NULL); } + + RoutingSearchParameters_LocalSearchNeighborhoodOperators* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RoutingSearchParameters_LocalSearchNeighborhoodOperators& from); + void MergeFrom(const RoutingSearchParameters_LocalSearchNeighborhoodOperators& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(RoutingSearchParameters_LocalSearchNeighborhoodOperators* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool use_relocate = 1; + void clear_use_relocate(); + static const int kUseRelocateFieldNumber = 1; + bool use_relocate() const; + void set_use_relocate(bool value); + + // optional bool use_relocate_pair = 2; + void clear_use_relocate_pair(); + static const int kUseRelocatePairFieldNumber = 2; + bool use_relocate_pair() const; + void set_use_relocate_pair(bool value); + + // optional bool use_relocate_neighbors = 3; + void clear_use_relocate_neighbors(); + static const int kUseRelocateNeighborsFieldNumber = 3; + bool use_relocate_neighbors() const; + void set_use_relocate_neighbors(bool value); + + // optional bool use_exchange = 4; + void clear_use_exchange(); + static const int kUseExchangeFieldNumber = 4; + bool use_exchange() const; + void set_use_exchange(bool value); + + // optional bool use_cross = 5; + void clear_use_cross(); + static const int kUseCrossFieldNumber = 5; + bool use_cross() const; + void set_use_cross(bool value); + + // optional bool use_cross_exchange = 6; + void clear_use_cross_exchange(); + static const int kUseCrossExchangeFieldNumber = 6; + bool use_cross_exchange() const; + void set_use_cross_exchange(bool value); + + // optional bool use_two_opt = 7; + void clear_use_two_opt(); + static const int kUseTwoOptFieldNumber = 7; + bool use_two_opt() const; + void set_use_two_opt(bool value); + + // optional bool use_or_opt = 8; + void clear_use_or_opt(); + static const int kUseOrOptFieldNumber = 8; + bool use_or_opt() const; + void set_use_or_opt(bool value); + + // optional bool use_lin_kernighan = 9; + void clear_use_lin_kernighan(); + static const int kUseLinKernighanFieldNumber = 9; + bool use_lin_kernighan() const; + void set_use_lin_kernighan(bool value); + + // optional bool use_tsp_opt = 10; + void clear_use_tsp_opt(); + static const int kUseTspOptFieldNumber = 10; + bool use_tsp_opt() const; + void set_use_tsp_opt(bool value); + + // optional bool use_make_active = 11; + void clear_use_make_active(); + static const int kUseMakeActiveFieldNumber = 11; + bool use_make_active() const; + void set_use_make_active(bool value); + + // optional bool use_relocate_and_make_active = 21; + void clear_use_relocate_and_make_active(); + static const int kUseRelocateAndMakeActiveFieldNumber = 21; + bool use_relocate_and_make_active() const; + void set_use_relocate_and_make_active(bool value); + + // optional bool use_make_inactive = 12; + void clear_use_make_inactive(); + static const int kUseMakeInactiveFieldNumber = 12; + bool use_make_inactive() const; + void set_use_make_inactive(bool value); + + // optional bool use_make_chain_inactive = 13; + void clear_use_make_chain_inactive(); + static const int kUseMakeChainInactiveFieldNumber = 13; + bool use_make_chain_inactive() const; + void set_use_make_chain_inactive(bool value); + + // optional bool use_swap_active = 14; + void clear_use_swap_active(); + static const int kUseSwapActiveFieldNumber = 14; + bool use_swap_active() const; + void set_use_swap_active(bool value); + + // optional bool use_extended_swap_active = 15; + void clear_use_extended_swap_active(); + static const int kUseExtendedSwapActiveFieldNumber = 15; + bool use_extended_swap_active() const; + void set_use_extended_swap_active(bool value); + + // optional bool use_node_pair_swap_active = 20; + void clear_use_node_pair_swap_active(); + static const int kUseNodePairSwapActiveFieldNumber = 20; + bool use_node_pair_swap_active() const; + void set_use_node_pair_swap_active(bool value); + + // optional bool use_path_lns = 16; + void clear_use_path_lns(); + static const int kUsePathLnsFieldNumber = 16; + bool use_path_lns() const; + void set_use_path_lns(bool value); + + // optional bool use_full_path_lns = 17; + void clear_use_full_path_lns(); + static const int kUseFullPathLnsFieldNumber = 17; + bool use_full_path_lns() const; + void set_use_full_path_lns(bool value); + + // optional bool use_tsp_lns = 18; + void clear_use_tsp_lns(); + static const int kUseTspLnsFieldNumber = 18; + bool use_tsp_lns() const; + void set_use_tsp_lns(bool value); + + // optional bool use_inactive_lns = 19; + void clear_use_inactive_lns(); + static const int kUseInactiveLnsFieldNumber = 19; + bool use_inactive_lns() const; + void set_use_inactive_lns(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + bool use_relocate_; + bool use_relocate_pair_; + bool use_relocate_neighbors_; + bool use_exchange_; + bool use_cross_; + bool use_cross_exchange_; + bool use_two_opt_; + bool use_or_opt_; + bool use_lin_kernighan_; + bool use_tsp_opt_; + bool use_make_active_; + bool use_relocate_and_make_active_; + bool use_make_inactive_; + bool use_make_chain_inactive_; + bool use_swap_active_; + bool use_extended_swap_active_; + bool use_node_pair_swap_active_; + bool use_path_lns_; + bool use_full_path_lns_; + bool use_tsp_lns_; + bool use_inactive_lns_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + + void InitAsDefaultInstance(); + static RoutingSearchParameters_LocalSearchNeighborhoodOperators* default_instance_; +}; +// ------------------------------------------------------------------- + +class RoutingSearchParameters : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.RoutingSearchParameters) */ { + public: + RoutingSearchParameters(); + virtual ~RoutingSearchParameters(); + + RoutingSearchParameters(const RoutingSearchParameters& from); + + inline RoutingSearchParameters& operator=(const RoutingSearchParameters& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RoutingSearchParameters& default_instance(); + + void Swap(RoutingSearchParameters* other); + + // implements Message ---------------------------------------------- + + inline RoutingSearchParameters* New() const { return New(NULL); } + + RoutingSearchParameters* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RoutingSearchParameters& from); + void MergeFrom(const RoutingSearchParameters& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(RoutingSearchParameters* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RoutingSearchParameters_LocalSearchNeighborhoodOperators LocalSearchNeighborhoodOperators; + + // accessors ------------------------------------------------------- + + // optional .operations_research.FirstSolutionStrategy.Value first_solution_strategy = 1; + void clear_first_solution_strategy(); + static const int kFirstSolutionStrategyFieldNumber = 1; + ::operations_research::FirstSolutionStrategy_Value first_solution_strategy() const; + void set_first_solution_strategy(::operations_research::FirstSolutionStrategy_Value value); + + // optional bool use_filtered_first_solution_strategy = 2; + void clear_use_filtered_first_solution_strategy(); + static const int kUseFilteredFirstSolutionStrategyFieldNumber = 2; + bool use_filtered_first_solution_strategy() const; + void set_use_filtered_first_solution_strategy(bool value); + + // optional .operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators local_search_operators = 3; + bool has_local_search_operators() const; + void clear_local_search_operators(); + static const int kLocalSearchOperatorsFieldNumber = 3; + const ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators& local_search_operators() const; + ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators* mutable_local_search_operators(); + ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators* release_local_search_operators(); + void set_allocated_local_search_operators(::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators* local_search_operators); + + // optional .operations_research.LocalSearchMetaheuristic.Value local_search_metaheuristic = 4; + void clear_local_search_metaheuristic(); + static const int kLocalSearchMetaheuristicFieldNumber = 4; + ::operations_research::LocalSearchMetaheuristic_Value local_search_metaheuristic() const; + void set_local_search_metaheuristic(::operations_research::LocalSearchMetaheuristic_Value value); + + // optional double guided_local_search_lambda_coefficient = 5; + void clear_guided_local_search_lambda_coefficient(); + static const int kGuidedLocalSearchLambdaCoefficientFieldNumber = 5; + double guided_local_search_lambda_coefficient() const; + void set_guided_local_search_lambda_coefficient(double value); + + // optional bool use_depth_first_search = 6; + void clear_use_depth_first_search(); + static const int kUseDepthFirstSearchFieldNumber = 6; + bool use_depth_first_search() const; + void set_use_depth_first_search(bool value); + + // optional int64 optimization_step = 7; + void clear_optimization_step(); + static const int kOptimizationStepFieldNumber = 7; + ::google::protobuf::int64 optimization_step() const; + void set_optimization_step(::google::protobuf::int64 value); + + // optional int64 solution_limit = 8; + void clear_solution_limit(); + static const int kSolutionLimitFieldNumber = 8; + ::google::protobuf::int64 solution_limit() const; + void set_solution_limit(::google::protobuf::int64 value); + + // optional int64 time_limit_ms = 9; + void clear_time_limit_ms(); + static const int kTimeLimitMsFieldNumber = 9; + ::google::protobuf::int64 time_limit_ms() const; + void set_time_limit_ms(::google::protobuf::int64 value); + + // optional int64 lns_time_limit_ms = 10; + void clear_lns_time_limit_ms(); + static const int kLnsTimeLimitMsFieldNumber = 10; + ::google::protobuf::int64 lns_time_limit_ms() const; + void set_lns_time_limit_ms(::google::protobuf::int64 value); + + // optional bool use_light_propagation = 11; + void clear_use_light_propagation(); + static const int kUseLightPropagationFieldNumber = 11; + bool use_light_propagation() const; + void set_use_light_propagation(bool value); + + // optional bool fingerprint_arc_cost_evaluators = 12; + void clear_fingerprint_arc_cost_evaluators(); + static const int kFingerprintArcCostEvaluatorsFieldNumber = 12; + bool fingerprint_arc_cost_evaluators() const; + void set_fingerprint_arc_cost_evaluators(bool value); + + // optional bool log_search = 13; + void clear_log_search(); + static const int kLogSearchFieldNumber = 13; + bool log_search() const; + void set_log_search(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.RoutingSearchParameters) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + int first_solution_strategy_; + int local_search_metaheuristic_; + ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators* local_search_operators_; + double guided_local_search_lambda_coefficient_; + ::google::protobuf::int64 optimization_step_; + ::google::protobuf::int64 solution_limit_; + bool use_filtered_first_solution_strategy_; + bool use_depth_first_search_; + bool use_light_propagation_; + bool fingerprint_arc_cost_evaluators_; + bool log_search_; + ::google::protobuf::int64 time_limit_ms_; + ::google::protobuf::int64 lns_time_limit_ms_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + + void InitAsDefaultInstance(); + static RoutingSearchParameters* default_instance_; +}; +// ------------------------------------------------------------------- + +class RoutingModelParameters : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.RoutingModelParameters) */ { + public: + RoutingModelParameters(); + virtual ~RoutingModelParameters(); + + RoutingModelParameters(const RoutingModelParameters& from); + + inline RoutingModelParameters& operator=(const RoutingModelParameters& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RoutingModelParameters& default_instance(); + + void Swap(RoutingModelParameters* other); + + // implements Message ---------------------------------------------- + + inline RoutingModelParameters* New() const { return New(NULL); } + + RoutingModelParameters* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RoutingModelParameters& from); + void MergeFrom(const RoutingModelParameters& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(RoutingModelParameters* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .operations_research.ConstraintSolverParameters solver_parameters = 1; + bool has_solver_parameters() const; + void clear_solver_parameters(); + static const int kSolverParametersFieldNumber = 1; + const ::operations_research::ConstraintSolverParameters& solver_parameters() const; + ::operations_research::ConstraintSolverParameters* mutable_solver_parameters(); + ::operations_research::ConstraintSolverParameters* release_solver_parameters(); + void set_allocated_solver_parameters(::operations_research::ConstraintSolverParameters* solver_parameters); + + // optional bool reduce_vehicle_cost_model = 2; + void clear_reduce_vehicle_cost_model(); + static const int kReduceVehicleCostModelFieldNumber = 2; + bool reduce_vehicle_cost_model() const; + void set_reduce_vehicle_cost_model(bool value); + + // optional int32 max_callback_cache_size = 3; + void clear_max_callback_cache_size(); + static const int kMaxCallbackCacheSizeFieldNumber = 3; + ::google::protobuf::int32 max_callback_cache_size() const; + void set_max_callback_cache_size(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:operations_research.RoutingModelParameters) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::operations_research::ConstraintSolverParameters* solver_parameters_; + bool reduce_vehicle_cost_model_; + ::google::protobuf::int32 max_callback_cache_size_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto(); + + void InitAsDefaultInstance(); + static RoutingModelParameters* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// RoutingSearchParameters_LocalSearchNeighborhoodOperators + +// optional bool use_relocate = 1; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_relocate() { + use_relocate_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_relocate() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_relocate) + return use_relocate_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_relocate(bool value) { + + use_relocate_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_relocate) +} + +// optional bool use_relocate_pair = 2; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_relocate_pair() { + use_relocate_pair_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_relocate_pair() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_relocate_pair) + return use_relocate_pair_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_relocate_pair(bool value) { + + use_relocate_pair_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_relocate_pair) +} + +// optional bool use_relocate_neighbors = 3; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_relocate_neighbors() { + use_relocate_neighbors_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_relocate_neighbors() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_relocate_neighbors) + return use_relocate_neighbors_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_relocate_neighbors(bool value) { + + use_relocate_neighbors_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_relocate_neighbors) +} + +// optional bool use_exchange = 4; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_exchange() { + use_exchange_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_exchange() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_exchange) + return use_exchange_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_exchange(bool value) { + + use_exchange_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_exchange) +} + +// optional bool use_cross = 5; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_cross() { + use_cross_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_cross() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_cross) + return use_cross_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_cross(bool value) { + + use_cross_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_cross) +} + +// optional bool use_cross_exchange = 6; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_cross_exchange() { + use_cross_exchange_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_cross_exchange() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_cross_exchange) + return use_cross_exchange_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_cross_exchange(bool value) { + + use_cross_exchange_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_cross_exchange) +} + +// optional bool use_two_opt = 7; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_two_opt() { + use_two_opt_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_two_opt() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_two_opt) + return use_two_opt_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_two_opt(bool value) { + + use_two_opt_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_two_opt) +} + +// optional bool use_or_opt = 8; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_or_opt() { + use_or_opt_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_or_opt() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_or_opt) + return use_or_opt_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_or_opt(bool value) { + + use_or_opt_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_or_opt) +} + +// optional bool use_lin_kernighan = 9; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_lin_kernighan() { + use_lin_kernighan_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_lin_kernighan() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_lin_kernighan) + return use_lin_kernighan_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_lin_kernighan(bool value) { + + use_lin_kernighan_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_lin_kernighan) +} + +// optional bool use_tsp_opt = 10; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_tsp_opt() { + use_tsp_opt_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_tsp_opt() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_tsp_opt) + return use_tsp_opt_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_tsp_opt(bool value) { + + use_tsp_opt_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_tsp_opt) +} + +// optional bool use_make_active = 11; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_make_active() { + use_make_active_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_make_active() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_make_active) + return use_make_active_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_make_active(bool value) { + + use_make_active_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_make_active) +} + +// optional bool use_relocate_and_make_active = 21; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_relocate_and_make_active() { + use_relocate_and_make_active_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_relocate_and_make_active() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_relocate_and_make_active) + return use_relocate_and_make_active_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_relocate_and_make_active(bool value) { + + use_relocate_and_make_active_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_relocate_and_make_active) +} + +// optional bool use_make_inactive = 12; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_make_inactive() { + use_make_inactive_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_make_inactive() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_make_inactive) + return use_make_inactive_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_make_inactive(bool value) { + + use_make_inactive_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_make_inactive) +} + +// optional bool use_make_chain_inactive = 13; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_make_chain_inactive() { + use_make_chain_inactive_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_make_chain_inactive() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_make_chain_inactive) + return use_make_chain_inactive_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_make_chain_inactive(bool value) { + + use_make_chain_inactive_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_make_chain_inactive) +} + +// optional bool use_swap_active = 14; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_swap_active() { + use_swap_active_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_swap_active() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_swap_active) + return use_swap_active_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_swap_active(bool value) { + + use_swap_active_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_swap_active) +} + +// optional bool use_extended_swap_active = 15; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_extended_swap_active() { + use_extended_swap_active_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_extended_swap_active() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_extended_swap_active) + return use_extended_swap_active_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_extended_swap_active(bool value) { + + use_extended_swap_active_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_extended_swap_active) +} + +// optional bool use_node_pair_swap_active = 20; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_node_pair_swap_active() { + use_node_pair_swap_active_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_node_pair_swap_active() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_node_pair_swap_active) + return use_node_pair_swap_active_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_node_pair_swap_active(bool value) { + + use_node_pair_swap_active_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_node_pair_swap_active) +} + +// optional bool use_path_lns = 16; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_path_lns() { + use_path_lns_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_path_lns() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_path_lns) + return use_path_lns_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_path_lns(bool value) { + + use_path_lns_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_path_lns) +} + +// optional bool use_full_path_lns = 17; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_full_path_lns() { + use_full_path_lns_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_full_path_lns() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_full_path_lns) + return use_full_path_lns_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_full_path_lns(bool value) { + + use_full_path_lns_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_full_path_lns) +} + +// optional bool use_tsp_lns = 18; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_tsp_lns() { + use_tsp_lns_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_tsp_lns() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_tsp_lns) + return use_tsp_lns_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_tsp_lns(bool value) { + + use_tsp_lns_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_tsp_lns) +} + +// optional bool use_inactive_lns = 19; +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::clear_use_inactive_lns() { + use_inactive_lns_ = false; +} +inline bool RoutingSearchParameters_LocalSearchNeighborhoodOperators::use_inactive_lns() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_inactive_lns) + return use_inactive_lns_; +} +inline void RoutingSearchParameters_LocalSearchNeighborhoodOperators::set_use_inactive_lns(bool value) { + + use_inactive_lns_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators.use_inactive_lns) +} + +// ------------------------------------------------------------------- + +// RoutingSearchParameters + +// optional .operations_research.FirstSolutionStrategy.Value first_solution_strategy = 1; +inline void RoutingSearchParameters::clear_first_solution_strategy() { + first_solution_strategy_ = 0; +} +inline ::operations_research::FirstSolutionStrategy_Value RoutingSearchParameters::first_solution_strategy() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.first_solution_strategy) + return static_cast< ::operations_research::FirstSolutionStrategy_Value >(first_solution_strategy_); +} +inline void RoutingSearchParameters::set_first_solution_strategy(::operations_research::FirstSolutionStrategy_Value value) { + + first_solution_strategy_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.first_solution_strategy) +} + +// optional bool use_filtered_first_solution_strategy = 2; +inline void RoutingSearchParameters::clear_use_filtered_first_solution_strategy() { + use_filtered_first_solution_strategy_ = false; +} +inline bool RoutingSearchParameters::use_filtered_first_solution_strategy() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.use_filtered_first_solution_strategy) + return use_filtered_first_solution_strategy_; +} +inline void RoutingSearchParameters::set_use_filtered_first_solution_strategy(bool value) { + + use_filtered_first_solution_strategy_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.use_filtered_first_solution_strategy) +} + +// optional .operations_research.RoutingSearchParameters.LocalSearchNeighborhoodOperators local_search_operators = 3; +inline bool RoutingSearchParameters::has_local_search_operators() const { + return !_is_default_instance_ && local_search_operators_ != NULL; +} +inline void RoutingSearchParameters::clear_local_search_operators() { + if (GetArenaNoVirtual() == NULL && local_search_operators_ != NULL) delete local_search_operators_; + local_search_operators_ = NULL; +} +inline const ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators& RoutingSearchParameters::local_search_operators() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.local_search_operators) + return local_search_operators_ != NULL ? *local_search_operators_ : *default_instance_->local_search_operators_; +} +inline ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators* RoutingSearchParameters::mutable_local_search_operators() { + + if (local_search_operators_ == NULL) { + local_search_operators_ = new ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators; + } + // @@protoc_insertion_point(field_mutable:operations_research.RoutingSearchParameters.local_search_operators) + return local_search_operators_; +} +inline ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators* RoutingSearchParameters::release_local_search_operators() { + // @@protoc_insertion_point(field_release:operations_research.RoutingSearchParameters.local_search_operators) + + ::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators* temp = local_search_operators_; + local_search_operators_ = NULL; + return temp; +} +inline void RoutingSearchParameters::set_allocated_local_search_operators(::operations_research::RoutingSearchParameters_LocalSearchNeighborhoodOperators* local_search_operators) { + delete local_search_operators_; + local_search_operators_ = local_search_operators; + if (local_search_operators) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:operations_research.RoutingSearchParameters.local_search_operators) +} + +// optional .operations_research.LocalSearchMetaheuristic.Value local_search_metaheuristic = 4; +inline void RoutingSearchParameters::clear_local_search_metaheuristic() { + local_search_metaheuristic_ = 0; +} +inline ::operations_research::LocalSearchMetaheuristic_Value RoutingSearchParameters::local_search_metaheuristic() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.local_search_metaheuristic) + return static_cast< ::operations_research::LocalSearchMetaheuristic_Value >(local_search_metaheuristic_); +} +inline void RoutingSearchParameters::set_local_search_metaheuristic(::operations_research::LocalSearchMetaheuristic_Value value) { + + local_search_metaheuristic_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.local_search_metaheuristic) +} + +// optional double guided_local_search_lambda_coefficient = 5; +inline void RoutingSearchParameters::clear_guided_local_search_lambda_coefficient() { + guided_local_search_lambda_coefficient_ = 0; +} +inline double RoutingSearchParameters::guided_local_search_lambda_coefficient() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.guided_local_search_lambda_coefficient) + return guided_local_search_lambda_coefficient_; +} +inline void RoutingSearchParameters::set_guided_local_search_lambda_coefficient(double value) { + + guided_local_search_lambda_coefficient_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.guided_local_search_lambda_coefficient) +} + +// optional bool use_depth_first_search = 6; +inline void RoutingSearchParameters::clear_use_depth_first_search() { + use_depth_first_search_ = false; +} +inline bool RoutingSearchParameters::use_depth_first_search() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.use_depth_first_search) + return use_depth_first_search_; +} +inline void RoutingSearchParameters::set_use_depth_first_search(bool value) { + + use_depth_first_search_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.use_depth_first_search) +} + +// optional int64 optimization_step = 7; +inline void RoutingSearchParameters::clear_optimization_step() { + optimization_step_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 RoutingSearchParameters::optimization_step() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.optimization_step) + return optimization_step_; +} +inline void RoutingSearchParameters::set_optimization_step(::google::protobuf::int64 value) { + + optimization_step_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.optimization_step) +} + +// optional int64 solution_limit = 8; +inline void RoutingSearchParameters::clear_solution_limit() { + solution_limit_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 RoutingSearchParameters::solution_limit() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.solution_limit) + return solution_limit_; +} +inline void RoutingSearchParameters::set_solution_limit(::google::protobuf::int64 value) { + + solution_limit_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.solution_limit) +} + +// optional int64 time_limit_ms = 9; +inline void RoutingSearchParameters::clear_time_limit_ms() { + time_limit_ms_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 RoutingSearchParameters::time_limit_ms() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.time_limit_ms) + return time_limit_ms_; +} +inline void RoutingSearchParameters::set_time_limit_ms(::google::protobuf::int64 value) { + + time_limit_ms_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.time_limit_ms) +} + +// optional int64 lns_time_limit_ms = 10; +inline void RoutingSearchParameters::clear_lns_time_limit_ms() { + lns_time_limit_ms_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 RoutingSearchParameters::lns_time_limit_ms() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.lns_time_limit_ms) + return lns_time_limit_ms_; +} +inline void RoutingSearchParameters::set_lns_time_limit_ms(::google::protobuf::int64 value) { + + lns_time_limit_ms_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.lns_time_limit_ms) +} + +// optional bool use_light_propagation = 11; +inline void RoutingSearchParameters::clear_use_light_propagation() { + use_light_propagation_ = false; +} +inline bool RoutingSearchParameters::use_light_propagation() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.use_light_propagation) + return use_light_propagation_; +} +inline void RoutingSearchParameters::set_use_light_propagation(bool value) { + + use_light_propagation_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.use_light_propagation) +} + +// optional bool fingerprint_arc_cost_evaluators = 12; +inline void RoutingSearchParameters::clear_fingerprint_arc_cost_evaluators() { + fingerprint_arc_cost_evaluators_ = false; +} +inline bool RoutingSearchParameters::fingerprint_arc_cost_evaluators() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.fingerprint_arc_cost_evaluators) + return fingerprint_arc_cost_evaluators_; +} +inline void RoutingSearchParameters::set_fingerprint_arc_cost_evaluators(bool value) { + + fingerprint_arc_cost_evaluators_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.fingerprint_arc_cost_evaluators) +} + +// optional bool log_search = 13; +inline void RoutingSearchParameters::clear_log_search() { + log_search_ = false; +} +inline bool RoutingSearchParameters::log_search() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingSearchParameters.log_search) + return log_search_; +} +inline void RoutingSearchParameters::set_log_search(bool value) { + + log_search_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingSearchParameters.log_search) +} + +// ------------------------------------------------------------------- + +// RoutingModelParameters + +// optional .operations_research.ConstraintSolverParameters solver_parameters = 1; +inline bool RoutingModelParameters::has_solver_parameters() const { + return !_is_default_instance_ && solver_parameters_ != NULL; +} +inline void RoutingModelParameters::clear_solver_parameters() { + if (GetArenaNoVirtual() == NULL && solver_parameters_ != NULL) delete solver_parameters_; + solver_parameters_ = NULL; +} +inline const ::operations_research::ConstraintSolverParameters& RoutingModelParameters::solver_parameters() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingModelParameters.solver_parameters) + return solver_parameters_ != NULL ? *solver_parameters_ : *default_instance_->solver_parameters_; +} +inline ::operations_research::ConstraintSolverParameters* RoutingModelParameters::mutable_solver_parameters() { + + if (solver_parameters_ == NULL) { + solver_parameters_ = new ::operations_research::ConstraintSolverParameters; + } + // @@protoc_insertion_point(field_mutable:operations_research.RoutingModelParameters.solver_parameters) + return solver_parameters_; +} +inline ::operations_research::ConstraintSolverParameters* RoutingModelParameters::release_solver_parameters() { + // @@protoc_insertion_point(field_release:operations_research.RoutingModelParameters.solver_parameters) + + ::operations_research::ConstraintSolverParameters* temp = solver_parameters_; + solver_parameters_ = NULL; + return temp; +} +inline void RoutingModelParameters::set_allocated_solver_parameters(::operations_research::ConstraintSolverParameters* solver_parameters) { + delete solver_parameters_; + solver_parameters_ = solver_parameters; + if (solver_parameters) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:operations_research.RoutingModelParameters.solver_parameters) +} + +// optional bool reduce_vehicle_cost_model = 2; +inline void RoutingModelParameters::clear_reduce_vehicle_cost_model() { + reduce_vehicle_cost_model_ = false; +} +inline bool RoutingModelParameters::reduce_vehicle_cost_model() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingModelParameters.reduce_vehicle_cost_model) + return reduce_vehicle_cost_model_; +} +inline void RoutingModelParameters::set_reduce_vehicle_cost_model(bool value) { + + reduce_vehicle_cost_model_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingModelParameters.reduce_vehicle_cost_model) +} + +// optional int32 max_callback_cache_size = 3; +inline void RoutingModelParameters::clear_max_callback_cache_size() { + max_callback_cache_size_ = 0; +} +inline ::google::protobuf::int32 RoutingModelParameters::max_callback_cache_size() const { + // @@protoc_insertion_point(field_get:operations_research.RoutingModelParameters.max_callback_cache_size) + return max_callback_cache_size_; +} +inline void RoutingModelParameters::set_max_callback_cache_size(::google::protobuf::int32 value) { + + max_callback_cache_size_ = value; + // @@protoc_insertion_point(field_set:operations_research.RoutingModelParameters.max_callback_cache_size) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fconstraint_5fsolver_2frouting_5fparameters_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/constraint_solver/routing_types.h b/thirdparty/linux/include/ortools/constraint_solver/routing_types.h new file mode 100644 index 0000000..cbace25 --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/routing_types.h @@ -0,0 +1,49 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_TYPES_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_TYPES_H_ + +#include +#include +#include "ortools/base/callback.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/int_type.h" + +namespace operations_research { + +// Defining common types used in the routing library outside the main +// RoutingModel class has several purposes: +// 1) It allows some small libraries to avoid a dependency on routing.{h,cc}, +// eg. routing_neighborhoods.h. +// 2) It allows an easier wrapping via SWIG, which can have issues with +// intra-class types. +// +// Users that depend on routing.{h,cc} should just use the +// RoutingModel:: equivalent, eg. RoutingModel::NodeIndex. +DEFINE_INT_TYPE(RoutingNodeIndex, int); +DEFINE_INT_TYPE(RoutingCostClassIndex, int); +DEFINE_INT_TYPE(RoutingDimensionIndex, int); +DEFINE_INT_TYPE(RoutingDisjunctionIndex, int); +DEFINE_INT_TYPE(RoutingVehicleClassIndex, int); + +typedef ResultCallback2 + RoutingNodeEvaluator2; +typedef std::function RoutingTransitEvaluator2; +// NOTE(user): keep the "> >" for SWIG. +typedef std::pair, std::vector > RoutingNodePair; +typedef std::vector RoutingNodePairs; + +} // namespace operations_research + +#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_TYPES_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/sat_constraint.h b/thirdparty/linux/include/ortools/constraint_solver/sat_constraint.h new file mode 100644 index 0000000..3b20d27 --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/sat_constraint.h @@ -0,0 +1,289 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains the definition and implementation of a constraint +// encapsulating a full SAT solver. Such a constraint can basically propagates +// any relationship between Boolean variables that can be expressed using +// clauses or pseudo-Boolean constraint. +// +// It also contains some utility classes to map an IntVar to a set of Boolean +// variables. Using this, a lot of constraints on integer variables can be dealt +// with quite efficiently by just adding their encoding to the underlying sat +// solver (for instance a table constraint propagated this way should be really +// efficient). +// +// TODO(user): Extend so that the constraint solver can use the conflict +// learning mecanism present in the underlying SAT solver. + +#ifndef OR_TOOLS_CONSTRAINT_SOLVER_SAT_CONSTRAINT_H_ +#define OR_TOOLS_CONSTRAINT_SOLVER_SAT_CONSTRAINT_H_ + +#include +#include + +#include "ortools/base/map_util.h" +#include "ortools/base/hash.h" +#include "ortools/constraint_solver/constraint_solver.h" +#include "ortools/constraint_solver/constraint_solveri.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/util/tuple_set.h" + +namespace operations_research { + +// Given an IntVar, this class fetches the sat::Literal associated with +// the fact that the variable is equal or not to a given value in its domain. +class IntVarLiteralGetter { + public: + // The mapping of IntVar values to Boolean variables is as follow: + // - We always assume the IntVar to take all possible values in [min, max]. + // - We create one Boolean variable per value: {i, i + 1, ..., i + max - min}. + // - If size([min, max] == 2) then we just use one variable i that represent + // the fact that the variable is bound to its min value. + // + // TODO(user): Support holes in the interval. + IntVarLiteralGetter(sat::BooleanVariable i, int64 min, int64 max) + : first_variable_(i), min_value_(min), max_value_(max) {} + + // Returns the literal encoding (var == value). + sat::Literal IsEqualTo(int64 value) const { + if (max_value_ == min_value_ + 1) { + return sat::Literal(first_variable_, value == min_value_); + } else { + return sat::Literal(first_variable_ + value - min_value_, true); + } + } + + // Returns the literal encoding (var != value). + sat::Literal IsNotEqualTo(int64 value) const { + return IsEqualTo(value).Negated(); + } + + // Returns the number of Boolean variables used for the encoding. + int NumVariableUsed() const { + return (max_value_ == min_value_ + 1) ? 1 : max_value_ - min_value_ + 1; + } + + private: + // These should really be const, but this causes problem with our open source + // build because we use std::vector. + sat::BooleanVariable first_variable_; + int64 min_value_; + int64 max_value_; +}; + +// Creates a new set of Boolean variables for each registered IntVar. These +// variables will encode for each possible value, whether or not the IntVar is +// fixed to this value or not. +// +// This class also provide utility to: +// - Find the Boolean variable associated to an IntVar value. +// - Find the corresponding IntVar value from the Boolean variable. +class BooleanVariableManager { + public: + explicit BooleanVariableManager(sat::SatSolver* solver) : solver_(solver) {} + + // If not already done, this register the given IntVar with this manager and + // creates the underlying Boolean variables in the SAT solver. + // Returns the IntVar registration index. + int RegisterIntVar(IntVar* int_var); + + // Returns the list of registered IntVar. + // Note that they are ordered by registration index. + const std::vector& RegisteredIntVars() const { + return registered_int_vars_; + } + + // Returns the IntVarLiteralGetter associated with the IntVar of given + // registration index. The reg_index can be retrieved with RegisterIntVar() + // or by iterating over RegisteredIntVars(). It must be valid. + const IntVarLiteralGetter& AssociatedBooleanVariables(int reg_index) const { + return associated_variables_[reg_index]; + } + + // A Boolean variable associated to an IntVar value means (var == value) if + // it is true. This returns the IntVar and the value. If the pointer is + // nullptr, then this variable index wasn't created by this class. + std::pair BooleanVariableMeaning( + sat::BooleanVariable var) const { + DCHECK_GE(var, 0); + // This test is necessary because the SAT solver may know of variables not + // registered by this class. + if (var >= variable_meaning_.size()) return std::make_pair(nullptr, 0); + return variable_meaning_[var]; + } + + private: + sat::SatSolver* solver_; + std::vector registered_int_vars_; + std::vector associated_variables_; + std::unordered_map registration_index_map_; + ITIVector> variable_meaning_; + DISALLOW_COPY_AND_ASSIGN(BooleanVariableManager); +}; + +// The actual constraint encapsulating the SAT solver. +class SatConstraint : public Constraint { + public: + explicit SatConstraint(Solver* const solver) + : Constraint(solver), + variable_manager_(&sat_solver_), + propagated_trail_index_(0), + rev_decision_level_(0) {} + + // Register the demons. + void Post() override { + int i = 0; + for (IntVar* int_var : variable_manager_.RegisteredIntVars()) { + int_var->WhenDomain(MakeConstraintDemon1( + solver(), this, &SatConstraint::Enqueue, "Enqueue", i)); + ++i; + } + } + + // Initial propagation. + void InitialPropagate() override { + if (sat_solver_.IsModelUnsat()) solver()->Fail(); + for (int i = 0; i < variable_manager_.RegisteredIntVars().size(); ++i) { + Enqueue(i); + } + } + + // Returns the underlying solver and variable manager + // These classes are used to create and add new constraint to the SAT solver. + // Note that any mapping IntVar -> Boolean variable must be done with this + // variable manager for the SatConstraint to properly push back to the + // constraint solver the propagated Boolean variables. + sat::SatSolver* SatSolver() { return &sat_solver_; } + BooleanVariableManager* VariableManager() { return &variable_manager_; } + + private: + // Push variable propagated from sat to the constraint solver. + void PropagateFromSatToCp() { + const sat::Trail& trail = sat_solver_.LiteralTrail(); + while (propagated_trail_index_ < trail.Index()) { + const sat::Literal literal = trail[propagated_trail_index_]; + const sat::BooleanVariable var = literal.Variable(); + if (trail.AssignmentType(var) != sat::AssignmentType::kSearchDecision) { + std::pair p = + variable_manager_.BooleanVariableMeaning(var); + IntVar* int_var = p.first; + const int64 value = p.second; + if (int_var != nullptr) { + if (literal.IsPositive()) { + int_var->SetValue(value); + } else { + int_var->RemoveValue(value); + } + } + } + ++propagated_trail_index_; + } + } + + // Called when more information is known on the IntVar with given registration + // index in the BooleanVariableManager. + void Enqueue(int reg_index) { + if (sat_solver_.CurrentDecisionLevel() > rev_decision_level_.Value()) { + // The constraint solver backtracked. Synchronise the state. + sat_solver_.Backtrack(rev_decision_level_.Value()); + propagated_trail_index_ = + std::min(propagated_trail_index_, sat_solver_.LiteralTrail().Index()); + } + + const IntVar* int_var = variable_manager_.RegisteredIntVars()[reg_index]; + const IntVarLiteralGetter literal_getter = + variable_manager_.AssociatedBooleanVariables(reg_index); + + if (int_var->Bound()) { + if (!EnqueueLiteral(literal_getter.IsEqualTo(int_var->Value()))) { + solver()->Fail(); + } + } else { + const int64 vmin = int_var->Min(); + for (int64 value = int_var->OldMin(); value < vmin; ++value) { + if (!EnqueueLiteral(literal_getter.IsNotEqualTo(value))) { + solver()->Fail(); + } + } + + // TODO(user): Investigate caching the hole iterator. + std::unique_ptr it(int_var->MakeHoleIterator(false)); + for (const int64 value : InitAndGetValues(it.get())) { + if (!EnqueueLiteral(literal_getter.IsNotEqualTo(value))) { + solver()->Fail(); + } + } + const int64 old_max = int_var->OldMax(); + for (int64 value = int_var->Max() + 1; value <= old_max; ++value) { + if (!EnqueueLiteral(literal_getter.IsNotEqualTo(value))) { + solver()->Fail(); + } + } + } + + // TODO(user): Use a constraint solver mechanism to just do that once after + // all the possible Enqueue() have been processed? see delayed demon example + // in expr_array.cc + PropagateFromSatToCp(); + rev_decision_level_.SetValue(solver(), sat_solver_.CurrentDecisionLevel()); + } + + // Try to Enqueue the given literal on the sat_trail. Returns false in case of + // conflict, true otherwise. Note that the literal is only enqueued if it is + // not already set. + bool EnqueueLiteral(sat::Literal literal) { + if (sat_solver_.Assignment().LiteralIsFalse(literal)) return false; + if (sat_solver_.Assignment().LiteralIsTrue(literal)) return true; + if (sat_solver_.EnqueueDecisionIfNotConflicting(literal)) return true; + return false; + } + + sat::SatSolver sat_solver_; + BooleanVariableManager variable_manager_; + int propagated_trail_index_; + Rev rev_decision_level_; + + DISALLOW_COPY_AND_ASSIGN(SatConstraint); +}; + +class SatTableConstraint : public Constraint { + public: + // Note that we need to copy the arguments. + SatTableConstraint(Solver* s, const std::vector& vars, + const IntTupleSet& tuples) + : Constraint(s), vars_(vars), tuples_(tuples), sat_constraint_(s) {} + + void Post() override; + void InitialPropagate() override { sat_constraint_.InitialPropagate(); } + + private: + const std::vector vars_; + const IntTupleSet tuples_; + + // TODO(user): share this between different constraint. We need to pay + // attention and call Post()/InitialPropagate() after all other constraint + // have been posted though. + SatConstraint sat_constraint_; + + DISALLOW_COPY_AND_ASSIGN(SatTableConstraint); +}; + +inline Constraint* BuildSatTableConstraint(Solver* solver, + const std::vector& vars, + const IntTupleSet& tuples) { + return solver->RevAlloc(new SatTableConstraint(solver, vars, tuples)); +} + +} // namespace operations_research + +#endif // OR_TOOLS_CONSTRAINT_SOLVER_SAT_CONSTRAINT_H_ diff --git a/thirdparty/linux/include/ortools/constraint_solver/search_limit.pb.h b/thirdparty/linux/include/ortools/constraint_solver/search_limit.pb.h new file mode 100644 index 0000000..cb7d8d7 --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/search_limit.pb.h @@ -0,0 +1,258 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/constraint_solver/search_limit.proto + +#ifndef PROTOBUF_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto__INCLUDED +#define PROTOBUF_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto(); +void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto(); +void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto(); + +class SearchLimitParameters; + +// =================================================================== + +class SearchLimitParameters : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.SearchLimitParameters) */ { + public: + SearchLimitParameters(); + virtual ~SearchLimitParameters(); + + SearchLimitParameters(const SearchLimitParameters& from); + + inline SearchLimitParameters& operator=(const SearchLimitParameters& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SearchLimitParameters& default_instance(); + + void Swap(SearchLimitParameters* other); + + // implements Message ---------------------------------------------- + + inline SearchLimitParameters* New() const { return New(NULL); } + + SearchLimitParameters* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SearchLimitParameters& from); + void MergeFrom(const SearchLimitParameters& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(SearchLimitParameters* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 time = 1; + void clear_time(); + static const int kTimeFieldNumber = 1; + ::google::protobuf::int64 time() const; + void set_time(::google::protobuf::int64 value); + + // optional int64 branches = 2; + void clear_branches(); + static const int kBranchesFieldNumber = 2; + ::google::protobuf::int64 branches() const; + void set_branches(::google::protobuf::int64 value); + + // optional int64 failures = 3; + void clear_failures(); + static const int kFailuresFieldNumber = 3; + ::google::protobuf::int64 failures() const; + void set_failures(::google::protobuf::int64 value); + + // optional int64 solutions = 4; + void clear_solutions(); + static const int kSolutionsFieldNumber = 4; + ::google::protobuf::int64 solutions() const; + void set_solutions(::google::protobuf::int64 value); + + // optional bool smart_time_check = 5; + void clear_smart_time_check(); + static const int kSmartTimeCheckFieldNumber = 5; + bool smart_time_check() const; + void set_smart_time_check(bool value); + + // optional bool cumulative = 6; + void clear_cumulative(); + static const int kCumulativeFieldNumber = 6; + bool cumulative() const; + void set_cumulative(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.SearchLimitParameters) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int64 time_; + ::google::protobuf::int64 branches_; + ::google::protobuf::int64 failures_; + ::google::protobuf::int64 solutions_; + bool smart_time_check_; + bool cumulative_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto(); + + void InitAsDefaultInstance(); + static SearchLimitParameters* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// SearchLimitParameters + +// optional int64 time = 1; +inline void SearchLimitParameters::clear_time() { + time_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 SearchLimitParameters::time() const { + // @@protoc_insertion_point(field_get:operations_research.SearchLimitParameters.time) + return time_; +} +inline void SearchLimitParameters::set_time(::google::protobuf::int64 value) { + + time_ = value; + // @@protoc_insertion_point(field_set:operations_research.SearchLimitParameters.time) +} + +// optional int64 branches = 2; +inline void SearchLimitParameters::clear_branches() { + branches_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 SearchLimitParameters::branches() const { + // @@protoc_insertion_point(field_get:operations_research.SearchLimitParameters.branches) + return branches_; +} +inline void SearchLimitParameters::set_branches(::google::protobuf::int64 value) { + + branches_ = value; + // @@protoc_insertion_point(field_set:operations_research.SearchLimitParameters.branches) +} + +// optional int64 failures = 3; +inline void SearchLimitParameters::clear_failures() { + failures_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 SearchLimitParameters::failures() const { + // @@protoc_insertion_point(field_get:operations_research.SearchLimitParameters.failures) + return failures_; +} +inline void SearchLimitParameters::set_failures(::google::protobuf::int64 value) { + + failures_ = value; + // @@protoc_insertion_point(field_set:operations_research.SearchLimitParameters.failures) +} + +// optional int64 solutions = 4; +inline void SearchLimitParameters::clear_solutions() { + solutions_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 SearchLimitParameters::solutions() const { + // @@protoc_insertion_point(field_get:operations_research.SearchLimitParameters.solutions) + return solutions_; +} +inline void SearchLimitParameters::set_solutions(::google::protobuf::int64 value) { + + solutions_ = value; + // @@protoc_insertion_point(field_set:operations_research.SearchLimitParameters.solutions) +} + +// optional bool smart_time_check = 5; +inline void SearchLimitParameters::clear_smart_time_check() { + smart_time_check_ = false; +} +inline bool SearchLimitParameters::smart_time_check() const { + // @@protoc_insertion_point(field_get:operations_research.SearchLimitParameters.smart_time_check) + return smart_time_check_; +} +inline void SearchLimitParameters::set_smart_time_check(bool value) { + + smart_time_check_ = value; + // @@protoc_insertion_point(field_set:operations_research.SearchLimitParameters.smart_time_check) +} + +// optional bool cumulative = 6; +inline void SearchLimitParameters::clear_cumulative() { + cumulative_ = false; +} +inline bool SearchLimitParameters::cumulative() const { + // @@protoc_insertion_point(field_get:operations_research.SearchLimitParameters.cumulative) + return cumulative_; +} +inline void SearchLimitParameters::set_cumulative(bool value) { + + cumulative_ = value; + // @@protoc_insertion_point(field_set:operations_research.SearchLimitParameters.cumulative) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fconstraint_5fsolver_2fsearch_5flimit_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/constraint_solver/solver_parameters.pb.h b/thirdparty/linux/include/ortools/constraint_solver/solver_parameters.pb.h new file mode 100644 index 0000000..264fbd3 --- /dev/null +++ b/thirdparty/linux/include/ortools/constraint_solver/solver_parameters.pb.h @@ -0,0 +1,894 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/constraint_solver/solver_parameters.proto + +#ifndef PROTOBUF_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto__INCLUDED +#define PROTOBUF_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto(); +void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto(); +void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto(); + +class ConstraintSolverParameters; + +enum ConstraintSolverParameters_TrailCompression { + ConstraintSolverParameters_TrailCompression_NO_COMPRESSION = 0, + ConstraintSolverParameters_TrailCompression_COMPRESS_WITH_ZLIB = 1, + ConstraintSolverParameters_TrailCompression_ConstraintSolverParameters_TrailCompression_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + ConstraintSolverParameters_TrailCompression_ConstraintSolverParameters_TrailCompression_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +bool ConstraintSolverParameters_TrailCompression_IsValid(int value); +const ConstraintSolverParameters_TrailCompression ConstraintSolverParameters_TrailCompression_TrailCompression_MIN = ConstraintSolverParameters_TrailCompression_NO_COMPRESSION; +const ConstraintSolverParameters_TrailCompression ConstraintSolverParameters_TrailCompression_TrailCompression_MAX = ConstraintSolverParameters_TrailCompression_COMPRESS_WITH_ZLIB; +const int ConstraintSolverParameters_TrailCompression_TrailCompression_ARRAYSIZE = ConstraintSolverParameters_TrailCompression_TrailCompression_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ConstraintSolverParameters_TrailCompression_descriptor(); +inline const ::std::string& ConstraintSolverParameters_TrailCompression_Name(ConstraintSolverParameters_TrailCompression value) { + return ::google::protobuf::internal::NameOfEnum( + ConstraintSolverParameters_TrailCompression_descriptor(), value); +} +inline bool ConstraintSolverParameters_TrailCompression_Parse( + const ::std::string& name, ConstraintSolverParameters_TrailCompression* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ConstraintSolverParameters_TrailCompression_descriptor(), name, value); +} +// =================================================================== + +class ConstraintSolverParameters : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.ConstraintSolverParameters) */ { + public: + ConstraintSolverParameters(); + virtual ~ConstraintSolverParameters(); + + ConstraintSolverParameters(const ConstraintSolverParameters& from); + + inline ConstraintSolverParameters& operator=(const ConstraintSolverParameters& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ConstraintSolverParameters& default_instance(); + + void Swap(ConstraintSolverParameters* other); + + // implements Message ---------------------------------------------- + + inline ConstraintSolverParameters* New() const { return New(NULL); } + + ConstraintSolverParameters* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ConstraintSolverParameters& from); + void MergeFrom(const ConstraintSolverParameters& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(ConstraintSolverParameters* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef ConstraintSolverParameters_TrailCompression TrailCompression; + static const TrailCompression NO_COMPRESSION = + ConstraintSolverParameters_TrailCompression_NO_COMPRESSION; + static const TrailCompression COMPRESS_WITH_ZLIB = + ConstraintSolverParameters_TrailCompression_COMPRESS_WITH_ZLIB; + static inline bool TrailCompression_IsValid(int value) { + return ConstraintSolverParameters_TrailCompression_IsValid(value); + } + static const TrailCompression TrailCompression_MIN = + ConstraintSolverParameters_TrailCompression_TrailCompression_MIN; + static const TrailCompression TrailCompression_MAX = + ConstraintSolverParameters_TrailCompression_TrailCompression_MAX; + static const int TrailCompression_ARRAYSIZE = + ConstraintSolverParameters_TrailCompression_TrailCompression_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + TrailCompression_descriptor() { + return ConstraintSolverParameters_TrailCompression_descriptor(); + } + static inline const ::std::string& TrailCompression_Name(TrailCompression value) { + return ConstraintSolverParameters_TrailCompression_Name(value); + } + static inline bool TrailCompression_Parse(const ::std::string& name, + TrailCompression* value) { + return ConstraintSolverParameters_TrailCompression_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .operations_research.ConstraintSolverParameters.TrailCompression compress_trail = 1; + void clear_compress_trail(); + static const int kCompressTrailFieldNumber = 1; + ::operations_research::ConstraintSolverParameters_TrailCompression compress_trail() const; + void set_compress_trail(::operations_research::ConstraintSolverParameters_TrailCompression value); + + // optional int32 trail_block_size = 2; + void clear_trail_block_size(); + static const int kTrailBlockSizeFieldNumber = 2; + ::google::protobuf::int32 trail_block_size() const; + void set_trail_block_size(::google::protobuf::int32 value); + + // optional int32 array_split_size = 3; + void clear_array_split_size(); + static const int kArraySplitSizeFieldNumber = 3; + ::google::protobuf::int32 array_split_size() const; + void set_array_split_size(::google::protobuf::int32 value); + + // optional bool store_names = 4; + void clear_store_names(); + static const int kStoreNamesFieldNumber = 4; + bool store_names() const; + void set_store_names(bool value); + + // optional bool name_cast_variables = 5; + void clear_name_cast_variables(); + static const int kNameCastVariablesFieldNumber = 5; + bool name_cast_variables() const; + void set_name_cast_variables(bool value); + + // optional bool name_all_variables = 6; + void clear_name_all_variables(); + static const int kNameAllVariablesFieldNumber = 6; + bool name_all_variables() const; + void set_name_all_variables(bool value); + + // optional bool profile_propagation = 7; + void clear_profile_propagation(); + static const int kProfilePropagationFieldNumber = 7; + bool profile_propagation() const; + void set_profile_propagation(bool value); + + // optional string profile_file = 8; + void clear_profile_file(); + static const int kProfileFileFieldNumber = 8; + const ::std::string& profile_file() const; + void set_profile_file(const ::std::string& value); + void set_profile_file(const char* value); + void set_profile_file(const char* value, size_t size); + ::std::string* mutable_profile_file(); + ::std::string* release_profile_file(); + void set_allocated_profile_file(::std::string* profile_file); + + // optional bool profile_local_search = 16; + void clear_profile_local_search(); + static const int kProfileLocalSearchFieldNumber = 16; + bool profile_local_search() const; + void set_profile_local_search(bool value); + + // optional bool print_local_search_profile = 17; + void clear_print_local_search_profile(); + static const int kPrintLocalSearchProfileFieldNumber = 17; + bool print_local_search_profile() const; + void set_print_local_search_profile(bool value); + + // optional bool trace_propagation = 9; + void clear_trace_propagation(); + static const int kTracePropagationFieldNumber = 9; + bool trace_propagation() const; + void set_trace_propagation(bool value); + + // optional bool trace_search = 10; + void clear_trace_search(); + static const int kTraceSearchFieldNumber = 10; + bool trace_search() const; + void set_trace_search(bool value); + + // optional bool print_model = 11; + void clear_print_model(); + static const int kPrintModelFieldNumber = 11; + bool print_model() const; + void set_print_model(bool value); + + // optional bool print_model_stats = 12; + void clear_print_model_stats(); + static const int kPrintModelStatsFieldNumber = 12; + bool print_model_stats() const; + void set_print_model_stats(bool value); + + // optional bool print_added_constraints = 13; + void clear_print_added_constraints(); + static const int kPrintAddedConstraintsFieldNumber = 13; + bool print_added_constraints() const; + void set_print_added_constraints(bool value); + + // optional string export_file = 14; + void clear_export_file(); + static const int kExportFileFieldNumber = 14; + const ::std::string& export_file() const; + void set_export_file(const ::std::string& value); + void set_export_file(const char* value); + void set_export_file(const char* value, size_t size); + ::std::string* mutable_export_file(); + ::std::string* release_export_file(); + void set_allocated_export_file(::std::string* export_file); + + // optional bool disable_solve = 15; + void clear_disable_solve(); + static const int kDisableSolveFieldNumber = 15; + bool disable_solve() const; + void set_disable_solve(bool value); + + // optional bool use_compact_table = 100; + void clear_use_compact_table(); + static const int kUseCompactTableFieldNumber = 100; + bool use_compact_table() const; + void set_use_compact_table(bool value); + + // optional bool use_small_table = 101; + void clear_use_small_table(); + static const int kUseSmallTableFieldNumber = 101; + bool use_small_table() const; + void set_use_small_table(bool value); + + // optional bool use_sat_table = 102; + void clear_use_sat_table(); + static const int kUseSatTableFieldNumber = 102; + bool use_sat_table() const; + void set_use_sat_table(bool value); + + // optional int32 ac4r_table_threshold = 103; + void clear_ac4r_table_threshold(); + static const int kAc4RTableThresholdFieldNumber = 103; + ::google::protobuf::int32 ac4r_table_threshold() const; + void set_ac4r_table_threshold(::google::protobuf::int32 value); + + // optional bool use_mdd_table = 104; + void clear_use_mdd_table(); + static const int kUseMddTableFieldNumber = 104; + bool use_mdd_table() const; + void set_use_mdd_table(bool value); + + // optional bool use_cumulative_edge_finder = 105; + void clear_use_cumulative_edge_finder(); + static const int kUseCumulativeEdgeFinderFieldNumber = 105; + bool use_cumulative_edge_finder() const; + void set_use_cumulative_edge_finder(bool value); + + // optional bool use_cumulative_time_table = 106; + void clear_use_cumulative_time_table(); + static const int kUseCumulativeTimeTableFieldNumber = 106; + bool use_cumulative_time_table() const; + void set_use_cumulative_time_table(bool value); + + // optional bool use_cumulative_time_table_sync = 112; + void clear_use_cumulative_time_table_sync(); + static const int kUseCumulativeTimeTableSyncFieldNumber = 112; + bool use_cumulative_time_table_sync() const; + void set_use_cumulative_time_table_sync(bool value); + + // optional bool use_sequence_high_demand_tasks = 107; + void clear_use_sequence_high_demand_tasks(); + static const int kUseSequenceHighDemandTasksFieldNumber = 107; + bool use_sequence_high_demand_tasks() const; + void set_use_sequence_high_demand_tasks(bool value); + + // optional bool use_all_possible_disjunctions = 108; + void clear_use_all_possible_disjunctions(); + static const int kUseAllPossibleDisjunctionsFieldNumber = 108; + bool use_all_possible_disjunctions() const; + void set_use_all_possible_disjunctions(bool value); + + // optional int32 max_edge_finder_size = 109; + void clear_max_edge_finder_size(); + static const int kMaxEdgeFinderSizeFieldNumber = 109; + ::google::protobuf::int32 max_edge_finder_size() const; + void set_max_edge_finder_size(::google::protobuf::int32 value); + + // optional bool diffn_use_cumulative = 110; + void clear_diffn_use_cumulative(); + static const int kDiffnUseCumulativeFieldNumber = 110; + bool diffn_use_cumulative() const; + void set_diffn_use_cumulative(bool value); + + // optional bool use_element_rmq = 111; + void clear_use_element_rmq(); + static const int kUseElementRmqFieldNumber = 111; + bool use_element_rmq() const; + void set_use_element_rmq(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.ConstraintSolverParameters) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + int compress_trail_; + ::google::protobuf::int32 trail_block_size_; + ::google::protobuf::int32 array_split_size_; + bool store_names_; + bool name_cast_variables_; + bool name_all_variables_; + bool profile_propagation_; + ::google::protobuf::internal::ArenaStringPtr profile_file_; + bool profile_local_search_; + bool print_local_search_profile_; + bool trace_propagation_; + bool trace_search_; + bool print_model_; + bool print_model_stats_; + bool print_added_constraints_; + bool disable_solve_; + ::google::protobuf::internal::ArenaStringPtr export_file_; + bool use_compact_table_; + bool use_small_table_; + bool use_sat_table_; + bool use_mdd_table_; + ::google::protobuf::int32 ac4r_table_threshold_; + bool use_cumulative_edge_finder_; + bool use_cumulative_time_table_; + bool use_cumulative_time_table_sync_; + bool use_sequence_high_demand_tasks_; + ::google::protobuf::int32 max_edge_finder_size_; + bool use_all_possible_disjunctions_; + bool diffn_use_cumulative_; + bool use_element_rmq_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto(); + + void InitAsDefaultInstance(); + static ConstraintSolverParameters* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// ConstraintSolverParameters + +// optional .operations_research.ConstraintSolverParameters.TrailCompression compress_trail = 1; +inline void ConstraintSolverParameters::clear_compress_trail() { + compress_trail_ = 0; +} +inline ::operations_research::ConstraintSolverParameters_TrailCompression ConstraintSolverParameters::compress_trail() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.compress_trail) + return static_cast< ::operations_research::ConstraintSolverParameters_TrailCompression >(compress_trail_); +} +inline void ConstraintSolverParameters::set_compress_trail(::operations_research::ConstraintSolverParameters_TrailCompression value) { + + compress_trail_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.compress_trail) +} + +// optional int32 trail_block_size = 2; +inline void ConstraintSolverParameters::clear_trail_block_size() { + trail_block_size_ = 0; +} +inline ::google::protobuf::int32 ConstraintSolverParameters::trail_block_size() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.trail_block_size) + return trail_block_size_; +} +inline void ConstraintSolverParameters::set_trail_block_size(::google::protobuf::int32 value) { + + trail_block_size_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.trail_block_size) +} + +// optional int32 array_split_size = 3; +inline void ConstraintSolverParameters::clear_array_split_size() { + array_split_size_ = 0; +} +inline ::google::protobuf::int32 ConstraintSolverParameters::array_split_size() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.array_split_size) + return array_split_size_; +} +inline void ConstraintSolverParameters::set_array_split_size(::google::protobuf::int32 value) { + + array_split_size_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.array_split_size) +} + +// optional bool store_names = 4; +inline void ConstraintSolverParameters::clear_store_names() { + store_names_ = false; +} +inline bool ConstraintSolverParameters::store_names() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.store_names) + return store_names_; +} +inline void ConstraintSolverParameters::set_store_names(bool value) { + + store_names_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.store_names) +} + +// optional bool name_cast_variables = 5; +inline void ConstraintSolverParameters::clear_name_cast_variables() { + name_cast_variables_ = false; +} +inline bool ConstraintSolverParameters::name_cast_variables() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.name_cast_variables) + return name_cast_variables_; +} +inline void ConstraintSolverParameters::set_name_cast_variables(bool value) { + + name_cast_variables_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.name_cast_variables) +} + +// optional bool name_all_variables = 6; +inline void ConstraintSolverParameters::clear_name_all_variables() { + name_all_variables_ = false; +} +inline bool ConstraintSolverParameters::name_all_variables() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.name_all_variables) + return name_all_variables_; +} +inline void ConstraintSolverParameters::set_name_all_variables(bool value) { + + name_all_variables_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.name_all_variables) +} + +// optional bool profile_propagation = 7; +inline void ConstraintSolverParameters::clear_profile_propagation() { + profile_propagation_ = false; +} +inline bool ConstraintSolverParameters::profile_propagation() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.profile_propagation) + return profile_propagation_; +} +inline void ConstraintSolverParameters::set_profile_propagation(bool value) { + + profile_propagation_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.profile_propagation) +} + +// optional string profile_file = 8; +inline void ConstraintSolverParameters::clear_profile_file() { + profile_file_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& ConstraintSolverParameters::profile_file() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.profile_file) + return profile_file_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void ConstraintSolverParameters::set_profile_file(const ::std::string& value) { + + profile_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.profile_file) +} +inline void ConstraintSolverParameters::set_profile_file(const char* value) { + + profile_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.ConstraintSolverParameters.profile_file) +} +inline void ConstraintSolverParameters::set_profile_file(const char* value, size_t size) { + + profile_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.ConstraintSolverParameters.profile_file) +} +inline ::std::string* ConstraintSolverParameters::mutable_profile_file() { + + // @@protoc_insertion_point(field_mutable:operations_research.ConstraintSolverParameters.profile_file) + return profile_file_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* ConstraintSolverParameters::release_profile_file() { + // @@protoc_insertion_point(field_release:operations_research.ConstraintSolverParameters.profile_file) + + return profile_file_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void ConstraintSolverParameters::set_allocated_profile_file(::std::string* profile_file) { + if (profile_file != NULL) { + + } else { + + } + profile_file_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), profile_file); + // @@protoc_insertion_point(field_set_allocated:operations_research.ConstraintSolverParameters.profile_file) +} + +// optional bool profile_local_search = 16; +inline void ConstraintSolverParameters::clear_profile_local_search() { + profile_local_search_ = false; +} +inline bool ConstraintSolverParameters::profile_local_search() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.profile_local_search) + return profile_local_search_; +} +inline void ConstraintSolverParameters::set_profile_local_search(bool value) { + + profile_local_search_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.profile_local_search) +} + +// optional bool print_local_search_profile = 17; +inline void ConstraintSolverParameters::clear_print_local_search_profile() { + print_local_search_profile_ = false; +} +inline bool ConstraintSolverParameters::print_local_search_profile() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.print_local_search_profile) + return print_local_search_profile_; +} +inline void ConstraintSolverParameters::set_print_local_search_profile(bool value) { + + print_local_search_profile_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.print_local_search_profile) +} + +// optional bool trace_propagation = 9; +inline void ConstraintSolverParameters::clear_trace_propagation() { + trace_propagation_ = false; +} +inline bool ConstraintSolverParameters::trace_propagation() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.trace_propagation) + return trace_propagation_; +} +inline void ConstraintSolverParameters::set_trace_propagation(bool value) { + + trace_propagation_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.trace_propagation) +} + +// optional bool trace_search = 10; +inline void ConstraintSolverParameters::clear_trace_search() { + trace_search_ = false; +} +inline bool ConstraintSolverParameters::trace_search() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.trace_search) + return trace_search_; +} +inline void ConstraintSolverParameters::set_trace_search(bool value) { + + trace_search_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.trace_search) +} + +// optional bool print_model = 11; +inline void ConstraintSolverParameters::clear_print_model() { + print_model_ = false; +} +inline bool ConstraintSolverParameters::print_model() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.print_model) + return print_model_; +} +inline void ConstraintSolverParameters::set_print_model(bool value) { + + print_model_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.print_model) +} + +// optional bool print_model_stats = 12; +inline void ConstraintSolverParameters::clear_print_model_stats() { + print_model_stats_ = false; +} +inline bool ConstraintSolverParameters::print_model_stats() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.print_model_stats) + return print_model_stats_; +} +inline void ConstraintSolverParameters::set_print_model_stats(bool value) { + + print_model_stats_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.print_model_stats) +} + +// optional bool print_added_constraints = 13; +inline void ConstraintSolverParameters::clear_print_added_constraints() { + print_added_constraints_ = false; +} +inline bool ConstraintSolverParameters::print_added_constraints() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.print_added_constraints) + return print_added_constraints_; +} +inline void ConstraintSolverParameters::set_print_added_constraints(bool value) { + + print_added_constraints_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.print_added_constraints) +} + +// optional string export_file = 14; +inline void ConstraintSolverParameters::clear_export_file() { + export_file_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& ConstraintSolverParameters::export_file() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.export_file) + return export_file_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void ConstraintSolverParameters::set_export_file(const ::std::string& value) { + + export_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.export_file) +} +inline void ConstraintSolverParameters::set_export_file(const char* value) { + + export_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.ConstraintSolverParameters.export_file) +} +inline void ConstraintSolverParameters::set_export_file(const char* value, size_t size) { + + export_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.ConstraintSolverParameters.export_file) +} +inline ::std::string* ConstraintSolverParameters::mutable_export_file() { + + // @@protoc_insertion_point(field_mutable:operations_research.ConstraintSolverParameters.export_file) + return export_file_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* ConstraintSolverParameters::release_export_file() { + // @@protoc_insertion_point(field_release:operations_research.ConstraintSolverParameters.export_file) + + return export_file_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void ConstraintSolverParameters::set_allocated_export_file(::std::string* export_file) { + if (export_file != NULL) { + + } else { + + } + export_file_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), export_file); + // @@protoc_insertion_point(field_set_allocated:operations_research.ConstraintSolverParameters.export_file) +} + +// optional bool disable_solve = 15; +inline void ConstraintSolverParameters::clear_disable_solve() { + disable_solve_ = false; +} +inline bool ConstraintSolverParameters::disable_solve() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.disable_solve) + return disable_solve_; +} +inline void ConstraintSolverParameters::set_disable_solve(bool value) { + + disable_solve_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.disable_solve) +} + +// optional bool use_compact_table = 100; +inline void ConstraintSolverParameters::clear_use_compact_table() { + use_compact_table_ = false; +} +inline bool ConstraintSolverParameters::use_compact_table() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_compact_table) + return use_compact_table_; +} +inline void ConstraintSolverParameters::set_use_compact_table(bool value) { + + use_compact_table_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_compact_table) +} + +// optional bool use_small_table = 101; +inline void ConstraintSolverParameters::clear_use_small_table() { + use_small_table_ = false; +} +inline bool ConstraintSolverParameters::use_small_table() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_small_table) + return use_small_table_; +} +inline void ConstraintSolverParameters::set_use_small_table(bool value) { + + use_small_table_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_small_table) +} + +// optional bool use_sat_table = 102; +inline void ConstraintSolverParameters::clear_use_sat_table() { + use_sat_table_ = false; +} +inline bool ConstraintSolverParameters::use_sat_table() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_sat_table) + return use_sat_table_; +} +inline void ConstraintSolverParameters::set_use_sat_table(bool value) { + + use_sat_table_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_sat_table) +} + +// optional int32 ac4r_table_threshold = 103; +inline void ConstraintSolverParameters::clear_ac4r_table_threshold() { + ac4r_table_threshold_ = 0; +} +inline ::google::protobuf::int32 ConstraintSolverParameters::ac4r_table_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.ac4r_table_threshold) + return ac4r_table_threshold_; +} +inline void ConstraintSolverParameters::set_ac4r_table_threshold(::google::protobuf::int32 value) { + + ac4r_table_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.ac4r_table_threshold) +} + +// optional bool use_mdd_table = 104; +inline void ConstraintSolverParameters::clear_use_mdd_table() { + use_mdd_table_ = false; +} +inline bool ConstraintSolverParameters::use_mdd_table() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_mdd_table) + return use_mdd_table_; +} +inline void ConstraintSolverParameters::set_use_mdd_table(bool value) { + + use_mdd_table_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_mdd_table) +} + +// optional bool use_cumulative_edge_finder = 105; +inline void ConstraintSolverParameters::clear_use_cumulative_edge_finder() { + use_cumulative_edge_finder_ = false; +} +inline bool ConstraintSolverParameters::use_cumulative_edge_finder() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_cumulative_edge_finder) + return use_cumulative_edge_finder_; +} +inline void ConstraintSolverParameters::set_use_cumulative_edge_finder(bool value) { + + use_cumulative_edge_finder_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_cumulative_edge_finder) +} + +// optional bool use_cumulative_time_table = 106; +inline void ConstraintSolverParameters::clear_use_cumulative_time_table() { + use_cumulative_time_table_ = false; +} +inline bool ConstraintSolverParameters::use_cumulative_time_table() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_cumulative_time_table) + return use_cumulative_time_table_; +} +inline void ConstraintSolverParameters::set_use_cumulative_time_table(bool value) { + + use_cumulative_time_table_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_cumulative_time_table) +} + +// optional bool use_cumulative_time_table_sync = 112; +inline void ConstraintSolverParameters::clear_use_cumulative_time_table_sync() { + use_cumulative_time_table_sync_ = false; +} +inline bool ConstraintSolverParameters::use_cumulative_time_table_sync() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_cumulative_time_table_sync) + return use_cumulative_time_table_sync_; +} +inline void ConstraintSolverParameters::set_use_cumulative_time_table_sync(bool value) { + + use_cumulative_time_table_sync_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_cumulative_time_table_sync) +} + +// optional bool use_sequence_high_demand_tasks = 107; +inline void ConstraintSolverParameters::clear_use_sequence_high_demand_tasks() { + use_sequence_high_demand_tasks_ = false; +} +inline bool ConstraintSolverParameters::use_sequence_high_demand_tasks() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_sequence_high_demand_tasks) + return use_sequence_high_demand_tasks_; +} +inline void ConstraintSolverParameters::set_use_sequence_high_demand_tasks(bool value) { + + use_sequence_high_demand_tasks_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_sequence_high_demand_tasks) +} + +// optional bool use_all_possible_disjunctions = 108; +inline void ConstraintSolverParameters::clear_use_all_possible_disjunctions() { + use_all_possible_disjunctions_ = false; +} +inline bool ConstraintSolverParameters::use_all_possible_disjunctions() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_all_possible_disjunctions) + return use_all_possible_disjunctions_; +} +inline void ConstraintSolverParameters::set_use_all_possible_disjunctions(bool value) { + + use_all_possible_disjunctions_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_all_possible_disjunctions) +} + +// optional int32 max_edge_finder_size = 109; +inline void ConstraintSolverParameters::clear_max_edge_finder_size() { + max_edge_finder_size_ = 0; +} +inline ::google::protobuf::int32 ConstraintSolverParameters::max_edge_finder_size() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.max_edge_finder_size) + return max_edge_finder_size_; +} +inline void ConstraintSolverParameters::set_max_edge_finder_size(::google::protobuf::int32 value) { + + max_edge_finder_size_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.max_edge_finder_size) +} + +// optional bool diffn_use_cumulative = 110; +inline void ConstraintSolverParameters::clear_diffn_use_cumulative() { + diffn_use_cumulative_ = false; +} +inline bool ConstraintSolverParameters::diffn_use_cumulative() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.diffn_use_cumulative) + return diffn_use_cumulative_; +} +inline void ConstraintSolverParameters::set_diffn_use_cumulative(bool value) { + + diffn_use_cumulative_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.diffn_use_cumulative) +} + +// optional bool use_element_rmq = 111; +inline void ConstraintSolverParameters::clear_use_element_rmq() { + use_element_rmq_ = false; +} +inline bool ConstraintSolverParameters::use_element_rmq() const { + // @@protoc_insertion_point(field_get:operations_research.ConstraintSolverParameters.use_element_rmq) + return use_element_rmq_; +} +inline void ConstraintSolverParameters::set_use_element_rmq(bool value) { + + use_element_rmq_ = value; + // @@protoc_insertion_point(field_set:operations_research.ConstraintSolverParameters.use_element_rmq) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::operations_research::ConstraintSolverParameters_TrailCompression> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::ConstraintSolverParameters_TrailCompression>() { + return ::operations_research::ConstraintSolverParameters_TrailCompression_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fconstraint_5fsolver_2fsolver_5fparameters_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/glop/basis_representation.h b/thirdparty/linux/include/ortools/glop/basis_representation.h new file mode 100644 index 0000000..3259bda --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/basis_representation.h @@ -0,0 +1,370 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_GLOP_BASIS_REPRESENTATION_H_ +#define OR_TOOLS_GLOP_BASIS_REPRESENTATION_H_ + +#include "ortools/base/logging.h" +#include "ortools/glop/lu_factorization.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/rank_one_update.h" +#include "ortools/glop/status.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/lp_data/sparse.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace glop { + +// An eta matrix E corresponds to the identity matrix except for one column e of +// index j. In particular, B.E is the matrix of the new basis obtained from B by +// replacing the j-th vector of B by B.e, note that this is exactly what happens +// during a "pivot" of the current basis in the simplex algorithm. +// +// E = [ 1 ... 0 e_0 0 ... 0 +// ... ... ... ... ... ... ... +// 0 ... 1 e_{j-1} 0 ... 0 +// 0 ... 0 e_j 0 ... 0 +// 0 ... 0 e_{j+1} 1 ... 0 +// ... ... ... ... ... ... ... +// 0 ... 0 e_{n-1} 0 ... 1 ] +// +// The inverse of the eta matrix is: +// E^{-1} = [ 1 ... 0 -e_0/e_j 0 ... 0 +// ... ... ... ... ... ... ... +// 0 ... 1 -e_{j-1}/e_j 0 ... 0 +// 0 ... 0 1/e_j 0 ... 0 +// 0 ... 0 -e_{j+1}/e_j 1 ... 0 +// ... ... ... ... ... ... ... +// 0 ... 0 -e_{n-1}/e_j 0 ... 1 ] +class EtaMatrix { + public: + EtaMatrix(ColIndex eta_col, const std::vector& eta_non_zeros, + DenseColumn* dense_eta); + virtual ~EtaMatrix(); + + // Solves the system y.E = c, 'c' beeing the initial value of 'y'. + // Then y = c.E^{-1}, so y is equal to c except for + // y_j = (c_j - \sum_{i != j}{c_i * e_i}) / e_j. + void LeftSolve(DenseRow* y) const; + + // Same as LeftSolve(), but 'pos' contains the non-zero positions of c. The + // order of the positions is not important, but there must be no duplicates. + // The values not in 'pos' are not used. If eta_col_ was not already in 'pos', + // it is added. + void SparseLeftSolve(DenseRow* y, ColIndexVector* pos) const; + + // Solves the system E.d = a, 'a' beeing the initial value of 'd'. + // Then d = E^{-1}.a = [ a_0 - e_0 * a_j / e_j + // ... + // a_{j-1} - e_{j-1} * a_j / e_j + // a_j / e_j + // a_{j+1} - e_{j+1} * a_j / e_j + // ... + // a_{n-1} - e_{n-1} * a_j / e_j ] + void RightSolve(DenseColumn* d) const; + + private: + // Internal RightSolve() and LeftSolve() implementations using either the + // dense or the sparse representation of the eta vector. + void LeftSolveWithDenseEta(DenseRow* y) const; + void LeftSolveWithSparseEta(DenseRow* y) const; + void RightSolveWithDenseEta(DenseColumn* d) const; + void RightSolveWithSparseEta(DenseColumn* d) const; + + // If an eta vector density is smaller than this threshold, we use the + // sparse version of the Solve() functions rather than the dense version. + // TODO(user): Detect automatically a good parameter? 0.5 is a good value on + // the Netlib (I only did a few experiments though). Note that in the future + // we may not even keep the dense representation at all. + static const Fractional kSparseThreshold; + + const ColIndex eta_col_; + const Fractional eta_col_coefficient_; + + // Note that to optimize solves, the position eta_col_ is set to 0.0 and + // stored in eta_col_coefficient_ instead. + DenseColumn eta_coeff_; + SparseColumn sparse_eta_coeff_; + + DISALLOW_COPY_AND_ASSIGN(EtaMatrix); +}; + +// An eta factorization corresponds to the product of k eta matrices, +// i.e. E = E_0.E_1. ... .E_{k-1} +// It is used to solve two systems: +// - E.d = a (where a is usually the entering column). +// - y.E = c (where c is usually the objective row). +class EtaFactorization { + public: + EtaFactorization(); + virtual ~EtaFactorization(); + + // Deletes all eta matrices. + void Clear(); + + // Updates the eta factorization, i.e. adds the new eta matrix defined by + // the leaving variable and the corresponding eta column. + void Update(ColIndex entering_col, RowIndex leaving_variable_row, + const std::vector& eta_non_zeros, + DenseColumn* dense_eta); + + // Left solves all systems from right to left, i.e. y_i = y_{i+1}.(E_i)^{-1} + void LeftSolve(DenseRow* y) const; + + // Same as LeftSolve(), but 'pos' contains the non-zero positions of c. The + // order of the positions is not important, but there must be no duplicates. + // The values not in 'pos' are not used. If eta_col_ was not already in 'pos', + // it is added. + void SparseLeftSolve(DenseRow* y, ColIndexVector* pos) const; + + // Right solves all systems from left to right, i.e. E_i.d_{i+1} = d_i + void RightSolve(DenseColumn* d) const; + + private: + std::vector eta_matrix_; + + DISALLOW_COPY_AND_ASSIGN(EtaFactorization); +}; + +// A basis factorization is the product of an eta factorization and +// a L.U decomposition, i.e. B = L.U.E_0.E_1. ... .E_{k-1} +// It is used to solve two systems: +// - B.d = a where a is the entering column. +// - y.B = c where c is the objective row. +// +// To speed-up and improve stability the factorization is refactorized at least +// every 'refactorization_period' updates. +class BasisFactorization { + public: + BasisFactorization(const MatrixView& matrix, const RowToColMapping& basis); + virtual ~BasisFactorization(); + + // Sets the parameters for this component. + void SetParameters(const GlopParameters& parameters) { + max_num_updates_ = parameters.basis_refactorization_period(); + use_middle_product_form_update_ = + parameters.use_middle_product_form_update(); + parameters_ = parameters; + lu_factorization_.SetParameters(parameters); + } + + // Returns the column permutation used by the LU factorization. + // This call only makes sense if the basis was just refactorized. + const ColumnPermutation& GetColumnPermutation() const { + DCHECK(IsRefactorized()); + return lu_factorization_.GetColumnPermutation(); + } + + // Sets the column permutation used by the LU factorization to the identity. + // Hense the Solve() results will be computed without this permutation. + // This call only makes sense if the basis was just refactorized. + void SetColumnPermutationToIdentity() { + DCHECK(IsRefactorized()); + lu_factorization_.SetColumnPermutationToIdentity(); + } + + // Clears the factorization and resets it to an identity matrix of size given + // by matrix_.num_rows(). + void Clear(); + + // Clears the factorization and initializes the class using the current + // matrix_ and basis_. This is fast if IsIdentityBasis() is true, otherwise + // it will trigger a refactorization and will return an error if the matrix + // could not be factorized. + Status Initialize() MUST_USE_RESULT; + + // Return the number of rows in the basis. + RowIndex GetNumberOfRows() const { return matrix_.num_rows(); } + + // Clears eta factorization and refactorizes LU. + // Nothing happens if this is called on an already refactorized basis. + // Returns an error if the matrix could not be factorized: i.e. not a basis. + Status Refactorize() MUST_USE_RESULT; + + // Like Refactorize(), but do it even if IsRefactorized() is true. + // Call this if the underlying basis_ changed and Update() wasn't called. + Status ForceRefactorization() MUST_USE_RESULT; + + // Returns true if the factorization was just recomputed. + bool IsRefactorized() const; + + // Updates the factorization. The 'eta' column will be modified with a swap to + // avoid a copy (only if the standard eta update is used). Returns an error if + // the matrix could not be factorized: i.e. not a basis. + Status Update(ColIndex entering_col, RowIndex leaving_variable_row, + const std::vector& eta_non_zeros, + DenseColumn* dense_eta) MUST_USE_RESULT; + + // Left solves the system y.B = rhs, where y initialy contains rhs. + // The second version also computes the non-zero positions of the result. + void LeftSolve(DenseRow* y) const; + void LeftSolveWithNonZeros(DenseRow* y, ColIndexVector* non_zeros) const; + + // Left solves the system y.B = e_j, where e_j has only 1 non-zero + // coefficient of value 1.0 at position 'j'. + void LeftSolveForUnitRow(ColIndex j, DenseRow* y, + ColIndexVector* non_zeros) const; + + // Same as RightSolve() for matrix.column(col). + // This also exploits its sparsity. + void RightSolveForProblemColumn(ColIndex col, DenseColumn* d, + std::vector* non_zeros) const; + + // Right solves the system B.d = a where the input is the initial value of d. + void RightSolve(DenseColumn* d) const; + void RightSolveWithNonZeros(DenseColumn* d, + std::vector* non_zeros) const; + + // Specialized version for ComputeTau() in DualEdgeNorms. This reuses an + // intermediate result of the last LeftSolveForUnitRow() in order to save a + // permutation if it is available. Note that the input 'a' should always be + // equal to the last result of LeftSolveForUnitRow() and will be used for a + // DCHECK() or if the intermediate result wasn't kept. + DenseColumn* RightSolveForTau(ScatteredColumnReference a) const; + + // Returns the norm of B^{-1}.a, this is a specific function because + // it is a bit faster and it avoids polluting the stats of RightSolve(). + // It can be called only when IsRefactorized() is true. + Fractional RightSolveSquaredNorm(const SparseColumn& a) const; + + // Returns the norm of (B^T)^{-1}.e_row where e is an unit vector. + // This is a bit faster and avoids polluting the stats of LeftSolve(). + // It can be called only when IsRefactorized() is true. + Fractional DualEdgeSquaredNorm(RowIndex row) const; + + // Computes the condition number of B. + // For a given norm, this is the matrix norm times the norm of its inverse. + // A condition number greater than 1E7 will lead to precision problems. + Fractional ComputeOneNormConditionNumber() const; + Fractional ComputeInfinityNormConditionNumber() const; + + // Computes the 1-norm of B. + // The 1-norm |A| is defined as max_j sum_i |a_ij| + // http://en.wikipedia.org/wiki/Matrix_norm + Fractional ComputeOneNorm() const; + + // Computes the infinity-norm of B. + // The infinity-norm |A| is defined as max_i sum_j |a_ij| + // http://en.wikipedia.org/wiki/Matrix_norm + Fractional ComputeInfinityNorm() const; + + // Computes the 1-norm of the inverse of B. + // For this we iteratively solve B.x = e_j, where e_j is the jth unit vector. + // The result of this computation is the jth column of B^-1. + Fractional ComputeInverseOneNorm() const; + + // Computes the infinity-norm of the inverse of B. + Fractional ComputeInverseInfinityNorm() const; + + // Stats related function. + // Note that ResetStats() could be const, but until needed it is not to + // prevent anyone holding a const BasisFactorization& to call it. + std::string StatString() const { + return stats_.StatString() + lu_factorization_.StatString(); + } + void ResetStats() { stats_.Reset(); } + + // The deterministic time used by this class. It is incremented for each + // solve and each factorization. + double DeterministicTime() const; + + private: + // Return true if the submatrix of matrix_ given by basis_ is exactly the + // identity (without permutation). + bool IsIdentityBasis() const; + + // Updates the factorization using the middle product form update. + // Qi Huangfu, J. A. Julian Hall, "Novel update techniques for the revised + // simplex method", 28 january 2013, Technical Report ERGO-13-0001 + Status MiddleProductFormUpdate(ColIndex entering_col, + RowIndex leaving_variable_row) MUST_USE_RESULT; + + // Increases the deterministic time for a solve operation with a vector having + // this number of non-zero entries (it can be an approximation). + void BumpDeterministicTimeForSolve(int num_entries) const; + + // Stats about this class. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("BasisFactorization"), + refactorization_interval("refactorization_interval", this) {} + IntegerDistribution refactorization_interval; + }; + + // Mutable because we track the running time of const method like + // RightSolve() and LeftSolve(). + mutable Stats stats_; + GlopParameters parameters_; + + // References to the basis subpart of the linear program matrix. + const MatrixView& matrix_; + const RowToColMapping& basis_; + + // Middle form product update factorization and scratchpad_ used to construct + // new rank one matrices. + RankOneUpdateFactorization rank_one_factorization_; + mutable DenseColumn scratchpad_; + mutable std::vector scratchpad_non_zeros_; + + // This is used by RightSolveForTau(). It holds an intermediate result from + // the last LeftSolveForUnitRow() and also the final result of + // RightSolveForTau(). + mutable DenseColumn tau_; + mutable std::vector tau_non_zeros_; + + // Booleans controlling the interaction between LeftSolveForUnitRow() that may + // or may not keep its intermediate results for the optimized + // RightSolveForTau(). + // + // tau_computation_can_be_optimized_ will be true iff LeftSolveForUnitRow() + // kept its intermediate result when it was called and the factorization + // didn't change since then. If it is true, then RightSolveForTau() can use + // this result for a faster computation. + // + // tau_is_computed_ is used as an heuristic by LeftSolveForUnitRow() to decide + // if it is worth keeping its intermediate result (which is sligthly slower). + // It is simply set to true by RightSolveForTau() and to false by + // LeftSolveForUnitRow(), this way the optimization will automatically switch + // itself on when switching from the primal simplex (where RightSolveForTau() + // is never called) to the dual where it is called after each + // LeftSolveForUnitRow(), and back off again in the other direction. + mutable bool tau_computation_can_be_optimized_; + mutable bool tau_is_computed_; + + // Data structure to store partial solve results for the middle form product + // update. See LeftSolveForUnitRow() and RightSolveForProblemColumn(). We use + // two CompactSparseMatrix to have a better cache behavior when solving with + // the rank_one_factorization_. + mutable CompactSparseMatrix storage_; + mutable CompactSparseMatrix right_storage_; + mutable ColMapping left_pool_mapping_; + mutable ColMapping right_pool_mapping_; + + bool use_middle_product_form_update_; + int max_num_updates_; + int num_updates_; + EtaFactorization eta_factorization_; + LuFactorization lu_factorization_; + + // mutable because the Solve() functions are const but need to update this. + mutable double deterministic_time_; + + DISALLOW_COPY_AND_ASSIGN(BasisFactorization); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_BASIS_REPRESENTATION_H_ diff --git a/thirdparty/linux/include/ortools/glop/dual_edge_norms.h b/thirdparty/linux/include/ortools/glop/dual_edge_norms.h new file mode 100644 index 0000000..abe67ca --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/dual_edge_norms.h @@ -0,0 +1,127 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_DUAL_EDGE_NORMS_H_ +#define OR_TOOLS_GLOP_DUAL_EDGE_NORMS_H_ + +#include "ortools/glop/basis_representation.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace glop { + +// This class maintains the dual edge squared norms to be used in the +// dual steepest edge pricing. The dual edge u_i associated with a basic +// variable of row index i is such that u_i.B = e_i where e_i is the unit row +// vector with a 1.0 at position i and B the current basis. We call such vector +// u_i an unit row left inverse, and it can be computed by +// +// basis_factorization.LeftSolveForUnitRow(i, &u_i); +// +// Instead of computing each ||u_i|| at every iteration, it is more efficient to +// update them incrementally for each basis pivot applied to B. See the code or +// the papers below for details: +// +// J.J. Forrest, D. Goldfarb, "Steepest-edge simplex algorithms for linear +// programming", Mathematical Programming 57 (1992) 341-374, North-Holland. +// http://www.springerlink.com/content/q645w3t2q229m248/ +// +// Achim Koberstein, "The dual simplex method, techniques for a fast and stable +// implementation", PhD, Paderborn, Univ., 2005. +// http://digital.ub.uni-paderborn.de/hs/download/pdf/3885?originalFilename=true +class DualEdgeNorms { + public: + // Takes references to the linear program data we need. + explicit DualEdgeNorms(const BasisFactorization& basis_factorization); + + // Clears, i.e. reset the object to its initial value. This will trigger a + // full norm recomputation on the next GetEdgeSquaredNorms(). + void Clear(); + + // If this is true, then the caller must re-factorize the basis before the + // next call to GetEdgeSquaredNorms(). This is because the latter will + // recompute the norms from scratch and therefore needs a hightened precision + // and speed. + bool NeedsBasisRefactorization(); + + // Returns the dual edge squared norms. This is only valid if the caller + // properly called UpdateBeforeBasisPivot() before each basis pivot, or just + // called Clear(). + const DenseColumn& GetEdgeSquaredNorms(); + + // Updates the norms if the columns of the basis where permuted. + void UpdateDataOnBasisPermutation(const ColumnPermutation& col_perm); + + // Updates the norms just before a basis pivot is applied: + // - The column at leaving_row will leave the basis and the column at + // entering_col will enter it. + // - direction is the right inverse of the entering column. + // - unit_row_left_inverse is the left inverse of the unit row with index + // given by the leaving_row. This is also the leaving dual edge. + void UpdateBeforeBasisPivot(ColIndex entering_col, RowIndex leaving_row, + ScatteredColumnReference direction, + ScatteredColumnReference unit_row_left_inverse); + + // Sets the algorithm parameters. + void SetParameters(const GlopParameters& parameters) { + parameters_ = parameters; + } + + // Stats related functions. + std::string StatString() const { return stats_.StatString(); } + + private: + // Recomputes the dual edge squared norms from scratch with maximum precision. + // The matrix must have been refactorized before because we will do a lot of + // inversions. See NeedsBasisRefactorization(). This is checked in debug mode. + void ComputeEdgeSquaredNorms(); + + // Computes the vector tau needed to update the norms using a right solve: + // B.tau = (u_i)^T, u_i.B = e_i for i = leaving_row. + DenseColumn* ComputeTau(ScatteredColumnReference unit_row_left_inverse); + + // Statistics. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("DualEdgeNorms"), + tau_density("tau_density", this), + edge_norms_accuracy("edge_norms_accuracy", this), + lower_bounded_norms("lower_bounded_norms", this) {} + RatioDistribution tau_density; + DoubleDistribution edge_norms_accuracy; + IntegerDistribution lower_bounded_norms; + }; + Stats stats_; + + // Parameters. + GlopParameters parameters_; + + // Problem data that should be updated from outside. + const BasisFactorization& basis_factorization_; + + // The dual edge norms. + DenseColumn edge_squared_norms_; + + // Whether we should recompute the norm from scratch. + bool recompute_edge_squared_norms_; + + DISALLOW_COPY_AND_ASSIGN(DualEdgeNorms); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_DUAL_EDGE_NORMS_H_ diff --git a/thirdparty/linux/include/ortools/glop/entering_variable.h b/thirdparty/linux/include/ortools/glop/entering_variable.h new file mode 100644 index 0000000..57d72fb --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/entering_variable.h @@ -0,0 +1,152 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_ENTERING_VARIABLE_H_ +#define OR_TOOLS_GLOP_ENTERING_VARIABLE_H_ + +#include "ortools/glop/basis_representation.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/primal_edge_norms.h" +#include "ortools/glop/reduced_costs.h" +#include "ortools/glop/status.h" +#include "ortools/glop/update_row.h" +#include "ortools/glop/variables_info.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/util/bitset.h" +#include "ortools/base/random.h" +#include "ortools/util/stats.h" + +#if !SWIG + +namespace operations_research { +namespace glop { + +// This class contains the primal and dual algorithms that choose the entering +// column (i.e. variable) during a simplex iteration. +// +// The goal of this component is, given a matrix A (matrix_), a subset of +// columns (basis_) that form a basis B and a cost (objective_) associated to +// each column of A, to choose a "good" non-basic column to enter the basis +// B. Note that this choice does not depend on the current variable values +// (except for the direction in which each variable is allowed to change given +// by variable_status_). +// +// Terminology: +// - The entering edge is the edge we are following during a simplex step, +// and we call "direction" the reverse of this edge restricted to the +// basic variables, i.e. the right inverse of the entering column. +// +// Papers: +// - Ping-Qi Pan, "Efficient nested pricing in the simplex algorithm", +// http://www.optimization-online.org/DB_FILE/2007/10/1810.pdf +class EnteringVariable { + public: + // Takes references to the linear program data we need. + EnteringVariable(const VariablesInfo& variables_info, RandomBase* random, + ReducedCosts* reduced_costs, + PrimalEdgeNorms* primal_edge_norms); + + // Returns the index of a valid primal entering column (see + // IsValidPrimalEnteringCandidate() for more details) or kInvalidCol if no + // such column exists. This latter case means that the primal algorithm has + // terminated: the optimal has been reached. + Status PrimalChooseEnteringColumn(ColIndex* entering_col) MUST_USE_RESULT; + + // Dual optimization phase (i.e. phase II) ratio test. + // Returns the index of the entering column given that we want to move along + // the "update" row vector in the direction given by the sign of + // cost_variation. Computes the smallest step that keeps the dual feasibility + // for all the columns. The pivot is the coefficient of the "update" vector at + // the entering column index. + Status DualChooseEnteringColumn(const UpdateRow& update_row, + Fractional cost_variation, + std::vector* bound_flip_candidates, + ColIndex* entering_col, Fractional* pivot, + Fractional* step) MUST_USE_RESULT; + + // Dual feasibility phase (i.e. phase I) ratio test. + // Similar to the optimization phase test, but allows a step that increases + // the infeasibility of an already infeasible column. The step magnitude is + // the one that minimize the sum of infeasibilities when applied. + Status DualPhaseIChooseEnteringColumn(const UpdateRow& update_row, + Fractional cost_variation, + ColIndex* entering_col, + Fractional* pivot, + Fractional* step) MUST_USE_RESULT; + + // Sets the pricing parameters. This does not change the pricing rule. + void SetParameters(const GlopParameters& parameters); + + // Sets the pricing rule. + void SetPricingRule(GlopParameters::PricingRule rule); + + // Stats related functions. + std::string StatString() const { return stats_.StatString(); } + + // Recomputes the set of unused columns used during nested pricing. + // Visible for testing (the returns value is also there for testing). + DenseBitRow* ResetUnusedColumns(); + + private: + // Dantzig selection rule: choose the variable with the best reduced cost. + // If normalize is true, we normalize the costs by the column norms. + // If nested_pricing is true, we use nested pricing (see parameters.proto). + template + void DantzigChooseEnteringColumn(ColIndex* entering_col); + + // Steepest edge rule: the reduced costs are normalized by the edges norm. + // Devex rule: the reduced costs are normalized by an approximation of the + // edges norm. + template + void NormalizedChooseEnteringColumn(ColIndex* entering_col); + + // Problem data that should be updated from outside. + const VariablesInfo& variables_info_; + + RandomBase* random_; + ReducedCosts* reduced_costs_; + PrimalEdgeNorms* primal_edge_norms_; + + // Internal data. + GlopParameters parameters_; + GlopParameters::PricingRule rule_; + + // Stats. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("EnteringVariable"), + num_perfect_ties("num_perfect_ties", this) {} + IntegerDistribution num_perfect_ties; + }; + Stats stats_; + + // This is used for nested pricing. It is denoted J in Ping-Qi Pan's paper. + // At a given step, it is true for the variable that should be considered for + // entering the basis. + DenseBitRow unused_columns_; + + // Temporary vector used to hold the best entering column candidates that are + // tied using the current choosing criteria. We actually only store the tied + // candidate #2, #3, ...; because the first tied candidate is remembered + // anyway. + std::vector equivalent_entering_choices_; + + DISALLOW_COPY_AND_ASSIGN(EnteringVariable); +}; + +} // namespace glop +} // namespace operations_research + +#endif // SWIG +#endif // OR_TOOLS_GLOP_ENTERING_VARIABLE_H_ diff --git a/thirdparty/linux/include/ortools/glop/initial_basis.h b/thirdparty/linux/include/ortools/glop/initial_basis.h new file mode 100644 index 0000000..a3c2a9a --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/initial_basis.h @@ -0,0 +1,122 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_INITIAL_BASIS_H_ +#define OR_TOOLS_GLOP_INITIAL_BASIS_H_ + +#include "ortools/lp_data/lp_data.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/lp_data/sparse.h" + +namespace operations_research { +namespace glop { + +// This class implements two initial basis algorithms. The idea is to replace as +// much as possible the columns of B that correspond to fixed slack variables +// with some column of A in order to have more freedom in the values the basic +// variables can take. +// +// The first algorithm is Bixby's initial basis algorithm, described in the +// paper below. It considers the columns of A in a particular order (the ones +// with more freedom first) and adds the current column to the basis if it keeps +// B almost triangular and with coefficients close to 1.0 on the diagonal for +// good numerical stability. +// +// Robert E. Bixby, "Implementing the Simplex Method: The Initial Basis" +// ORSA Jounal on Computing, Vol. 4, No. 3, Summer 1992. +// http://joc.journal.informs.org/content/4/3/267.abstract +// +// The second algorithm is is similar to the "advanced initial basis" that GLPK +// uses by default. It adds columns one by one to the basis B while keeping it +// triangular (not almost triangular as in Bixby's algorithm). The next +// column to add is chosen amongst the set of possible candidates using a +// heuristic similar to the one used by Bixby. +class InitialBasis { + public: + // Takes references to the linear program data we need. + InitialBasis(const MatrixView& matrix, const DenseRow& objective, + const DenseRow& lower_bound, const DenseRow& upper_bound, + const VariableTypeRow& variable_type); + + // Completes the entries of the given basis that are equal to kInvalidCol with + // one of the first num_cols columns of A using Bixby's algorithm. + // + // Important: For this function, the matrix must be scaled such that the + // maximum absolute value in each column is 1.0. + void CompleteBixbyBasis(ColIndex num_cols, RowToColMapping* basis); + + // Similar to CompleteBixbyBasis() but completes the basis into a triangular + // one. This function usually produces better initial bases. The dual version + // just restricts the possible entering columns to the ones with a cost of 0.0 + // in order to always start with the all-zeros vector of dual values. + // + // Returns false if an error occurred during the algorithm (numerically + // instable basis). + bool CompleteTriangularPrimalBasis(ColIndex num_cols, RowToColMapping* basis); + bool CompleteTriangularDualBasis(ColIndex num_cols, RowToColMapping* basis); + + // Visible for testing. Computes a list of candidate column indices out of the + // fist num_candidate_columns of A and sorts them using the + // bixby_column_comparator_. This also fills max_scaled_abs_cost_. + void ComputeCandidates(ColIndex num_candidate_columns, + std::vector* candidates); + + private: + // Internal implementation of the Primal/Dual CompleteTriangularBasis(). + template + bool CompleteTriangularBasis(ColIndex num_cols, RowToColMapping* basis); + + // Returns an integer representing the order (the lower the better) + // between column categories (known as C2, C3 or C4 in the paper). + // Also returns a greater index for fixed columns. + int GetColumnCategory(ColIndex col) const; + + // Returns the penalty (the lower the better) of a column. This is 'q_j' for a + // column 'j' in the paper. + Fractional GetColumnPenalty(ColIndex col) const; + + // Maximum scaled absolute value of the objective for the columns which are + // entering candidates. This is used by GetColumnPenalty(). + Fractional max_scaled_abs_cost_; + + // Comparator used to sort column indices according to their penalty. + // Lower is better. + struct BixbyColumnComparator { + explicit BixbyColumnComparator(const InitialBasis& initial_basis) + : initial_basis_(initial_basis) {} + bool operator()(ColIndex col_a, ColIndex col_b) const; + const InitialBasis& initial_basis_; + } bixby_column_comparator_; + + // Comparator used by CompleteTriangularBasis(). Note that this one is meant + // to be used by a priority queue, so higher is better. + struct TriangularColumnComparator { + explicit TriangularColumnComparator(const InitialBasis& initial_basis) + : initial_basis_(initial_basis) {} + bool operator()(ColIndex col_a, ColIndex col_b) const; + const InitialBasis& initial_basis_; + } triangular_column_comparator_; + + const MatrixView& matrix_; + const DenseRow& objective_; + const DenseRow& lower_bound_; + const DenseRow& upper_bound_; + const VariableTypeRow& variable_type_; + + DISALLOW_COPY_AND_ASSIGN(InitialBasis); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_INITIAL_BASIS_H_ diff --git a/thirdparty/linux/include/ortools/glop/lp_solver.h b/thirdparty/linux/include/ortools/glop/lp_solver.h new file mode 100644 index 0000000..19cf8c9 --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/lp_solver.h @@ -0,0 +1,279 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_LP_SOLVER_H_ +#define OR_TOOLS_GLOP_LP_SOLVER_H_ + +#include + +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/preprocessor.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { +namespace glop { + +// A full-fledged linear programming solver. +class LPSolver { + public: + LPSolver(); + + // Sets and gets the solver parameters. + // See the proto for an extensive documentation. + void SetParameters(const GlopParameters& parameters); + const GlopParameters& GetParameters() const; + + // Solves the given linear program and returns the solve status. See the + // ProblemStatus documentation for a description of the different values. + // + // The solution can be retrieved afterwards using the getter functions below. + // Note that depending on the returned ProblemStatus the solution values may + // not mean much, so it is important to check the returned status. + // + // Incrementality: From one Solve() call to the next, the internal state is + // not cleared and the solver may take advantage of its current state if the + // given lp is only slightly modified. If the modification is too important, + // or if the solver does not see how to reuse the previous state efficiently, + // it will just solve the problem from scratch. On the other hand, if the lp + // is the same, calling Solve() again should basically resume the solve from + // the last position. To disable this behavior, simply call Clear() before. + ProblemStatus Solve(const LinearProgram& lp) MUST_USE_RESULT; + + // Same as Solve() but use the given time limit rather than constructing a new + // one from the current GlopParameters. + ProblemStatus SolveWithTimeLimit(const LinearProgram& lp, + TimeLimit* time_limit) MUST_USE_RESULT; + + // Puts the solver in a clean state. + // + // Calling Solve() for the first time, or calling Clear() then Solve() on the + // same problem is guaranted to be deterministic and to always give the same + // result, assuming that no time limit was specified. + void Clear(); + + // Advanced usage. This should be called before calling Solve(). It will + // configure the solver to try to start from the given point for the next + // Solve() only. Note that calling Clear() will invalidate this information. + // + // If the set of variables/constraints with a BASIC status does not form a + // basis a warning will be logged and the code will ignore it. Otherwise, the + // non-basic variables will be initialized to their given status and solving + // will start from there (even if the solution is not primal/dual feasible). + // + // Important: There is no facility to transform this information in sync with + // presolve. So you should probably disable presolve when using this since + // otherwise there is a good chance that the matrix will change and that the + // given basis will make no sense. Even worse if it happens to be factorizable + // but doesn't correspond to what was intended. + void SetInitialBasis(const VariableStatusRow& variable_statuses, + const ConstraintStatusColumn& constraint_statuses); + + // This loads a given solution and computes related quantities so that the + // getters below will refer to it. + // + // Depending on the given solution status, this also checks the solution + // feasibility or optimality. The exact behavior and tolerances are controlled + // by the solver parameters. Because of this, the returned ProblemStatus may + // be changed from the one passed in the ProblemSolution to ABNORMAL or + // IMPRECISE. Note that this is the same logic as the one used by Solve() to + // verify the solver solution. + ProblemStatus LoadAndVerifySolution(const LinearProgram& lp, + const ProblemSolution& solution); + + // Returns the objective value of the solution with its offset and scaling. + Fractional GetObjectiveValue() const; + + // Accessors to information related to variables. + const DenseRow& variable_values() const { return primal_values_; } + const DenseRow& reduced_costs() const { return reduced_costs_; } + const VariableStatusRow& variable_statuses() const { + return variable_statuses_; + } + + // Accessors to information related to constraints. The activity of a + // constraint is the sum of its linear terms evaluated with variables taking + // their values at the current solution. + // + // Note that the dual_values() do not take into account an eventual objective + // scaling of the solved LinearProgram. + const DenseColumn& dual_values() const { return dual_values_; } + const DenseColumn& constraint_activities() const { + return constraint_activities_; + } + const ConstraintStatusColumn& constraint_statuses() const { + return constraint_statuses_; + } + + // Returns the primal maximum infeasibility of the solution. + // This indicates by how much the variable and constraint bounds are violated. + Fractional GetMaximumPrimalInfeasibility() const; + + // Returns the dual maximum infeasibility of the solution. + // This indicates by how much the variable costs (i.e. objective) should be + // modified for the solution to be an exact optimal solution. + Fractional GetMaximumDualInfeasibility() const; + + // Returns true if the solution status was OPTIMAL and it seems that there is + // more than one basic optimal solution. Note that this solver always returns + // an optimal BASIC solution and that there is only a finite number of them. + // Moreover, given one basic solution, since the basis is always refactorized + // at optimality before reporting the numerical result, then all the + // quantities (even the floating point ones) should be always the same. + // + // TODO(user): Test this behavior extensively if a client relies on it. + bool MayHaveMultipleOptimalSolutions() const; + + // Returns the number of simplex iterations used by the last Solve(). + int GetNumberOfSimplexIterations() const; + + + // Returns the "deterministic time" since the creation of the solver. Note + // That this time is only increased when some operations take place in this + // class. + // + // TODO(user): Currently, this is only modified when the simplex code is + // executed. + // + // TODO(user): Improve the correlation with the running time. + double DeterministicTime() const; + + private: + // Resizes all the solution vectors to the given sizes. + // This is used in case of error to make sure all the getter functions will + // not crash when given row/col inside the initial linear program dimension. + void ResizeSolution(RowIndex row, ColIndex col); + + // Make sure the primal and dual values are within their bounds in order to + // have a strong guarantee on the optimal solution. See + // provide_strong_optimal_guarantee in the GlopParameters proto. + void MovePrimalValuesWithinBounds(const LinearProgram& lp); + void MoveDualValuesWithinBounds(const LinearProgram& lp); + + // Runs the revised simplex algorithm if needed (i.e. if the program was not + // already solved by the preprocessors). + void RunRevisedSimplexIfNeeded(ProblemSolution* solution, + TimeLimit* time_limit); + + + // Checks that the returned solution values and statuses are consistent. + // Returns true if this is the case. See the code for the exact check + // performed. + bool IsProblemSolutionConsistent(const LinearProgram& lp, + const ProblemSolution& solution) const; + + // Returns true if there may be multiple optimal solutions. + // The return value is true if: + // - a non-fixed variable, at one of its boumds, has its reduced + // cost close to zero. + // or if: + // - a non-equality constraint (i.e. l <= a.x <= r, with l != r), is at one of + // its bounds (a.x = r or a.x = l) and has its dual value close to zero. + bool IsOptimalSolutionOnFacet(const LinearProgram& lp); + + // Computes derived quantities from the solution. + void ComputeReducedCosts(const LinearProgram& lp); + void ComputeConstraintActivities(const LinearProgram& lp); + + // Computes the primal/dual objectives (without the offset). Note that the + // dual objective needs the reduced costs in addition to the dual values. + double ComputeObjective(const LinearProgram& lp); + double ComputeDualObjective(const LinearProgram& lp); + + // Given a relative precision on the primal values of up to + // solution_feasibility_tolerance(), this returns an upper bound on the + // expected precision of the objective. + double ComputeMaxExpectedObjectiveError(const LinearProgram& lp); + + // Returns the max absolute cost pertubation (resp. rhs perturbation) so that + // the pair (primal values, dual values) is an EXACT optimal solution to the + // perturbed problem. Note that this assumes that + // MovePrimalValuesWithinBounds() and MoveDualValuesWithinBounds() have + // already been called. The Boolean is_too_large is set to true if any of the + // perturbation exceed the tolerance (which depends of the coordinate). + // + // These bounds are computed using the variable and constraint statuses by + // enforcing the complementary slackness optimal conditions. Note that they + // are almost the same as ComputeActivityInfeasibility() and + // ComputeReducedCostInfeasibility() but looks for optimality rather than just + // feasibility. + // + // Note(user): We could get EXACT bounds on these perturbations by changing + // the rounding mode appropriately during these computations. But this is + // probably not needed. + Fractional ComputeMaxCostPerturbationToEnforceOptimality( + const LinearProgram& lp, bool* is_too_large); + Fractional ComputeMaxRhsPerturbationToEnforceOptimality( + const LinearProgram& lp, bool* is_too_large); + + // Computes the maximum of the infeasibilities associated with each values. + // The returned infeasibilities are the maximum of the "absolute" errors of + // each vector coefficients. + // + // These function also set is_too_large to true if any infeasibility is + // greater than the tolerance (which depends of the coordinate). + double ComputePrimalValueInfeasibility(const LinearProgram& lp, + bool* is_too_large); + double ComputeActivityInfeasibility(const LinearProgram& lp, + bool* is_too_large); + double ComputeDualValueInfeasibility(const LinearProgram& lp, + bool* is_too_large); + double ComputeReducedCostInfeasibility(const LinearProgram& lp, + bool* is_too_large); + + // On a call to Solve(), this is initialized to an exact copy of the given + // linear program. It is later modified by the preprocessors and then solved + // by the revised simplex. + // + // This is not efficient memory-wise but allows to check optimality with + // respect to the given LinearProgram that is guaranteed to not have been + // modified. It also allows for a nicer Solve() API with a const + // LinearProgram& input. + LinearProgram current_linear_program_; + + // The revised simplex solver. + std::unique_ptr revised_simplex_; + + // The number of revised simplex iterations used by the last Solve(). + int num_revised_simplex_iterations_; + + + // The current ProblemSolution. + // TODO(user): use a ProblemSolution directly? + DenseRow primal_values_; + DenseColumn dual_values_; + VariableStatusRow variable_statuses_; + ConstraintStatusColumn constraint_statuses_; + + // Quantities computed from the solution and the linear program. + DenseRow reduced_costs_; + DenseColumn constraint_activities_; + Fractional problem_objective_value_; + bool may_have_multiple_solutions_; + Fractional max_absolute_primal_infeasibility_; + Fractional max_absolute_dual_infeasibility_; + + // Proto holding all the parameters of the algorithm. + GlopParameters parameters_; + + // The number of times Solve() was called. Used to number dump files. + int num_solves_; + + DISALLOW_COPY_AND_ASSIGN(LPSolver); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_LP_SOLVER_H_ diff --git a/thirdparty/linux/include/ortools/glop/lu_factorization.h b/thirdparty/linux/include/ortools/glop/lu_factorization.h new file mode 100644 index 0000000..99ca95a --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/lu_factorization.h @@ -0,0 +1,306 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_LU_FACTORIZATION_H_ +#define OR_TOOLS_GLOP_LU_FACTORIZATION_H_ + +#include "ortools/glop/markowitz.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/status.h" +#include "ortools/lp_data/sparse.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace glop { + +// An LU-Factorization class encapsulating the LU factorization data and +// algorithms. The actual algorithm is in markowitz.h and .cc. This class holds +// all the Solve() functions that deal with the permutations and the L and U +// factors once they are computed. +// +// TODO(user): Add a ScatteredColumn class containing a DenseColumn and +// an EntryRowIndexVector non-zero pattern. +class LuFactorization { + public: + LuFactorization(); + + // Returns true if the LuFactorization is a factorization of the identity + // matrix. In this state, all the Solve() functions will work for any + // vector dimension. + bool IsIdentityFactorization() { return is_identity_factorization_; } + + // Clears internal data structure and reset this class to the factorization + // of an identity matrix. + void Clear(); + + // Computes an LU-decomposition for a given matrix B. If for some reason, + // there was an error, then the factorization is reset to the one of the + // identity matrix, and an error is reported. + // + // Note(user): Since a client must use the result, there is little chance of + // it being confused by this revert to identity factorization behavior. The + // reason behind it is that this way, calling any public function of this + // class will never cause a crash of the program. + Status ComputeFactorization(const MatrixView& matrix) MUST_USE_RESULT; + + // Returns the column permutation used by the LU factorization. + const ColumnPermutation& GetColumnPermutation() const { return col_perm_; } + + // Sets the column permutation to the identity permutation. The idea is that + // the column permutation can be incorporated in the basis RowToColMapping, + // and once this is done, then a client can call this and effectively remove + // the need for a column permutation on each solve. + void SetColumnPermutationToIdentity() { + col_perm_.clear(); + inverse_col_perm_.clear(); + } + + // Solves 'B.x = b', x initially contains b, and is replaced by 'B^{-1}.b'. + // Since P.B.Q^{-1} = L.U, we have B = P^{-1}.L.U.Q. + // 1/ Solve P^{-1}.y = b for y by computing y = P.b, + // 2/ solve L.z = y for z, + // 3/ solve U.t = z for t, + // 4/ finally solve Q.x = t, by computing x = Q^{-1}.t. + void RightSolve(DenseColumn* x) const; + + // Same as RightSolve(), but takes a SparseColumn b as an input. It also needs + // the number of rows because if the matrix is the identity matrix, this is + // not stored in this class or in the given sparse column. + void SparseRightSolve(const SparseColumn& b, RowIndex num_rows, + DenseColumn* x) const; + + // Solves 'y.B = r', y initially contains r, and is replaced by r.B^{-1}. + // Internally, it takes x = y^T, b = r^T and solves B^T.x = b. + // We have P.B.Q^{-1} = P.B.Q^T = L.U, thus (L.U)^T = Q.B^T.P^T. + // Therefore B^T = Q^{-1}.U^T.L^T.P^T.P^{-1} = Q^{-1}.U^T.L^T.P + // The procedure is thus: + // 1/ Solve Q^{-1}.y = b for y, by computing y = Q.b, + // 2/ solve U^T.z = y for z, + // 3/ solve L^T.t = z for t, + // 4/ finally, solve P.x = t for x by computing x = P^{-1}.t. + void LeftSolve(DenseRow* y) const; + + // Same as LeftSolve(), but exploits the given non_zeros of the input. + // Also returns the non-zeros patern of the result in non_zeros. + void SparseLeftSolve(DenseRow* y, ColIndexVector* non_zeros) const; + + // More fine-grained right/left solve functions. + // Note that a solve involving L actually solves P^{-1}.L and a solve + // involving U actually solves U.Q. To solve a system with the initial matrix + // B, one needs to call: + // - RightSolveL() and then RightSolveU() for a right solve (B.x = initial x). + // - LeftSolveU() and then LeftSolveL() for a left solve (y.B = initial y). + void RightSolveL(DenseColumn* x) const; + void RightSolveU(DenseColumn* x) const; + void LeftSolveU(DenseRow* y) const; + void LeftSolveL(DenseRow* y) const; + + // Specialized version of RightSolveL() that takes a SparseColumn (or a + // ScatteredColumnReference) as input. non_zeros will either be cleared or set + // to the non zeros of the result. Important: the output x must be of the + // correct size and all zero. + void RightSolveLForSparseColumn(const SparseColumn& b, DenseColumn* x, + std::vector* non_zeros) const; + void RightSolveLForScatteredColumn(const ScatteredColumnReference& b, + DenseColumn* x, + std::vector* non_zeros) const; + + // Specialized version of RightSolveL() where x is originaly equal to + // 'a' permuted by row_perm_. Note that 'a' is only used for DCHECK or when + // is_identity_factorization_ is true, in which case the assumption of x is + // relaxed since x is not used at all. + void RightSolveLWithPermutedInput(const DenseColumn& a, DenseColumn* x) const; + + // Specialized version of LeftSolveU() for an unit right-hand side. + // non_zeros will either be cleared or set to the non zeros of the results. + // It also returns the value of col permuted by Q (which is the position + // of the unit-vector rhs in the solve system: y.U = rhs). + // Important: the output y must be of the correct size and all zero. + ColIndex LeftSolveUForUnitRow(ColIndex col, DenseRow* y, + std::vector* non_zeros) const; + + // Specialized version of RightSolveU() and LeftSolveU() that may exploit the + // initial non-zeros if it is non-empty. In addition, + // RightSolveUWithNonZeros() always return the non-zeros of the output. + void RightSolveUWithNonZeros(DenseColumn* x, + std::vector* non_zeros) const; + void LeftSolveUWithNonZeros(DenseRow* y, + std::vector* non_zeros) const; + + // Specialized version of LeftSolveL() that also computes the non-zero + // pattern of the output. Moreover, if result_before_permutation is not NULL, + // it is filled with the result just before row_perm_ is applied to it and + // true is returned. If result_before_permutation is not filled, then false is + // returned. + bool LeftSolveLWithNonZeros(DenseRow* y, ColIndexVector* non_zeros, + DenseColumn* result_before_permutation) const; + + // Returns the given column of U. + // It will only be valid until the next call to GetColumnOfU(). + const SparseColumn& GetColumnOfU(ColIndex col) const; + + // Returns the norm of B^{-1}.a + Fractional RightSolveSquaredNorm(const SparseColumn& a) const; + + // Returns the norm of (B^T)^{-1}.e_row where e is an unit vector. + Fractional DualEdgeSquaredNorm(RowIndex row) const; + + // The fill-in of the LU-factorization is defined as the sum of the number + // of entries of both the lower- and upper-triangular matrices L and U minus + // the number of entries in the initial matrix B. + // + // This returns the number of entries in lower + upper as the percentage of + // the number of entries in B. + double GetFillInPercentage(const MatrixView& matrix) const; + + // Returns the number of entries in L + U. + // If the factorization is the identity, this returns 0. + EntryIndex NumberOfEntries() const; + + // Computes the determinant of the input matrix B. + // Since P.B.Q^{-1} = L.U, det(P) * det(B) * det(Q^{-1}) = det(L) * det(U). + // det(L) = 1 since L is a lower-triangular matrix with 1 on the diagonal. + // det(P) = +1 or -1 (by definition it is the sign of the permutation P) + // det(Q^{-1}) = +1 or -1 (the sign of the permutation Q^{-1}) + // Finally det(U) = product of the diagonal elements of U, since U is an + // upper-triangular matrix. + // Taking all this into account: + // det(B) = sign(P) * sign(Q^{-1}) * prod_i u_ii . + Fractional ComputeDeterminant() const; + + // Computes the 1-norm of the inverse of the input matrix B. + // For this we iteratively solve B.x = e_j, where e_j is the jth unit vector. + // The result of this computation is the jth column of B^-1. + // The 1-norm |B| is defined as max_j sum_i |a_ij| + // http://en.wikipedia.org/wiki/Matrix_norm + Fractional ComputeInverseOneNorm() const; + + // Computes the infinity-norm of the inverse of the input matrix B. + // The infinity-norm |B| is defined as max_i sum_j |a_ij| + // http://en.wikipedia.org/wiki/Matrix_norm + Fractional ComputeInverseInfinityNorm() const; + + // Computes the condition number of the input matrix B. + // For a given norm, this is the matrix norm times the norm of its inverse. + // + // Note that because the LuFactorization class does not keep the + // non-factorized matrix in memory, it needs to be passed to these functions. + // It is up to the client to pass exactly the same matrix as the one used + // for ComputeFactorization(). + // + // TODO(user): separate this from LuFactorization. + Fractional ComputeOneNormConditionNumber(const MatrixView& matrix) const; + Fractional ComputeInfinityNormConditionNumber(const MatrixView& matrix) const; + + // Sets the current parameters. + void SetParameters(const GlopParameters& parameters) { + parameters_ = parameters; + markowitz_.SetParameters(parameters); + } + + // Returns a std::string containing the statistics for this class. + std::string StatString() const { + return stats_.StatString() + markowitz_.StatString(); + } + + // This is only used for testing and in debug mode. + // TODO(user): avoid the matrix conversion by multiplying TriangularMatrix + // directly. + void ComputeLowerTimesUpper(SparseMatrix* product) const { + SparseMatrix temp_lower, temp_upper; + lower_.CopyToSparseMatrix(&temp_lower); + upper_.CopyToSparseMatrix(&temp_upper); + product->PopulateFromProduct(temp_lower, temp_upper); + } + + // Visible for testing. + const RowPermutation& row_perm() const { return row_perm_; } + const ColumnPermutation& inverse_col_perm() const { + return inverse_col_perm_; + } + + private: + // Statistics about this class. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("LuFactorization"), + basis_num_entries("basis_num_entries", this), + lu_fill_in("lu_fill_in", this) {} + IntegerDistribution basis_num_entries; + RatioDistribution lu_fill_in; + }; + + // Internal function used in the left solve functions. + void LeftSolveScratchpad() const; + + // Fills transpose_upper_ from upper_. + void ComputeTransposeUpper(); + + // transpose_lower_ is only needed when we compute dual norms. + void ComputeTransposeLower() const; + + // Computes R = P.B.Q^{-1} - L.U and returns false if the largest magnitude of + // the coefficients of P.B.Q^{-1} - L.U is greater than tolerance. + bool CheckFactorization(const MatrixView& matrix, Fractional tolerance) const; + + // Special case where we have nothing to do. This happens at the beginning + // when we start the problem with an all-slack basis and gives a good speedup + // on really easy problems. It is initially true and set to true each time we + // call Clear(). We set it to false if a call to ComputeFactorization() + // succeeds. + bool is_identity_factorization_; + + // The triangular factor L and U (and its transpose). + TriangularMatrix lower_; + TriangularMatrix upper_; + TriangularMatrix transpose_upper_; + + // The transpose of lower_. It is just used by DualEdgeSquaredNorm() + // and mutable so it can be lazily initialized. + mutable TriangularMatrix transpose_lower_; + + // The column permutation Q and its inverse Q^{-1} in P.B.Q^{-1} = L.U. + ColumnPermutation col_perm_; + ColumnPermutation inverse_col_perm_; + + // The row permutation P and its inverse P^{-1} in P.B.Q^{-1} = L.U. + RowPermutation row_perm_; + RowPermutation inverse_row_perm_; + + // Temporary storage used by LeftSolve()/RightSolve(). + mutable DenseColumn dense_column_scratchpad_; + + // Temporary storage used by GetColumnOfU(). + mutable SparseColumn column_of_upper_; + + // Same as dense_column_scratchpad_ but this vector is always reset to zero by + // the functions that use it. non_zero_rows_ is used to track the + // non_zero_rows_ position of dense_column_scratchpad_. + mutable DenseColumn dense_zero_scratchpad_; + mutable std::vector non_zero_rows_; + + // Statistics, mutable so const functions can still update it. + mutable Stats stats_; + + // Proto holding all the parameters of this algorithm. + GlopParameters parameters_; + + // The class doing the Markowitz LU factorization. + Markowitz markowitz_; + + DISALLOW_COPY_AND_ASSIGN(LuFactorization); +}; + +} // namespace glop +} // namespace operations_research +#endif // OR_TOOLS_GLOP_LU_FACTORIZATION_H_ diff --git a/thirdparty/linux/include/ortools/glop/markowitz.h b/thirdparty/linux/include/ortools/glop/markowitz.h new file mode 100644 index 0000000..e3186b4 --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/markowitz.h @@ -0,0 +1,435 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// LU decomposition algorithm of a sparse matrix B with Markowitz pivot +// selection strategy. The algorithm constructs a lower matrix L, upper matrix +// U, row permutation P and a column permutation Q such that L.U = P.B.Q^{-1}. +// +// The current algorithm is a mix of ideas that can be found in the literature +// and of some optimizations tailored for its use in a revised simplex algorithm +// (like a fast processing of the singleton columns present in B). It constructs +// L and U column by column from left to right. +// +// A key concept is the one of the residual matrix which is the bottom right +// square submatrix that still needs to be factorized during the classical +// Gaussian elimination. The algorithm maintains the non-zero pattern of its +// rows and its row/column degrees. +// +// At each step, a number of columns equal to 'markowitz_zlatev_parameter' are +// chosen as candidates from the residual matrix. They are the ones with minimal +// residual column degree. They can be found easily because the columns of the +// residual matrix are kept in a priority queue. +// +// We compute the numerical value of these residual columns like in a +// left-looking algorithm by solving a sparse lower-triangular system with the +// current L constructed so far. Note that this step is highly optimized for +// sparsity and we reuse the computations done in the previous steps (if the +// candidate column was already considered before). As a by-product, we also +// get the corresponding column of U. +// +// Among the entries of these columns, a pivot is chosen such that the product: +// (num_column_entries - 1) * (num_row_entries - 1) +// is minimized. Only the pivots with a magnitude greater than +// 'lu_factorization_pivot_threshold' times the maximum magnitude of the +// corresponding residual column are considered for stability reasons. +// +// Once the pivot is chosen, the residual column divided by the pivot becomes a +// column of L, and the non-zero pattern of the new residual submatrix is +// updated by subtracting the outer product of this pivot column times the pivot +// row. The product minimized above is thus an upper bound of the number of +// fill-in created during a step. +// +// References: +// +// J. R. Gilbert and T. Peierls, "Sparse partial pivoting in time proportional +// to arithmetic operations," SIAM J. Sci. Statist. Comput., 9 (1988): 862-874. +// +// I.S. Duff, A.M. Erisman and J.K. Reid, "Direct Methods for Sparse Matrices", +// Clarendon, Oxford, UK, 1987, ISBN 0-19-853421-3, +// http://www.amazon.com/dp/0198534213 +// +// T.A. Davis, "Direct methods for Sparse Linear Systems", SIAM, Philadelphia, +// 2006, ISBN-13: 978-0-898716-13, http://www.amazon.com/dp/0898716136 +// +// TODO(user): Determine whether any of these would bring any benefit: +// - S.C. Eisenstat and J.W.H. Liu, "The theory of elimination trees for +// sparse unsymmetric matrices," SIAM J. Matrix Anal. Appl., 26:686-705, +// January 2005 +// - S.C. Eisenstat and J.W.H. Liu. "Algorithmic aspects of elimination trees +// for sparse unsymmetric matrices," SIAM J. Matrix Anal. Appl., +// 29:1363-1381, January 2008. +// - http://perso.ens-lyon.fr/~bucar/papers/kauc.pdf + +#ifndef OR_TOOLS_GLOP_MARKOWITZ_H_ +#define OR_TOOLS_GLOP_MARKOWITZ_H_ + +#include + +#include "ortools/base/logging.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/status.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/lp_data/sparse.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace glop { + +// Holds the non-zero positions (by row) and column/row degree of the residual +// matrix during the Gaussian elimination. +// +// During each step of Gaussian elimination, a row and a column will be +// "removed" from the residual matrix. Note however that the row and column +// indices of the non-removed part do not change, so the residual matrix at a +// given step will only correspond to a subset of the initial indices. +class MatrixNonZeroPattern { + public: + MatrixNonZeroPattern() {} + + // Releases the memory used by this class. + void Clear(); + + // Resets the pattern to the one of an empty square matrix of the given size. + void Reset(RowIndex num_rows, ColIndex num_cols); + + // Resets the pattern to the one of the given matrix but only for the + // rows/columns whose given permutation is kInvalidRow or kInvalidCol. + void InitializeFromMatrixSubset(const MatrixView& basis_matrix, + const RowPermutation& row_perm, + const ColumnPermutation& col_perm); + + // Adds a non-zero entry to the matrix. There should be no duplicates. + void AddEntry(RowIndex row, ColIndex col); + + // Marks the given pivot row and column as deleted. + // This is called at each step of the Gaussian elimination on the pivot. + void DeleteRowAndColumn(RowIndex pivot_row, ColIndex pivot_col); + + // Decreases the degree of a row/column. This is the basic operation used to + // keep the correct degree after a call to DeleteRowAndColumn(). This is + // because row_non_zero_[row] is only lazily cleaned. + int32 DecreaseRowDegree(RowIndex row); + int32 DecreaseColDegree(ColIndex col); + + // Returns true if the column has been deleted by DeleteRowAndColumn(). + bool IsColumnDeleted(ColIndex col) const; + + // Removes from the corresponding row_non_zero_[row] the columns that have + // been previously deleted by DeleteRowAndColumn(). + void RemoveDeletedColumnsFromRow(RowIndex row); + + // Returns the first non-deleted column index from this row or kInvalidCol if + // none can be found. + ColIndex GetFirstNonDeletedColumnFromRow(RowIndex row) const; + + // Performs a generic Gaussian update of the residual matrix: + // - DeleteRowAndColumn() must already have been called. + // - The non-zero pattern is augmented (set union) by the one of the + // outer product of the pivot column and row. + // + // Important: as a small optimization, this function does not call + // DecreaseRowDegree() on the row in the pivot column. This has to be done by + // the client. + void Update(RowIndex pivot_row, ColIndex pivot_col, + const SparseColumn& column); + + // Returns the degree (i.e. the number of non-zeros) of the given column. + // This is only valid for the column indices still in the residual matrix. + int32 ColDegree(ColIndex col) const { + DCHECK(!deleted_columns_[col]); + return col_degree_[col]; + } + + // Returns the degree (i.e. the number of non-zeros) of the given row. + // This is only valid for the row indices still in the residual matrix. + int32 RowDegree(RowIndex row) const { return row_degree_[row]; } + + // Returns the set of non-zeros of the given row (unsorted). + // Call RemoveDeletedColumnsFromRow(row) to clean the row first. + // This is only valid for the row indices still in the residual matrix. + const std::vector& RowNonZero(RowIndex row) const { + return row_non_zero_[row]; + } + + private: + // Augments the non-zero pattern of the given row by taking its union with the + // non-zero pattern of the given pivot_row. + void MergeInto(RowIndex pivot_row, RowIndex row); + + // Different version of MergeInto() that works only if the non-zeros position + // of each row are sorted in increasing order. The output will also be sorted. + // + // TODO(user): This is currently not used but about the same speed as the + // non-sorted version. Investigate more. + void MergeIntoSorted(RowIndex pivot_row, RowIndex row); + + ITIVector> row_non_zero_; + StrictITIVector row_degree_; + StrictITIVector col_degree_; + DenseBooleanRow deleted_columns_; + DenseBooleanRow bool_scratchpad_; + std::vector col_scratchpad_; + ColIndex num_non_deleted_columns_; + + DISALLOW_COPY_AND_ASSIGN(MatrixNonZeroPattern); +}; + +// Adjustable priority queue of columns. Pop() returns a column with the +// smallest degree first (degree = number of entries in the column). +// Empty columns (i.e. with degree 0) are not stored in the queue. +class ColumnPriorityQueue { + public: + ColumnPriorityQueue() {} + + // Releases the memory used by this class. + void Clear(); + + // Clears the queue and prepares it to store up to num_cols column indices + // with a degree from 1 to max_degree included. + void Reset(int32 max_degree, ColIndex num_cols); + + // Changes the degree of a column and make sure it is in the queue. The degree + // must be non-negative (>= 0) and at most equal to the value of num_cols used + // in Reset(). A degree of zero will remove the column from the queue. + void PushOrAdjust(ColIndex col, int32 degree); + + // Removes the column index with higher priority from the queue and returns + // it. Returns kInvalidCol if the queue is empty. + ColIndex Pop(); + + private: + StrictITIVector col_index_; + StrictITIVector col_degree_; + std::vector> col_by_degree_; + int32 min_degree_; + DISALLOW_COPY_AND_ASSIGN(ColumnPriorityQueue); +}; + +// Contains a set of columns indexed by ColIndex. This is like a SparseMatrix +// but this class is optimized for the case where only a small subset of columns +// is needed at the same time (like it is the case in our LU algorithm). It +// reuses the memory of the columns that are no longer needed. +class SparseMatrixWithReusableColumnMemory { + public: + SparseMatrixWithReusableColumnMemory() {} + + // Resets the repository to num_cols empty columns. + void Reset(ColIndex num_cols); + + // Returns the column with given index. + const SparseColumn& column(ColIndex col) const; + + // Gets the mutable column with given column index. The returned vector + // address is only valid until the next call to mutable_column(). + SparseColumn* mutable_column(ColIndex col); + + // Clears the column with given index and releases its memory to the common + // memory pool that is used to create new mutable_column() on demand. + void ClearAndReleaseColumn(ColIndex col); + + // Reverts this class to its initial state. This releases the memory of the + // columns that were used but not the memory of this class member (this should + // be fine). + void Clear(); + + private: + // mutable_column(col) is stored in columns_[mapping_[col]]. + // The columns_ that can be reused have their index stored in free_columns_. + const SparseColumn empty_column_; + ITIVector mapping_; + std::vector free_columns_; + std::vector columns_; + DISALLOW_COPY_AND_ASSIGN(SparseMatrixWithReusableColumnMemory); +}; + +// The class that computes either the actual L.U decomposition, or the +// permutation P and Q such that P.B.Q^{-1} will have a sparse L.U +// decomposition. +class Markowitz { + public: + Markowitz() {} + + // Computes the full factorization with P, Q, L and U. + // + // If the matrix is singular, the returned status will indicate it and the + // permutation (col_perm) will contain a maximum non-singular set of columns + // of the matrix. Moreover, by adding singleton columns with a one at the rows + // such that 'row_perm[row] == kInvalidRow', then the matrix will be + // non-singular. + Status ComputeLU(const MatrixView& basis_matrix, RowPermutation* row_perm, + ColumnPermutation* col_perm, TriangularMatrix* lower, + TriangularMatrix* upper) MUST_USE_RESULT; + + // Only computes P and Q^{-1}, L and U can be computed later from these + // permutations using another algorithm (for instance left-looking L.U). This + // may be faster than computing the full L and U at the same time but the + // current implementation is not optimized for this. + // + // It behaves the same as ComputeLU() for singular matrices. + // + // This function also works with a non-square matrix. It will return a set of + // independent columns of maximum size. If all the given columns are + // independent, the returned Status will be OK. + Status ComputeRowAndColumnPermutation( + const MatrixView& basis_matrix, RowPermutation* row_perm, + ColumnPermutation* col_perm) MUST_USE_RESULT; + + // Releases the memory used by this class. + void Clear(); + + // Returns a std::string containing the statistics for this class. + std::string StatString() const { return stats_.StatString(); } + + // Sets the current parameters. + void SetParameters(const GlopParameters& parameters) { + parameters_ = parameters; + } + + private: + // Statistics about this class. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("Markowitz"), + basis_singleton_column_ratio("basis_singleton_column_ratio", this), + basis_residual_singleton_column_ratio( + "basis_residual_singleton_column_ratio", this), + pivots_without_fill_in_ratio("pivots_without_fill_in_ratio", this), + degree_two_pivot_columns("degree_two_pivot_columns", this) {} + RatioDistribution basis_singleton_column_ratio; + RatioDistribution basis_residual_singleton_column_ratio; + RatioDistribution pivots_without_fill_in_ratio; + RatioDistribution degree_two_pivot_columns; + }; + Stats stats_; + + // Initializes residual_matrix_non_zero_, singleton_column_ and + // singleton_row_. + void InitializeResidualMatrix(const MatrixView& basis_matrix, + const RowPermutation& row_perm, + const ColumnPermutation& col_perm); + + // Fast track for singleton columns of the matrix. Fills a part of the row and + // column permutation that move these columns in order to form an identity + // sub-matrix on the upper left. + // + // Note(user): Linear programming bases usually have a resonable percentage of + // slack columns in them, so this gives a big speedup. + void ExtractSingletonColumns(const MatrixView& basis_matrix, + RowPermutation* row_perm, + ColumnPermutation* col_perm, int* index); + + // Fast track for columns that form a triangular matrix. This does not find + // all of them, but because the column are ordered in the same way they were + // ordered at the end of the previous factorization, this is likely to find + // quite a few. + // + // The main gain here is that it avoids taking these columns into account in + // InitializeResidualMatrix() and later in RemoveRowFromResidualMatrix(). + void ExtractResidualSingletonColumns(const MatrixView& basis_matrix, + RowPermutation* row_perm, + ColumnPermutation* col_perm, int* index); + + // Returns the column of the current residual matrix with an index 'col' in + // the initial matrix. We compute it by solving a linear system with the + // current lower_ and the last computed column 'col' of a previous residual + // matrix. This uses the same algorithm as a left-looking factorization (see + // lu_factorization.h for more details). + const SparseColumn& ComputeColumn(const RowPermutation& row_perm, + ColIndex col); + + // Finds an entry in the residual matrix with a low Markowitz score and a high + // enough magnitude. Returns its Markowitz score and updates the given + // pointers. + // + // We use the strategy of Zlatev, "On some pivotal strategies in Gaussian + // elimination by sparse technique" (1980). SIAM J. Numer. Anal. 17 18-30. It + // consists of looking for the best pivot in only a few columns (usually 3 + // or 4) amongst the ones which have the lowest number of entries. + // + // Amongst the pivots with a minimum Markowitz number, we choose the one + // with highest magnitude. This doesn't apply to pivots with a 0 Markowitz + // number because all such pivots will have to be taken at some point anyway. + int64 FindPivot(const RowPermutation& row_perm, + const ColumnPermutation& col_perm, RowIndex* pivot_row, + ColIndex* pivot_col, Fractional* pivot_coefficient); + + // Updates the degree of a given column in the internal structure of the + // class. + void UpdateDegree(ColIndex col, int degree); + + // Removes all the coefficients in the residual matrix that are on the given + // row or column. In both cases, the pivot row or column is ignored. + void RemoveRowFromResidualMatrix(RowIndex pivot_row, ColIndex pivot_col); + void RemoveColumnFromResidualMatrix(RowIndex pivot_row, ColIndex pivot_col); + + // Updates the residual matrix given the pivot position. This is needed if the + // pivot row and pivot column both have more than one entry. Otherwise, the + // residual matrix can be updated more efficiently by calling one of the + // Remove...() functions above. + void UpdateResidualMatrix(RowIndex pivot_row, ColIndex pivot_col); + + // Pointer to the matrix to factorize. + MatrixView const* basis_matrix_; + + // These matrices are transformed during the algorithm into the final L and U + // matrices modulo some row and column permutations. Note that the columns of + // these matrices stay in the initial order. + SparseMatrixWithReusableColumnMemory permuted_lower_; + SparseMatrixWithReusableColumnMemory permuted_upper_; + + // These matrices will hold the final L and U. The are created columns by + // columns from left to right, and at the end, their rows are permuted by + // ComputeLU() to become triangular. + TriangularMatrix lower_; + TriangularMatrix upper_; + + // The columns of permuted_lower_ for which we do need a call to + // PermutedLowerSparseSolve(). This speeds up ComputeColumn(). + DenseBooleanRow permuted_lower_column_needs_solve_; + + // Contains the non-zero positions of the current residual matrix (the + // lower-right square matrix that gets smaller by one row and column at each + // Gaussian elimination step). + MatrixNonZeroPattern residual_matrix_non_zero_; + + // Data structure to access the columns by increasing degree. + ColumnPriorityQueue col_by_degree_; + + // True as long as only singleton columns of the residual matrix are used. + bool contains_only_singleton_columns_; + + // Boolean used to know when col_by_degree_ become useful. + bool is_col_by_degree_initialized_; + + // FindPivot() needs to look at the first entries of col_by_degree_, it + // temporary put them here before pushing them back to col_by_degree_. + std::vector examined_col_; + + // Singleton column indices are kept here rather than in col_by_degree_ to + // optimize the algorithm: as long as this or singleton_row_ are not empty, + // col_by_degree_ do not need to be initialized nor updated. + std::vector singleton_column_; + + // List of singleton row indices. + std::vector singleton_row_; + + // Proto holding all the parameters of this algorithm. + GlopParameters parameters_; + + DISALLOW_COPY_AND_ASSIGN(Markowitz); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_MARKOWITZ_H_ diff --git a/thirdparty/linux/include/ortools/glop/parameters.pb.h b/thirdparty/linux/include/ortools/glop/parameters.pb.h new file mode 100644 index 0000000..9bd9af6 --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/parameters.pb.h @@ -0,0 +1,1913 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/glop/parameters.proto + +#ifndef PROTOBUF_ortools_2fglop_2fparameters_2eproto__INCLUDED +#define PROTOBUF_ortools_2fglop_2fparameters_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { +namespace glop { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fglop_2fparameters_2eproto(); +void protobuf_AssignDesc_ortools_2fglop_2fparameters_2eproto(); +void protobuf_ShutdownFile_ortools_2fglop_2fparameters_2eproto(); + +class GlopParameters; + +enum GlopParameters_SolverBehavior { + GlopParameters_SolverBehavior_ALWAYS_DO = 0, + GlopParameters_SolverBehavior_NEVER_DO = 1, + GlopParameters_SolverBehavior_LET_SOLVER_DECIDE = 2 +}; +bool GlopParameters_SolverBehavior_IsValid(int value); +const GlopParameters_SolverBehavior GlopParameters_SolverBehavior_SolverBehavior_MIN = GlopParameters_SolverBehavior_ALWAYS_DO; +const GlopParameters_SolverBehavior GlopParameters_SolverBehavior_SolverBehavior_MAX = GlopParameters_SolverBehavior_LET_SOLVER_DECIDE; +const int GlopParameters_SolverBehavior_SolverBehavior_ARRAYSIZE = GlopParameters_SolverBehavior_SolverBehavior_MAX + 1; + +const ::google::protobuf::EnumDescriptor* GlopParameters_SolverBehavior_descriptor(); +inline const ::std::string& GlopParameters_SolverBehavior_Name(GlopParameters_SolverBehavior value) { + return ::google::protobuf::internal::NameOfEnum( + GlopParameters_SolverBehavior_descriptor(), value); +} +inline bool GlopParameters_SolverBehavior_Parse( + const ::std::string& name, GlopParameters_SolverBehavior* value) { + return ::google::protobuf::internal::ParseNamedEnum( + GlopParameters_SolverBehavior_descriptor(), name, value); +} +enum GlopParameters_PricingRule { + GlopParameters_PricingRule_DANTZIG = 0, + GlopParameters_PricingRule_STEEPEST_EDGE = 1, + GlopParameters_PricingRule_DEVEX = 2 +}; +bool GlopParameters_PricingRule_IsValid(int value); +const GlopParameters_PricingRule GlopParameters_PricingRule_PricingRule_MIN = GlopParameters_PricingRule_DANTZIG; +const GlopParameters_PricingRule GlopParameters_PricingRule_PricingRule_MAX = GlopParameters_PricingRule_DEVEX; +const int GlopParameters_PricingRule_PricingRule_ARRAYSIZE = GlopParameters_PricingRule_PricingRule_MAX + 1; + +const ::google::protobuf::EnumDescriptor* GlopParameters_PricingRule_descriptor(); +inline const ::std::string& GlopParameters_PricingRule_Name(GlopParameters_PricingRule value) { + return ::google::protobuf::internal::NameOfEnum( + GlopParameters_PricingRule_descriptor(), value); +} +inline bool GlopParameters_PricingRule_Parse( + const ::std::string& name, GlopParameters_PricingRule* value) { + return ::google::protobuf::internal::ParseNamedEnum( + GlopParameters_PricingRule_descriptor(), name, value); +} +enum GlopParameters_InitialBasisHeuristic { + GlopParameters_InitialBasisHeuristic_NONE = 0, + GlopParameters_InitialBasisHeuristic_BIXBY = 1, + GlopParameters_InitialBasisHeuristic_TRIANGULAR = 2 +}; +bool GlopParameters_InitialBasisHeuristic_IsValid(int value); +const GlopParameters_InitialBasisHeuristic GlopParameters_InitialBasisHeuristic_InitialBasisHeuristic_MIN = GlopParameters_InitialBasisHeuristic_NONE; +const GlopParameters_InitialBasisHeuristic GlopParameters_InitialBasisHeuristic_InitialBasisHeuristic_MAX = GlopParameters_InitialBasisHeuristic_TRIANGULAR; +const int GlopParameters_InitialBasisHeuristic_InitialBasisHeuristic_ARRAYSIZE = GlopParameters_InitialBasisHeuristic_InitialBasisHeuristic_MAX + 1; + +const ::google::protobuf::EnumDescriptor* GlopParameters_InitialBasisHeuristic_descriptor(); +inline const ::std::string& GlopParameters_InitialBasisHeuristic_Name(GlopParameters_InitialBasisHeuristic value) { + return ::google::protobuf::internal::NameOfEnum( + GlopParameters_InitialBasisHeuristic_descriptor(), value); +} +inline bool GlopParameters_InitialBasisHeuristic_Parse( + const ::std::string& name, GlopParameters_InitialBasisHeuristic* value) { + return ::google::protobuf::internal::ParseNamedEnum( + GlopParameters_InitialBasisHeuristic_descriptor(), name, value); +} +// =================================================================== + +class GlopParameters : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.glop.GlopParameters) */ { + public: + GlopParameters(); + virtual ~GlopParameters(); + + GlopParameters(const GlopParameters& from); + + inline GlopParameters& operator=(const GlopParameters& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const GlopParameters& default_instance(); + + void Swap(GlopParameters* other); + + // implements Message ---------------------------------------------- + + inline GlopParameters* New() const { return New(NULL); } + + GlopParameters* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const GlopParameters& from); + void MergeFrom(const GlopParameters& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(GlopParameters* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef GlopParameters_SolverBehavior SolverBehavior; + static const SolverBehavior ALWAYS_DO = + GlopParameters_SolverBehavior_ALWAYS_DO; + static const SolverBehavior NEVER_DO = + GlopParameters_SolverBehavior_NEVER_DO; + static const SolverBehavior LET_SOLVER_DECIDE = + GlopParameters_SolverBehavior_LET_SOLVER_DECIDE; + static inline bool SolverBehavior_IsValid(int value) { + return GlopParameters_SolverBehavior_IsValid(value); + } + static const SolverBehavior SolverBehavior_MIN = + GlopParameters_SolverBehavior_SolverBehavior_MIN; + static const SolverBehavior SolverBehavior_MAX = + GlopParameters_SolverBehavior_SolverBehavior_MAX; + static const int SolverBehavior_ARRAYSIZE = + GlopParameters_SolverBehavior_SolverBehavior_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + SolverBehavior_descriptor() { + return GlopParameters_SolverBehavior_descriptor(); + } + static inline const ::std::string& SolverBehavior_Name(SolverBehavior value) { + return GlopParameters_SolverBehavior_Name(value); + } + static inline bool SolverBehavior_Parse(const ::std::string& name, + SolverBehavior* value) { + return GlopParameters_SolverBehavior_Parse(name, value); + } + + typedef GlopParameters_PricingRule PricingRule; + static const PricingRule DANTZIG = + GlopParameters_PricingRule_DANTZIG; + static const PricingRule STEEPEST_EDGE = + GlopParameters_PricingRule_STEEPEST_EDGE; + static const PricingRule DEVEX = + GlopParameters_PricingRule_DEVEX; + static inline bool PricingRule_IsValid(int value) { + return GlopParameters_PricingRule_IsValid(value); + } + static const PricingRule PricingRule_MIN = + GlopParameters_PricingRule_PricingRule_MIN; + static const PricingRule PricingRule_MAX = + GlopParameters_PricingRule_PricingRule_MAX; + static const int PricingRule_ARRAYSIZE = + GlopParameters_PricingRule_PricingRule_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + PricingRule_descriptor() { + return GlopParameters_PricingRule_descriptor(); + } + static inline const ::std::string& PricingRule_Name(PricingRule value) { + return GlopParameters_PricingRule_Name(value); + } + static inline bool PricingRule_Parse(const ::std::string& name, + PricingRule* value) { + return GlopParameters_PricingRule_Parse(name, value); + } + + typedef GlopParameters_InitialBasisHeuristic InitialBasisHeuristic; + static const InitialBasisHeuristic NONE = + GlopParameters_InitialBasisHeuristic_NONE; + static const InitialBasisHeuristic BIXBY = + GlopParameters_InitialBasisHeuristic_BIXBY; + static const InitialBasisHeuristic TRIANGULAR = + GlopParameters_InitialBasisHeuristic_TRIANGULAR; + static inline bool InitialBasisHeuristic_IsValid(int value) { + return GlopParameters_InitialBasisHeuristic_IsValid(value); + } + static const InitialBasisHeuristic InitialBasisHeuristic_MIN = + GlopParameters_InitialBasisHeuristic_InitialBasisHeuristic_MIN; + static const InitialBasisHeuristic InitialBasisHeuristic_MAX = + GlopParameters_InitialBasisHeuristic_InitialBasisHeuristic_MAX; + static const int InitialBasisHeuristic_ARRAYSIZE = + GlopParameters_InitialBasisHeuristic_InitialBasisHeuristic_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + InitialBasisHeuristic_descriptor() { + return GlopParameters_InitialBasisHeuristic_descriptor(); + } + static inline const ::std::string& InitialBasisHeuristic_Name(InitialBasisHeuristic value) { + return GlopParameters_InitialBasisHeuristic_Name(value); + } + static inline bool InitialBasisHeuristic_Parse(const ::std::string& name, + InitialBasisHeuristic* value) { + return GlopParameters_InitialBasisHeuristic_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .operations_research.glop.GlopParameters.PricingRule feasibility_rule = 1 [default = STEEPEST_EDGE]; + bool has_feasibility_rule() const; + void clear_feasibility_rule(); + static const int kFeasibilityRuleFieldNumber = 1; + ::operations_research::glop::GlopParameters_PricingRule feasibility_rule() const; + void set_feasibility_rule(::operations_research::glop::GlopParameters_PricingRule value); + + // optional .operations_research.glop.GlopParameters.PricingRule optimization_rule = 2 [default = STEEPEST_EDGE]; + bool has_optimization_rule() const; + void clear_optimization_rule(); + static const int kOptimizationRuleFieldNumber = 2; + ::operations_research::glop::GlopParameters_PricingRule optimization_rule() const; + void set_optimization_rule(::operations_research::glop::GlopParameters_PricingRule value); + + // optional bool normalize_using_column_norm = 4 [default = true]; + bool has_normalize_using_column_norm() const; + void clear_normalize_using_column_norm(); + static const int kNormalizeUsingColumnNormFieldNumber = 4; + bool normalize_using_column_norm() const; + void set_normalize_using_column_norm(bool value); + + // optional bool use_nested_pricing = 5 [default = true]; + bool has_use_nested_pricing() const; + void clear_use_nested_pricing(); + static const int kUseNestedPricingFieldNumber = 5; + bool use_nested_pricing() const; + void set_use_nested_pricing(bool value); + + // optional double refactorization_threshold = 6 [default = 1e-08]; + bool has_refactorization_threshold() const; + void clear_refactorization_threshold(); + static const int kRefactorizationThresholdFieldNumber = 6; + double refactorization_threshold() const; + void set_refactorization_threshold(double value); + + // optional double recompute_reduced_costs_threshold = 8 [default = 1e-08]; + bool has_recompute_reduced_costs_threshold() const; + void clear_recompute_reduced_costs_threshold(); + static const int kRecomputeReducedCostsThresholdFieldNumber = 8; + double recompute_reduced_costs_threshold() const; + void set_recompute_reduced_costs_threshold(double value); + + // optional double recompute_edges_norm_threshold = 9 [default = 100]; + bool has_recompute_edges_norm_threshold() const; + void clear_recompute_edges_norm_threshold(); + static const int kRecomputeEdgesNormThresholdFieldNumber = 9; + double recompute_edges_norm_threshold() const; + void set_recompute_edges_norm_threshold(double value); + + // optional double primal_feasibility_tolerance = 10 [default = 1e-08]; + bool has_primal_feasibility_tolerance() const; + void clear_primal_feasibility_tolerance(); + static const int kPrimalFeasibilityToleranceFieldNumber = 10; + double primal_feasibility_tolerance() const; + void set_primal_feasibility_tolerance(double value); + + // optional double dual_feasibility_tolerance = 11 [default = 1e-10]; + bool has_dual_feasibility_tolerance() const; + void clear_dual_feasibility_tolerance(); + static const int kDualFeasibilityToleranceFieldNumber = 11; + double dual_feasibility_tolerance() const; + void set_dual_feasibility_tolerance(double value); + + // optional double ratio_test_zero_threshold = 12 [default = 1e-09]; + bool has_ratio_test_zero_threshold() const; + void clear_ratio_test_zero_threshold(); + static const int kRatioTestZeroThresholdFieldNumber = 12; + double ratio_test_zero_threshold() const; + void set_ratio_test_zero_threshold(double value); + + // optional double harris_tolerance_ratio = 13 [default = 0.5]; + bool has_harris_tolerance_ratio() const; + void clear_harris_tolerance_ratio(); + static const int kHarrisToleranceRatioFieldNumber = 13; + double harris_tolerance_ratio() const; + void set_harris_tolerance_ratio(double value); + + // optional double small_pivot_threshold = 14 [default = 1e-06]; + bool has_small_pivot_threshold() const; + void clear_small_pivot_threshold(); + static const int kSmallPivotThresholdFieldNumber = 14; + double small_pivot_threshold() const; + void set_small_pivot_threshold(double value); + + // optional double minimum_acceptable_pivot = 15 [default = 1e-06]; + bool has_minimum_acceptable_pivot() const; + void clear_minimum_acceptable_pivot(); + static const int kMinimumAcceptablePivotFieldNumber = 15; + double minimum_acceptable_pivot() const; + void set_minimum_acceptable_pivot(double value); + + // optional double drop_tolerance = 52 [default = 1e-14]; + bool has_drop_tolerance() const; + void clear_drop_tolerance(); + static const int kDropToleranceFieldNumber = 52; + double drop_tolerance() const; + void set_drop_tolerance(double value); + + // optional bool use_scaling = 16 [default = true]; + bool has_use_scaling() const; + void clear_use_scaling(); + static const int kUseScalingFieldNumber = 16; + bool use_scaling() const; + void set_use_scaling(bool value); + + // optional .operations_research.glop.GlopParameters.InitialBasisHeuristic initial_basis = 17 [default = TRIANGULAR]; + bool has_initial_basis() const; + void clear_initial_basis(); + static const int kInitialBasisFieldNumber = 17; + ::operations_research::glop::GlopParameters_InitialBasisHeuristic initial_basis() const; + void set_initial_basis(::operations_research::glop::GlopParameters_InitialBasisHeuristic value); + + // optional bool use_transposed_matrix = 18 [default = true]; + bool has_use_transposed_matrix() const; + void clear_use_transposed_matrix(); + static const int kUseTransposedMatrixFieldNumber = 18; + bool use_transposed_matrix() const; + void set_use_transposed_matrix(bool value); + + // optional int32 basis_refactorization_period = 19 [default = 64]; + bool has_basis_refactorization_period() const; + void clear_basis_refactorization_period(); + static const int kBasisRefactorizationPeriodFieldNumber = 19; + ::google::protobuf::int32 basis_refactorization_period() const; + void set_basis_refactorization_period(::google::protobuf::int32 value); + + // optional .operations_research.glop.GlopParameters.SolverBehavior solve_dual_problem = 20 [default = LET_SOLVER_DECIDE]; + bool has_solve_dual_problem() const; + void clear_solve_dual_problem(); + static const int kSolveDualProblemFieldNumber = 20; + ::operations_research::glop::GlopParameters_SolverBehavior solve_dual_problem() const; + void set_solve_dual_problem(::operations_research::glop::GlopParameters_SolverBehavior value); + + // optional double dualizer_threshold = 21 [default = 1.5]; + bool has_dualizer_threshold() const; + void clear_dualizer_threshold(); + static const int kDualizerThresholdFieldNumber = 21; + double dualizer_threshold() const; + void set_dualizer_threshold(double value); + + // optional double solution_feasibility_tolerance = 22 [default = 1e-06]; + bool has_solution_feasibility_tolerance() const; + void clear_solution_feasibility_tolerance(); + static const int kSolutionFeasibilityToleranceFieldNumber = 22; + double solution_feasibility_tolerance() const; + void set_solution_feasibility_tolerance(double value); + + // optional bool provide_strong_optimal_guarantee = 24 [default = true]; + bool has_provide_strong_optimal_guarantee() const; + void clear_provide_strong_optimal_guarantee(); + static const int kProvideStrongOptimalGuaranteeFieldNumber = 24; + bool provide_strong_optimal_guarantee() const; + void set_provide_strong_optimal_guarantee(bool value); + + // optional double max_number_of_reoptimizations = 56 [default = 40]; + bool has_max_number_of_reoptimizations() const; + void clear_max_number_of_reoptimizations(); + static const int kMaxNumberOfReoptimizationsFieldNumber = 56; + double max_number_of_reoptimizations() const; + void set_max_number_of_reoptimizations(double value); + + // optional double lu_factorization_pivot_threshold = 25 [default = 0.01]; + bool has_lu_factorization_pivot_threshold() const; + void clear_lu_factorization_pivot_threshold(); + static const int kLuFactorizationPivotThresholdFieldNumber = 25; + double lu_factorization_pivot_threshold() const; + void set_lu_factorization_pivot_threshold(double value); + + // optional double max_time_in_seconds = 26 [default = inf]; + bool has_max_time_in_seconds() const; + void clear_max_time_in_seconds(); + static const int kMaxTimeInSecondsFieldNumber = 26; + double max_time_in_seconds() const; + void set_max_time_in_seconds(double value); + + // optional double max_deterministic_time = 45 [default = inf]; + bool has_max_deterministic_time() const; + void clear_max_deterministic_time(); + static const int kMaxDeterministicTimeFieldNumber = 45; + double max_deterministic_time() const; + void set_max_deterministic_time(double value); + + // optional int64 max_number_of_iterations = 27 [default = -1]; + bool has_max_number_of_iterations() const; + void clear_max_number_of_iterations(); + static const int kMaxNumberOfIterationsFieldNumber = 27; + ::google::protobuf::int64 max_number_of_iterations() const; + void set_max_number_of_iterations(::google::protobuf::int64 value); + + // optional int32 markowitz_zlatev_parameter = 29 [default = 3]; + bool has_markowitz_zlatev_parameter() const; + void clear_markowitz_zlatev_parameter(); + static const int kMarkowitzZlatevParameterFieldNumber = 29; + ::google::protobuf::int32 markowitz_zlatev_parameter() const; + void set_markowitz_zlatev_parameter(::google::protobuf::int32 value); + + // optional double markowitz_singularity_threshold = 30 [default = 1e-15]; + bool has_markowitz_singularity_threshold() const; + void clear_markowitz_singularity_threshold(); + static const int kMarkowitzSingularityThresholdFieldNumber = 30; + double markowitz_singularity_threshold() const; + void set_markowitz_singularity_threshold(double value); + + // optional bool use_dual_simplex = 31 [default = false]; + bool has_use_dual_simplex() const; + void clear_use_dual_simplex(); + static const int kUseDualSimplexFieldNumber = 31; + bool use_dual_simplex() const; + void set_use_dual_simplex(bool value); + + // optional bool allow_simplex_algorithm_change = 32 [default = false]; + bool has_allow_simplex_algorithm_change() const; + void clear_allow_simplex_algorithm_change(); + static const int kAllowSimplexAlgorithmChangeFieldNumber = 32; + bool allow_simplex_algorithm_change() const; + void set_allow_simplex_algorithm_change(bool value); + + // optional int32 devex_weights_reset_period = 33 [default = 150]; + bool has_devex_weights_reset_period() const; + void clear_devex_weights_reset_period(); + static const int kDevexWeightsResetPeriodFieldNumber = 33; + ::google::protobuf::int32 devex_weights_reset_period() const; + void set_devex_weights_reset_period(::google::protobuf::int32 value); + + // optional bool use_preprocessing = 34 [default = true]; + bool has_use_preprocessing() const; + void clear_use_preprocessing(); + static const int kUsePreprocessingFieldNumber = 34; + bool use_preprocessing() const; + void set_use_preprocessing(bool value); + + // optional bool use_middle_product_form_update = 35 [default = true]; + bool has_use_middle_product_form_update() const; + void clear_use_middle_product_form_update(); + static const int kUseMiddleProductFormUpdateFieldNumber = 35; + bool use_middle_product_form_update() const; + void set_use_middle_product_form_update(bool value); + + // optional bool initialize_devex_with_column_norms = 36 [default = true]; + bool has_initialize_devex_with_column_norms() const; + void clear_initialize_devex_with_column_norms(); + static const int kInitializeDevexWithColumnNormsFieldNumber = 36; + bool initialize_devex_with_column_norms() const; + void set_initialize_devex_with_column_norms(bool value); + + // optional bool exploit_singleton_column_in_initial_basis = 37 [default = true]; + bool has_exploit_singleton_column_in_initial_basis() const; + void clear_exploit_singleton_column_in_initial_basis(); + static const int kExploitSingletonColumnInInitialBasisFieldNumber = 37; + bool exploit_singleton_column_in_initial_basis() const; + void set_exploit_singleton_column_in_initial_basis(bool value); + + // optional double dual_small_pivot_threshold = 38 [default = 0.0001]; + bool has_dual_small_pivot_threshold() const; + void clear_dual_small_pivot_threshold(); + static const int kDualSmallPivotThresholdFieldNumber = 38; + double dual_small_pivot_threshold() const; + void set_dual_small_pivot_threshold(double value); + + // optional double preprocessor_zero_tolerance = 39 [default = 1e-09]; + bool has_preprocessor_zero_tolerance() const; + void clear_preprocessor_zero_tolerance(); + static const int kPreprocessorZeroToleranceFieldNumber = 39; + double preprocessor_zero_tolerance() const; + void set_preprocessor_zero_tolerance(double value); + + // optional double objective_lower_limit = 40 [default = -inf]; + bool has_objective_lower_limit() const; + void clear_objective_lower_limit(); + static const int kObjectiveLowerLimitFieldNumber = 40; + double objective_lower_limit() const; + void set_objective_lower_limit(double value); + + // optional double objective_upper_limit = 41 [default = inf]; + bool has_objective_upper_limit() const; + void clear_objective_upper_limit(); + static const int kObjectiveUpperLimitFieldNumber = 41; + double objective_upper_limit() const; + void set_objective_upper_limit(double value); + + // optional double degenerate_ministep_factor = 42 [default = 0.01]; + bool has_degenerate_ministep_factor() const; + void clear_degenerate_ministep_factor(); + static const int kDegenerateMinistepFactorFieldNumber = 42; + double degenerate_ministep_factor() const; + void set_degenerate_ministep_factor(double value); + + // optional int32 random_seed = 43 [default = 1]; + bool has_random_seed() const; + void clear_random_seed(); + static const int kRandomSeedFieldNumber = 43; + ::google::protobuf::int32 random_seed() const; + void set_random_seed(::google::protobuf::int32 value); + + // optional int32 num_omp_threads = 44 [default = 1]; + bool has_num_omp_threads() const; + void clear_num_omp_threads(); + static const int kNumOmpThreadsFieldNumber = 44; + ::google::protobuf::int32 num_omp_threads() const; + void set_num_omp_threads(::google::protobuf::int32 value); + + // optional bool use_solowhalim = 46 [default = false]; + bool has_use_solowhalim() const; + void clear_use_solowhalim(); + static const int kUseSolowhalimFieldNumber = 46; + bool use_solowhalim() const; + void set_use_solowhalim(bool value); + + // optional bool perturb_costs_in_dual_simplex = 53 [default = false]; + bool has_perturb_costs_in_dual_simplex() const; + void clear_perturb_costs_in_dual_simplex(); + static const int kPerturbCostsInDualSimplexFieldNumber = 53; + bool perturb_costs_in_dual_simplex() const; + void set_perturb_costs_in_dual_simplex(bool value); + + // optional double relative_cost_perturbation = 54 [default = 1e-05]; + bool has_relative_cost_perturbation() const; + void clear_relative_cost_perturbation(); + static const int kRelativeCostPerturbationFieldNumber = 54; + double relative_cost_perturbation() const; + void set_relative_cost_perturbation(double value); + + // optional double relative_max_cost_perturbation = 55 [default = 1e-07]; + bool has_relative_max_cost_perturbation() const; + void clear_relative_max_cost_perturbation(); + static const int kRelativeMaxCostPerturbationFieldNumber = 55; + double relative_max_cost_perturbation() const; + void set_relative_max_cost_perturbation(double value); + + // @@protoc_insertion_point(class_scope:operations_research.glop.GlopParameters) + private: + inline void set_has_feasibility_rule(); + inline void clear_has_feasibility_rule(); + inline void set_has_optimization_rule(); + inline void clear_has_optimization_rule(); + inline void set_has_normalize_using_column_norm(); + inline void clear_has_normalize_using_column_norm(); + inline void set_has_use_nested_pricing(); + inline void clear_has_use_nested_pricing(); + inline void set_has_refactorization_threshold(); + inline void clear_has_refactorization_threshold(); + inline void set_has_recompute_reduced_costs_threshold(); + inline void clear_has_recompute_reduced_costs_threshold(); + inline void set_has_recompute_edges_norm_threshold(); + inline void clear_has_recompute_edges_norm_threshold(); + inline void set_has_primal_feasibility_tolerance(); + inline void clear_has_primal_feasibility_tolerance(); + inline void set_has_dual_feasibility_tolerance(); + inline void clear_has_dual_feasibility_tolerance(); + inline void set_has_ratio_test_zero_threshold(); + inline void clear_has_ratio_test_zero_threshold(); + inline void set_has_harris_tolerance_ratio(); + inline void clear_has_harris_tolerance_ratio(); + inline void set_has_small_pivot_threshold(); + inline void clear_has_small_pivot_threshold(); + inline void set_has_minimum_acceptable_pivot(); + inline void clear_has_minimum_acceptable_pivot(); + inline void set_has_drop_tolerance(); + inline void clear_has_drop_tolerance(); + inline void set_has_use_scaling(); + inline void clear_has_use_scaling(); + inline void set_has_initial_basis(); + inline void clear_has_initial_basis(); + inline void set_has_use_transposed_matrix(); + inline void clear_has_use_transposed_matrix(); + inline void set_has_basis_refactorization_period(); + inline void clear_has_basis_refactorization_period(); + inline void set_has_solve_dual_problem(); + inline void clear_has_solve_dual_problem(); + inline void set_has_dualizer_threshold(); + inline void clear_has_dualizer_threshold(); + inline void set_has_solution_feasibility_tolerance(); + inline void clear_has_solution_feasibility_tolerance(); + inline void set_has_provide_strong_optimal_guarantee(); + inline void clear_has_provide_strong_optimal_guarantee(); + inline void set_has_max_number_of_reoptimizations(); + inline void clear_has_max_number_of_reoptimizations(); + inline void set_has_lu_factorization_pivot_threshold(); + inline void clear_has_lu_factorization_pivot_threshold(); + inline void set_has_max_time_in_seconds(); + inline void clear_has_max_time_in_seconds(); + inline void set_has_max_deterministic_time(); + inline void clear_has_max_deterministic_time(); + inline void set_has_max_number_of_iterations(); + inline void clear_has_max_number_of_iterations(); + inline void set_has_markowitz_zlatev_parameter(); + inline void clear_has_markowitz_zlatev_parameter(); + inline void set_has_markowitz_singularity_threshold(); + inline void clear_has_markowitz_singularity_threshold(); + inline void set_has_use_dual_simplex(); + inline void clear_has_use_dual_simplex(); + inline void set_has_allow_simplex_algorithm_change(); + inline void clear_has_allow_simplex_algorithm_change(); + inline void set_has_devex_weights_reset_period(); + inline void clear_has_devex_weights_reset_period(); + inline void set_has_use_preprocessing(); + inline void clear_has_use_preprocessing(); + inline void set_has_use_middle_product_form_update(); + inline void clear_has_use_middle_product_form_update(); + inline void set_has_initialize_devex_with_column_norms(); + inline void clear_has_initialize_devex_with_column_norms(); + inline void set_has_exploit_singleton_column_in_initial_basis(); + inline void clear_has_exploit_singleton_column_in_initial_basis(); + inline void set_has_dual_small_pivot_threshold(); + inline void clear_has_dual_small_pivot_threshold(); + inline void set_has_preprocessor_zero_tolerance(); + inline void clear_has_preprocessor_zero_tolerance(); + inline void set_has_objective_lower_limit(); + inline void clear_has_objective_lower_limit(); + inline void set_has_objective_upper_limit(); + inline void clear_has_objective_upper_limit(); + inline void set_has_degenerate_ministep_factor(); + inline void clear_has_degenerate_ministep_factor(); + inline void set_has_random_seed(); + inline void clear_has_random_seed(); + inline void set_has_num_omp_threads(); + inline void clear_has_num_omp_threads(); + inline void set_has_use_solowhalim(); + inline void clear_has_use_solowhalim(); + inline void set_has_perturb_costs_in_dual_simplex(); + inline void clear_has_perturb_costs_in_dual_simplex(); + inline void set_has_relative_cost_perturbation(); + inline void clear_has_relative_cost_perturbation(); + inline void set_has_relative_max_cost_perturbation(); + inline void clear_has_relative_max_cost_perturbation(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[2]; + int feasibility_rule_; + int optimization_rule_; + double refactorization_threshold_; + double recompute_reduced_costs_threshold_; + double recompute_edges_norm_threshold_; + double primal_feasibility_tolerance_; + double dual_feasibility_tolerance_; + double ratio_test_zero_threshold_; + double harris_tolerance_ratio_; + bool normalize_using_column_norm_; + bool use_nested_pricing_; + bool use_scaling_; + bool use_transposed_matrix_; + int initial_basis_; + double small_pivot_threshold_; + double minimum_acceptable_pivot_; + double drop_tolerance_; + ::google::protobuf::int32 basis_refactorization_period_; + int solve_dual_problem_; + double dualizer_threshold_; + double solution_feasibility_tolerance_; + double max_number_of_reoptimizations_; + double lu_factorization_pivot_threshold_; + double max_time_in_seconds_; + double max_deterministic_time_; + ::google::protobuf::int64 max_number_of_iterations_; + ::google::protobuf::int32 markowitz_zlatev_parameter_; + bool provide_strong_optimal_guarantee_; + bool use_dual_simplex_; + bool allow_simplex_algorithm_change_; + bool use_preprocessing_; + double markowitz_singularity_threshold_; + ::google::protobuf::int32 devex_weights_reset_period_; + bool use_middle_product_form_update_; + bool initialize_devex_with_column_norms_; + bool exploit_singleton_column_in_initial_basis_; + bool use_solowhalim_; + double dual_small_pivot_threshold_; + double preprocessor_zero_tolerance_; + double objective_lower_limit_; + double objective_upper_limit_; + double degenerate_ministep_factor_; + ::google::protobuf::int32 random_seed_; + ::google::protobuf::int32 num_omp_threads_; + double relative_cost_perturbation_; + double relative_max_cost_perturbation_; + bool perturb_costs_in_dual_simplex_; + mutable int _cached_size_; + friend void protobuf_AddDesc_ortools_2fglop_2fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fglop_2fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fglop_2fparameters_2eproto(); + + void InitAsDefaultInstance(); + static GlopParameters* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// GlopParameters + +// optional .operations_research.glop.GlopParameters.PricingRule feasibility_rule = 1 [default = STEEPEST_EDGE]; +inline bool GlopParameters::has_feasibility_rule() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void GlopParameters::set_has_feasibility_rule() { + _has_bits_[0] |= 0x00000001u; +} +inline void GlopParameters::clear_has_feasibility_rule() { + _has_bits_[0] &= ~0x00000001u; +} +inline void GlopParameters::clear_feasibility_rule() { + feasibility_rule_ = 1; + clear_has_feasibility_rule(); +} +inline ::operations_research::glop::GlopParameters_PricingRule GlopParameters::feasibility_rule() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.feasibility_rule) + return static_cast< ::operations_research::glop::GlopParameters_PricingRule >(feasibility_rule_); +} +inline void GlopParameters::set_feasibility_rule(::operations_research::glop::GlopParameters_PricingRule value) { + assert(::operations_research::glop::GlopParameters_PricingRule_IsValid(value)); + set_has_feasibility_rule(); + feasibility_rule_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.feasibility_rule) +} + +// optional .operations_research.glop.GlopParameters.PricingRule optimization_rule = 2 [default = STEEPEST_EDGE]; +inline bool GlopParameters::has_optimization_rule() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void GlopParameters::set_has_optimization_rule() { + _has_bits_[0] |= 0x00000002u; +} +inline void GlopParameters::clear_has_optimization_rule() { + _has_bits_[0] &= ~0x00000002u; +} +inline void GlopParameters::clear_optimization_rule() { + optimization_rule_ = 1; + clear_has_optimization_rule(); +} +inline ::operations_research::glop::GlopParameters_PricingRule GlopParameters::optimization_rule() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.optimization_rule) + return static_cast< ::operations_research::glop::GlopParameters_PricingRule >(optimization_rule_); +} +inline void GlopParameters::set_optimization_rule(::operations_research::glop::GlopParameters_PricingRule value) { + assert(::operations_research::glop::GlopParameters_PricingRule_IsValid(value)); + set_has_optimization_rule(); + optimization_rule_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.optimization_rule) +} + +// optional bool normalize_using_column_norm = 4 [default = true]; +inline bool GlopParameters::has_normalize_using_column_norm() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void GlopParameters::set_has_normalize_using_column_norm() { + _has_bits_[0] |= 0x00000004u; +} +inline void GlopParameters::clear_has_normalize_using_column_norm() { + _has_bits_[0] &= ~0x00000004u; +} +inline void GlopParameters::clear_normalize_using_column_norm() { + normalize_using_column_norm_ = true; + clear_has_normalize_using_column_norm(); +} +inline bool GlopParameters::normalize_using_column_norm() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.normalize_using_column_norm) + return normalize_using_column_norm_; +} +inline void GlopParameters::set_normalize_using_column_norm(bool value) { + set_has_normalize_using_column_norm(); + normalize_using_column_norm_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.normalize_using_column_norm) +} + +// optional bool use_nested_pricing = 5 [default = true]; +inline bool GlopParameters::has_use_nested_pricing() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void GlopParameters::set_has_use_nested_pricing() { + _has_bits_[0] |= 0x00000008u; +} +inline void GlopParameters::clear_has_use_nested_pricing() { + _has_bits_[0] &= ~0x00000008u; +} +inline void GlopParameters::clear_use_nested_pricing() { + use_nested_pricing_ = true; + clear_has_use_nested_pricing(); +} +inline bool GlopParameters::use_nested_pricing() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.use_nested_pricing) + return use_nested_pricing_; +} +inline void GlopParameters::set_use_nested_pricing(bool value) { + set_has_use_nested_pricing(); + use_nested_pricing_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.use_nested_pricing) +} + +// optional double refactorization_threshold = 6 [default = 1e-08]; +inline bool GlopParameters::has_refactorization_threshold() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void GlopParameters::set_has_refactorization_threshold() { + _has_bits_[0] |= 0x00000010u; +} +inline void GlopParameters::clear_has_refactorization_threshold() { + _has_bits_[0] &= ~0x00000010u; +} +inline void GlopParameters::clear_refactorization_threshold() { + refactorization_threshold_ = 1e-08; + clear_has_refactorization_threshold(); +} +inline double GlopParameters::refactorization_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.refactorization_threshold) + return refactorization_threshold_; +} +inline void GlopParameters::set_refactorization_threshold(double value) { + set_has_refactorization_threshold(); + refactorization_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.refactorization_threshold) +} + +// optional double recompute_reduced_costs_threshold = 8 [default = 1e-08]; +inline bool GlopParameters::has_recompute_reduced_costs_threshold() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void GlopParameters::set_has_recompute_reduced_costs_threshold() { + _has_bits_[0] |= 0x00000020u; +} +inline void GlopParameters::clear_has_recompute_reduced_costs_threshold() { + _has_bits_[0] &= ~0x00000020u; +} +inline void GlopParameters::clear_recompute_reduced_costs_threshold() { + recompute_reduced_costs_threshold_ = 1e-08; + clear_has_recompute_reduced_costs_threshold(); +} +inline double GlopParameters::recompute_reduced_costs_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.recompute_reduced_costs_threshold) + return recompute_reduced_costs_threshold_; +} +inline void GlopParameters::set_recompute_reduced_costs_threshold(double value) { + set_has_recompute_reduced_costs_threshold(); + recompute_reduced_costs_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.recompute_reduced_costs_threshold) +} + +// optional double recompute_edges_norm_threshold = 9 [default = 100]; +inline bool GlopParameters::has_recompute_edges_norm_threshold() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void GlopParameters::set_has_recompute_edges_norm_threshold() { + _has_bits_[0] |= 0x00000040u; +} +inline void GlopParameters::clear_has_recompute_edges_norm_threshold() { + _has_bits_[0] &= ~0x00000040u; +} +inline void GlopParameters::clear_recompute_edges_norm_threshold() { + recompute_edges_norm_threshold_ = 100; + clear_has_recompute_edges_norm_threshold(); +} +inline double GlopParameters::recompute_edges_norm_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.recompute_edges_norm_threshold) + return recompute_edges_norm_threshold_; +} +inline void GlopParameters::set_recompute_edges_norm_threshold(double value) { + set_has_recompute_edges_norm_threshold(); + recompute_edges_norm_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.recompute_edges_norm_threshold) +} + +// optional double primal_feasibility_tolerance = 10 [default = 1e-08]; +inline bool GlopParameters::has_primal_feasibility_tolerance() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void GlopParameters::set_has_primal_feasibility_tolerance() { + _has_bits_[0] |= 0x00000080u; +} +inline void GlopParameters::clear_has_primal_feasibility_tolerance() { + _has_bits_[0] &= ~0x00000080u; +} +inline void GlopParameters::clear_primal_feasibility_tolerance() { + primal_feasibility_tolerance_ = 1e-08; + clear_has_primal_feasibility_tolerance(); +} +inline double GlopParameters::primal_feasibility_tolerance() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.primal_feasibility_tolerance) + return primal_feasibility_tolerance_; +} +inline void GlopParameters::set_primal_feasibility_tolerance(double value) { + set_has_primal_feasibility_tolerance(); + primal_feasibility_tolerance_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.primal_feasibility_tolerance) +} + +// optional double dual_feasibility_tolerance = 11 [default = 1e-10]; +inline bool GlopParameters::has_dual_feasibility_tolerance() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void GlopParameters::set_has_dual_feasibility_tolerance() { + _has_bits_[0] |= 0x00000100u; +} +inline void GlopParameters::clear_has_dual_feasibility_tolerance() { + _has_bits_[0] &= ~0x00000100u; +} +inline void GlopParameters::clear_dual_feasibility_tolerance() { + dual_feasibility_tolerance_ = 1e-10; + clear_has_dual_feasibility_tolerance(); +} +inline double GlopParameters::dual_feasibility_tolerance() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.dual_feasibility_tolerance) + return dual_feasibility_tolerance_; +} +inline void GlopParameters::set_dual_feasibility_tolerance(double value) { + set_has_dual_feasibility_tolerance(); + dual_feasibility_tolerance_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.dual_feasibility_tolerance) +} + +// optional double ratio_test_zero_threshold = 12 [default = 1e-09]; +inline bool GlopParameters::has_ratio_test_zero_threshold() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void GlopParameters::set_has_ratio_test_zero_threshold() { + _has_bits_[0] |= 0x00000200u; +} +inline void GlopParameters::clear_has_ratio_test_zero_threshold() { + _has_bits_[0] &= ~0x00000200u; +} +inline void GlopParameters::clear_ratio_test_zero_threshold() { + ratio_test_zero_threshold_ = 1e-09; + clear_has_ratio_test_zero_threshold(); +} +inline double GlopParameters::ratio_test_zero_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.ratio_test_zero_threshold) + return ratio_test_zero_threshold_; +} +inline void GlopParameters::set_ratio_test_zero_threshold(double value) { + set_has_ratio_test_zero_threshold(); + ratio_test_zero_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.ratio_test_zero_threshold) +} + +// optional double harris_tolerance_ratio = 13 [default = 0.5]; +inline bool GlopParameters::has_harris_tolerance_ratio() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void GlopParameters::set_has_harris_tolerance_ratio() { + _has_bits_[0] |= 0x00000400u; +} +inline void GlopParameters::clear_has_harris_tolerance_ratio() { + _has_bits_[0] &= ~0x00000400u; +} +inline void GlopParameters::clear_harris_tolerance_ratio() { + harris_tolerance_ratio_ = 0.5; + clear_has_harris_tolerance_ratio(); +} +inline double GlopParameters::harris_tolerance_ratio() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.harris_tolerance_ratio) + return harris_tolerance_ratio_; +} +inline void GlopParameters::set_harris_tolerance_ratio(double value) { + set_has_harris_tolerance_ratio(); + harris_tolerance_ratio_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.harris_tolerance_ratio) +} + +// optional double small_pivot_threshold = 14 [default = 1e-06]; +inline bool GlopParameters::has_small_pivot_threshold() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void GlopParameters::set_has_small_pivot_threshold() { + _has_bits_[0] |= 0x00000800u; +} +inline void GlopParameters::clear_has_small_pivot_threshold() { + _has_bits_[0] &= ~0x00000800u; +} +inline void GlopParameters::clear_small_pivot_threshold() { + small_pivot_threshold_ = 1e-06; + clear_has_small_pivot_threshold(); +} +inline double GlopParameters::small_pivot_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.small_pivot_threshold) + return small_pivot_threshold_; +} +inline void GlopParameters::set_small_pivot_threshold(double value) { + set_has_small_pivot_threshold(); + small_pivot_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.small_pivot_threshold) +} + +// optional double minimum_acceptable_pivot = 15 [default = 1e-06]; +inline bool GlopParameters::has_minimum_acceptable_pivot() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void GlopParameters::set_has_minimum_acceptable_pivot() { + _has_bits_[0] |= 0x00001000u; +} +inline void GlopParameters::clear_has_minimum_acceptable_pivot() { + _has_bits_[0] &= ~0x00001000u; +} +inline void GlopParameters::clear_minimum_acceptable_pivot() { + minimum_acceptable_pivot_ = 1e-06; + clear_has_minimum_acceptable_pivot(); +} +inline double GlopParameters::minimum_acceptable_pivot() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.minimum_acceptable_pivot) + return minimum_acceptable_pivot_; +} +inline void GlopParameters::set_minimum_acceptable_pivot(double value) { + set_has_minimum_acceptable_pivot(); + minimum_acceptable_pivot_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.minimum_acceptable_pivot) +} + +// optional double drop_tolerance = 52 [default = 1e-14]; +inline bool GlopParameters::has_drop_tolerance() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void GlopParameters::set_has_drop_tolerance() { + _has_bits_[0] |= 0x00002000u; +} +inline void GlopParameters::clear_has_drop_tolerance() { + _has_bits_[0] &= ~0x00002000u; +} +inline void GlopParameters::clear_drop_tolerance() { + drop_tolerance_ = 1e-14; + clear_has_drop_tolerance(); +} +inline double GlopParameters::drop_tolerance() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.drop_tolerance) + return drop_tolerance_; +} +inline void GlopParameters::set_drop_tolerance(double value) { + set_has_drop_tolerance(); + drop_tolerance_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.drop_tolerance) +} + +// optional bool use_scaling = 16 [default = true]; +inline bool GlopParameters::has_use_scaling() const { + return (_has_bits_[0] & 0x00004000u) != 0; +} +inline void GlopParameters::set_has_use_scaling() { + _has_bits_[0] |= 0x00004000u; +} +inline void GlopParameters::clear_has_use_scaling() { + _has_bits_[0] &= ~0x00004000u; +} +inline void GlopParameters::clear_use_scaling() { + use_scaling_ = true; + clear_has_use_scaling(); +} +inline bool GlopParameters::use_scaling() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.use_scaling) + return use_scaling_; +} +inline void GlopParameters::set_use_scaling(bool value) { + set_has_use_scaling(); + use_scaling_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.use_scaling) +} + +// optional .operations_research.glop.GlopParameters.InitialBasisHeuristic initial_basis = 17 [default = TRIANGULAR]; +inline bool GlopParameters::has_initial_basis() const { + return (_has_bits_[0] & 0x00008000u) != 0; +} +inline void GlopParameters::set_has_initial_basis() { + _has_bits_[0] |= 0x00008000u; +} +inline void GlopParameters::clear_has_initial_basis() { + _has_bits_[0] &= ~0x00008000u; +} +inline void GlopParameters::clear_initial_basis() { + initial_basis_ = 2; + clear_has_initial_basis(); +} +inline ::operations_research::glop::GlopParameters_InitialBasisHeuristic GlopParameters::initial_basis() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.initial_basis) + return static_cast< ::operations_research::glop::GlopParameters_InitialBasisHeuristic >(initial_basis_); +} +inline void GlopParameters::set_initial_basis(::operations_research::glop::GlopParameters_InitialBasisHeuristic value) { + assert(::operations_research::glop::GlopParameters_InitialBasisHeuristic_IsValid(value)); + set_has_initial_basis(); + initial_basis_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.initial_basis) +} + +// optional bool use_transposed_matrix = 18 [default = true]; +inline bool GlopParameters::has_use_transposed_matrix() const { + return (_has_bits_[0] & 0x00010000u) != 0; +} +inline void GlopParameters::set_has_use_transposed_matrix() { + _has_bits_[0] |= 0x00010000u; +} +inline void GlopParameters::clear_has_use_transposed_matrix() { + _has_bits_[0] &= ~0x00010000u; +} +inline void GlopParameters::clear_use_transposed_matrix() { + use_transposed_matrix_ = true; + clear_has_use_transposed_matrix(); +} +inline bool GlopParameters::use_transposed_matrix() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.use_transposed_matrix) + return use_transposed_matrix_; +} +inline void GlopParameters::set_use_transposed_matrix(bool value) { + set_has_use_transposed_matrix(); + use_transposed_matrix_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.use_transposed_matrix) +} + +// optional int32 basis_refactorization_period = 19 [default = 64]; +inline bool GlopParameters::has_basis_refactorization_period() const { + return (_has_bits_[0] & 0x00020000u) != 0; +} +inline void GlopParameters::set_has_basis_refactorization_period() { + _has_bits_[0] |= 0x00020000u; +} +inline void GlopParameters::clear_has_basis_refactorization_period() { + _has_bits_[0] &= ~0x00020000u; +} +inline void GlopParameters::clear_basis_refactorization_period() { + basis_refactorization_period_ = 64; + clear_has_basis_refactorization_period(); +} +inline ::google::protobuf::int32 GlopParameters::basis_refactorization_period() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.basis_refactorization_period) + return basis_refactorization_period_; +} +inline void GlopParameters::set_basis_refactorization_period(::google::protobuf::int32 value) { + set_has_basis_refactorization_period(); + basis_refactorization_period_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.basis_refactorization_period) +} + +// optional .operations_research.glop.GlopParameters.SolverBehavior solve_dual_problem = 20 [default = LET_SOLVER_DECIDE]; +inline bool GlopParameters::has_solve_dual_problem() const { + return (_has_bits_[0] & 0x00040000u) != 0; +} +inline void GlopParameters::set_has_solve_dual_problem() { + _has_bits_[0] |= 0x00040000u; +} +inline void GlopParameters::clear_has_solve_dual_problem() { + _has_bits_[0] &= ~0x00040000u; +} +inline void GlopParameters::clear_solve_dual_problem() { + solve_dual_problem_ = 2; + clear_has_solve_dual_problem(); +} +inline ::operations_research::glop::GlopParameters_SolverBehavior GlopParameters::solve_dual_problem() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.solve_dual_problem) + return static_cast< ::operations_research::glop::GlopParameters_SolverBehavior >(solve_dual_problem_); +} +inline void GlopParameters::set_solve_dual_problem(::operations_research::glop::GlopParameters_SolverBehavior value) { + assert(::operations_research::glop::GlopParameters_SolverBehavior_IsValid(value)); + set_has_solve_dual_problem(); + solve_dual_problem_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.solve_dual_problem) +} + +// optional double dualizer_threshold = 21 [default = 1.5]; +inline bool GlopParameters::has_dualizer_threshold() const { + return (_has_bits_[0] & 0x00080000u) != 0; +} +inline void GlopParameters::set_has_dualizer_threshold() { + _has_bits_[0] |= 0x00080000u; +} +inline void GlopParameters::clear_has_dualizer_threshold() { + _has_bits_[0] &= ~0x00080000u; +} +inline void GlopParameters::clear_dualizer_threshold() { + dualizer_threshold_ = 1.5; + clear_has_dualizer_threshold(); +} +inline double GlopParameters::dualizer_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.dualizer_threshold) + return dualizer_threshold_; +} +inline void GlopParameters::set_dualizer_threshold(double value) { + set_has_dualizer_threshold(); + dualizer_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.dualizer_threshold) +} + +// optional double solution_feasibility_tolerance = 22 [default = 1e-06]; +inline bool GlopParameters::has_solution_feasibility_tolerance() const { + return (_has_bits_[0] & 0x00100000u) != 0; +} +inline void GlopParameters::set_has_solution_feasibility_tolerance() { + _has_bits_[0] |= 0x00100000u; +} +inline void GlopParameters::clear_has_solution_feasibility_tolerance() { + _has_bits_[0] &= ~0x00100000u; +} +inline void GlopParameters::clear_solution_feasibility_tolerance() { + solution_feasibility_tolerance_ = 1e-06; + clear_has_solution_feasibility_tolerance(); +} +inline double GlopParameters::solution_feasibility_tolerance() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.solution_feasibility_tolerance) + return solution_feasibility_tolerance_; +} +inline void GlopParameters::set_solution_feasibility_tolerance(double value) { + set_has_solution_feasibility_tolerance(); + solution_feasibility_tolerance_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.solution_feasibility_tolerance) +} + +// optional bool provide_strong_optimal_guarantee = 24 [default = true]; +inline bool GlopParameters::has_provide_strong_optimal_guarantee() const { + return (_has_bits_[0] & 0x00200000u) != 0; +} +inline void GlopParameters::set_has_provide_strong_optimal_guarantee() { + _has_bits_[0] |= 0x00200000u; +} +inline void GlopParameters::clear_has_provide_strong_optimal_guarantee() { + _has_bits_[0] &= ~0x00200000u; +} +inline void GlopParameters::clear_provide_strong_optimal_guarantee() { + provide_strong_optimal_guarantee_ = true; + clear_has_provide_strong_optimal_guarantee(); +} +inline bool GlopParameters::provide_strong_optimal_guarantee() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.provide_strong_optimal_guarantee) + return provide_strong_optimal_guarantee_; +} +inline void GlopParameters::set_provide_strong_optimal_guarantee(bool value) { + set_has_provide_strong_optimal_guarantee(); + provide_strong_optimal_guarantee_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.provide_strong_optimal_guarantee) +} + +// optional double max_number_of_reoptimizations = 56 [default = 40]; +inline bool GlopParameters::has_max_number_of_reoptimizations() const { + return (_has_bits_[0] & 0x00400000u) != 0; +} +inline void GlopParameters::set_has_max_number_of_reoptimizations() { + _has_bits_[0] |= 0x00400000u; +} +inline void GlopParameters::clear_has_max_number_of_reoptimizations() { + _has_bits_[0] &= ~0x00400000u; +} +inline void GlopParameters::clear_max_number_of_reoptimizations() { + max_number_of_reoptimizations_ = 40; + clear_has_max_number_of_reoptimizations(); +} +inline double GlopParameters::max_number_of_reoptimizations() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.max_number_of_reoptimizations) + return max_number_of_reoptimizations_; +} +inline void GlopParameters::set_max_number_of_reoptimizations(double value) { + set_has_max_number_of_reoptimizations(); + max_number_of_reoptimizations_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.max_number_of_reoptimizations) +} + +// optional double lu_factorization_pivot_threshold = 25 [default = 0.01]; +inline bool GlopParameters::has_lu_factorization_pivot_threshold() const { + return (_has_bits_[0] & 0x00800000u) != 0; +} +inline void GlopParameters::set_has_lu_factorization_pivot_threshold() { + _has_bits_[0] |= 0x00800000u; +} +inline void GlopParameters::clear_has_lu_factorization_pivot_threshold() { + _has_bits_[0] &= ~0x00800000u; +} +inline void GlopParameters::clear_lu_factorization_pivot_threshold() { + lu_factorization_pivot_threshold_ = 0.01; + clear_has_lu_factorization_pivot_threshold(); +} +inline double GlopParameters::lu_factorization_pivot_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.lu_factorization_pivot_threshold) + return lu_factorization_pivot_threshold_; +} +inline void GlopParameters::set_lu_factorization_pivot_threshold(double value) { + set_has_lu_factorization_pivot_threshold(); + lu_factorization_pivot_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.lu_factorization_pivot_threshold) +} + +// optional double max_time_in_seconds = 26 [default = inf]; +inline bool GlopParameters::has_max_time_in_seconds() const { + return (_has_bits_[0] & 0x01000000u) != 0; +} +inline void GlopParameters::set_has_max_time_in_seconds() { + _has_bits_[0] |= 0x01000000u; +} +inline void GlopParameters::clear_has_max_time_in_seconds() { + _has_bits_[0] &= ~0x01000000u; +} +inline void GlopParameters::clear_max_time_in_seconds() { + max_time_in_seconds_ = ::google::protobuf::internal::Infinity(); + clear_has_max_time_in_seconds(); +} +inline double GlopParameters::max_time_in_seconds() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.max_time_in_seconds) + return max_time_in_seconds_; +} +inline void GlopParameters::set_max_time_in_seconds(double value) { + set_has_max_time_in_seconds(); + max_time_in_seconds_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.max_time_in_seconds) +} + +// optional double max_deterministic_time = 45 [default = inf]; +inline bool GlopParameters::has_max_deterministic_time() const { + return (_has_bits_[0] & 0x02000000u) != 0; +} +inline void GlopParameters::set_has_max_deterministic_time() { + _has_bits_[0] |= 0x02000000u; +} +inline void GlopParameters::clear_has_max_deterministic_time() { + _has_bits_[0] &= ~0x02000000u; +} +inline void GlopParameters::clear_max_deterministic_time() { + max_deterministic_time_ = ::google::protobuf::internal::Infinity(); + clear_has_max_deterministic_time(); +} +inline double GlopParameters::max_deterministic_time() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.max_deterministic_time) + return max_deterministic_time_; +} +inline void GlopParameters::set_max_deterministic_time(double value) { + set_has_max_deterministic_time(); + max_deterministic_time_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.max_deterministic_time) +} + +// optional int64 max_number_of_iterations = 27 [default = -1]; +inline bool GlopParameters::has_max_number_of_iterations() const { + return (_has_bits_[0] & 0x04000000u) != 0; +} +inline void GlopParameters::set_has_max_number_of_iterations() { + _has_bits_[0] |= 0x04000000u; +} +inline void GlopParameters::clear_has_max_number_of_iterations() { + _has_bits_[0] &= ~0x04000000u; +} +inline void GlopParameters::clear_max_number_of_iterations() { + max_number_of_iterations_ = GOOGLE_LONGLONG(-1); + clear_has_max_number_of_iterations(); +} +inline ::google::protobuf::int64 GlopParameters::max_number_of_iterations() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.max_number_of_iterations) + return max_number_of_iterations_; +} +inline void GlopParameters::set_max_number_of_iterations(::google::protobuf::int64 value) { + set_has_max_number_of_iterations(); + max_number_of_iterations_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.max_number_of_iterations) +} + +// optional int32 markowitz_zlatev_parameter = 29 [default = 3]; +inline bool GlopParameters::has_markowitz_zlatev_parameter() const { + return (_has_bits_[0] & 0x08000000u) != 0; +} +inline void GlopParameters::set_has_markowitz_zlatev_parameter() { + _has_bits_[0] |= 0x08000000u; +} +inline void GlopParameters::clear_has_markowitz_zlatev_parameter() { + _has_bits_[0] &= ~0x08000000u; +} +inline void GlopParameters::clear_markowitz_zlatev_parameter() { + markowitz_zlatev_parameter_ = 3; + clear_has_markowitz_zlatev_parameter(); +} +inline ::google::protobuf::int32 GlopParameters::markowitz_zlatev_parameter() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.markowitz_zlatev_parameter) + return markowitz_zlatev_parameter_; +} +inline void GlopParameters::set_markowitz_zlatev_parameter(::google::protobuf::int32 value) { + set_has_markowitz_zlatev_parameter(); + markowitz_zlatev_parameter_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.markowitz_zlatev_parameter) +} + +// optional double markowitz_singularity_threshold = 30 [default = 1e-15]; +inline bool GlopParameters::has_markowitz_singularity_threshold() const { + return (_has_bits_[0] & 0x10000000u) != 0; +} +inline void GlopParameters::set_has_markowitz_singularity_threshold() { + _has_bits_[0] |= 0x10000000u; +} +inline void GlopParameters::clear_has_markowitz_singularity_threshold() { + _has_bits_[0] &= ~0x10000000u; +} +inline void GlopParameters::clear_markowitz_singularity_threshold() { + markowitz_singularity_threshold_ = 1e-15; + clear_has_markowitz_singularity_threshold(); +} +inline double GlopParameters::markowitz_singularity_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.markowitz_singularity_threshold) + return markowitz_singularity_threshold_; +} +inline void GlopParameters::set_markowitz_singularity_threshold(double value) { + set_has_markowitz_singularity_threshold(); + markowitz_singularity_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.markowitz_singularity_threshold) +} + +// optional bool use_dual_simplex = 31 [default = false]; +inline bool GlopParameters::has_use_dual_simplex() const { + return (_has_bits_[0] & 0x20000000u) != 0; +} +inline void GlopParameters::set_has_use_dual_simplex() { + _has_bits_[0] |= 0x20000000u; +} +inline void GlopParameters::clear_has_use_dual_simplex() { + _has_bits_[0] &= ~0x20000000u; +} +inline void GlopParameters::clear_use_dual_simplex() { + use_dual_simplex_ = false; + clear_has_use_dual_simplex(); +} +inline bool GlopParameters::use_dual_simplex() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.use_dual_simplex) + return use_dual_simplex_; +} +inline void GlopParameters::set_use_dual_simplex(bool value) { + set_has_use_dual_simplex(); + use_dual_simplex_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.use_dual_simplex) +} + +// optional bool allow_simplex_algorithm_change = 32 [default = false]; +inline bool GlopParameters::has_allow_simplex_algorithm_change() const { + return (_has_bits_[0] & 0x40000000u) != 0; +} +inline void GlopParameters::set_has_allow_simplex_algorithm_change() { + _has_bits_[0] |= 0x40000000u; +} +inline void GlopParameters::clear_has_allow_simplex_algorithm_change() { + _has_bits_[0] &= ~0x40000000u; +} +inline void GlopParameters::clear_allow_simplex_algorithm_change() { + allow_simplex_algorithm_change_ = false; + clear_has_allow_simplex_algorithm_change(); +} +inline bool GlopParameters::allow_simplex_algorithm_change() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.allow_simplex_algorithm_change) + return allow_simplex_algorithm_change_; +} +inline void GlopParameters::set_allow_simplex_algorithm_change(bool value) { + set_has_allow_simplex_algorithm_change(); + allow_simplex_algorithm_change_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.allow_simplex_algorithm_change) +} + +// optional int32 devex_weights_reset_period = 33 [default = 150]; +inline bool GlopParameters::has_devex_weights_reset_period() const { + return (_has_bits_[0] & 0x80000000u) != 0; +} +inline void GlopParameters::set_has_devex_weights_reset_period() { + _has_bits_[0] |= 0x80000000u; +} +inline void GlopParameters::clear_has_devex_weights_reset_period() { + _has_bits_[0] &= ~0x80000000u; +} +inline void GlopParameters::clear_devex_weights_reset_period() { + devex_weights_reset_period_ = 150; + clear_has_devex_weights_reset_period(); +} +inline ::google::protobuf::int32 GlopParameters::devex_weights_reset_period() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.devex_weights_reset_period) + return devex_weights_reset_period_; +} +inline void GlopParameters::set_devex_weights_reset_period(::google::protobuf::int32 value) { + set_has_devex_weights_reset_period(); + devex_weights_reset_period_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.devex_weights_reset_period) +} + +// optional bool use_preprocessing = 34 [default = true]; +inline bool GlopParameters::has_use_preprocessing() const { + return (_has_bits_[1] & 0x00000001u) != 0; +} +inline void GlopParameters::set_has_use_preprocessing() { + _has_bits_[1] |= 0x00000001u; +} +inline void GlopParameters::clear_has_use_preprocessing() { + _has_bits_[1] &= ~0x00000001u; +} +inline void GlopParameters::clear_use_preprocessing() { + use_preprocessing_ = true; + clear_has_use_preprocessing(); +} +inline bool GlopParameters::use_preprocessing() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.use_preprocessing) + return use_preprocessing_; +} +inline void GlopParameters::set_use_preprocessing(bool value) { + set_has_use_preprocessing(); + use_preprocessing_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.use_preprocessing) +} + +// optional bool use_middle_product_form_update = 35 [default = true]; +inline bool GlopParameters::has_use_middle_product_form_update() const { + return (_has_bits_[1] & 0x00000002u) != 0; +} +inline void GlopParameters::set_has_use_middle_product_form_update() { + _has_bits_[1] |= 0x00000002u; +} +inline void GlopParameters::clear_has_use_middle_product_form_update() { + _has_bits_[1] &= ~0x00000002u; +} +inline void GlopParameters::clear_use_middle_product_form_update() { + use_middle_product_form_update_ = true; + clear_has_use_middle_product_form_update(); +} +inline bool GlopParameters::use_middle_product_form_update() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.use_middle_product_form_update) + return use_middle_product_form_update_; +} +inline void GlopParameters::set_use_middle_product_form_update(bool value) { + set_has_use_middle_product_form_update(); + use_middle_product_form_update_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.use_middle_product_form_update) +} + +// optional bool initialize_devex_with_column_norms = 36 [default = true]; +inline bool GlopParameters::has_initialize_devex_with_column_norms() const { + return (_has_bits_[1] & 0x00000004u) != 0; +} +inline void GlopParameters::set_has_initialize_devex_with_column_norms() { + _has_bits_[1] |= 0x00000004u; +} +inline void GlopParameters::clear_has_initialize_devex_with_column_norms() { + _has_bits_[1] &= ~0x00000004u; +} +inline void GlopParameters::clear_initialize_devex_with_column_norms() { + initialize_devex_with_column_norms_ = true; + clear_has_initialize_devex_with_column_norms(); +} +inline bool GlopParameters::initialize_devex_with_column_norms() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.initialize_devex_with_column_norms) + return initialize_devex_with_column_norms_; +} +inline void GlopParameters::set_initialize_devex_with_column_norms(bool value) { + set_has_initialize_devex_with_column_norms(); + initialize_devex_with_column_norms_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.initialize_devex_with_column_norms) +} + +// optional bool exploit_singleton_column_in_initial_basis = 37 [default = true]; +inline bool GlopParameters::has_exploit_singleton_column_in_initial_basis() const { + return (_has_bits_[1] & 0x00000008u) != 0; +} +inline void GlopParameters::set_has_exploit_singleton_column_in_initial_basis() { + _has_bits_[1] |= 0x00000008u; +} +inline void GlopParameters::clear_has_exploit_singleton_column_in_initial_basis() { + _has_bits_[1] &= ~0x00000008u; +} +inline void GlopParameters::clear_exploit_singleton_column_in_initial_basis() { + exploit_singleton_column_in_initial_basis_ = true; + clear_has_exploit_singleton_column_in_initial_basis(); +} +inline bool GlopParameters::exploit_singleton_column_in_initial_basis() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.exploit_singleton_column_in_initial_basis) + return exploit_singleton_column_in_initial_basis_; +} +inline void GlopParameters::set_exploit_singleton_column_in_initial_basis(bool value) { + set_has_exploit_singleton_column_in_initial_basis(); + exploit_singleton_column_in_initial_basis_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.exploit_singleton_column_in_initial_basis) +} + +// optional double dual_small_pivot_threshold = 38 [default = 0.0001]; +inline bool GlopParameters::has_dual_small_pivot_threshold() const { + return (_has_bits_[1] & 0x00000010u) != 0; +} +inline void GlopParameters::set_has_dual_small_pivot_threshold() { + _has_bits_[1] |= 0x00000010u; +} +inline void GlopParameters::clear_has_dual_small_pivot_threshold() { + _has_bits_[1] &= ~0x00000010u; +} +inline void GlopParameters::clear_dual_small_pivot_threshold() { + dual_small_pivot_threshold_ = 0.0001; + clear_has_dual_small_pivot_threshold(); +} +inline double GlopParameters::dual_small_pivot_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.dual_small_pivot_threshold) + return dual_small_pivot_threshold_; +} +inline void GlopParameters::set_dual_small_pivot_threshold(double value) { + set_has_dual_small_pivot_threshold(); + dual_small_pivot_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.dual_small_pivot_threshold) +} + +// optional double preprocessor_zero_tolerance = 39 [default = 1e-09]; +inline bool GlopParameters::has_preprocessor_zero_tolerance() const { + return (_has_bits_[1] & 0x00000020u) != 0; +} +inline void GlopParameters::set_has_preprocessor_zero_tolerance() { + _has_bits_[1] |= 0x00000020u; +} +inline void GlopParameters::clear_has_preprocessor_zero_tolerance() { + _has_bits_[1] &= ~0x00000020u; +} +inline void GlopParameters::clear_preprocessor_zero_tolerance() { + preprocessor_zero_tolerance_ = 1e-09; + clear_has_preprocessor_zero_tolerance(); +} +inline double GlopParameters::preprocessor_zero_tolerance() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.preprocessor_zero_tolerance) + return preprocessor_zero_tolerance_; +} +inline void GlopParameters::set_preprocessor_zero_tolerance(double value) { + set_has_preprocessor_zero_tolerance(); + preprocessor_zero_tolerance_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.preprocessor_zero_tolerance) +} + +// optional double objective_lower_limit = 40 [default = -inf]; +inline bool GlopParameters::has_objective_lower_limit() const { + return (_has_bits_[1] & 0x00000040u) != 0; +} +inline void GlopParameters::set_has_objective_lower_limit() { + _has_bits_[1] |= 0x00000040u; +} +inline void GlopParameters::clear_has_objective_lower_limit() { + _has_bits_[1] &= ~0x00000040u; +} +inline void GlopParameters::clear_objective_lower_limit() { + objective_lower_limit_ = -::google::protobuf::internal::Infinity(); + clear_has_objective_lower_limit(); +} +inline double GlopParameters::objective_lower_limit() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.objective_lower_limit) + return objective_lower_limit_; +} +inline void GlopParameters::set_objective_lower_limit(double value) { + set_has_objective_lower_limit(); + objective_lower_limit_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.objective_lower_limit) +} + +// optional double objective_upper_limit = 41 [default = inf]; +inline bool GlopParameters::has_objective_upper_limit() const { + return (_has_bits_[1] & 0x00000080u) != 0; +} +inline void GlopParameters::set_has_objective_upper_limit() { + _has_bits_[1] |= 0x00000080u; +} +inline void GlopParameters::clear_has_objective_upper_limit() { + _has_bits_[1] &= ~0x00000080u; +} +inline void GlopParameters::clear_objective_upper_limit() { + objective_upper_limit_ = ::google::protobuf::internal::Infinity(); + clear_has_objective_upper_limit(); +} +inline double GlopParameters::objective_upper_limit() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.objective_upper_limit) + return objective_upper_limit_; +} +inline void GlopParameters::set_objective_upper_limit(double value) { + set_has_objective_upper_limit(); + objective_upper_limit_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.objective_upper_limit) +} + +// optional double degenerate_ministep_factor = 42 [default = 0.01]; +inline bool GlopParameters::has_degenerate_ministep_factor() const { + return (_has_bits_[1] & 0x00000100u) != 0; +} +inline void GlopParameters::set_has_degenerate_ministep_factor() { + _has_bits_[1] |= 0x00000100u; +} +inline void GlopParameters::clear_has_degenerate_ministep_factor() { + _has_bits_[1] &= ~0x00000100u; +} +inline void GlopParameters::clear_degenerate_ministep_factor() { + degenerate_ministep_factor_ = 0.01; + clear_has_degenerate_ministep_factor(); +} +inline double GlopParameters::degenerate_ministep_factor() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.degenerate_ministep_factor) + return degenerate_ministep_factor_; +} +inline void GlopParameters::set_degenerate_ministep_factor(double value) { + set_has_degenerate_ministep_factor(); + degenerate_ministep_factor_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.degenerate_ministep_factor) +} + +// optional int32 random_seed = 43 [default = 1]; +inline bool GlopParameters::has_random_seed() const { + return (_has_bits_[1] & 0x00000200u) != 0; +} +inline void GlopParameters::set_has_random_seed() { + _has_bits_[1] |= 0x00000200u; +} +inline void GlopParameters::clear_has_random_seed() { + _has_bits_[1] &= ~0x00000200u; +} +inline void GlopParameters::clear_random_seed() { + random_seed_ = 1; + clear_has_random_seed(); +} +inline ::google::protobuf::int32 GlopParameters::random_seed() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.random_seed) + return random_seed_; +} +inline void GlopParameters::set_random_seed(::google::protobuf::int32 value) { + set_has_random_seed(); + random_seed_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.random_seed) +} + +// optional int32 num_omp_threads = 44 [default = 1]; +inline bool GlopParameters::has_num_omp_threads() const { + return (_has_bits_[1] & 0x00000400u) != 0; +} +inline void GlopParameters::set_has_num_omp_threads() { + _has_bits_[1] |= 0x00000400u; +} +inline void GlopParameters::clear_has_num_omp_threads() { + _has_bits_[1] &= ~0x00000400u; +} +inline void GlopParameters::clear_num_omp_threads() { + num_omp_threads_ = 1; + clear_has_num_omp_threads(); +} +inline ::google::protobuf::int32 GlopParameters::num_omp_threads() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.num_omp_threads) + return num_omp_threads_; +} +inline void GlopParameters::set_num_omp_threads(::google::protobuf::int32 value) { + set_has_num_omp_threads(); + num_omp_threads_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.num_omp_threads) +} + +// optional bool use_solowhalim = 46 [default = false]; +inline bool GlopParameters::has_use_solowhalim() const { + return (_has_bits_[1] & 0x00000800u) != 0; +} +inline void GlopParameters::set_has_use_solowhalim() { + _has_bits_[1] |= 0x00000800u; +} +inline void GlopParameters::clear_has_use_solowhalim() { + _has_bits_[1] &= ~0x00000800u; +} +inline void GlopParameters::clear_use_solowhalim() { + use_solowhalim_ = false; + clear_has_use_solowhalim(); +} +inline bool GlopParameters::use_solowhalim() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.use_solowhalim) + return use_solowhalim_; +} +inline void GlopParameters::set_use_solowhalim(bool value) { + set_has_use_solowhalim(); + use_solowhalim_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.use_solowhalim) +} + +// optional bool perturb_costs_in_dual_simplex = 53 [default = false]; +inline bool GlopParameters::has_perturb_costs_in_dual_simplex() const { + return (_has_bits_[1] & 0x00001000u) != 0; +} +inline void GlopParameters::set_has_perturb_costs_in_dual_simplex() { + _has_bits_[1] |= 0x00001000u; +} +inline void GlopParameters::clear_has_perturb_costs_in_dual_simplex() { + _has_bits_[1] &= ~0x00001000u; +} +inline void GlopParameters::clear_perturb_costs_in_dual_simplex() { + perturb_costs_in_dual_simplex_ = false; + clear_has_perturb_costs_in_dual_simplex(); +} +inline bool GlopParameters::perturb_costs_in_dual_simplex() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.perturb_costs_in_dual_simplex) + return perturb_costs_in_dual_simplex_; +} +inline void GlopParameters::set_perturb_costs_in_dual_simplex(bool value) { + set_has_perturb_costs_in_dual_simplex(); + perturb_costs_in_dual_simplex_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.perturb_costs_in_dual_simplex) +} + +// optional double relative_cost_perturbation = 54 [default = 1e-05]; +inline bool GlopParameters::has_relative_cost_perturbation() const { + return (_has_bits_[1] & 0x00002000u) != 0; +} +inline void GlopParameters::set_has_relative_cost_perturbation() { + _has_bits_[1] |= 0x00002000u; +} +inline void GlopParameters::clear_has_relative_cost_perturbation() { + _has_bits_[1] &= ~0x00002000u; +} +inline void GlopParameters::clear_relative_cost_perturbation() { + relative_cost_perturbation_ = 1e-05; + clear_has_relative_cost_perturbation(); +} +inline double GlopParameters::relative_cost_perturbation() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.relative_cost_perturbation) + return relative_cost_perturbation_; +} +inline void GlopParameters::set_relative_cost_perturbation(double value) { + set_has_relative_cost_perturbation(); + relative_cost_perturbation_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.relative_cost_perturbation) +} + +// optional double relative_max_cost_perturbation = 55 [default = 1e-07]; +inline bool GlopParameters::has_relative_max_cost_perturbation() const { + return (_has_bits_[1] & 0x00004000u) != 0; +} +inline void GlopParameters::set_has_relative_max_cost_perturbation() { + _has_bits_[1] |= 0x00004000u; +} +inline void GlopParameters::clear_has_relative_max_cost_perturbation() { + _has_bits_[1] &= ~0x00004000u; +} +inline void GlopParameters::clear_relative_max_cost_perturbation() { + relative_max_cost_perturbation_ = 1e-07; + clear_has_relative_max_cost_perturbation(); +} +inline double GlopParameters::relative_max_cost_perturbation() const { + // @@protoc_insertion_point(field_get:operations_research.glop.GlopParameters.relative_max_cost_perturbation) + return relative_max_cost_perturbation_; +} +inline void GlopParameters::set_relative_max_cost_perturbation(double value) { + set_has_relative_max_cost_perturbation(); + relative_max_cost_perturbation_ = value; + // @@protoc_insertion_point(field_set:operations_research.glop.GlopParameters.relative_max_cost_perturbation) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace glop +} // namespace operations_research + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::operations_research::glop::GlopParameters_SolverBehavior> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::glop::GlopParameters_SolverBehavior>() { + return ::operations_research::glop::GlopParameters_SolverBehavior_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::glop::GlopParameters_PricingRule> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::glop::GlopParameters_PricingRule>() { + return ::operations_research::glop::GlopParameters_PricingRule_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::glop::GlopParameters_InitialBasisHeuristic> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::glop::GlopParameters_InitialBasisHeuristic>() { + return ::operations_research::glop::GlopParameters_InitialBasisHeuristic_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fglop_2fparameters_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/glop/preprocessor.h b/thirdparty/linux/include/ortools/glop/preprocessor.h new file mode 100644 index 0000000..5a43d33 --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/preprocessor.h @@ -0,0 +1,999 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// This file contains the presolving code for a LinearProgram. +// +// A classical reference is: +// E. D. Andersen, K. D. Andersen, "Presolving in linear programming.", +// Mathematical Programming 71 (1995) 221-245. + +#ifndef OR_TOOLS_GLOP_PREPROCESSOR_H_ +#define OR_TOOLS_GLOP_PREPROCESSOR_H_ + +#include + +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/revised_simplex.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/lp_data/matrix_scaler.h" + +namespace operations_research { +namespace glop { + +// -------------------------------------------------------- +// Preprocessor +// -------------------------------------------------------- +// This is the base class for preprocessors. +// +// TODO(user): On most preprocessors, calling Run() more than once will not work +// as expected. Fix? or document and crash in debug if this happens. +class Preprocessor { + public: + Preprocessor(); + virtual ~Preprocessor(); + + // Runs the preprocessor by modifying the given linear program. Returns true + // if a postsolve step will be needed (i.e. RecoverSolution() is not the + // identity function). Also updates status_ to something different from + // ProblemStatus::INIT if the problem was solved (including bad statuses + // like ProblemStatus::ABNORMAL, ProblemStatus::INFEASIBLE, etc.). + virtual bool Run(LinearProgram* linear_program, TimeLimit* time_limit) = 0; + + // Stores the optimal solution of the linear program that was passed to + // Run(). The given solution needs to be set to the optimal solution of the + // linear program "modified" by Run(). + virtual void RecoverSolution(ProblemSolution* solution) const = 0; + + // Returns the status of the preprocessor. + // A status different from ProblemStatus::INIT means that the problem is + // solved and there is not need to call subsequent preprocessors. + ProblemStatus status() const { return status_; } + + // Stores the parameters for use by the different preprocessors. + void SetParameters(const GlopParameters& parameters) { + parameters_ = parameters; + } + + // Some preprocessors only need minimal changes when used with integer + // variables in a MIP context. Setting this to true allows to consider integer + // variables as integer in these preprocessors. + // + // Not all preprocessors handle integer variables correctly, calling this + // function on them will cause a LOG(FATAL). + virtual void UseInMipContext() { in_mip_context_ = true; } + + protected: + // Returns true if a is less than b (or slighlty greater than b with a given + // tolerance). + bool IsSmallerWithinFeasibilityTolerance(Fractional a, Fractional b) const { + return ::operations_research::IsSmallerWithinTolerance( + a, b, parameters_.solution_feasibility_tolerance()); + } + bool IsSmallerWithinPreprocessorZeroTolerance(Fractional a, + Fractional b) const { + // TODO(user): use an absolute tolerance here to be even more defensive? + return ::operations_research::IsSmallerWithinTolerance( + a, b, parameters_.preprocessor_zero_tolerance()); + } + + ProblemStatus status_; + GlopParameters parameters_; + bool in_mip_context_; + + private: + DISALLOW_COPY_AND_ASSIGN(Preprocessor); +}; + +// -------------------------------------------------------- +// MainLpPreprocessor +// -------------------------------------------------------- +// This is the main LP preprocessor responsible for calling all the other +// preprocessors in this file, possibly more than once. +class MainLpPreprocessor : public Preprocessor { + public: + MainLpPreprocessor() {} + ~MainLpPreprocessor() override {} + + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const override; + + private: + // Runs the given preprocessor and push it on preprocessors_ for the postsolve + // step when needed. + void RunAndPushIfRelevant(std::unique_ptr preprocessor, + const std::string& name, TimeLimit* time_limit, + LinearProgram* lp); + + // Stack of preprocessors currently applied to the lp that needs postsolve. + // + // TODO(user): This is mutable so that the preprocessor can be freed as soon + // as their RecoverSolution() is called. Make RecoverSolution() non-const or + // remove this optimization? + mutable std::vector> preprocessors_; + + // Initial dimension of the lp given to Run(), for displaying purpose. + EntryIndex initial_num_entries_; + RowIndex initial_num_rows_; + ColIndex initial_num_cols_; + + DISALLOW_COPY_AND_ASSIGN(MainLpPreprocessor); +}; + +// -------------------------------------------------------- +// ColumnDeletionHelper +// -------------------------------------------------------- +// Help preprocessors deal with column deletion. +class ColumnDeletionHelper { + public: + ColumnDeletionHelper() {} + + // Remember the given column as "deleted" so that it can later be restored + // by RestoreDeletedColumns(). Optionally, the caller may indicate the + // value and status of the corresponding variable so that it is automatically + // restored; if they don't then the restored value and status will be junk + // and must be set by the caller. + // + // The actual deletion is done by LinearProgram::DeleteColumns(). + void MarkColumnForDeletion(ColIndex col); + void MarkColumnForDeletionWithState(ColIndex col, Fractional value, + VariableStatus status); + + // From a solution omitting the deleted column, expands it and inserts the + // deleted columns. If values and statuses for the corresponding variables + // were saved, they'll be restored. + void RestoreDeletedColumns(ProblemSolution* solution) const; + + // Returns whether or not the given column is marked for deletion. + bool IsColumnMarked(ColIndex col) const { + return col < is_column_deleted_.size() && is_column_deleted_[col]; + } + + // Returns a Boolean vector of the column to be deleted. + const DenseBooleanRow& GetMarkedColumns() const { return is_column_deleted_; } + + // Returns true if no columns have been marked for deletion. + bool IsEmpty() const { return is_column_deleted_.empty(); } + + // Restores the class to its initial state. + void Clear(); + + // Returns the value that will be restored by + // RestoreDeletedColumnInSolution(). Note that only the marked position value + // make sense. + const DenseRow& GetStoredValue() const { return stored_value_; } + + private: + DenseBooleanRow is_column_deleted_; + + // Note that this vector has the same size as is_column_deleted_ and that + // the value of the variable corresponding to a deleted column col is stored + // at position col. Values of columns not deleted are not used. We use this + // data structure so columns can be deleted in any order if needed. + DenseRow stored_value_; + VariableStatusRow stored_status_; + DISALLOW_COPY_AND_ASSIGN(ColumnDeletionHelper); +}; + +// -------------------------------------------------------- +// RowDeletionHelper +// -------------------------------------------------------- +// Help preprocessors deal with row deletion. +class RowDeletionHelper { + public: + RowDeletionHelper() {} + + // Returns true if no rows have been marked for deletion. + bool IsEmpty() const { return is_row_deleted_.empty(); } + + // Restores the class to its initial state. + void Clear(); + + // Adds a deleted row to the helper. + void MarkRowForDeletion(RowIndex row); + + // If the given row was marked for deletion, unmark it. + void UnmarkRow(RowIndex row); + + // Returns a Boolean vector of the row to be deleted. + const DenseBooleanColumn& GetMarkedRows() const; + + // Returns whether or not the given row is marked for deletion. + bool IsRowMarked(RowIndex row) const { + return row < is_row_deleted_.size() && is_row_deleted_[row]; + } + + // From a solution without the deleted rows, expand it by restoring + // the deleted rows to a VariableStatus::BASIC status with 0.0 value. + // This latter value is important, many preprocessors rely on it. + void RestoreDeletedRows(ProblemSolution* solution) const; + + private: + DenseBooleanColumn is_row_deleted_; + + DISALLOW_COPY_AND_ASSIGN(RowDeletionHelper); +}; + +// -------------------------------------------------------- +// EmptyColumnPreprocessor +// -------------------------------------------------------- +// Removes the empty columns from the problem. +class EmptyColumnPreprocessor : public Preprocessor { + public: + EmptyColumnPreprocessor() {} + ~EmptyColumnPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + ColumnDeletionHelper column_deletion_helper_; + DISALLOW_COPY_AND_ASSIGN(EmptyColumnPreprocessor); +}; + +// -------------------------------------------------------- +// ProportionalColumnPreprocessor +// -------------------------------------------------------- +// TODO(user): For now this preprocessor just logs the number of proportional +// columns. Do something with this information. +// +// Removes the proportional columns from the problem when possible. Two columns +// are proportional if one is a non-zero scalar multiple of the other. +// +// Note that in the linear programming literature, two proportional columns are +// usually called duplicates. The notion is the same once the problem has been +// scaled. However, during presolve the columns can't be assumed to be scaled, +// so it makes sense to use the more general notion of proportional columns. +class ProportionalColumnPreprocessor : public Preprocessor { + public: + ProportionalColumnPreprocessor() {} + ~ProportionalColumnPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + void UseInMipContext() final { LOG(FATAL) << "Not implemented."; } + + private: + // Postsolve information about proportional columns with the same scaled cost + // that were merged during presolve. + + // The proportionality factor of each column. If two columns are proportional + // with factor p1 and p2 then p1 times the first column is the same as p2 + // times the second column. + DenseRow column_factors_; + + // If merged_columns_[col] != kInvalidCol, then column col has been merged + // into the column merged_columns_[col]. + ColMapping merged_columns_; + + // The old and new variable bounds. + DenseRow lower_bounds_; + DenseRow upper_bounds_; + DenseRow new_lower_bounds_; + DenseRow new_upper_bounds_; + + ColumnDeletionHelper column_deletion_helper_; + + DISALLOW_COPY_AND_ASSIGN(ProportionalColumnPreprocessor); +}; + +// -------------------------------------------------------- +// ProportionalRowPreprocessor +// -------------------------------------------------------- +// Removes the proportional rows from the problem. +// The linear programming literature also calls such rows duplicates, see the +// same remark above for columns in ProportionalColumnPreprocessor. +class ProportionalRowPreprocessor : public Preprocessor { + public: + ProportionalRowPreprocessor() {} + ~ProportionalRowPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + // Informations about proportional rows, only filled for such rows. + DenseColumn row_factors_; + RowMapping upper_bound_sources_; + RowMapping lower_bound_sources_; + + bool lp_is_maximization_problem_; + RowDeletionHelper row_deletion_helper_; + DISALLOW_COPY_AND_ASSIGN(ProportionalRowPreprocessor); +}; + +// -------------------------------------------------------- +// SingletonPreprocessor +// -------------------------------------------------------- +// Removes as many singleton rows and singleton columns as possible from the +// problem. Note that not all types of singleton columns can be removed. See the +// comments below on the SingletonPreprocessor functions for more details. +// +// TODO(user): Generalize the design used in this preprocessor to a general +// "propagation" framework in order to apply as many reductions as possible in +// an efficient manner. + +// Holds a triplet (row, col, coefficient). +struct MatrixEntry { + MatrixEntry(RowIndex _row, ColIndex _col, Fractional _coeff) + : row(_row), col(_col), coeff(_coeff) {} + RowIndex row; + ColIndex col; + Fractional coeff; +}; + +// Stores the information needed to undo a singleton row/column deletion. +class SingletonUndo { + public: + // The type of a given operation. + typedef enum { + ZERO_COST_SINGLETON_COLUMN, + SINGLETON_ROW, + SINGLETON_COLUMN_IN_EQUALITY, + MAKE_CONSTRAINT_AN_EQUALITY, + } OperationType; + + // Stores the information, which together with the field deleted_columns_ and + // deleted_rows_ of SingletonPreprocessor, are needed to undo an operation + // with the given type. Note that all the arguments must refer to the linear + // program BEFORE the operation is applied. + SingletonUndo(OperationType type, const LinearProgram& linear_program, + MatrixEntry e, ConstraintStatus status); + + // Undo the operation saved in this class, taking into account the deleted + // columns and rows passed by the calling instance of SingletonPreprocessor. + // Note that the operations must be undone in the reverse order of the one + // in which they were applied. + void Undo(const GlopParameters& parameters, + const SparseMatrix& deleted_columns, + const SparseMatrix& deleted_rows, ProblemSolution* solution) const; + + private: + // Actual undo functions for each OperationType. + // Undo() just calls the correct one. + void SingletonRowUndo(const SparseMatrix& deleted_columns, + ProblemSolution* solution) const; + void ZeroCostSingletonColumnUndo(const GlopParameters& parameters, + const SparseMatrix& deleted_rows, + ProblemSolution* solution) const; + void SingletonColumnInEqualityUndo(const GlopParameters& parameters, + const SparseMatrix& deleted_rows, + ProblemSolution* solution) const; + void MakeConstraintAnEqualityUndo(ProblemSolution* solution) const; + + // All the information needed during undo. + OperationType type_; + bool is_maximization_; + MatrixEntry e_; + Fractional cost_; + + // TODO(user): regroup the pair (lower bound, upper bound) in a bound class? + Fractional variable_lower_bound_; + Fractional variable_upper_bound_; + Fractional constraint_lower_bound_; + Fractional constraint_upper_bound_; + + // This in only used with MAKE_CONSTRAINT_AN_EQUALITY undo. + // TODO(user): Clean that up using many Undo classes and virtual functions. + ConstraintStatus constraint_status_; +}; + +// Deletes as many singleton rows or singleton columns as possible. Note that +// each time we delete a row or a column, new singletons may be created. +class SingletonPreprocessor : public Preprocessor { + public: + SingletonPreprocessor() {} + ~SingletonPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + // Returns the MatrixEntry of the given singleton row or column, taking into + // account the rows and columns that were already deleted. + MatrixEntry GetSingletonColumnMatrixEntry(ColIndex col, + const SparseMatrix& matrix); + MatrixEntry GetSingletonRowMatrixEntry(RowIndex row, + const SparseMatrix& matrix_transpose); + + // A singleton row can always be removed by changing the corresponding + // variable bounds to take into account the bounds on this singleton row. + void DeleteSingletonRow(MatrixEntry e, LinearProgram* lp); + + // Internal operation when removing a zero-cost singleton column corresponding + // to the given entry. This modifies the constraint bounds to take into acount + // the bounds of the corresponding variable. + void UpdateConstraintBoundsWithVariableBounds(MatrixEntry e, + LinearProgram* lp); + + + // A singleton column with a cost of zero can always be removed by changing + // the corresponding constraint bounds to take into acount the bound of this + // singleton column. + void DeleteZeroCostSingletonColumn(const SparseMatrix& matrix_transpose, + MatrixEntry e, LinearProgram* lp); + + // Returns true if the constraint associated to the given singleton column was + // an equality or could be made one: + // If a singleton variable is free in a direction that improves the cost, then + // we can always move it as much as possible in this direction. Only the + // constraint will stop us, making it an equality. If the constraint doesn't + // stop us, then the program is unbounded (provided that there is a feasible + // solution). + // + // Note that this operation does not need any "undo" during the post-solve. At + // optimality, the dual value on the constraint row will be of the correct + // sign, and relaxing the constraint bound will not impact the dual + // feasibility of the solution. + // + // TODO(user): this operation can be generalized to columns with just one + // blocking constraint. Investigate how to use this. The 'reverse' can + // probably also be done, relaxing a constraint that is blocking a + // unconstrained variable. + bool MakeConstraintAnEqualityIfPossible(const SparseMatrix& matrix_transpose, + MatrixEntry e, LinearProgram* lp); + + // If a singleton column appears in an equality, we can remove its cost by + // changing the other variables cost using the constraint. We can then delete + // the column like in DeleteZeroCostSingletonColumn(). + void DeleteSingletonColumnInEquality(const SparseMatrix& matrix_transpose, + MatrixEntry e, LinearProgram* lp); + + ColumnDeletionHelper column_deletion_helper_; + RowDeletionHelper row_deletion_helper_; + std::vector undo_stack_; + + // This is used as a "cache" by MakeConstraintAnEqualityIfPossible() to avoid + // scanning more than once each row. See the code to see how this is used. + ITIVector row_sum_is_cached_; + ITIVector row_lb_sum_; + ITIVector row_ub_sum_; + + // The columns that are deleted by this preprocessor. + SparseMatrix deleted_columns_; + // The transpose of the rows that are deleted by this preprocessor. + // TODO(user): implement a RowMajorSparseMatrix class to simplify the code. + SparseMatrix deleted_rows_; + + DISALLOW_COPY_AND_ASSIGN(SingletonPreprocessor); +}; + +// -------------------------------------------------------- +// FixedVariablePreprocessor +// -------------------------------------------------------- +// Removes the fixed variables from the problem. +class FixedVariablePreprocessor : public Preprocessor { + public: + FixedVariablePreprocessor() {} + ~FixedVariablePreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + ColumnDeletionHelper column_deletion_helper_; + DISALLOW_COPY_AND_ASSIGN(FixedVariablePreprocessor); +}; + +// -------------------------------------------------------- +// ForcingAndImpliedFreeConstraintPreprocessor +// -------------------------------------------------------- +// This preprocessor computes for each constraint row the bounds that are +// implied by the variable bounds and applies one of the following reductions: +// +// * If the intersection of the implied bounds and the current constraint bounds +// is empty (modulo some tolerance), the problem is INFEASIBLE. +// +// * If the intersection of the implied bounds and the current constraint bounds +// is a singleton (modulo some tolerance), then the constraint is said to be +// forcing and all the variables that appear in it can be fixed to one of their +// bounds. All these columns and the constraint row is removed. +// +// * If the implied bounds are included inside the current constraint bounds +// (modulo some tolerance) then the constraint is said to be redundant or +// implied free. Its bounds are relaxed and the constraint will be removed +// later by the FreeConstraintPreprocessor. +// +// * Otherwise, wo do nothing. +class ForcingAndImpliedFreeConstraintPreprocessor : public Preprocessor { + public: + ForcingAndImpliedFreeConstraintPreprocessor() {} + ~ForcingAndImpliedFreeConstraintPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + bool lp_is_maximization_problem_; + SparseMatrix deleted_columns_; + DenseRow costs_; + DenseBooleanColumn is_forcing_up_; + ColumnDeletionHelper column_deletion_helper_; + RowDeletionHelper row_deletion_helper_; + + DISALLOW_COPY_AND_ASSIGN(ForcingAndImpliedFreeConstraintPreprocessor); +}; + +// -------------------------------------------------------- +// ImpliedFreePreprocessor +// -------------------------------------------------------- +// It is possible to compute "implied" bounds on a variable from the bounds of +// all the other variables and the constraints in which this variable take +// place. If such "implied" bounds are inside the variable bounds, then the +// variable bounds can be relaxed and the variable is said to be "implied free". +// +// This preprocessor detects the implied free variables and make as many as +// possible free with a priority towards low-degree columns. This transformation +// will make the simplex algorithm more efficient later, but will also make it +// possible to reduce the problem by applying subsequent transformations: +// +// * The SingletonPreprocessor already deals with implied free singleton +// variables and removes the columns and the rows in which they appear. +// +// * Any multiple of the column of a free variable can be added to any other +// column without changing the linear program solution. This is the dual +// counterpart of the fact that any multiple of an equality row can be added to +// any row. +// +// TODO(user): Only process doubleton columns so we have more chance in the +// later passes to create more doubleton columns? Such columns lead to a smaller +// problem thanks to the DoubletonFreeColumnPreprocessor. +class ImpliedFreePreprocessor : public Preprocessor { + public: + ImpliedFreePreprocessor() {} + ~ImpliedFreePreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + // This preprocessor adds fixed offsets to some variables. We remember those + // here to un-offset them in RecoverSolution(). + DenseRow variable_offsets_; + + // This preprocessor causes some variables who would normally be + // AT_{LOWER,UPPER}_BOUND to be VariableStatus::FREE. We store the restore + // value of these variables; which will only be used (eg. restored) if the + // variable actually turns out to be VariableStatus::FREE. + VariableStatusRow postsolve_status_of_free_variables_; + + DISALLOW_COPY_AND_ASSIGN(ImpliedFreePreprocessor); +}; + +// -------------------------------------------------------- +// DoubletonFreeColumnPreprocessor +// -------------------------------------------------------- +// This preprocessor removes one of the two rows in which a doubleton column of +// a free variable appears. Since we can add any multiple of such a column to +// any other column, the way this works is that we can always remove all the +// entries on one row. +// +// Actually, we can remove all the entries except the one of the free column. +// But we will be left with a singleton row that we can delete in the same way +// as what is done in SingletonPreprocessor. That is by reporting the constraint +// bounds into the one of the originally free variable. After this operation, +// the doubleton free column will become a singleton and may or may not be +// removed later by the SingletonPreprocessor. +// +// Note that this preprocessor can be seen as the dual of the +// DoubletonEqualityRowPreprocessor since when taking the dual, an equality row +// becomes a free variable and vice versa. +// +// Note(user): As far as I know, this doubleton free column procedure is more +// general than what can be found in the research papers or in any of the linear +// solver open source codes as of July 2013. All of them only process such +// columns if one of the two rows is also an equality which is not actually +// required. Most probably, commercial solvers do use it though. +class DoubletonFreeColumnPreprocessor : public Preprocessor { + public: + DoubletonFreeColumnPreprocessor() {} + ~DoubletonFreeColumnPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + void UseInMipContext() final { + LOG(FATAL) << "Not implemented."; + } + + private: + enum RowChoice { + DELETED = 0, + MODIFIED = 1, + // This is just a constant for the number of rows in a doubleton column. + // That is 2, one will be DELETED, the other MODIFIED. + NUM_ROWS = 2, + }; + struct RestoreInfo { + // The index of the original free doubleton column and its objective. + ColIndex col; + Fractional objective_coefficient; + + // The row indices of the two involved rows and their coefficients on + // column col. + RowIndex row[NUM_ROWS]; + Fractional coeff[NUM_ROWS]; + + // The deleted row as a column. + SparseColumn deleted_row_as_column; + }; + std::vector restore_stack_; + RowDeletionHelper row_deletion_helper_; + DISALLOW_COPY_AND_ASSIGN(DoubletonFreeColumnPreprocessor); +}; + +// -------------------------------------------------------- +// UnconstrainedVariablePreprocessor +// -------------------------------------------------------- +// If for a given variable, none of the constraints block it in one direction +// and this direction improves the objective, then this variable can be fixed to +// its bound in this direction. If this bound is infinite and the variable cost +// is non-zero, then the problem is unbounded. +// +// TODO(user): This is similar to a preprocessor infering bounds on the reduced +// costs to fix a variable. It deals with less cases, however there are no +// numerical errors here. +class UnconstrainedVariablePreprocessor : public Preprocessor { + public: + UnconstrainedVariablePreprocessor() {} + ~UnconstrainedVariablePreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + // Removes the given variable and all the rows in which it appears: If a + // variable is unconstrained with a zero cost, then all the constraints in + // which it appears can be made free! More precisely, during postsolve, if + // such a variable is unconstrained towards +kInfinity, for any activity value + // of the involved constraints, an M exists such that for each value of the + // variable >= M the problem will be feasible. + // + // The algorithm during postsolve is to find a feasible value for all such + // variables while trying to keep their magnitudes small (for better numerical + // behavior). target_bound should take only two possible values: +/-kInfinity. + void RemoveZeroCostUnconstrainedVariable(ColIndex col, + Fractional target_bound, + LinearProgram* lp); + + private: + ColumnDeletionHelper column_deletion_helper_; + RowDeletionHelper row_deletion_helper_; + DenseColumn rhs_; + DenseColumn activity_sign_correction_; + DenseBooleanRow is_unbounded_; + + SparseMatrix deleted_columns_; + SparseMatrix deleted_rows_as_column_; + + DISALLOW_COPY_AND_ASSIGN(UnconstrainedVariablePreprocessor); +}; + +// -------------------------------------------------------- +// FreeConstraintPreprocessor +// -------------------------------------------------------- +// Removes the constraints with no bounds from the problem. +class FreeConstraintPreprocessor : public Preprocessor { + public: + FreeConstraintPreprocessor() {} + ~FreeConstraintPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + RowDeletionHelper row_deletion_helper_; + DISALLOW_COPY_AND_ASSIGN(FreeConstraintPreprocessor); +}; + +// -------------------------------------------------------- +// EmptyConstraintPreprocessor +// -------------------------------------------------------- +// Removes the constraints with no coefficients from the problem. +class EmptyConstraintPreprocessor : public Preprocessor { + public: + EmptyConstraintPreprocessor() {} + ~EmptyConstraintPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + RowDeletionHelper row_deletion_helper_; + DISALLOW_COPY_AND_ASSIGN(EmptyConstraintPreprocessor); +}; + +// -------------------------------------------------------- +// RemoveNearZeroEntriesPreprocessor +// -------------------------------------------------------- +// Removes matrix entries that have only a negligible impact on the solution. +// Using the variable bounds, we derive a maximum possible impact, and remove +// the entries whose impact is under a given tolerance. +// +// TODO(user): This preprocessor doesn't work well on badly scaled problems. In +// particular, it will set the objective to zero if all the objective +// coefficients are small! Run it after ScalingPreprocessor or fix the code. +class RemoveNearZeroEntriesPreprocessor : public Preprocessor { + public: + RemoveNearZeroEntriesPreprocessor() {} + ~RemoveNearZeroEntriesPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + DISALLOW_COPY_AND_ASSIGN(RemoveNearZeroEntriesPreprocessor); +}; + +// -------------------------------------------------------- +// SingletonColumnSignPreprocessor +// -------------------------------------------------------- +// Make sure that the only coefficient of all singleton columns (i.e. column +// with only one entry) is positive. This is because this way the column will +// be transformed in an identity column by the scaling. This will lead to more +// efficient solve when this column is involved. +class SingletonColumnSignPreprocessor : public Preprocessor { + public: + SingletonColumnSignPreprocessor() {} + ~SingletonColumnSignPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + std::vector changed_columns_; + DISALLOW_COPY_AND_ASSIGN(SingletonColumnSignPreprocessor); +}; + +// -------------------------------------------------------- +// DoubletonEqualityRowPreprocessor +// -------------------------------------------------------- +// Reduce equality constraints involving two variables (i.e. aX + bY = c), +// by substitution (and thus removal) of one of the variables by the other +// in all the constraints that it is involved in. +class DoubletonEqualityRowPreprocessor : public Preprocessor { + public: + DoubletonEqualityRowPreprocessor() {} + ~DoubletonEqualityRowPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + enum ColChoice { + DELETED = 0, + MODIFIED = 1, + // For for() loops iterating over the ColChoice values, and/or arrays. + NUM_DOUBLETON_COLS = 2, + }; + static ColChoice OtherColChoice(ColChoice x) { + return x == DELETED ? MODIFIED : DELETED; + } + + ColumnDeletionHelper column_deletion_helper_; + RowDeletionHelper row_deletion_helper_; + + struct RestoreInfo { + // The row index of the doubleton equality constraint, and its constant. + RowIndex row; + Fractional rhs; // The constant c in the equality aX + bY = c. + + // The indices and the data of the two columns that we touched, exactly + // as they were beforehand. + ColIndex col[NUM_DOUBLETON_COLS]; + Fractional coeff[NUM_DOUBLETON_COLS]; + Fractional lb[NUM_DOUBLETON_COLS]; + Fractional ub[NUM_DOUBLETON_COLS]; + SparseColumn column[NUM_DOUBLETON_COLS]; + Fractional objective_coefficient[NUM_DOUBLETON_COLS]; + + // If the modified variable has status AT_[LOWER,UPPER]_BOUND, then we'll + // set one of the two original variables to one of its bounds, and set the + // other to VariableStatus::BASIC. We store this information (which variable + // will be set to one of its bounds, and which bound) for each possible + // outcome. + struct ColChoiceAndStatus { + ColChoice col_choice; + VariableStatus status; + Fractional value; + ColChoiceAndStatus() : col_choice(), status(), value(0.0) {} + ColChoiceAndStatus(ColChoice c, VariableStatus s, Fractional v) + : col_choice(c), status(s), value(v) {} + }; + ColChoiceAndStatus bound_backtracking_at_lower_bound; + ColChoiceAndStatus bound_backtracking_at_upper_bound; + }; + void SwapDeletedAndModifiedVariableRestoreInfo(RestoreInfo* r); + + std::vector restore_stack_; + + DISALLOW_COPY_AND_ASSIGN(DoubletonEqualityRowPreprocessor); +}; + +// -------------------------------------------------------- +// DualizerPreprocessor +// -------------------------------------------------------- +// DualizerPreprocessor may change the given program to its dual depending +// on the value of the parameter solve_dual_problem. +// +// IMPORTANT: FreeConstraintPreprocessor() must be called first since this +// preprocessor does not deal correctly with free constraints. +class DualizerPreprocessor : public Preprocessor { + public: + DualizerPreprocessor() {} + ~DualizerPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + void UseInMipContext() final { + LOG(FATAL) << "In the presence of integer variables, " + << "there is no notion of a dual problem."; + } + + // Convert the given problem status to the one of its dual. + ProblemStatus ChangeStatusToDualStatus(ProblemStatus status) const; + + private: + DenseRow variable_lower_bounds_; + DenseRow variable_upper_bounds_; + + RowIndex primal_num_rows_; + ColIndex primal_num_cols_; + bool primal_is_maximization_problem_; + RowToColMapping duplicated_rows_; + + // For postsolving the variable/constraint statuses. + VariableStatusRow dual_status_correspondence_; + ColMapping slack_or_surplus_mapping_; + + DISALLOW_COPY_AND_ASSIGN(DualizerPreprocessor); +}; + +// -------------------------------------------------------- +// ShiftVariableBoundsPreprocessor +// -------------------------------------------------------- +// For each variable, inspects its bounds and "shift" them if necessary, so that +// its domain contains zero. A variable that was shifted will always have at +// least one of its bounds to zero. Doing it all at once allows to have a better +// precision when modifying the constraint bounds by using an accurate summation +// algorithm. +// +// Example: +// - A variable with bound [1e10, infinity] will be shifted to [0, infinity]. +// - A variable with domain [-1e10, 1e10] will not be shifted. Note that +// compared to the first case, doing so here may introduce unecessary +// numerical errors if the variable value in the final solution is close to +// zero. +// +// The expected impact of this is: +// - Better behavior of the scaling. +// - Better precision and numerical accuracy of the simplex method. +// - Slightly improved speed (because adding a column with a variable value of +// zero takes no work later). +// +// TODO(user): Having for each variable one of their bounds at zero is a +// requirement for the DualizerPreprocessor and for the implied free column in +// the ImpliedFreePreprocessor. However, shifting a variable with a domain like +// [-1e10, 1e10] may introduce numerical issues. Relax the definition of +// a free variable so that only having a domain containing 0.0 is enough? +class ShiftVariableBoundsPreprocessor : public Preprocessor { + public: + ShiftVariableBoundsPreprocessor() {} + ~ShiftVariableBoundsPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + // Contains for each variable by how much its bounds where shifted during + // presolve. Note that the shift was negative (new bound = initial bound - + // offset). + DenseRow offsets_; + // Contains the initial problem bounds. They are needed to get the perfect + // numerical accuracy for variables at their bound after postsolve. + DenseRow variable_initial_lbs_; + DenseRow variable_initial_ubs_; + DISALLOW_COPY_AND_ASSIGN(ShiftVariableBoundsPreprocessor); +}; + +// -------------------------------------------------------- +// ScalingPreprocessor +// -------------------------------------------------------- +// Scales the SparseMatrix of the linear program using a SparseMatrixScaler. +// This is only applied if the parameter use_scaling is true. +class ScalingPreprocessor : public Preprocessor { + public: + ScalingPreprocessor() {} + ~ScalingPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + void UseInMipContext() final { LOG(FATAL) << "Not implemented."; } + + private: + DenseRow variable_lower_bounds_; + DenseRow variable_upper_bounds_; + Fractional cost_scaling_factor_; + SparseMatrixScaler scaler_; + + DISALLOW_COPY_AND_ASSIGN(ScalingPreprocessor); +}; + +// -------------------------------------------------------- +// ToMinimizationPreprocessor +// -------------------------------------------------------- +// Changes the problem from maximization to minimization (if applicable). +// As of 2015/09/03 this is not used by Glop, but will be used by Glip. +// The preprocessor is kept here, because it could be used by Glop too. +class ToMinimizationPreprocessor : public Preprocessor { + public: + ToMinimizationPreprocessor() {} + ~ToMinimizationPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + DISALLOW_COPY_AND_ASSIGN(ToMinimizationPreprocessor); +}; + +// -------------------------------------------------------- +// AddSlackVariablesPreprocessor +// -------------------------------------------------------- +// Transforms the linear program to the equation form +// min c.x, s.t. A.x = 0. This is done by: +// 1. Introducing slack variables for all constraints; all these variables are +// introduced with coefficient 1.0, and their bounds are set to be negative +// bounds of the corresponding constraint. +// 2. Changing the bounds of all constraints to (0, 0) to make them an equality. +// +// As a consequence, the matrix of the linear program always has full row rank +// after this preprocessor. Note that the slack variables are always added last, +// so that the rightmost square sub-matrix is always the identity matrix. +class AddSlackVariablesPreprocessor : public Preprocessor { + public: + AddSlackVariablesPreprocessor() {} + ~AddSlackVariablesPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + ColIndex first_slack_col_; + + DISALLOW_COPY_AND_ASSIGN(AddSlackVariablesPreprocessor); +}; + +// -------------------------------------------------------- +// SolowHalimPreprocessor +// -------------------------------------------------------- +// Modifies the problem by changing variables to begin +// geometrically near to the optimal solution according to the suggestion of +// Solow & Halim. +// Variable changes have a very simple form : +// x_j' = upper_bound(j) - x_j if cost(j) > 0 +// x_j' = -lower_bound(j) + x_j if cost(j) < 0 +// for a maximization problem +// +// reference: +// Improving the Efficiency of the Simplex Algorithm Based on a +// Geometric Explanation of Phase 1 +// https://weatherhead.case.edu/faculty/research/library/detail?id=12128593921 +// DOI: 10.1504/IJOR.2009.025701 +class SolowHalimPreprocessor : public Preprocessor { + public: + SolowHalimPreprocessor() {} + ~SolowHalimPreprocessor() final {} + bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + void RecoverSolution(ProblemSolution* solution) const final; + + private: + typedef enum { + NOT_MODIFIED = 0, + SHIFTED = 1, + SHIFTED_OPPOSITE_DIRECTION = 2 + } ColumnTransformType; + + // Contains the coordinate change information for each column + ITIVector column_transform_; + + // Contains the initial problem bounds. + DenseRow variable_initial_lbs_; + DenseRow variable_initial_ubs_; + DISALLOW_COPY_AND_ASSIGN(SolowHalimPreprocessor); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_PREPROCESSOR_H_ diff --git a/thirdparty/linux/include/ortools/glop/primal_edge_norms.h b/thirdparty/linux/include/ortools/glop/primal_edge_norms.h new file mode 100644 index 0000000..c6b51e1 --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/primal_edge_norms.h @@ -0,0 +1,210 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_PRIMAL_EDGE_NORMS_H_ +#define OR_TOOLS_GLOP_PRIMAL_EDGE_NORMS_H_ + +#include "ortools/glop/basis_representation.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/update_row.h" +#include "ortools/glop/variables_info.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace glop { + +// This class maintains the primal edge squared norms (and other variants) to be +// used in the primal pricing step. Instead of computing the needed values from +// scractch at each iteration, it is more efficient to update them incrementally +// for each basis pivot applied to the simplex basis matrix B. +// +// Terminology: +// - To each non-basic column 'a' of a matrix A, we can associate an "edge" in +// the kernel of A equal to 1.0 on the index of 'a' and '-B^{-1}.a' on the +// basic variables. +// - 'B^{-1}.a' is called the "right inverse" of 'a'. +// - The entering edge is the edge we are following during a simplex step, +// and we call "direction" the reverse of this edge restricted to the +// basic variables, i.e. the right inverse of the entering column. +// +// Papers: +// - D. Goldfarb, J.K. Reid, "A practicable steepest-edge simplex algorithm" +// Mathematical Programming 12 (1977) 361-371, North-Holland. +// http://www.springerlink.com/content/g8335137n3j16934/ +// - J.J. Forrest, D. Goldfarb, "Steepest-edge simplex algorithms for linear +// programming", Mathematical Programming 57 (1992) 341-374, North-Holland. +// http://www.springerlink.com/content/q645w3t2q229m248/ +// - Ping-Qi Pan "A fast simplex algorithm for linear programming". +// http://www.optimization-online.org/DB_FILE/2007/10/1805.pdf +// - Ping-Qi Pan, "Efficient nested pricing in the simplex algorithm", +// http://www.optimization-online.org/DB_FILE/2007/10/1810.pdf +class PrimalEdgeNorms { + public: + // Takes references to the linear program data we need. Note that we assume + // that the matrix will never change in our back, but the other references are + // supposed to reflect the correct state. + PrimalEdgeNorms(const MatrixView& matrix, + const CompactSparseMatrix& compact_matrix, + const VariablesInfo& variables_info, + const BasisFactorization& basis_factorization); + + // Clears, i.e. resets the object to its initial value. This will trigger + // a recomputation for the next Get*() method call. + void Clear(); + + // If this is true, then the caller must re-factorize the basis before the + // next call to GetEdgeSquaredNorms(). This is because the latter will + // recompute the norms from scratch and therefore needs a hightened precision + // and speed. + bool NeedsBasisRefactorization() const; + + // Returns the primal edge squared norms. This is only valid if the caller + // properly called UpdateBeforeBasisPivot() before each basis pivot, or if + // this is the first call to this function after a Clear(). Note that only the + // relevant columns are filled. + const DenseRow& GetEdgeSquaredNorms(); + + // Returns an approximation of the edges norms "devex". + // This is only valid if the caller properly called UpdateBeforeBasisPivot() + // before each basis pivot, or if this is the first call to this function + // after a Clear(). + const DenseRow& GetDevexWeights(); + + // Returns the L2 norms of all the columns of A. + // Note that this is currently not cleared by Clear(). + const DenseRow& GetMatrixColumnNorms(); + + // Compares the current entering edge norm with its precise version (using the + // direction that wasn't avaible before) and triggers a full recomputation if + // the precision is not good enough (see recompute_edges_norm_threshold in + // GlopParameters). As a side effect, this replace the entering_col edge + // norm with its precise version. + void TestEnteringEdgeNormPrecision(ColIndex entering_col, + ScatteredColumnReference direction); + + // Updates any internal data BEFORE the given simplex pivot is applied to B. + // Note that no updates are needed in case of a bound flip. + // The arguments are in order: + // - The index of the entering non-basic column of A. + // - The index in B of the leaving basic variable. + // - The 'direction', i.e. the right inverse of the entering column. + // - The update row (see UpdateRow), which will only be computed if needed. + void UpdateBeforeBasisPivot(ColIndex entering_col, ColIndex leaving_col, + RowIndex leaving_row, + ScatteredColumnReference direction, + UpdateRow* update_row); + + // Sets the algorithm parameters. + void SetParameters(const GlopParameters& parameters) { + parameters_ = parameters; + } + + // Returns a std::string with statistics about this class. + std::string StatString() const { return stats_.StatString(); } + + // Deterministic time used by the scalar product computation of this class. + double DeterministicTime() const { + return DeterministicTimeForFpOperations(num_operations_); + } + + private: + // Statistics about this class. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("PrimalEdgeNorms"), + direction_left_inverse_density("direction_left_inverse_density", + this), + direction_left_inverse_accuracy("direction_left_inverse_accuracy", + this), + edges_norm_accuracy("edges_norm_accuracy", this), + lower_bounded_norms("lower_bounded_norms", this) {} + RatioDistribution direction_left_inverse_density; + DoubleDistribution direction_left_inverse_accuracy; + DoubleDistribution edges_norm_accuracy; + IntegerDistribution lower_bounded_norms; + }; + + // Recompute the matrix column L2 norms from scratch. + void ComputeMatrixColumnNorms(); + + // Recompute the edge squared L2 norms from scratch. + void ComputeEdgeSquaredNorms(); + + // Compute the left inverse of the direction. + // The first argument is there for checking precision. + void ComputeDirectionLeftInverse(ColIndex entering_col, + ScatteredColumnReference direction); + + // Updates edges_squared_norm_ according to the given pivot. + void UpdateEdgeSquaredNorms(ColIndex entering_col, ColIndex leaving_col, + RowIndex leaving_row, + const DenseColumn& direction, + const UpdateRow& update_row); + + // Resets all devex weights to 1.0 . + void ResetDevexWeights(); + + // Updates devex_weights_ according to the given pivot. + void UpdateDevexWeights(ColIndex entering_col, ColIndex leaving_col, + RowIndex leaving_row, const DenseColumn& direction, + const UpdateRow& update_row); + + // Problem data that should be updated from outside. + const MatrixView& matrix_; + const CompactSparseMatrix& compact_matrix_; + const VariablesInfo& variables_info_; + const BasisFactorization& basis_factorization_; + + // Internal data. + GlopParameters parameters_; + Stats stats_; + + // Booleans to control what happens on the next ChooseEnteringColumn() call. + bool must_refactorize_basis_; + bool recompute_edge_squared_norms_; + bool reset_devex_weights_; + + // Norm^2 of the edges of the relevant columns of A. + DenseRow edge_squared_norms_; + + // Norm of all the columns of A. + DenseRow matrix_column_norms_; + + // Approximation of edges norms "devex". + // Denoted by vector 'w' in Pin Qi Pan (1810.pdf section 1.1.4) + // At any time, devex_weights_ >= 1.0. + DenseRow devex_weights_; + + // Tracks number of updates of the devex weights since we have to reset + // them to 1.0 every now and then. + int num_devex_updates_since_reset_; + + // Left inverse by B of the 'direction'. This is the transpose of 'v' in the + // steepest edge paper. Its scalar product with a column 'a' of A gives the + // value of the scalar product of the 'direction' with the right inverse of + // 'a'. + DenseRow direction_left_inverse_; + ColIndexVector direction_left_inverse_non_zeros_; + + // Used by DeterministicTime(). + int64 num_operations_; + + DISALLOW_COPY_AND_ASSIGN(PrimalEdgeNorms); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_PRIMAL_EDGE_NORMS_H_ diff --git a/thirdparty/linux/include/ortools/glop/rank_one_update.h b/thirdparty/linux/include/ortools/glop/rank_one_update.h new file mode 100644 index 0000000..f6e2adb --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/rank_one_update.h @@ -0,0 +1,250 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_RANK_ONE_UPDATE_H_ +#define OR_TOOLS_GLOP_RANK_ONE_UPDATE_H_ + +#include "ortools/base/logging.h" +#include "ortools/glop/status.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/lp_data/lp_utils.h" +#include "ortools/lp_data/sparse.h" + +namespace operations_research { +namespace glop { + +// This class holds a matrix of the form T = I + u.Tr(v) where I is the +// identity matrix and u and v are two column vectors of the same size as I. It +// allows for efficient left and right solves with T. When T is non-singular, +// it is easy to show that T^{-1} = I - 1 / mu * u.Tr(v) where +// mu = 1.0 + Tr(v).u +// +// Note that when v is a unit vector, T is a regular Eta matrix and when u +// is a unit vector, T is a row-wise Eta matrix. +// +// This is based on section 3.1 of: +// Qi Huangfu, J. A. Julian Hall, "Novel update techniques for the revised +// simplex method", 28 january 2013, Technical Report ERGO-13-0001 +class RankOneUpdateElementaryMatrix { + public: + // Rather than copying the vectors u and v, RankOneUpdateElementaryMatrix + // takes two columns of a provided CompactSparseMatrix which is used for + // storage. This has a couple of advantages, especially in the context of the + // RankOneUpdateFactorization below: + // - It uses less overall memory (and avoid allocation overhead). + // - It has a better cache behavior for the RankOneUpdateFactorization solves. + RankOneUpdateElementaryMatrix(const CompactSparseMatrix* storage, + ColIndex u_index, ColIndex v_index, + Fractional u_dot_v) + : storage_(storage), + u_index_(u_index), + v_index_(v_index), + mu_(1.0 + u_dot_v) {} + + // Returns whether or not this matrix is singular. + // Note that the RightSolve() and LeftSolve() function will fail if this is + // the case. + bool IsSingular() const { return mu_ == 0.0; } + + // Solves T.x = rhs with rhs initialy in x (a column vector). + // The non-zeros version keeps track of the new non-zeros. + void RightSolve(DenseColumn* x) const { + DCHECK(!IsSingular()); + const Fractional multiplier = + -storage_->ColumnScalarProduct(v_index_, Transpose(*x)) / mu_; + storage_->ColumnAddMultipleToDenseColumn(u_index_, multiplier, x); + } + void RightSolveWithNonZeros(DenseColumn* x, + StrictITIVector* is_non_zero, + std::vector* non_zeros) const { + DCHECK(!IsSingular()); + const Fractional multiplier = + -storage_->ColumnScalarProduct(v_index_, Transpose(*x)) / mu_; + if (multiplier != 0.0) { + storage_->ColumnAddMultipleToDenseColumnAndUpdateNonZeros( + u_index_, multiplier, x, is_non_zero, non_zeros); + } + } + + // Solves y.T = rhs with rhs initialy in y (a row vector). + // The non-zeros version keeps track of the new non-zeros. + void LeftSolve(DenseRow* y) const { + DCHECK(!IsSingular()); + const Fractional multiplier = + -storage_->ColumnScalarProduct(u_index_, *y) / mu_; + storage_->ColumnAddMultipleToDenseColumn(v_index_, multiplier, + reinterpret_cast(y)); + } + void LeftSolveWithNonZeros(DenseRow* y, + StrictITIVector* is_non_zero, + std::vector* non_zeros) const { + DCHECK(!IsSingular()); + const Fractional multiplier = + -storage_->ColumnScalarProduct(u_index_, *y) / mu_; + if (multiplier != 0.0) { + storage_->ColumnAddMultipleToDenseColumnAndUpdateNonZeros( + v_index_, multiplier, reinterpret_cast(y), + reinterpret_cast*>(is_non_zero), + reinterpret_cast*>(non_zeros)); + } + } + + // Computes T.x for a given column vector. + void RightMultiply(DenseColumn* x) const { + const Fractional multiplier = + storage_->ColumnScalarProduct(v_index_, Transpose(*x)); + storage_->ColumnAddMultipleToDenseColumn(u_index_, multiplier, x); + } + + // Computes y.T for a given row vector. + void LeftMultiply(DenseRow* y) const { + const Fractional multiplier = storage_->ColumnScalarProduct(u_index_, *y); + storage_->ColumnAddMultipleToDenseColumn(v_index_, multiplier, + reinterpret_cast(y)); + } + + EntryIndex num_entries() const { + return storage_->column(u_index_).num_entries() + + storage_->column(v_index_).num_entries(); + } + + private: + // This is only used in debug mode. + Fractional ComputeUScalarV() const { + DenseColumn dense_u; + storage_->ColumnCopyToDenseColumn(u_index_, &dense_u); + return storage_->ColumnScalarProduct(v_index_, Transpose(dense_u)); + } + + // Note that we allow copy and assignment so we can store a + // RankOneUpdateElementaryMatrix in an STL container. + const CompactSparseMatrix* storage_; + ColIndex u_index_; + ColIndex v_index_; + Fractional mu_; +}; + +// A rank one update factorization corresponds to the product of k rank one +// update elementary matrices, i.e. T = T_0.T_1. ... .T_{k-1} +class RankOneUpdateFactorization { + public: + // TODO(user): make the 5% a parameter and share it between all the places + // that switch between a sparse/dense version. + RankOneUpdateFactorization() : hypersparse_ratio_(0.05) {} + + // This is currently only visible for testing. + void set_hypersparse_ratio(double value) { hypersparse_ratio_ = value; } + + // Deletes all elementary matrices of this factorization. + void Clear() { + elementary_matrices_.clear(); + num_entries_ = 0; + } + + // Updates the factorization. + void Update(const RankOneUpdateElementaryMatrix& update_matrix) { + elementary_matrices_.push_back(update_matrix); + num_entries_ += update_matrix.num_entries(); + } + + // Left-solves all systems from right to left, i.e. y_i = y_{i+1}.(T_i)^{-1} + void LeftSolve(DenseRow* y) const { + RETURN_IF_NULL(y); + for (int i = elementary_matrices_.size() - 1; i >= 0; --i) { + elementary_matrices_[i].LeftSolve(y); + } + } + + // Same as LeftSolve(), but if the given non_zeros are not empty, then all + // the new non-zeros in the result are happended to it. + void LeftSolveWithNonZeros(DenseRow* y, + std::vector* non_zeros) const { + RETURN_IF_NULL(y); + if (non_zeros->empty()) { + LeftSolve(y); + return; + } + + // tmp_row_is_non_zero_ is always all false before and after this code. + tmp_col_is_non_zero_.resize(y->size(), false); + DCHECK(std::all_of(tmp_col_is_non_zero_.begin(), tmp_col_is_non_zero_.end(), + [](bool v) { return !v; })); + for (const ColIndex col : *non_zeros) tmp_col_is_non_zero_[col] = true; + const int hypersparse_threshold = static_cast( + hypersparse_ratio_ * static_cast(y->size().value())); + for (int i = elementary_matrices_.size() - 1; i >= 0; --i) { + if (non_zeros->size() < hypersparse_threshold) { + elementary_matrices_[i].LeftSolveWithNonZeros(y, &tmp_col_is_non_zero_, + non_zeros); + } else { + elementary_matrices_[i].LeftSolve(y); + } + } + for (const ColIndex col : *non_zeros) tmp_col_is_non_zero_[col] = false; + if (non_zeros->size() >= hypersparse_threshold) non_zeros->clear(); + } + + // Right-solves all systems from left to right, i.e. T_i.d_{i+1} = d_i + void RightSolve(DenseColumn* d) const { + RETURN_IF_NULL(d); + const size_t end = elementary_matrices_.size(); + for (int i = 0; i < end; ++i) { + elementary_matrices_[i].RightSolve(d); + } + } + + // Same as RightSolve(), but if the given non_zeros are not empty, then all + // the new non-zeros in the result are happended to it. + void RightSolveWithNonZeros(DenseColumn* d, + std::vector* non_zeros) const { + RETURN_IF_NULL(d); + if (non_zeros->empty()) { + RightSolve(d); + return; + } + + // tmp_row_is_non_zero_ is always all false before and after this code. + tmp_row_is_non_zero_.resize(d->size(), false); + DCHECK(std::all_of(tmp_row_is_non_zero_.begin(), tmp_row_is_non_zero_.end(), + [](bool v) { return !v; })); + for (const RowIndex row : *non_zeros) tmp_row_is_non_zero_[row] = true; + const size_t end = elementary_matrices_.size(); + const int hypersparse_threshold = static_cast( + hypersparse_ratio_ * static_cast(d->size().value())); + for (int i = 0; i < end; ++i) { + if (non_zeros->size() < hypersparse_threshold) { + elementary_matrices_[i].RightSolveWithNonZeros(d, &tmp_row_is_non_zero_, + non_zeros); + } else { + elementary_matrices_[i].RightSolve(d); + } + } + for (const RowIndex row : *non_zeros) tmp_row_is_non_zero_[row] = false; + if (non_zeros->size() >= hypersparse_threshold) non_zeros->clear(); + } + + EntryIndex num_entries() const { return num_entries_; } + + private: + double hypersparse_ratio_; + EntryIndex num_entries_; + std::vector elementary_matrices_; + mutable StrictITIVector tmp_row_is_non_zero_; + mutable StrictITIVector tmp_col_is_non_zero_; + DISALLOW_COPY_AND_ASSIGN(RankOneUpdateFactorization); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_RANK_ONE_UPDATE_H_ diff --git a/thirdparty/linux/include/ortools/glop/reduced_costs.h b/thirdparty/linux/include/ortools/glop/reduced_costs.h new file mode 100644 index 0000000..f36bdc6 --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/reduced_costs.h @@ -0,0 +1,297 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_REDUCED_COSTS_H_ +#define OR_TOOLS_GLOP_REDUCED_COSTS_H_ + +#include "ortools/glop/basis_representation.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/primal_edge_norms.h" +#include "ortools/glop/status.h" +#include "ortools/glop/update_row.h" +#include "ortools/glop/variables_info.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/util/stats.h" +#include "ortools/base/random.h" + +namespace operations_research { +namespace glop { + +// Maintains the reduced costs of the non-basic variables and some related +// quantities. +// +// Terminology: +// - To each non-basic column 'a' of A, we can associate an "edge" in the +// kernel of A equal to 1.0 on the index of 'a' and '-B^{-1}.a' on the basic +// variables. +// - 'B^{-1}.a' is called the "right inverse" of 'a'. +// - The reduced cost of a column is equal to the scalar product of this +// column's edge with the cost vector (objective_), and corresponds to the +// variation in the objective function when we add this edge to the current +// solution. +// - The dual values are the "left inverse" of the basic objective by B. +// That is 'basic_objective_.B^{-1}' +// - The reduced cost of a column is also equal to the scalar product of this +// column with the vector of the dual values. +class ReducedCosts { + public: + // Takes references to the linear program data we need. + ReducedCosts(const CompactSparseMatrix& matrix_, const DenseRow& objective, + const RowToColMapping& basis, + const VariablesInfo& variables_info, + const BasisFactorization& basis_factorization, + RandomBase* random); + + // If this is true, then the caller must re-factorize the basis before the + // next call to GetReducedCosts(). + bool NeedsBasisRefactorization() const; + + // Checks the precision of the entering variable choice now that the direction + // is computed, and return true if we can continue with this entering column, + // or false if this column is actually not good and ChooseEnteringColumn() + // need to be called again. + bool TestEnteringReducedCostPrecision(ColIndex entering_col, + ScatteredColumnReference direction, + Fractional* reduced_cost); + + // Computes the current dual residual and infeasibility. Note that these + // functions are not really fast (many scalar products will be computed) and + // shouldn't be called at each iteration. They will return 0.0 if the reduced + // costs need to be recomputed first and fail in debug mode. + Fractional ComputeMaximumDualResidual() const; + Fractional ComputeMaximumDualInfeasibility() const; + Fractional ComputeSumOfDualInfeasibilities() const; + + // Updates any internal data BEFORE the given simplex pivot is applied to B. + // Note that no updates are needed in case of a bound flip. + // The arguments are in order: + // - The index of the entering non-basic column of A. + // - The index in B of the leaving basic variable. + // - The 'direction', i.e. the right inverse of the entering column. + void UpdateBeforeBasisPivot(ColIndex entering_col, RowIndex leaving_row, + const DenseColumn& direction, + UpdateRow* update_row); + + // Once a pivot has been done, this need to be called on the column that just + // left the basis before the next ChooseEnteringColumn(). On a bound flip, + // this must also be called with the variable that flipped. + // + // In both cases, the variable should be dual-feasible by construction. This + // sets is_dual_infeasible_[col] to false and checks in debug mode that the + // variable is indeed not an entering candidate. + void SetAndDebugCheckThatColumnIsDualFeasible(ColIndex col); + + // Sets the cost of the given non-basic variable to zero and updates its + // reduced cost. Note that changing the cost of a non-basic variable only + // impacts its reduced cost and not the one of any other variables. + // The current_cost pointer must be equal to the address of objective[col] + // where objective is the DenseRow passed at construction. + void SetNonBasicVariableCostToZero(ColIndex col, Fractional* current_cost); + + // Sets the pricing parameters. This does not change the pricing rule. + void SetParameters(const GlopParameters& parameters); + + // Returns true if the current reduced costs are computed with maximum + // precision. + bool AreReducedCostsPrecise() { return are_reduced_costs_precise_; } + + // Returns true if the current reduced costs where just recomputed or will be + // on the next call to GetReducedCosts(). + bool AreReducedCostsRecomputed() { + return recompute_reduced_costs_ || are_reduced_costs_recomputed_; + } + + // Makes sure the next time the reduced cost are needed, they will be + // recomputed with maximum precision (i.e. from scratch with a basis + // refactorization first). + void MakeReducedCostsPrecise(); + + // Randomly perturb the costs. Both Koberstein and Huangfu recommend doing + // that before the dual simplex starts in their Phd thesis. + // + // The perturbation follows what is explained in Huangfu Q (2013) "High + // performance simplex solver", Ph.D, dissertation, University of Edinburgh, + // section 3.2.3, page 58. + void PerturbCosts(); + + // Shifts the cost of the given non-basic column such that its current reduced + // cost becomes 0.0. Actually, this shifts the cost a bit more, so that the + // reduced cost becomes slightly of the other sign. + // + // This is explained in Koberstein's thesis (section 6.2.2.3) and helps on + // degenerate problems. As of july 2013, this allowed to pass dano3mip and + // dbic1 without cycling forever. Note that contrary to what is explained in + // the thesis, we do not shift any other variable costs. If any becomes + // infeasible, it will be selected and shifted in subsequent iterations. + void ShiftCost(ColIndex col); + + // Removes any cost shift and cost perturbation. This also lazily forces a + // recomputation of all the derived quantities. This effectively resets the + // class to its initial state. + void ClearAndRemoveCostShifts(); + + // Invalidates all internal structure that depends on the objective function. + void ResetForNewObjective(); + + // Sets whether or not the bitset of the dual infeasible positions is updated. + void MaintainDualInfeasiblePositions(bool maintain); + + // Invalidates the data that depends on the order of the column in basis_. + void UpdateDataOnBasisPermutation(); + + // Returns the current reduced costs. If AreReducedCostsPrecise() is true, + // then for basic columns, this gives the error between 'c_B' and 'y.B' and + // for non-basic columns, this is the classic reduced cost. If it is false, + // then this is defined only for the columns in + // variables_info_.GetIsRelevantBitRow(). + const DenseRow& GetReducedCosts(); + + // Returns the non-basic columns that are dual-infeasible. These are also + // the primal simplex possible entering columns. + const DenseBitRow& GetDualInfeasiblePositions() const { + // TODO(user): recompute if needed? + DCHECK(are_dual_infeasible_positions_maintained_); + return is_dual_infeasible_; + } + + // Returns the dual values associated to the current basis. + const DenseColumn& GetDualValues(); + + // Stats related functions. + std::string StatString() const { return stats_.StatString(); } + + // Returns the current dual feasibility tolerance. + Fractional GetDualFeasibilityTolerance() const { + return dual_feasibility_tolerance_; + } + + // Does basic checking of an entering candidate. To be used in DCHECK(). + bool IsValidPrimalEnteringCandidate(ColIndex col) const; + + // Visible for testing. + const DenseRow& GetCostPerturbations() const { + return objective_perturbation_; + } + + private: + // Statistics about this class. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("ReducedCosts"), + basic_objective_left_inverse_density( + "basic_objective_left_inverse_density", this), + reduced_costs_accuracy("reduced_costs_accuracy", this), + cost_shift("cost_shift", this) {} + RatioDistribution basic_objective_left_inverse_density; + DoubleDistribution reduced_costs_accuracy; + DoubleDistribution cost_shift; + }; + + // Small utility function to be called before reduced_costs_ and/or + // is_dual_infeasible_ are accessed. + void RecomputeReducedCostsAndPrimalEnteringCandidatesIfNeeded(); + + // All these Compute() functions fill the corresponding DenseRow using + // the current problem data. + void ComputeBasicObjective(); + void ComputeReducedCosts(); + void ComputeBasicObjectiveLeftInverse(); + + // Updates reduced_costs_ according to the given pivot. This adds a multiple + // of the vector equal to 1.0 on the leaving column and given by + // ComputeUpdateRow() on the non-basic columns. The multiple is such that the + // new leaving reduced cost is zero. If update_column_status is false, then + // is_dual_infeasible_ will not be updated. + void UpdateReducedCosts(ColIndex entering_col, ColIndex leaving_col, + RowIndex leaving_row, Fractional pivot, + UpdateRow* update_row); + + // Recomputes from scratch the is_dual_infeasible_ bit row. Note that an + // entering candidate is by definition a dual-infeasible variable. + void ResetDualInfeasibilityBitSet(); + + // Recomputes is_dual_infeasible_ but only for the given column indices. + template + void UpdateEnteringCandidates(const ColumnsToUpdate& cols); + + // Updates basic_objective_ according to the given pivot. + void UpdateBasicObjective(ColIndex entering_col, RowIndex leaving_row); + + // Problem data that should be updated from outside. + const CompactSparseMatrix& matrix_; + const DenseRow& objective_; + const RowToColMapping& basis_; + const VariablesInfo& variables_info_; + const BasisFactorization& basis_factorization_; + RandomBase* random_; + + // Internal data. + GlopParameters parameters_; + mutable Stats stats_; + + // Booleans to control what happens on the next ChooseEnteringColumn() call. + bool must_refactorize_basis_; + bool recompute_basic_objective_left_inverse_; + bool recompute_basic_objective_; + bool recompute_reduced_costs_; + + // Indicates if we have computed the reduced costs with a good precision. + bool are_reduced_costs_precise_; + bool are_reduced_costs_recomputed_; + + // Values of the objective on the columns of the basis. The order is given by + // the basis_ mapping. It is usually denoted as 'c_B' in the literature . + DenseRow basic_objective_; + + // Perturbations to the objective function. This may be introduced to + // counter degenerecency. It will be removed at the end of the algorithm. + // + // TODO(user): rename this cost_perturbations_ to be more consistent with + // the literature. + DenseRow objective_perturbation_; + + // Reduced costs of the relevant columns of A. + DenseRow reduced_costs_; + + // Left inverse by B of the basic_objective_. This is known as 'y' or 'pi' in + // the literature. Its scalar product with a column 'a' of A gives the value + // of the scalar product of the basic objective with the right inverse of 'a'. + // + // TODO(user): using the unit_row_left_inverse_, we can update the + // basic_objective_left_inverse_ at each iteration, this is not needed for the + // algorithm, but may gives us a good idea of the current precision of our + // estimates. It is also faster to compute the unit_row_left_inverse_ because + // of sparsity. + DenseRow basic_objective_left_inverse_; + + // This is usually parameters_.dual_feasibility_tolerance() except when the + // dual residual error |y.B - c_B| is higher than it and we have to increase + // the tolerance. + Fractional dual_feasibility_tolerance_; + + // True for the columns that can enter the basis. + // TODO(user): Investigate using a list of ColIndex instead (but we need + // dynamic update and may lose the ordering of the indices). + DenseBitRow is_dual_infeasible_; + + // Indicates if the dual-infeasible positions are maintained or not. + bool are_dual_infeasible_positions_maintained_; + + DISALLOW_COPY_AND_ASSIGN(ReducedCosts); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_REDUCED_COSTS_H_ diff --git a/thirdparty/linux/include/ortools/glop/revised_simplex.h b/thirdparty/linux/include/ortools/glop/revised_simplex.h new file mode 100644 index 0000000..9d23354 --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/revised_simplex.h @@ -0,0 +1,826 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Solves a Linear Programing problem using the Revised Simplex algorithm +// as described by G.B. Dantzig. +// The general form is: +// min c.x where c and x are n-vectors, +// subject to Ax = b where A is an mxn-matrix, b an m-vector, +// with l <= x <= u, i.e. +// l_i <= x_i <= u_i for all i in {1 .. m}. +// +// c.x is called the objective function. +// Each row a_i of A is an n-vector, and a_i.x = b_i is a linear constraint. +// A is called the constraint matrix. +// b is called the right hand side (rhs) of the problem. +// The constraints l_i <= x_i <= u_i are called the generalized bounds +// of the problem (most introductory textbooks only deal with x_i >= 0, as +// did the first version of the Simplex algorithm). Note that l_i and u_i +// can be -infinity and +infinity, respectively. +// +// To simplify the entry of data, this code actually handles problems in the +// form: +// min c.x where c and x are n-vectors, +// subject to: +// A1 x <= b1 +// A2 x >= b2 +// A3 x = b3 +// l <= x <= u +// +// It transforms the above problem into +// min c.x where c and x are n-vectors, +// subject to: +// A1 x + s1 = b1 +// A2 x - s2 = b2 +// A3 x = b3 +// l <= x <= u +// s1 >= 0, s2 >= 0 +// where xT = (x1, x2, x3), +// s1 is an m1-vector (m1 being the height of A1), +// s2 is an m2-vector (m2 being the height of A2). +// +// See Design Document at +// or search for "Google Linear Programming" in Docs +// +// The following are very good references for terminology, data structures, +// and algorithms. They all contain a wealth of references. +// +// Vasek Chvátal, "Linear Programming," W.H. Freeman, 1983. ISBN 978-0716715870. +// http://www.amazon.com/dp/0716715872 +// +// Robert J. Vanderbei, "Linear Programming: Foundations and Extensions," +// Springer, 2010, ISBN-13: 978-1441944979 +// http://www.amazon.com/dp/1441944974 +// +// Istvan Maros, "Computational Techniques of the Simplex Method.", Springer, +// 2002, ISBN 978-1402073328 +// http://www.amazon.com/dp/1402073321 +// +// =============================================== +// Short description of the dual simplex algorithm. +// +// The dual simplex algorithm uses the same data structure as the primal, but +// progresses towards the optimal solution in a different way: +// * It tries to keep the dual values dual-feasible at all time which means that +// the reduced costs are of the correct sign depending on the bounds of the +// non-basic variables. As a consequence the values of the basic variable are +// out of bound until the optimal is reached. +// * A basic leaving variable is selected first (dual pricing) and then a +// corresponding entering variable is selected. This is done in such a way +// that the dual objective value increases (lower bound on the optimal +// solution). +// * Once the basis pivot is chosen, the variable values and the reduced costs +// are updated the same way as in the primal algorithm. +// +// Good references on the Dual simplex algorithm are: +// +// Robert Fourer, "Notes on the Dual simplex Method", March 14, 1994. +// http://users.iems.northwestern.edu/~4er/WRITINGS/dual.pdf +// +// Achim Koberstein, "The dual simplex method, techniques for a fast and stable +// implementation", PhD, Paderborn, Univ., 2005. +// http://digital.ub.uni-paderborn.de/hs/download/pdf/3885?originalFilename=true + +#ifndef OR_TOOLS_GLOP_REVISED_SIMPLEX_H_ +#define OR_TOOLS_GLOP_REVISED_SIMPLEX_H_ + +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/macros.h" +#include "ortools/glop/basis_representation.h" +#include "ortools/glop/dual_edge_norms.h" +#include "ortools/glop/entering_variable.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/primal_edge_norms.h" +#include "ortools/glop/reduced_costs.h" +#include "ortools/glop/status.h" +#include "ortools/glop/update_row.h" +#include "ortools/glop/variable_values.h" +#include "ortools/glop/variables_info.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/lp_data/lp_print_utils.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/lp_data/matrix_scaler.h" +#include "ortools/lp_data/sparse_row.h" +#include "ortools/base/random.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { +namespace glop { + +// Holds the statuses of all the variables, including slack variables. There +// is no point storing constraint statuses since internally all constraints are +// always fixed to zero. +// +// Note that this is the minimal amount of information needed to perform a "warm +// start". Using this information and the original linear program, the basis can +// be refactorized and all the needed quantities derived. +// +// TODO(user): Introduce another state class to store a complete state of the +// solver. Using this state and the original linear program, the solver can be +// restarted with as little time overhead as possible. This is especially useful +// for strong branching in a MIP context. +struct BasisState { + // TODO(user): A MIP solver will potentially store a lot of BasicStates so + // memory usage is important. It is possible to use only 2 bits for one + // VariableStatus enum. To achieve this, the FIXED_VALUE status can be + // converted to either AT_LOWER_BOUND or AT_UPPER_BOUND and decoded properly + // later since this will be used with a given linear program. This way we can + // even encode more information by using the reduced cost sign to choose to + // which bound the fixed status correspond. + VariableStatusRow statuses; + + // Returns true if this state is empty. + bool IsEmpty() const { return statuses.empty(); } +}; + +// Entry point of the revised simplex algorithm implementation. +class RevisedSimplex { + public: + RevisedSimplex(); + + // Sets or gets the algorithm parameters to be used on the next Solve(). + void SetParameters(const GlopParameters& parameters); + const GlopParameters& GetParameters() const { return parameters_; } + + // Solves the given linear program. + // + // Expects that the linear program is in the equations form Ax = 0 created by + // LinearProgram::AddSlackVariablesForAllRows, i.e. the rightmost square + // submatrix of A is an identity matrix, all its columns have been marked as + // slack variables, and the bounds of all constraints have been set to [0, 0]. + // Returns ERROR_INVALID_PROBLEM, if these assumptions are violated. + // + // By default, the algorithm tries to exploit the computation done during the + // last Solve() call. It will analyze the difference of the new linear program + // and try to use the previously computed solution as a warm-start. To disable + // this behavior or give explicit warm-start data, use one of the State*() + // functions below. + Status Solve(const LinearProgram& linear_program, + TimeLimit* time_limit) MUST_USE_RESULT; + + // Do not use the current solution as a warm-start for the next Solve(). The + // next Solve() will behave as if the class just got created. + void ClearStateForNextSolve(); + + // Uses the given state as a warm-start for the next Solve() call. + void LoadStateForNextSolve(const BasisState& state); + + // Getters to retrieve all the information computed by the last Solve(). + RowIndex GetProblemNumRows() const; + ColIndex GetProblemNumCols() const; + ProblemStatus GetProblemStatus() const; + Fractional GetObjectiveValue() const; + int64 GetNumberOfIterations() const; + Fractional GetVariableValue(ColIndex col) const; + Fractional GetReducedCost(ColIndex col) const; + Fractional GetDualValue(RowIndex row) const; + Fractional GetConstraintActivity(RowIndex row) const; + VariableStatus GetVariableStatus(ColIndex col) const; + ConstraintStatus GetConstraintStatus(RowIndex row) const; + const BasisState& GetState() const; + double DeterministicTime() const; + bool objective_limit_reached() const { return objective_limit_reached_; } + + // If the problem status is PRIMAL_UNBOUNDED (respectively DUAL_UNBOUNDED), + // then the solver has a corresponding primal (respectively dual) ray to show + // the unboundness. From a primal (respectively dual) feasible solution any + // positive multiple of this ray can be added to the solution and keep it + // feasible. Moreover, by doing so, the objective of the problem will improve + // and its magnitude will go to infinity. + // + // Note that when the problem is DUAL_UNBOUNDED, the dual ray is also known as + // the Farkas proof of infeasibility of the problem. + const DenseRow& GetPrimalRay() const; + const DenseColumn& GetDualRay() const; + + // This is the "dual ray" linear combination of the matrix rows. + const DenseRow& GetDualRayRowCombination() const; + + // Returns the index of the column in the basis and the basis factorization. + // Note that the order of the column in the basis is important since it is the + // one used by the various solve functions provided by the BasisFactorization + // class. + ColIndex GetBasis(RowIndex row) const; + + // Returns a copy of basis_ vector for outside applications (like cuts) to + // have the correspondence between rows and columns of the dictionary. + RowToColMapping GetBasisVector() const { return basis_; } + + const BasisFactorization& GetBasisFactorization() const; + + // Returns statistics about this class as a std::string. + std::string StatString(); + + // Computes the dictionary B^-1*N on-the-fly row by row. Returns the resulting + // matrix as a vector of sparse rows so that it is easy to use it on the left + // side in the matrix multiplication. Runs in O(num_non_zeros_in_matrix). + RowMajorSparseMatrix ComputeDictionary(); + + private: + // Propagates parameters_ to all the other classes that need it. + // + // TODO(user): Maybe a better design is for them to have a reference to a + // unique parameters object? it will clutter a bit more these classes + // contructor though. + void PropagateParameters(); + + // Returns a std::string containing the same information as with GetSolverStats, + // but in a much more human-readable format. For example: + // Problem status : Optimal + // Solving time : 1.843 + // Number of iterations : 12345 + // Time for solvability (first phase) : 1.343 + // Number of iterations for solvability : 10000 + // Time for optimization : 0.5 + // Number of iterations for optimization : 2345 + // Maximum time allowed in seconds : 6000 + // Maximum number of iterations : 1000000 + // Stop after first basis : 0 + std::string GetPrettySolverStats() const; + + // Returns a std::string containing formatted information about the variable + // corresponding to column col. + std::string SimpleVariableInfo(ColIndex col) const; + + // Displays a short std::string with the current iteration and objective value. + void DisplayIterationInfo() const; + + // Displays the error bounds of the current solution. + void DisplayErrors() const; + + // Displays the status of the variables. + void DisplayInfoOnVariables() const; + + // Displays the bounds of the variables. + void DisplayVariableBounds(); + + // Displays the following information: + // * Linear Programming problem as a dictionary, taking into + // account the iterations that have been made; + // * Variable info; + // * Reduced costs; + // * Variable bounds. + // A dictionary is in the form: + // xB = value + sum_{j in N} pa_ij x_j + // z = objective_value + sum_{i in N} rc_i x_i + // where the pa's are the coefficients of the matrix after the pivotings + // and the rc's are the reduced costs, i.e. the coefficients of the objective + // after the pivotings. + // Dictionaries are the modern way of presenting the result of an iteration + // of the Simplex algorithm in the literature. + void DisplayRevisedSimplexDebugInfo(); + + // Displays the Linear Programming problem as it was input. + void DisplayProblem() const; + + // Returns the current objective value. This is just the sum of the current + // variable values times their current cost. + Fractional ComputeObjectiveValue() const; + + // Returns the current objective of the linear program given to Solve() using + // the initial costs, maximization direction, objective offset and objective + // scaling factor. + Fractional ComputeInitialProblemObjectiveValue() const; + + // Assigns names to variables. Variables in the input will be named + // x1..., slack variables will be s1... . + void SetVariableNames(); + + // Computes the initial variable status from its type. A constrained variable + // is set to the lowest of its 2 bounds in absolute value. + VariableStatus ComputeDefaultVariableStatus(ColIndex col) const; + + // Sets the variable status and derives the variable value according to the + // exact status definition. This can only be called for non-basic variables + // because the value of a basic variable is computed from the values of the + // non-basic variables. + void SetNonBasicVariableStatusAndDeriveValue(ColIndex col, + VariableStatus status); + + // Checks if the basis_ and is_basic_ arrays are well formed. Also checks that + // the variable statuses are consistent with this basis. Returns true if this + // is the case. This is meant to be used in debug mode only. + bool BasisIsConsistent() const; + + // Moves the column entering_col into the basis at position basis_row. Removes + // the current basis column at position basis_row from the basis and sets its + // status to leaving_variable_status. + void UpdateBasis(ColIndex entering_col, RowIndex basis_row, + VariableStatus leaving_variable_status); + + // Initializes matrix-related internal data. Returns true if this data was + // unchanged. If not, also sets only_change_is_new_rows to true if compared + // to the current matrix, the only difference is that new rows have been + // added (with their corresponding extra slack variables). Similarly, sets + // only_change_is_new_cols to true if the only difference is that new columns + // have been added, in which case also sets num_new_cols to the number of + // new columns. + bool InitializeMatrixAndTestIfUnchanged(const LinearProgram& lp, + bool* only_change_is_new_rows, + bool* only_change_is_new_cols, + ColIndex* num_new_cols); + + // Initializes bound-related internal data. Returns true if unchanged. + bool InitializeBoundsAndTestIfUnchanged(const LinearProgram& lp); + + // Checks if the only change to the bounds is the addition of new columns, + // and that the new columns have at least one bound equal to zero. + bool OldBoundsAreUnchangedAndNewVariablesHaveOneBoundAtZero( + const LinearProgram& lp, ColIndex num_new_cols); + + // Initializes objective-related internal data. Returns true if unchanged. + bool InitializeObjectiveAndTestIfUnchanged(const LinearProgram& lp); + + // Computes the stopping criterion on the problem objective value. + void InitializeObjectiveLimit(const LinearProgram& lp); + + // Initializes the variable statuses using a warm-start basis. + void InitializeVariableStatusesForWarmStart(const BasisState& state, + ColIndex num_new_cols); + + // Initializes the starting basis. In most cases it starts by the all slack + // basis and tries to apply some heuristics to replace fixed variables. + Status CreateInitialBasis() MUST_USE_RESULT; + + // Sets the initial basis to the given columns, try to factorize it and + // recompute the basic variable values. + Status InitializeFirstBasis(const RowToColMapping& initial_basis) + MUST_USE_RESULT; + + // Entry point for the solver initialization. + Status Initialize(const LinearProgram& lp) MUST_USE_RESULT; + + // Saves the current variable statuses in solution_state_. + void SaveState(); + + // Displays statistics on what kinds of variables are in the current basis. + void DisplayBasicVariableStatistics(); + + // Tries to reduce the initial infeasibility (stored in error_) by using the + // singleton columns present in the problem. A singleton column is a column + // with only one non-zero. This is used by CreateInitialBasis(). + void UseSingletonColumnInInitialBasis(RowToColMapping* basis); + + // Returns the number of empty rows in the matrix, i.e. rows where all + // the coefficients are zero. + RowIndex ComputeNumberOfEmptyRows(); + + // Returns the number of empty columns in the matrix, i.e. columns where all + // the coefficients are zero. + ColIndex ComputeNumberOfEmptyColumns(); + + // This method transforms a basis for the first phase, with the optimal + // value at zero, into a feasible basis for the initial problem, thus + // preparing the execution of phase-II of the algorithm. + void CleanUpBasis(); + + // If the primal maximum residual is too large, recomputes the basic variable + // value from the non-basic ones. This function also perturbs the bounds + // during the primal simplex if too many iterations are degenerate. + // + // Only call this on a refactorized basis to have the best precision. + void CorrectErrorsOnVariableValues(); + + // Computes b - A.x in error_ + void ComputeVariableValuesError(); + + // Solves the system B.d = a where a is the entering column (given by col). + // Known as FTRAN (Forward transformation) in FORTRAN codes. + // See Chvatal's book for more detail (Chapter 7). + void ComputeDirection(ColIndex col); + + // Computes a - B.d in error_ and return the maximum std::abs() of its coeffs. + // TODO(user): Use this to trigger a refactorization of B? Or to track the + // error created by calls to SkipVariableForRatioTest()? + Fractional ComputeDirectionError(ColIndex col); + + // Marks the corresponding basic variable so that it will not take part in the + // ratio test and will never be chosen as a leaving variable. This is used + // to avoid degenerate pivots. + void SkipVariableForRatioTest(RowIndex row); + + // Computes the ratio of the basic variable corresponding to 'row'. A target + // bound (upper or lower) is choosen depending on the sign of the entering + // reduced cost and the sign of the direction 'd_[row]'. The ratio is such + // that adding 'ratio * d_[row]' to the variable value changes it to its + // target bound. + template + Fractional GetRatio(RowIndex row) const; + + // First pass of the Harris ratio test. Returns the harris ratio value which + // is an upper bound on the ratio value that the leaving variable can take. + // Fills leaving_candidates with the ratio and row index of a super-set of the + // columns with a ratio <= harris_ratio. + template + Fractional ComputeHarrisRatioAndLeavingCandidates( + Fractional bound_flip_ratio, SparseColumn* leaving_candidates) const; + + // Chooses the leaving variable, considering the entering column and its + // associated reduced cost. If there was a precision issue and the basis is + // not refactorized, set refactorize to true. Otherwise, the row number of the + // leaving variable is written in *leaving_row, and the step length + // is written in *step_length. + Status ChooseLeavingVariableRow(ColIndex entering_col, + Fractional reduced_cost, bool* refactorize, + RowIndex* leaving_row, + Fractional* step_length, + Fractional* target_bound); + + // Updates the primal phase-I costs of the given basic variables. Such + // variable has a cost of +1/-1 if it is primal-infeasible and of 0 otherwise. + template + void UpdatePrimalPhaseICosts(const Rows& rows); + + // Chooses the leaving variable for the primal phase-I algorithm. The + // algorithm follows more or less what is described in Istvan Maros's book in + // chapter 9.6 and what is done for the dual phase-I algorithm which was + // derived from Koberstein's PhD. Both references can be found at the top of + // this file. + void PrimalPhaseIChooseLeavingVariableRow(ColIndex entering_col, + Fractional reduced_cost, + bool* refactorize, + RowIndex* leaving_row, + Fractional* step_length, + Fractional* target_bound) const; + + // Chooses an infeasible basic variable. The returned values are: + // - leaving_row: the basic index of the infeasible leaving variable + // or kNoLeavingVariable if no such row exists: the dual simplex algorithm + // has terminated and the optimal has been reached. + // - cost_variation: how much do we improve the objective by moving one unit + // along this dual edge. + // - target_bound: the bound at which the leaving variable should go when + // leaving the basis. + Status DualChooseLeavingVariableRow(RowIndex* leaving_row, + Fractional* cost_variation, + Fractional* target_bound) MUST_USE_RESULT; + + // Updates the prices used by DualChooseLeavingVariableRow() after a simplex + // iteration by using direction_. The prices are stored in + // dual_pricing_vector_. Note that this function only takes care of the + // entering and leaving column dual feasibility status change and that other + // changes will be dealt with by DualPhaseIUpdatePriceOnReducedCostsChange(). + void DualPhaseIUpdatePrice(RowIndex leaving_row, ColIndex entering_col); + + // Updates the prices used by DualChooseLeavingVariableRow() when the reduced + // costs of the given columns have changed. + template + void DualPhaseIUpdatePriceOnReducedCostChange(const Cols& cols); + + // Same as DualChooseLeavingVariableRow() but for the phase I of the dual + // simplex. Here the objective is not to minimize the primal infeasibility, + // but the dual one, so the variable is not chosen in the same way. See + // "Notes on the Dual simplex Method" or Istvan Maros, "A Piecewise Linear + // Dual Phase-1 Algorithm for the Simplex Method", Computational Optimization + // and Applications, October 2003, Volume 26, Issue 1, pp 63-81. + // http://rd.springer.com/article/10.1023%2FA%3A1025102305440 + Status DualPhaseIChooseLeavingVariableRow( + RowIndex* leaving_row, Fractional* cost_variation, + Fractional* target_bound) MUST_USE_RESULT; + + // Makes sure the boxed variable are dual-feasible by setting them to the + // correct bound according to their reduced costs. This is called + // Dual feasibility correction in the literature. + // + // Note that this function is also used as a part of the bound flipping ratio + // test by flipping the boxed dual-infeasible variables at each iteration. + // + // If update_basic_values is true, the basic variable values are updated. + template + void MakeBoxedVariableDualFeasible(const BoxedVariableCols& cols, + bool update_basic_values); + + // Computes the step needed to move the leaving_row basic variable to the + // given target bound. + Fractional ComputeStepToMoveBasicVariableToBound(RowIndex leaving_row, + Fractional target_bound); + + // Returns true if the basis obtained after the given pivot can be factorized. + bool TestPivot(ColIndex entering_col, RowIndex leaving_row); + + // Gets the current LU column permutation from basis_representation, + // applies it to basis_ and then sets it to the identity permutation since + // it will no longer be needed during solves. This function also updates all + // the data that depends on the column order in basis_. + void PermuteBasis(); + + // Updates the system state according to the given basis pivot. + // Returns an error if the update could not be done because of some precision + // issue. + Status UpdateAndPivot(ColIndex entering_col, RowIndex leaving_row, + Fractional target_bound) MUST_USE_RESULT; + + // Displays all the timing stats related to the calling object. + void DisplayAllStats(); + + // Returns whether or not a basis refactorization is needed at the beginning + // of the main loop in Minimize() or DualMinimize(). The idea is that if a + // refactorization is going to be needed by one of the components, it is + // better to do that as soon as possible so that every component can take + // advantage of it. + bool NeedsBasisRefactorization(bool refactorize); + + // Calls basis_factorization_.Refactorize() depending on the result of + // NeedsBasisRefactorization(). Invalidates any data structure that depends + // on the current factorization. Sets refactorize to false. + Status RefactorizeBasisIfNeeded(bool* refactorize); + + // Minimize the objective function, be it for satisfiability or for + // optimization. Used by Solve(). + Status Minimize(TimeLimit* time_limit) MUST_USE_RESULT; + + // Same as Minimize() for the dual simplex algorithm. + // TODO(user): remove duplicate code between the two functions. + Status DualMinimize(TimeLimit* time_limit) MUST_USE_RESULT; + + // Utility functions to return the current ColIndex of the slack column with + // given number. Note that currently, such columns are always present in the + // internal representation of a linear program. + ColIndex SlackColIndex(RowIndex row) const; + + // Advances the deterministic time in time_limit with the difference between + // the current internal deterministic time and the internal deterministic time + // during the last call to this method. + // TODO(user): Update the internals of revised simplex so that the time + // limit is updated at the source and remove this method. + void AdvanceDeterministicTime(TimeLimit* time_limit); + + // Problem status + ProblemStatus problem_status_; + + // Current number of rows in the problem. + RowIndex num_rows_; + + // Current number of columns in the problem. + ColIndex num_cols_; + + // Index of the first slack variable in the input problem. We assume that all + // variables with index greater or equal to first_slack_col_ are slack + // variables. + ColIndex first_slack_col_; + + // We're using vectors after profiling and looking at the generated assembly + // it's as fast as std::unique_ptr as long as the size is properly reserved + // beforehand. + + // Temporary view of the matrix given to Solve(). Note that it is an error + // to access this view once Solve() is finished since there is no guarantee + // that the stored pointers are still valid. + // TODO(user): The matrix view is identical to the matrix of the linear + // program after pre-processing. Investigate if we could get rid of it and use + // compact_matrix_ in all places. + MatrixView matrix_with_slack_; + + // The compact version of matrix_with_slack_. + CompactSparseMatrix compact_matrix_; + + // The tranpose of compact_matrix_, it may be empty if it is not needed. + CompactSparseMatrix transposed_matrix_; + + // Stop the algorithm and report feasibility if: + // - The primal simplex is used, the problem is primal-feasible and the + // current objective value is strictly lower than primal_objective_limit_. + // - The dual simplex is used, the problem is dual-feasible and the current + // objective value is strictly greater than dual_objective_limit_. + Fractional primal_objective_limit_; + Fractional dual_objective_limit_; + + // Current objective (feasibility for Phase-I, user-provided for Phase-II). + DenseRow current_objective_; + + // Array of coefficients for the user-defined objective. + // Indexed by column number. Used in Phase-II. + DenseRow objective_; + + // Objective offset and scaling factor of the linear program given to Solve(). + // This is used to display the correct objective values in the logs with + // ComputeInitialProblemObjectiveValue(). + Fractional objective_offset_; + Fractional objective_scaling_factor_; + + // Array of values representing variable bounds. Indexed by column number. + DenseRow lower_bound_; + DenseRow upper_bound_; + + // The bound perturbation to be used for basic variable that are slightly + // outside their bounds. This contains small values that are non-zero only if + // the primal simplex ran into many degenerate iterations. + DenseRow bound_perturbation_; + + // Used in dual phase I to keep track of the non-basic dual infeasible + // columns and their sign of infeasibility (+1 or -1). + DenseRow dual_infeasibility_improvement_direction_; + int num_dual_infeasible_positions_; + + // Used in dual phase I to hold the price of each possible leaving choices + // and the bitset of the possible leaving candidates. + DenseColumn dual_pricing_vector_; + DenseBitColumn is_dual_entering_candidate_; + + // A temporary dense column that is always reset to all zero after use. + DenseColumn initially_all_zero_scratchpad_; + + // A temporary RowIndexVector used to hold the non-zero positions of a column. + RowIndexVector row_index_vector_scratchpad_; + + // Array of column index, giving the column number corresponding + // to a given basis row. + RowToColMapping basis_; + + // Vector of strings containing the names of variables. + // Indexed by column number. + StrictITIVector variable_name_; + + // Information about the solution computed by the last Solve(). + Fractional solution_objective_value_; + DenseColumn solution_dual_values_; + DenseRow solution_reduced_costs_; + DenseRow solution_primal_ray_; + DenseColumn solution_dual_ray_; + DenseRow solution_dual_ray_row_combination_; + BasisState solution_state_; + bool solution_state_has_been_set_externally_; + + // This is known as 'd' in the literature and is set during each pivot to the + // right inverse of the basic entering column of A by ComputeDirection(). + // ComputeDirection() also fills direction_non_zero_ with the position of the + // non-zero. + DenseColumn direction_; + std::vector direction_non_zero_; + Fractional direction_infinity_norm_; + + // Subpart of direction_ that was ignored during the ratio test. This is only + // used for degenerate problem. See SkipVariableForRatioTest() for more + // details. + SparseColumn direction_ignored_position_; + + // Used to compute the error 'b - A.x' or 'a - B.d'. + DenseColumn error_; + + // Representation of matrix B using eta matrices and LU decomposition. + BasisFactorization basis_factorization_; + + // Classes responsible for maintaining the data of the corresponding names. + VariablesInfo variables_info_; + VariableValues variable_values_; + DualEdgeNorms dual_edge_norms_; + PrimalEdgeNorms primal_edge_norms_; + UpdateRow update_row_; + ReducedCosts reduced_costs_; + + // Class holding the algorithms to choose the entering column during a simplex + // pivot. + EnteringVariable entering_variable_; + + // Total number of iterations performed. + uint64 num_iterations_; + + // Number of iterations performed during the first (feasibility) phase. + uint64 num_feasibility_iterations_; + + // Number of iterations performed during the second (optimization) phase. + uint64 num_optimization_iterations_; + + // Total time spent in Solve(). + double total_time_; + + // Time spent in the first (feasibility) phase. + double feasibility_time_; + + // Time spent in the second (optimization) phase. + double optimization_time_; + + // The internal deterministic time during the most recent call to + // RevisedSimplex::AdvanceDeterministicTime. + double last_deterministic_time_update_; + + // Statistics about the iterations done by Minimize(). + struct IterationStats : public StatsGroup { + IterationStats() + : StatsGroup("IterationStats"), + total("total", this), + normal("normal", this), + bound_flip("bound_flip", this), + degenerate("degenerate", this), + degenerate_run_size("degenerate_run_size", this) {} + TimeDistribution total; + TimeDistribution normal; + TimeDistribution bound_flip; + TimeDistribution degenerate; + IntegerDistribution degenerate_run_size; + }; + IterationStats iteration_stats_; + + struct RatioTestStats : public StatsGroup { + RatioTestStats() + : StatsGroup("RatioTestStats"), + bound_shift("bound_shift", this), + abs_used_pivot("abs_used_pivot", this), + abs_tested_pivot("abs_tested_pivot", this), + abs_skipped_pivot("abs_skipped_pivot", this), + direction_density("direction_density", this), + leaving_choices("leaving_choices", this), + num_perfect_ties("num_perfect_ties", this) {} + DoubleDistribution bound_shift; + DoubleDistribution abs_used_pivot; + DoubleDistribution abs_tested_pivot; + DoubleDistribution abs_skipped_pivot; + RatioDistribution direction_density; + IntegerDistribution leaving_choices; + IntegerDistribution num_perfect_ties; + }; + mutable RatioTestStats ratio_test_stats_; + + // Placeholder for all the function timing stats. + // Mutable because we time const functions like ChooseLeavingVariableRow(). + mutable StatsGroup function_stats_; + + // Proto holding all the parameters of this algorithm. + // + // Note that parameters_ may actually change during a solve as the solver may + // dynamically adapt some values. It is why we store the argument of the last + // SetParameters() call in initial_parameters_ so the next Solve() can reset + // it correctly. + GlopParameters parameters_; + GlopParameters initial_parameters_; + + // LuFactorization used to test if a pivot will cause the new basis to + // not be factorizable. + LuFactorization test_lu_; + + // Number of degenerate iterations made just before the current iteration. + int num_consecutive_degenerate_iterations_; + + // Indicate if we are in the feasibility_phase (1st phase) or not. + bool feasibility_phase_; + + // Indicates whether simplex ended due to the objective limit being reached. + // Note that it's not enough to compare the final objective value with the + // limit due to numerical issues (i.e., the limit which is reached within + // given tolerance on the internal objective may no longer be reached when the + // objective scaling and offset are taken into account). + bool objective_limit_reached_; + + // Temporary SparseColumn used by ChooseLeavingVariableRow(). + SparseColumn leaving_candidates_; + + // Temporary vector used to hold the best leaving column candidates that are + // tied using the current choosing criteria. We actually only store the tied + // candidate #2, #3, ...; because the first tied candidate is remembered + // anyway. + std::vector equivalent_leaving_choices_; + + // A random number generator. + MTRandom random_; + + DISALLOW_COPY_AND_ASSIGN(RevisedSimplex); +}; + +// Hides the details of the dictionary matrix implementation. In the future, +// GLOP will support generating the dictionary one row at a time without having +// to store the whole matrix in memory. +class RevisedSimplexDictionary { + public: + typedef RowMajorSparseMatrix::const_iterator ConstIterator; + + // RevisedSimplex cannot be passed const because we have to call a non-const + // method ComputeDictionary. + explicit RevisedSimplexDictionary(RevisedSimplex* revised_simplex) + : dictionary_(CHECK_NOTNULL(revised_simplex)->ComputeDictionary()), + basis_vars_(CHECK_NOTNULL(revised_simplex)->GetBasisVector()) {} + + ConstIterator begin() const { return dictionary_.begin(); } + ConstIterator end() const { return dictionary_.end(); } + + size_t size() const { return dictionary_.size(); } + + // TODO(user): this function is a better fit for the future custom iterator. + ColIndex GetVariableIndex(RowIndex r) const { return basis_vars_[r]; } + + private: + const RowMajorSparseMatrix dictionary_; + const RowToColMapping basis_vars_; + DISALLOW_COPY_AND_ASSIGN(RevisedSimplexDictionary); +}; + +// TODO(user): When a row-by-row generation of the dictionary is supported, +// implement DictionaryIterator class that would call it inside operator*(). + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_REVISED_SIMPLEX_H_ diff --git a/thirdparty/linux/include/ortools/glop/status.h b/thirdparty/linux/include/ortools/glop/status.h new file mode 100644 index 0000000..b4802bd --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/status.h @@ -0,0 +1,97 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_STATUS_H_ +#define OR_TOOLS_GLOP_STATUS_H_ + +#include +#include "ortools/base/port.h" + +namespace operations_research { +namespace glop { + +// Return type for the solver functions that return "Did that work?". +// It should only be used for unrecoverable errors. +class Status { + public: + // Possible kinds of errors. + enum ErrorCode { + // Not an error. Returned on success. + NO_ERROR = 0, + + // The LU factorization of the current basis couldn't be computed. + ERROR_LU = 1, + + // The current variable values are out of their bound modulo the tolerance. + ERROR_BOUND = 2, + + // A pointer argument was NULL when it shouldn't be. + ERROR_NULL = 3, + + // The linear program is invalid or it does not have the required format. + ERROR_INVALID_PROBLEM = 4, + + }; + + // Creates a "successful" status. + Status(); + + // Creates a status with the specified error code and error message. + // If "code == 0", error_message is ignored and a Status object identical + // to Status::OK is constructed. + Status(ErrorCode error_code, std::string error_message); + + // Improves readability but identical to 0-arg constructor. + static const Status OK; + + // Accessors. + ErrorCode error_code() const { return error_code_; } + const std::string& error_message() const { return error_message_; } + bool ok() const { return error_code_ == NO_ERROR; } + + private: + ErrorCode error_code_; + std::string error_message_; +}; + +// Returns the std::string representation of the ErrorCode enum. +std::string GetErrorCodeString(Status::ErrorCode error_code); + +// Macro to simplify error propagation between function returning Status. +#define GLOP_RETURN_IF_ERROR(function_call) \ + do { \ + const Status return_status = function_call; \ + if (!return_status.ok()) return return_status; \ + } while (false) + +// Macro to simplify the creation of an error. +#define GLOP_RETURN_AND_LOG_ERROR(error_code, message) \ + do { \ + const std::string error_message = message; \ + LOG(ERROR) << GetErrorCodeString(error_code) << ": " << error_message; \ + return Status(error_code, error_message); \ + } while (false) + +// Macro to check that a pointer argument is not null. +#define GLOP_RETURN_ERROR_IF_NULL(arg) \ + if (arg == nullptr) { \ + const std::string variable_name = #arg; \ + const std::string error_message = variable_name + " must not be null."; \ + LOG(DFATAL) << error_message; \ + return Status(Status::ERROR_NULL, error_message); \ + } + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_STATUS_H_ diff --git a/thirdparty/linux/include/ortools/glop/update_row.h b/thirdparty/linux/include/ortools/glop/update_row.h new file mode 100644 index 0000000..d124e2b --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/update_row.h @@ -0,0 +1,155 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_UPDATE_ROW_H_ +#define OR_TOOLS_GLOP_UPDATE_ROW_H_ + +#include "ortools/glop/basis_representation.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/glop/variables_info.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace glop { + +// During a simplex iteration, when the basis 'leaving_row' has been +// selected, one of the main quantities needed in the primal or dual simplex +// algorithm is called the update row. +// +// By definition, update_row[col] is the coefficient at position +// 'leaving_row' in the current basis of the column 'col' of the matrix A. +// +// One efficient way to compute it is to compute the left inverse by B of the +// unit vector with a one at the given leaving_row, and then to take the +// scalar product of this left inverse with all the columns of A: +// update_row[col] = (unit_{leaving_row} . B^{-1}) . A_col +class UpdateRow { + public: + // Takes references to the linear program data we need. + UpdateRow(const CompactSparseMatrix& matrix, + const CompactSparseMatrix& transposed_matrix, + const VariablesInfo& variables_info, const RowToColMapping& basis, + const BasisFactorization& basis_factorization); + + // Invalidates the current update row and unit_row_left_inverse so the next + // call to ComputeUpdateRow() will recompute everything and not just return + // right away. + void Invalidate(); + + // Computes the relevant coefficients (See GetIsRelevantBitRow() in + // VariablesInfo) of the update row. The result is only computed once until + // the next Invalidate() call and calling this function more than once will + // have no effect until then. + void ComputeUpdateRow(RowIndex leaving_row); + + // Returns the left inverse of the unit row as computed by the last call to + // ComputeUpdateRow(). In debug mode, we check that ComputeUpdateRow() was + // called since the last Invalidate(). + ScatteredColumnReference GetUnitRowLeftInverse() const; + + // Returns the update coefficients and non-zero positions corresponding to the + // last call to ComputeUpdateRow(). + const DenseRow& GetCoefficients() const; + const ColIndexVector& GetNonZeroPositions() const; + const Fractional GetCoefficient(ColIndex col) const { + return coefficient_[col]; + } + + // This must be called after a call to ComputeUpdateRow(). It will fill + // all the non-relevant positions that where not filled by ComputeUpdateRow(). + void RecomputeFullUpdateRow(RowIndex leaving_row); + + // Sets to zero the coefficient for column col. + void IgnoreUpdatePosition(ColIndex col); + + // Sets the algorithm parameters. + void SetParameters(const GlopParameters& parameters); + + // Returns statistics about this class as a std::string. + std::string StatString() const { return stats_.StatString(); } + + // Only used for testing. + // Computes as the update row the product 'lhs' times the linear program + // matrix given at construction. Only the relevant columns matter (see + // VariablesInfo) and 'algorithm' can be one of "column", "row" or + // "row_hypersparse". + void ComputeUpdateRowForBenchmark(const DenseRow& lhs, + const std::string& algorithm); + + // Deterministic time used by the scalar product computation of this class. + double DeterministicTime() const { + return DeterministicTimeForFpOperations(num_operations_); + } + + private: + // Computes the left inverse of the given unit row, and stores it in + // unit_row_left_inverse_ and unit_row_left_inverse_non_zeros_. + void ComputeUnitRowLeftInverse(RowIndex leaving_row); + + // ComputeUpdateRow() does the common work and call one of these functions + // depending on the situation. + void ComputeUpdatesRowWise(); + void ComputeUpdatesRowWiseHypersparse(); + void ComputeUpdatesColumnWise(); + + // Problem data that should be updated from outside. + const CompactSparseMatrix& matrix_; + const CompactSparseMatrix& transposed_matrix_; + const VariablesInfo& variables_info_; + const RowToColMapping& basis_; + const BasisFactorization& basis_factorization_; + + // Left inverse by B of a unit row. Its scalar product with a column 'a' of A + // gives the value of the right inverse of 'a' on the 'leaving_row'. + DenseRow unit_row_left_inverse_; + ColIndexVector unit_row_left_inverse_non_zeros_; + + // Holds the current update row data. + // TODO(user): Introduce a ScatteredSparseRow class? + ColIndexVector non_zero_position_list_; + DenseBitRow non_zero_position_set_; + DenseRow coefficient_; + + // Boolean used to avoid recomputing many times the same thing. + bool compute_unit_row_left_inverse_; + bool compute_update_row_; + + // Statistics about this class. + struct Stats : public StatsGroup { + Stats() + : StatsGroup("UpdateRow"), + unit_row_left_inverse_density("unit_row_left_inverse_density", this), + unit_row_left_inverse_accuracy("unit_row_left_inverse_accuracy", + this), + update_row_density("update_row_density", this) {} + RatioDistribution unit_row_left_inverse_density; + DoubleDistribution unit_row_left_inverse_accuracy; + RatioDistribution update_row_density; + }; + + // Track the number of basic floating point multiplication. + // Used by DeterministicTime(). + int64 num_operations_; + + // Glop standard classes. + GlopParameters parameters_; + Stats stats_; + + DISALLOW_COPY_AND_ASSIGN(UpdateRow); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_UPDATE_ROW_H_ diff --git a/thirdparty/linux/include/ortools/glop/variable_values.h b/thirdparty/linux/include/ortools/glop/variable_values.h new file mode 100644 index 0000000..c9e061b --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/variable_values.h @@ -0,0 +1,140 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_VARIABLE_VALUES_H_ +#define OR_TOOLS_GLOP_VARIABLE_VALUES_H_ + +#include "ortools/glop/basis_representation.h" +#include "ortools/glop/variables_info.h" +#include "ortools/lp_data/lp_types.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace glop { + +// Class holding all the variable values and responsible for updating them. The +// variable values 'x' are such that 'A.x = 0' where A is the linear program +// matrix. This is because slack variables with bounds corresponding to the +// constraints bounds were added to the linear program matrix A. +// +// Some remarks: +// - For convenience, the variable values are stored in a DenseRow and indexed +// by ColIndex, like the variables and the columns of A. +// - During the dual-simplex, all non-basic variable values are at their exact +// bounds or exactly at 0.0 for a free variable. +// - During the primal-simplex, the non-basic variable values may not be exactly +// at their bounds because of bound-shifting during degenerate simplex +// pivoting which is implemented by not setting the variable values exactly at +// their bounds to have a lower primal residual error. +class VariableValues { + public: + VariableValues(const CompactSparseMatrix& matrix, + const RowToColMapping& basis, + const VariablesInfo& variables_info, + const BasisFactorization& basis_factorization); + + // Getters for the variable values. + const Fractional Get(ColIndex col) const { return variable_values_[col]; } + const DenseRow& GetDenseRow() const { return variable_values_; } + + // Sets the value of a non-basic variable to the exact value implied by its + // current status. Note that the basic variable values are NOT updated by this + // function and it is up to the client to call RecomputeBasicVariableValues(). + void SetNonBasicVariableValueFromStatus(ColIndex col); + + // Recomputes the value of the basic variables from the non-basic ones knowing + // that the linear program matrix A times the variable values vector must be + // zero. It is better to call this when the basis is refactorized. This + // is checked in debug mode. + void RecomputeBasicVariableValues(); + + // Computes the infinity norm of A.x where A is the linear_program matrix and + // x is the variable values column. + Fractional ComputeMaximumPrimalResidual() const; + + // Computes the maximum bound error for all the variables, defined as the + // distance of the current value of the variable to its interval + // [lower bound, upper bound]. The residual is thus equal to 0.0 if the + // current value falls within the bounds, to the distance to lower_bound + // (resp. upper_bound), if the current value is below (resp. above) + // lower_bound (resp. upper_bound). + Fractional ComputeMaximumPrimalInfeasibility() const; + Fractional ComputeSumOfPrimalInfeasibilities() const; + + // Updates the variable during a simplex pivot: + // - step * direction is substracted from the basic variables value. + // - step is added to the entering column value. + void UpdateOnPivoting(ScatteredColumnReference direction, + ColIndex entering_col, Fractional step); + + // Batch version of SetNonBasicVariableValueFromStatus(). This function also + // updates the basic variable values and infeasibility statuses if + // update_basic_variables is true. The update is done in an incremental way + // and is thus more efficient than calling afterwards + // RecomputeBasicVariableValues() and ResetPrimalInfeasibilityInformation(). + void UpdateGivenNonBasicVariables(const std::vector& cols_to_update, + bool update_basic_variables); + + // Functions dealing with the primal-infeasible basic variables. A basic + // variable is primal-infeasible if its value is outside its bounds + // (modulo the absolute tolerance set by SetBoundTolerance()). This + // information is only available after a call to + // ResetPrimalInfeasibilityInformation() and has to be kept in sync by calling + // UpdatePrimalInfeasibilityInformation() for the rows that changed values. + void SetBoundTolerance(Fractional tolerance) { tolerance_ = tolerance; } + const DenseBitColumn& GetPrimalInfeasiblePositions() const; + const DenseColumn& GetPrimalSquaredInfeasibilities() const; + void ResetPrimalInfeasibilityInformation(); + void UpdatePrimalInfeasibilityInformation(const std::vector& rows); + + // Sets the variable value of a given column. + void Set(ColIndex col, Fractional value) { variable_values_[col] = value; } + + // Parameters and stats functions. + std::string StatString() const { return stats_.StatString(); } + + private: + // Internal version of UpdatePrimalInfeasibilityInformation(). + template + void UpdatePrimalInfeasibilities(const Rows& rows); + + // Input problem data. + const CompactSparseMatrix& matrix_; + const RowToColMapping& basis_; + const VariablesInfo& variables_info_; + const BasisFactorization& basis_factorization_; + + // Values of the variables. + DenseRow variable_values_; + + // Members used for the basic primal-infeasible variables. + Fractional tolerance_; + DenseColumn primal_squared_infeasibilities_; + DenseBitColumn primal_infeasible_positions_; + + mutable StatsGroup stats_; + mutable DenseColumn scratchpad_; + + // A temporary dense column that is always reset to all zero after use. + DenseColumn initially_all_zero_scratchpad_; + + // A temporary RowIndexVector used to hold the non-zero positions of a column. + RowIndexVector row_index_vector_scratchpad_; + + DISALLOW_COPY_AND_ASSIGN(VariableValues); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_VARIABLE_VALUES_H_ diff --git a/thirdparty/linux/include/ortools/glop/variables_info.h b/thirdparty/linux/include/ortools/glop/variables_info.h new file mode 100644 index 0000000..a6e1d93 --- /dev/null +++ b/thirdparty/linux/include/ortools/glop/variables_info.h @@ -0,0 +1,128 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GLOP_VARIABLES_INFO_H_ +#define OR_TOOLS_GLOP_VARIABLES_INFO_H_ + +#include "ortools/lp_data/lp_types.h" +#include "ortools/lp_data/sparse.h" + +namespace operations_research { +namespace glop { + +// Class responsible for maintaining diverse information for each variable that +// depend on its bounds and status. +// +// Note(user): Not all information is needed at all time, but it is cheap to +// maintain it since it only requires a few calls to Update() per simplex +// iteration. +class VariablesInfo { + public: + // Takes references to the linear program data we need. + VariablesInfo(const CompactSparseMatrix& matrix, const DenseRow& lower_bound, + const DenseRow& upper_bound); + + // Resets all the quantities to a default value. Note that nothing can be + // assumed on the return values of the getters until Update() has been called + // at least once on all the columns. + void Initialize(); + + // Updates the information of the given variable. Note that it is not needed + // to call this if the status or the bound of a variable didn't change. + void Update(ColIndex col, VariableStatus status); + + // Slighlty optimized version of Update() above for the two separate cases. + void UpdateToBasicStatus(ColIndex col); + void UpdateToNonBasicStatus(ColIndex col, VariableStatus status); + + // Various getter, see the corresponding member declaration below for more + // information. + const VariableTypeRow& GetTypeRow() const; + const VariableStatusRow& GetStatusRow() const; + const DenseBitRow& GetCanIncreaseBitRow() const; + const DenseBitRow& GetCanDecreaseBitRow() const; + const DenseBitRow& GetIsRelevantBitRow() const; + const DenseBitRow& GetIsBasicBitRow() const; + const DenseBitRow& GetNotBasicBitRow() const; + const DenseBitRow& GetNonBasicBoxedVariables() const; + + // Returns the variable bounds. + const DenseRow& GetVariableLowerBounds() const { return lower_bound_; } + const DenseRow& GetVariableUpperBounds() const { return upper_bound_; } + + const ColIndex GetNumberOfColumns() const { return matrix_.num_cols(); } + + // Changes whether or not a non-basic boxed variable is 'relevant' and will be + // returned as such by GetIsRelevantBitRow(). + void MakeBoxedVariableRelevant(bool are_boxed_variables_relevant); + + // This is used in UpdateRow to decide wheter to compute it using the row-wise + // or column-wise representation. + EntryIndex GetNumEntriesInRelevantColumns() const; + + // Returns the distance between the upper and lower bound of the given column. + Fractional GetBoundDifference(ColIndex col) const { + return upper_bound_[col] - lower_bound_[col]; + } + + private: + // Computes the variable type from its lower and upper bound. + VariableType ComputeVariableType(ColIndex col) const; + + // Sets the column relevance and updates num_entries_in_relevant_columns_. + void SetRelevance(ColIndex col, bool relevance); + + // Problem data that should be updated from outside. + const CompactSparseMatrix& matrix_; + const DenseRow& lower_bound_; + const DenseRow& upper_bound_; + + // Array of variable statuses, indexed by column index. + VariableStatusRow variable_status_; + + // Array of variable types, indexed by column index. + VariableTypeRow variable_type_; + + // Indicates if a non-basic variable can move up or down while not increasing + // the primal infeasibility. Note that all combinaisons are possible for a + // variable according to its status: fixed, free, upper or lower bounded. This + // is always false for basic variable. + DenseBitRow can_increase_; + DenseBitRow can_decrease_; + + // Indicates if we should consider this variable for entering the basis during + // the simplex algorithm. Only non-fixed and non-basic columns are relevant. + DenseBitRow relevance_; + + // Indicates if a variable is BASIC or not. There are currently two members + // because the DenseBitRow class only supports a nice range-based iteration on + // the non-zero positions and not on the others. + DenseBitRow is_basic_; + DenseBitRow not_basic_; + + // Set of boxed variables that are non-basic. + DenseBitRow non_basic_boxed_variables_; + + // Number of entries for the relevant matrix columns (see relevance_). + EntryIndex num_entries_in_relevant_columns_; + + // Whether or not a boxed variable should be considered relevant. + bool boxed_variables_are_relevant_; + + DISALLOW_COPY_AND_ASSIGN(VariablesInfo); +}; + +} // namespace glop +} // namespace operations_research + +#endif // OR_TOOLS_GLOP_VARIABLES_INFO_H_ diff --git a/thirdparty/linux/include/ortools/graph/assignment.h b/thirdparty/linux/include/ortools/graph/assignment.h new file mode 100644 index 0000000..1f523f0 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/assignment.h @@ -0,0 +1,130 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Simple interface to solve the linear sum assignment problem. It +// uses about twice as much memory as directly using the +// LinearSumAssignment class template, but it is as fast and presents +// a simpler interface. This is the class you should use in most +// situations. +// +// The assignment problem: Given N "left" nodes and N "right" nodes, +// and a set of left->right arcs with integer costs, find a perfect +// matching (i.e., each "left" node is assigned to one "right" node) +// that minimizes the overall cost. +// +// Example usage: +// +// #include "ortools/graph/assignment.h" +// +// SimpleLinearSumAssignment assignment; +// for (int arc = 0; arc < num_arcs; ++arc) { +// assignment.AddArcWithCost(head(arc), tail(arc), cost(arc)); +// } +// if (assignment.Solve() == SimpleLinearSumAssignment::OPTIMAL) { +// printf("A perfect matching exists.\n"); +// printf("The best possible cost is %d.\n", assignment.OptimalCost()); +// printf("An optimal assignment is:\n"); +// for (int node = 0; node < assignment.NumNodes(); ++node) { +// printf("left node %d assigned to right node %d with cost %d.\n", +// node, +// assignment.RightMate(node), +// assignment.AssignmentCost(node)); +// } +// printf("Note that it may not be the unique optimal assignment."); +// } else { +// printf("There is an issue with the input or no perfect matching exists."); +// } + +#ifndef OR_TOOLS_GRAPH_ASSIGNMENT_H_ +#define OR_TOOLS_GRAPH_ASSIGNMENT_H_ + +#include + +#include "ortools/graph/ebert_graph.h" + +namespace operations_research { + +class SimpleLinearSumAssignment { + public: + // The constructor takes no size. + // New node indices will be created lazily by AddArcWithCost(). + SimpleLinearSumAssignment(); + + // Adds an arc from a left node to a right node with a given cost. + // * Node indices must be non-negative (>= 0). For a perfect + // matching to exist on n nodes, the values taken by "left_node" + // must cover [0, n), same for "right_node". + // * The arc cost can be any integer, negative, positive or zero. + // * After the method finishes, NumArcs() == the returned ArcIndex + 1. + ArcIndex AddArcWithCost(NodeIndex left_node, NodeIndex right_node, + CostValue cost); + + // Returns the current number of left nodes which is the same as the + // number of right nodes. This is one greater than the largest node + // index seen so far in AddArcWithCost(). + NodeIndex NumNodes() const; + + // Returns the current number of arcs in the graph. + ArcIndex NumArcs() const; + + // Returns user-provided data. + // The implementation will crash if "arc" is not in [0, NumArcs()). + NodeIndex LeftNode(ArcIndex arc) const; + NodeIndex RightNode(ArcIndex arc) const; + CostValue Cost(ArcIndex arc) const; + + // Solves the problem (finds the perfect matching that minimizes the + // cost) and returns the solver status. + enum Status { + OPTIMAL, // The algorithm found a minimum-cost perfect matching. + INFEASIBLE, // The given problem admits no perfect matching. + POSSIBLE_OVERFLOW, // Some cost magnitude is too large. + }; + Status Solve(); + + // Returns the cost of an assignment with minimal cost. + // This is 0 if the last Solve() didn't return OPTIMAL. + CostValue OptimalCost() const { return optimal_cost_; } + + // Returns the right node assigned to the given left node in the + // last solution computed by Solve(). This works only if Solve() + // returned OPTIMAL. + // + // Note: It is possible that there is more than one optimal + // solution. The algorithm is deterministic so it will always return + // the same solution for a given problem. There is no such guarantee + // from one code version to the next, but the code does not change + // often. + NodeIndex RightMate(NodeIndex left_node) const { + return arc_head_[assignment_arcs_[left_node]]; + } + + // Returns the cost of the arc used for "left_node"'s assignment. + // This works only if Solve() returned OPTIMAL. + CostValue AssignmentCost(NodeIndex left_node) const { + return arc_cost_[assignment_arcs_[left_node]]; + } + + private: + NodeIndex num_nodes_; + std::vector arc_tail_; + std::vector arc_head_; + std::vector arc_cost_; + std::vector assignment_arcs_; + CostValue optimal_cost_; + DISALLOW_COPY_AND_ASSIGN(SimpleLinearSumAssignment); +}; + +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_ASSIGNMENT_H_ diff --git a/thirdparty/linux/include/ortools/graph/christofides.h b/thirdparty/linux/include/ortools/graph/christofides.h new file mode 100644 index 0000000..4f6865a --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/christofides.h @@ -0,0 +1,300 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// ChristofidesPathSolver computes an approximate solution to the Traveling +// Salesman Problen using the Christofides algorithm (c.f. +// https://en.wikipedia.org/wiki/Christofides_algorithm). +// Note that the algorithm guarantees finding a solution within 3/2 of the +// optimum. Its complexity is O(n^2 * log(n)) where n is the number of nodes. + +#ifndef OR_TOOLS_GRAPH_CHRISTOFIDES_H_ +#define OR_TOOLS_GRAPH_CHRISTOFIDES_H_ + +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/graph/eulerian_path.h" +#include "ortools/graph/minimum_spanning_tree.h" +#include "ortools/linear_solver/linear_solver.h" +#include "ortools/linear_solver/linear_solver.pb.h" + +namespace operations_research { + +template > +class ChristofidesPathSolver { + public: + enum class MatchingAlgorithm { +#if defined(USE_CBC) || defined(USE_SCIP) + MINIMUM_WEIGHT_MATCHING, +#endif // defined(USE_CBC) || defined(USE_SCIP) + MINIMAL_WEIGHT_MATCHING, + }; + ChristofidesPathSolver(NodeIndex num_nodes, CostFunction costs); + + // Sets the matching algorith to use. A minimum weight perfect matching + // (MINIMUM_WEIGHT_MATCHING) guarantees the 3/2 upper bound to the optimal + // solution. A minimal weight perfect matching (MINIMAL_WEIGHT_MATCHING) + // finds a locally minimal weight matching which does not offer any bound + // guarantee but, as of 1/2017, is orders of magnitude faster than the + // minimum matching. + // By default, MINIMAL_WEIGHT_MATCHING is selected. + // TODO(user): Change the default when minimum matching gets faster. + void SetMatchingAlgorithm(MatchingAlgorithm matching) { + matching_ = matching; + } + + // Returns the cost of the approximate TSP tour. + CostType TravelingSalesmanCost(); + + // Returns the approximate TSP tour. + std::vector TravelingSalesmanPath(); + + private: + // Runs the Christofides algorithm. + void Solve(); + + // Matching algorithm to use. + MatchingAlgorithm matching_; + + // The complete graph on the nodes of the problem. + CompleteGraph graph_; + + // Function returning the cost between nodes of the problem. + const CostFunction costs_; + + // The cost of the computed TSP path. + CostType tsp_cost_; + + // The path of the computed TSP, + std::vector tsp_path_; + + // True if the TSP has been solved, false otherwise. + bool solved_; +}; + +#if defined(USE_CBC) || defined(USE_SCIP) +// Computes a minimum weight perfect matching on an undirected graph using a +// Mixed Integer Programming model. +// TODO(user): Handle infeasible cases if this algorithm is used outside of +// Christofides. +template +std::vector ComputeMinimumWeightMatchingWithMIP( + const GraphType& graph, const WeightFunctionType& weight) { + using ArcIndex = typename GraphType::ArcIndex; + using NodeIndex = typename GraphType::NodeIndex; + MPModelProto model; + model.set_maximize(false); + // The model is composed of Boolean decision variables to select matching arcs + // and constraints ensuring that each node appears in exactly one selected + // arc. The objective is to minimize the sum of the weights of selected arcs. + // It is assumed the graph is symmetrical. + std::unordered_map variable_indices; + for (NodeIndex node : graph.AllNodes()) { + // Creating arc-selection Boolean variable. + for (const ArcIndex arc : graph.OutgoingArcs(node)) { + const NodeIndex head = graph.Head(arc); + if (node < head) { + variable_indices[arc] = model.variable_size(); + MPVariableProto* const arc_var = model.add_variable(); + arc_var->set_lower_bound(0); + arc_var->set_upper_bound(1); + arc_var->set_is_integer(true); + arc_var->set_objective_coefficient(weight(arc)); + } + } + // Creating matching constraint: + // for all node i, sum(j) arc(i,j) + sum(j) arc(j,i) = 1 + MPConstraintProto* const one_of_ct = model.add_constraint(); + one_of_ct->set_lower_bound(1); + one_of_ct->set_upper_bound(1); + } + for (NodeIndex node : graph.AllNodes()) { + for (const ArcIndex arc : graph.OutgoingArcs(node)) { + const NodeIndex head = graph.Head(arc); + if (node < head) { + MPConstraintProto* one_of_ct = model.mutable_constraint(node); + one_of_ct->add_var_index(variable_indices[arc]); + one_of_ct->add_coefficient(1); + one_of_ct = model.mutable_constraint(head); + one_of_ct->add_var_index(variable_indices[arc]); + one_of_ct->add_coefficient(1); + } + } + } +#if defined(USE_SCIP) + MPSolver scip_solver("MatchingWithSCIP", + MPSolver::SCIP_MIXED_INTEGER_PROGRAMMING); +#elif defined(USE_CBC) + MPSolver scip_solver("MatchingWithCBC", + MPSolver::CBC_MIXED_INTEGER_PROGRAMMING); +#endif + // TODO(user): Glip performs significantly faster on very small problems; + // investigate the necessity of switching solvers depending on model size. + std::string error; + scip_solver.LoadModelFromProto(model, &error); + MPSolver::ResultStatus status = scip_solver.Solve(); + CHECK_EQ(status, MPSolver::OPTIMAL); + MPSolutionResponse response; + scip_solver.FillSolutionResponseProto(&response); + std::vector matching; + for (auto arc : variable_indices) { + if (response.variable_value(arc.second) > .9) { + DCHECK_GE(response.variable_value(arc.second), 1.0 - 1e-4); + matching.push_back(arc.first); + } + } + return matching; +} +#endif // defined(USE_CBC) || defined(USE_SCIP) + +template +ChristofidesPathSolver:: + ChristofidesPathSolver(NodeIndex num_nodes, CostFunction costs) + : matching_(MatchingAlgorithm::MINIMAL_WEIGHT_MATCHING), + graph_(num_nodes), + costs_(std::move(costs)), + tsp_cost_(0), + solved_(false) {} + +template +CostType ChristofidesPathSolver::TravelingSalesmanCost() { + if (!solved_) { + Solve(); + } + return tsp_cost_; +} + +template +std::vector ChristofidesPathSolver< + CostType, ArcIndex, NodeIndex, CostFunction>::TravelingSalesmanPath() { + if (!solved_) { + Solve(); + } + return tsp_path_; +} + +template +void ChristofidesPathSolver::Solve() { + const NodeIndex num_nodes = graph_.num_nodes(); + tsp_path_.clear(); + tsp_cost_ = 0; + if (num_nodes == 1) { + tsp_path_ = {0, 0}; + } + if (num_nodes <= 1) { + return; + } + // Compute Minimum Spanning Tree. + const std::vector mst = + BuildPrimMinimumSpanningTree(graph_, [this](ArcIndex arc) { + return costs_(graph_.Tail(arc), graph_.Head(arc)); + }); + // Detect odd degree nodes. + std::vector degrees(num_nodes, 0); + for (ArcIndex arc : mst) { + degrees[graph_.Tail(arc)]++; + degrees[graph_.Head(arc)]++; + } + std::vector odd_degree_nodes; + for (int i = 0; i < degrees.size(); ++i) { + if (degrees[i] % 2 != 0) { + odd_degree_nodes.push_back(i); + } + } + // Find minimum-weight perfect matching on odd-degree-node complete graph. + // TODO(user): Make this code available as an independent algorithm. + const NodeIndex reduced_size = odd_degree_nodes.size(); + DCHECK_NE(0, reduced_size); + CompleteGraph reduced_graph(reduced_size); + std::vector closure_arcs; + switch (matching_) { +#if defined(USE_CBC) || defined(USE_SCIP) + case MatchingAlgorithm::MINIMUM_WEIGHT_MATCHING: { + closure_arcs = ComputeMinimumWeightMatchingWithMIP( + reduced_graph, [this, &reduced_graph, + &odd_degree_nodes](CompleteGraph<>::ArcIndex arc) { + return costs_(odd_degree_nodes[reduced_graph.Tail(arc)], + odd_degree_nodes[reduced_graph.Head(arc)]); + }); + break; + } +#endif // defined(USE_CBC) || defined(USE_SCIP) + case MatchingAlgorithm::MINIMAL_WEIGHT_MATCHING: { + // TODO(user): Cost caching was added and can gain up to 20% but + // increases memory usage; see if we can avoid caching. + std::vector ordered_arcs(reduced_graph.num_arcs()); + std::vector ordered_arc_costs(reduced_graph.num_arcs(), 0); + for (const ArcIndex arc : reduced_graph.AllForwardArcs()) { + ordered_arcs[arc] = arc; + ordered_arc_costs[arc] = + costs_(odd_degree_nodes[reduced_graph.Tail(arc)], + odd_degree_nodes[reduced_graph.Head(arc)]); + } + std::sort(ordered_arcs.begin(), ordered_arcs.end(), + [&ordered_arc_costs](ArcIndex arc_a, ArcIndex arc_b) { + return ordered_arc_costs[arc_a] < ordered_arc_costs[arc_b]; + }); + std::vector touched_nodes(reduced_size, false); + for (ArcIndex arc_index = 0; closure_arcs.size() * 2 < reduced_size; + ++arc_index) { + const ArcIndex arc = ordered_arcs[arc_index]; + const NodeIndex tail = reduced_graph.Tail(arc); + const NodeIndex head = reduced_graph.Head(arc); + if (head != tail && !touched_nodes[tail] && !touched_nodes[head]) { + touched_nodes[tail] = true; + touched_nodes[head] = true; + closure_arcs.push_back(arc); + } + } + break; + } + } + // Build Eulerian path on minimum spanning tree + closing edges from matching + // and extract a solution to the Traveling Salesman from the path by skipping + // duplicate nodes. + ReverseArcListGraph egraph( + num_nodes, closure_arcs.size() + mst.size()); + for (ArcIndex arc : mst) { + const NodeIndex tail = graph_.Tail(arc); + const NodeIndex head = graph_.Head(arc); + egraph.AddArc(tail, head); + } + for (ArcIndex arc : closure_arcs) { + const NodeIndex tail = odd_degree_nodes[reduced_graph.Tail(arc)]; + const NodeIndex head = odd_degree_nodes[reduced_graph.Head(arc)]; + egraph.AddArc(tail, head); + } + std::vector touched(num_nodes, false); + DCHECK(IsEulerianGraph(egraph)); + for (const NodeIndex node : BuildEulerianTourFromNode(egraph, 0)) { + if (touched[node]) continue; + touched[node] = true; + tsp_cost_ += tsp_path_.empty() ? 0 : costs_(tsp_path_.back(), node); + tsp_path_.push_back(node); + } + tsp_cost_ += tsp_path_.empty() ? 0 : costs_(tsp_path_.back(), 0); + tsp_path_.push_back(0); + solved_ = true; +} +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_CHRISTOFIDES_H_ diff --git a/thirdparty/linux/include/ortools/graph/cliques.h b/thirdparty/linux/include/ortools/graph/cliques.h new file mode 100644 index 0000000..e2294bf --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/cliques.h @@ -0,0 +1,561 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// Maximal clique algorithms, based on the Bron-Kerbosch algorithm. +// See http://en.wikipedia.org/wiki/Bron-Kerbosch_algorithm +// and +// C. Bron and J. Kerbosch, Joep, "Algorithm 457: finding all cliques of an +// undirected graph", CACM 16 (9): 575–577, 1973. +// http://dl.acm.org/citation.cfm?id=362367&bnc=1. +// +// Keywords: undirected graph, clique, clique cover, Bron, Kerbosch. + +#ifndef OR_TOOLS_GRAPH_CLIQUES_H_ +#define OR_TOOLS_GRAPH_CLIQUES_H_ + +#include +#include +#include +#include + +#include "ortools/base/logging.h" +#include "ortools/base/join.h" +#include "ortools/base/int_type.h" +#include "ortools/base/int_type_indexed_vector.h" +#include "ortools/util/time_limit.h" + +namespace operations_research { + +// Finds all maximal cliques, even of size 1, in the +// graph described by the graph callback. graph->Run(i, j) indicates +// if there is an arc between i and j. +// This function takes ownership of 'callback' and deletes it after it has run. +// If 'callback' returns true, then the search for cliques stops. +void FindCliques(std::function graph, int node_count, + std::function&)> callback); + +// Covers the maximum number of arcs of the graph with cliques. The graph +// is described by the graph callback. graph->Run(i, j) indicates if +// there is an arc between i and j. +// This function takes ownership of 'callback' and deletes it after it has run. +// It calls 'callback' upon each clique. +// It ignores cliques of size 1. +void CoverArcsByCliques(std::function graph, int node_count, + std::function&)> callback); + +// Possible return values of the callback for reporting cliques. The returned +// value determines whether the algorithm will continue the search. +enum class CliqueResponse { + // The algorithm will continue searching for other maximal cliques. + CONTINUE, + // The algorithm will stop the search immediately. The search can be resumed + // by calling BronKerboschAlgorithm::Run (resp. RunIterations) again. + STOP +}; + +// The status value returned by BronKerboschAlgorithm::Run and +// BronKerboschAlgorithm::RunIterations. +enum class BronKerboschAlgorithmStatus { + // The algorithm has enumerated all maximal cliques. + COMPLETED, + // The search algorithm was interrupted either because it reached the + // iteration limit or because the clique callback returned + // CliqueResponse::STOP. + INTERRUPTED +}; + +// Implements the Bron-Kerbosch algorithm for finding maximal cliques. +// The graph is represented as a callback that gets two nodes as its arguments +// and it returns true if and only if there is an arc between the two nodes. The +// cliques are reported back to the user using a second callback. +// +// Typical usage: +// auto graph = [](int node1, int node2) { return true; }; +// auto on_clique = [](const std::vector& clique) { LOG(INFO) << "Clique!"; }; +// +// BronKerboschAlgorithm bron_kerbosch(graph, num_nodes, on_clique); +// bron_kerbosch.Run(); +// +// or: +// +// BronKerboschAlgorithm bron_kerbosch(graph, num_nodes, clique); +// bron_kerbosch.RunIterations(kMaxNumIterations); +// +// This is a non-recursive implementation of the Bron-Kerbosch algorithm with +// pivots as described in the paper by Bron and Kerbosch (1973) (the version 2 +// algorithm in the paper). +// The basic idea of the algorithm is to incrementally build the cliques using +// depth-first search. During the search, the algorithm maintains two sets of +// candidates (nodes that are connected to all nodes in the current clique): +// - the "not" set - these are candidates that were already visited by the +// search and all the maximal cliques that contain them as a part of the +// current clique were already reported. +// - the actual candidates - these are candidates that were not visited yet, and +// they can be added to the clique. +// In each iteration, the algorithm does the first of the following actions that +// applies: +// A. If there are no actual candidates and there are candidates in the "not" +// set, or if all actual candidates are connected to the same node in the +// "not" set, the current clique can't be extended to a maximal clique that +// was not already reported. Return from the recursive call and move the +// selected candidate to the set "not". +// B. If there are no candidates at all, it means that the current clique can't +// be extended and that it is in fact a maximal clique. Report it to the user +// and return from the recursive call. Move the selected candidate to the set +// "not". +// C. Otherwise, there are actual candidates, extend the current clique with one +// of these candidates and process it recursively. +// +// To avoid unnecessary steps, the algorithm selects a pivot at each level of +// the recursion to guide the selection of candidates added to the current +// clique. The pivot can be either in the "not" set and among the actual +// candidates. The algorithm tries to move the pivot and all actual candidates +// connected to it to the set "not" as quickly as possible. This will fulfill +// the conditions of step A, and the search algorithm will be able to leave the +// current branch. Selecting a pivot that has the lowest number of disconnected +// nodes among the candidates can reduce the running time significantly. +// +// The worst-case maximal depth of the recursion is equal to the number of nodes +// in the graph, which makes the natural recursive implementation impractical +// for nodes with more than a few thousands of nodes. To avoid the limitation, +// this class simulates the recursion by maintaining a stack with the state at +// each level of the recursion. The algorithm then runs in a loop. In each +// iteration, the algorithm can do one or both of: +// 1. Return to the previous recursion level (step A or B of the algorithm) by +// removing the top state from the stack. +// 2. Select the next candidate and enter the next recursion level (step C of +// the algorithm) by adding a new state to the stack. +// +// The worst-case time complexity of the algorithm is O(3^(N/3)), and the memory +// complexity is O(N^2), where N is the number of nodes in the graph. +template +class BronKerboschAlgorithm { + public: + // A callback called by the algorithm to test if there is an arc between a + // pair of nodes. The callback must return true if and only if there is an + // arc. Note that to function properly, the function must be symmetrical + // (represent an undirected graph). + using IsArcCallback = std::function; + // A callback called by the algorithm to report a maximal clique to the user. + // The clique is returned as a list of nodes in the clique, in no particular + // order. The caller must make a copy of the vector if they want to keep the + // nodes. + // + // The return value of the callback controls how the algorithm continues after + // this clique. See the description of the values of 'CliqueResponse' for more + // details. + using CliqueCallback = + std::function&)>; + + // Initializes the Bron-Kerbosch algorithm for the given graph and clique + // callback function. + BronKerboschAlgorithm(IsArcCallback is_arc, NodeIndex num_nodes, + CliqueCallback clique_callback) + : is_arc_(std::move(is_arc)), + clique_callback_(std::move(clique_callback)), + num_nodes_(num_nodes) {} + + // Runs the Bron-Kerbosch algorithm for kint64max iterations. In practice, + // this is equivalent to running until completion or until the clique callback + // returns BronKerboschAlgorithmStatus::STOP. If the method returned because + // the search is finished, it will return COMPLETED; otherwise, it will return + // INTERRUPTED and it can be resumed by calling this method again. + BronKerboschAlgorithmStatus Run(); + + // Runs at most 'max_num_iterations' iterations of the Bron-Kerbosch + // algorithm. When this function returns INTERRUPTED, there is still work to + // be done to process all the cliques in the graph. In such case the method + // can be called again and it will resume the work where the previous call had + // stopped. When it returns COMPLETED any subsequent call to the method will + // resume the search from the beginning. + BronKerboschAlgorithmStatus RunIterations(int64 max_num_iterations); + + // Runs at most 'max_num_iterations' iterations of the Bron-Kerbosch + // algorithm, until the time limit is exceeded or until all cliques are + // enumerated. When this function returns INTERRUPTED, there is still work to + // be done to process all the cliques in the graph. In such case the method + // can be called again and it will resume the work where the previous call had + // stopped. When it returns COMPLETED any subsequent call to the method will + // resume the search from the beginning. + BronKerboschAlgorithmStatus RunWithTimeLimit(int64 max_num_iterations, + TimeLimit* time_limit); + + // Runs the Bron-Kerbosch algorithm for at most kint64max iterations, until + // the time limit is excceded or until all cliques are enumerated. In + // practice, running the algorithm for kint64max iterations is equivalent to + // running until completion or until the other stopping conditions apply. When + // this function returns INTERRUPTED, there is still work to be done to + // process all the cliques in the graph. In such case the method can be called + // again and it will resume the work where the previous call had stopped. When + // it returns COMPLETED any subsequent call to the method will resume the + // search from the beginning. + BronKerboschAlgorithmStatus RunWithTimeLimit(TimeLimit* time_limit) { + return RunWithTimeLimit(kint64max, time_limit); + } + + private: + DEFINE_INT_TYPE(CandidateIndex, ptrdiff_t); + + // A data structure that maintains the variables of one "iteration" of the + // search algorithm. These are the variables that would normally be allocated + // on the stack in the recursive implementation. + // + // Note that most of the variables in the structure are explicitly left + // uninitialized by the constructor to avoid wasting resources on values that + // will be overwritten anyway. Most of the initialization is done in + // BronKerboschAlgorithm::InitializeState. + struct State { + State() {} + State(const State& other) + : pivot(other.pivot), + num_remaining_candidates(other.num_remaining_candidates), + candidates(other.candidates), + first_candidate_index(other.first_candidate_index), + candidate_for_recursion(other.candidate_for_recursion) {} + + State& operator=(const State& other) { + pivot = other.pivot; + num_remaining_candidates = other.num_remaining_candidates; + candidates = other.candidates; + first_candidate_index = other.first_candidate_index; + candidate_for_recursion = other.candidate_for_recursion; + return *this; + } + + // Moves the first candidate in the state to the "not" set. Assumes that the + // first candidate is also the pivot or a candidate disconnected from the + // pivot (as done by RunIteration). + inline void MoveFirstCandidateToNotSet() { + ++first_candidate_index; + --num_remaining_candidates; + } + + // Creates a human-readable representation of the current state. + std::string DebugString() { + std::string buffer; + StrAppend(&buffer, "pivot = ", pivot, + "\nnum_remaining_candidates = ", num_remaining_candidates, + "\ncandidates = ["); + for (CandidateIndex i(0); i < candidates.size(); ++i) { + if (i > 0) buffer += ", "; + StrAppend(&buffer, candidates[i]); + } + StrAppend( + &buffer, "]\nfirst_candidate_index = ", first_candidate_index.value(), + "\ncandidate_for_recursion = ", candidate_for_recursion.value()); + return buffer; + } + + // The pivot node selected for the given level of the recursion. + NodeIndex pivot; + // The number of remaining candidates to be explored at the given level of + // the recursion; the number is computed as num_disconnected_nodes + + // pre_increment in the original algorithm. + int num_remaining_candidates; + // The list of nodes that are candidates for extending the current clique. + // This vector has the format proposed in the paper by Bron-Kerbosch; the + // first 'first_candidate_index' elements of the vector represent the + // "not" set of nodes that were already visited by the algorithm. The + // remaining elements are the actual candidates for extending the current + // clique. + // NOTE(user): We could store the delta between the iterations; however, + // we need to evaluate the impact this would have on the performance. + ITIVector candidates; + // The index of the first actual candidate in 'candidates'. This number is + // also the number of elements of the "not" set stored at the beginning of + // 'candidates'. + CandidateIndex first_candidate_index; + + // The current position in candidates when looking for the pivot and/or the + // next candidate disconnected from the pivot. + CandidateIndex candidate_for_recursion; + }; + + // The deterministic time coefficients for the push and pop operations of the + // Bron-Kerbosch algorithm. The coefficients are set to match approximately + // the running time in seconds on a recent workstation on the random graph + // benchmark. + // NOTE(user): PushState is not the only source of complexity in the + // algorithm, but non-negative linear least squares produced zero coefficients + // for all other deterministic counters tested during the benchmarking. When + // we optimize the algorithm, we might need to add deterministic time to the + // other places that may produce complexity, namely InitializeState, PopState + // and SelectCandidateIndexForRecursion. + static const double kPushStateDeterministicTimeSecondsPerCandidate; + + // Initializes the root state of the algorithm. + void Initialize(); + + // Removes the top state from the state stack. This is equivalent to returning + // in the recursive implementation of the algorithm. + void PopState(); + + // Adds a new state to the top of the stack, adding the node 'selected' to the + // current clique. This is equivalent to making a recurisve call in the + // recursive implementation of the algorithm. + void PushState(NodeIndex selected); + + // Initializes the given state. Runs the pivot selection algorithm in the + // state. + void InitializeState(State* state); + + // Returns true if (node1, node2) is an arc in the graph or if node1 == node2. + inline bool IsArc(NodeIndex node1, NodeIndex node2) const { + return node1 == node2 || is_arc_(node1, node2); + } + + // Selects the next node for recursion. The selected node is either the pivot + // (if it is not in the set "not") or a node that is disconnected from the + // pivot. + CandidateIndex SelectCandidateIndexForRecursion(State* state); + + // Returns a human-readable std::string representation of the clique. + std::string CliqueDebugString(const std::vector& clique); + + // The callback called when the algorithm needs to determine if (node1, node2) + // is an arc in the graph. + IsArcCallback is_arc_; + + // The callback called when the algorithm discovers a maximal clique. The + // return value of the callback controls how the algorithm proceeds with the + // clique search. + CliqueCallback clique_callback_; + + // The number of nodes in the graph. + const NodeIndex num_nodes_; + + // Contains the state of the aglorithm. The vector serves as an external stack + // for the recursive part of the algorithm - instead of using the C++ stack + // and natural recursion, it is implemented as a loop and new states are added + // to the top of the stack. The algorithm ends when the stack is empty. + std::vector states_; + + // A vector that receives the current clique found by the algorithm. + std::vector current_clique_; + + // Set to true if the algorithm is active (it was not stopped by an the clique + // callback). + int64 num_remaining_iterations_; + + // The current time limit used by the solver. The time limit is assigned by + // the Run methods and it can be different for each call to run. + TimeLimit* time_limit_; +}; + +template +void BronKerboschAlgorithm::InitializeState(State* state) { + DCHECK(state != nullptr); + const int num_candidates = state->candidates.size(); + int num_disconnected_candidates = num_candidates; + state->pivot = 0; + CandidateIndex pivot_index(-1); + for (CandidateIndex pivot_candidate_index(0); + pivot_candidate_index < num_candidates && + num_disconnected_candidates > 0; + ++pivot_candidate_index) { + const NodeIndex pivot_candidate = state->candidates[pivot_candidate_index]; + int count = 0; + for (CandidateIndex i(state->first_candidate_index); i < num_candidates; + ++i) { + if (!IsArc(pivot_candidate, state->candidates[i])) { + ++count; + } + } + if (count < num_disconnected_candidates) { + pivot_index = pivot_candidate_index; + state->pivot = pivot_candidate; + num_disconnected_candidates = count; + } + } + state->num_remaining_candidates = num_disconnected_candidates; + if (pivot_index >= state->first_candidate_index) { + std::swap(state->candidates[pivot_index], + state->candidates[state->first_candidate_index]); + ++state->num_remaining_candidates; + } +} + +template +typename BronKerboschAlgorithm::CandidateIndex BronKerboschAlgorithm< + NodeIndex>::SelectCandidateIndexForRecursion(State* state) { + DCHECK(state != nullptr); + CandidateIndex disconnected_node_index = + std::max(state->first_candidate_index, state->candidate_for_recursion); + while (disconnected_node_index < state->candidates.size() && + state->candidates[disconnected_node_index] != state->pivot && + IsArc(state->pivot, state->candidates[disconnected_node_index])) { + ++disconnected_node_index; + } + state->candidate_for_recursion = disconnected_node_index; + return disconnected_node_index; +} + +template +void BronKerboschAlgorithm::Initialize() { + DCHECK(states_.empty()); + states_.reserve(num_nodes_); + states_.emplace_back(); + + State* const root_state = &states_.back(); + root_state->first_candidate_index = 0; + root_state->candidate_for_recursion = 0; + root_state->candidates.resize(num_nodes_, 0); + std::iota(root_state->candidates.begin(), root_state->candidates.end(), 0); + root_state->num_remaining_candidates = num_nodes_; + InitializeState(root_state); + + DVLOG(2) << "Initialized"; +} + +template +void BronKerboschAlgorithm::PopState() { + DCHECK(!states_.empty()); + states_.pop_back(); + if (!states_.empty()) { + State* const state = &states_.back(); + current_clique_.pop_back(); + state->MoveFirstCandidateToNotSet(); + } +} + +template +std::string BronKerboschAlgorithm::CliqueDebugString( + const std::vector& clique) { + std::string message = "Clique: [ "; + for (const NodeIndex node : clique) { + StrAppend(&message, node, " "); + } + message += "]"; + return message; +} + +template +void BronKerboschAlgorithm::PushState(NodeIndex selected) { + DCHECK(!states_.empty()); + DCHECK(time_limit_ != nullptr); + DVLOG(2) << "PushState: New depth = " << states_.size() + 1 + << ", selected node = " << selected; + ITIVector new_candidates; + + State* const previous_state = &states_.back(); + const double deterministic_time = + kPushStateDeterministicTimeSecondsPerCandidate * + previous_state->candidates.size(); + time_limit_->AdvanceDeterministicTime(deterministic_time, "PushState"); + + // Add all candidates from previous_state->candidates that are connected to + // 'selected' in the graph to the vector 'new_candidates', skipping the node + // 'selected'; this node is always at the position + // 'previous_state->first_candidate_index', so we can skip it by skipping the + // element at this particular index. + new_candidates.reserve(previous_state->candidates.size()); + for (CandidateIndex i(0); i < previous_state->first_candidate_index; ++i) { + const NodeIndex candidate = previous_state->candidates[i]; + if (IsArc(selected, candidate)) { + new_candidates.push_back(candidate); + } + } + const CandidateIndex new_first_candidate_index(new_candidates.size()); + for (CandidateIndex i = previous_state->first_candidate_index + 1; + i < previous_state->candidates.size(); ++i) { + const NodeIndex candidate = previous_state->candidates[i]; + if (IsArc(selected, candidate)) { + new_candidates.push_back(candidate); + } + } + + current_clique_.push_back(selected); + if (new_candidates.empty()) { + // We've found a clique. Report it to the user, but do not push the state + // because it would be popped immediately anyway. + DVLOG(2) << CliqueDebugString(current_clique_); + const CliqueResponse response = clique_callback_(current_clique_); + if (response == CliqueResponse::STOP) { + // The number of remaining iterations will be decremented at the end of + // the loop in RunIterations; setting it to 0 here would make it -1 at + // the end of the main loop. + num_remaining_iterations_ = 1; + } + current_clique_.pop_back(); + previous_state->MoveFirstCandidateToNotSet(); + return; + } + + // NOTE(user): The following line may invalidate previous_state (if the + // vector data was re-allocated in the process). We must avoid using + // previous_state below here. + states_.emplace_back(); + State* const new_state = &states_.back(); + new_state->candidates.swap(new_candidates); + new_state->first_candidate_index = new_first_candidate_index; + + InitializeState(new_state); +} + +template +BronKerboschAlgorithmStatus BronKerboschAlgorithm::RunWithTimeLimit( + int64 max_num_iterations, TimeLimit* time_limit) { + CHECK(time_limit != nullptr); + time_limit_ = time_limit; + if (states_.empty()) { + Initialize(); + } + for (num_remaining_iterations_ = max_num_iterations; + !states_.empty() && num_remaining_iterations_ > 0 && + !time_limit->LimitReached(); + --num_remaining_iterations_) { + State* const state = &states_.back(); + DVLOG(2) << "Loop: " << states_.size() << " states, " + << state->num_remaining_candidates << " candidate to explore\n" + << state->DebugString(); + if (state->num_remaining_candidates == 0) { + PopState(); + continue; + } + + const CandidateIndex selected_index = + SelectCandidateIndexForRecursion(state); + DVLOG(2) << "selected_index = " << selected_index; + const NodeIndex selected = state->candidates[selected_index]; + DVLOG(2) << "Selected candidate = " << selected; + + NodeIndex& f = state->candidates[state->first_candidate_index]; + NodeIndex& s = state->candidates[selected_index]; + std::swap(f, s); + + PushState(selected); + } + time_limit_ = nullptr; + return states_.empty() ? BronKerboschAlgorithmStatus::COMPLETED + : BronKerboschAlgorithmStatus::INTERRUPTED; +} + +template +BronKerboschAlgorithmStatus BronKerboschAlgorithm::RunIterations( + int64 max_num_iterations) { + TimeLimit time_limit(std::numeric_limits::infinity()); + return RunWithTimeLimit(max_num_iterations, &time_limit); +} + +template +BronKerboschAlgorithmStatus BronKerboschAlgorithm::Run() { + return RunIterations(kint64max); +} + +template +const double BronKerboschAlgorithm< + NodeIndex>::kPushStateDeterministicTimeSecondsPerCandidate = 0.54663e-7; +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_CLIQUES_H_ diff --git a/thirdparty/linux/include/ortools/graph/connectivity.h b/thirdparty/linux/include/ortools/graph/connectivity.h new file mode 100644 index 0000000..6c3ec7a --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/connectivity.h @@ -0,0 +1,171 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Graph connectivity algorithm for undirected graphs. +// Memory consumption: O(n) where m is the number of arcs and n the number +// of nodes. +// TODO(user): add depth-first-search based connectivity for directed graphs. +// TODO(user): add depth-first-search based biconnectivity for directed graphs. + +#ifndef OR_TOOLS_GRAPH_CONNECTIVITY_H_ +#define OR_TOOLS_GRAPH_CONNECTIVITY_H_ + +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" + +namespace operations_research { + +// Template class implementing a Union-Find algorithm with path compression for +// maintaining the connected components of a graph. +// See Cormen et al. 2nd Edition. MIT Press, 2001. ISBN 0-262-03293-7. +// Chapter 21: Data structures for Disjoint Sets, pp. 498–524. +// and Tarjan (1975). Efficiency of a Good But Not Linear Set +// Union Algorithm. Journal of the ACM 22(2):215–225 +// It is implemented as a template so that the size of NodeIndex can be chosen +// depending on the size of the graphs considered. +// The main interest is that arcs do not need to be kept. Thus the memory +// complexity is O(n) where n is the number of nodes in the graph. +// The complexity of this algorithm is O(n . alpha(n)) where alpha(n) is +// the inverse Ackermann function. alpha(n) <= log(log(log(..log(log(n))..) +// In practice alpha(n) <= 5. +// See Tarjan and van Leeuwen (1984). Worst-case analysis of set union +// algorithms. Journal of the ACM 31(2):245–281. +// +// Usage example: +// ConnectedComponents components; +// components.Init(num_nodes); +// for (int arc = 0; arc < num_arcs; ++arc) { +// components.AddArc(tail[arc], head[arc]); +// } +// int num_connected_components = components.GetNumberOfConnectedComponents(); +// if (num_connected_components == 1) { +// // Graph is completely connected. +// } +// // Group the nodes in the same connected component together. +// // group[class_number][i] contains the i-th node in group class_number. +// std::unordered_map > group(num_connected_components); +// for (int node = 0; node < num_nodes; ++node) { +// group[components.GetClassRepresentative(node)].push_back(node); +// } +// +// Keywords: graph, connected components. + +template +class ConnectedComponents { + public: + ConnectedComponents() : num_nodes_(0), class_(), class_size_() {} + + // Reserves memory for num_nodes and resets the data structures. + void Init(NodeIndex num_nodes) { + CHECK_GE(num_nodes, 0); + num_nodes_ = num_nodes; + class_.resize(num_nodes_); + class_size_.assign(num_nodes_, 1); + for (NodeIndex node = 0; node < num_nodes_; ++node) { + class_[node] = node; + } + } + + // Adds the information that NodeIndex tail and NodeIndex head are connected. + void AddArc(NodeIndex tail, NodeIndex head) { + const NodeIndex tail_class = CompressPath(tail); + const NodeIndex head_class = CompressPath(head); + if (tail_class != head_class) { + MergeClasses(tail_class, head_class); + } + } + + // Adds a complete StarGraph to the object. Note that Depth-First Search + // is a better algorithm for finding connected components on graphs. + // TODO(user): implement Depth-First Search-based connected components finder. + template + void AddGraph(const Graph& graph) { + Init(graph.num_nodes()); + for (NodeIndex tail = 0; tail < graph.num_nodes(); ++tail) { + for (typename Graph::OutgoingArcIterator it(graph, tail); it.Ok(); + it.Next()) { + AddArc(tail, graph.Head(it.Index())); + } + } + } + + // Compresses the path for node. + NodeIndex CompressPath(NodeIndex node) { + CheckNodeBounds(node); + NodeIndex parent = node; + while (parent != class_[parent]) { + CheckNodeBounds(class_[parent]); + CheckNodeBounds(class_[class_[parent]]); + parent = class_[parent]; + } + while (node != class_[node]) { + const NodeIndex old_parent = class_[node]; + class_[node] = parent; + node = old_parent; + } + return parent; + } + + // Returns the equivalence class representative for node. + NodeIndex GetClassRepresentative(NodeIndex node) { + return CompressPath(node); + } + + // Returns the number of connected components. Allocates num_nodes_ bits for + // the computation. + NodeIndex GetNumberOfConnectedComponents() { + NodeIndex number = 0; + for (NodeIndex node = 0; node < num_nodes_; ++node) { + if (class_[node] == node) ++number; + } + return number; + } + + // Merges the equivalence classes of node1 and node2. + void MergeClasses(NodeIndex node1, NodeIndex node2) { + // It's faster (~10%) to swap the two values and have a single piece of + // code for merging the classes. + CheckNodeBounds(node1); + CheckNodeBounds(node2); + if (class_size_[node1] < class_size_[node2]) { + std::swap(node1, node2); + } + class_[node2] = node1; + class_size_[node1] += class_size_[node2]; + } + + private: + void CheckNodeBounds(NodeIndex node_index) { + DCHECK_LE(0, node_index); + DCHECK_LT(node_index, num_nodes_); + } + // The exact number of nodes in the graph. + NodeIndex num_nodes_; + + // The equivalence class representative for each node. + std::vector class_; + + // The size of each equivalence class of each node. Used to compress the paths + // and therefore achieve better time complexity. + std::vector class_size_; + + DISALLOW_COPY_AND_ASSIGN(ConnectedComponents); +}; + +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_CONNECTIVITY_H_ diff --git a/thirdparty/linux/include/ortools/graph/ebert_graph.h b/thirdparty/linux/include/ortools/graph/ebert_graph.h new file mode 100644 index 0000000..cb85bc6 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/ebert_graph.h @@ -0,0 +1,2123 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_GRAPH_EBERT_GRAPH_H_ +#define OR_TOOLS_GRAPH_EBERT_GRAPH_H_ + +// A few variations on a theme of the "star" graph representation by +// Ebert, as described in J. Ebert, "A versatile data structure for +// edge-oriented graph algorithms." Communications of the ACM +// 30(6):513-519 (June 1987). +// http://portal.acm.org/citation.cfm?id=214769 +// +// In this file there are three representations that have much in +// common. The general one, called simply EbertGraph, contains both +// forward- and backward-star representations. The other, called +// ForwardEbertGraph, contains only the forward-star representation of +// the graph, and is appropriate for applications where the reverse +// arcs are not needed. +// +// The point of including all the representations in this one file is +// to capitalize, where possible, on the commonalities among them, and +// those commonalities are mostly factored out into base classes as +// described below. Despite the commonalities, however, each of the +// three representations presents a somewhat different interface +// because of their different underlying semantics. A quintessential +// example is that the AddArc() method, very natural for the +// EbertGraph representation, cannot exist for an inherently static +// representation like ForwardStaticGraph. +// +// Many clients are expected to use the interfaces to the graph +// objects directly, but some clients are parameterized by graph type +// and need a consistent interface for their underlying graph +// objects. For such clients, a small library of class templates is +// provided to give a consistent interface to clients where the +// underlying graph interfaces differ. Examples are the +// AnnotatedGraphBuildManager<> template, which provides a uniform +// interface for building the various types of graphs; and the +// TailArrayManager<> template, which provides a uniform interface for +// applications that need to map from arc indices to arc tail nodes, +// accounting for the fact that such a mapping has to be requested +// explicitly from the ForwardStaticGraph and ForwardStarGraph +// representations. +// +// There are two base class templates, StarGraphBase, and +// EbertGraphBase; their purpose is to hold methods and data +// structures that are in common among their descendants. Only classes +// that are leaves in the following hierarchy tree are eligible for +// free-standing instantiation and use by clients. The parentheses +// around StarGraphBase and EbertGraphBase indicate that they should +// not normally be instantiated by clients: +// +// (StarGraphBase) | +// / \ | +// / \ | +// / \ | +// / \ | +// (EbertGraphBase) ForwardStaticGraph | +// / \ | +// / \ | +// EbertGraph ForwardEbertGraph | +// +// In the general EbertGraph case, the graph is represented with three +// arrays. +// Let n be the number of nodes and m be the number of arcs. +// Let i be an integer in [0..m-1], denoting the index of an arc. +// * head_[i] contains the end-node of arc i, +// * head_[-i-1] contains the start-node of arc i. +// Note that in two's-complement arithmetic, -i-1 = ~i. +// Consequently: +// * head_[~i] contains the end-node of the arc reverse to arc i, +// * head_[i] contains the start-node of the arc reverse to arc i. +// Note that if arc (u, v) is defined, then the data structure also stores +// (v, u). +// Arc ~i thus denotes the arc reverse to arc i. +// This is what makes this representation useful for undirected graphs and for +// implementing algorithms like bidirectional shortest paths. +// Also note that the representation handles multi-graphs. If several arcs +// going from node u to node v are added to the graph, they will be handled as +// separate arcs. +// +// Now, for an integer u in [0..n-1] denoting the index of a node: +// * first_incident_arc_[u] denotes the first arc in the adjacency list of u. +// * going from an arc i, the adjacency list can be traversed using +// j = next_adjacent_arc_[i]. +// +// The EbertGraph implementation has the following benefits: +// * It is able to handle both directed or undirected graphs. +// * Being based on indices, it is easily serializable. Only the contents +// of the head_ array need to be stored. Even so, serialization is +// currently not implemented. +// * The node indices and arc indices can be stored in 32 bits, while +// still allowing to go a bit further than the 4-gigabyte +// limitation (48 gigabytes for a pure graph, without capacities or +// costs.) +// * The representation can be recomputed if edges have been loaded from +// * The representation can be recomputed if edges have been loaded from +// external memory or if edges have been re-ordered. +// * The memory consumption is: 2 * m * sizeof(NodeIndexType) +// + 2 * m * sizeof(ArcIndexType) +// + n * sizeof(ArcIndexType) +// plus a small constant. +// +// The EbertGraph implementation differs from the implementation described in +// [Ebert 1987] in the following respects: +// * arcs are represented using an (i, ~i) approach, whereas Ebert used +// (i, -i). Indices for direct arcs thus start at 0, in a fashion that is +// compatible with the index numbering in C and C++. Note that we also tested +// a (2*i, 2*i+1) storage pattern, which did not show any speed benefit, and +// made the use of the API much more difficult. +// * because of this, the 'nil' values for nodes and arcs are not 0, as Ebert +// first described. The value for the 'nil' node is set to -1, while the +// value for the 'nil' arc is set to the smallest integer representable with +// ArcIndexSize bytes. +// * it is possible to add arcs to the graph, with AddArc, in a much simpler +// way than described by Ebert. +// * TODO(user) although it is already possible, using the +// GroupForwardArcsByFunctor method, to group all the outgoing (resp. +// incoming) arcs of a node, the iterator logic could still be improved to +// allow traversing the outgoing (resp. incoming) arcs in O(out_degree(node)) +// (resp. O(in_degree(node))) instead of O(degree(node)). +// * TODO(user) it is possible to implement arc deletion and garbage collection +// in an efficient (relatively) manner. For the time being we haven't seen an +// application for this. +// +// The ForwardEbertGraph representation is like the EbertGraph case described +// above, with the following modifications: +// * The part of the head_[] array with negative indices is absent. In its +// place is a pointer tail_ which, if assigned, points to an array of tail +// nodes indexed by (nonnegative) arc index. In typical usage tail_ is NULL +// and the memory for the tail nodes need not be allocated. +// * The array of arc tails can be allocated as needed and populated from the +// adjacency lists of the graph. +// * Representing only the forward star of each node implies that the graph +// cannot be serialized directly nor rebuilt from scratch from just the head_ +// array. Rebuilding from scratch requires constructing the array of arc +// tails from the adjacency lists first, and serialization can be done either +// by first constructing the array of arc tails from the adjacency lists, or +// by serializing directly from the adjacency lists. +// * The memory consumption is: m * sizeof(NodeIndexType) +// + m * sizeof(ArcIndexType) +// + n * sizeof(ArcIndexType) +// plus a small constant when the array of arc tails is absent. Allocating +// the arc tail array adds another m * sizeof(NodeIndexType). +// +// The ForwardStaticGraph representation is restricted yet farther +// than ForwardEbertGraph, with the benefit that it provides higher +// performance to those applications that can use it. +// * As with ForwardEbertGraph, the presence of the array of arc +// tails is optional. +// * The outgoing adjacency list for each node is stored in a +// contiguous segment of the head_[] array, obviating the +// next_adjacent_arc_ structure entirely and ensuring good locality +// of reference for applications that iterate over outgoing +// adjacency lists. +// * The memory consumption is: m * sizeof(NodeIndexType) +// + n * sizeof(ArcIndexType) +// plus a small constant when the array of arc tails is absent. Allocating +// the arc tail array adds another m * sizeof(NodeIndexType). + +#include +#include +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/stringprintf.h" +#include "ortools/base/join.h" +#include "ortools/util/permutation.h" +#include "ortools/util/zvector.h" + +namespace operations_research { + +// Forward declarations. +template +class EbertGraph; +template +class ForwardEbertGraph; +template +class ForwardStaticGraph; + +// Standard instantiation of ForwardEbertGraph (named 'ForwardStarGraph') of +// EbertGraph (named 'StarGraph'); and relevant type shortcuts. Unless their use +// cases prevent them from doing so, users are encouraged to use StarGraph or +// ForwardStarGraph according to whether or not they require reverse arcs to be +// represented explicitly. Along with either graph representation, the other +// type shortcuts here will often come in handy. +typedef int32 NodeIndex; +typedef int32 ArcIndex; +typedef int64 FlowQuantity; +typedef int64 CostValue; +typedef EbertGraph StarGraph; +typedef ForwardEbertGraph ForwardStarGraph; +typedef ForwardStaticGraph ForwardStarStaticGraph; +typedef ZVector NodeIndexArray; +typedef ZVector ArcIndexArray; +typedef ZVector QuantityArray; +typedef ZVector CostArray; + +template +class StarGraphBase { + public: + // The index of the 'nil' node in the graph. + static const NodeIndexType kNilNode; + + // The index of the 'nil' arc in the graph. + static const ArcIndexType kNilArc; + + // The index of the first node in the graph. + static const NodeIndexType kFirstNode; + + // The index of the first arc in the graph. + static const ArcIndexType kFirstArc; + + // The maximum possible number of nodes in the graph. (The maximum + // index is kMaxNumNodes-1, since indices start at 0. Unfortunately + // we waste a value representing this and the max_num_nodes_ member.) + static const NodeIndexType kMaxNumNodes; + + // The maximum possible number of arcs in the graph. (The maximum + // index is kMaxNumArcs-1, since indices start at 0. Unfortunately + // we waste a value representing this and the max_num_arcs_ member.) + static const ArcIndexType kMaxNumArcs; + // Returns the number of nodes in the graph. + NodeIndexType num_nodes() const { return num_nodes_; } + + // Returns the number of original arcs in the graph + // (The ones with positive indices.) + ArcIndexType num_arcs() const { return num_arcs_; } + + // Returns one more than the largest index of an extant node, + // meaning a node that is mentioned as the head or tail of some arc + // in the graph. To be used as a helper when clients need to + // dimension or iterate over arrays of node annotation information. + NodeIndexType end_node_index() const { return kFirstNode + num_nodes_; } + + // Returns one more than the largest index of an extant direct + // arc. To be used as a helper when clients need to dimension or + // iterate over arrays of arc annotation information. + ArcIndexType end_arc_index() const { return kFirstArc + num_arcs_; } + + // Returns the maximum possible number of nodes in the graph. + NodeIndexType max_num_nodes() const { return max_num_nodes_; } + + // Returns the maximum possible number of original arcs in the graph. + // (The ones with positive indices.) + ArcIndexType max_num_arcs() const { return max_num_arcs_; } + + // Returns one more than the largest valid index of a node. To be + // used as a helper when clients need to dimension or iterate over + // arrays of node annotation information. + NodeIndexType max_end_node_index() const { + return kFirstNode + max_num_nodes_; + } + + // Returns one more than the largest valid index of a direct arc. To + // be used as a helper when clients need to dimension or iterate + // over arrays of arc annotation information. + ArcIndexType max_end_arc_index() const { return kFirstArc + max_num_arcs_; } + + // Utility function to check that a node index is within the bounds AND + // different from kNilNode. + // Returns true if node is in the range [kFirstNode .. max_num_nodes_). + // It is exported so that users of the DerivedGraph class can use it. + // To be used in a DCHECK; also used internally to validate + // arguments passed to our methods from clients (e.g., AddArc()). + bool IsNodeValid(NodeIndexType node) const { + return node >= kFirstNode && node < max_num_nodes_; + } + + // Returns the first arc going from tail to head, if it exists, or kNilArc + // if such an arc does not exist. + ArcIndexType LookUpArc(const NodeIndexType tail, + const NodeIndexType head) const { + for (ArcIndexType arc = FirstOutgoingArc(tail); arc != kNilArc; + arc = ThisAsDerived()->NextOutgoingArc(tail, arc)) { + if (Head(arc) == head) { + return arc; + } + } + return kNilArc; + } + + // Returns the head or end-node of arc. + NodeIndexType Head(const ArcIndexType arc) const { + DCHECK(ThisAsDerived()->CheckArcValidity(arc)); + return head_[arc]; + } + + std::string NodeDebugString(const NodeIndexType node) const { + if (node == kNilNode) { + return "NilNode"; + } else { + return StrCat(static_cast(node)); + } + } + + std::string ArcDebugString(const ArcIndexType arc) const { + if (arc == kNilArc) { + return "NilArc"; + } else { + return StrCat(static_cast(arc)); + } + } + +#if !defined(SWIG) + // Iterator class for traversing all the nodes in the graph. + class NodeIterator { + public: + explicit NodeIterator(const DerivedGraph& graph) + : graph_(graph), head_(graph_.StartNode(kFirstNode)) {} + + // Returns true unless all the nodes have been traversed. + bool Ok() const { return head_ != kNilNode; } + + // Advances the current node index. + void Next() { head_ = graph_.NextNode(head_); } + + // Returns the index of the node currently pointed to by the iterator. + NodeIndexType Index() const { return head_; } + + private: + // A reference to the current DerivedGraph considered. + const DerivedGraph& graph_; + + // The index of the current node considered. + NodeIndexType head_; + }; + + // Iterator class for traversing the arcs in the graph. + class ArcIterator { + public: + explicit ArcIterator(const DerivedGraph& graph) + : graph_(graph), arc_(graph_.StartArc(kFirstArc)) {} + + // Returns true unless all the arcs have been traversed. + bool Ok() const { return arc_ != kNilArc; } + + // Advances the current arc index. + void Next() { arc_ = graph_.NextArc(arc_); } + + // Returns the index of the arc currently pointed to by the iterator. + ArcIndexType Index() const { return arc_; } + + private: + // A reference to the current DerivedGraph considered. + const DerivedGraph& graph_; + + // The index of the current arc considered. + ArcIndexType arc_; + }; + + // Iterator class for traversing the outgoing arcs associated to a given node. + class OutgoingArcIterator { + public: + OutgoingArcIterator(const DerivedGraph& graph, NodeIndexType node) + : graph_(graph), + node_(graph_.StartNode(node)), + arc_(graph_.StartArc(graph_.FirstOutgoingArc(node))) { + DCHECK(CheckInvariant()); + } + + // This constructor takes an arc as extra argument and makes the iterator + // start at arc. + OutgoingArcIterator(const DerivedGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(graph), + node_(graph_.StartNode(node)), + arc_(graph_.StartArc(arc)) { + DCHECK(CheckInvariant()); + } + + // Can only assign from an iterator on the same graph. + void operator=(const OutgoingArcIterator& iterator) { + DCHECK(&iterator.graph_ == &graph_); + node_ = iterator.node_; + arc_ = iterator.arc_; + } + + // Returns true unless all the outgoing arcs have been traversed. + bool Ok() const { return arc_ != kNilArc; } + + // Advances the current outgoing arc index. + void Next() { + arc_ = graph_.NextOutgoingArc(node_, arc_); + DCHECK(CheckInvariant()); + } + + // Returns the index of the arc currently pointed to by the iterator. + ArcIndexType Index() const { return arc_; } + + private: + // Returns true if the invariant for the iterator is verified. + // To be used in a DCHECK. + bool CheckInvariant() const { + if (arc_ == kNilArc) { + return true; // This occurs when the iterator has reached the end. + } + DCHECK(graph_.IsOutgoing(arc_, node_)); + return true; + } + + // A reference to the current DerivedGraph considered. + const DerivedGraph& graph_; + + // The index of the node on which arcs are iterated. + NodeIndexType node_; + + // The index of the current arc considered. + ArcIndexType arc_; + }; +#endif // SWIG + + protected: + StarGraphBase() + : max_num_nodes_(0), + max_num_arcs_(0), + num_nodes_(0), + num_arcs_(0), + first_incident_arc_() {} + + ~StarGraphBase() {} + + // Returns kNilNode if the graph has no nodes or node if it has at least one + // node. Useful for initializing iterators correctly in the case of empty + // graphs. + NodeIndexType StartNode(NodeIndexType node) const { + return num_nodes_ == 0 ? kNilNode : node; + } + + // Returns kNilArc if the graph has no arcs arc if it has at least one arc. + // Useful for initializing iterators correctly in the case of empty graphs. + ArcIndexType StartArc(ArcIndexType arc) const { + return num_arcs_ == 0 ? kNilArc : arc; + } + + // Returns the node following the argument in the graph. + // Returns kNilNode (= end) if the range of nodes has been exhausted. + // It is called by NodeIterator::Next() and as such does not expect to be + // passed an argument equal to kNilNode. + // This is why the return line is simplified from + // return (node == kNilNode || next_node >= num_nodes_) + // ? kNilNode : next_node; + // to + // return next_node < num_nodes_ ? next_node : kNilNode; + NodeIndexType NextNode(const NodeIndexType node) const { + DCHECK(IsNodeValid(node)); + const NodeIndexType next_node = node + 1; + return next_node < num_nodes_ ? next_node : kNilNode; + } + + // Returns the arc following the argument in the graph. + // Returns kNilArc (= end) if the range of arcs has been exhausted. + // It is called by ArcIterator::Next() and as such does not expect to be + // passed an argument equal to kNilArc. + // This is why the return line is simplified from + // return ( arc == kNilArc || next_arc >= num_arcs_) ? kNilArc : next_arc; + // to + // return next_arc < num_arcs_ ? next_arc : kNilArc; + ArcIndexType NextArc(const ArcIndexType arc) const { + DCHECK(ThisAsDerived()->CheckArcValidity(arc)); + const ArcIndexType next_arc = arc + 1; + return next_arc < num_arcs_ ? next_arc : kNilArc; + } + + // Returns the first outgoing arc for node. + ArcIndexType FirstOutgoingArc(const NodeIndexType node) const { + DCHECK(IsNodeValid(node)); + return ThisAsDerived()->FindNextOutgoingArc( + ThisAsDerived()->FirstOutgoingOrOppositeIncomingArc(node)); + } + + // The maximum number of nodes that the graph can hold. + NodeIndexType max_num_nodes_; + + // The maximum number of arcs that the graph can hold. + ArcIndexType max_num_arcs_; + + // The maximum index of the node currently held by the graph. + NodeIndexType num_nodes_; + + // The current number of arcs held by the graph. + ArcIndexType num_arcs_; + + // Array of node indices. head_[i] contains the head node of arc i. + ZVector head_; + + // Array of arc indices. first_incident_arc_[i] contains the first arc + // incident to node i. + ZVector first_incident_arc_; + + private: + // Shorthand: returns a const DerivedGraph*-typed version of our + // "this" pointer. + inline const DerivedGraph* ThisAsDerived() const { + return static_cast(this); + } + + // Shorthand: returns a DerivedGraph*-typed version of our "this" + // pointer. + inline DerivedGraph* ThisAsDerived() { + return static_cast(this); + } +}; + +template +class PermutationIndexComparisonByArcHead { + public: + explicit PermutationIndexComparisonByArcHead( + const ZVector& head) + : head_(head) {} + + bool operator()(ArcIndexType a, ArcIndexType b) const { + return head_[a] < head_[b]; + } + + private: + const ZVector& head_; +}; + +template +class ForwardStaticGraph + : public StarGraphBase > { + typedef StarGraphBase > Base; + friend class StarGraphBase >; + + using Base::ArcDebugString; + using Base::NodeDebugString; + + using Base::first_incident_arc_; + using Base::head_; + using Base::max_num_arcs_; + using Base::max_num_nodes_; + using Base::num_arcs_; + using Base::num_nodes_; + + public: +#if !defined(SWIG) + using Base::end_arc_index; + using Base::Head; + using Base::IsNodeValid; + + using Base::kFirstArc; + using Base::kFirstNode; + using Base::kNilArc; +#endif // SWIG + + typedef NodeIndexType NodeIndex; + typedef ArcIndexType ArcIndex; + +// TODO(user): Configure SWIG to handle the +// CycleHandlerForAnnotatedArcs class. +#if !defined(SWIG) + class CycleHandlerForAnnotatedArcs + : public ArrayIndexCycleHandler { + typedef ArrayIndexCycleHandler Base; + + public: + CycleHandlerForAnnotatedArcs( + PermutationCycleHandler* annotation_handler, + NodeIndexType* data) + : ArrayIndexCycleHandler(&data[kFirstArc]), + annotation_handler_(annotation_handler) {} + + void SetTempFromIndex(ArcIndexType source) override { + Base::SetTempFromIndex(source); + annotation_handler_->SetTempFromIndex(source); + } + + void SetIndexFromIndex(ArcIndexType source, + ArcIndexType destination) const override { + Base::SetIndexFromIndex(source, destination); + annotation_handler_->SetIndexFromIndex(source, destination); + } + + void SetIndexFromTemp(ArcIndexType destination) const override { + Base::SetIndexFromTemp(destination); + annotation_handler_->SetIndexFromTemp(destination); + } + + private: + PermutationCycleHandler* annotation_handler_; + + DISALLOW_COPY_AND_ASSIGN(CycleHandlerForAnnotatedArcs); + }; +#endif // SWIG + + // Constructor for use by GraphBuilderFromArcs instances and direct + // clients that want to materialize a graph in one step. + // Materializing all at once is the only choice available with a + // static graph. + // + // Args: + // sort_arcs_by_head: determines whether arcs incident to each tail + // node are sorted by head node. + // client_cycle_handler: if non-NULL, mediates the permutation of + // arbitrary annotation data belonging to the client according + // to the permutation applied to the arcs in forming the + // graph. Two permutations may be composed to form the final one + // that affects the arcs. First, the arcs are always permuted to + // group them by tail node because ForwardStaticGraph requires + // this. Second, if each node's outgoing arcs are sorted by head + // node (according to sort_arcs_by_head), that sorting implies + // an additional permutation on the arcs. + ForwardStaticGraph( + const NodeIndexType num_nodes, const ArcIndexType num_arcs, + const bool sort_arcs_by_head, + std::vector >* client_input_arcs, + // TODO(user): For some reason, SWIG breaks if the + // operations_research namespace is not explicit in the + // following argument declaration. + operations_research::PermutationCycleHandler* const + client_cycle_handler) { + max_num_arcs_ = num_arcs; + num_arcs_ = num_arcs; + max_num_nodes_ = num_nodes; + // A more convenient name for a parameter required by style to be + // a pointer, because we modify its referent. + std::vector >& input_arcs = + *client_input_arcs; + + // We coopt the first_incident_arc_ array as a node-indexed vector + // used for two purposes related to degree before setting up its + // final values. First, it counts the out-degree of each + // node. Second, it is reused to count the number of arcs outgoing + // from each node that have already been put in place from the + // given input_arcs. We reserve an extra entry as a sentinel at + // the end. + first_incident_arc_.Reserve(kFirstNode, kFirstNode + num_nodes); + first_incident_arc_.SetAll(0); + for (ArcIndexType arc = kFirstArc; arc < kFirstArc + num_arcs; ++arc) { + first_incident_arc_[kFirstNode + input_arcs[arc].first] += 1; + // Take this opportunity to see how many nodes are really + // mentioned in the arc list. + num_nodes_ = std::max( + num_nodes_, static_cast(input_arcs[arc].first + 1)); + num_nodes_ = std::max( + num_nodes_, static_cast(input_arcs[arc].second + 1)); + } + ArcIndexType next_arc = kFirstArc; + for (NodeIndexType node = 0; node < num_nodes; ++node) { + ArcIndexType degree = first_incident_arc_[kFirstNode + node]; + first_incident_arc_[kFirstNode + node] = next_arc; + next_arc += degree; + } + DCHECK_EQ(num_arcs, next_arc); + head_.Reserve(kFirstArc, kFirstArc + num_arcs - 1); + std::unique_ptr arc_permutation; + if (client_cycle_handler != nullptr) { + arc_permutation.reset(new ArcIndexType[end_arc_index()]); + for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) { + NodeIndexType tail = input_arcs[input_arc].first; + NodeIndexType head = input_arcs[input_arc].second; + ArcIndexType arc = first_incident_arc_[kFirstNode + tail]; + // The head_ entry will get permuted into the right place + // later. + head_[kFirstArc + input_arc] = kFirstNode + head; + arc_permutation[kFirstArc + arc] = input_arc; + first_incident_arc_[kFirstNode + tail] += 1; + } + } else { + if (sizeof(input_arcs[0].first) >= sizeof(first_incident_arc_[0])) { + // We reuse the input_arcs[].first entries to hold our + // mapping to the head_ array. This allows us to spread out + // cache badness. + for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) { + NodeIndexType tail = input_arcs[input_arc].first; + ArcIndexType arc = first_incident_arc_[kFirstNode + tail]; + first_incident_arc_[kFirstNode + tail] = arc + 1; + input_arcs[input_arc].first = static_cast(arc); + } + for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) { + ArcIndexType arc = + static_cast(input_arcs[input_arc].first); + NodeIndexType head = input_arcs[input_arc].second; + head_[kFirstArc + arc] = kFirstNode + head; + } + } else { + // We cannot reuse the input_arcs[].first entries so we map to + // the head_ array in a single loop. + for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) { + NodeIndexType tail = input_arcs[input_arc].first; + NodeIndexType head = input_arcs[input_arc].second; + ArcIndexType arc = first_incident_arc_[kFirstNode + tail]; + first_incident_arc_[kFirstNode + tail] = arc + 1; + head_[kFirstArc + arc] = kFirstNode + head; + } + } + } + // Shift the entries in first_incident_arc_ to compensate for the + // counting each one has done through its incident arcs. Note that + // there is a special sentry element at the end of + // first_incident_arc_. + for (NodeIndexType node = kFirstNode + num_nodes; node > /* kFirstNode */ 0; + --node) { + first_incident_arc_[node] = first_incident_arc_[node - 1]; + } + first_incident_arc_[kFirstNode] = kFirstArc; + if (sort_arcs_by_head) { + ArcIndexType begin = first_incident_arc_[kFirstNode]; + if (client_cycle_handler != nullptr) { + for (NodeIndexType node = 0; node < num_nodes; ++node) { + ArcIndexType end = first_incident_arc_[node + 1]; + std::sort( + &arc_permutation[begin], &arc_permutation[end], + PermutationIndexComparisonByArcHead( + head_)); + begin = end; + } + } else { + for (NodeIndexType node = 0; node < num_nodes; ++node) { + ArcIndexType end = first_incident_arc_[node + 1]; + // The second argument in the following has a strange index + // expression because ZVector claims that no index is valid + // unless it refers to an element in the vector. In particular + // an index one past the end is invalid. + ArcIndexType begin_index = (begin < num_arcs ? begin : begin - 1); + ArcIndexType begin_offset = (begin < num_arcs ? 0 : 1); + ArcIndexType end_index = (end > 0 ? end - 1 : end); + ArcIndexType end_offset = (end > 0 ? 1 : 0); + std::sort(&head_[begin_index] + begin_offset, + &head_[end_index] + end_offset); + begin = end; + } + } + } + if (client_cycle_handler != nullptr && num_arcs > 0) { + // Apply the computed permutation if we haven't already. + CycleHandlerForAnnotatedArcs handler_for_constructor( + client_cycle_handler, &head_[kFirstArc] - kFirstArc); + // We use a permutation cycle handler to place the head array + // indices and permute the client's arc annotation data along + // with them. + PermutationApplier permutation(&handler_for_constructor); + permutation.Apply(&arc_permutation[0], kFirstArc, end_arc_index()); + } + } + + // Returns the tail or start-node of arc. + NodeIndexType Tail(const ArcIndexType arc) const { + DCHECK(CheckArcValidity(arc)); + DCHECK(CheckTailIndexValidity(arc)); + return (*tail_)[arc]; + } + + // Returns true if arc is incoming to node. + bool IsIncoming(ArcIndexType arc, NodeIndexType node) const { + return Head(arc) == node; + } + + // Utility function to check that an arc index is within the bounds. + // It is exported so that users of the ForwardStaticGraph class can use it. + // To be used in a DCHECK. + bool CheckArcBounds(const ArcIndexType arc) const { + return ((arc == kNilArc) || (arc >= kFirstArc && arc < max_num_arcs_)); + } + + // Utility function to check that an arc index is within the bounds AND + // different from kNilArc. + // It is exported so that users of the ForwardStaticGraph class can use it. + // To be used in a DCHECK. + bool CheckArcValidity(const ArcIndexType arc) const { + return ((arc != kNilArc) && (arc >= kFirstArc && arc < max_num_arcs_)); + } + + // Returns true if arc is a valid index into the (*tail_) array. + bool CheckTailIndexValidity(const ArcIndexType arc) const { + return ((tail_ != nullptr) && (arc >= kFirstArc) && + (arc <= tail_->max_index())); + } + + ArcIndexType NextOutgoingArc(const NodeIndexType node, + ArcIndexType arc) const { + DCHECK(IsNodeValid(node)); + DCHECK(CheckArcValidity(arc)); + ++arc; + if (arc < first_incident_arc_[node + 1]) { + return arc; + } else { + return kNilArc; + } + } + + // Returns a debug std::string containing all the information contained in the + // data structure in raw form. + std::string DebugString() const { + std::string result = "Arcs:(node) :\n"; + for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) { + result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) + + ")\n"; + } + result += "Node:First arc :\n"; + for (NodeIndexType node = kFirstNode; node <= num_nodes_; ++node) { + result += " " + NodeDebugString(node) + ":" + + ArcDebugString(first_incident_arc_[node]) + "\n"; + } + return result; + } + + bool BuildTailArray() { + // If (*tail_) is already allocated, we have the invariant that + // its contents are canonical, so we do not need to do anything + // here in that case except return true. + if (tail_ == nullptr) { + if (!RepresentationClean()) { + // We have been asked to build the (*tail_) array, but we have + // no valid information from which to build it. The graph is + // in an unrecoverable, inconsistent state. + return false; + } + // Reallocate (*tail_) and rebuild its contents from the + // adjacency lists. + tail_.reset(new ZVector); + tail_->Reserve(kFirstArc, max_num_arcs_ - 1); + typename Base::NodeIterator node_it(*this); + for (; node_it.Ok(); node_it.Next()) { + NodeIndexType node = node_it.Index(); + typename Base::OutgoingArcIterator arc_it(*this, node); + for (; arc_it.Ok(); arc_it.Next()) { + (*tail_)[arc_it.Index()] = node; + } + } + } + DCHECK(TailArrayComplete()); + return true; + } + + void ReleaseTailArray() { tail_.reset(nullptr); } + + // To be used in a DCHECK(). + bool TailArrayComplete() const { + CHECK_NOTNULL(tail_); + for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) { + CHECK(CheckTailIndexValidity(arc)); + CHECK(IsNodeValid((*tail_)[arc])); + } + return true; + } + + private: + bool IsDirect() const { return true; } + bool RepresentationClean() const { return true; } + bool IsOutgoing(const NodeIndexType node, + const ArcIndexType unused_arc) const { + return true; + } + + // Returns the first arc in node's incidence list. + ArcIndexType FirstOutgoingOrOppositeIncomingArc(NodeIndexType node) const { + DCHECK(RepresentationClean()); + DCHECK(IsNodeValid(node)); + ArcIndexType result = first_incident_arc_[node]; + return ((result != first_incident_arc_[node + 1]) ? result : kNilArc); + } + + // Utility method that finds the next outgoing arc. + ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const { + DCHECK(CheckArcBounds(arc)); + return arc; + } + + // Array of node indices, not always present. (*tail_)[i] contains + // the tail node of arc i. This array is not needed for normal graph + // traversal operations, but is used in optimizing the graph's + // layout so arcs are grouped by tail node, and can be used in one + // approach to serializing the graph. + // + // Invariants: At any time when we are not executing a method of + // this class, either tail_ == NULL or the tail_ array's contents + // are kept canonical. If tail_ != NULL, any method that modifies + // adjacency lists must also ensure (*tail_) is modified + // correspondingly. The converse does not hold: Modifications to + // (*tail_) are allowed without updating the adjacency lists. If + // such modifications take place, representation_clean_ must be set + // to false, of course, to indicate that the adjacency lists are no + // longer current. + std::unique_ptr > tail_; +}; + +// The index of the 'nil' node in the graph. +template +const NodeIndexType + StarGraphBase::kNilNode = -1; + +// The index of the 'nil' arc in the graph. +template +const ArcIndexType + StarGraphBase::kNilArc = + std::numeric_limits::min(); + +// The index of the first node in the graph. +template +const NodeIndexType + StarGraphBase::kFirstNode = 0; + +// The index of the first arc in the graph. +template +const ArcIndexType + StarGraphBase::kFirstArc = 0; + +// The maximum possible node index in the graph. +template +const NodeIndexType + StarGraphBase::kMaxNumNodes = + std::numeric_limits::max(); + +// The maximum possible number of arcs in the graph. +// (The maximum index is kMaxNumArcs-1, since indices start at 0.) +template +const ArcIndexType + StarGraphBase::kMaxNumArcs = + std::numeric_limits::max(); + +// A template for the base class that holds the functionality that exists in +// common between the EbertGraph<> template and the ForwardEbertGraph<> +// template. +// +// This template is for internal use only, and this is enforced by making all +// constructors for this class template protected. Clients should use one of the +// two derived-class templates. Most clients will not even use those directly, +// but will use the StarGraph and ForwardStarGraph typenames declared above. +// +// The DerivedGraph template argument must be the type of the class (typically +// itself built from a template) that: +// 1. implements the full interface expected for either ForwardEbertGraph or +// EbertGraph, and +// 2. inherits from an instance of this template. +// The base class needs access to some members of the derived class such as, for +// example, NextOutgoingArc(), and it gets this access via the DerivedGraph +// template argument. +template +class EbertGraphBase + : public StarGraphBase { + typedef StarGraphBase Base; + friend class StarGraphBase; + + protected: + using Base::first_incident_arc_; + using Base::head_; + using Base::max_num_arcs_; + using Base::max_num_nodes_; + using Base::num_arcs_; + using Base::num_nodes_; + + public: +#if !SWIG + using Base::end_arc_index; + using Base::IsNodeValid; + + using Base::kFirstArc; + using Base::kFirstNode; + using Base::kMaxNumArcs; + using Base::kMaxNumNodes; + using Base::kNilArc; + using Base::kNilNode; +#endif // SWIG + + // Reserves memory needed for max_num_nodes nodes and max_num_arcs arcs. + // Returns false if the parameters passed are not OK. + // It can be used to enlarge the graph, but does not shrink memory + // if called with smaller values. + bool Reserve(NodeIndexType new_max_num_nodes, ArcIndexType new_max_num_arcs) { + if (new_max_num_nodes < 0 || new_max_num_nodes > kMaxNumNodes) { + return false; + } + if (new_max_num_arcs < 0 || new_max_num_arcs > kMaxNumArcs) { + return false; + } + first_incident_arc_.Reserve(kFirstNode, new_max_num_nodes - 1); + for (NodeIndexType node = max_num_nodes_; + node <= first_incident_arc_.max_index(); ++node) { + first_incident_arc_.Set(node, kNilArc); + } + ThisAsDerived()->ReserveInternal(new_max_num_nodes, new_max_num_arcs); + max_num_nodes_ = new_max_num_nodes; + max_num_arcs_ = new_max_num_arcs; + return true; + } + + // Adds an arc to the graph and returns its index. + // Returns kNilArc if the arc could not be added. + // Note that for a given pair (tail, head) AddArc does not overwrite an + // already-existing arc between tail and head: Another arc is created + // instead. This makes it possible to handle multi-graphs. + ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head) { + if (num_arcs_ >= max_num_arcs_ || !IsNodeValid(tail) || + !IsNodeValid(head)) { + return kNilArc; + } + if (tail + 1 > num_nodes_) { + num_nodes_ = tail + 1; // max does not work on int16. + } + if (head + 1 > num_nodes_) { + num_nodes_ = head + 1; + } + ArcIndexType arc = num_arcs_; + ++num_arcs_; + ThisAsDerived()->RecordArc(arc, tail, head); + return arc; + } + +// TODO(user): Configure SWIG to handle the GroupForwardArcsByFunctor +// member template and the CycleHandlerForAnnotatedArcs class. +#if !SWIG + template + void GroupForwardArcsByFunctor( + const ArcIndexTypeStrictWeakOrderingFunctor& compare, + PermutationCycleHandler* annotation_handler) { + std::unique_ptr arc_permutation( + new ArcIndexType[end_arc_index()]); + + // Determine the permutation that groups arcs by their tail nodes. + for (ArcIndexType i = 0; i < end_arc_index(); ++i) { + // Start with the identity permutation. + arc_permutation[i] = i; + } + std::sort(&arc_permutation[kFirstArc], &arc_permutation[end_arc_index()], + compare); + + // Now we actually permute the head_ array and the + // scaled_arc_cost_ array according to the sorting permutation. + CycleHandlerForAnnotatedArcs cycle_handler(annotation_handler, + ThisAsDerived()); + PermutationApplier permutation(&cycle_handler); + permutation.Apply(&arc_permutation[0], kFirstArc, end_arc_index()); + + // Finally, rebuild the graph from its permuted head_ array. + ThisAsDerived()->BuildRepresentation(); + } + + class CycleHandlerForAnnotatedArcs + : public PermutationCycleHandler { + public: + CycleHandlerForAnnotatedArcs( + PermutationCycleHandler* annotation_handler, + DerivedGraph* graph) + : annotation_handler_(annotation_handler), + graph_(graph), + head_temp_(kNilNode), + tail_temp_(kNilNode) {} + + void SetTempFromIndex(ArcIndexType source) override { + if (annotation_handler_ != nullptr) { + annotation_handler_->SetTempFromIndex(source); + } + head_temp_ = graph_->Head(source); + tail_temp_ = graph_->Tail(source); + } + + void SetIndexFromIndex(ArcIndexType source, + ArcIndexType destination) const override { + if (annotation_handler_ != nullptr) { + annotation_handler_->SetIndexFromIndex(source, destination); + } + graph_->SetHead(destination, graph_->Head(source)); + graph_->SetTail(destination, graph_->Tail(source)); + } + + void SetIndexFromTemp(ArcIndexType destination) const override { + if (annotation_handler_ != nullptr) { + annotation_handler_->SetIndexFromTemp(destination); + } + graph_->SetHead(destination, head_temp_); + graph_->SetTail(destination, tail_temp_); + } + + // Since we are free to destroy the permutation array we use the + // kNilArc value to mark entries in the array that have been + // processed already. There is no need to be able to recover the + // original permutation array entries once they have been seen. + void SetSeen(ArcIndexType* permutation_element) const override { + *permutation_element = kNilArc; + } + + bool Unseen(ArcIndexType permutation_element) const override { + return permutation_element != kNilArc; + } + + ~CycleHandlerForAnnotatedArcs() override {} + + private: + PermutationCycleHandler* annotation_handler_; + DerivedGraph* graph_; + NodeIndexType head_temp_; + NodeIndexType tail_temp_; + + DISALLOW_COPY_AND_ASSIGN(CycleHandlerForAnnotatedArcs); + }; +#endif // SWIG + + protected: + EbertGraphBase() : next_adjacent_arc_(), representation_clean_(true) {} + + ~EbertGraphBase() {} + + void Initialize(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) { + if (!Reserve(max_num_nodes, max_num_arcs)) { + LOG(DFATAL) << "Could not reserve memory for " + << static_cast(max_num_nodes) << " nodes and " + << static_cast(max_num_arcs) << " arcs."; + } + first_incident_arc_.SetAll(kNilArc); + ThisAsDerived()->InitializeInternal(max_num_nodes, max_num_arcs); + } + + // Returns the first arc in node's incidence list. + ArcIndexType FirstOutgoingOrOppositeIncomingArc( + const NodeIndexType node) const { + DCHECK(representation_clean_); + DCHECK(IsNodeValid(node)); + return first_incident_arc_[node]; + } + + // Returns the next arc following the passed argument in its adjacency list. + ArcIndexType NextAdjacentArc(const ArcIndexType arc) const { + DCHECK(representation_clean_); + DCHECK(ThisAsDerived()->CheckArcValidity(arc)); + return next_adjacent_arc_[arc]; + } + + // Returns the outgoing arc following the argument in the adjacency list. + ArcIndexType NextOutgoingArc(const NodeIndexType unused_node, + const ArcIndexType arc) const { + DCHECK(ThisAsDerived()->CheckArcValidity(arc)); + DCHECK(ThisAsDerived()->IsDirect(arc)); + return ThisAsDerived()->FindNextOutgoingArc(NextAdjacentArc(arc)); + } + + // Array of next indices. + // next_adjacent_arc_[i] contains the next arc in the adjacency list of arc i. + ZVector next_adjacent_arc_; + + // Flag to indicate that BuildRepresentation() needs to be called + // before the adjacency lists are examined. Only for DCHECK in debug + // builds. + bool representation_clean_; + + private: + // Shorthand: returns a const DerivedGraph*-typed version of our + // "this" pointer. + inline const DerivedGraph* ThisAsDerived() const { + return static_cast(this); + } + + // Shorthand: returns a DerivedGraph*-typed version of our "this" + // pointer. + inline DerivedGraph* ThisAsDerived() { + return static_cast(this); + } + + void InitializeInternal(NodeIndexType max_num_nodes, + ArcIndexType max_num_arcs) { + next_adjacent_arc_.SetAll(kNilArc); + } + + bool RepresentationClean() const { return representation_clean_; } + + // Using the SetHead() method implies that the BuildRepresentation() + // method must be called to restore consistency before the graph is + // used. + void SetHead(const ArcIndexType arc, const NodeIndexType head) { + representation_clean_ = false; + head_.Set(arc, head); + } +}; + +// Most users should only use StarGraph, which is EbertGraph, and +// other type shortcuts; see the bottom of this file. +template +class EbertGraph + : public EbertGraphBase > { + typedef EbertGraphBase > Base; + friend class EbertGraphBase >; + friend class StarGraphBase >; + + using Base::ArcDebugString; + using Base::FirstOutgoingOrOppositeIncomingArc; + using Base::Initialize; + using Base::NextAdjacentArc; + using Base::NodeDebugString; + + using Base::first_incident_arc_; + using Base::head_; + using Base::max_num_arcs_; + using Base::max_num_nodes_; + using Base::next_adjacent_arc_; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::representation_clean_; + + public: +#if !SWIG + using Base::Head; + using Base::IsNodeValid; + + using Base::kFirstArc; + using Base::kFirstNode; + using Base::kNilArc; + using Base::kNilNode; +#endif // SWIG + + typedef NodeIndexType NodeIndex; + typedef ArcIndexType ArcIndex; + + EbertGraph() {} + + EbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) { + Initialize(max_num_nodes, max_num_arcs); + } + + ~EbertGraph() {} + +#if !SWIG + // Iterator class for traversing the arcs incident to a given node in the + // graph. + class OutgoingOrOppositeIncomingArcIterator { + public: + OutgoingOrOppositeIncomingArcIterator(const EbertGraph& graph, + NodeIndexType node) + : graph_(graph), + node_(graph_.StartNode(node)), + arc_(graph_.StartArc( + graph_.FirstOutgoingOrOppositeIncomingArc(node))) { + DCHECK(CheckInvariant()); + } + + // This constructor takes an arc as extra argument and makes the iterator + // start at arc. + OutgoingOrOppositeIncomingArcIterator(const EbertGraph& graph, + NodeIndexType node, ArcIndexType arc) + : graph_(graph), + node_(graph_.StartNode(node)), + arc_(graph_.StartArc(arc)) { + DCHECK(CheckInvariant()); + } + + // Can only assign from an iterator on the same graph. + void operator=(const OutgoingOrOppositeIncomingArcIterator& iterator) { + DCHECK(&iterator.graph_ == &graph_); + node_ = iterator.node_; + arc_ = iterator.arc_; + } + + // Returns true unless all the adjancent arcs have been traversed. + bool Ok() const { return arc_ != kNilArc; } + + // Advances the current adjacent arc index. + void Next() { + arc_ = graph_.NextAdjacentArc(arc_); + DCHECK(CheckInvariant()); + } + + // Returns the index of the arc currently pointed to by the iterator. + ArcIndexType Index() const { return arc_; } + + private: + // Returns true if the invariant for the iterator is verified. + // To be used in a DCHECK. + bool CheckInvariant() const { + if (arc_ == kNilArc) { + return true; // This occurs when the iterator has reached the end. + } + DCHECK(graph_.IsOutgoingOrOppositeIncoming(arc_, node_)); + return true; + } + // A reference to the current EbertGraph considered. + const EbertGraph& graph_; + + // The index of the node on which arcs are iterated. + NodeIndexType node_; + + // The index of the current arc considered. + ArcIndexType arc_; + }; + + // Iterator class for traversing the incoming arcs associated to a given node. + class IncomingArcIterator { + public: + IncomingArcIterator(const EbertGraph& graph, NodeIndexType node) + : graph_(graph), + node_(graph_.StartNode(node)), + arc_(graph_.StartArc(graph_.FirstIncomingArc(node))) { + DCHECK(CheckInvariant()); + } + + // This constructor takes an arc as extra argument and makes the iterator + // start at arc. + IncomingArcIterator(const EbertGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(graph), + node_(graph_.StartNode(node)), + arc_(arc == kNilArc ? kNilArc + : graph_.StartArc(graph_.Opposite(arc))) { + DCHECK(CheckInvariant()); + } + + // Can only assign from an iterator on the same graph. + void operator=(const IncomingArcIterator& iterator) { + DCHECK(&iterator.graph_ == &graph_); + node_ = iterator.node_; + arc_ = iterator.arc_; + } + + // Returns true unless all the incoming arcs have been traversed. + bool Ok() const { return arc_ != kNilArc; } + + // Advances the current incoming arc index. + void Next() { + arc_ = graph_.NextIncomingArc(arc_); + DCHECK(CheckInvariant()); + } + + // Returns the index of the arc currently pointed to by the iterator. + ArcIndexType Index() const { + return arc_ == kNilArc ? kNilArc : graph_.Opposite(arc_); + } + + private: + // Returns true if the invariant for the iterator is verified. + // To be used in a DCHECK. + bool CheckInvariant() const { + if (arc_ == kNilArc) { + return true; // This occurs when the iterator has reached the end. + } + DCHECK(graph_.IsIncoming(Index(), node_)); + return true; + } + // A reference to the current EbertGraph considered. + const EbertGraph& graph_; + + // The index of the node on which arcs are iterated. + NodeIndexType node_; + + // The index of the current arc considered. + ArcIndexType arc_; + }; +#endif // SWIG + + // Utility function to check that an arc index is within the bounds. + // It is exported so that users of the EbertGraph class can use it. + // To be used in a DCHECK. + bool CheckArcBounds(const ArcIndexType arc) const { + return (arc == kNilArc) || (arc >= -max_num_arcs_ && arc < max_num_arcs_); + } + + // Utility function to check that an arc index is within the bounds AND + // different from kNilArc. + // It is exported so that users of the EbertGraph class can use it. + // To be used in a DCHECK. + bool CheckArcValidity(const ArcIndexType arc) const { + return (arc != kNilArc) && (arc >= -max_num_arcs_ && arc < max_num_arcs_); + } + + // Returns the tail or start-node of arc. + NodeIndexType Tail(const ArcIndexType arc) const { + DCHECK(CheckArcValidity(arc)); + return head_[Opposite(arc)]; + } + + // Returns the tail or start-node of arc if it is positive + // (i.e. it is taken in the direction it was entered in the graph), + // and the head or end-node otherwise. 'This' in Ebert's paper. + NodeIndexType DirectArcTail(const ArcIndexType arc) const { + return Tail(DirectArc(arc)); + } + + // Returns the head or end-node of arc if it is positive + // (i.e. it is taken in the direction it was entered in the graph), + // and the tail or start-node otherwise. 'That' in Ebert's paper. + NodeIndexType DirectArcHead(const ArcIndexType arc) const { + return Head(DirectArc(arc)); + } + + // Returns the arc in normal/direct direction. + ArcIndexType DirectArc(const ArcIndexType arc) const { + DCHECK(CheckArcValidity(arc)); + return std::max(arc, Opposite(arc)); + } + + // Returns the arc in reverse direction. + ArcIndexType ReverseArc(const ArcIndexType arc) const { + DCHECK(CheckArcValidity(arc)); + return std::min(arc, Opposite(arc)); + } + + // Returns the opposite arc, i.e the direct arc is the arc is in reverse + // direction, and the reverse arc if the arc is direct. + ArcIndexType Opposite(const ArcIndexType arc) const { + const ArcIndexType opposite = ~arc; + DCHECK(CheckArcValidity(arc)); + DCHECK(CheckArcValidity(opposite)); + return opposite; + } + + // Returns true if the arc is direct. + bool IsDirect(const ArcIndexType arc) const { + DCHECK(CheckArcBounds(arc)); + return arc != kNilArc && arc >= 0; + } + + // Returns true if the arc is in the reverse direction. + bool IsReverse(const ArcIndexType arc) const { + DCHECK(CheckArcBounds(arc)); + return arc != kNilArc && arc < 0; + } + + // Returns true if arc is incident to node. + bool IsOutgoingOrOppositeIncoming(ArcIndexType arc, + NodeIndexType node) const { + return Tail(arc) == node; + } + + // Returns true if arc is incoming to node. + bool IsIncoming(ArcIndexType arc, NodeIndexType node) const { + return IsDirect(arc) && Head(arc) == node; + } + + // Returns true if arc is outgoing from node. + bool IsOutgoing(ArcIndexType arc, NodeIndexType node) const { + return IsDirect(arc) && Tail(arc) == node; + } + + // Recreates the next_adjacent_arc_ and first_incident_arc_ variables from + // the array head_ in O(n + m) time. + // This is useful if head_ array has been sorted according to a given + // criterion, for example. + void BuildRepresentation() { + first_incident_arc_.SetAll(kNilArc); + for (ArcIndexType arc = kFirstArc; arc < max_num_arcs_; ++arc) { + Attach(arc); + } + representation_clean_ = true; + } + + // Returns a debug std::string containing all the information contained in the + // data structure in raw form. + std::string DebugString() const { + DCHECK(representation_clean_); + std::string result = "Arcs:(node, next arc) :\n"; + for (ArcIndexType arc = -num_arcs_; arc < num_arcs_; ++arc) { + result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) + + "," + ArcDebugString(next_adjacent_arc_[arc]) + ")\n"; + } + result += "Node:First arc :\n"; + for (NodeIndexType node = kFirstNode; node < num_nodes_; ++node) { + result += " " + NodeDebugString(node) + ":" + + ArcDebugString(first_incident_arc_[node]) + "\n"; + } + return result; + } + + private: + // Handles reserving space in the next_adjacent_arc_ and head_ + // arrays, which are always present and are therefore in the base + // class. Although they reside in the base class, those two arrays + // are maintained differently by different derived classes, + // depending on whether the derived class stores reverse arcs. Hence + // the code to set those arrays up is in a method of the derived + // class. + void ReserveInternal(NodeIndexType new_max_num_nodes, + ArcIndexType new_max_num_arcs) { + head_.Reserve(-new_max_num_arcs, new_max_num_arcs - 1); + next_adjacent_arc_.Reserve(-new_max_num_arcs, new_max_num_arcs - 1); + for (ArcIndexType arc = -new_max_num_arcs; arc < -max_num_arcs_; ++arc) { + head_.Set(arc, kNilNode); + next_adjacent_arc_.Set(arc, kNilArc); + } + for (ArcIndexType arc = max_num_arcs_; arc < new_max_num_arcs; ++arc) { + head_.Set(arc, kNilNode); + next_adjacent_arc_.Set(arc, kNilArc); + } + } + + // Returns the first incoming arc for node. + ArcIndexType FirstIncomingArc(const NodeIndexType node) const { + DCHECK_LE(kFirstNode, node); + DCHECK_GE(max_num_nodes_, node); + return FindNextIncomingArc(FirstOutgoingOrOppositeIncomingArc(node)); + } + + // Returns the incoming arc following the argument in the adjacency list. + ArcIndexType NextIncomingArc(const ArcIndexType arc) const { + DCHECK(CheckArcValidity(arc)); + DCHECK(IsReverse(arc)); + return FindNextIncomingArc(NextAdjacentArc(arc)); + } + + // Handles the part of AddArc() that is not in common with other + // graph classes based on the EbertGraphBase template. + void RecordArc(ArcIndexType arc, NodeIndexType tail, NodeIndexType head) { + head_.Set(Opposite(arc), tail); + head_.Set(arc, head); + Attach(arc); + } + + // Using the SetTail() method implies that the BuildRepresentation() + // method must be called to restore consistency before the graph is + // used. + void SetTail(const ArcIndexType arc, const NodeIndexType tail) { + representation_clean_ = false; + head_.Set(Opposite(arc), tail); + } + + // Utility method to attach a new arc. + void Attach(ArcIndexType arc) { + DCHECK(CheckArcValidity(arc)); + const NodeIndexType tail = head_[Opposite(arc)]; + DCHECK(IsNodeValid(tail)); + next_adjacent_arc_.Set(arc, first_incident_arc_[tail]); + first_incident_arc_.Set(tail, arc); + const NodeIndexType head = head_[arc]; + DCHECK(IsNodeValid(head)); + next_adjacent_arc_.Set(Opposite(arc), first_incident_arc_[head]); + first_incident_arc_.Set(head, Opposite(arc)); + } + + // Utility method that finds the next outgoing arc. + ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const { + DCHECK(CheckArcBounds(arc)); + while (IsReverse(arc)) { + arc = NextAdjacentArc(arc); + DCHECK(CheckArcBounds(arc)); + } + return arc; + } + + // Utility method that finds the next incoming arc. + ArcIndexType FindNextIncomingArc(ArcIndexType arc) const { + DCHECK(CheckArcBounds(arc)); + while (IsDirect(arc)) { + arc = NextAdjacentArc(arc); + DCHECK(CheckArcBounds(arc)); + } + return arc; + } +}; + +// A forward-star-only graph representation for greater efficiency in +// those algorithms that don't need reverse arcs. +template +class ForwardEbertGraph + : public EbertGraphBase > { + typedef EbertGraphBase > Base; + friend class EbertGraphBase >; + friend class StarGraphBase >; + + using Base::ArcDebugString; + using Base::Initialize; + using Base::NextAdjacentArc; + using Base::NodeDebugString; + + using Base::first_incident_arc_; + using Base::head_; + using Base::max_num_arcs_; + using Base::max_num_nodes_; + using Base::next_adjacent_arc_; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::representation_clean_; + + public: +#if !SWIG + using Base::Head; + using Base::IsNodeValid; + + using Base::kFirstArc; + using Base::kFirstNode; + using Base::kNilArc; + using Base::kNilNode; +#endif // SWIG + + typedef NodeIndexType NodeIndex; + typedef ArcIndexType ArcIndex; + + ForwardEbertGraph() {} + + ForwardEbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) { + Initialize(max_num_nodes, max_num_arcs); + } + + ~ForwardEbertGraph() {} + + // Utility function to check that an arc index is within the bounds. + // It is exported so that users of the ForwardEbertGraph class can use it. + // To be used in a DCHECK. + bool CheckArcBounds(const ArcIndexType arc) const { + return (arc == kNilArc) || (arc >= kFirstArc && arc < max_num_arcs_); + } + + // Utility function to check that an arc index is within the bounds AND + // different from kNilArc. + // It is exported so that users of the ForwardEbertGraph class can use it. + // To be used in a DCHECK. + bool CheckArcValidity(const ArcIndexType arc) const { + return (arc != kNilArc) && (arc >= kFirstArc && arc < max_num_arcs_); + } + + // Returns true if arc is a valid index into the (*tail_) array. + bool CheckTailIndexValidity(const ArcIndexType arc) const { + return (tail_ != nullptr) && (arc >= kFirstArc) && + (arc <= tail_->max_index()); + } + + // Returns the tail or start-node of arc. + NodeIndexType Tail(const ArcIndexType arc) const { + DCHECK(CheckArcValidity(arc)); + DCHECK(CheckTailIndexValidity(arc)); + return (*tail_)[arc]; + } + + // Returns true if arc is incoming to node. + bool IsIncoming(ArcIndexType arc, NodeIndexType node) const { + return IsDirect(arc) && Head(arc) == node; + } + + // Recreates the next_adjacent_arc_ and first_incident_arc_ + // variables from the arrays head_ and tail_ in O(n + m) time. This + // is useful if the head_ and tail_ arrays have been sorted + // according to a given criterion, for example. + void BuildRepresentation() { + first_incident_arc_.SetAll(kNilArc); + DCHECK(TailArrayComplete()); + for (ArcIndexType arc = kFirstArc; arc < max_num_arcs_; ++arc) { + DCHECK(CheckTailIndexValidity(arc)); + Attach((*tail_)[arc], arc); + } + representation_clean_ = true; + } + + bool BuildTailArray() { + // If (*tail_) is already allocated, we have the invariant that + // its contents are canonical, so we do not need to do anything + // here in that case except return true. + if (tail_ == nullptr) { + if (!representation_clean_) { + // We have been asked to build the (*tail_) array, but we have + // no valid information from which to build it. The graph is + // in an unrecoverable, inconsistent state. + return false; + } + // Reallocate (*tail_) and rebuild its contents from the + // adjacency lists. + tail_.reset(new ZVector); + tail_->Reserve(kFirstArc, max_num_arcs_ - 1); + typename Base::NodeIterator node_it(*this); + for (; node_it.Ok(); node_it.Next()) { + NodeIndexType node = node_it.Index(); + typename Base::OutgoingArcIterator arc_it(*this, node); + for (; arc_it.Ok(); arc_it.Next()) { + (*tail_)[arc_it.Index()] = node; + } + } + } + DCHECK(TailArrayComplete()); + return true; + } + + void ReleaseTailArray() { tail_.reset(nullptr); } + + // To be used in a DCHECK(). + bool TailArrayComplete() const { + CHECK_NOTNULL(tail_); + for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) { + CHECK(CheckTailIndexValidity(arc)); + CHECK(IsNodeValid((*tail_)[arc])); + } + return true; + } + + // Returns a debug std::string containing all the information contained in the + // data structure in raw form. + std::string DebugString() const { + DCHECK(representation_clean_); + std::string result = "Arcs:(node, next arc) :\n"; + for (ArcIndexType arc = kFirstArc; arc < num_arcs_; ++arc) { + result += " " + ArcDebugString(arc) + ":(" + NodeDebugString(head_[arc]) + + "," + ArcDebugString(next_adjacent_arc_[arc]) + ")\n"; + } + result += "Node:First arc :\n"; + for (NodeIndexType node = kFirstNode; node < num_nodes_; ++node) { + result += " " + NodeDebugString(node) + ":" + + ArcDebugString(first_incident_arc_[node]) + "\n"; + } + return result; + } + + private: + // Reserves space for the (*tail_) array. + // + // This method is separate from ReserveInternal() because our + // practice of making the (*tail_) array optional implies that the + // tail_ pointer might not be constructed when the ReserveInternal() + // method is called. Therefore we have this method also, and we + // ensure that it is called only when tail_ is guaranteed to have + // been initialized. + void ReserveTailArray(ArcIndexType new_max_num_arcs) { + if (tail_ != nullptr) { + // The (*tail_) values are already canonical, so we're just + // reserving additional space for new arcs that haven't been + // added yet. + if (tail_->Reserve(kFirstArc, new_max_num_arcs - 1)) { + for (ArcIndexType arc = tail_->max_index() + 1; arc < new_max_num_arcs; + ++arc) { + tail_->Set(arc, kNilNode); + } + } + } + } + + // Reserves space for the arrays indexed by arc indices, except + // (*tail_) even if it is present. We cannot grow the (*tail_) array + // in this method because this method is called from + // Base::Reserve(), which in turn is called from the base template + // class constructor. That base class constructor is called on *this + // before tail_ is constructed. Hence when this method is called, + // tail_ might contain garbage. This method can safely refer only to + // fields of the base template class, not to fields of *this outside + // the base template class. + // + // The strange situation in which this method of a derived class can + // refer only to members of the base class arises because different + // derived classes use the data members of the base class in + // slightly different ways. The purpose of this derived class + // method, then, is only to encode the derived-class-specific + // conventions for how the derived class uses the data members of + // the base class. + // + // To be specific, the forward-star graph representation, lacking + // reverse arcs, allocates only the positive index range for the + // head_ and next_adjacent_arc_ arrays, while the general + // representation allocates space for both positive- and + // negative-indexed arcs (i.e., both forward and reverse arcs). + void ReserveInternal(NodeIndexType new_max_num_nodes, + ArcIndexType new_max_num_arcs) { + head_.Reserve(kFirstArc, new_max_num_arcs - 1); + next_adjacent_arc_.Reserve(kFirstArc, new_max_num_arcs - 1); + for (ArcIndexType arc = max_num_arcs_; arc < new_max_num_arcs; ++arc) { + head_.Set(arc, kNilNode); + next_adjacent_arc_.Set(arc, kNilArc); + } + ReserveTailArray(new_max_num_arcs); + } + + // Handles the part of AddArc() that is not in common wth other + // graph classes based on the EbertGraphBase template. + void RecordArc(ArcIndexType arc, NodeIndexType tail, NodeIndexType head) { + head_.Set(arc, head); + Attach(tail, arc); + } + + // Using the SetTail() method implies that the BuildRepresentation() + // method must be called to restore consistency before the graph is + // used. + void SetTail(const ArcIndexType arc, const NodeIndexType tail) { + DCHECK(CheckTailIndexValidity(arc)); + CHECK_NOTNULL(tail_); + representation_clean_ = false; + tail_->Set(arc, tail); + } + + // Utility method to attach a new arc. + void Attach(NodeIndexType tail, ArcIndexType arc) { + DCHECK(CheckArcValidity(arc)); + DCHECK(IsNodeValid(tail)); + next_adjacent_arc_.Set(arc, first_incident_arc_[tail]); + first_incident_arc_.Set(tail, arc); + const NodeIndexType head = head_[arc]; + DCHECK(IsNodeValid(head)); + // Because Attach() is a public method, keeping (*tail_) canonical + // requires us to record the new arc's tail here. + if (tail_ != nullptr) { + DCHECK(CheckTailIndexValidity(arc)); + tail_->Set(arc, tail); + } + } + + // Utility method that finds the next outgoing arc. + ArcIndexType FindNextOutgoingArc(ArcIndexType arc) const { + DCHECK(CheckArcBounds(arc)); + return arc; + } + + private: + // Always returns true because for any ForwardEbertGraph, only + // direct arcs are represented, so all valid arc indices refer to + // arcs that are outgoing from their tail nodes. + bool IsOutgoing(const ArcIndex unused_arc, + const NodeIndex unused_node) const { + return true; + } + + // Always returns true because for any ForwardEbertGraph, only + // outgoing arcs are represented, so all valid arc indices refer to + // direct arcs. + bool IsDirect(const ArcIndex unused_arc) const { return true; } + + // Array of node indices, not always present. (*tail_)[i] contains + // the tail node of arc i. This array is not needed for normal graph + // traversal operations, but is used in optimizing the graph's + // layout so arcs are grouped by tail node, and can be used in one + // approach to serializing the graph. + // + // Invariants: At any time when we are not executing a method of + // this class, either tail_ == NULL or the tail_ array's contents + // are kept canonical. If tail_ != NULL, any method that modifies + // adjacency lists must also ensure (*tail_) is modified + // correspondingly. The converse does not hold: Modifications to + // (*tail_) are allowed without updating the adjacency lists. If + // such modifications take place, representation_clean_ must be set + // to false, of course, to indicate that the adjacency lists are no + // longer current. + std::unique_ptr > tail_; +}; + +// Traits for EbertGraphBase types, for use in testing and clients +// that work with both forward-only and forward/reverse graphs. +// +// The default is to assume reverse arcs so if someone forgets to +// specialize the traits of a new forward-only graph type, they will +// get errors from tests rather than incomplete testing. +template +struct graph_traits { + static const bool has_reverse_arcs = true; + static const bool is_dynamic = true; +}; + +template +struct graph_traits > { + static const bool has_reverse_arcs = false; + static const bool is_dynamic = true; +}; + +template +struct graph_traits > { + static const bool has_reverse_arcs = false; + static const bool is_dynamic = false; +}; + +namespace or_internal { + +// The TailArrayBuilder class template is not expected to be used by +// clients. It is a helper for the TailArrayManager template. +// +// The TailArrayBuilder for graphs with reverse arcs does nothing. +template +struct TailArrayBuilder { + explicit TailArrayBuilder(GraphType* unused_graph) {} + + bool BuildTailArray() const { return true; } +}; + +// The TailArrayBuilder for graphs without reverse arcs calls the +// appropriate method on the graph from the TailArrayBuilder +// constructor. +template +struct TailArrayBuilder { + explicit TailArrayBuilder(GraphType* graph) : graph_(graph) {} + + bool BuildTailArray() const { return graph_->BuildTailArray(); } + + GraphType* const graph_; +}; + +// The TailArrayReleaser class template is not expected to be used by +// clients. It is a helper for the TailArrayManager template. +// +// The TailArrayReleaser for graphs with reverse arcs does nothing. +template +struct TailArrayReleaser { + explicit TailArrayReleaser(GraphType* unused_graph) {} + + void ReleaseTailArray() const {} +}; + +// The TailArrayReleaser for graphs without reverse arcs calls the +// appropriate method on the graph from the TailArrayReleaser +// constructor. +template +struct TailArrayReleaser { + explicit TailArrayReleaser(GraphType* graph) : graph_(graph) {} + + void ReleaseTailArray() const { graph_->ReleaseTailArray(); } + + GraphType* const graph_; +}; + +} // namespace or_internal + +template +class TailArrayManager { + public: + explicit TailArrayManager(GraphType* g) : graph_(g) {} + + bool BuildTailArrayFromAdjacencyListsIfForwardGraph() const { + or_internal::TailArrayBuilder::has_reverse_arcs> + tail_array_builder(graph_); + return tail_array_builder.BuildTailArray(); + } + + void ReleaseTailArrayIfForwardGraph() const { + or_internal::TailArrayReleaser::has_reverse_arcs> + tail_array_releaser(graph_); + tail_array_releaser.ReleaseTailArray(); + } + + private: + GraphType* graph_; +}; + +template +class ArcFunctorOrderingByTailAndHead { + public: + explicit ArcFunctorOrderingByTailAndHead(const GraphType& graph) + : graph_(graph) {} + + bool operator()(typename GraphType::ArcIndex a, + typename GraphType::ArcIndex b) const { + return ((graph_.Tail(a) < graph_.Tail(b)) || + ((graph_.Tail(a) == graph_.Tail(b)) && + (graph_.Head(a) < graph_.Head(b)))); + } + + private: + const GraphType& graph_; +}; + +namespace or_internal { + +// The GraphBuilderFromArcs class template is not expected to be used +// by clients. It is a helper for the AnnotatedGraphBuildManager +// template. +// +// Deletes itself upon returning the graph! +template +class GraphBuilderFromArcs { + public: + GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, + typename GraphType::ArcIndex max_num_arcs, + bool sort_arcs) + : num_arcs_(0), sort_arcs_(sort_arcs) { + Reserve(max_num_nodes, max_num_arcs); + } + + typename GraphType::ArcIndex AddArc(typename GraphType::NodeIndex tail, + typename GraphType::NodeIndex head) { + DCHECK_LT(num_arcs_, max_num_arcs_); + DCHECK_LT(tail, GraphType::kFirstNode + max_num_nodes_); + DCHECK_LT(head, GraphType::kFirstNode + max_num_nodes_); + if (num_arcs_ < max_num_arcs_ && + tail < GraphType::kFirstNode + max_num_nodes_ && + head < GraphType::kFirstNode + max_num_nodes_) { + typename GraphType::ArcIndex result = GraphType::kFirstArc + num_arcs_; + arcs_.push_back(std::make_pair(tail, head)); + num_arcs_ += 1; + return result; + } else { + // Too many arcs or node index out of bounds! + return GraphType::kNilArc; + } + } + + // Builds the graph from the given arcs. + GraphType* Graph(PermutationCycleHandler* + client_cycle_handler) { + GraphType* graph = new GraphType(max_num_nodes_, num_arcs_, sort_arcs_, + &arcs_, client_cycle_handler); + delete this; + return graph; + } + + private: + bool Reserve(typename GraphType::NodeIndex new_max_num_nodes, + typename GraphType::ArcIndex new_max_num_arcs) { + max_num_nodes_ = new_max_num_nodes; + max_num_arcs_ = new_max_num_arcs; + arcs_.reserve(new_max_num_arcs); + return true; + } + + typename GraphType::NodeIndex max_num_nodes_; + typename GraphType::ArcIndex max_num_arcs_; + typename GraphType::ArcIndex num_arcs_; + + std::vector< + std::pair > + arcs_; + + const bool sort_arcs_; +}; + +// Trivial delegating specialization for dynamic graphs. +// +// Deletes itself upon returning the graph! +template +class GraphBuilderFromArcs { + public: + GraphBuilderFromArcs(typename GraphType::NodeIndex max_num_nodes, + typename GraphType::ArcIndex max_num_arcs, + bool sort_arcs) + : graph_(new GraphType(max_num_nodes, max_num_arcs)), + sort_arcs_(sort_arcs) {} + + bool Reserve(const typename GraphType::NodeIndex new_max_num_nodes, + const typename GraphType::ArcIndex new_max_num_arcs) { + return graph_->Reserve(new_max_num_nodes, new_max_num_arcs); + } + + typename GraphType::ArcIndex AddArc( + const typename GraphType::NodeIndex tail, + const typename GraphType::NodeIndex head) { + return graph_->AddArc(tail, head); + } + + GraphType* Graph(PermutationCycleHandler* + client_cycle_handler) { + if (sort_arcs_) { + TailArrayManager tail_array_manager(graph_); + tail_array_manager.BuildTailArrayFromAdjacencyListsIfForwardGraph(); + ArcFunctorOrderingByTailAndHead arc_ordering(*graph_); + graph_->GroupForwardArcsByFunctor(arc_ordering, client_cycle_handler); + tail_array_manager.ReleaseTailArrayIfForwardGraph(); + } + GraphType* result = graph_; + delete this; + return result; + } + + private: + GraphType* const graph_; + const bool sort_arcs_; +}; + +} // namespace or_internal + +template +class AnnotatedGraphBuildManager + : public or_internal::GraphBuilderFromArcs< + GraphType, graph_traits::is_dynamic> { + public: + AnnotatedGraphBuildManager(typename GraphType::NodeIndex num_nodes, + typename GraphType::ArcIndex num_arcs, + bool sort_arcs) + : or_internal::GraphBuilderFromArcs::is_dynamic>( + num_nodes, num_arcs, sort_arcs) {} +}; + +// Builds a directed line graph for 'graph' (see "directed line graph" in +// http://en.wikipedia.org/wiki/Line_graph). Arcs of the original graph +// become nodes and the new graph contains only nodes created from arcs in the +// original graph (we use the notation (a->b) for these new nodes); the index +// of the node (a->b) in the new graph is exactly the same as the index of the +// arc a->b in the original graph. +// An arc from node (a->b) to node (c->d) in the new graph is added if and only +// if b == c in the original graph. +// This method expects that 'line_graph' is an empty graph (it has no nodes +// and no arcs). +// Returns false on an error. +template +bool BuildLineGraph(const GraphType& graph, GraphType* const line_graph) { + if (line_graph == nullptr) { + LOG(DFATAL) << "line_graph must not be NULL"; + return false; + } + if (line_graph->num_nodes() != 0) { + LOG(DFATAL) << "line_graph must be empty"; + return false; + } + typedef typename GraphType::ArcIterator ArcIterator; + typedef typename GraphType::OutgoingArcIterator OutgoingArcIterator; + // Sizing then filling. + typename GraphType::ArcIndex num_arcs = 0; + for (ArcIterator arc_iterator(graph); arc_iterator.Ok(); + arc_iterator.Next()) { + const typename GraphType::ArcIndex arc = arc_iterator.Index(); + const typename GraphType::NodeIndex head = graph.Head(arc); + for (OutgoingArcIterator iterator(graph, head); iterator.Ok(); + iterator.Next()) { + ++num_arcs; + } + } + line_graph->Reserve(graph.num_arcs(), num_arcs); + for (ArcIterator arc_iterator(graph); arc_iterator.Ok(); + arc_iterator.Next()) { + const typename GraphType::ArcIndex arc = arc_iterator.Index(); + const typename GraphType::NodeIndex head = graph.Head(arc); + for (OutgoingArcIterator iterator(graph, head); iterator.Ok(); + iterator.Next()) { + line_graph->AddArc(arc, iterator.Index()); + } + } + return true; +} + +} // namespace operations_research +#endif // OR_TOOLS_GRAPH_EBERT_GRAPH_H_ diff --git a/thirdparty/linux/include/ortools/graph/eulerian_path.h b/thirdparty/linux/include/ortools/graph/eulerian_path.h new file mode 100644 index 0000000..2d11408 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/eulerian_path.h @@ -0,0 +1,150 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Utility to build Eulerian paths and tours on a graph. For more information, +// see https://en.wikipedia.org/wiki/Eulerian_path. +// As of 10/2015, only undirected graphs are supported. +// +// Usage: +// - Building an Eulerian tour on a ReverseArcListGraph: +// ReverseArcListGraph graph; +// // Fill graph +// std::vector tour = BuildEulerianTour(graph); +// +// - Building an Eulerian path on a ReverseArcListGraph: +// ReverseArcListGraph graph; +// // Fill graph +// std::vector tour = BuildEulerianPath(graph); +// +#ifndef OR_TOOLS_GRAPH_EULERIAN_PATH_H_ +#define OR_TOOLS_GRAPH_EULERIAN_PATH_H_ + +#include + +#include "ortools/base/logging.h" + +namespace operations_research { + +// Returns true if a graph is Eulerian, aka all its nodes are of even degree. +template +bool IsEulerianGraph(const Graph& graph) { + typedef typename Graph::NodeIndex NodeIndex; + for (const NodeIndex node : graph.AllNodes()) { + if ((graph.OutDegree(node) + graph.InDegree(node)) % 2 != 0) { + return false; + } + } + // TODO(user): Check graph connectivity. + return true; +} + +// Returns true if a graph is Semi-Eulerian, aka at most two of its nodes are of +// odd degree. +// odd_nodes is filled with odd nodes of the graph. +template +bool IsSemiEulerianGraph(const Graph& graph, + std::vector* odd_nodes) { + CHECK(odd_nodes != nullptr); + for (const NodeIndex node : graph.AllNodes()) { + const int degree = graph.OutDegree(node) + graph.InDegree(node); + if (degree % 2 != 0) { + odd_nodes->push_back(node); + } + } + // TODO(user): Check graph connectivity. + return odd_nodes->size() <= 2; +} + +// Builds an Eulerian path/trail on an undirected graph starting from node root. +// Supposes the graph is connected and is eulerian or semi-eulerian. +// This is an implementation of Hierholzer's algorithm. +// If m is the number of edges in the graph and n the number of nodes, time +// and memory complexity is O(n + m). +template +std::vector BuildEulerianPathFromNode(const Graph& graph, + NodeIndex root) { + typedef typename Graph::ArcIndex ArcIndex; + std::vector unvisited_edges(graph.num_arcs(), true); + std::vector tour; + if (graph.IsNodeValid(root)) { + std::vector tour_stack = {root}; + std::vector active_arcs(graph.num_nodes()); + for (const NodeIndex node : graph.AllNodes()) { + active_arcs[node] = *(graph.OutgoingOrOppositeIncomingArcs(node)).begin(); + } + while (!tour_stack.empty()) { + const NodeIndex node = tour_stack.back(); + bool has_unvisited_edges = false; + for (const ArcIndex arc : + graph.OutgoingOrOppositeIncomingArcsStartingFrom( + node, active_arcs[node])) { + const ArcIndex edge = arc < 0 ? graph.OppositeArc(arc) : arc; + if (unvisited_edges[edge]) { + has_unvisited_edges = true; + active_arcs[node] = arc; + tour_stack.push_back(graph.Head(arc)); + unvisited_edges[edge] = false; + break; + } + } + if (!has_unvisited_edges) { + tour.push_back(node); + tour_stack.pop_back(); + } + } + } + return tour; +} + +// Builds an Eulerian tour/circuit/cycle starting and ending at node root on an +// undirected graph. +// This function works only on Reverse graphs +// (cf. ortools/graph/graph.h). +// Returns an empty tour if either root is invalid or if a tour cannot be built. +// As of 10/2015, assumes the graph is connected. +template +std::vector BuildEulerianTourFromNode(const Graph& graph, + NodeIndex root) { + std::vector tour; + if (IsEulerianGraph(graph)) { + tour = BuildEulerianPathFromNode(graph, root); + } + return tour; +} + +// Same as above but without specifying a start/end root node (node 0 is taken +// as default root). +template +std::vector BuildEulerianTour(const Graph& graph) { + return BuildEulerianTourFromNode(graph, 0); +} + +// Builds an Eulerian path/trail on an undirected graph. +// This function works only on Reverse graphs +// (cf. ortools/graph/graph.h). +// Returns an empty tour if a tour cannot be built. +// As of 10/2015, assumes the graph is connected. +template +std::vector BuildEulerianPath(const Graph& graph) { + typedef typename Graph::NodeIndex NodeIndex; + std::vector path; + std::vector roots; + if (IsSemiEulerianGraph(graph, &roots)) { + const NodeIndex root = roots.empty() ? 0 : roots.back(); + path = BuildEulerianPathFromNode(graph, root); + } + return path; +} +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_EULERIAN_PATH_H_ diff --git a/thirdparty/linux/include/ortools/graph/flow_problem.pb.h b/thirdparty/linux/include/ortools/graph/flow_problem.pb.h new file mode 100644 index 0000000..6b2fd57 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/flow_problem.pb.h @@ -0,0 +1,708 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/graph/flow_problem.proto + +#ifndef PROTOBUF_ortools_2fgraph_2fflow_5fproblem_2eproto__INCLUDED +#define PROTOBUF_ortools_2fgraph_2fflow_5fproblem_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fgraph_2fflow_5fproblem_2eproto(); +void protobuf_AssignDesc_ortools_2fgraph_2fflow_5fproblem_2eproto(); +void protobuf_ShutdownFile_ortools_2fgraph_2fflow_5fproblem_2eproto(); + +class Arc; +class FlowModel; +class Node; + +enum FlowModel_ProblemType { + FlowModel_ProblemType_LINEAR_SUM_ASSIGNMENT = 0, + FlowModel_ProblemType_MAX_FLOW = 1, + FlowModel_ProblemType_MIN_COST_FLOW = 2 +}; +bool FlowModel_ProblemType_IsValid(int value); +const FlowModel_ProblemType FlowModel_ProblemType_ProblemType_MIN = FlowModel_ProblemType_LINEAR_SUM_ASSIGNMENT; +const FlowModel_ProblemType FlowModel_ProblemType_ProblemType_MAX = FlowModel_ProblemType_MIN_COST_FLOW; +const int FlowModel_ProblemType_ProblemType_ARRAYSIZE = FlowModel_ProblemType_ProblemType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* FlowModel_ProblemType_descriptor(); +inline const ::std::string& FlowModel_ProblemType_Name(FlowModel_ProblemType value) { + return ::google::protobuf::internal::NameOfEnum( + FlowModel_ProblemType_descriptor(), value); +} +inline bool FlowModel_ProblemType_Parse( + const ::std::string& name, FlowModel_ProblemType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + FlowModel_ProblemType_descriptor(), name, value); +} +// =================================================================== + +class Arc : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.Arc) */ { + public: + Arc(); + virtual ~Arc(); + + Arc(const Arc& from); + + inline Arc& operator=(const Arc& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Arc& default_instance(); + + void Swap(Arc* other); + + // implements Message ---------------------------------------------- + + inline Arc* New() const { return New(NULL); } + + Arc* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Arc& from); + void MergeFrom(const Arc& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Arc* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 tail_node_id = 1; + bool has_tail_node_id() const; + void clear_tail_node_id(); + static const int kTailNodeIdFieldNumber = 1; + ::google::protobuf::int64 tail_node_id() const; + void set_tail_node_id(::google::protobuf::int64 value); + + // optional int64 head_node_id = 2; + bool has_head_node_id() const; + void clear_head_node_id(); + static const int kHeadNodeIdFieldNumber = 2; + ::google::protobuf::int64 head_node_id() const; + void set_head_node_id(::google::protobuf::int64 value); + + // optional int64 capacity = 3 [default = 1]; + bool has_capacity() const; + void clear_capacity(); + static const int kCapacityFieldNumber = 3; + ::google::protobuf::int64 capacity() const; + void set_capacity(::google::protobuf::int64 value); + + // optional int64 unit_cost = 4 [default = 0]; + bool has_unit_cost() const; + void clear_unit_cost(); + static const int kUnitCostFieldNumber = 4; + ::google::protobuf::int64 unit_cost() const; + void set_unit_cost(::google::protobuf::int64 value); + + // @@protoc_insertion_point(class_scope:operations_research.Arc) + private: + inline void set_has_tail_node_id(); + inline void clear_has_tail_node_id(); + inline void set_has_head_node_id(); + inline void clear_has_head_node_id(); + inline void set_has_capacity(); + inline void clear_has_capacity(); + inline void set_has_unit_cost(); + inline void clear_has_unit_cost(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int64 tail_node_id_; + ::google::protobuf::int64 head_node_id_; + ::google::protobuf::int64 capacity_; + ::google::protobuf::int64 unit_cost_; + friend void protobuf_AddDesc_ortools_2fgraph_2fflow_5fproblem_2eproto(); + friend void protobuf_AssignDesc_ortools_2fgraph_2fflow_5fproblem_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fgraph_2fflow_5fproblem_2eproto(); + + void InitAsDefaultInstance(); + static Arc* default_instance_; +}; +// ------------------------------------------------------------------- + +class Node : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.Node) */ { + public: + Node(); + virtual ~Node(); + + Node(const Node& from); + + inline Node& operator=(const Node& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Node& default_instance(); + + void Swap(Node* other); + + // implements Message ---------------------------------------------- + + inline Node* New() const { return New(NULL); } + + Node* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Node& from); + void MergeFrom(const Node& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Node* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 id = 1; + bool has_id() const; + void clear_id(); + static const int kIdFieldNumber = 1; + ::google::protobuf::int64 id() const; + void set_id(::google::protobuf::int64 value); + + // optional int64 supply = 2 [default = 0]; + bool has_supply() const; + void clear_supply(); + static const int kSupplyFieldNumber = 2; + ::google::protobuf::int64 supply() const; + void set_supply(::google::protobuf::int64 value); + + // @@protoc_insertion_point(class_scope:operations_research.Node) + private: + inline void set_has_id(); + inline void clear_has_id(); + inline void set_has_supply(); + inline void clear_has_supply(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int64 id_; + ::google::protobuf::int64 supply_; + friend void protobuf_AddDesc_ortools_2fgraph_2fflow_5fproblem_2eproto(); + friend void protobuf_AssignDesc_ortools_2fgraph_2fflow_5fproblem_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fgraph_2fflow_5fproblem_2eproto(); + + void InitAsDefaultInstance(); + static Node* default_instance_; +}; +// ------------------------------------------------------------------- + +class FlowModel : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.FlowModel) */ { + public: + FlowModel(); + virtual ~FlowModel(); + + FlowModel(const FlowModel& from); + + inline FlowModel& operator=(const FlowModel& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FlowModel& default_instance(); + + void Swap(FlowModel* other); + + // implements Message ---------------------------------------------- + + inline FlowModel* New() const { return New(NULL); } + + FlowModel* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FlowModel& from); + void MergeFrom(const FlowModel& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FlowModel* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef FlowModel_ProblemType ProblemType; + static const ProblemType LINEAR_SUM_ASSIGNMENT = + FlowModel_ProblemType_LINEAR_SUM_ASSIGNMENT; + static const ProblemType MAX_FLOW = + FlowModel_ProblemType_MAX_FLOW; + static const ProblemType MIN_COST_FLOW = + FlowModel_ProblemType_MIN_COST_FLOW; + static inline bool ProblemType_IsValid(int value) { + return FlowModel_ProblemType_IsValid(value); + } + static const ProblemType ProblemType_MIN = + FlowModel_ProblemType_ProblemType_MIN; + static const ProblemType ProblemType_MAX = + FlowModel_ProblemType_ProblemType_MAX; + static const int ProblemType_ARRAYSIZE = + FlowModel_ProblemType_ProblemType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + ProblemType_descriptor() { + return FlowModel_ProblemType_descriptor(); + } + static inline const ::std::string& ProblemType_Name(ProblemType value) { + return FlowModel_ProblemType_Name(value); + } + static inline bool ProblemType_Parse(const ::std::string& name, + ProblemType* value) { + return FlowModel_ProblemType_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // repeated .operations_research.Node node = 1; + int node_size() const; + void clear_node(); + static const int kNodeFieldNumber = 1; + const ::operations_research::Node& node(int index) const; + ::operations_research::Node* mutable_node(int index); + ::operations_research::Node* add_node(); + ::google::protobuf::RepeatedPtrField< ::operations_research::Node >* + mutable_node(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::Node >& + node() const; + + // repeated .operations_research.Arc arc = 2; + int arc_size() const; + void clear_arc(); + static const int kArcFieldNumber = 2; + const ::operations_research::Arc& arc(int index) const; + ::operations_research::Arc* mutable_arc(int index); + ::operations_research::Arc* add_arc(); + ::google::protobuf::RepeatedPtrField< ::operations_research::Arc >* + mutable_arc(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::Arc >& + arc() const; + + // optional .operations_research.FlowModel.ProblemType problem_type = 3 [default = MIN_COST_FLOW]; + bool has_problem_type() const; + void clear_problem_type(); + static const int kProblemTypeFieldNumber = 3; + ::operations_research::FlowModel_ProblemType problem_type() const; + void set_problem_type(::operations_research::FlowModel_ProblemType value); + + // @@protoc_insertion_point(class_scope:operations_research.FlowModel) + private: + inline void set_has_problem_type(); + inline void clear_has_problem_type(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::operations_research::Node > node_; + ::google::protobuf::RepeatedPtrField< ::operations_research::Arc > arc_; + int problem_type_; + friend void protobuf_AddDesc_ortools_2fgraph_2fflow_5fproblem_2eproto(); + friend void protobuf_AssignDesc_ortools_2fgraph_2fflow_5fproblem_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fgraph_2fflow_5fproblem_2eproto(); + + void InitAsDefaultInstance(); + static FlowModel* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Arc + +// optional int64 tail_node_id = 1; +inline bool Arc::has_tail_node_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Arc::set_has_tail_node_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void Arc::clear_has_tail_node_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Arc::clear_tail_node_id() { + tail_node_id_ = GOOGLE_LONGLONG(0); + clear_has_tail_node_id(); +} +inline ::google::protobuf::int64 Arc::tail_node_id() const { + // @@protoc_insertion_point(field_get:operations_research.Arc.tail_node_id) + return tail_node_id_; +} +inline void Arc::set_tail_node_id(::google::protobuf::int64 value) { + set_has_tail_node_id(); + tail_node_id_ = value; + // @@protoc_insertion_point(field_set:operations_research.Arc.tail_node_id) +} + +// optional int64 head_node_id = 2; +inline bool Arc::has_head_node_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Arc::set_has_head_node_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void Arc::clear_has_head_node_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Arc::clear_head_node_id() { + head_node_id_ = GOOGLE_LONGLONG(0); + clear_has_head_node_id(); +} +inline ::google::protobuf::int64 Arc::head_node_id() const { + // @@protoc_insertion_point(field_get:operations_research.Arc.head_node_id) + return head_node_id_; +} +inline void Arc::set_head_node_id(::google::protobuf::int64 value) { + set_has_head_node_id(); + head_node_id_ = value; + // @@protoc_insertion_point(field_set:operations_research.Arc.head_node_id) +} + +// optional int64 capacity = 3 [default = 1]; +inline bool Arc::has_capacity() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Arc::set_has_capacity() { + _has_bits_[0] |= 0x00000004u; +} +inline void Arc::clear_has_capacity() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Arc::clear_capacity() { + capacity_ = GOOGLE_LONGLONG(1); + clear_has_capacity(); +} +inline ::google::protobuf::int64 Arc::capacity() const { + // @@protoc_insertion_point(field_get:operations_research.Arc.capacity) + return capacity_; +} +inline void Arc::set_capacity(::google::protobuf::int64 value) { + set_has_capacity(); + capacity_ = value; + // @@protoc_insertion_point(field_set:operations_research.Arc.capacity) +} + +// optional int64 unit_cost = 4 [default = 0]; +inline bool Arc::has_unit_cost() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Arc::set_has_unit_cost() { + _has_bits_[0] |= 0x00000008u; +} +inline void Arc::clear_has_unit_cost() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Arc::clear_unit_cost() { + unit_cost_ = GOOGLE_LONGLONG(0); + clear_has_unit_cost(); +} +inline ::google::protobuf::int64 Arc::unit_cost() const { + // @@protoc_insertion_point(field_get:operations_research.Arc.unit_cost) + return unit_cost_; +} +inline void Arc::set_unit_cost(::google::protobuf::int64 value) { + set_has_unit_cost(); + unit_cost_ = value; + // @@protoc_insertion_point(field_set:operations_research.Arc.unit_cost) +} + +// ------------------------------------------------------------------- + +// Node + +// optional int64 id = 1; +inline bool Node::has_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Node::set_has_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void Node::clear_has_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Node::clear_id() { + id_ = GOOGLE_LONGLONG(0); + clear_has_id(); +} +inline ::google::protobuf::int64 Node::id() const { + // @@protoc_insertion_point(field_get:operations_research.Node.id) + return id_; +} +inline void Node::set_id(::google::protobuf::int64 value) { + set_has_id(); + id_ = value; + // @@protoc_insertion_point(field_set:operations_research.Node.id) +} + +// optional int64 supply = 2 [default = 0]; +inline bool Node::has_supply() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Node::set_has_supply() { + _has_bits_[0] |= 0x00000002u; +} +inline void Node::clear_has_supply() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Node::clear_supply() { + supply_ = GOOGLE_LONGLONG(0); + clear_has_supply(); +} +inline ::google::protobuf::int64 Node::supply() const { + // @@protoc_insertion_point(field_get:operations_research.Node.supply) + return supply_; +} +inline void Node::set_supply(::google::protobuf::int64 value) { + set_has_supply(); + supply_ = value; + // @@protoc_insertion_point(field_set:operations_research.Node.supply) +} + +// ------------------------------------------------------------------- + +// FlowModel + +// repeated .operations_research.Node node = 1; +inline int FlowModel::node_size() const { + return node_.size(); +} +inline void FlowModel::clear_node() { + node_.Clear(); +} +inline const ::operations_research::Node& FlowModel::node(int index) const { + // @@protoc_insertion_point(field_get:operations_research.FlowModel.node) + return node_.Get(index); +} +inline ::operations_research::Node* FlowModel::mutable_node(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.FlowModel.node) + return node_.Mutable(index); +} +inline ::operations_research::Node* FlowModel::add_node() { + // @@protoc_insertion_point(field_add:operations_research.FlowModel.node) + return node_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::Node >* +FlowModel::mutable_node() { + // @@protoc_insertion_point(field_mutable_list:operations_research.FlowModel.node) + return &node_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::Node >& +FlowModel::node() const { + // @@protoc_insertion_point(field_list:operations_research.FlowModel.node) + return node_; +} + +// repeated .operations_research.Arc arc = 2; +inline int FlowModel::arc_size() const { + return arc_.size(); +} +inline void FlowModel::clear_arc() { + arc_.Clear(); +} +inline const ::operations_research::Arc& FlowModel::arc(int index) const { + // @@protoc_insertion_point(field_get:operations_research.FlowModel.arc) + return arc_.Get(index); +} +inline ::operations_research::Arc* FlowModel::mutable_arc(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.FlowModel.arc) + return arc_.Mutable(index); +} +inline ::operations_research::Arc* FlowModel::add_arc() { + // @@protoc_insertion_point(field_add:operations_research.FlowModel.arc) + return arc_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::Arc >* +FlowModel::mutable_arc() { + // @@protoc_insertion_point(field_mutable_list:operations_research.FlowModel.arc) + return &arc_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::Arc >& +FlowModel::arc() const { + // @@protoc_insertion_point(field_list:operations_research.FlowModel.arc) + return arc_; +} + +// optional .operations_research.FlowModel.ProblemType problem_type = 3 [default = MIN_COST_FLOW]; +inline bool FlowModel::has_problem_type() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FlowModel::set_has_problem_type() { + _has_bits_[0] |= 0x00000004u; +} +inline void FlowModel::clear_has_problem_type() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FlowModel::clear_problem_type() { + problem_type_ = 2; + clear_has_problem_type(); +} +inline ::operations_research::FlowModel_ProblemType FlowModel::problem_type() const { + // @@protoc_insertion_point(field_get:operations_research.FlowModel.problem_type) + return static_cast< ::operations_research::FlowModel_ProblemType >(problem_type_); +} +inline void FlowModel::set_problem_type(::operations_research::FlowModel_ProblemType value) { + assert(::operations_research::FlowModel_ProblemType_IsValid(value)); + set_has_problem_type(); + problem_type_ = value; + // @@protoc_insertion_point(field_set:operations_research.FlowModel.problem_type) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::operations_research::FlowModel_ProblemType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::FlowModel_ProblemType>() { + return ::operations_research::FlowModel_ProblemType_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fgraph_2fflow_5fproblem_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/graph/graph.h b/thirdparty/linux/include/ortools/graph/graph.h new file mode 100644 index 0000000..afb2d25 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/graph.h @@ -0,0 +1,2249 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// +// This file defines a generic graph interface on which most algorithms can be +// built and provides a few efficient implementations with a fast construction +// time. Its design is based on the experience acquired by the Operations +// Research team in their various graph algorithm implementations. +// +// The main ideas are: +// - Graph nodes and arcs are represented by integers. +// - Node or arc annotations (weight, cost, ...) are not part of the graph +// class, they can be stored outside in one or more arrays and can be easily +// retrieved using a node or arc as an index. +// +// Terminology: +// - An arc of a graph is directed and going from a tail node to a head node. +// - Some implementations also store 'reverse' arcs and can be used for +// undirected graph or flow-like algorithm. +// - A node or arc index is 'valid' if it represents a node or arc of +// the graph. The validity ranges are always [0, num_nodes()) for nodes and +// [0, num_arcs()) for forward arcs. Reverse arcs are elements of +// [-num_arcs(), 0) and are also considered valid by the implementations that +// store them. +// +// Provided implementations: +// - ListGraph<> for the simplest api +// - StaticGraph<> for performance, but require calling Build(), see below +// - CompleteGraph<> if you need a fully connected graph +// - CompleteBipartiteGraph<> if you need a fully connected bipartite graph +// - ReverseArcListGraph<> to add reverse arcs to ListGraph<> +// - ReverseArcStaticGraph<> to add reverse arcs to StaticGraph<> +// - ReverseArcMixedGraph<> for a smaller memory footprint +// +// Utility classes & functions: +// - Permute() to permute an array according to a given permutation. +// - SVector<> vector with index range [-size(), size()) for ReverseArcGraph. +// +// Basic usage: +// typedef ListGraph<> Graph; // Choose a graph implementation. +// Graph graph; +// for (...) { +// graph.AddArc(tail, head); +// } +// ... +// for (int node = 0; node < graph.num_nodes(); ++node) { +// for (const int arc : graph.OutgoingArcs(node)) { +// head = graph.Head(arc); +// tail = node; // or graph.Tail(arc) which is fast but not as much. +// } +// } +// +// Iteration over the arcs touching a node: +// +// - OutgoingArcs(node): All the forward arcs leaving the node. +// - IncomingArcs(node): All the forward arcs arriving at the node. +// +// And a more involved one: +// +// - OutgoingOrOppositeIncomingArcs(node): This returns both the forward arcs +// leaving the node (i.e. OutgoingArcs(node)) and the reverse arcs leaving the +// node (i.e. the opposite arcs of the ones returned by IncomingArcs(node)). +// +// Note on iteration efficiency: When re-indexing the arcs it is not possible to +// have both the outgoing arcs and the incoming ones form a consecutive range. +// +// It is however possible to do so for the outgoing arcs and the opposite +// incoming arcs. It is why the OutgoingOrOppositeIncomingArcs() and +// OutgoingArcs() iterations are more efficient than the IncomingArcs() one. If +// needed, we can add a OppositeIncomingArcs() function to quickly iterate on +// the opposite incoming arcs (and their heads). +// +// If you know the graph size in advance, this already set the number of nodes, +// reserve space for the arcs and check in DEBUG mode that you don't go over the +// bounds: +// Graph graph(num_nodes, arc_capacity); +// +// Storing and using node annotations: +// std::vector is_visited(graph.num_nodes(), false); +// ... +// for (int node = 0; node < graph.num_nodes(); ++node) { +// if (!is_visited[node]) ... +// } +// +// Storing and using arc annotations: +// std::vector weights; +// for (...) { +// graph.AddArc(tail, head); +// weights.push_back(arc_weight); +// } +// ... +// for (const int arc : graph.OutgoingArcs(node)) { +// ... weights[arc] ...; +// } +// +// More efficient version: +// typedef StaticGraph<> Graph; +// Graph graph(num_nodes, arc_capacity); // Optional, but help memory usage. +// std::vector weights; +// weights.reserve(arc_capacity); // Optional, but help memory usage. +// for (...) { +// graph.AddArc(tail, head); +// weights.push_back(arc_weight); +// } +// ... +// std::vector permutation; +// graph.Build(&permutation); // A static graph must be Build() before usage. +// Permute(permutation, &weights); // Build() may permute the arc index. +// ... +// +// Encoding an undirected graph: If you don't need arc annotation, then the best +// is to add two arcs for each edge (one in each direction) to a directed graph. +// Otherwise you can do the following. +// +// typedef ReverseArc... Graph; +// Graph graph; +// for (...) { +// graph.AddArc(tail, head); // or graph.AddArc(head, tail) but not both. +// edge_annotations.push_back(value); +// } +// ... +// for (const Graph::NodeIndex node : graph.AllNodes()) { +// for (const Graph::ArcIndex arc : +// graph.OutgoingOrOppositeIncomingArcs(node)) { +// destination = graph.Head(arc); +// annotation = edge_annotations[arc < 0 ? graph.OppositeArc(arc) : arc]; +// } +// } +// +// +// Note: The graphs are primarily designed to be constructed first and then used +// because it covers most of the use cases. It is possible to extend the +// interface with more dynamicity (like removing arcs), but this is not done at +// this point. Note that a "dynamic" implementation will break some assumptions +// we make on what node or arc are valid and also on the indices returned by +// AddArc(). Some arguments for simplifying the interface at the cost of +// dynamicity are: +// +// - It is always possible to construct a static graph from a dynamic one +// before calling a complex algo. +// - If you really need a dynamic graph, maybe it is better to compute a graph +// property incrementally rather than calling an algorithm that starts from +// scratch each time. + +#ifndef OR_TOOLS_GRAPH_GRAPH_H_ +#define OR_TOOLS_GRAPH_GRAPH_H_ + +#include +#include +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/port.h" +#include "ortools/util/iterators.h" + + +namespace operations_research { + +// Forward declaration. +template +class SVector; + +// Base class of all Graphs implemented here. The default value for the graph +// index types is int32 since allmost all graphs that fit into memory do not +// need bigger indices. +// +// Note: The type can be unsigned, except for the graphs with reverse arcs +// where the ArcIndexType must be signed, but not necessarly the NodeIndexType. +template +class BaseGraph { + public: + // Typedef so you can use Graph::NodeIndex and Graph::ArcIndex to be generic + // but also to improve the readability of your code. We also recommend + // that you define a typedef ... Graph; for readability. + typedef NodeIndexType NodeIndex; + typedef ArcIndexType ArcIndex; + + BaseGraph() + : num_nodes_(0), + node_capacity_(0), + num_arcs_(0), + arc_capacity_(0), + const_capacities_(false) {} + virtual ~BaseGraph() {} + + // Returns the number of valid nodes in the graph. + NodeIndexType num_nodes() const { return num_nodes_; } + + // Returns the number of valid arcs in the graph. + ArcIndexType num_arcs() const { return num_arcs_; } + + // Allows nice range-based for loop: + // for (const NodeIndex node : graph.AllNodes()) { ... } + // for (const ArcIndex arc : graph.AllForwardArcs()) { ... } + IntegerRange AllNodes() const; + IntegerRange AllForwardArcs() const; + + // Returns true if the given node is a valid node of the graph. + bool IsNodeValid(NodeIndexType node) const { + return node >= 0 && node < num_nodes_; + } + + // Returns true if the given arc is a valid arc of the graph. + // Note that the arc validity range changes for graph with reverse arcs. + bool IsArcValid(ArcIndexType arc) const { + return (HasReverseArcs ? -num_arcs_ : 0) <= arc && arc < num_arcs_; + } + + // Capacity reserved for future nodes, always >= num_nodes_. + NodeIndexType node_capacity() const; + + // Capacity reserved for future arcs, always >= num_arcs_. + ArcIndexType arc_capacity() const; + + // Changes the graph capacities. The functions will fail in debug mode if: + // - const_capacities_ is true. + // - A valid node does not fall into the new node range. + // - A valid arc does not fall into the new arc range. + // In non-debug mode, const_capacities_ is ignored and nothing will happen + // if the new capacity value for the arcs or the nodes is too small. + virtual void ReserveNodes(NodeIndexType bound) { + DCHECK(!const_capacities_); + DCHECK_GE(bound, num_nodes_); + if (bound <= num_nodes_) return; + node_capacity_ = bound; + } + virtual void ReserveArcs(ArcIndexType bound) { + DCHECK(!const_capacities_); + DCHECK_GE(bound, num_arcs_); + if (bound <= num_arcs_) return; + arc_capacity_ = bound; + } + void Reserve(NodeIndexType node_capacity, ArcIndexType arc_capacity) { + ReserveNodes(node_capacity); + ReserveArcs(arc_capacity); + } + + // FreezeCapacities() makes any future attempt to change the graph capacities + // crash in DEBUG mode. + void FreezeCapacities(); + + // Constants that will never be a valid node or arc. + // They are the maximum possible node and arc capacity. + static const NodeIndexType kNilNode; + static const ArcIndexType kNilArc; + + // TODO(user): remove the public functions below. They are just here during + // the transition from the old ebert_graph api to this new graph api. + template + void GroupForwardArcsByFunctor(const A& a, B* b) { + LOG(FATAL) << "Not supported"; + } + ArcIndexType max_end_arc_index() const { return arc_capacity_; } + + protected: + // Functions commented when defined because they are implementation details. + void ComputeCumulativeSum(std::vector* v); + void BuildStartAndForwardHead(SVector* head, + std::vector* start, + std::vector* permutation); + + NodeIndexType num_nodes_; + NodeIndexType node_capacity_; + ArcIndexType num_arcs_; + ArcIndexType arc_capacity_; + bool const_capacities_; +}; + +// Basic graph implementation without reverse arc. This class also serves as a +// documentation for the generic graph interface (minus the part related to +// reverse arcs). +// +// This implementation uses a linked list and compared to StaticGraph: +// - Is a bit faster to construct (if the arcs are not ordered by tail). +// - Does not require calling Build(). +// - Has slower outgoing arc iteration. +// - Uses more memory: ArcIndexType * node_capacity() +// + (ArcIndexType + NodeIndexType) * arc_capacity(). +// - Has an efficient Tail() but need an extra NodeIndexType/arc memory for it. +// - Never changes the initial arc index returned by AddArc(). +// +template +class ListGraph : public BaseGraph { + typedef BaseGraph Base; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::arc_capacity_; + using Base::node_capacity_; + using Base::const_capacities_; + + public: + using Base::IsArcValid; + ListGraph() {} + + // Reserve space for the graph at construction and do not allow it to grow + // beyond that, see FreezeCapacities(). This constructor also makes any nodes + // in [0, num_nodes) valid. + ListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity) { + this->Reserve(num_nodes, arc_capacity); + this->FreezeCapacities(); + this->AddNode(num_nodes - 1); + } + + // If node is not a valid node, sets num_nodes_ to node + 1 so that the given + // node becomes valid. It will fail in DEBUG mode if the capacities are fixed + // and the new node is out of range. + void AddNode(NodeIndexType node); + + // Adds an arc to the graph and returns its current index which will always + // be num_arcs() - 1. It will also automatically call AddNode(tail) + // and AddNode(head). It will fail in DEBUG mode if the capacities + // are fixed and this cause the graph to grow beyond them. + // + // Note: Self referencing arcs and duplicate arcs are supported. + ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head); + + // Some graph implementations need to be finalized with Build() before they + // can be used. After Build() is called, the arc indices (which had been the + // return values of previous AddArc() calls) may change: the new index of + // former arc #i will be stored in permutation[i] if #i is smaller than + // permutation.size() or will be unchanged otherwise. If you don't care about + // these, just call the simple no-output version Build(). + // + // Note that some implementations become immutable after calling Build(). + void Build() { Build(nullptr); } + void Build(std::vector* permutation); + + // Do not use directly. + class OutgoingArcIterator; + class OutgoingHeadIterator; + + // Graph jargon: the "degree" of a node is its number of arcs. The out-degree + // is the number of outgoing arcs. The in-degree is the number of incoming + // arcs, and is only available for some graph implementations, below. + // + // ListGraph<>::OutDegree() works in O(degree). + ArcIndexType OutDegree(NodeIndexType node) const; + + // Allows to iterate over the forward arcs that verify Tail(arc) == node. + // This is meant to be used as: + // for (const ArcIndex arc : graph.OutgoingArcs(node)) { ... } + BeginEndWrapper OutgoingArcs(NodeIndexType node) const; + + // Advanced usage. Same as OutgoingArcs(), but allows to restart the iteration + // from an already known outgoing arc of the given node. + BeginEndWrapper OutgoingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const; + + // This loops over the heads of the OutgoingArcs(node). It is just a more + // convenient way to achieve this. Moreover this interface is used by some + // graph algorithms. + BeginEndWrapper operator[](NodeIndexType node) const; + + // Returns the tail/head of a valid arc. + NodeIndexType Tail(ArcIndexType arc) const; + NodeIndexType Head(ArcIndexType arc) const; + + void ReserveNodes(NodeIndexType bound) override; + void ReserveArcs(ArcIndexType bound) override; + + private: + std::vector start_; + std::vector next_; + std::vector head_; + std::vector tail_; + DISALLOW_COPY_AND_ASSIGN(ListGraph); +}; + +// Most efficient implementation of a graph without reverse arcs: +// - Build() needs to be called after the arc and node have been added. +// - The graph is really compact memory wise: +// ArcIndexType * node_capacity() + 2 * NodeIndexType * arc_capacity(), +// but when Build() is called it uses a temporary extra space of +// ArcIndexType * arc_capacity(). +// - The construction is really fast. +// +// NOTE(user): if the need arises for very-well compressed graphs, we could +// shave NodeIndexType * arc_capacity() off the permanent memory requirement +// with a similar class that doesn't support Tail(), i.e. +// StaticGraphWithoutTail<>. This almost corresponds to a past implementation +// of StaticGraph<> @CL 116144340. +template +class StaticGraph : public BaseGraph { + typedef BaseGraph Base; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::arc_capacity_; + using Base::node_capacity_; + using Base::const_capacities_; + + public: + using Base::IsArcValid; + StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {} + StaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity) + : is_built_(false), arc_in_order_(true), last_tail_seen_(0) { + this->Reserve(num_nodes, arc_capacity); + this->FreezeCapacities(); + this->AddNode(num_nodes - 1); + } + + // Do not use directly. See instead the arc iteration functions below. + class OutgoingArcIterator; + + NodeIndexType Head(ArcIndexType arc) const; + NodeIndexType Tail(ArcIndexType arc) const; + ArcIndexType OutDegree(NodeIndexType node) const; // Work in O(1). + BeginEndWrapper OutgoingArcs(NodeIndexType node) const; + BeginEndWrapper OutgoingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const; + + // This loops over the heads of the OutgoingArcs(node). It is just a more + // convenient way to achieve this. Moreover this interface is used by some + // graph algorithms. + BeginEndWrapper operator[](NodeIndexType node) const; + + void ReserveNodes(NodeIndexType bound) override; + void ReserveArcs(ArcIndexType bound) override; + void AddNode(NodeIndexType node); + ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head); + + void Build() { Build(nullptr); } + void Build(std::vector* permutation); + + private: + ArcIndexType DirectArcLimit(NodeIndexType node) const { + DCHECK(is_built_); + DCHECK(Base::IsNodeValid(node)); + return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_; + } + + bool is_built_; + bool arc_in_order_; + NodeIndexType last_tail_seen_; + std::vector start_; + std::vector head_; + std::vector tail_; + DISALLOW_COPY_AND_ASSIGN(StaticGraph); +}; + +// Extends the ListGraph by also storing the reverse arcs. +// This class also documents the Graph interface related to reverse arc. +// - NodeIndexType can be unsigned, but ArcIndexType must be signed. +// - It has most of the same advantanges and disadvantages as ListGraph. +// - It takes 2 * ArcIndexType * node_capacity() +// + 2 * (ArcIndexType + NodeIndexType) * arc_capacity() memory. +template +class ReverseArcListGraph + : public BaseGraph { + typedef BaseGraph Base; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::arc_capacity_; + using Base::node_capacity_; + using Base::const_capacities_; + + public: + using Base::IsArcValid; + ReverseArcListGraph() {} + ReverseArcListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity) { + this->Reserve(num_nodes, arc_capacity); + this->FreezeCapacities(); + this->AddNode(num_nodes - 1); + } + + // Returns the opposite arc of a given arc. That is the reverse arc of the + // given forward arc or the forward arc of a given reverse arc. + ArcIndexType OppositeArc(ArcIndexType arc) const; + + // Do not use directly. See instead the arc iteration functions below. + class OutgoingOrOppositeIncomingArcIterator; + class IncomingArcIterator; + class OutgoingArcIterator; + class OutgoingHeadIterator; + + // ReverseArcListGraph<>::OutDegree() and ::InDegree() work in O(degree). + ArcIndexType OutDegree(NodeIndexType node) const; + ArcIndexType InDegree(NodeIndexType node) const; + + // Arc iterations functions over the arcs touching a node (see the top-level + // comment for the different types). To be used as follows: + // for (const Graph::ArcIndex arc : IterationFunction(node)) { ... } + // + // The StartingFrom() version are similar, but restart the iteration from a + // given arc position (which must be valid in the iteration context). + BeginEndWrapper OutgoingArcs(NodeIndexType node) const; + BeginEndWrapper IncomingArcs(NodeIndexType node) const; + BeginEndWrapper + OutgoingOrOppositeIncomingArcs(NodeIndexType node) const; + BeginEndWrapper OutgoingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const; + BeginEndWrapper IncomingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const; + BeginEndWrapper + OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, + ArcIndexType from) const; + + // This loops over the heads of the OutgoingArcs(node). It is just a more + // convenient way to achieve this. Moreover this interface is used by some + // graph algorithms. + BeginEndWrapper operator[](NodeIndexType node) const; + + NodeIndexType Head(ArcIndexType arc) const; + NodeIndexType Tail(ArcIndexType arc) const; + + void ReserveNodes(NodeIndexType bound) override; + void ReserveArcs(ArcIndexType bound) override; + void AddNode(NodeIndexType node); + ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head); + + void Build() { Build(nullptr); } + void Build(std::vector* permutation); + + private: + std::vector start_; + std::vector reverse_start_; + SVector next_; + SVector head_; + DISALLOW_COPY_AND_ASSIGN(ReverseArcListGraph); +}; + +// StaticGraph with reverse arc. +// - NodeIndexType can be unsigned, but ArcIndexType must be signed. +// - It has most of the same advantanges and disadvantages as StaticGraph. +// - It takes 2 * ArcIndexType * node_capacity() +// + 2 * (ArcIndexType + NodeIndexType) * arc_capacity() memory. +// - If the ArcIndexPermutation is needed, then an extra ArcIndexType * +// arc_capacity() is needed for it. +// - The reverse arcs from a node are sorted by head (so we could add a log() +// time lookup function). +template +class ReverseArcStaticGraph + : public BaseGraph { + typedef BaseGraph Base; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::arc_capacity_; + using Base::node_capacity_; + using Base::const_capacities_; + + public: + using Base::IsArcValid; + ReverseArcStaticGraph() : is_built_(false) {} + ReverseArcStaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity) + : is_built_(false) { + this->Reserve(num_nodes, arc_capacity); + this->FreezeCapacities(); + this->AddNode(num_nodes - 1); + } + + // Deprecated. + class OutgoingOrOppositeIncomingArcIterator; + class IncomingArcIterator; + class OutgoingArcIterator; + + // ReverseArcStaticGraph<>::OutDegree() and ::InDegree() work in O(1). + ArcIndexType OutDegree(NodeIndexType node) const; + ArcIndexType InDegree(NodeIndexType node) const; + + BeginEndWrapper OutgoingArcs(NodeIndexType node) const; + BeginEndWrapper IncomingArcs(NodeIndexType node) const; + BeginEndWrapper + OutgoingOrOppositeIncomingArcs(NodeIndexType node) const; + BeginEndWrapper OutgoingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const; + BeginEndWrapper IncomingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const; + BeginEndWrapper + OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, + ArcIndexType from) const; + + // This loops over the heads of the OutgoingArcs(node). It is just a more + // convenient way to achieve this. Moreover this interface is used by some + // graph algorithms. + BeginEndWrapper operator[](NodeIndexType node) const; + + ArcIndexType OppositeArc(ArcIndexType arc) const; + // TODO(user): support Head() and Tail() before Build(), like StaticGraph<>. + NodeIndexType Head(ArcIndexType arc) const; + NodeIndexType Tail(ArcIndexType arc) const; + + void ReserveArcs(ArcIndexType bound) override; + void AddNode(NodeIndexType node); + ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head); + + void Build() { Build(nullptr); } + void Build(std::vector* permutation); + + private: + ArcIndexType DirectArcLimit(NodeIndexType node) const { + DCHECK(is_built_); + DCHECK(Base::IsNodeValid(node)); + return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_; + } + ArcIndexType ReverseArcLimit(NodeIndexType node) const { + DCHECK(is_built_); + DCHECK(Base::IsNodeValid(node)); + return node + 1 < num_nodes_ ? reverse_start_[node + 1] : 0; + } + + bool is_built_; + std::vector start_; + std::vector reverse_start_; + SVector head_; + SVector opposite_; + DISALLOW_COPY_AND_ASSIGN(ReverseArcStaticGraph); +}; + +// This graph is a mix between the ReverseArcListGraph and the +// ReverseArcStaticGraph. It uses less memory: +// - It takes 2 * ArcIndexType * node_capacity() +// + (2 * NodeIndexType + ArcIndexType) * arc_capacity() memory. +// - If the ArcIndexPermutation is needed, then an extra ArcIndexType * +// arc_capacity() is needed for it. +template +class ReverseArcMixedGraph + : public BaseGraph { + typedef BaseGraph Base; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::arc_capacity_; + using Base::node_capacity_; + using Base::const_capacities_; + + public: + using Base::IsArcValid; + ReverseArcMixedGraph() : is_built_(false) {} + ReverseArcMixedGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity) + : is_built_(false) { + this->Reserve(num_nodes, arc_capacity); + this->FreezeCapacities(); + this->AddNode(num_nodes - 1); + } + + // Deprecated. + class OutgoingOrOppositeIncomingArcIterator; + class IncomingArcIterator; + class OutgoingArcIterator; + + ArcIndexType OutDegree(NodeIndexType node) const; // O(1) + ArcIndexType InDegree(NodeIndexType node) const; // O(in-degree) + + BeginEndWrapper OutgoingArcs(NodeIndexType node) const; + BeginEndWrapper IncomingArcs(NodeIndexType node) const; + BeginEndWrapper + OutgoingOrOppositeIncomingArcs(NodeIndexType node) const; + BeginEndWrapper OutgoingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const; + BeginEndWrapper IncomingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const; + BeginEndWrapper + OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, + ArcIndexType from) const; + + // This loops over the heads of the OutgoingArcs(node). It is just a more + // convenient way to achieve this. Moreover this interface is used by some + // graph algorithms. + BeginEndWrapper operator[](NodeIndexType node) const; + + ArcIndexType OppositeArc(ArcIndexType arc) const; + // TODO(user): support Head() and Tail() before Build(), like StaticGraph<>. + NodeIndexType Head(ArcIndexType arc) const; + NodeIndexType Tail(ArcIndexType arc) const; + + void ReserveArcs(ArcIndexType bound) override; + void AddNode(NodeIndexType node); + ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head); + + void Build() { Build(nullptr); } + void Build(std::vector* permutation); + + private: + ArcIndexType DirectArcLimit(NodeIndexType node) const { + DCHECK(is_built_); + DCHECK(Base::IsNodeValid(node)); + return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_; + } + + bool is_built_; + std::vector start_; + std::vector reverse_start_; + std::vector next_; + SVector head_; + DISALLOW_COPY_AND_ASSIGN(ReverseArcMixedGraph); +}; + +// Permutes the elements of array_to_permute: element #i will be moved to +// position permutation[i]. permutation must be either empty (in which case +// nothing happens), or a permutation of [0, permutation.size()). +// +// The algorithm is fast but need extra memory for a copy of the permuted part +// of array_to_permute. +// +// TODO(user): consider slower but more memory efficient implementations that +// follow the cycles of the permutation and use a bitmap to indicate what has +// been permuted or to mark the beginning of each cycle. + +// Some compiler do not know typeof(), so we have to use this extra function +// internally. +template +void PermuteWithExplicitElementType(const IntVector& permutation, + Array* array_to_permute, + ElementType unused) { + std::vector temp(permutation.size()); + for (int i = 0; i < permutation.size(); ++i) { + temp[i] = (*array_to_permute)[i]; + } + for (int i = 0; i < permutation.size(); ++i) { + (*array_to_permute)[permutation[i]] = temp[i]; + } +} + +template +void Permute(const IntVector& permutation, Array* array_to_permute) { + if (permutation.empty()) { + return; + } + PermuteWithExplicitElementType(permutation, array_to_permute, + (*array_to_permute)[0]); +} + +// We need a specialization for std::vector, because the default code uses +// (*array_to_permute)[0] as ElementType, which isn't 'bool' in that case. +template +void Permute(const IntVector& permutation, + std::vector* array_to_permute) { + if (permutation.empty()) { + return; + } + bool unused = false; + PermuteWithExplicitElementType(permutation, array_to_permute, unused); +} + +// A vector-like class where valid indices are in [- size_, size_) and reserved +// indices for future growth are in [- capacity_, capacity_). It is used to hold +// arc related information for graphs with reverse arcs. +// It supports only up to 2^31-1 elements, for compactness. If you ever need +// more, consider using templates for the size/capacity integer types. +// +// Sample usage: +// +// SVector v; +// v.grow(left_value, right_value); +// v.resize(10); +// v.clear(); +// v.swap(new_v); +// std:swap(v[i], v[~i]); +template +class SVector { + public: + SVector() : base_(nullptr), size_(0), capacity_(0) {} + + ~SVector() { + clear(); + if (capacity_ > 0) { + free(base_ - capacity_); + } + } + + T& operator[](int n) { + DCHECK_LT(n, size_); + DCHECK_GE(n, -size_); + return base_[n]; + } + + const T& operator[](int n) const { + DCHECK_LT(n, size_); + DCHECK_GE(n, -size_); + return base_[n]; + } + + void resize(int n, T left = T(), T right = T()) { + reserve(n); + for (int i = -n; i < -size_; ++i) { + new (base_ + i) T(left); + } + for (int i = size_; i < n; ++i) { + new (base_ + i) T(right); + } + for (int i = -size_; i < -n; ++i) { + base_[i].~T(); + } + for (int i = n; i < size_; ++i) { + base_[i].~T(); + } + size_ = n; + } + + void clear() { resize(0); } + + T* data() const { return base_; } + + void swap(SVector& x) { + std::swap(base_, x.base_); + std::swap(size_, x.size_); + std::swap(capacity_, x.capacity_); + } + + void reserve(int n) { + DCHECK_GE(n, 0); + DCHECK_LE(n, max_size()); + if (n > capacity_) { + int new_capacity = n; + size_t requested_block_size = 2LL * new_capacity * sizeof(T); + T* new_storage = static_cast(malloc(requested_block_size)); + CHECK(new_storage != nullptr); + size_t block_size = requested_block_size; + if (block_size > 0) { + new_capacity = static_cast(std::min( + static_cast(max_size()), block_size / (2 * sizeof(T)))); + } + T* new_base = new_storage + new_capacity; + for (int i = -size_; i < size_; ++i) { + new (new_base + i) T(base_[i]); + } + int temp = size_; + clear(); + if (capacity_ > 0) { + free(base_ - capacity_); + } + size_ = temp; + base_ = new_base; + capacity_ = new_capacity; + } + } + + void grow(const T& left = T(), const T& right = T()) { + if (size_ == capacity_) { + // We have to copy the elements because they are allowed to be element of + // *this. + T left_copy(left); // NOLINT + T right_copy(right); // NOLINT + reserve(NewCapacity(1)); + new (base_ + size_) T(right_copy); + new (base_ - size_ - 1) T(left_copy); + ++size_; + } else { + new (base_ + size_) T(right); + new (base_ - size_ - 1) T(left); + ++size_; + } + } + + int size() const { return size_; } + + int capacity() const { return capacity_; } + + int max_size() const { return std::numeric_limits::max(); } + + private: + int NewCapacity(int delta) { + // TODO(user): check validity. + double candidate = 1.3 * static_cast(capacity_); + if (candidate > static_cast(max_size())) { + candidate = static_cast(max_size()); + } + int new_capacity = static_cast(candidate); + if (new_capacity > capacity_ + delta) { + return new_capacity; + } + return capacity_ + delta; + } + + T* base_; // Pointer to the element of index 0. + int size_; // Valid index are [- size_, size_). + int capacity_; // Reserved index are [- capacity_, capacity_). + DISALLOW_COPY_AND_ASSIGN(SVector); +}; + +// BaseGraph implementation ---------------------------------------------------- + +template +IntegerRange +BaseGraph::AllNodes() const { + return IntegerRange(0, num_nodes_); +} + +template +IntegerRange +BaseGraph::AllForwardArcs() const { + return IntegerRange(0, num_arcs_); +} + +template +const NodeIndexType + BaseGraph::kNilNode = + std::numeric_limits::max(); + +template +const ArcIndexType + BaseGraph::kNilArc = + std::numeric_limits::max(); + +template +NodeIndexType +BaseGraph::node_capacity() const { + // TODO(user): Is it needed? remove completely? return the real capacities + // at the cost of having a different implementation for each graphs? + return node_capacity_ > num_nodes_ ? node_capacity_ : num_nodes_; +} + +template +ArcIndexType +BaseGraph::arc_capacity() const { + // TODO(user): Same questions as the ones in node_capacity(). + return arc_capacity_ > num_arcs_ ? arc_capacity_ : num_arcs_; +} + +template +void BaseGraph::FreezeCapacities() { + // TODO(user): Only define this in debug mode at the cost of having a lot + // of ifndef NDEBUG all over the place? remove the function completely ? + const_capacities_ = true; + node_capacity_ = std::max(node_capacity_, num_nodes_); + arc_capacity_ = std::max(arc_capacity_, num_arcs_); +} + +// Computes the cummulative sum of the entry in v. We only use it with +// in/out degree distribution, hence the Check() at the end. +template +void BaseGraph:: + ComputeCumulativeSum(std::vector* v) { + ArcIndexType sum = 0; + for (int i = 0; i < num_nodes_; ++i) { + ArcIndexType temp = (*v)[i]; + (*v)[i] = sum; + sum += temp; + } + DCHECK(sum == num_arcs_); +} + +// Given the tail of arc #i in (*head)[i] and the head of arc #i in (*head)[~i] +// - Reorder the arc by increasing tail. +// - Put the head of the new arc #i in (*head)[i]. +// - Put in start[i] the index of the first arc with tail >= i. +// - Update "permutation" to reflect the change, unless it is NULL. +template +void BaseGraph:: + BuildStartAndForwardHead(SVector* head, + std::vector* start, + std::vector* permutation) { + // Computes the outgoing degree of each nodes and check if we need to permute + // something or not. Note that the tails are currently stored in the positive + // range of the SVector head. + start->assign(num_nodes_, 0); + int last_tail_seen = 0; + bool permutation_needed = false; + for (int i = 0; i < num_arcs_; ++i) { + NodeIndexType tail = (*head)[i]; + if (!permutation_needed) { + permutation_needed = tail < last_tail_seen; + last_tail_seen = tail; + } + (*start)[tail]++; + } + ComputeCumulativeSum(start); + + // Abort early if we do not need the permutation: we only need to put the + // heads in the positive range. + if (!permutation_needed) { + for (int i = 0; i < num_arcs_; ++i) { + (*head)[i] = (*head)[~i]; + } + if (permutation != nullptr) { + permutation->clear(); + } + return; + } + + // Computes the forward arc permutation. + // Note that this temporarily alters the start vector. + std::vector perm(num_arcs_); + for (int i = 0; i < num_arcs_; ++i) { + perm[i] = (*start)[(*head)[i]]++; + } + + // Restore in (*start)[i] the index of the first arc with tail >= i. + for (int i = num_nodes_ - 1; i > 0; --i) { + (*start)[i] = (*start)[i - 1]; + } + (*start)[0] = 0; + + // Permutes the head into their final position in head. + // We do not need the tails anymore at this point. + for (int i = 0; i < num_arcs_; ++i) { + (*head)[perm[i]] = (*head)[~i]; + } + if (permutation != nullptr) { + permutation->swap(perm); + } +} + +// --------------------------------------------------------------------------- +// Macros to wrap old style iteration into the new range-based for loop style. +// --------------------------------------------------------------------------- + +// The parameters are: +// - c: the class name. +// - t: the iteration type (Outgoing, Incoming or OutgoingOrOppositeIncoming). +// - e: the "end" ArcIndexType. +#define DEFINE_RANGE_BASED_ARC_ITERATION(c, t, e) \ + template \ + BeginEndWrapper::t##ArcIterator> \ + c::t##Arcs(NodeIndexType node) const { \ + return BeginEndWrapper(t##ArcIterator(*this, node), \ + t##ArcIterator(*this, node, e)); \ + } \ + template \ + BeginEndWrapper::t##ArcIterator> \ + c::t##ArcsStartingFrom( \ + NodeIndexType node, ArcIndexType from) const { \ + return BeginEndWrapper(t##ArcIterator(*this, node, from), \ + t##ArcIterator(*this, node, e)); \ + } + +// Adapt our old iteration style to support range-based for loops. Add typedefs +// required by std::iterator_traits. +#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \ + using iterator_category = std::input_iterator_tag; \ + using difference_type = ptrdiff_t; \ + using pointer = const ArcIndexType*; \ + using reference = const ArcIndexType&; \ + using value_type = ArcIndexType; \ + bool operator!=(const iterator_class_name& other) const { \ + return index_ != other.index_; \ + } \ + bool operator==(const iterator_class_name& other) const { \ + return index_ == other.index_; \ + } \ + ArcIndexType operator*() const { return Index(); } \ + void operator++() { Next(); } + +// ListGraph implementation ---------------------------------------------------- + +DEFINE_RANGE_BASED_ARC_ITERATION(ListGraph, Outgoing, Base::kNilArc); + +template +BeginEndWrapper< + typename ListGraph::OutgoingHeadIterator> + ListGraph::operator[]( + NodeIndexType node) const { + return BeginEndWrapper( + OutgoingHeadIterator(*this, node), + OutgoingHeadIterator(*this, node, Base::kNilArc)); +} + +template +NodeIndexType ListGraph::Tail( + ArcIndexType arc) const { + DCHECK(IsArcValid(arc)); + return tail_[arc]; +} + +template +NodeIndexType ListGraph::Head( + ArcIndexType arc) const { + DCHECK(IsArcValid(arc)); + return head_[arc]; +} + +template +ArcIndexType ListGraph::OutDegree( + NodeIndexType node) const { + ArcIndexType degree(0); + for (auto arc ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree; + return degree; +} + +template +void ListGraph::AddNode(NodeIndexType node) { + if (node < num_nodes_) return; + DCHECK(!const_capacities_ || node < node_capacity_); + num_nodes_ = node + 1; + start_.resize(num_nodes_, Base::kNilArc); +} + +template +ArcIndexType ListGraph::AddArc( + NodeIndexType tail, NodeIndexType head) { + DCHECK_GE(tail, 0); + DCHECK_GE(head, 0); + AddNode(tail > head ? tail : head); + head_.push_back(head); + tail_.push_back(tail); + next_.push_back(start_[tail]); + start_[tail] = num_arcs_; + DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_); + return num_arcs_++; +} + +template +void ListGraph::ReserveNodes(NodeIndexType bound) { + Base::ReserveNodes(bound); + if (bound <= num_nodes_) return; + start_.reserve(bound); +} + +template +void ListGraph::ReserveArcs(ArcIndexType bound) { + Base::ReserveArcs(bound); + if (bound <= num_arcs_) return; + head_.reserve(bound); + tail_.reserve(bound); + next_.reserve(bound); +} + +template +void ListGraph::Build( + std::vector* permutation) { + if (permutation != nullptr) { + permutation->clear(); + } +} + +template +class ListGraph::OutgoingArcIterator { + public: + OutgoingArcIterator(const ListGraph& graph, NodeIndexType node) + : graph_(graph), index_(graph.start_[node]) { + DCHECK(graph.IsNodeValid(node)); + } + OutgoingArcIterator(const ListGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(graph), index_(arc) { + DCHECK(graph.IsNodeValid(node)); + DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node); + } + bool Ok() const { return index_ != Base::kNilArc; } + ArcIndexType Index() const { return index_; } + void Next() { + DCHECK(Ok()); + index_ = graph_.next_[index_]; + } + + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator); + + private: + const ListGraph& graph_; + ArcIndexType index_; +}; + +template +class ListGraph::OutgoingHeadIterator { + public: + using iterator_category = std::input_iterator_tag; + using difference_type = ptrdiff_t; + using pointer = const NodeIndexType*; + using reference = const NodeIndexType&; + using value_type = NodeIndexType; + + OutgoingHeadIterator(const ListGraph& graph, NodeIndexType node) + : graph_(graph), index_(graph.start_[node]) { + DCHECK(graph.IsNodeValid(node)); + } + OutgoingHeadIterator(const ListGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(graph), index_(arc) { + DCHECK(graph.IsNodeValid(node)); + DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node); + } + bool Ok() const { return index_ != Base::kNilArc; } + NodeIndexType Index() const { return graph_.Head(index_); } + void Next() { + DCHECK(Ok()); + index_ = graph_.next_[index_]; + } + + bool operator!=( + const typename ListGraph< + NodeIndexType, ArcIndexType>::OutgoingHeadIterator& other) const { + return index_ != other.index_; + } + NodeIndexType operator*() const { return Index(); } + void operator++() { Next(); } + + private: + const ListGraph& graph_; + ArcIndexType index_; +}; + +// StaticGraph implementation -------------------------------------------------- + +DEFINE_RANGE_BASED_ARC_ITERATION(StaticGraph, Outgoing, DirectArcLimit(node)); + +template +BeginEndWrapper StaticGraph:: +operator[](NodeIndexType node) const { + return BeginEndWrapper( + head_.data() + start_[node], head_.data() + DirectArcLimit(node)); +} + +template +ArcIndexType StaticGraph::OutDegree( + NodeIndexType node) const { + return DirectArcLimit(node) - start_[node]; +} + +template +void StaticGraph::ReserveNodes( + NodeIndexType bound) { + Base::ReserveNodes(bound); + if (bound <= num_nodes_) return; + start_.reserve(bound); +} + +template +void StaticGraph::ReserveArcs(ArcIndexType bound) { + Base::ReserveArcs(bound); + if (bound <= num_arcs_) return; + head_.reserve(bound); + tail_.reserve(bound); +} + +template +void StaticGraph::AddNode(NodeIndexType node) { + if (node < num_nodes_) return; + DCHECK(!const_capacities_ || node < node_capacity_); + num_nodes_ = node + 1; + start_.resize(num_nodes_, 0); +} + +template +ArcIndexType StaticGraph::AddArc( + NodeIndexType tail, NodeIndexType head) { + DCHECK_GE(tail, 0); + DCHECK_GE(head, 0); + DCHECK(!is_built_); + AddNode(tail > head ? tail : head); + if (arc_in_order_) { + if (tail >= last_tail_seen_) { + start_[tail]++; + last_tail_seen_ = tail; + } else { + arc_in_order_ = false; + } + } + tail_.push_back(tail); + head_.push_back(head); + DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_); + return num_arcs_++; +} + +template +NodeIndexType StaticGraph::Tail( + ArcIndexType arc) const { + DCHECK(IsArcValid(arc)); + return tail_[arc]; +} + +template +NodeIndexType StaticGraph::Head( + ArcIndexType arc) const { + DCHECK(IsArcValid(arc)); + return head_[arc]; +} + +// Implementation details: A reader may be surprised that we do many passes +// into the data where things could be done in one pass. For instance, during +// construction, we store the edges first, and then do a second pass at the +// end to compute the degree distribution. +// +// This is because it is a lot more efficient cache-wise to do it this way. +// This was determined by various experiments, but can also be understood: +// - during repetitive call to AddArc() a client usually accesses various +// areas of memory, and there is no reason to polute the cache with +// possibly random access to degree[i]. +// - When the degrees are needed, we compute them in one go, maximizing the +// chance of cache hit during the computation. +template +void StaticGraph::Build( + std::vector* permutation) { + DCHECK(!is_built_); + if (is_built_) return; + is_built_ = true; + node_capacity_ = num_nodes_; + arc_capacity_ = num_arcs_; + this->FreezeCapacities(); + + // If Arc are in order, start_ already contains the degree distribution. + if (arc_in_order_) { + if (permutation != nullptr) { + permutation->clear(); + } + this->ComputeCumulativeSum(&start_); + return; + } + + // Computes outgoing degree of each nodes. We have to clear start_, since + // at least the first arc was processed with arc_in_order_ == true. + start_.assign(num_nodes_, 0); + for (int i = 0; i < num_arcs_; ++i) { + start_[tail_[i]]++; + } + this->ComputeCumulativeSum(&start_); + + // Computes the forward arc permutation. + // Note that this temporarily alters the start_ vector. + std::vector perm(num_arcs_); + for (int i = 0; i < num_arcs_; ++i) { + perm[i] = start_[tail_[i]]++; + } + + // We use "tail_" (which now contains rubbish) to permute "head_" faster. + CHECK_EQ(tail_.size(), num_arcs_); + tail_.swap(head_); + for (int i = 0; i < num_arcs_; ++i) { + head_[perm[i]] = tail_[i]; + } + + if (permutation != nullptr) { + permutation->swap(perm); + } + + // Restore in start_[i] the index of the first arc with tail >= i. + for (int i = num_nodes_ - 1; i > 0; --i) { + start_[i] = start_[i - 1]; + } + start_[0] = 0; + + // Recompute the correct tail_ vector + for (const NodeIndexType node : Base::AllNodes()) { + for (const ArcIndexType arc : OutgoingArcs(node)) { + tail_[arc] = node; + } + } +} + +template +class StaticGraph::OutgoingArcIterator { + public: + OutgoingArcIterator(const StaticGraph& graph, NodeIndexType node) + : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {} + OutgoingArcIterator(const StaticGraph& graph, NodeIndexType node, + ArcIndexType arc) + : index_(arc), limit_(graph.DirectArcLimit(node)) { + DCHECK_GE(arc, graph.start_[node]); + } + + bool Ok() const { return index_ < limit_; } + ArcIndexType Index() const { return index_; } + void Next() { + DCHECK(Ok()); + index_++; + } + + // Note(user): we lose a bit by returning a BeginEndWrapper<> on top of + // this iterator rather than a simple IntegerRange<> on the arc indices. + // On my computer: around 420M arcs/sec instead of 440M arcs/sec. + // + // However, it is slightly more consistent to do it this way, and we don't + // have two different codes depending on the way a client iterates on the + // arcs. + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator); + + private: + ArcIndexType index_; + const ArcIndexType limit_; +}; + +// ReverseArcListGraph implementation ------------------------------------------ + +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcListGraph, Outgoing, Base::kNilArc); +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcListGraph, Incoming, Base::kNilArc); +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcListGraph, + OutgoingOrOppositeIncoming, Base::kNilArc); + +template +BeginEndWrapper::OutgoingHeadIterator> + ReverseArcListGraph::operator[]( + NodeIndexType node) const { + return BeginEndWrapper( + OutgoingHeadIterator(*this, node), + OutgoingHeadIterator(*this, node, Base::kNilArc)); +} + +template +ArcIndexType ReverseArcListGraph::OutDegree( + NodeIndexType node) const { + ArcIndexType degree(0); + for (auto arc ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree; + return degree; +} + +template +ArcIndexType ReverseArcListGraph::InDegree( + NodeIndexType node) const { + ArcIndexType degree(0); + for (auto arc ATTRIBUTE_UNUSED : IncomingArcs(node)) ++degree; + return degree; +} + +template +ArcIndexType ReverseArcListGraph::OppositeArc( + ArcIndexType arc) const { + DCHECK(IsArcValid(arc)); + return ~arc; +} + +template +NodeIndexType ReverseArcListGraph::Head( + ArcIndexType arc) const { + DCHECK(IsArcValid(arc)); + return head_[arc]; +} + +template +NodeIndexType ReverseArcListGraph::Tail( + ArcIndexType arc) const { + return head_[OppositeArc(arc)]; +} + +template +void ReverseArcListGraph::ReserveNodes( + NodeIndexType bound) { + Base::ReserveNodes(bound); + if (bound <= num_nodes_) return; + start_.reserve(bound); + reverse_start_.reserve(bound); +} + +template +void ReverseArcListGraph::ReserveArcs( + ArcIndexType bound) { + Base::ReserveArcs(bound); + if (bound <= num_arcs_) return; + head_.reserve(bound); + next_.reserve(bound); +} + +template +void ReverseArcListGraph::AddNode( + NodeIndexType node) { + if (node < num_nodes_) return; + DCHECK(!const_capacities_ || node < node_capacity_); + num_nodes_ = node + 1; + start_.resize(num_nodes_, Base::kNilArc); + reverse_start_.resize(num_nodes_, Base::kNilArc); +} + +template +ArcIndexType ReverseArcListGraph::AddArc( + NodeIndexType tail, NodeIndexType head) { + DCHECK_GE(tail, 0); + DCHECK_GE(head, 0); + AddNode(tail > head ? tail : head); + head_.grow(tail, head); + next_.grow(reverse_start_[head], start_[tail]); + start_[tail] = num_arcs_; + reverse_start_[head] = ~num_arcs_; + DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_); + return num_arcs_++; +} + +template +void ReverseArcListGraph::Build( + std::vector* permutation) { + if (permutation != nullptr) { + permutation->clear(); + } +} + +template +class ReverseArcListGraph::OutgoingArcIterator { + public: + OutgoingArcIterator(const ReverseArcListGraph& graph, NodeIndexType node) + : graph_(graph), index_(graph.start_[node]) { + DCHECK(graph.IsNodeValid(node)); + } + OutgoingArcIterator(const ReverseArcListGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(graph), index_(arc) { + DCHECK(graph.IsNodeValid(node)); + DCHECK(arc == Base::kNilArc || arc >= 0); + DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node); + } + bool Ok() const { return index_ != Base::kNilArc; } + ArcIndexType Index() const { return index_; } + void Next() { + DCHECK(Ok()); + index_ = graph_.next_[index_]; + } + + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator); + + private: + const ReverseArcListGraph& graph_; + ArcIndexType index_; +}; + +template +class ReverseArcListGraph::IncomingArcIterator { + public: + IncomingArcIterator(const ReverseArcListGraph& graph, NodeIndexType node) + : graph_(graph), index_(graph.reverse_start_[node]) { + DCHECK(graph.IsNodeValid(node)); + } + IncomingArcIterator(const ReverseArcListGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(graph), + index_(arc == Base::kNilArc ? Base::kNilArc : graph.OppositeArc(arc)) { + DCHECK(graph.IsNodeValid(node)); + DCHECK(arc == Base::kNilArc || arc >= 0); + DCHECK(arc == Base::kNilArc || graph.Head(arc) == node); + } + + bool Ok() const { return index_ != Base::kNilArc; } + ArcIndexType Index() const { + return index_ == Base::kNilArc ? Base::kNilArc : graph_.OppositeArc(index_); + } + void Next() { + DCHECK(Ok()); + index_ = graph_.next_[index_]; + } + + DEFINE_STL_ITERATOR_FUNCTIONS(IncomingArcIterator); + + private: + const ReverseArcListGraph& graph_; + ArcIndexType index_; +}; + +template +class ReverseArcListGraph::OutgoingOrOppositeIncomingArcIterator { + public: + OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph& graph, + NodeIndexType node) + : graph_(graph), index_(graph.reverse_start_[node]), node_(node) { + DCHECK(graph.IsNodeValid(node)); + if (index_ == Base::kNilArc) index_ = graph.start_[node]; + } + OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph& graph, + NodeIndexType node, ArcIndexType arc) + : graph_(graph), index_(arc), node_(node) { + DCHECK(graph.IsNodeValid(node)); + DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node); + } + + bool Ok() const { return index_ != Base::kNilArc; } + ArcIndexType Index() const { return index_; } + void Next() { + DCHECK(Ok()); + if (index_ < 0) { + index_ = graph_.next_[index_]; + if (index_ == Base::kNilArc) { + index_ = graph_.start_[node_]; + } + } else { + index_ = graph_.next_[index_]; + } + } + + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator); + + private: + const ReverseArcListGraph& graph_; + ArcIndexType index_; + const NodeIndexType node_; +}; + +template +class ReverseArcListGraph::OutgoingHeadIterator { + public: + OutgoingHeadIterator(const ReverseArcListGraph& graph, NodeIndexType node) + : graph_(&graph), index_(graph.start_[node]) { + DCHECK(graph.IsNodeValid(node)); + } + OutgoingHeadIterator(const ReverseArcListGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(&graph), index_(arc) { + DCHECK(graph.IsNodeValid(node)); + DCHECK(arc == Base::kNilArc || arc >= 0); + DCHECK(arc == Base::kNilArc || graph.Tail(arc) == node); + } + bool Ok() const { return index_ != Base::kNilArc; } + ArcIndexType Index() const { return graph_->Head(index_); } + void Next() { + DCHECK(Ok()); + index_ = graph_->next_[index_]; + } + + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingHeadIterator); + + private: + const ReverseArcListGraph* graph_; + ArcIndexType index_; +}; + +// ReverseArcStaticGraph implementation ---------------------------------------- + +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcStaticGraph, Outgoing, + DirectArcLimit(node)); +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcStaticGraph, Incoming, + ReverseArcLimit(node)); +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcStaticGraph, + OutgoingOrOppositeIncoming, + DirectArcLimit(node)); + +template +ArcIndexType ReverseArcStaticGraph::OutDegree( + NodeIndexType node) const { + return DirectArcLimit(node) - start_[node]; +} + +template +ArcIndexType ReverseArcStaticGraph::InDegree( + NodeIndexType node) const { + return ReverseArcLimit(node) - reverse_start_[node]; +} + +template +BeginEndWrapper ReverseArcStaticGraph< + NodeIndexType, ArcIndexType>::operator[](NodeIndexType node) const { + return BeginEndWrapper( + head_.data() + start_[node], head_.data() + DirectArcLimit(node)); +} + +template +ArcIndexType ReverseArcStaticGraph::OppositeArc( + ArcIndexType arc) const { + DCHECK(is_built_); + DCHECK(IsArcValid(arc)); + return opposite_[arc]; +} + +template +NodeIndexType ReverseArcStaticGraph::Head( + ArcIndexType arc) const { + DCHECK(is_built_); + DCHECK(IsArcValid(arc)); + return head_[arc]; +} + +template +NodeIndexType ReverseArcStaticGraph::Tail( + ArcIndexType arc) const { + DCHECK(is_built_); + return head_[OppositeArc(arc)]; +} + +template +void ReverseArcStaticGraph::ReserveArcs( + ArcIndexType bound) { + Base::ReserveArcs(bound); + if (bound <= num_arcs_) return; + head_.reserve(bound); +} + +template +void ReverseArcStaticGraph::AddNode( + NodeIndexType node) { + if (node < num_nodes_) return; + DCHECK(!const_capacities_ || node < node_capacity_); + num_nodes_ = node + 1; +} + +template +ArcIndexType ReverseArcStaticGraph::AddArc( + NodeIndexType tail, NodeIndexType head) { + DCHECK_GE(tail, 0); + DCHECK_GE(head, 0); + AddNode(tail > head ? tail : head); + + // We inverse head and tail here because it is more convenient this way + // during build time, see Build(). + head_.grow(head, tail); + DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_); + return num_arcs_++; +} + +template +void ReverseArcStaticGraph::Build( + std::vector* permutation) { + DCHECK(!is_built_); + if (is_built_) return; + is_built_ = true; + node_capacity_ = num_nodes_; + arc_capacity_ = num_arcs_; + this->FreezeCapacities(); + this->BuildStartAndForwardHead(&head_, &start_, permutation); + + // Computes incoming degree of each nodes. + reverse_start_.assign(num_nodes_, 0); + for (int i = 0; i < num_arcs_; ++i) { + reverse_start_[head_[i]]++; + } + this->ComputeCumulativeSum(&reverse_start_); + + // Computes the reverse arcs of the forward arcs. + // Note that this sort the reverse arcs with the same tail by head. + opposite_.reserve(num_arcs_); + for (int i = 0; i < num_arcs_; ++i) { + // TODO(user): the 0 is wasted here, but minor optimisation. + opposite_.grow(0, reverse_start_[head_[i]]++ - num_arcs_); + } + + // Computes in reverse_start_ the start index of the reverse arcs. + for (int i = num_nodes_ - 1; i > 0; --i) { + reverse_start_[i] = reverse_start_[i - 1] - num_arcs_; + } + if (num_nodes_ != 0) { + reverse_start_[0] = -num_arcs_; + } + + // Fill reverse arc information. + for (int i = 0; i < num_arcs_; ++i) { + opposite_[opposite_[i]] = i; + } + for (const NodeIndexType node : Base::AllNodes()) { + for (const ArcIndexType arc : OutgoingArcs(node)) { + head_[opposite_[arc]] = node; + } + } +} + +template +class ReverseArcStaticGraph::OutgoingArcIterator { + public: + OutgoingArcIterator(const ReverseArcStaticGraph& graph, NodeIndexType node) + : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {} + OutgoingArcIterator(const ReverseArcStaticGraph& graph, NodeIndexType node, + ArcIndexType arc) + : index_(arc), limit_(graph.DirectArcLimit(node)) { + DCHECK_GE(arc, graph.start_[node]); + } + + bool Ok() const { return index_ < limit_; } + ArcIndexType Index() const { return index_; } + void Next() { + DCHECK(Ok()); + index_++; + } + + // TODO(user): we lose a bit by returning a BeginEndWrapper<> on top of this + // iterator rather than a simple IntegerRange on the arc indices. + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator); + + private: + ArcIndexType index_; + const ArcIndexType limit_; +}; + +template +class ReverseArcStaticGraph::IncomingArcIterator { + public: + IncomingArcIterator(const ReverseArcStaticGraph& graph, NodeIndexType node) + : graph_(graph), + limit_(graph.ReverseArcLimit(node)), + index_(graph.reverse_start_[node]) { + DCHECK(graph.IsNodeValid(node)); + DCHECK_LE(index_, limit_); + } + IncomingArcIterator(const ReverseArcStaticGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(graph), + limit_(graph.ReverseArcLimit(node)), + index_(arc == limit_ ? limit_ : graph_.OppositeArc(arc)) { + DCHECK(graph.IsNodeValid(node)); + DCHECK_GE(index_, graph.reverse_start_[node]); + DCHECK_LE(index_, limit_); + } + + bool Ok() const { return index_ < limit_; } + ArcIndexType Index() const { + return index_ == limit_ ? limit_ : graph_.OppositeArc(index_); + } + void Next() { + DCHECK(Ok()); + index_++; + } + + DEFINE_STL_ITERATOR_FUNCTIONS(IncomingArcIterator); + + private: + const ReverseArcStaticGraph& graph_; + const ArcIndexType limit_; + ArcIndexType index_; +}; + +template +class ReverseArcStaticGraph< + NodeIndexType, ArcIndexType>::OutgoingOrOppositeIncomingArcIterator { + public: + OutgoingOrOppositeIncomingArcIterator(const ReverseArcStaticGraph& graph, + NodeIndexType node) + : index_(graph.reverse_start_[node]), + first_limit_(graph.ReverseArcLimit(node)), + next_start_(graph.start_[node]), + limit_(graph.DirectArcLimit(node)) { + if (index_ == first_limit_) index_ = next_start_; + DCHECK(graph.IsNodeValid(node)); + DCHECK((index_ < first_limit_) || (index_ >= next_start_)); + } + OutgoingOrOppositeIncomingArcIterator(const ReverseArcStaticGraph& graph, + NodeIndexType node, ArcIndexType arc) + : index_(arc), + first_limit_(graph.ReverseArcLimit(node)), + next_start_(graph.start_[node]), + limit_(graph.DirectArcLimit(node)) { + DCHECK(graph.IsNodeValid(node)); + DCHECK((index_ >= graph.reverse_start_[node] && index_ < first_limit_) || + (index_ >= next_start_)); + } + + ArcIndexType Index() const { return index_; } + bool Ok() const { return index_ < limit_; } + void Next() { + DCHECK(Ok()); + index_++; + if (index_ == first_limit_) { + index_ = next_start_; + } + } + + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator); + + private: + ArcIndexType index_; + const ArcIndexType first_limit_; + const ArcIndexType next_start_; + const ArcIndexType limit_; +}; + +// ReverseArcMixedGraph implementation ----------------------------------------- + +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcMixedGraph, Outgoing, + DirectArcLimit(node)); +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcMixedGraph, Incoming, Base::kNilArc); +DEFINE_RANGE_BASED_ARC_ITERATION(ReverseArcMixedGraph, + OutgoingOrOppositeIncoming, + DirectArcLimit(node)); + +template +ArcIndexType ReverseArcMixedGraph::OutDegree( + NodeIndexType node) const { + return DirectArcLimit(node) - start_[node]; +} + +template +ArcIndexType ReverseArcMixedGraph::InDegree( + NodeIndexType node) const { + ArcIndexType degree(0); + for (auto arc ATTRIBUTE_UNUSED : IncomingArcs(node)) ++degree; + return degree; +} + +template +BeginEndWrapper ReverseArcMixedGraph< + NodeIndexType, ArcIndexType>::operator[](NodeIndexType node) const { + return BeginEndWrapper( + head_.data() + start_[node], head_.data() + DirectArcLimit(node)); +} + +template +ArcIndexType ReverseArcMixedGraph::OppositeArc( + ArcIndexType arc) const { + DCHECK(IsArcValid(arc)); + return ~arc; +} + +template +NodeIndexType ReverseArcMixedGraph::Head( + ArcIndexType arc) const { + DCHECK(is_built_); + DCHECK(IsArcValid(arc)); + return head_[arc]; +} + +template +NodeIndexType ReverseArcMixedGraph::Tail( + ArcIndexType arc) const { + DCHECK(is_built_); + return head_[OppositeArc(arc)]; +} + +template +void ReverseArcMixedGraph::ReserveArcs( + ArcIndexType bound) { + Base::ReserveArcs(bound); + if (bound <= num_arcs_) return; + head_.reserve(bound); +} + +template +void ReverseArcMixedGraph::AddNode( + NodeIndexType node) { + if (node < num_nodes_) return; + DCHECK(!const_capacities_ || node < node_capacity_); + num_nodes_ = node + 1; +} + +template +ArcIndexType ReverseArcMixedGraph::AddArc( + NodeIndexType tail, NodeIndexType head) { + DCHECK_GE(tail, 0); + DCHECK_GE(head, 0); + AddNode(tail > head ? tail : head); + + // We inverse head and tail here because it is more convenient this way + // during build time, see Build(). + head_.grow(head, tail); + DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_); + return num_arcs_++; +} + +template +void ReverseArcMixedGraph::Build( + std::vector* permutation) { + DCHECK(!is_built_); + if (is_built_) return; + is_built_ = true; + node_capacity_ = num_nodes_; + arc_capacity_ = num_arcs_; + this->FreezeCapacities(); + this->BuildStartAndForwardHead(&head_, &start_, permutation); + + // Fill tails. + for (const NodeIndexType node : Base::AllNodes()) { + for (const ArcIndexType arc : OutgoingArcs(node)) { + head_[~arc] = node; + } + } + + // Fill information for iterating over reverse arcs. + reverse_start_.assign(num_nodes_, Base::kNilArc); + next_.reserve(num_arcs_); + for (const ArcIndexType arc : Base::AllForwardArcs()) { + next_.push_back(reverse_start_[Head(arc)]); + reverse_start_[Head(arc)] = -next_.size(); + } +} + +template +class ReverseArcMixedGraph::OutgoingArcIterator { + public: + OutgoingArcIterator(const ReverseArcMixedGraph& graph, NodeIndexType node) + : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {} + OutgoingArcIterator(const ReverseArcMixedGraph& graph, NodeIndexType node, + ArcIndexType arc) + : index_(arc), limit_(graph.DirectArcLimit(node)) { + DCHECK_GE(arc, graph.start_[node]); + } + + bool Ok() const { return index_ < limit_; } + ArcIndexType Index() const { return index_; } + void Next() { + DCHECK(Ok()); + index_++; + } + + // TODO(user): we lose a bit by returning a BeginEndWrapper<> on top of this + // iterator rather than a simple IntegerRange on the arc indices. + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingArcIterator); + + private: + ArcIndexType index_; + const ArcIndexType limit_; +}; + +template +class ReverseArcMixedGraph::IncomingArcIterator { + public: + IncomingArcIterator(const ReverseArcMixedGraph& graph, NodeIndexType node) + : graph_(&graph) { + DCHECK(graph.is_built_); + DCHECK(graph.IsNodeValid(node)); + index_ = graph.reverse_start_[node]; + } + IncomingArcIterator(const ReverseArcMixedGraph& graph, NodeIndexType node, + ArcIndexType arc) + : graph_(&graph) { + DCHECK(graph.is_built_); + DCHECK(graph.IsNodeValid(node)); + DCHECK(arc == Base::kNilArc || arc >= 0); + DCHECK(arc == Base::kNilArc || graph.Head(arc) == node); + index_ = arc == Base::kNilArc ? arc : graph.OppositeArc(arc); + } + bool Ok() const { return index_ != Base::kNilArc; } + ArcIndexType Index() const { + return index_ == Base::kNilArc ? Base::kNilArc + : graph_->OppositeArc(index_); + } + void Next() { + DCHECK(Ok()); + index_ = graph_->next_[~index_]; + } + + DEFINE_STL_ITERATOR_FUNCTIONS(IncomingArcIterator); + + private: + const ReverseArcMixedGraph* graph_; + ArcIndexType index_; +}; + +template +class ReverseArcMixedGraph< + NodeIndexType, ArcIndexType>::OutgoingOrOppositeIncomingArcIterator { + public: + OutgoingOrOppositeIncomingArcIterator(const ReverseArcMixedGraph& graph, + NodeIndexType node) + : graph_(&graph) { + limit_ = graph.DirectArcLimit(node); // also DCHECKs node and is_built_. + index_ = graph.reverse_start_[node]; + restart_ = graph.start_[node]; + if (index_ == Base::kNilArc) { + index_ = restart_; + } + } + OutgoingOrOppositeIncomingArcIterator(const ReverseArcMixedGraph& graph, + NodeIndexType node, ArcIndexType arc) + : graph_(&graph) { + limit_ = graph.DirectArcLimit(node); + index_ = arc; + restart_ = graph.start_[node]; + DCHECK(arc == Base::kNilArc || arc == limit_ || graph.Tail(arc) == node); + } + bool Ok() const { + // Note that we always have limit_ <= Base::kNilArc. + return index_ < limit_; + } + ArcIndexType Index() const { return index_; } + void Next() { + DCHECK(Ok()); + if (index_ < 0) { + index_ = graph_->next_[graph_->OppositeArc(index_)]; + if (index_ == Base::kNilArc) { + index_ = restart_; + } + } else { + index_++; + } + } + + DEFINE_STL_ITERATOR_FUNCTIONS(OutgoingOrOppositeIncomingArcIterator); + + private: + const ReverseArcMixedGraph* graph_; + ArcIndexType index_; + ArcIndexType restart_; + ArcIndexType limit_; +}; + +// CompleteGraph implementation ------------------------------------------------ +// Nodes and arcs are implicit and not stored. + +template +class CompleteGraph : public BaseGraph { + typedef BaseGraph Base; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::arc_capacity_; + using Base::node_capacity_; + using Base::const_capacities_; + + public: + // Builds a complete graph with num_nodes nodes. + explicit CompleteGraph(NodeIndexType num_nodes) { + this->Reserve(num_nodes, num_nodes * num_nodes); + this->FreezeCapacities(); + num_nodes_ = num_nodes; + num_arcs_ = num_nodes * num_nodes; + } + + NodeIndexType Head(ArcIndexType arc) const; + NodeIndexType Tail(ArcIndexType arc) const; + ArcIndexType OutDegree(NodeIndexType node) const; + IntegerRange OutgoingArcs(NodeIndexType node) const; + IntegerRange OutgoingArcsStartingFrom(NodeIndexType node, + ArcIndexType from) const; + IntegerRange operator[](NodeIndexType node) const; +}; + +template +NodeIndexType CompleteGraph::Head( + ArcIndexType arc) const { + DCHECK(this->IsArcValid(arc)); + return arc % num_nodes_; +} + +template +NodeIndexType CompleteGraph::Tail( + ArcIndexType arc) const { + DCHECK(this->IsArcValid(arc)); + return arc / num_nodes_; +} + +template +ArcIndexType CompleteGraph::OutDegree( + NodeIndexType node) const { + return num_nodes_; +} + +template +IntegerRange CompleteGraph< + NodeIndexType, ArcIndexType>::OutgoingArcs(NodeIndexType node) const { + DCHECK_LT(node, num_nodes_); + return IntegerRange( + static_cast(num_nodes_) * node, + static_cast(num_nodes_) * (node + 1)); +} + +template +IntegerRange +CompleteGraph::OutgoingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const { + DCHECK_LT(node, num_nodes_); + return IntegerRange( + from, static_cast(num_nodes_) * (node + 1)); +} + +template +IntegerRange CompleteGraph:: +operator[](NodeIndexType node) const { + DCHECK_LT(node, num_nodes_); + return IntegerRange(0, num_nodes_); +} + +// CompleteBipartiteGraph implementation --------------------------------------- +// Nodes and arcs are implicit and not stored. + +template +class CompleteBipartiteGraph + : public BaseGraph { + typedef BaseGraph Base; + using Base::num_arcs_; + using Base::num_nodes_; + using Base::arc_capacity_; + using Base::node_capacity_; + using Base::const_capacities_; + + public: + // Builds a complete bipartite graph from a set of left nodes to a set of + // right nodes. + // Indices of left nodes of the bipartite graph range from 0 to left_nodes-1; + // indices of right nodes range from left_nodes to left_nodes+right_nodes-1. + CompleteBipartiteGraph(NodeIndexType left_nodes, NodeIndexType right_nodes) + : left_nodes_(left_nodes), right_nodes_(right_nodes) { + this->Reserve(left_nodes + right_nodes, left_nodes * right_nodes); + this->FreezeCapacities(); + num_nodes_ = left_nodes + right_nodes; + num_arcs_ = left_nodes * right_nodes; + } + + NodeIndexType Head(ArcIndexType arc) const; + NodeIndexType Tail(ArcIndexType arc) const; + ArcIndexType OutDegree(NodeIndexType node) const; + IntegerRange OutgoingArcs(NodeIndexType node) const; + IntegerRange OutgoingArcsStartingFrom(NodeIndexType node, + ArcIndexType from) const; + IntegerRange operator[](NodeIndexType node) const; + + // Deprecated interface. + class OutgoingArcIterator { + public: + OutgoingArcIterator(const CompleteBipartiteGraph& graph, NodeIndexType node) + : index_(graph.right_nodes_ * node), + limit_(node >= graph.left_nodes_ ? index_ + : graph.right_nodes_ * (node + 1)) {} + + bool Ok() const { return index_ < limit_; } + ArcIndexType Index() const { return index_; } + void Next() { index_++; } + + private: + ArcIndexType index_; + const ArcIndexType limit_; + }; + + private: + const NodeIndexType left_nodes_; + const NodeIndexType right_nodes_; +}; + +template +NodeIndexType CompleteBipartiteGraph::Head( + ArcIndexType arc) const { + DCHECK(this->IsArcValid(arc)); + return left_nodes_ + arc % right_nodes_; +} + +template +NodeIndexType CompleteBipartiteGraph::Tail( + ArcIndexType arc) const { + DCHECK(this->IsArcValid(arc)); + return arc / right_nodes_; +} + +template +ArcIndexType CompleteBipartiteGraph::OutDegree( + NodeIndexType node) const { + return (node < left_nodes_) ? right_nodes_ : 0; +} + +template +IntegerRange CompleteBipartiteGraph< + NodeIndexType, ArcIndexType>::OutgoingArcs(NodeIndexType node) const { + if (node < left_nodes_) { + return IntegerRange(right_nodes_ * node, + right_nodes_ * (node + 1)); + } else { + return IntegerRange(0, 0); + } +} + +template +IntegerRange +CompleteBipartiteGraph::OutgoingArcsStartingFrom( + NodeIndexType node, ArcIndexType from) const { + if (node < left_nodes_) { + return IntegerRange(from, right_nodes_ * (node + 1)); + } else { + return IntegerRange(0, 0); + } +} + +template +IntegerRange CompleteBipartiteGraph< + NodeIndexType, ArcIndexType>::operator[](NodeIndexType node) const { + if (node < left_nodes_) { + return IntegerRange(left_nodes_, left_nodes_ + right_nodes_); + } else { + return IntegerRange(0, 0); + } +} + +} // namespace operations_research + +#undef DEFINE_RANGE_BASED_ARC_ITERATION +#undef DEFINE_STL_ITERATOR_FUNCTIONS + +#endif // OR_TOOLS_GRAPH_GRAPH_H_ diff --git a/thirdparty/linux/include/ortools/graph/graphs.h b/thirdparty/linux/include/ortools/graph/graphs.h new file mode 100644 index 0000000..5a2bf8d --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/graphs.h @@ -0,0 +1,79 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Temporary utility class needed as long as we have two slightly +// different graph interface: The one in ebert_graph.h and the one in graph.h + +#ifndef OR_TOOLS_GRAPH_GRAPHS_H_ +#define OR_TOOLS_GRAPH_GRAPHS_H_ + +#include "ortools/graph/ebert_graph.h" +#include "ortools/graph/graph.h" + +namespace operations_research { + +// Since StarGraph does not have exactly the same interface as the other +// graphs, we define a correspondance there. +template +struct Graphs { + typedef typename Graph::ArcIndex ArcIndex; + typedef typename Graph::NodeIndex NodeIndex; + static ArcIndex OppositeArc(const Graph& graph, ArcIndex arc) { + return graph.OppositeArc(arc); + } + static bool IsArcValid(const Graph& graph, ArcIndex arc) { + return graph.IsArcValid(arc); + } + static NodeIndex NodeReservation(const Graph& graph) { + return graph.node_capacity(); + } + static ArcIndex ArcReservation(const Graph& graph) { + return graph.arc_capacity(); + } + static void Build(Graph* graph) { graph->Build(); } + static void Build(Graph* graph, std::vector* permutation) { + graph->Build(permutation); + } +}; + +template <> +struct Graphs { + typedef operations_research::StarGraph Graph; +#if defined(_MSC_VER) + typedef Graph::ArcIndex ArcIndex; + typedef Graph::NodeIndex NodeIndex; +#else + typedef typename Graph::ArcIndex ArcIndex; + typedef typename Graph::NodeIndex NodeIndex; +#endif + static ArcIndex OppositeArc(const Graph& graph, ArcIndex arc) { + return graph.Opposite(arc); + } + static bool IsArcValid(const Graph& graph, ArcIndex arc) { + return graph.CheckArcValidity(arc); + } + static NodeIndex NodeReservation(const Graph& graph) { + return graph.max_num_nodes(); + } + static ArcIndex ArcReservation(const Graph& graph) { + return graph.max_num_arcs(); + } + static void Build(Graph* graph) {} + static void Build(Graph* graph, std::vector* permutation) { + permutation->clear(); + } +}; + +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_GRAPHS_H_ diff --git a/thirdparty/linux/include/ortools/graph/hamiltonian_path.h b/thirdparty/linux/include/ortools/graph/hamiltonian_path.h new file mode 100644 index 0000000..a0c82dc --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/hamiltonian_path.h @@ -0,0 +1,1020 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_GRAPH_HAMILTONIAN_PATH_H_ +#define OR_TOOLS_GRAPH_HAMILTONIAN_PATH_H_ + +// Solves the Shortest Hamiltonian Path Problem using a complete algorithm. +// The algorithm was first described in +// M. Held, R.M. Karp, A dynamic programming approach to sequencing problems, +// J. SIAM 10 (1962) 196–210 +// +// The Shortest Hamiltonian Path Problem (SHPP) is similar to the Traveling +// Salesperson Problem (TSP). +// You have to visit all the cities, starting from a given one and you +// do not need to return to your starting point. With the TSP, you can start +// anywhere, but you have to return to your start location. +// +// By complete we mean that the algorithm guarantees to compute the optimal +// solution. The algorithm uses dynamic programming. Its time complexity is +// O(n^2 * 2^(n-1)), where n is the number of nodes to be visited, and '^' +// denotes exponentiation. Its space complexity is O(n * 2 ^ (n - 1)). +// +// Note that the naive implementation of the SHPP +// exploring all permutations without memorizing intermediate results would +// have a complexity of (n - 1)! (factorial of (n - 1) ), which is much higher +// than n^2 * 2^(n-1). To convince oneself of this, just use Stirling's +// formula: n! ~ sqrt(2 * pi * n)*( n / exp(1)) ^ n. +// Because of these complexity figures, the algorithm is not practical for +// problems with more than 20 nodes. +// +// Here is how the algorithm works: +// Let us denote the nodes to be visited by their indices 0 .. n - 1 +// Let us pick 0 as the starting node. +// Let d(i,j) denote the distance (or cost) from i to j. +// f(S, j) where S is a set of nodes and j is a node in S is defined as follows: +// f(S, j) = min (i in S \ {j}, f(S \ {j}, i) + cost(i, j)) +// (j is an element of S) +// Note that this formulation, from the original Held-Karp paper is a bit +// different, but equivalent to the one used in Caseau and Laburthe, Solving +// Small TSPs with Constraints, 1997, ICLP +// f(S, j) = min (i in S, f(S \ {i}, i) + cost(i, j)) +// (j is not an element of S) +// +// The advantage of the Held and Karp formulation is that it enables: +// - to build the dynamic programming lattice layer by layer starting from the +// subsets with cardinality 1, and increasing the cardinality. +// - to traverse the dynamic programming lattice using sequential memory +// accesses, making the algorithm cache-friendly, and faster, despite the large +// amount of computation needed to get the position when f(S, j) is stored. +// - TODO(user): implement pruning procedures on top of the Held-Karp algorithm. +// +// The set S can be represented by an integer where bit i corresponds to +// element i in the set. In the following S denotes the integer corresponding +// to set S. +// +// The dynamic programming iteration is implemented in the method Solve. +// The optimal value of the Hamiltonian path starting at 0 is given by +// min (i in S, f(2 ^ n - 1, i)) +// The optimal value of the Traveling Salesman tour is given by f(2 ^ n, 0). +// (There is actually no need to duplicate the first node, as all the paths +// are computed from node 0.) +// +// To implement dynamic programming, we store the preceding results of +// computing f(S,j) in an array M[Offset(S,j)]. See the comments about +// LatticeMemoryManager::BaseOffset() to see how this is computed. +// +// Keywords: Traveling Salesman, Hamiltonian Path, Dynamic Programming, +// Held, Karp. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/util/bitset.h" +#include "ortools/util/saturated_arithmetic.h" +#include "ortools/util/vector_or_function.h" + +namespace operations_research { + +// TODO(user): Move the Set-related classbelow to util/bitset.h +// Iterates over the elements of a set represented as an unsigned integer, +// starting from the smallest element. (See the class Set below.) +template +class ElementIterator { + public: + explicit ElementIterator(Set set) : current_set_(set) {} + bool operator!=(const ElementIterator& other) const { + return current_set_ != other.current_set_; + } + + // Returns the smallest element in the current_set_. + int operator*() const { return current_set_.SmallestElement(); } + + // Advances the iterator by removing its smallest element. + const ElementIterator& operator++() { + current_set_ = current_set_.RemoveSmallestElement(); + return *this; + } + + private: + // The current position of the iterator. Stores the set consisting of the + // not-yet iterated elements. + Set current_set_; +}; + +template +class Set { + public: + // Make this visible to classes using this class. + typedef Integer IntegerType; + + // Useful constants. + static const Integer One = static_cast(1); + static const Integer Zero = static_cast(0); + static const int MaxCardinality = 8 * sizeof(Integer); // NOLINT + + // Construct a set from an Integer. + explicit Set(Integer n) : value_(n) { + static_assert(std::is_integral::value, "Integral type required"); + static_assert(std::is_unsigned::value, "Unsigned type required"); + } + + // Returns the integer corresponding to the set. + Integer value() const { return value_; } + + static Set FullSet(Integer card) { + return card == 0 ? Set(0) : Set(~Zero >> (MaxCardinality - card)); + } + + // Returns the singleton set with 'n' as its only element. + static Set Singleton(Integer n) { return Set(One << n); } + + // Returns a set equal to the calling object, with element n added. + // If n is already in the set, no operation occurs. + Set AddElement(int n) const { return Set(value_ | (One << n)); } + + // Returns a set equal to the calling object, with element n removed. + // If n is not in the set, no operation occurs. + Set RemoveElement(int n) const { return Set(value_ & ~(One << n)); } + + // Returns true if the calling set contains element n. + bool Contains(int n) const { return ((One << n) & value_) != 0; } + + // Returns true if 'other' is included in the calling set. + bool Includes(Set other) const { + return (value_ & other.value_) == other.value_; + } + + // Returns the number of elements in the set. Uses the 32-bit version for + // types that have 32-bits or less. Specialized for uint64. + int Cardinality() const { return BitCount32(value_); } + + // Returns the index of the smallest element in the set. Uses the 32-bit + // version for types that have 32-bits or less. Specialized for uint64. + int SmallestElement() const { return LeastSignificantBitPosition32(value_); } + + // Returns a set equal to the calling object, with its smallest + // element removed. + Set RemoveSmallestElement() const { return Set(value_ & (value_ - 1)); } + + // Returns the rank of an element in a set. For the set 11100, ElementRank(4) + // would return 2. (Ranks start at zero). + int ElementRank(int n) const { + DCHECK(Contains(n)) << "n = " << n << ", value_ = " << value_; + return SingletonRank(Singleton(n)); + } + + // Returns the set consisting of the smallest element of the calling object. + Set SmallestSingleton() const { return Set(value_ & -value_); } + + // Returns the rank of the singleton's element in the calling Set. + int SingletonRank(Set singleton) const { + DCHECK_EQ(singleton.value(), singleton.SmallestSingleton().value()); + return Set(value_ & (singleton.value_ - 1)).Cardinality(); + } + + // STL iterator-related member functions. + ElementIterator begin() const { + return ElementIterator(Set(value_)); + } + ElementIterator end() const { return ElementIterator(Set(0)); } + bool operator!=(const Set& other) const { return value_ != other.value_; } + + private: + // The Integer representing the set. + Integer value_; +}; + +template <> +inline int Set::SmallestElement() const { + return LeastSignificantBitPosition64(value_); +} + +template <> +inline int Set::Cardinality() const { + return BitCount64(value_); +} + +// An iterator for sets of increasing corresponding values that have the same +// cardinality. For example, the sets with cardinality 3 will be listed as +// ...00111, ...01011, ...01101, ...1110, etc... +template +class SetRangeIterator { + public: + // Make the parameter types visible to SetRangeWithCardinality. + typedef typename SetRange::SetType SetType; + typedef typename SetType::IntegerType IntegerType; + + explicit SetRangeIterator(const SetType set) : current_set_(set) {} + + // STL iterator-related methods. + SetType operator*() const { return current_set_; } + bool operator!=(const SetRangeIterator& other) const { + return current_set_ != other.current_set_; + } + + // Computes the next set with the same cardinality using Gosper's hack. + // ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-239.pdf ITEM 175 + // Also translated in C https://www.cl.cam.ac.uk/~am21/hakmemc.html + const SetRangeIterator& operator++() { + const IntegerType c = current_set_.SmallestSingleton().value(); + const IntegerType a = current_set_.value(); + const IntegerType r = c + current_set_.value(); + // Dividing by c as in HAKMEMC can be avoided by taking into account + // that c is the smallest singleton of current_set_, and using a shift. + const IntegerType shift = current_set_.SmallestElement(); + current_set_ = r == 0 ? SetType(0) : SetType(((r ^ a) >> (shift + 2)) | r); + return *this; + } + + private: + // The current set of iterator. + SetType current_set_; +}; + +template +class SetRangeWithCardinality { + public: + typedef Set SetType; + // The end_ set is the first set with cardinality card, that does not fit + // in max_card bits. Thus, its bit at position max_card is set, and the + // rightmost (card - 1) bits are set. + SetRangeWithCardinality(int card, int max_card) + : begin_(Set::FullSet(card)), + end_(Set::FullSet(card - 1).AddElement(max_card)) { + DCHECK_LT(0, card); + DCHECK_LT(0, max_card); + DCHECK_EQ(card, begin_.Cardinality()); + DCHECK_EQ(card, end_.Cardinality()); + } + + // STL iterator-related methods. + SetRangeIterator begin() const { + return SetRangeIterator(begin_); + } + SetRangeIterator end() const { + return SetRangeIterator(end_); + } + + private: + // Keep the beginning and end of the iterator. + SetType begin_; + SetType end_; +}; + +// The Dynamic Programming (DP) algorithm memorizes the values f(set, node) for +// node in set, for all the subsets of cardinality <= max_card_. +// LatticeMemoryManager manages the storage of f(set, node) so that the +// DP iteration access memory in increasing addresses. +template +class LatticeMemoryManager { + public: + LatticeMemoryManager() : max_card_(0) {} + + // Reserves memory and fills in the data necessary to access memory. + void Init(int max_card); + + // Returns the offset in memory for f(s, node), with node contained in s. + uint64 Offset(Set s, int node) const; + + // Returns the base offset in memory for f(s, node), with node contained in s. + // This is useful in the Dynamic Programming iterations. + // Note(user): inlining this function gains about 5%. + // TODO(user): Investigate how to compute BaseOffset(card - 1, s \ { n }) + // from BaseOffset(card, n) to speed up the DP iteration. + inline uint64 BaseOffset(int card, Set s) const; + + // Returns the offset delta for a set of cardinality 'card', to which + // node 'removed_node' is replaced by 'added_node' at 'rank' + uint64 OffsetDelta(int card, int added_node, int removed_node, + int rank) const { + return card * + (binomial_coefficients_[added_node][rank] - // delta for added_node + binomial_coefficients_[removed_node][rank]); // for removed_node. + } + + // Memorizes the value = f(s, node) at the correct offset. + // This is favored in all other uses than the Dynamic Programming iterations. + void SetValue(Set s, int node, CostType value); + + // Memorizes 'value' at 'offset'. This is useful in the Dynamic Programming + // iterations where we want to avoid compute the offset of a pair (set, node). + void SetValueAtOffset(uint64 offset, CostType value) { + memory_[offset] = value; + } + + // Returns the memorized value f(s, node) with node in s. + // This is favored in all other uses than the Dynamic Programming iterations. + CostType Value(Set s, int node) const; + + // Returns the memorized value at 'offset'. + // This is useful in the Dynamic Programming iterations. + CostType ValueAtOffset(uint64 offset) const { return memory_[offset]; } + + private: + // Returns true if the values used to manage memory are set correctly. + // This is intended to only be used in a DCHECK. + bool CheckConsistency() const; + + // The maximum cardinality of the set on which the lattice is going to be + // used. This is equal to the number of nodes in the TSP. + int max_card_; + + // binomial_coefficients_[n][k] contains (n choose k). + std::vector> binomial_coefficients_; + + // base_offset_[card] contains the base offset for all f(set, node) with + // card(set) == card. + std::vector base_offset_; + + // memory_[Offset(set, node)] contains the costs of the partial path + // f(set, node). + std::vector memory_; +}; + +template +void LatticeMemoryManager::Init(int max_card) { + DCHECK_LT(0, max_card); + DCHECK_GE(Set::MaxCardinality, max_card); + if (max_card <= max_card_) return; + max_card_ = max_card; + binomial_coefficients_.resize(max_card_ + 1); + + // Initialize binomial_coefficients_ using Pascal's triangle recursion. + for (int n = 0; n <= max_card_; ++n) { + binomial_coefficients_[n].resize(n + 2); + binomial_coefficients_[n][0] = 1; + for (int k = 1; k <= n; ++k) { + binomial_coefficients_[n][k] = binomial_coefficients_[n - 1][k - 1] + + binomial_coefficients_[n - 1][k]; + } + // Extend to (n, n + 1) to minimize branchings in LatticeMemoryManager(). + // This also makes the recurrence above work for k = n. + binomial_coefficients_[n][n + 1] = 0; + } + base_offset_.resize(max_card_ + 1); + base_offset_[0] = 0; + // There are k * binomial_coefficients_[max_card_][k] f(S,j) values to store + // for each group of f(S,j), with card(S) = k. Update base_offset[k] + // accordingly. + for (int k = 0; k < max_card_; ++k) { + base_offset_[k + 1] = + base_offset_[k] + k * binomial_coefficients_[max_card_][k]; + } + memory_.resize(0); + memory_.shrink_to_fit(); + memory_.resize(max_card_ * (1 << (max_card_ - 1))); + DCHECK(CheckConsistency()); +} + +template +bool LatticeMemoryManager::CheckConsistency() const { + for (int n = 0; n <= max_card_; ++n) { + int64 sum = 0; + for (int k = 0; k <= n; ++k) { + sum += binomial_coefficients_[n][k]; + } + DCHECK_EQ(1 << n, sum); + } + DCHECK_EQ(0, base_offset_[1]); + DCHECK_EQ(max_card_ * (1 << (max_card_ - 1)), + base_offset_[max_card_] + max_card_); + return true; +} + +template +uint64 LatticeMemoryManager::BaseOffset(int card, + Set set) const { + DCHECK_LT(0, card); + DCHECK_EQ(set.Cardinality(), card); + uint64 local_offset = 0; + int node_rank = 0; + for (int node : set) { + // There are binomial_coefficients_[node][node_rank + 1] sets which have + // node at node_rank. + local_offset += binomial_coefficients_[node][node_rank + 1]; + ++node_rank; + } + DCHECK_EQ(card, node_rank); + // Note(user): It is possible to get rid of base_offset_[card] by using a 2-D + // array. It would also make it possible to free all the memory but the layer + // being constructed and the preceding one, if another lattice of paths is + // constructed. + // TODO(user): Evaluate the interest of the above. + // There are 'card' f(set, j) to store. That is why we need to multiply + // local_offset by card before adding it to the corresponding base_offset_. + return base_offset_[card] + card * local_offset; +} + +template +uint64 LatticeMemoryManager::Offset(Set set, int node) const { + DCHECK(set.Contains(node)); + return BaseOffset(set.Cardinality(), set) + set.ElementRank(node); +} + +template +CostType LatticeMemoryManager::Value(Set set, int node) const { + DCHECK(set.Contains(node)); + return ValueAtOffset(Offset(set, node)); +} + +template +void LatticeMemoryManager::SetValue(Set set, int node, + CostType value) { + DCHECK(set.Contains(node)); + SetValueAtOffset(Offset(set, node), value); +} + +// Deprecated type. +typedef int PathNodeIndex; + +template +class HamiltonianPathSolver { + // HamiltonianPathSolver computes a minimum Hamiltonian path starting at node + // 0 over a graph defined by a cost matrix. The cost function need not be + // symmetric. + // When the Hamiltonian path is closed, it's a Hamiltonian cycle, + // i.e. the algorithm solves the Traveling Salesman Problem. + // Example: + + // std::vector> cost_mat; + // ... fill in cost matrix + // HamiltonianPathSolver>> + // mhp(cost_mat); // no computation done + // printf("%d\n", mhp.TravelingSalesmanCost()); // computation done and + // stored + public: + // In 2010, 26 was the maximum solvable with 24 Gigs of RAM, and it took + // several minutes. With this 2014 version of the code, one may go a little + // higher, but considering the complexity of the algorithm (n*2^n), and that + // there are very good ways to solve TSP with more than 32 cities, + // we limit ourselves to 32 cites. + // This is why we define the type NodeSet to be 32-bit wide. + // TODO(user): remove this limitation by using pruning techniques. + typedef uint32 Integer; + typedef Set NodeSet; + + explicit HamiltonianPathSolver(CostFunction cost); + HamiltonianPathSolver(int num_nodes, CostFunction cost); + + // Replaces the cost matrix while avoiding re-allocating memory. + void ChangeCostMatrix(CostFunction cost); + void ChangeCostMatrix(int num_nodes, CostFunction cost); + + // Returns the cost of the Hamiltonian path from 0 to end_node. + CostType HamiltonianCost(int end_node); + + // Returns the shortest Hamiltonian path from 0 to end_node. + std::vector HamiltonianPath(int end_node); + + // Returns the end-node that yields the shortest Hamiltonian path of + // all shortest Hamiltonian path from 0 to end-node (end-node != 0). + int BestHamiltonianPathEndNode(); + + // Deprecated API. Stores HamiltonianPath(BestHamiltonianPathEndNode()) into + // *path. + void HamiltonianPath(std::vector* path); + + // Returns the cost of the TSP tour. + CostType TravelingSalesmanCost(); + + // Returns the TSP tour in the vector pointed to by the argument. + std::vector TravelingSalesmanPath(); + + // Deprecated API. + void TravelingSalesmanPath(std::vector* path); + + // Returns true if there won't be precision issues. + // This is always true for integers, but not for floating-point types. + bool IsRobust(); + + // Returns true if the cost matrix verifies the triangle inequality. + bool VerifiesTriangleInequality(); + + private: + // Saturated arithmetic helper class. + template + // Returns the saturated addition of a and b. It is specialized below for + // int32 and int64. + struct SaturatedArithmetic { + static T Add(T a, T b) { return a + b; } + static T Sub(T a, T b) { return a - b; } + }; + template + struct SaturatedArithmetic { + static int64 Add(int64 a, int64 b) { return CapAdd(a, b); } + static int64 Sub(int64 a, int64 b) { return CapSub(a, b); } + }; + // TODO(user): implement this natively in saturated_arithmetic.h + template + struct SaturatedArithmetic { + static int32 Add(int32 a, int32 b) { + const int64 a64 = a; + const int64 b64 = b; + const int64 min_int32 = kint32min; + const int64 max_int32 = kint32max; + return static_cast( + std::max(min_int32, std::min(max_int32, a64 + b64))); + } + static int32 Sub(int32 a, int32 b) { + const int64 a64 = a; + const int64 b64 = b; + const int64 min_int32 = kint32min; + const int64 max_int32 = kint32max; + return static_cast( + std::max(min_int32, std::min(max_int32, a64 - b64))); + } + }; + + template + using Saturated = SaturatedArithmetic; + + // Returns the cost value between two nodes. + CostType Cost(int i, int j) { return cost_(i, j); } + + // Does all the Dynamic Progamming iterations. + void Solve(); + + // Computes a path by looking at the information in mem_. + std::vector ComputePath(CostType cost, NodeSet set, int end); + + // Returns true if the path covers all nodes, and its cost is equal to cost. + bool PathIsValid(const std::vector& path, CostType cost); + + // Cost function used to build Hamiltonian paths. + MatrixOrFunction cost_; + + // The number of nodes in the problem. + int num_nodes_; + + // The cost of the computed TSP path. + CostType tsp_cost_; + + // The cost of the computed Hamiltonian path. + std::vector hamiltonian_costs_; + + bool robust_; + bool triangle_inequality_ok_; + bool robustness_checked_; + bool triangle_inequality_checked_; + bool solved_; + std::vector tsp_path_; + + // The vector of smallest Hamiltonian paths starting at 0, indexed by their + // end nodes. + std::vector> hamiltonian_paths_; + + // The end node that gives the smallest Hamiltonian path. The smallest + // Hamiltonian path starting at 0 of all + // is hamiltonian_paths_[best_hamiltonian_path_end_node_]. + int best_hamiltonian_path_end_node_; + + LatticeMemoryManager mem_; +}; + +// Utility function to simplify building a HamiltonianPathSolver from a functor. +template +HamiltonianPathSolver MakeHamiltonianPathSolver( + int num_nodes, CostFunction cost) { + return HamiltonianPathSolver(num_nodes, + std::move(cost)); +} + +template +HamiltonianPathSolver::HamiltonianPathSolver( + CostFunction cost) + : HamiltonianPathSolver(cost.size(), cost) {} + +template +HamiltonianPathSolver::HamiltonianPathSolver( + int num_nodes, CostFunction cost) + : cost_(std::move(cost)), + num_nodes_(num_nodes), + tsp_cost_(0), + hamiltonian_costs_(0), + robust_(true), + triangle_inequality_ok_(true), + robustness_checked_(false), + triangle_inequality_checked_(false), + solved_(false) { + CHECK_GE(NodeSet::MaxCardinality, num_nodes_); + CHECK(cost_.Check()); +} + +template +void HamiltonianPathSolver::ChangeCostMatrix( + CostFunction cost) { + ChangeCostMatrix(cost.size(), cost); +} + +template +void HamiltonianPathSolver::ChangeCostMatrix( + int num_nodes, CostFunction cost) { + robustness_checked_ = false; + triangle_inequality_checked_ = false; + solved_ = false; + cost_.Reset(cost); + num_nodes_ = num_nodes; + CHECK_GE(NodeSet::MaxCardinality, num_nodes_); + CHECK(cost_.Check()); +} + +template +void HamiltonianPathSolver::Solve() { + if (solved_) return; + if (num_nodes_ == 0) { + tsp_cost_ = 0; + tsp_path_ = {0}; + hamiltonian_paths_.resize(1); + hamiltonian_costs_.resize(1); + best_hamiltonian_path_end_node_ = 0; + hamiltonian_costs_[0] = 0; + hamiltonian_paths_[0] = {0}; + return; + } + mem_.Init(num_nodes_); + // Initialize the first layer of the search lattice, taking into account + // that base_offset_[1] == 0. (This is what the DCHECK_EQ is for). + for (int dest = 0; dest < num_nodes_; ++dest) { + DCHECK_EQ(dest, mem_.BaseOffset(1, NodeSet::Singleton(dest))); + mem_.SetValueAtOffset(dest, Cost(0, dest)); + } + + // Populate the dynamic programming lattice layer by layer, by iterating + // on cardinality. + for (int card = 2; card <= num_nodes_; ++card) { + // Iterate on sets of same cardinality. + for (NodeSet set : SetRangeWithCardinality>(card, num_nodes_)) { + // Using BaseOffset and maintaining the node ranks, to reduce the + // computational effort for accessing the data. + const uint64 set_offset = mem_.BaseOffset(card, set); + // The first subset on which we'll iterate is set.RemoveSmallestElement(). + // Compute its offset. It will be updated incrementaly. This saves about + // 30-35% of computation time. + uint64 subset_offset = + mem_.BaseOffset(card - 1, set.RemoveSmallestElement()); + int prev_dest = set.SmallestElement(); + int dest_rank = 0; + for (int dest : set) { + CostType min_cost = std::numeric_limits::max(); + const NodeSet subset = set.RemoveElement(dest); + // We compute the offset for subset from the preceding iteration + // by taking into account that prev_dest is now in subset, and + // that dest is now removed from subset. + subset_offset += mem_.OffsetDelta(card - 1, prev_dest, dest, dest_rank); + int src_rank = 0; + for (int src : subset) { + min_cost = std::min( + min_cost, Saturated::Add( + Cost(src, dest), + mem_.ValueAtOffset(subset_offset + src_rank))); + ++src_rank; + } + prev_dest = dest; + mem_.SetValueAtOffset(set_offset + dest_rank, min_cost); + ++dest_rank; + } + } + } + + const NodeSet full_set = NodeSet::FullSet(num_nodes_); + + // Get the cost of the tsp from node 0. It is the path that leaves 0 and goes + // through all other nodes, and returns at 0, with minimal cost. + tsp_cost_ = mem_.Value(full_set, 0); + tsp_path_ = ComputePath(tsp_cost_, full_set, 0); + + hamiltonian_paths_.resize(num_nodes_); + hamiltonian_costs_.resize(num_nodes_); + // Compute the cost of the Hamiltonian paths starting from node 0, going + // through all the other nodes, and ending at end_node. Compute the minimum + // one along the way. + CostType min_hamiltonian_cost = std::numeric_limits::max(); + const NodeSet hamiltonian_set = full_set.RemoveElement(0); + for (int end_node : hamiltonian_set) { + const CostType cost = mem_.Value(hamiltonian_set, end_node); + hamiltonian_costs_[end_node] = cost; + if (cost <= min_hamiltonian_cost) { + min_hamiltonian_cost = cost; + best_hamiltonian_path_end_node_ = end_node; + } + DCHECK_LE(tsp_cost_, Saturated::Add(cost, Cost(end_node, 0))); + // Get the Hamiltonian paths. + hamiltonian_paths_[end_node] = + ComputePath(hamiltonian_costs_[end_node], hamiltonian_set, end_node); + } + + solved_ = true; +} + +template +std::vector HamiltonianPathSolver::ComputePath( + CostType cost, NodeSet set, int end_node) { + DCHECK(set.Contains(end_node)); + const int path_size = set.Cardinality() + 1; + std::vector path(path_size, 0); + NodeSet subset = set.RemoveElement(end_node); + path[path_size - 1] = end_node; + int dest = end_node; + CostType current_cost = cost; + for (int rank = path_size - 2; rank >= 0; --rank) { + for (int src : subset) { + const CostType partial_cost = mem_.Value(subset, src); + const CostType incumbent_cost = + Saturated::Add(partial_cost, Cost(src, dest)); + // Take precision into account when CosttType is float or double. + // There is no visible penalty in the case CostType is an integer type. + if (std::abs(Saturated::Sub(current_cost, incumbent_cost)) <= + std::numeric_limits::epsilon() * current_cost) { + subset = subset.RemoveElement(src); + current_cost = partial_cost; + path[rank] = src; + dest = src; + break; + } + } + } + DCHECK_EQ(0, subset.value()); + DCHECK(PathIsValid(path, cost)); + return path; +} + +template +bool HamiltonianPathSolver::PathIsValid( + const std::vector& path, CostType cost) { + NodeSet coverage(0); + for (int node : path) { + coverage = coverage.AddElement(node); + } + DCHECK_EQ(NodeSet::FullSet(num_nodes_).value(), coverage.value()); + CostType check_cost = 0; + for (int i = 0; i < path.size() - 1; ++i) { + check_cost = + Saturated::Add(check_cost, Cost(path[i], path[i + 1])); + } + DCHECK_LE(std::abs(Saturated::Sub(cost, check_cost)), + std::numeric_limits::epsilon() * cost) + << "cost = " << cost << " check_cost = " << check_cost; + return true; +} + +template +bool HamiltonianPathSolver::IsRobust() { + if (robustness_checked_) return robust_; + CostType min_cost = std::numeric_limits::max(); + CostType max_cost = std::numeric_limits::min(); + + // We compute the min and max for the cost matrix. + for (int i = 0; i < num_nodes_; ++i) { + for (int j = 0; j < num_nodes_; ++j) { + if (i == j) continue; + min_cost = std::min(min_cost, Cost(i, j)); + max_cost = std::max(max_cost, Cost(i, j)); + } + } + // We determine if the range of the cost matrix is going to + // make the algorithm not robust because of precision issues. + robust_ = min_cost >= 0 && + min_cost > num_nodes_ * max_cost * + std::numeric_limits::epsilon(); + robustness_checked_ = true; + return robust_; +} + +template +bool HamiltonianPathSolver::VerifiesTriangleInequality() { + if (triangle_inequality_checked_) return triangle_inequality_ok_; + triangle_inequality_ok_ = true; + triangle_inequality_checked_ = true; + for (int k = 0; k < num_nodes_; ++k) { + for (int i = 0; i < num_nodes_; ++i) { + for (int j = 0; j < num_nodes_; ++j) { + const CostType detour_cost = + Saturated::Add(Cost(i, k), Cost(k, j)); + if (detour_cost < Cost(i, j)) { + triangle_inequality_ok_ = false; + return triangle_inequality_ok_; + } + } + } + } + return triangle_inequality_ok_; +} + +template +int HamiltonianPathSolver::BestHamiltonianPathEndNode() { + Solve(); + return best_hamiltonian_path_end_node_; +} + +template +CostType HamiltonianPathSolver::HamiltonianCost( + int end_node) { + Solve(); + return hamiltonian_costs_[end_node]; +} + +template +std::vector HamiltonianPathSolver::HamiltonianPath( + int end_node) { + Solve(); + return hamiltonian_paths_[end_node]; +} + +template +void HamiltonianPathSolver::HamiltonianPath( + std::vector* path) { + *path = HamiltonianPath(best_hamiltonian_path_end_node_); +} + +template +CostType +HamiltonianPathSolver::TravelingSalesmanCost() { + Solve(); + return tsp_cost_; +} + +template +std::vector +HamiltonianPathSolver::TravelingSalesmanPath() { + Solve(); + return tsp_path_; +} + +template +void HamiltonianPathSolver::TravelingSalesmanPath( + std::vector* path) { + *path = TravelingSalesmanPath(); +} + +template +class PruningHamiltonianSolver { + // PruningHamiltonianSolver computes a minimum Hamiltonian path from node 0 + // over a graph defined by a cost matrix, with pruning. For each search state, + // PruningHamiltonianSolver computes the lower bound for the future overall + // TSP cost, and stops further search if it exceeds the current best solution. + + // For the heuristics to determine future lower bound over visited nodeset S + // and last visited node k, the cost of minimum spanning tree of (V \ S) ∪ {k} + // is calculated and added to the current cost(S). The cost of MST is + // guaranteed to be smaller than or equal to the cost of Hamiltonian path, + // because Hamiltonian path is a spanning tree itself. + + // TODO(user): Use generic map-based cache instead of lattice-based one. + // TODO(user): Use SaturatedArithmetic for better precision. + + public: + typedef uint32 Integer; + typedef Set NodeSet; + + explicit PruningHamiltonianSolver(CostFunction cost); + PruningHamiltonianSolver(int num_nodes, CostFunction cost); + + // Returns the cost of the Hamiltonian path from 0 to end_node. + CostType HamiltonianCost(int end_node); + + // TODO(user): Add function to return an actual path. + // TODO(user): Add functions for Hamiltonian cycle. + + private: + // Returns the cost value between two nodes. + CostType Cost(int i, int j) { return cost_(i, j); } + + // Solve and get TSP cost. + void Solve(int end_node); + + // Compute lower bound for remaining subgraph. + CostType ComputeFutureLowerBound(NodeSet current_set, int last_visited); + + // Cost function used to build Hamiltonian paths. + MatrixOrFunction cost_; + + // The number of nodes in the problem. + int num_nodes_; + + // The cost of the computed TSP path. + CostType tsp_cost_; + + // If already solved. + bool solved_; + + // Memoize for dynamic programming. + LatticeMemoryManager mem_; +}; + +template +PruningHamiltonianSolver::PruningHamiltonianSolver( + CostFunction cost) + : PruningHamiltonianSolver(cost.size(), cost) {} + +template +PruningHamiltonianSolver::PruningHamiltonianSolver( + int num_nodes, CostFunction cost) + : cost_(std::move(cost)), + num_nodes_(num_nodes), + tsp_cost_(0), + solved_(false) {} + +template +void PruningHamiltonianSolver::Solve(int end_node) { + if (solved_ || num_nodes_ == 0) return; + // TODO(user): Use an approximate solution as a base target before solving. + + // TODO(user): Instead of pure DFS, find out the order of sets to compute + // to utilize cache as possible. + + mem_.Init(num_nodes_); + NodeSet start_set = NodeSet::Singleton(0); + std::stack> state_stack; + state_stack.push(std::make_pair(start_set, 0)); + + while (!state_stack.empty()) { + const std::pair current = state_stack.top(); + state_stack.pop(); + + const NodeSet current_set = current.first; + const int last_visited = current.second; + const CostType current_cost = mem_.Value(current_set, last_visited); + + // TODO(user): Optimize iterating unvisited nodes. + for (int next_to_visit = 0; next_to_visit < num_nodes_; next_to_visit++) { + // Let's to as much check possible before adding to stack. + + // Skip if this node is already visited. + if (current_set.Contains(next_to_visit)) continue; + + // Skip if the end node is prematurely visited. + const int next_cardinality = current_set.Cardinality() + 1; + if (next_to_visit == end_node && next_cardinality != num_nodes_) continue; + + const NodeSet next_set = current_set.AddElement(next_to_visit); + const CostType next_cost = + current_cost + Cost(last_visited, next_to_visit); + + // Compare with the best cost found so far, and skip if that is better. + const CostType previous_best = mem_.Value(next_set, next_to_visit); + if (previous_best != 0 && next_cost >= previous_best) continue; + + // Compute lower bound of Hamiltonian cost, and skip if this is greater + // than the best Hamiltonian cost found so far. + const CostType lower_bound = + ComputeFutureLowerBound(next_set, next_to_visit); + if (tsp_cost_ != 0 && next_cost + lower_bound >= tsp_cost_) continue; + + // If next is the last node to visit, update tsp_cost_ and skip. + if (next_cardinality == num_nodes_) { + tsp_cost_ = next_cost; + continue; + } + + // Add to the stack, finally. + mem_.SetValue(next_set, next_to_visit, next_cost); + state_stack.push(std::make_pair(next_set, next_to_visit)); + } + } + + solved_ = true; +} + +template +CostType PruningHamiltonianSolver::HamiltonianCost( + int end_node) { + Solve(end_node); + return tsp_cost_; +} + +template +CostType +PruningHamiltonianSolver::ComputeFutureLowerBound( + NodeSet current_set, int last_visited) { + // TODO(user): Compute MST. + return 0; // For now, return 0 as future lower bound. +} +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_HAMILTONIAN_PATH_H_ diff --git a/thirdparty/linux/include/ortools/graph/io.h b/thirdparty/linux/include/ortools/graph/io.h new file mode 100644 index 0000000..ce1b01a --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/io.h @@ -0,0 +1,283 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// A collections of i/o utilities for the Graph classes in ./graph.h. + +#ifndef OR_TOOLS_GRAPH_IO_H_ +#define OR_TOOLS_GRAPH_IO_H_ + +#include +#include +#include +#include +#include + +#include "ortools/base/join.h" +#include "ortools/base/numbers.h" +#include "ortools/base/split.h" +#include "ortools/base/join.h" +#include "ortools/graph/graph.h" +#include "ortools/util/filelineiter.h" +#include "ortools/base/status.h" +#include "ortools/base/statusor.h" + +namespace operations_research { + +// Returns a std::string representation of a graph. +enum GraphToStringFormat { + // One arc per line, eg. "3->1". + PRINT_GRAPH_ARCS, + + // One space-separated adjacency list per line, eg. "5 1 3 1". + // Nodes with no outgoing arc get an empty line. + PRINT_GRAPH_ADJACENCY_LISTS, + + // Ditto, but the adjacency lists are sorted. + PRINT_GRAPH_ADJACENCY_LISTS_SORTED, +}; +template +std::string GraphToString(const Graph& graph, GraphToStringFormat format); + +// Read a graph file in the simple ".g" format: the file should be a text file +// containing only space-separated integers, whose first line is: +// [ +// ...] +// and whose subsequent lines represent edges if "directed" is false, or arcs if +// "directed" is true: +// . +// +// This returns a newly created graph upon success, which the user needs to take +// ownership of, or a failure status. See ortools/base/statusor.h. +// +// If "num_nodes_with_color_or_null" is not nullptr, it will be filled with the +// color information: num_nodes_with_color_or_null[i] will be the number of +// nodes with color #i. Furthermore, nodes are sorted by color. +// +// Examples: +// // Simply crash if the graph isn't successfully read from the file. +// typedef StaticGraph<> MyGraph; // This is just an example. +// std::unique_ptr my_graph( +// ReadGraphFile("graph.g", /*directed=*/ false).ValueOrDie()); +// +// // More complicated error handling. +// util::StatusOr error_or_graph = +// ReadGraphFile("graph.g", /*directed=*/ false); +// if (!error_or_graph.ok()) { +// LOG(ERROR) << "Error: " << error_or_graph.status().error_message(); +// } else { +// std::unique_ptr my_graph(error_or_graph.ValueOrDie()); +// ... +// } +template +util::StatusOr ReadGraphFile( + const std::string& filename, bool directed, + std::vector* num_nodes_with_color_or_null); + +// Writes a graph to the ".g" file format described above. If "directed" is +// true, all arcs are written to the file. If it is false, the graph is expected +// to be undirected (i.e. the number of arcs a->b is equal to the number of arcs +// b->a for all nodes a,b); and only the arcs a->b where a<=b are written. Note +// however that in this case, the symmetry of the graph is not fully checked +// (only the parity of the number of non-self arcs is). +// +// "num_nodes_with_color" is optional. If it is not empty, then the color +// information will be written to the header of the .g file. See ReadGraphFile. +// +// This method is the reverse of ReadGraphFile (with the same value for +// "directed"). +template +util::Status WriteGraphToFile(const Graph& graph, const std::string& filename, + bool directed, + const std::vector& num_nodes_with_color); + +// Implementations of the templated methods. + +template +std::string GraphToString(const Graph& graph, GraphToStringFormat format) { + std::string out; + std::vector adj; + for (const typename Graph::NodeIndex node : graph.AllNodes()) { + if (format == PRINT_GRAPH_ARCS) { + for (const typename Graph::ArcIndex arc : graph.OutgoingArcs(node)) { + if (!out.empty()) out += '\n'; + StrAppend(&out, node, "->", graph.Head(arc)); + } + } else { // PRINT_GRAPH_ADJACENCY_LISTS[_SORTED] + adj.clear(); + for (const typename Graph::ArcIndex arc : graph.OutgoingArcs(node)) { + adj.push_back(graph.Head(arc)); + } + if (format == PRINT_GRAPH_ADJACENCY_LISTS_SORTED) { + std::sort(adj.begin(), adj.end()); + } + if (node != 0) out += '\n'; + StrAppend(&out, node, ": ", strings::Join(adj, " ")); + } + } + return out; +} + +template +util::StatusOr ReadGraphFile( + const std::string& filename, bool directed, + std::vector* num_nodes_with_color_or_null) { + std::unique_ptr graph; + int64 num_nodes = -1; + int64 num_expected_lines = -1; + int64 num_lines_read = 0; + for (const std::string& line : FileLines(filename)) { + ++num_lines_read; + if (num_lines_read == 1) { + std::vector header_ints; + if (!SplitStringAndParse(line, " ", &safe_strto64, &header_ints) || + header_ints.size() < 2 || header_ints[0] < 0 || header_ints[1] < 0) { + return util::Status( + util::error::INVALID_ARGUMENT, + StrCat("First line of '", filename, + "' should be at least two nonnegative integers.")); + } + num_nodes = header_ints[0]; + num_expected_lines = header_ints[1]; + if (num_nodes_with_color_or_null != nullptr) { + num_nodes_with_color_or_null->clear(); + if (header_ints.size() == 2) { + // No coloring: all the nodes have the same color. + num_nodes_with_color_or_null->push_back(num_nodes); + } else { + const int num_colors = header_ints[2]; + if (header_ints.size() != num_colors + 2) { + return util::Status( + util::error::INVALID_ARGUMENT, + StrCat( + "There should be num_colors-1 color cardinalities in the" + " header of '", + filename, "' (where num_colors=", num_colors, + "): the last color cardinality should be", " skipped.")); + } + num_nodes_with_color_or_null->reserve(num_colors); + int num_nodes_left = num_nodes; + for (int i = 3; i < header_ints.size(); ++i) { + num_nodes_with_color_or_null->push_back(header_ints[i]); + num_nodes_left -= header_ints[i]; + if (header_ints[i] <= 0 || num_nodes_left <= 0) { + return util::Status( + util::error::INVALID_ARGUMENT, + StrCat( + "The color cardinalities in the header of '", filename, + " should always be >0 and add up to less than the" + " total number of nodes.")); + } + } + num_nodes_with_color_or_null->push_back(num_nodes_left); + } + } + const int64 num_arcs = (directed ? 1 : 2) * num_expected_lines; + graph.reset(new Graph(num_nodes, num_arcs)); + continue; + } + int64 node1 = -1; + int64 node2 = -1; + if (sscanf(line.c_str(), "%lld %lld", &node1, &node2) != 2 || node1 < 0 || + node2 < 0 || node1 >= num_nodes || node2 >= num_nodes) { + return util::Status( + util::error::INVALID_ARGUMENT, + StrCat("In '", filename, "', line ", num_lines_read, + ": Expected two", " integers in the range [0, ", + num_nodes, ").")); + } + // We don't add superfluous arcs to the graph, but we still keep reading + // the file, to get better error messages: we want to know the actual + // number of lines, and also want to check the validity of the superfluous + // arcs (i.e. that their src/dst nodes are ok). + if (num_lines_read > num_expected_lines + 1) continue; + graph->AddArc(node1, node2); + if (!directed && node1 != node2) graph->AddArc(node2, node1); + } + if (num_lines_read == 0) { + return util::Status(util::error::INVALID_ARGUMENT, "Unknown or empty file"); + } + if (num_lines_read != num_expected_lines + 1) { + return util::Status(util::error::INVALID_ARGUMENT, + StrCat("The number of arcs/edges in '", filename, + "' (", num_lines_read - 1, + " does not match the value announced in", + " the header (", num_expected_lines, ")")); + } + graph->Build(); + return graph.release(); +} + +template +util::Status WriteGraphToFile(const Graph& graph, const std::string& filename, + bool directed, + const std::vector& num_nodes_with_color) { + FILE* f = fopen(filename.c_str(), "w"); + if (f == nullptr) { + return util::Status(util::error::INVALID_ARGUMENT, + "Could not open file: '" + filename + "'"); + } + // In undirected mode, we must count the self-arcs separately. All other arcs + // should be duplicated. + int num_self_arcs = 0; + if (!directed) { + for (const typename Graph::NodeIndex node : graph.AllNodes()) { + for (const typename Graph::ArcIndex arc : graph.OutgoingArcs(node)) { + if (graph.Head(arc) == node) ++num_self_arcs; + } + } + if ((graph.num_arcs() - num_self_arcs) % 2 != 0) { + fclose(f); + return util::Status(util::error::INVALID_ARGUMENT, + "WriteGraphToFile() called with directed=false" + " and with a graph with an odd number of (non-self)" + " arcs!"); + } + } + fprintf( + f, "%lld %lld", static_cast(graph.num_nodes()), + static_cast(directed ? graph.num_arcs() + : (graph.num_arcs() + num_self_arcs) / 2)); + if (!num_nodes_with_color.empty()) { + if (std::accumulate(num_nodes_with_color.begin(), + num_nodes_with_color.end(), 0) != graph.num_nodes() || + *std::min_element(num_nodes_with_color.begin(), + num_nodes_with_color.end()) <= 0) { + return util::Status(util::error::INVALID_ARGUMENT, + "WriteGraphToFile() called with invalid coloring."); + } + fprintf(f, " %lu", num_nodes_with_color.size()); + for (int i = 0; i < num_nodes_with_color.size() - 1; ++i) { + fprintf(f, " %lld", static_cast(num_nodes_with_color[i])); + } + } + fprintf(f, "\n"); + + for (const typename Graph::NodeIndex node : graph.AllNodes()) { + for (const typename Graph::ArcIndex arc : graph.OutgoingArcs(node)) { + const typename Graph::NodeIndex head = graph.Head(arc); + if (directed || head >= node) { + fprintf(f, "%lld %lld\n", static_cast(node), + static_cast(head)); + } + } + } + if (fclose(f) != 0) { + return util::Status(util::error::INTERNAL, + "Could not close file '" + filename + "'"); + } + return util::Status::OK; +} + +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_IO_H_ diff --git a/thirdparty/linux/include/ortools/graph/linear_assignment.h b/thirdparty/linux/include/ortools/graph/linear_assignment.h new file mode 100644 index 0000000..82c246e --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/linear_assignment.h @@ -0,0 +1,1482 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// An implementation of a cost-scaling push-relabel algorithm for the +// assignment problem (minimum-cost perfect bipartite matching), from +// the paper of Goldberg and Kennedy (1995). +// +// +// This implementation finds the minimum-cost perfect assignment in +// the given graph with integral edge weights set through the +// SetArcCost method. +// +// The running time is O(n*m*log(nC)) where n is the number of nodes, +// m is the number of edges, and C is the largest magnitude of an edge cost. +// In principle it can be worse than the Hungarian algorithm but we don't know +// of any class of problems where that actually happens. An additional sqrt(n) +// factor could be shaved off the running time bound using the technique +// described in http://dx.doi.org/10.1137/S0895480194281185 +// (see also http://theory.stanford.edu/~robert/papers/glob_upd.ps). +// +// +// Example usage: +// +// #include "ortools/graph/graph.h" +// #include "ortools/graph/linear_assignment.h" +// +// // Choose a graph implementation (we recommend StaticGraph<>). +// typedef operations_research::StaticGraph<> Graph; +// +// // Define a num_nodes / 2 by num_nodes / 2 assignment problem: +// const int num_nodes = ... +// const int num_arcs = ... +// const int num_left_nodes = num_nodes / 2; +// Graph graph(num_nodes, num_arcs); +// std::vector arc_costs(num_arcs); +// for (int arc = 0; arc < num_arcs; ++arc) { +// const int arc_tail = ... // must be in [0, num_left_nodes) +// const int arc_head = ... // must be in [num_left_nodes, num_nodes) +// graph.AddArc(arc_tail, arc_head); +// arc_costs[arc] = ... +// } +// +// // Build the StaticGraph. You can skip this step by using a ListGraph<> +// // instead, but then the ComputeAssignment() below will be slower. It is +// // okay if your graph is small and performance is not critical though. +// { +// std::vector arc_permutation; +// graph->get()->Build(&arc_permutation); +// operations_research::Permute(arc_permutation, &arc_costs); +// } +// +// // Construct the LinearSumAssignment. +// ::operations_research::LinearSumAssignment a(graph, num_left_nodes); +// for (int arc = 0; arc < num_arcs; ++arc) { +// // You can also replace 'arc_costs[arc]' by something like +// // ComputeArcCost(permutation.empty() ? arc : permutation[arc]) +// // if you don't want to store the costs in arc_costs to save memory. +// a.SetArcCost(arc, arc_costs[arc]); +// } +// +// // Compute the optimum assignment. +// bool success = a.ComputeAssignment(); +// // Retrieve the cost of the optimum assignment. +// operations_research::CostValue optimum_cost = a.GetCost(); +// // Retrieve the node-node correspondence of the optimum assignment and the +// // cost of each node pairing. +// for (int left_node = 0; left_node < num_left_nodes; ++left_node) { +// const int right_node = a.GetMate(left_node); +// operations_research::CostValue node_pair_cost = +// a.GetAssignmentCost(left_node); +// ... +// } +// +// In the following, we consider a bipartite graph +// G = (V = X union Y, E subset XxY), +// where V denodes the set of nodes (vertices) in the graph, E denotes +// the set of arcs (edges), n = |V| denotes the number of nodes in the +// graph, and m = |E| denotes the number of arcs in the graph. +// +// The set of nodes is divided into two parts, X and Y, and every arc +// must go between a node of X and a node of Y. With each arc is +// associated a cost c(v, w). A matching M is a subset of E with the +// property that no two arcs in M have a head or tail node in common, +// and a perfect matching is a matching that touches every node in the +// graph. The cost of a matching M is the sum of the costs of all the +// arcs in M. +// +// The assignment problem is to find a perfect matching of minimum +// cost in the given bipartite graph. The present algorithm reduces +// the assignment problem to an instance of the minimum-cost flow +// problem and takes advantage of special properties of the resulting +// minimum-cost flow problem to solve it efficiently using a +// push-relabel method. For more information about minimum-cost flow +// see google3/ortools/graph/min_cost_flow.h +// +// The method used here is the cost-scaling approach for the +// minimum-cost circulation problem as described in [Goldberg and +// Tarjan] with some technical modifications: +// 1. For efficiency, we solve a transportation problem instead of +// minimum-cost circulation. We might revisit this decision if it +// is important to handle problems in which no perfect matching +// exists. +// 2. We use a modified "asymmetric" notion of epsilon-optimality in +// which left-to-right residual arcs are required to have reduced +// cost bounded below by zero and right-to-left residual arcs are +// required to have reduced cost bounded below by -epsilon. For +// each residual arc direction, the reduced-cost threshold for +// admissibility is epsilon/2 above the threshold for epsilon +// optimality. +// 3. We do not limit the applicability of the relabeling operation to +// nodes with excess. Instead we use the double-push operation +// (discussed in the Goldberg and Kennedy CSA paper and Kennedy's +// thesis) which relabels right-side nodes just *after* they have +// been discharged. +// The above differences are explained in detail in [Kennedy's thesis] +// and explained not quite as cleanly in [Goldberg and Kennedy's CSA +// paper]. But note that the thesis explanation uses a value of +// epsilon that's double what we use here. +// +// Some definitions: +// Active: A node is called active when it has excess. It is +// eligible to be pushed from. In this implementation, every active +// node is on the left side of the graph where prices are determined +// implicitly, so no left-side relabeling is necessary before +// pushing from an active node. We do, however, need to compute +// the implications for price changes on the affected right-side +// nodes. +// Admissible: A residual arc (one that can carry more flow) is +// called admissible when its reduced cost is small enough. We can +// push additional flow along such an arc without violating +// epsilon-optimality. In the case of a left-to-right residual +// arc, the reduced cost must be at most epsilon/2. In the case of +// a right-to-left residual arc, the reduced cost must be at +// most -epsilon/2. The careful reader will note that these thresholds +// are not used explicitly anywhere in this implementation, and +// the reason is the implicit pricing of left-side nodes. +// Reduced cost: Essentially an arc's reduced cost is its +// complementary slackness. In push-relabel algorithms this is +// c_p(v, w) = p(v) + c(v, w) - p(w), +// where p() is the node price function and c(v, w) is the cost of +// the arc from v to w. See min_cost_flow.h for more details. +// Partial reduced cost: We maintain prices implicitly for left-side +// nodes in this implementation, so instead of reduced costs we +// work with partial reduced costs, defined as +// c'_p(v, w) = c(v, w) - p(w). +// +// We check at initialization time for the possibility of arithmetic +// overflow and warn if the given costs are too large. In many cases +// the bound we use to trigger the warning is pessimistic so the given +// problem can often be solved even if we warn that overflow is +// possible. +// +// We don't use the interface from +// operations_research/algorithms/hungarian.h because we want to be +// able to express sparse problems efficiently. +// +// When asked to solve the given assignment problem we return a +// boolean to indicate whether the given problem was feasible. +// +// References: +// [ Goldberg and Kennedy's CSA paper ] A. V. Goldberg and R. Kennedy, +// "An Efficient Cost Scaling Algorithm for the Assignment Problem." +// Mathematical Programming, Vol. 71, pages 153-178, December 1995. +// +// [ Goldberg and Tarjan ] A. V. Goldberg and R. E. Tarjan, "Finding +// Minimum-Cost Circulations by Successive Approximation." Mathematics +// of Operations Research, Vol. 15, No. 3, pages 430-466, August 1990. +// +// [ Kennedy's thesis ] J. R. Kennedy, Jr., "Solving Unweighted and +// Weighted Bipartite Matching Problems in Theory and Practice." +// Stanford University Doctoral Dissertation, Department of Computer +// Science, 1995. +// +// [ Burkard et al. ] R. Burkard, M. Dell'Amico, S. Martello, "Assignment +// Problems", SIAM, 2009, ISBN: 978-0898716634, +// http://www.amazon.com/dp/0898716632/ +// +// [ Ahuja et al. ] R. K. Ahuja, T. L. Magnanti, J. B. Orlin, "Network Flows: +// Theory, Algorithms, and Applications," Prentice Hall, 1993, +// ISBN: 978-0136175490, http://www.amazon.com/dp/013617549X. +// +// Keywords: linear sum assignment problem, Hungarian method, Goldberg, Kennedy. + +#ifndef OR_TOOLS_GRAPH_LINEAR_ASSIGNMENT_H_ +#define OR_TOOLS_GRAPH_LINEAR_ASSIGNMENT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ortools/base/commandlineflags.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/stringprintf.h" +#include "ortools/graph/ebert_graph.h" +#include "ortools/util/permutation.h" +#include "ortools/util/zvector.h" + +#ifndef SWIG +DECLARE_int64(assignment_alpha); +DECLARE_int32(assignment_progress_logging_period); +DECLARE_bool(assignment_stack_order); +#endif + +namespace operations_research { + +// This class does not take ownership of its underlying graph. +template +class LinearSumAssignment { + public: + typedef typename GraphType::NodeIndex NodeIndex; + typedef typename GraphType::ArcIndex ArcIndex; + + // Constructor for the case in which we will build the graph + // incrementally as we discover arc costs, as might be done with any + // of the dynamic graph representations such as StarGraph or ForwardStarGraph. + LinearSumAssignment(const GraphType& graph, NodeIndex num_left_nodes); + + // Constructor for the case in which the underlying graph cannot be + // built until after all the arc costs are known, as is the case + // with ForwardStarStaticGraph. In this case, the graph is passed to + // us later via the SetGraph() method, below. + LinearSumAssignment(NodeIndex num_left_nodes, ArcIndex num_arcs); + + ~LinearSumAssignment() {} + + // Sets the graph used by the LinearSumAssignment instance, for use + // when the graph layout can be determined only after arc costs are + // set. This happens, for example, when we use a ForwardStarStaticGraph. + void SetGraph(const GraphType* graph) { + DCHECK(graph_ == nullptr); + graph_ = graph; + } + + // Sets the cost-scaling divisor, i.e., the amount by which we + // divide the scaling parameter on each iteration. + void SetCostScalingDivisor(CostValue factor) { alpha_ = factor; } + + // Returns a permutation cycle handler that can be passed to the + // TransformToForwardStaticGraph method so that arc costs get + // permuted along with arcs themselves. + // + // Passes ownership of the cycle handler to the caller. + // + operations_research::PermutationCycleHandler* + ArcAnnotationCycleHandler(); + + // Optimizes the layout of the graph for the access pattern our + // implementation will use. + // + // REQUIRES for LinearSumAssignment template instantiation if a call + // to the OptimizeGraphLayout() method is compiled: GraphType is a + // dynamic graph, i.e., one that implements the + // GroupForwardArcsByFunctor() member template method. + // + // If analogous optimization is needed for LinearSumAssignment + // instances based on static graphs, the graph layout should be + // constructed such that each node's outgoing arcs are sorted by + // head node index before the + // LinearSumAssignment::SetGraph() method is called. + void OptimizeGraphLayout(GraphType* graph); + + // Allows tests, iterators, etc., to inspect our underlying graph. + inline const GraphType& Graph() const { return *graph_; } + + // These handy member functions make the code more compact, and we + // expose them to clients so that client code that doesn't have + // direct access to the graph can learn about the optimum assignment + // once it is computed. + inline NodeIndex Head(ArcIndex arc) const { return graph_->Head(arc); } + + // Returns the original arc cost for use by a client that's + // iterating over the optimum assignment. + CostValue ArcCost(ArcIndex arc) const { + DCHECK_EQ(0, scaled_arc_cost_[arc] % cost_scaling_factor_); + return scaled_arc_cost_[arc] / cost_scaling_factor_; + } + + // Sets the cost of an arc already present in the given graph. + void SetArcCost(ArcIndex arc, CostValue cost); + + // Completes initialization after the problem is fully specified. + // Returns true if we successfully prove that arithmetic + // calculations are guaranteed not to overflow. ComputeAssignment() + // calls this method itself, so only clients that care about + // obtaining a warning about the possibility of arithmetic precision + // problems need to call this method explicitly. + // + // Separate from ComputeAssignment() for white-box testing and for + // clients that need to react to the possibility that arithmetic + // overflow is not ruled out. + // + // FinalizeSetup() is idempotent. + bool FinalizeSetup(); + + // Computes the optimum assignment. Returns true on success. Return + // value of false implies the given problem is infeasible. + bool ComputeAssignment(); + + // Returns the cost of the minimum-cost perfect matching. + // Precondition: success_ == true, signifying that we computed the + // optimum assignment for a feasible problem. + CostValue GetCost() const; + + // Returns the total number of nodes in the given problem. + NodeIndex NumNodes() const { + if (graph_ == nullptr) { + // Return a guess that must be true if ultimately we are given a + // feasible problem to solve. + return 2 * NumLeftNodes(); + } else { + return graph_->num_nodes(); + } + } + + // Returns the number of nodes on the left side of the given + // problem. + NodeIndex NumLeftNodes() const { return num_left_nodes_; } + + // Returns the arc through which the given node is matched. + inline ArcIndex GetAssignmentArc(NodeIndex left_node) const { + DCHECK_LT(left_node, num_left_nodes_); + return matched_arc_[left_node]; + } + + // Returns the cost of the assignment arc incident to the given + // node. + inline CostValue GetAssignmentCost(NodeIndex node) const { + return ArcCost(GetAssignmentArc(node)); + } + + // Returns the node to which the given node is matched. + inline NodeIndex GetMate(NodeIndex left_node) const { + DCHECK_LT(left_node, num_left_nodes_); + ArcIndex matching_arc = GetAssignmentArc(left_node); + DCHECK_NE(GraphType::kNilArc, matching_arc); + return Head(matching_arc); + } + + std::string StatsString() const { return total_stats_.StatsString(); } + + class BipartiteLeftNodeIterator { + public: + BipartiteLeftNodeIterator(const GraphType& graph, NodeIndex num_left_nodes) + : num_left_nodes_(num_left_nodes), node_iterator_(0) {} + + explicit BipartiteLeftNodeIterator(const LinearSumAssignment& assignment) + : num_left_nodes_(assignment.NumLeftNodes()), node_iterator_(0) {} + + NodeIndex Index() const { return node_iterator_; } + + bool Ok() const { return node_iterator_ < num_left_nodes_; } + + void Next() { ++node_iterator_; } + + private: + const NodeIndex num_left_nodes_; + typename GraphType::NodeIndex node_iterator_; + }; + + private: + struct Stats { + Stats() : pushes_(0), double_pushes_(0), relabelings_(0), refinements_(0) {} + void Clear() { + pushes_ = 0; + double_pushes_ = 0; + relabelings_ = 0; + refinements_ = 0; + } + void Add(const Stats& that) { + pushes_ += that.pushes_; + double_pushes_ += that.double_pushes_; + relabelings_ += that.relabelings_; + refinements_ += that.refinements_; + } + std::string StatsString() const { + return StringPrintf( + "%lld refinements; %lld relabelings; " + "%lld double pushes; %lld pushes", + refinements_, relabelings_, double_pushes_, pushes_); + } + int64 pushes_; + int64 double_pushes_; + int64 relabelings_; + int64 refinements_; + }; + +#ifndef SWIG + class ActiveNodeContainerInterface { + public: + virtual ~ActiveNodeContainerInterface() {} + virtual bool Empty() const = 0; + virtual void Add(NodeIndex node) = 0; + virtual NodeIndex Get() = 0; + }; + + class ActiveNodeStack : public ActiveNodeContainerInterface { + public: + ~ActiveNodeStack() override {} + + bool Empty() const override { return v_.empty(); } + + void Add(NodeIndex node) override { v_.push_back(node); } + + NodeIndex Get() override { + DCHECK(!Empty()); + NodeIndex result = v_.back(); + v_.pop_back(); + return result; + } + + private: + std::vector v_; + }; + + class ActiveNodeQueue : public ActiveNodeContainerInterface { + public: + ~ActiveNodeQueue() override {} + + bool Empty() const override { return q_.empty(); } + + void Add(NodeIndex node) override { q_.push_front(node); } + + NodeIndex Get() override { + DCHECK(!Empty()); + NodeIndex result = q_.back(); + q_.pop_back(); + return result; + } + + private: + std::deque q_; + }; +#endif + + // Type definition for a pair + // (arc index, reduced cost gap) + // giving the arc along which we will push from a given left-side + // node and the gap between that arc's partial reduced cost and the + // reduced cost of the next-best (necessarily residual) arc out of + // the node. This information helps us efficiently relabel + // right-side nodes during DoublePush operations. + typedef std::pair ImplicitPriceSummary; + + // Returns true if and only if the current pseudoflow is + // epsilon-optimal. To be used in a DCHECK. + bool EpsilonOptimal() const; + + // Checks that all nodes are matched. + // To be used in a DCHECK. + bool AllMatched() const; + + // Calculates the implicit price of the given node. + // Only for debugging, for use in EpsilonOptimal(). + inline CostValue ImplicitPrice(NodeIndex left_node) const; + + // For use by DoublePush() + inline ImplicitPriceSummary BestArcAndGap(NodeIndex left_node) const; + + // Accumulates stats between iterations and reports them if the + // verbosity level is high enough. + void ReportAndAccumulateStats(); + + // Utility function to compute the next error parameter value. This + // is used to ensure that the same sequence of error parameter + // values is used for computation of price bounds as is used for + // computing the optimum assignment. + CostValue NewEpsilon(CostValue current_epsilon) const; + + // Advances internal state to prepare for the next scaling + // iteration. Returns false if infeasibility is detected, true + // otherwise. + bool UpdateEpsilon(); + + // Indicates whether the given left_node has positive excess. Called + // only for nodes on the left side. + inline bool IsActive(NodeIndex left_node) const; + + // Indicates whether the given node has nonzero excess. The idea + // here is the same as the IsActive method above, but that method + // contains a safety DCHECK() that its argument is a left-side node, + // while this method is usable for any node. + // To be used in a DCHECK. + inline bool IsActiveForDebugging(NodeIndex node) const; + + // Performs the push/relabel work for one scaling iteration. + bool Refine(); + + // Puts all left-side nodes in the active set in preparation for the + // first scaling iteration. + void InitializeActiveNodeContainer(); + + // Saturates all negative-reduced-cost arcs at the beginning of each + // scaling iteration. Note that according to the asymmetric + // definition of admissibility, this action is different from + // saturating all admissible arcs (which we never do). All negative + // arcs are admissible, but not all admissible arcs are negative. It + // is alwsys enough to saturate only the negative ones. + void SaturateNegativeArcs(); + + // Performs an optimized sequence of pushing a unit of excess out of + // the left-side node v and back to another left-side node if no + // deficit is cancelled with the first push. + bool DoublePush(NodeIndex source); + + // Returns the partial reduced cost of the given arc. + inline CostValue PartialReducedCost(ArcIndex arc) const { + return scaled_arc_cost_[arc] - price_[Head(arc)]; + } + + // The graph underlying the problem definition we are given. Not + // owned by *this. + const GraphType* graph_; + + // The number of nodes on the left side of the graph we are given. + NodeIndex num_left_nodes_; + + // A flag indicating, after FinalizeSetup() has run, whether the + // arc-incidence precondition required by BestArcAndGap() is + // satisfied by every left-side node. If not, the problem is + // infeasible. + bool incidence_precondition_satisfied_; + + // A flag indicating that an optimal perfect matching has been computed. + bool success_; + + // The value by which we multiply all the arc costs we are given in + // order to be able to use integer arithmetic in all our + // computations. In order to establish optimality of the final + // matching we compute, we need that + // (cost_scaling_factor_ / kMinEpsilon) > graph_->num_nodes(). + const CostValue cost_scaling_factor_; + + // Scaling divisor. + CostValue alpha_; + + // Minimum value of epsilon. When a flow is epsilon-optimal for + // epsilon == kMinEpsilon, the flow is optimal. + static const CostValue kMinEpsilon; + + // Current value of epsilon, the cost scaling parameter. + CostValue epsilon_; + + // The following two data members, price_lower_bound_ and + // slack_relabeling_price_, have to do with bounds on the amount by + // which node prices can change during execution of the algorithm. + // We need some detailed discussion of this topic because we violate + // several simplifying assumptions typically made in the theoretical + // literature. In particular, we use integer arithmetic, we use a + // reduction to the transportation problem rather than min-cost + // circulation, we provide detection of infeasible problems rather + // than assume feasibility, we detect when our computations might + // exceed the range of representable cost values, and we use the + // double-push heuristic which relabels nodes that do not have + // excess. + // + // In the following discussion, we prove the following propositions: + // Proposition 1. [Fidelity of arithmetic precision guarantee] If + // FinalizeSetup() returns true, no arithmetic + // overflow occurs during ComputeAssignment(). + // Proposition 2. [Fidelity of feasibility detection] If no + // arithmetic overflow occurs during + // ComputeAssignment(), the return value of + // ComputeAssignment() faithfully indicates whether + // the given problem is feasible. + // + // We begin with some general discussion. + // + // The ideas used to prove our two propositions are essentially + // those that appear in [Goldberg and Tarjan], but several details + // are different: [Goldberg and Tarjan] assumes a feasible problem, + // uses a symmetric notion of epsilon-optimality, considers only + // nodes with excess eligible for relabeling, and does not treat the + // question of arithmetic overflow. This implementation, on the + // other hand, detects and reports infeasible problems, uses + // asymmetric epsilon-optimality, relabels nodes with no excess in + // the course of the double-push operation, and gives a reasonably + // tight guarantee of arithmetic precision. No fundamentally new + // ideas are involved, but the details are a bit tricky so they are + // explained here. + // + // We have two intertwined needs that lead us to compute bounds on + // the prices nodes can have during the assignment computation, on + // the assumption that the given problem is feasible: + // 1. Infeasibility detection: Infeasibility is detected by + // observing that some node's price has been reduced too much by + // relabeling operations (see [Goldberg and Tarjan] for the + // argument -- duplicated in modified form below -- bounding the + // running time of the push/relabel min-cost flow algorithm for + // feasible problems); and + // 2. Aggressively relabeling nodes and arcs whose matching is + // forced: When a left-side node is incident to only one arc a, + // any feasible solution must include a, and reducing the price + // of Head(a) by any nonnegative amount preserves epsilon- + // optimality. Because of this freedom, we'll call this sort of + // relabeling (i.e., a relabeling of a right-side node that is + // the only neighbor of the left-side node to which it has been + // matched in the present double-push operation) a "slack" + // relabeling. Relabelings that are not slack relabelings are + // called "confined" relabelings. By relabeling Head(a) to have + // p(Head(a))=-infinity, we could guarantee that a never becomes + // unmatched during the current iteration, and this would prevent + // our wasting time repeatedly unmatching and rematching a. But + // there are some details we need to handle: + // a. The CostValue type cannot represent -infinity; + // b. Low node prices are precisely the signal we use to detect + // infeasibility (see (1)), so we must be careful not to + // falsely conclude that the problem is infeasible as a result + // of the low price we gave Head(a); and + // c. We need to indicate accurately to the client when our best + // understanding indicates that we can't rule out arithmetic + // overflow in our calculations. Most importantly, if we don't + // warn the client, we must be certain to avoid overflow. This + // means our slack relabelings must not be so aggressive as to + // create the possibility of unforeseen overflow. Although we + // will not achieve this in practice, slack relabelings would + // ideally not introduce overflow unless overflow was + // inevitable were even the smallest reasonable price change + // (== epsilon) used for slack relabelings. + // Using the analysis below, we choose a finite amount of price + // change for slack relabelings aggressive enough that we don't + // waste time doing repeated slack relabelings in a single + // iteration, yet modest enough that we keep a good handle on + // arithmetic precision and our ability to detect infeasible + // problems. + // + // To provide faithful detection of infeasibility, a dependable + // guarantee of arithmetic precision whenever possible, and good + // performance by aggressively relabeling nodes whose matching is + // forced, we exploit these facts: + // 1. Beyond the first iteration, infeasibility detection isn't needed + // because a problem is feasible in some iteration if and only if + // it's feasible in all others. Therefore we are free to use an + // infeasibility detection mechanism that might work in just one + // iteration and switch it off in all other iterations. + // 2. When we do a slack relabeling, we must choose the amount of + // price reduction to use. We choose an amount large enough to + // guarantee putting the node's matching to rest, yet (although + // we don't bother to prove this explicitly) small enough that + // the node's price obeys the overall lower bound that holds if + // the slack relabeling amount is small. + // + // We will establish Propositions (1) and (2) above according to the + // following steps: + // First, we prove Lemma 1, which is a modified form of lemma 5.8 of + // [Goldberg and Tarjan] giving a bound on the difference in price + // between the end nodes of certain paths in the residual graph. + // Second, we prove Lemma 2, which is technical lemma to establish + // reachability of certain "anchor" nodes in the residual graph from + // any node where a relabeling takes place. + // Third, we apply the first two lemmas to prove Lemma 3 and Lemma + // 4, which give two similar bounds that hold whenever the given + // problem is feasible: (for feasibility detection) a bound on the + // price of any node we relabel during any iteration (and the first + // iteration in particular), and (for arithmetic precision) a bound + // on the price of any node we relabel during the entire algorithm. + // + // Finally, we note that if the whole-algorithm price bound can be + // represented precisely by the CostValue type, arithmetic overflow + // cannot occur (establishing Proposition 1), and assuming no + // overflow occurs during the first iteration, any violation of the + // first-iteration price bound establishes infeasibility + // (Proposition 2). + // + // The statement of Lemma 1 is perhaps easier to understand when the + // reader knows how it will be used. To wit: In this lemma, f' and + // e_0 are the flow and error parameter (epsilon) at the beginning + // of the current iteration, while f and e_1 are the current + // pseudoflow and error parameter when a relabeling of interest + // occurs. Without loss of generality, c is the reduced cost + // function at the beginning of the current iteration and p is the + // change in prices that has taken place in the current iteration. + // + // Lemma 1 (a variant of lemma 5.8 from [Goldberg and Tarjan]): Let + // f be a pseudoflow and let f' be a flow. Suppose P is a simple + // path from right-side node v to right-side node w such that P is + // residual with respect to f and reverse(P) is residual with + // respect to f'. Further, suppose c is an arc cost function with + // respect to which f' is e_0-optimal with the zero price function + // and p is a price function with respect to which f is e_1-optimal + // with respect to p. Then + // p(v) - p(w) >= -(e_0 + e_1) * (n-2)/2. (***) + // + // Proof: We have c_p(P) = p(v) + c(P) - p(w) and hence + // p(v) - p(w) = c_p(P) - c(P). + // So we seek a bound on c_p(P) - c(P). + // p(v) = c_p(P) - c(P). + // Let arc a lie on P, which implies that a is residual with respect + // to f and reverse(a) is residual with respect to f'. + // Case 1: a is a forward arc. Then by e_1-optimality of f with + // respect to p, c_p(a) >= 0 and reverse(a) is residual with + // respect to f'. By e_0-optimality of f', c(a) <= e_0. So + // c_p(a) - c(a) >= -e_0. + // Case 2: a is a reverse arc. Then by e_1-optimality of f with + // respect to p, c_p(a) >= -e_1 and reverse(a) is residual + // with respect to f'. By e_0-optimality of f', c(a) <= 0. + // So + // c_p(a) - c(a) >= -e_1. + // We assumed v and w are both right-side nodes, so there are at + // most n - 2 arcs on the path P, of which at most (n-2)/2 are + // forward arcs and at most (n-2)/2 are reverse arcs, so + // p(v) - p(w) = c_p(P) - c(P) + // >= -(e_0 + e_1) * (n-2)/2. (***) + // + // Some of the rest of our argument is given as a sketch, omitting + // several details. Also elided here are some minor technical issues + // related to the first iteration, inasmuch as our arguments assume + // on the surface a "previous iteration" that doesn't exist in that + // case. The issues are not substantial, just a bit messy. + // + // Lemma 2 is analogous to lemma 5.7 of [Goldberg and Tarjan], where + // they have only relabelings that take place at nodes with excess + // while we have only relabelings that take place as part of the + // double-push operation at nodes without excess. + // + // Lemma 2: When a right-side node v is relabeled by our + // implementation, either the problem is infeasible or there exists + // a node w such that + // A. w is reachable from v along some simple residual path P where + // reverse(P) was residual at the beginning of the current + // iteration; and + // B. at least one of the following holds: + // 1. when w was last relabeled, there existed a path P' from w + // to a node with deficit in the residual graph where + // reverse(P') was residual at the beginning of the current + // iteration; or + // 2. when w was last relabeled, it was a slack relabeling; + // and + // C. at least one of the following holds: + // 1. w will not be relabeled again in this iteration; or + // 2. v == w. + // + // The proof of Lemma 2 is somewhat messy and is omitted for + // expedience. + // + // Lemma 1 bounds the price change during an iteration for any node + // relabeled when a deficit is residually reachable from that node, + // since a node w with deficit is not relabeled, hence p(w) = 0 in + // the Lemma 1 bound. Let the bound from Lemma 1 with p(w) = 0 be + // called B(e_0, e_1), and let us say that when a slack relabeling + // of a node v occurs, we will set the price of v to B(e_0, e_1) + // such that v tightly satisfies the bound of Lemma 1. Explicitly, + // we define + // B(e_0, e_1) = -(e_0 + e_1) * (n-2)/2. + // + // From Lemma 1 and Lemma 2, and taking into account our knowledge + // of the slack relabeling amount, we have Lemma 3. + // + // Lemma 3: During any iteration, if the given problem is feasible + // the price of any node is reduced by less than + // 2 * B(e_0, e_1) = -(e_0 + e_1) * (n-2). + // + // Proof: Straightforward, omitted for expedience. + // + // In the case where e_0 = e_1 * alpha, we can express the bound + // just in terms of e_1, the current iteration's value of epsilon_: + // B(e_1) = B(e_1 * alpha, e_1) = -(1 + alpha) * e_1 * (n-2)/2, + // so we have that p(v) is reduced by less than 2 * B(e_1). + // + // Because we use truncating division to compute each iteration's error + // parameter from that of the previous iteration, it isn't exactly + // the case that e_0 = e_1 * alpha as we just assumed. To patch this + // up, we can use the observation that + // e_1 = floor(e_0 / alpha), + // which implies + // -e_0 > -(e_1 + 1) * alpha + // to rewrite from (***): + // p(v) > 2 * B(e_0, e_1) > 2 * B((e_1 + 1) * alpha, e_1) + // = 2 * -((e_1 + 1) * alpha + e_1) * (n-2)/2 + // = 2 * -(1 + alpha) * e_1 * (n-2)/2 - alpha * (n-2) + // = 2 * B(e_1) - alpha * (n-2) + // = -((1 + alpha) * e_1 + alpha) * (n-2). + // + // We sum up the bounds for all the iterations to get Lemma 4: + // + // Lemma 4: If the given problem is feasible, after k iterations the + // price of any node is always greater than + // -((1 + alpha) * C + (k * alpha)) * (n-2) + // + // Proof: Suppose the price decrease of every node in the iteration + // with epsilon_ == x is bounded by B(x) which is proportional to x + // (not surpisingly, this will be the same function B() as + // above). Assume for simplicity that C, the largest cost magnitude, + // is a power of alpha. Then the price of each node, tallied across + // all iterations is bounded + // p(v) > 2 * B(C/alpha) + 2 * B(C/alpha^2) + ... + 2 * B(kMinEpsilon) + // == 2 * B(C/alpha) * alpha / (alpha - 1) + // == 2 * B(C) / (alpha - 1). + // As above, this needs some patching up to handle the fact that we + // use truncating arithmetic. We saw that each iteration effectively + // reduces the price bound by alpha * (n-2), hence if there are k + // iterations, the bound is + // p(v) > 2 * B(C) / (alpha - 1) - k * alpha * (n-2) + // = -(1 + alpha) * C * (n-2) / (alpha - 1) - k * alpha * (n-2) + // = (n-2) * (C * (1 + alpha) / (1 - alpha) - k * alpha). + // + // The bound of lemma 4 can be used to warn for possible overflow of + // arithmetic precision. But because it involves the number of + // iterations, k, we might as well count through the iterations + // simply adding up the bounds given by Lemma 3 to get a tighter + // result. This is what the implementation does. + + // A lower bound on the price of any node at any time throughout the + // computation. A price below this level proves infeasibility; this + // value is used for feasibility detection. We use this value also + // to rule out the possibility of arithmetic overflow or warn the + // client that we have not been able to rule out that possibility. + // + // We can use the value implied by Lemma 4 here, but note that that + // value includes k, the number of iterations. It's plenty fast if + // we count through the iterations to compute that value, but if + // we're going to count through the iterations, we might as well use + // the two-parameter bound from Lemma 3, summing up as we go. This + // gives us a tighter bound and more comprehensible code. + // + // While computing this bound, if we find the value justified by the + // theory lies outside the representable range of CostValue, we + // conclude that the given arc costs have magnitudes so large that + // we cannot guarantee our calculations don't overflow. If the value + // justified by the theory lies inside the representable range of + // CostValue, we commit that our calculation will not overflow. This + // commitment means we need to be careful with the amount by which + // we relabel right-side nodes that are incident to any node with + // only one neighbor. + CostValue price_lower_bound_; + + // A bound on the amount by which a node's price can be reduced + // during the current iteration, used only for slack + // relabelings. Where epsilon is the first iteration's error + // parameter and C is the largest magnitude of an arc cost, we set + // slack_relabeling_price_ = -B(C, epsilon) + // = (C + epsilon) * (n-2)/2. + // + // We could use slack_relabeling_price_ for feasibility detection + // but the feasibility threshold is double the slack relabeling + // amount and we judge it not to be worth having to multiply by two + // gratuitously to check feasibility in each double push + // operation. Instead we settle for feasibility detection using + // price_lower_bound_ instead, which is somewhat slower in the + // infeasible case because more relabelings will be required for + // some node price to attain the looser bound. + CostValue slack_relabeling_price_; + + // Computes the value of the bound on price reduction for an + // iteration, given the old and new values of epsilon_. Because the + // expression computed here is used in at least one place where we + // want an additional factor in the denominator, we take that factor + // as an argument. If extra_divisor == 1, this function computes of + // the function B() discussed above. + // + // Avoids overflow in computing the bound, and sets *in_range = + // false if the value of the bound doesn't fit in CostValue. + inline CostValue PriceChangeBound(CostValue old_epsilon, + CostValue new_epsilon, + bool* in_range) const { + const CostValue n = graph_->num_nodes(); + // We work in double-precision floating point to determine whether + // we'll overflow the integral CostValue type's range of + // representation. Switching between integer and double is a + // rather expensive operation, but we do this only twice per + // scaling iteration, so we can afford it rather than resort to + // complex and subtle tricks within the bounds of integer + // arithmetic. + // + // You will want to read the comments above about + // price_lower_bound_ and slack_relabeling_price_, and have a + // pencil handy. :-) + const double result = + static_cast(std::max(1, n / 2 - 1)) * + (static_cast(old_epsilon) + static_cast(new_epsilon)); + const double limit = + static_cast(std::numeric_limits::max()); + if (result > limit) { + // Our integer computations could overflow. + if (in_range != nullptr) *in_range = false; + return std::numeric_limits::max(); + } else { + // Don't touch *in_range; other computations could already have + // set it to false and we don't want to overwrite that result. + return static_cast(result); + } + } + + // A scaled record of the largest arc-cost magnitude we've been + // given during problem setup. This is used to set the initial value + // of epsilon_, which in turn is used not only as the error + // parameter but also to determine whether we risk arithmetic + // overflow during the algorithm. + // + // Note: Our treatment of arithmetic overflow assumes the following + // property of CostValue: + // -std::numeric_limits::max() is a representable + // CostValue. + // That property is satisfied if CostValue uses a two's-complement + // representation. + CostValue largest_scaled_cost_magnitude_; + + // The total excess in the graph. Given our asymmetric definition of + // epsilon-optimality and our use of the double-push operation, this + // equals the number of unmatched left-side nodes. + NodeIndex total_excess_; + + // Indexed by node index, the price_ values are maintained only for + // right-side nodes. + // + // Note: We use a ZVector to only allocate a vector of size num_left_nodes_ + // instead of 2*num_left_nodes_ since the right-side node indices start at + // num_left_nodes_. + ZVector price_; + + // Indexed by left-side node index, the matched_arc_ array gives the + // arc index of the arc matching any given left-side node, or + // GraphType::kNilArc if the node is unmatched. + std::vector matched_arc_; + + // Indexed by right-side node index, the matched_node_ array gives + // the node index of the left-side node matching any given + // right-side node, or GraphType::kNilNode if the right-side node is + // unmatched. + // + // Note: We use a ZVector for the same reason as for price_. + ZVector matched_node_; + + // The array of arc costs as given in the problem definition, except + // that they are scaled up by the number of nodes in the graph so we + // can use integer arithmetic throughout. + std::vector scaled_arc_cost_; + + // The container of active nodes (i.e., unmatched nodes). This can + // be switched easily between ActiveNodeStack and ActiveNodeQueue + // for experimentation. + std::unique_ptr active_nodes_; + + // Statistics giving the overall numbers of various operations the + // algorithm performs. + Stats total_stats_; + + // Statistics giving the numbers of various operations the algorithm + // has performed in the current iteration. + Stats iteration_stats_; + + DISALLOW_COPY_AND_ASSIGN(LinearSumAssignment); +}; + +// Implementation of out-of-line LinearSumAssignment template member +// functions. + +template +const CostValue LinearSumAssignment::kMinEpsilon = 1; + +template +LinearSumAssignment::LinearSumAssignment( + const GraphType& graph, const NodeIndex num_left_nodes) + : graph_(&graph), + num_left_nodes_(num_left_nodes), + success_(false), + cost_scaling_factor_(1 + num_left_nodes), + alpha_(FLAGS_assignment_alpha), + epsilon_(0), + price_lower_bound_(0), + slack_relabeling_price_(0), + largest_scaled_cost_magnitude_(0), + total_excess_(0), + price_(num_left_nodes, 2 * num_left_nodes - 1), + matched_arc_(num_left_nodes, 0), + matched_node_(num_left_nodes, 2 * num_left_nodes - 1), + scaled_arc_cost_(graph.max_end_arc_index(), 0), + active_nodes_(FLAGS_assignment_stack_order + ? static_cast( + new ActiveNodeStack()) + : static_cast( + new ActiveNodeQueue())) {} + +template +LinearSumAssignment::LinearSumAssignment( + const NodeIndex num_left_nodes, const ArcIndex num_arcs) + : graph_(nullptr), + num_left_nodes_(num_left_nodes), + success_(false), + cost_scaling_factor_(1 + num_left_nodes), + alpha_(FLAGS_assignment_alpha), + epsilon_(0), + price_lower_bound_(0), + slack_relabeling_price_(0), + largest_scaled_cost_magnitude_(0), + total_excess_(0), + price_(num_left_nodes, 2 * num_left_nodes - 1), + matched_arc_(num_left_nodes, 0), + matched_node_(num_left_nodes, 2 * num_left_nodes - 1), + scaled_arc_cost_(num_arcs, 0), + active_nodes_(FLAGS_assignment_stack_order + ? static_cast( + new ActiveNodeStack()) + : static_cast( + new ActiveNodeQueue())) {} + +template +void LinearSumAssignment::SetArcCost(ArcIndex arc, CostValue cost) { + if (graph_ != nullptr) { + DCHECK_GE(arc, 0); + DCHECK_LT(arc, graph_->num_arcs()); + NodeIndex head = Head(arc); + DCHECK_LE(num_left_nodes_, head); + } + cost *= cost_scaling_factor_; + const CostValue cost_magnitude = std::abs(cost); + largest_scaled_cost_magnitude_ = + std::max(largest_scaled_cost_magnitude_, cost_magnitude); + scaled_arc_cost_[arc] = cost; +} + +template +class CostValueCycleHandler : public PermutationCycleHandler { + public: + explicit CostValueCycleHandler(std::vector* cost) + : temp_(0), cost_(cost) {} + + void SetTempFromIndex(ArcIndexType source) override { + temp_ = (*cost_)[source]; + } + + void SetIndexFromIndex(ArcIndexType source, + ArcIndexType destination) const override { + (*cost_)[destination] = (*cost_)[source]; + } + + void SetIndexFromTemp(ArcIndexType destination) const override { + (*cost_)[destination] = temp_; + } + + ~CostValueCycleHandler() override {} + + private: + CostValue temp_; + std::vector* const cost_; + + DISALLOW_COPY_AND_ASSIGN(CostValueCycleHandler); +}; + +// Logically this class should be defined inside OptimizeGraphLayout, +// but compilation fails if we do that because C++98 doesn't allow +// instantiation of member templates with function-scoped types as +// template parameters, which in turn is because those function-scoped +// types lack linkage. +template +class ArcIndexOrderingByTailNode { + public: + explicit ArcIndexOrderingByTailNode(const GraphType& graph) : graph_(graph) {} + + // Says ArcIndex a is less than ArcIndex b if arc a's tail is less + // than arc b's tail. If their tails are equal, orders according to + // heads. + bool operator()(typename GraphType::ArcIndex a, + typename GraphType::ArcIndex b) const { + return ((graph_.Tail(a) < graph_.Tail(b)) || + ((graph_.Tail(a) == graph_.Tail(b)) && + (graph_.Head(a) < graph_.Head(b)))); + } + + private: + const GraphType& graph_; + + // Copy and assign are allowed; they have to be for STL to work + // with this functor, although it seems like a bug for STL to be + // written that way. +}; + +// Passes ownership of the cycle handler to the caller. +template +PermutationCycleHandler* +LinearSumAssignment::ArcAnnotationCycleHandler() { + return new CostValueCycleHandler( + &scaled_arc_cost_); +} + +template +void LinearSumAssignment::OptimizeGraphLayout(GraphType* graph) { + // The graph argument is only to give us a non-const-qualified + // handle on the graph we already have. Any different graph is + // nonsense. + DCHECK_EQ(graph_, graph); + const ArcIndexOrderingByTailNode compare(*graph_); + CostValueCycleHandler cycle_handler( + &scaled_arc_cost_); + TailArrayManager tail_array_manager(graph); + tail_array_manager.BuildTailArrayFromAdjacencyListsIfForwardGraph(); + graph->GroupForwardArcsByFunctor(compare, &cycle_handler); + tail_array_manager.ReleaseTailArrayIfForwardGraph(); +} + +template +CostValue LinearSumAssignment::NewEpsilon( + const CostValue current_epsilon) const { + return std::max(current_epsilon / alpha_, kMinEpsilon); +} + +template +bool LinearSumAssignment::UpdateEpsilon() { + CostValue new_epsilon = NewEpsilon(epsilon_); + slack_relabeling_price_ = PriceChangeBound(epsilon_, new_epsilon, nullptr); + epsilon_ = new_epsilon; + VLOG(3) << "Updated: epsilon_ == " << epsilon_; + VLOG(4) << "slack_relabeling_price_ == " << slack_relabeling_price_; + DCHECK_GT(slack_relabeling_price_, 0); + // For today we always return true; in the future updating epsilon + // in sophisticated ways could conceivably detect infeasibility + // before the first iteration of Refine(). + return true; +} + +// For production code that checks whether a left-side node is active. +template +inline bool LinearSumAssignment::IsActive(NodeIndex left_node) + const { + DCHECK_LT(left_node, num_left_nodes_); + return matched_arc_[left_node] == GraphType::kNilArc; +} + +// Only for debugging. Separate from the production IsActive() method +// so that method can assert that its argument is a left-side node, +// while for debugging we need to be able to test any node. +template +inline bool LinearSumAssignment::IsActiveForDebugging(NodeIndex node) + const { + if (node < num_left_nodes_) { + return IsActive(node); + } else { + return matched_node_[node] == GraphType::kNilNode; + } +} + +template +void LinearSumAssignment::InitializeActiveNodeContainer() { + DCHECK(active_nodes_->Empty()); + for (BipartiteLeftNodeIterator node_it(*graph_, num_left_nodes_); + node_it.Ok(); node_it.Next()) { + const NodeIndex node = node_it.Index(); + if (IsActive(node)) { + active_nodes_->Add(node); + } + } +} + +// There exists a price function such that the admissible arcs at the +// beginning of an iteration are exactly the reverse arcs of all +// matching arcs. Saturating all admissible arcs with respect to that +// price function therefore means simply unmatching every matched +// node. +// +// In the future we will price out arcs, which will reduce the set of +// nodes we unmatch here. If a matching arc is priced out, we will not +// unmatch its endpoints since that element of the matching is +// guaranteed not to change. +template +void LinearSumAssignment::SaturateNegativeArcs() { + total_excess_ = 0; + for (BipartiteLeftNodeIterator node_it(*graph_, num_left_nodes_); + node_it.Ok(); node_it.Next()) { + const NodeIndex node = node_it.Index(); + if (IsActive(node)) { + // This can happen in the first iteration when nothing is + // matched yet. + total_excess_ += 1; + } else { + // We're about to create a unit of excess by unmatching these nodes. + total_excess_ += 1; + const NodeIndex mate = GetMate(node); + matched_arc_[node] = GraphType::kNilArc; + matched_node_[mate] = GraphType::kNilNode; + } + } +} + +// Returns true for success, false for infeasible. +template +bool LinearSumAssignment::DoublePush(NodeIndex source) { + DCHECK_GT(num_left_nodes_, source); + DCHECK(IsActive(source)) << "Node " << source + << "must be active (unmatched)!"; + ImplicitPriceSummary summary = BestArcAndGap(source); + const ArcIndex best_arc = summary.first; + const CostValue gap = summary.second; + // Now we have the best arc incident to source, i.e., the one with + // minimum reduced cost. Match that arc, unmatching its head if + // necessary. + if (best_arc == GraphType::kNilArc) { + return false; + } + const NodeIndex new_mate = Head(best_arc); + const NodeIndex to_unmatch = matched_node_[new_mate]; + if (to_unmatch != GraphType::kNilNode) { + // Unmatch new_mate from its current mate, pushing the unit of + // flow back to a node on the left side as a unit of excess. + matched_arc_[to_unmatch] = GraphType::kNilArc; + active_nodes_->Add(to_unmatch); + // This counts as a double push. + iteration_stats_.double_pushes_ += 1; + } else { + // We are about to increase the cardinality of the matching. + total_excess_ -= 1; + // This counts as a single push. + iteration_stats_.pushes_ += 1; + } + matched_arc_[source] = best_arc; + matched_node_[new_mate] = source; + // Finally, relabel new_mate. + iteration_stats_.relabelings_ += 1; + const CostValue new_price = price_[new_mate] - gap - epsilon_; + price_[new_mate] = new_price; + return new_price >= price_lower_bound_; +} + +template +bool LinearSumAssignment::Refine() { + SaturateNegativeArcs(); + InitializeActiveNodeContainer(); + while (total_excess_ > 0) { + // Get an active node (i.e., one with excess == 1) and discharge + // it using DoublePush. + const NodeIndex node = active_nodes_->Get(); + if (!DoublePush(node)) { + // Infeasibility detected. + return false; + } + } + DCHECK(active_nodes_->Empty()); + iteration_stats_.refinements_ += 1; + return true; +} + +// Computes best_arc, the minimum reduced-cost arc incident to +// left_node and admissibility_gap, the amount by which the reduced +// cost of best_arc must be increased to make it equal in reduced cost +// to another residual arc incident to left_node. +// +// Precondition: left_node is unmatched and has at least one incident +// arc. This allows us to simplify the code. The debug-only +// counterpart to this routine is LinearSumAssignment::ImplicitPrice() +// and it assumes there is an incident arc but does not assume the +// node is unmatched. The condition that each left node has at least +// one incident arc is explicitly computed during FinalizeSetup(). +// +// This function is large enough that our suggestion that the compiler +// inline it might be pointless. +template +inline typename LinearSumAssignment::ImplicitPriceSummary +LinearSumAssignment::BestArcAndGap(NodeIndex left_node) const { + DCHECK(IsActive(left_node)) << "Node " << left_node + << " must be active (unmatched)!"; + DCHECK_GT(epsilon_, 0); + typename GraphType::OutgoingArcIterator arc_it(*graph_, left_node); + ArcIndex best_arc = arc_it.Index(); + CostValue min_partial_reduced_cost = PartialReducedCost(best_arc); + // We choose second_min_partial_reduced_cost so that in the case of + // the largest possible gap (which results from a left-side node + // with only a single incident residual arc), the corresponding + // right-side node will be relabeled by an amount that exactly + // matches slack_relabeling_price_. + CostValue second_min_partial_reduced_cost = + min_partial_reduced_cost + slack_relabeling_price_ - epsilon_; + for (arc_it.Next(); arc_it.Ok(); arc_it.Next()) { + const ArcIndex arc = arc_it.Index(); + const CostValue partial_reduced_cost = PartialReducedCost(arc); + if (partial_reduced_cost < second_min_partial_reduced_cost) { + if (partial_reduced_cost < min_partial_reduced_cost) { + best_arc = arc; + second_min_partial_reduced_cost = min_partial_reduced_cost; + min_partial_reduced_cost = partial_reduced_cost; + } else { + second_min_partial_reduced_cost = partial_reduced_cost; + } + } + } + const CostValue gap = + second_min_partial_reduced_cost - min_partial_reduced_cost; + DCHECK_GE(gap, 0); + return std::make_pair(best_arc, gap); +} + +// Only for debugging. +// +// Requires the precondition, explicitly computed in FinalizeSetup(), +// that every left-side node has at least one incident arc. +template +inline CostValue LinearSumAssignment::ImplicitPrice( + NodeIndex left_node) const { + DCHECK_GT(num_left_nodes_, left_node); + DCHECK_GT(epsilon_, 0); + typename GraphType::OutgoingArcIterator arc_it(*graph_, left_node); + // We must not execute this method if left_node has no incident arc. + DCHECK(arc_it.Ok()); + ArcIndex best_arc = arc_it.Index(); + if (best_arc == matched_arc_[left_node]) { + arc_it.Next(); + if (arc_it.Ok()) { + best_arc = arc_it.Index(); + } + } + CostValue min_partial_reduced_cost = PartialReducedCost(best_arc); + if (!arc_it.Ok()) { + // Only one arc is incident to left_node, and the node is + // currently matched along that arc, which must be the case in any + // feasible solution. Therefore we implicitly price this node so + // low that we will never consider unmatching it. + return -(min_partial_reduced_cost + slack_relabeling_price_); + } + for (arc_it.Next(); arc_it.Ok(); arc_it.Next()) { + const ArcIndex arc = arc_it.Index(); + if (arc != matched_arc_[left_node]) { + const CostValue partial_reduced_cost = PartialReducedCost(arc); + if (partial_reduced_cost < min_partial_reduced_cost) { + min_partial_reduced_cost = partial_reduced_cost; + } + } + } + return -min_partial_reduced_cost; +} + +// Only for debugging. +template +bool LinearSumAssignment::AllMatched() const { + for (NodeIndex node = 0; node < graph_->num_nodes(); ++node) { + if (IsActiveForDebugging(node)) { + return false; + } + } + return true; +} + +// Only for debugging. +template +bool LinearSumAssignment::EpsilonOptimal() const { + for (BipartiteLeftNodeIterator node_it(*graph_, num_left_nodes_); + node_it.Ok(); node_it.Next()) { + const NodeIndex left_node = node_it.Index(); + // Get the implicit price of left_node and make sure the reduced + // costs of left_node's incident arcs are in bounds. + CostValue left_node_price = ImplicitPrice(left_node); + for (typename GraphType::OutgoingArcIterator arc_it(*graph_, left_node); + arc_it.Ok(); arc_it.Next()) { + const ArcIndex arc = arc_it.Index(); + const CostValue reduced_cost = left_node_price + PartialReducedCost(arc); + // Note the asymmetric definition of epsilon-optimality that we + // use because it means we can saturate all admissible arcs in + // the beginning of Refine() just by unmatching all matched + // nodes. + if (matched_arc_[left_node] == arc) { + // The reverse arc is residual. Epsilon-optimality requires + // that the reduced cost of the forward arc be at most + // epsilon_. + if (reduced_cost > epsilon_) { + return false; + } + } else { + // The forward arc is residual. Epsilon-optimality requires + // that the reduced cost of the forward arc be at least zero. + if (reduced_cost < 0) { + return false; + } + } + } + } + return true; +} + +template +bool LinearSumAssignment::FinalizeSetup() { + incidence_precondition_satisfied_ = true; + // epsilon_ must be greater than kMinEpsilon so that in the case + // where the largest arc cost is zero, we still do a Refine() + // iteration. + epsilon_ = std::max(largest_scaled_cost_magnitude_, kMinEpsilon + 1); + VLOG(2) << "Largest given cost magnitude: " + << largest_scaled_cost_magnitude_ / cost_scaling_factor_; + // Initialize left-side node-indexed arrays and check incidence + // precondition. + for (NodeIndex node = 0; node < num_left_nodes_; ++node) { + matched_arc_[node] = GraphType::kNilArc; + typename GraphType::OutgoingArcIterator arc_it(*graph_, node); + if (!arc_it.Ok()) { + incidence_precondition_satisfied_ = false; + } + } + // Initialize right-side node-indexed arrays. Example: prices are + // stored only for right-side nodes. + for (NodeIndex node = num_left_nodes_; node < graph_->num_nodes(); ++node) { + price_[node] = 0; + matched_node_[node] = GraphType::kNilNode; + } + bool in_range = true; + double double_price_lower_bound = 0.0; + CostValue new_error_parameter; + CostValue old_error_parameter = epsilon_; + do { + new_error_parameter = NewEpsilon(old_error_parameter); + double_price_lower_bound -= + 2.0 * static_cast(PriceChangeBound( + old_error_parameter, new_error_parameter, &in_range)); + old_error_parameter = new_error_parameter; + } while (new_error_parameter != kMinEpsilon); + const double limit = + -static_cast(std::numeric_limits::max()); + if (double_price_lower_bound < limit) { + in_range = false; + price_lower_bound_ = -std::numeric_limits::max(); + } else { + price_lower_bound_ = static_cast(double_price_lower_bound); + } + VLOG(4) << "price_lower_bound_ == " << price_lower_bound_; + DCHECK_LE(price_lower_bound_, 0); + if (!in_range) { + LOG(WARNING) << "Price change bound exceeds range of representable " + << "costs; arithmetic overflow is not ruled out and " + << "infeasibility might go undetected."; + } + return in_range; +} + +template +void LinearSumAssignment::ReportAndAccumulateStats() { + total_stats_.Add(iteration_stats_); + VLOG(3) << "Iteration stats: " << iteration_stats_.StatsString(); + iteration_stats_.Clear(); +} + +template +bool LinearSumAssignment::ComputeAssignment() { + CHECK_NOTNULL(graph_); + bool ok = graph_->num_nodes() == 2 * num_left_nodes_; + if (!ok) return false; + // Note: FinalizeSetup() might have been called already by white-box + // test code or by a client that wants to react to the possibility + // of overflow before solving the given problem, but FinalizeSetup() + // is idempotent and reasonably fast, so we call it unconditionally + // here. + FinalizeSetup(); + ok = ok && incidence_precondition_satisfied_; + DCHECK(!ok || EpsilonOptimal()); + while (ok && epsilon_ > kMinEpsilon) { + ok = ok && UpdateEpsilon(); + ok = ok && Refine(); + ReportAndAccumulateStats(); + DCHECK(!ok || EpsilonOptimal()); + DCHECK(!ok || AllMatched()); + } + success_ = ok; + VLOG(1) << "Overall stats: " << total_stats_.StatsString(); + return ok; +} + +template +CostValue LinearSumAssignment::GetCost() const { + // It is illegal to call this method unless we successfully computed + // an optimum assignment. + DCHECK(success_); + CostValue cost = 0; + for (BipartiteLeftNodeIterator node_it(*this); node_it.Ok(); node_it.Next()) { + cost += GetAssignmentCost(node_it.Index()); + } + return cost; +} + +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_LINEAR_ASSIGNMENT_H_ diff --git a/thirdparty/linux/include/ortools/graph/max_flow.h b/thirdparty/linux/include/ortools/graph/max_flow.h new file mode 100644 index 0000000..a6bc66f --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/max_flow.h @@ -0,0 +1,709 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// An implementation of a push-relabel algorithm for the max flow problem. +// +// In the following, we consider a graph G = (V,E,s,t) where V denotes the set +// of nodes (vertices) in the graph, E denotes the set of arcs (edges). s and t +// denote distinguished nodes in G called source and target. n = |V| denotes the +// number of nodes in the graph, and m = |E| denotes the number of arcs in the +// graph. +// +// Each arc (v,w) is associated a capacity c(v,w). +// +// A flow is a function from E to R such that: +// +// a) f(v,w) <= c(v,w) for all (v,w) in E (capacity constraint.) +// +// b) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint.) +// +// c) sum on v f(v,w) = 0 (flow conservation.) +// +// The goal of this algorithm is to find the maximum flow from s to t, i.e. +// for example to maximize sum v f(s,v). +// +// The starting reference for this class of algorithms is: +// A.V. Goldberg and R.E. Tarjan. A new approach to the maximum flow problem. +// ACM Symposium on Theory of Computing, pp. 136-146. +// http://portal.acm.org/citation.cfm?id=12144. +// +// The basic idea of the algorithm is to handle preflows instead of flows, +// and to refine preflows until a maximum flow is obtained. +// A preflow is like a flow, except that the inflow can be larger than the +// outflow. If it is the case at a given node v, it is said that there is an +// excess at node v, and inflow = outflow + excess. +// +// More formally, a preflow is a function f such that: +// +// 1) f(v,w) <= c(v,w) for all (v,w) in E (capacity constraint). c(v,w) is a +// value representing the maximum capacity for arc (v,w). +// +// 2) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint) +// +// 3) excess(v) = sum on u f(u,v) >= 0 is the excess at node v, the +// algebraic sum of all the incoming preflows at this node. +// +// Each node has an associated "height", in addition to its excess. The +// height of the source is defined to be equal to n, and cannot change. The +// height of the target is defined to be zero, and cannot change either. The +// height of all the other nodes is initialized at zero and is updated during +// the algorithm (see below). For those who want to know the details, the height +// of a node, corresponds to a reduced cost, and this enables one to prove that +// the algorithm actually computes the max flow. Note that the height of a node +// can be initialized to the distance to the target node in terms of number of +// nodes. This has not been tried in this implementation. +// +// A node v is said to be *active* if excess(v) > 0. +// +// In this case the following operations can be applied to it: +// +// - if there are *admissible* incident arcs, i.e. arcs which are not saturated, +// and whose tail's height is lower than the height of the active node +// considered, a PushFlow operation can be applied. It consists in sending as +// much flow as both the excess at the node and the capacity of the arc +// permit. +// - if there are no admissible arcs, the active node considered is relabeled, +// i.e. its height is increased to 1 + the minimum height of its neighboring +// nodes on admissible arcs. +// This is implemented in Discharge, which itself calls PushFlow and Relabel. +// +// Before running Discharge, it is necessary to initialize the algorithm with a +// preflow. This is done in InitializePreflow, which saturates all the arcs +// leaving the source node, and sets the excess at the heads of those arcs +// accordingly. +// +// The algorithm terminates when there are no remaining active nodes, i.e. all +// the excesses at all nodes are equal to zero. In this case, a maximum flow is +// obtained. +// +// The complexity of this algorithm depends amongst other things on the choice +// of the next active node. It has been shown, for example in: +// L. Tuncel, "On the Complexity of Preflow-Push Algorithms for Maximum-Flow +// Problems", Algorithmica 11(4): 353-359 (1994). +// and +// J. Cheriyan and K. Mehlhorn, "An analysis of the highest-level selection rule +// in the preflow-push max-flow algorithm", Information processing letters, +// 69(5):239-242 (1999). +// http://www.math.uwaterloo.ca/~jcheriya/PS_files/me3.0.ps +// +// ...that choosing the active node with the highest level yields a +// complexity of O(n^2 * sqrt(m)). +// +// TODO(user): implement the above active node choice rule. +// +// This has been validated experimentally in: +// R.K. Ahuja, M. Kodialam, A.K. Mishra, and J.B. Orlin, "Computational +// Investigations of Maximum Flow Algorithms", EJOR 97:509-542(1997). +// http://jorlin.scripts.mit.edu/docs/publications/58-comput%20investigations%20of.pdf. +// +// +// TODO(user): an alternative would be to evaluate: +// A.V. Goldberg, "The Partial Augment-Relabel Algorithm for the Maximum Flow +// Problem.” In Proceedings of Algorithms ESA, LNCS 5193:466-477, Springer 2008. +// http://www.springerlink.com/index/5535k2j1mt646338.pdf +// +// An interesting general reference on network flows is: +// R. K. Ahuja, T. L. Magnanti, J. B. Orlin, "Network Flows: Theory, Algorithms, +// and Applications," Prentice Hall, 1993, ISBN: 978-0136175490, +// http://www.amazon.com/dp/013617549X +// +// Keywords: Push-relabel, max-flow, network, graph, Goldberg, Tarjan, Dinic, +// Dinitz. + +#ifndef OR_TOOLS_GRAPH_MAX_FLOW_H_ +#define OR_TOOLS_GRAPH_MAX_FLOW_H_ + +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/graph/ebert_graph.h" +#include "ortools/graph/flow_problem.pb.h" +#include "ortools/graph/graph.h" +#include "ortools/util/stats.h" +#include "ortools/util/zvector.h" + +namespace operations_research { + +// Forward declaration. +template +class GenericMaxFlow; + +// A simple and efficient max-cost flow interface. This is as fast as +// GenericMaxFlow, which is the fastest, but uses +// more memory in order to hide the somewhat involved construction of the +// static graph. +// +// TODO(user): If the need arises, extend this interface to support warm start +// and incrementality between solves. +class SimpleMaxFlow { + public: + // The constructor takes no size. + // New node indices will be created lazily by AddArcWithCapacity(). + SimpleMaxFlow(); + + // Adds a directed arc with the given capacity from tail to head. + // * Node indices and capacity must be non-negative (>= 0). + // * Self-looping and duplicate arcs are supported. + // * After the method finishes, NumArcs() == the returned ArcIndex + 1. + ArcIndex AddArcWithCapacity(NodeIndex tail, NodeIndex head, + FlowQuantity capacity); + + // Returns the current number of nodes. This is one more than the largest + // node index seen so far in AddArcWithCapacity(). + NodeIndex NumNodes() const; + + // Returns the current number of arcs in the graph. + ArcIndex NumArcs() const; + + // Returns user-provided data. + // The implementation will crash if "arc" is not in [0, NumArcs()). + NodeIndex Tail(ArcIndex arc) const; + NodeIndex Head(ArcIndex arc) const; + FlowQuantity Capacity(ArcIndex arc) const; + + // Solves the problem (finds the maximum flow from the given source to the + // given sink), and returns the problem status. + enum Status { + // Solve() was called and found an optimal solution. Note that OptimalFlow() + // may be 0 which means that the sink is not reachable from the source. + OPTIMAL, + // There is a flow > std::numeric_limits::max(). Note that in + // this case, the class will contain a solution with a flow reaching that + // bound. + // + // TODO(user): rename POSSIBLE_OVERFLOW to INT_OVERFLOW and modify our + // clients. + POSSIBLE_OVERFLOW, + // The input is inconsistent (bad tail/head/capacity values). + BAD_INPUT, + // This should not happen. There was an error in our code (i.e. file a bug). + BAD_RESULT + }; + Status Solve(NodeIndex source, NodeIndex sink); + + // Returns the maximum flow we can send from the source to the sink in the + // last OPTIMAL Solve() context. + FlowQuantity OptimalFlow() const; + + // Returns the flow on the given arc in the last OPTIMAL Solve() context. + // + // Note: It is possible that there is more than one optimal solution. The + // algorithm is deterministic so it will always return the same solution for + // a given problem. However, there is no guarantee of this from one code + // version to the next (but the code does not change often). + FlowQuantity Flow(ArcIndex arc) const; + + // Returns the nodes reachable from the source by non-saturated arcs (.i.e. + // arc with Flow(arc) < Capacity(arc)), the outgoing arcs of this set form a + // minimum cut. This works only if Solve() returned OPTIMAL. + void GetSourceSideMinCut(std::vector* result); + + // Returns the nodes that can reach the sink by non-saturated arcs, the + // outgoing arcs of this set form a minimun cut. Note that if this is the + // complement set of GetNodeReachableFromSource(), then the min-cut is unique. + // This works only if Solve() returned OPTIMAL. + void GetSinkSideMinCut(std::vector* result); + + // Creates the protocol buffer representation of the problem used by the last + // Solve() call. This is mainly useful for debugging. + FlowModel CreateFlowModelOfLastSolve(); + + private: + NodeIndex num_nodes_; + std::vector arc_tail_; + std::vector arc_head_; + std::vector arc_capacity_; + std::vector arc_permutation_; + std::vector arc_flow_; + FlowQuantity optimal_flow_; + + // Note that we cannot free the graph before we stop using the max-flow + // instance that uses it. + typedef ReverseArcStaticGraph Graph; + std::unique_ptr underlying_graph_; + std::unique_ptr > underlying_max_flow_; + + DISALLOW_COPY_AND_ASSIGN(SimpleMaxFlow); +}; + +// Specific but efficient priority queue implementation. The priority type must +// be an integer. The queue allows to retrieve the element with highest priority +// but only allows pushes with a priority greater or equal to the highest +// priority in the queue minus one. All operations are in O(1) and the memory is +// in O(num elements in the queue). Elements with the same priority are +// retrieved with LIFO order. +// +// Note(user): As far as I know, this is an original idea and is the only code +// that use this in the Maximum Flow context. Papers usually refer to an +// height-indexed array of simple linked lists of active node with the same +// height. Even worse, sometimes they use double-linked list to allow arbitrary +// height update in order to detect missing height (used for the Gap heuristic). +// But this can actually be implemented a lot more efficiently by just +// maintaining the height distribution of all the node in the graph. +template +class PriorityQueueWithRestrictedPush { + public: + PriorityQueueWithRestrictedPush() : even_queue_(), odd_queue_() {} + + // Is the queue empty? + bool IsEmpty() const; + + // Clears the queue. + void Clear(); + + // Push a new element in the queue. Its priority must be greater or equal to + // the highest priority present in the queue, minus one. This condition is + // DCHECKed, and violating it yields erroneous queue behavior in NDEBUG mode. + void Push(Element index, IntegerPriority priority); + + // Returns the element with highest priority and remove it from the queue. + // IsEmpty() must be false, this condition is DCHECKed. + Element Pop(); + + private: + // Helper function to get the last element of a vector and pop it. + Element PopBack(std::vector >* queue); + + // This is the heart of the algorithm. basically we split the elements by + // parity of their priority and the precondition on the Push() ensures that + // both vectors are always sorted by increasing priority. + std::vector > even_queue_; + std::vector > odd_queue_; + + DISALLOW_COPY_AND_ASSIGN(PriorityQueueWithRestrictedPush); +}; + +// We want an enum for the Status of a max flow run, and we want this +// enum to be scoped under GenericMaxFlow<>. Unfortunately, swig +// doesn't handle templated enums very well, so we need a base, +// untemplated class to hold it. +class MaxFlowStatusClass { + public: + enum Status { + NOT_SOLVED, // The problem was not solved, or its data were edited. + OPTIMAL, // Solve() was called and found an optimal solution. + INT_OVERFLOW, // There is a feasible flow > max possible flow. + BAD_INPUT, // The input is inconsistent. + BAD_RESULT // There was an error. + }; +}; + +// Generic MaxFlow (there is a default MaxFlow specialization defined below) +// that works with StarGraph and all the reverse arc graphs from graph.h, see +// the end of max_flow.cc for the exact types this class is compiled for. +template +class GenericMaxFlow : public MaxFlowStatusClass { + public: + typedef typename Graph::NodeIndex NodeIndex; + typedef typename Graph::ArcIndex ArcIndex; + typedef typename Graph::OutgoingArcIterator OutgoingArcIterator; + typedef typename Graph::OutgoingOrOppositeIncomingArcIterator + OutgoingOrOppositeIncomingArcIterator; + typedef typename Graph::IncomingArcIterator IncomingArcIterator; + typedef ZVector ArcIndexArray; + + // The height of a node never excess 2 times the number of node, so we + // use the same type as a Node index. + typedef NodeIndex NodeHeight; + typedef ZVector NodeHeightArray; + + // Initialize a MaxFlow instance on the given graph. The graph does not need + // to be fully built yet, but its capacity reservation are used to initialize + // the memory of this class. source and target must also be valid node of + // graph. + GenericMaxFlow(const Graph* graph, NodeIndex source, NodeIndex target); + virtual ~GenericMaxFlow() {} + + // Returns the graph associated to the current object. + const Graph* graph() const { return graph_; } + + // Returns the status of last call to Solve(). NOT_SOLVED is returned if + // Solve() has never been called or if the problem has been modified in such a + // way that the previous solution becomes invalid. + Status status() const { return status_; } + + // Returns the index of the node corresponding to the source of the network. + NodeIndex GetSourceNodeIndex() const { return source_; } + + // Returns the index of the node corresponding to the sink of the network. + NodeIndex GetSinkNodeIndex() const { return sink_; } + + // Sets the capacity for arc to new_capacity. + void SetArcCapacity(ArcIndex arc, FlowQuantity new_capacity); + + // Sets the flow for arc. + void SetArcFlow(ArcIndex arc, FlowQuantity new_flow); + + // Returns true if a maximum flow was solved. + bool Solve(); + + // Returns the total flow found by the algorithm. + FlowQuantity GetOptimalFlow() const { return node_excess_[sink_]; } + + // Returns the flow on arc using the equations given in the comment on + // residual_arc_capacity_. + FlowQuantity Flow(ArcIndex arc) const { + if (IsArcDirect(arc)) { + return residual_arc_capacity_[Opposite(arc)]; + } else { + return -residual_arc_capacity_[arc]; + } + } + + // Returns the capacity of arc using the equations given in the comment on + // residual_arc_capacity_. + FlowQuantity Capacity(ArcIndex arc) const { + if (IsArcDirect(arc)) { + return residual_arc_capacity_[arc] + + residual_arc_capacity_[Opposite(arc)]; + } else { + return 0; + } + } + + // Returns the nodes reachable from the source in the residual graph, the + // outgoing arcs of this set form a minimum cut. + void GetSourceSideMinCut(std::vector* result); + + // Returns the nodes that can reach the sink in the residual graph, the + // outgoing arcs of this set form a minimun cut. Note that if this is the + // complement of GetNodeReachableFromSource(), then the min-cut is unique. + // + // TODO(user): In the two-phases algorithm, we can get this minimum cut + // without doing the second phase. Add an option for this if there is a need + // to, note that the second phase is pretty fast so the gain will be small. + void GetSinkSideMinCut(std::vector* result); + + // Checks the consistency of the input, i.e. that capacities on the arcs are + // non-negative or null. + bool CheckInputConsistency() const; + + // Checks whether the result is valid, i.e. that node excesses are all equal + // to zero (we have a flow) and that residual capacities are all non-negative + // or zero. + bool CheckResult() const; + + // Returns true if there exists a path from the source to the sink with + // remaining capacity. This allows us to easily check at the end that the flow + // we computed is indeed optimal (provided that all the conditions tested by + // CheckResult() also hold). + bool AugmentingPathExists() const; + + // Sets the different algorithm options. All default to true. + // See the corresponding variable declaration below for more details. + void SetUseGlobalUpdate(bool value) { + use_global_update_ = value; + if (!use_global_update_) process_node_by_height_ = false; + } + void SetUseTwoPhaseAlgorithm(bool value) { use_two_phase_algorithm_ = value; } + void SetCheckInput(bool value) { check_input_ = value; } + void SetCheckResult(bool value) { check_result_ = value; } + void ProcessNodeByHeight(bool value) { + process_node_by_height_ = value && use_global_update_; + } + + // Returns the protocol buffer representation of the current problem. + FlowModel CreateFlowModel(); + + protected: + // Returns true if arc is admissible. + bool IsAdmissible(ArcIndex arc) const { + return residual_arc_capacity_[arc] > 0 && + node_potential_[Tail(arc)] == node_potential_[Head(arc)] + 1; + } + + // Returns true if node is active, i.e. if its excess is positive and it + // is neither the source or the sink of the graph. + bool IsActive(NodeIndex node) const { + return (node != source_) && (node != sink_) && (node_excess_[node] > 0); + } + + // Sets the capacity of arc to 'capacity' and clears the flow on arc. + void SetCapacityAndClearFlow(ArcIndex arc, FlowQuantity capacity) { + residual_arc_capacity_.Set(arc, capacity); + residual_arc_capacity_.Set(Opposite(arc), 0); + } + + // Returns true if a precondition for Relabel is met, i.e. the outgoing arcs + // of node are all either saturated or the heights of their heads are greater + // or equal to the height of node. + bool CheckRelabelPrecondition(NodeIndex node) const; + + // Returns context concatenated with information about arc + // in a human-friendly way. + std::string DebugString(const std::string& context, ArcIndex arc) const; + + // Initializes the container active_nodes_. + void InitializeActiveNodeContainer(); + + // Get the first element from the active node container. + NodeIndex GetAndRemoveFirstActiveNode() { + if (process_node_by_height_) return active_node_by_height_.Pop(); + const NodeIndex node = active_nodes_.back(); + active_nodes_.pop_back(); + return node; + } + + // Push element to the active node container. + void PushActiveNode(const NodeIndex& node) { + if (process_node_by_height_) { + active_node_by_height_.Push(node, node_potential_[node]); + } else { + active_nodes_.push_back(node); + } + } + + // Check the emptiness of the container. + bool IsEmptyActiveNodeContainer() { + if (process_node_by_height_) { + return active_node_by_height_.IsEmpty(); + } else { + return active_nodes_.empty(); + } + } + + // Performs optimization step. + void Refine(); + void RefineWithGlobalUpdate(); + + // Discharges an active node node by saturating its admissible adjacent arcs, + // if any, and by relabelling it when it becomes inactive. + void Discharge(NodeIndex node); + + // Initializes the preflow to a state that enables to run Refine. + void InitializePreflow(); + + // Clears the flow excess at each node by pushing the flow back to the source: + // - Do a depth-first search from the source in the direct graph to cancel + // flow cycles. + // - Then, return flow excess along the depth-first search tree (by pushing + // the flow in the reverse dfs topological order). + // The theoretical complexity is O(mn), but it is a lot faster in practice. + void PushFlowExcessBackToSource(); + + // Computes the best possible node potential given the current flow using a + // reverse breadth-first search from the sink in the reverse residual graph. + // This is an implementation of the global update heuristic mentioned in many + // max-flow papers. See for instance: B.V. Cherkassky, A.V. Goldberg, "On + // implementing push-relabel methods for the maximum flow problem", + // Algorithmica, 19:390-410, 1997. + // ftp://reports.stanford.edu/pub/cstr/reports/cs/tr/94/1523/CS-TR-94-1523.pdf + void GlobalUpdate(); + + // Tries to saturate all the outgoing arcs from the source that can reach the + // sink. Most of the time, we can do that in one go, except when more flow + // than kMaxFlowQuantity can be pushed out of the source in which case we + // have to be careful. Returns true if some flow was pushed. + bool SaturateOutgoingArcsFromSource(); + + // Pushes flow on arc, i.e. consumes flow on residual_arc_capacity_[arc], + // and consumes -flow on residual_arc_capacity_[Opposite(arc)]. Updates + // node_excess_ at the tail and head of arc accordingly. + void PushFlow(FlowQuantity flow, ArcIndex arc); + + // Relabels a node, i.e. increases its height by the minimum necessary amount. + // This version of Relabel is relaxed in a way such that if an admissible arc + // exists at the current node height, then the node is not relabeled. This + // enables us to deal with wrong values of first_admissible_arc_[node] when + // updating it is too costly. + void Relabel(NodeIndex node); + + // Handy member functions to make the code more compact. + NodeIndex Head(ArcIndex arc) const { return graph_->Head(arc); } + NodeIndex Tail(ArcIndex arc) const { return graph_->Tail(arc); } + ArcIndex Opposite(ArcIndex arc) const; + bool IsArcDirect(ArcIndex arc) const; + bool IsArcValid(ArcIndex arc) const; + + // Returns the set of nodes reachable from start in the residual graph or in + // the reverse residual graph (if reverse is true). + template + void ComputeReachableNodes(NodeIndex start, std::vector* result); + + // Maximum manageable flow. + static const FlowQuantity kMaxFlowQuantity; + + // A pointer to the graph passed as argument. + const Graph* graph_; + + // An array representing the excess for each node in graph_. + QuantityArray node_excess_; + + // An array representing the height function for each node in graph_. For a + // given node, this is a lower bound on the shortest path length from this + // node to the sink in the residual network. The height of a node always goes + // up during the course of a Solve(). + // + // Since initially we saturate all the outgoing arcs of the source, we can + // never reach the sink from the source in the residual graph. Initially we + // set the height of the source to n (the number of node of the graph) and it + // never changes. If a node as an height >= n, then this node can't reach the + // sink and its height minus n is a lower bound on the shortest path length + // from this node to the source in the residual graph. + NodeHeightArray node_potential_; + + // An array representing the residual_capacity for each arc in graph_. + // Residual capacities enable one to represent the capacity and flow for all + // arcs in the graph in the following manner. + // For all arc, residual_arc_capacity_[arc] = capacity[arc] - flow[arc] + // Moreover, for reverse arcs, capacity[arc] = 0 by definition, + // Also flow[Opposite(arc)] = -flow[arc] by definition. + // Therefore: + // - for a direct arc: + // flow[arc] = 0 - flow[Opposite(arc)] + // = capacity[Opposite(arc)] - flow[Opposite(arc)] + // = residual_arc_capacity_[Opposite(arc)] + // - for a reverse arc: + // flow[arc] = -residual_arc_capacity_[arc] + // Using these facts enables one to only maintain residual_arc_capacity_, + // instead of both capacity and flow, for each direct and indirect arc. This + // reduces the amount of memory for this information by a factor 2. + QuantityArray residual_arc_capacity_; + + // An array representing the first admissible arc for each node in graph_. + ArcIndexArray first_admissible_arc_; + + // A stack used for managing active nodes in the algorithm. + // Note that the papers cited above recommend the use of a queue, but + // benchmarking so far has not proved it is better. In particular, processing + // nodes in LIFO order has better cache locality. + std::vector active_nodes_; + + // A priority queue used for managing active nodes in the algorithm. It allows + // to select the active node with highest height before each Discharge(). + // Moreover, since all pushes from this node will be to nodes with height + // greater or equal to the initial discharged node height minus one, the + // PriorityQueueWithRestrictedPush is a perfect fit. + PriorityQueueWithRestrictedPush active_node_by_height_; + + // The index of the source node in graph_. + NodeIndex source_; + + // The index of the sink node in graph_. + NodeIndex sink_; + + // The status of the problem. + Status status_; + + // BFS queue used by the GlobalUpdate() function. We do not use a C++ queue + // because we need access to the vector for different optimizations. + std::vector node_in_bfs_queue_; + std::vector bfs_queue_; + + // Whether or not to use GlobalUpdate(). + bool use_global_update_; + + // Whether or not we use a two-phase algorithm: + // 1/ Only deal with nodes that can reach the sink. At the end we know the + // value of the maximum flow and we have a min-cut. + // 2/ Call PushFlowExcessBackToSource() to obtain a max-flow. This is usually + // a lot faster than the first phase. + bool use_two_phase_algorithm_; + + // Whether or not we use the PriorityQueueWithRestrictedPush to process the + // active nodes rather than a simple queue. This can only be true if + // use_global_update_ is true. + // + // Note(user): using a template will be slightly faster, but since we test + // this in a non-critical path, this only has a minor impact. + bool process_node_by_height_; + + // Whether or not we check the input, this is a small price to pay for + // robustness. Disable only if you know the input is valid because an invalid + // input can cause the algorithm to run into an infinite loop! + bool check_input_; + + // Whether or not we check the result. + // TODO(user): Make the check more exhaustive by checking the optimality? + bool check_result_; + + // Statistics about this class. + mutable StatsGroup stats_; + + private: + DISALLOW_COPY_AND_ASSIGN(GenericMaxFlow); +}; + +#if !SWIG + +// Default instance MaxFlow that uses StarGraph. Note that we cannot just use a +// typedef because of dependent code expecting MaxFlow to be a real class. +// TODO(user): Modify this code and remove it. +class MaxFlow : public GenericMaxFlow { + public: + MaxFlow(const StarGraph* graph, NodeIndex source, NodeIndex target) + : GenericMaxFlow(graph, source, target) {} +}; + +#endif // SWIG + +template +bool PriorityQueueWithRestrictedPush::IsEmpty() + const { + return even_queue_.empty() && odd_queue_.empty(); +} + +template +void PriorityQueueWithRestrictedPush::Clear() { + even_queue_.clear(); + odd_queue_.clear(); +} + +template +void PriorityQueueWithRestrictedPush::Push( + Element element, IntegerPriority priority) { + // Since users may rely on it, we DCHECK the exact condition. + DCHECK(even_queue_.empty() || priority >= even_queue_.back().second - 1); + DCHECK(odd_queue_.empty() || priority >= odd_queue_.back().second - 1); + + // Note that the DCHECK() below are less restrictive than the ones above but + // check a necessary and sufficient condition for the priority queue to behave + // as expected. + if (priority & 1) { + DCHECK(odd_queue_.empty() || priority >= odd_queue_.back().second); + odd_queue_.push_back(std::make_pair(element, priority)); + } else { + DCHECK(even_queue_.empty() || priority >= even_queue_.back().second); + even_queue_.push_back(std::make_pair(element, priority)); + } +} + +template +Element PriorityQueueWithRestrictedPush::Pop() { + DCHECK(!IsEmpty()); + if (even_queue_.empty()) return PopBack(&odd_queue_); + if (odd_queue_.empty()) return PopBack(&even_queue_); + if (odd_queue_.back().second > even_queue_.back().second) { + return PopBack(&odd_queue_); + } else { + return PopBack(&even_queue_); + } +} + +template +Element PriorityQueueWithRestrictedPush::PopBack( + std::vector >* queue) { + DCHECK(!queue->empty()); + Element element = queue->back().first; + queue->pop_back(); + return element; +} + +} // namespace operations_research +#endif // OR_TOOLS_GRAPH_MAX_FLOW_H_ diff --git a/thirdparty/linux/include/ortools/graph/min_cost_flow.h b/thirdparty/linux/include/ortools/graph/min_cost_flow.h new file mode 100644 index 0000000..fe2bdba --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/min_cost_flow.h @@ -0,0 +1,621 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// An implementation of a cost-scaling push-relabel algorithm for +// the min-cost flow problem. +// +// In the following, we consider a graph G = (V,E) where V denotes the set +// of nodes (vertices) in the graph, E denotes the set of arcs (edges). +// n = |V| denotes the number of nodes in the graph, and m = |E| denotes the +// number of arcs in the graph. +// +// With each arc (v,w) is associated a nonnegative capacity u(v,w) +// (where 'u' stands for "upper bound") and a unit cost c(v,w). With +// each node v is associated a quantity named supply(v), which +// represents a supply of fluid (if >0) or a demand (if <0). +// Furthermore, no fluid is created in the graph so +// sum_{v in V} supply(v) = 0. +// +// A flow is a function from E to R such that: +// a) f(v,w) <= u(v,w) for all (v,w) in E (capacity constraint). +// b) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint). +// c) sum on v f(v,w) + supply(w) = 0 (flow conservation). +// +// The cost of a flow is sum on (v,w) in E ( f(v,w) * c(v,w) ) [Note: +// It can be confusing to beginners that the cost is actually double +// the amount that it might seem at first because of flow +// antisymmetry.] +// +// The problem to solve: find a flow of minimum cost such that all the +// fluid flows from the supply nodes to the demand nodes. +// +// The principles behind this algorithm are the following: +// 1/ handle pseudo-flows instead of flows and refine pseudo-flows until an +// epsilon-optimal minimum-cost flow is obtained, +// 2/ deal with epsilon-optimal pseudo-flows. +// +// 1/ A pseudo-flow is like a flow, except that a node's outflow minus +// its inflow can be different from its supply. If it is the case at a +// given node v, it is said that there is an excess (or deficit) at +// node v. A deficit is denoted by a negative excess and inflow = +// outflow + excess. +// (Look at ortools/graph/max_flow.h to see that the definition +// of preflow is more restrictive than the one for pseudo-flow in that a preflow +// only allows non-negative excesses, i.e., no deficit.) +// More formally, a pseudo-flow is a function f such that: +// a) f(v,w) <= u(v,w) for all (v,w) in E (capacity constraint). +// b) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint). +// +// For each v in E, we also define the excess at node v, the algebraic sum of +// all the incoming preflows at this node, added together with the supply at v. +// excess(v) = sum on u f(u,v) + supply(v) +// +// The goal of the algorithm is to obtain excess(v) = 0 for all v in V, while +// consuming capacity on some arcs, at the lowest possible cost. +// +// 2/ Internally to the algorithm and its analysis (but invisibly to +// the client), each node has an associated "price" (or potential), in +// addition to its excess. It is formally a function from E to R (the +// set of real numbers.). For a given price function p, the reduced +// cost of an arc (v,w) is: +// c_p(v,w) = c(v,w) + p(v) - p(w) +// (c(v,w) is the cost of arc (v,w).) For those familiar with linear +// programming, the price function can be viewed as a set of dual +// variables. +// +// For a constant epsilon >= 0, a pseudo-flow f is said to be epsilon-optimal +// with respect to a price function p if for every residual arc (v,w) in E, +// c_p(v,w) >= -epsilon. +// +// A flow f is optimal if and only if there exists a price function p such that +// no arc is admissible with respect to f and p. +// +// If the arc costs are integers, and epsilon < 1/n, any epsilon-optimal flow +// is optimal. The integer cost case is handled by multiplying all the arc costs +// and the initial value of epsilon by (n+1). When epsilon reaches 1, and +// the solution is epsilon-optimal, it means: for all residual arc (v,w) in E, +// (n+1) * c_p(v,w) >= -1, thus c_p(v,w) >= -1/(n+1) >= 1/n, and the +// solution is optimal. +// +// A node v is said to be *active* if excess(v) > 0. +// In this case the following operations can be applied to it: +// - if there are *admissible* incident arcs, i.e. arcs which are not saturated, +// and whose reduced costs are negative, a PushFlow operation can +// be applied. It consists in sending as much flow as both the excess at the +// node and the capacity of the arc permit. +// - if there are no admissible arcs, the active node considered is relabeled, +// This is implemented in Discharge, which itself calls PushFlow and Relabel. +// +// Discharge itself is called by Refine. Refine first saturates all the +// admissible arcs, then builds a stack of active nodes. It then applies +// Discharge for each active node, possibly adding new ones in the process, +// until no nodes are active. In that case an epsilon-optimal flow is obtained. +// +// Optimize iteratively calls Refine, while epsilon > 1, and divides epsilon by +// alpha (set by default to 5) before each iteration. +// +// The algorithm starts with epsilon = C, where C is the maximum absolute value +// of the arc costs. In the integer case which we are dealing with, since all +// costs are multiplied by (n+1), the initial value of epsilon is (n+1)*C. +// The algorithm terminates when epsilon = 1, and Refine() has been called. +// In this case, a minimum-cost flow is obtained. +// +// The complexity of the algorithm is O(n^2*m*log(n*C)) where C is the value of +// the largest arc cost in the graph. +// +// IMPORTANT: +// The algorithm is not able to detect the infeasibility of a problem (i.e., +// when a bottleneck in the network prohibits sending all the supplies.) +// Worse, it could in some cases loop forever. This is why feasibility checking +// is enabled by default (FLAGS_min_cost_flow_check_feasibility=true.) +// Feasibility checking is implemented using a max-flow, which has a much lower +// complexity. The impact on performance is negligible, while the risk of being +// caught in an endless loop is removed. Note that using the feasibility checker +// roughly doubles the memory consumption. +// +// The starting reference for this class of algorithms is: +// A.V. Goldberg and R.E. Tarjan, "Finding Minimum-Cost Circulations by +// Successive Approximation." Mathematics of Operations Research, Vol. 15, +// 1990:430-466. +// http://portal.acm.org/citation.cfm?id=92225 +// +// Implementation issues are tackled in: +// A.V. Goldberg, "An Efficient Implementation of a Scaling Minimum-Cost Flow +// Algorithm," Journal of Algorithms, (1997) 22:1-29 +// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.258 +// +// A.V. Goldberg and M. Kharitonov, "On Implementing Scaling Push-Relabel +// Algorithms for the Minimum-Cost Flow Problem", Network flows and matching: +// First DIMACS implementation challenge, DIMACS Series in Discrete Mathematics +// and Theoretical Computer Science, (1993) 12:157-198. +// ftp://dimacs.rutgers.edu/pub/netflow/submit/papers/Goldberg-mincost/scalmin.ps +// and in: +// U. Bunnagel, B. Korte, and J. Vygen. “Efficient implementation of the +// Goldberg-Tarjan minimum-cost flow algorithm.” Optimization Methods and +// Software (1998) vol. 10, no. 2:157-174. +// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.84.9897 +// +// We have tried as much as possible in this implementation to keep the +// notations and namings of the papers cited above, except for 'demand' or +// 'balance' which have been replaced by 'supply', with the according sign +// changes to better accomodate with the API of the rest of our tools. A demand +// is denoted by a negative supply. +// +// TODO(user): See whether the following can bring any improvements on real-life +// problems. +// R.K. Ahuja, A.V. Goldberg, J.B. Orlin, and R.E. Tarjan, "Finding minimum-cost +// flows by double scaling," Mathematical Programming, (1992) 53:243-266. +// http://www.springerlink.com/index/gu7404218u6kt166.pdf +// +// An interesting general reference on network flows is: +// R. K. Ahuja, T. L. Magnanti, J. B. Orlin, "Network Flows: Theory, Algorithms, +// and Applications," Prentice Hall, 1993, ISBN: 978-0136175490, +// http://www.amazon.com/dp/013617549X +// +// Keywords: Push-relabel, min-cost flow, network, graph, Goldberg, Tarjan, +// Dinic, Dinitz. + +#ifndef OR_TOOLS_GRAPH_MIN_COST_FLOW_H_ +#define OR_TOOLS_GRAPH_MIN_COST_FLOW_H_ + +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/graph/ebert_graph.h" +#include "ortools/graph/graph.h" +#include "ortools/util/stats.h" +#include "ortools/util/zvector.h" + +namespace operations_research { + +// Forward declaration. +template +class GenericMinCostFlow; + +// Different statuses for a solved problem. +// We use a base class to share it between our different interfaces. +class MinCostFlowBase { + public: + enum Status { + NOT_SOLVED, + OPTIMAL, + FEASIBLE, + INFEASIBLE, + UNBALANCED, + BAD_RESULT, + BAD_COST_RANGE + }; +}; + +// A simple and efficient min-cost flow interface. This is as fast as +// GenericMinCostFlow, which is the fastest, but is uses +// more memory in order to hide the somewhat involved construction of the +// static graph. +// +// TODO(user): If the need arises, extend this interface to support warm start +// and incrementality between solves. Note that this is already supported by the +// GenericMinCostFlow<> interface. +class SimpleMinCostFlow : public MinCostFlowBase { + public: + // The constructor takes no size. New node indices will be created lazily by + // AddArcWithCapacityAndUnitCost() or SetNodeSupply() such that the set of + // valid nodes will always be [0, NumNodes()). + SimpleMinCostFlow(); + + // Adds a directed arc from tail to head to the underlying graph with + // a given capacity and cost per unit of flow. + // * Node indices and the capacity must be non-negative (>= 0). + // * The unit cost can take any integer value (even negative). + // * Self-looping and duplicate arcs are supported. + // * After the method finishes, NumArcs() == the returned ArcIndex + 1. + ArcIndex AddArcWithCapacityAndUnitCost(NodeIndex tail, NodeIndex head, + FlowQuantity capacity, + CostValue unit_cost); + + // Sets the supply of the given node. The node index must be non-negative (>= + // 0). Nodes implicitly created will have a default supply set to 0. A demand + // is modeled as a negative supply. + void SetNodeSupply(NodeIndex node, FlowQuantity supply); + + // Solves the problem, and returns the problem status. This function + // requires that the sum of all node supply minus node demand is zero and + // that the graph has enough capacity to send all supplies and serve all + // demands. Otherwise, it will return INFEASIBLE. + Status Solve() { + return SolveWithPossibleAdjustment(SupplyAdjustment::DONT_ADJUST); + } + + // Same as Solve(), but does not have the restriction that the supply + // must match the demand or that the graph has enough capacity to serve + // all the demand or use all the supply. This will compute a maximum-flow + // with minimum cost. The value of the maximum-flow will be given by + // MaximumFlow(). + Status SolveMaxFlowWithMinCost() { + return SolveWithPossibleAdjustment(SupplyAdjustment::ADJUST); + } + + // Returns the cost of the minimum-cost flow found by the algorithm when + // the returned Status is OPTIMAL. + CostValue OptimalCost() const; + + // Returns the total flow of the minimum-cost flow found by the algorithm + // when the returned Status is OPTIMAL. + FlowQuantity MaximumFlow() const; + + // Returns the flow on arc, this only make sense for a successful Solve(). + // + // Note: It is possible that there is more than one optimal solution. The + // algorithm is deterministic so it will always return the same solution for + // a given problem. However, there is no guarantee of this from one code + // version to the next (but the code does not change often). + FlowQuantity Flow(ArcIndex arc) const; + + // Accessors for the user given data. The implementation will crash if "arc" + // is not in [0, NumArcs()) or "node" is not in [0, NumNodes()). + NodeIndex NumNodes() const; + ArcIndex NumArcs() const; + NodeIndex Tail(ArcIndex arc) const; + NodeIndex Head(ArcIndex arc) const; + FlowQuantity Capacity(ArcIndex arc) const; + FlowQuantity Supply(NodeIndex node) const; + CostValue UnitCost(ArcIndex arc) const; + + private: + typedef ReverseArcStaticGraph Graph; + enum SupplyAdjustment { + ADJUST, + DONT_ADJUST + }; + + // Applies the permutation in arc_permutation_ to the given arc index. + ArcIndex PermutedArc(ArcIndex arc); + // Solves the problem, potentially applying supply and demand adjustment, + // and returns the problem status. + Status SolveWithPossibleAdjustment(SupplyAdjustment adjustment); + void ResizeNodeVectors(NodeIndex node); + + std::vector arc_tail_; + std::vector arc_head_; + std::vector arc_capacity_; + std::vector node_supply_; + std::vector arc_cost_; + std::vector arc_permutation_; + std::vector arc_flow_; + CostValue optimal_cost_; + FlowQuantity maximum_flow_; + + DISALLOW_COPY_AND_ASSIGN(SimpleMinCostFlow); +}; + +// Generic MinCostFlow that works with StarGraph and all the graphs handling +// reverse arcs from graph.h, see the end of min_cost_flow.cc for the exact +// types this class is compiled for. +// +// One can greatly decrease memory usage by using appropriately small integer +// types: +// - For the Graph<> types, i.e. NodeIndexType and ArcIndexType, see graph.h. +// - ArcFlowType is used for the *per-arc* flow quantity. It must be signed, and +// large enough to hold the maximum arc capacity and its negation. +// - ArcScaledCostType is used for a per-arc scaled cost. It must be signed +// and large enough to hold the maximum unit cost of an arc times +// (num_nodes + 1). +// +// Note that the latter two are different than FlowQuantity and CostValue, which +// are used for global, aggregated values and may need to be larger. +// +// TODO(user): Avoid using the globally defined type CostValue and FlowQuantity. +// Also uses the Arc*Type where there is no risk of overflow in more places. +template +class GenericMinCostFlow : public MinCostFlowBase { + public: + typedef typename Graph::NodeIndex NodeIndex; + typedef typename Graph::ArcIndex ArcIndex; + typedef typename Graph::OutgoingArcIterator OutgoingArcIterator; + typedef typename Graph::OutgoingOrOppositeIncomingArcIterator + OutgoingOrOppositeIncomingArcIterator; + typedef ZVector ArcIndexArray; + + // Initialize a MinCostFlow instance on the given graph. The graph does not + // need to be fully built yet, but its capacity reservation is used to + // initialize the memory of this class. + explicit GenericMinCostFlow(const Graph* graph); + + // Returns the graph associated to the current object. + const Graph* graph() const { return graph_; } + + // Returns the status of last call to Solve(). NOT_SOLVED is returned if + // Solve() has never been called or if the problem has been modified in such a + // way that the previous solution becomes invalid. + Status status() const { return status_; } + + // Sets the supply corresponding to node. A demand is modeled as a negative + // supply. + void SetNodeSupply(NodeIndex node, FlowQuantity supply); + + // Sets the unit cost for the given arc. + void SetArcUnitCost(ArcIndex arc, ArcScaledCostType unit_cost); + + // Sets the capacity for the given arc. + void SetArcCapacity(ArcIndex arc, ArcFlowType new_capacity); + + // Sets the flow for the given arc. Note that new_flow must be smaller than + // the capacity of the arc. + void SetArcFlow(ArcIndex arc, ArcFlowType new_flow); + + // Solves the problem, returning true if a min-cost flow could be found. + bool Solve(); + + // Checks for feasibility, i.e., that all the supplies and demands can be + // matched without exceeding bottlenecks in the network. + // If infeasible_supply_node (resp. infeasible_demand_node) are not NULL, + // they are populated with the indices of the nodes where the initial supplies + // (resp. demands) are too large. Feasible values for the supplies and + // demands are accessible through FeasibleSupply. + // Note that CheckFeasibility is called by Solve() when the flag + // min_cost_flow_check_feasibility is set to true (which is the default.) + bool CheckFeasibility(std::vector* const infeasible_supply_node, + std::vector* const infeasible_demand_node); + + // Makes the min-cost flow problem solvable by truncating supplies and + // demands to a level acceptable by the network. There may be several ways to + // do it. In our case, the levels are computed from the result of the max-flow + // algorithm run in CheckFeasibility(). + // MakeFeasible returns false if CheckFeasibility() was not called before. + bool MakeFeasible(); + + // Returns the cost of the minimum-cost flow found by the algorithm. + CostValue GetOptimalCost() const { return total_flow_cost_; } + + // Returns the flow on the given arc using the equations given in the + // comment on residual_arc_capacity_. + FlowQuantity Flow(ArcIndex arc) const; + + // Returns the capacity of the given arc. + FlowQuantity Capacity(ArcIndex arc) const; + + // Returns the unscaled cost for the given arc. + CostValue UnitCost(ArcIndex arc) const; + + // Returns the supply at a given node. Demands are modelled as negative + // supplies. + FlowQuantity Supply(NodeIndex node) const; + + // Returns the initial supply at a given node. + FlowQuantity InitialSupply(NodeIndex node) const; + + // Returns the largest supply (if > 0) or largest demand in absolute value + // (if < 0) admissible at node. If the problem is not feasible, some of these + // values will be smaller (in absolute value) than the initial supplies + // and demand given as input. + FlowQuantity FeasibleSupply(NodeIndex node) const; + + // Whether to use the UpdatePrices() heuristic. + void SetUseUpdatePrices(bool value) { use_price_update_ = value; } + + // Whether to check the feasibility of the problem with a max-flow, prior to + // solving it. This uses about twice as much memory, but detects infeasible + // problems (where the flow can't be satisfied) and makes Solve() return + // INFEASIBLE. If you disable this check, you will spare memory but you must + // make sure that your problem is feasible, otherwise the code can loop + // forever. + void SetCheckFeasibility(bool value) { check_feasibility_ = value; } + + private: + // Returns true if the given arc is admissible i.e. if its residual capacity + // is strictly positive, and its reduced cost strictly negative, i.e., pushing + // more flow into it will result in a reduction of the total cost. + bool IsAdmissible(ArcIndex arc) const; + bool FastIsAdmissible(ArcIndex arc, CostValue tail_potential) const; + + // Returns true if node is active, i.e., if its supply is positive. + bool IsActive(NodeIndex node) const; + + // Returns the reduced cost for a given arc. + CostValue ReducedCost(ArcIndex arc) const; + CostValue FastReducedCost(ArcIndex arc, CostValue tail_potential) const; + + // Returns the first incident arc of a given node. + ArcIndex GetFirstOutgoingOrOppositeIncomingArc(NodeIndex node) const; + + // Checks the consistency of the input, i.e., whether the sum of the supplies + // for all nodes is equal to zero. To be used in a DCHECK. + bool CheckInputConsistency() const; + + // Checks whether the result is valid, i.e. whether for each arc, + // residual_arc_capacity_[arc] == 0 || ReducedCost(arc) >= -epsilon_. + // (A solution is epsilon-optimal if ReducedCost(arc) >= -epsilon.) + // To be used in a DCHECK. + bool CheckResult() const; + + // Checks that the cost range fits in the range of int64's. + // To be used in a DCHECK. + bool CheckCostRange() const; + + // Checks the relabel precondition (to be used in a DCHECK): + // - The node must be active, or have a 0 excess (relaxation for the Push + // Look-Ahead heuristic). + // - The node must have no admissible arcs. + bool CheckRelabelPrecondition(NodeIndex node) const; + + // Returns context concatenated with information about a given arc + // in a human-friendly way. + std::string DebugString(const std::string& context, ArcIndex arc) const; + + // Resets the first_admissible_arc_ array to the first incident arc of each + // node. + void ResetFirstAdmissibleArcs(); + + // Scales the costs, by multiplying them by (graph_->num_nodes() + 1). + void ScaleCosts(); + + // Unscales the costs, by dividing them by (graph_->num_nodes() + 1). + void UnscaleCosts(); + + // Optimizes the cost by dividing epsilon_ by alpha_ and calling Refine(). + void Optimize(); + + // Saturates the admissible arcs, i.e., push as much flow as possible. + void SaturateAdmissibleArcs(); + + // Pushes flow on a given arc, i.e., consumes flow on + // residual_arc_capacity_[arc], and consumes -flow on + // residual_arc_capacity_[Opposite(arc)]. Updates node_excess_ at the tail + // and head of the arc accordingly. + void PushFlow(FlowQuantity flow, ArcIndex arc); + void FastPushFlow(FlowQuantity flow, ArcIndex arc, NodeIndex tail); + + // Initializes the stack active_nodes_. + void InitializeActiveNodeStack(); + + // Price update heuristics as described in A.V. Goldberg, "An Efficient + // Implementation of a Scaling Minimum-Cost Flow Algorithm," Journal of + // Algorithms, (1997) 22:1-29 + // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.258 + void UpdatePrices(); + + // Performs an epsilon-optimization step by saturating admissible arcs + // and discharging the active nodes. + void Refine(); + + // Discharges an active node by saturating its admissible adjacent arcs, + // if any, and by relabelling it when it becomes inactive. + void Discharge(NodeIndex node); + + // Part of the Push LookAhead heuristic. When we are about to push on the + // in_arc, we check that the head (i.e node here) can accept the flow and + // return true if this is the case: + // - Returns true if the node excess is < 0. + // - Returns true if node is an admissible arc at its current potential. + // - If the two conditions above are false, the node can be relabeled. We + // do that and return true if the in_arc is still admissible. + bool LookAhead(ArcIndex in_arc, CostValue in_tail_potential, NodeIndex node); + + // Relabels node, i.e., decreases its potential while keeping the + // epsilon-optimality of the pseudo flow. See CheckRelabelPrecondition() for + // details on the preconditions. + void Relabel(NodeIndex node); + + // Handy member functions to make the code more compact. + NodeIndex Head(ArcIndex arc) const { return graph_->Head(arc); } + NodeIndex Tail(ArcIndex arc) const { return graph_->Tail(arc); } + ArcIndex Opposite(ArcIndex arc) const; + bool IsArcDirect(ArcIndex arc) const; + bool IsArcValid(ArcIndex arc) const; + + // Pointer to the graph passed as argument. + const Graph* graph_; + + // An array representing the supply (if > 0) or the demand (if < 0) + // for each node in graph_. + QuantityArray node_excess_; + + // An array representing the potential (or price function) for + // each node in graph_. + CostArray node_potential_; + + // An array representing the residual_capacity for each arc in graph_. + // Residual capacities enable one to represent the capacity and flow for all + // arcs in the graph in the following manner. + // For all arcs, residual_arc_capacity_[arc] = capacity[arc] - flow[arc] + // Moreover, for reverse arcs, capacity[arc] = 0 by definition. + // Also flow[Opposite(arc)] = -flow[arc] by definition. + // Therefore: + // - for a direct arc: + // flow[arc] = 0 - flow[Opposite(arc)] + // = capacity[Opposite(arc)] - flow[Opposite(arc)] + // = residual_arc_capacity_[Opposite(arc)] + // - for a reverse arc: + // flow[arc] = -residual_arc_capacity_[arc] + // Using these facts enables one to only maintain residual_arc_capacity_, + // instead of both capacity and flow, for each direct and indirect arc. This + // reduces the amount of memory for this information by a factor 2. + // Note that the sum of the largest capacity of an arc in the graph and of + // the total flow in the graph mustn't exceed the largest 64 bit integer + // to avoid errors. CheckInputConsistency() verifies this constraint. + ZVector residual_arc_capacity_; + + // An array representing the first admissible arc for each node in graph_. + ArcIndexArray first_admissible_arc_; + + // A stack used for managing active nodes in the algorithm. + // Note that the papers cited above recommend the use of a queue, but + // benchmarking so far has not proved it is better. + std::stack active_nodes_; + + // epsilon_ is the tolerance for optimality. + CostValue epsilon_; + + // alpha_ is the factor by which epsilon_ is divided at each iteration of + // Refine(). + const int64 alpha_; + + // cost_scaling_factor_ is the scaling factor for cost. + CostValue cost_scaling_factor_; + + // An array representing the scaled unit cost for each arc in graph_. + ZVector scaled_arc_unit_cost_; + + // The total cost of the flow. + CostValue total_flow_cost_; + + // The status of the problem. + Status status_; + + // An array containing the initial excesses (i.e. the supplies) for each + // node. This is used to create the max-flow-based feasibility checker. + QuantityArray initial_node_excess_; + + // An array containing the best acceptable excesses for each of the + // nodes. These excesses are imposed by the result of the max-flow-based + // feasibility checker for the nodes with an initial supply != 0. For the + // other nodes, the excess is simply 0. + QuantityArray feasible_node_excess_; + + // Statistics about this class. + StatsGroup stats_; + + // Number of Relabel() since last UpdatePrices(). + int num_relabels_since_last_price_update_; + + // A Boolean which is true when feasibility has been checked. + bool feasibility_checked_; + + // Whether to use the UpdatePrices() heuristic. + bool use_price_update_; + + // Whether to check the problem feasibility with a max-flow. + bool check_feasibility_; + + DISALLOW_COPY_AND_ASSIGN(GenericMinCostFlow); +}; + +#if !SWIG + +// Default MinCostFlow instance that uses StarGraph. +// New clients should use SimpleMinCostFlow if they can. +class MinCostFlow : public GenericMinCostFlow { + public: + explicit MinCostFlow(const StarGraph* graph) : GenericMinCostFlow(graph) {} +}; + +#endif // SWIG + +} // namespace operations_research +#endif // OR_TOOLS_GRAPH_MIN_COST_FLOW_H_ diff --git a/thirdparty/linux/include/ortools/graph/minimum_spanning_tree.h b/thirdparty/linux/include/ortools/graph/minimum_spanning_tree.h new file mode 100644 index 0000000..dad9009 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/minimum_spanning_tree.h @@ -0,0 +1,182 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_GRAPH_MINIMUM_SPANNING_TREE_H_ +#define OR_TOOLS_GRAPH_MINIMUM_SPANNING_TREE_H_ + +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/graph/connectivity.h" +#include "ortools/graph/graph.h" +#include "ortools/util/vector_or_function.h" +#include "ortools/base/adjustable_priority_queue-inl.h" +#include "ortools/base/adjustable_priority_queue.h" + +namespace operations_research { + +// Implementation of Kruskal's mininumum spanning tree algorithm (c.f. +// https://en.wikipedia.org/wiki/Kruskal%27s_algorithm). +// Returns the index of the arcs appearing in the tree; will return a forest if +// the graph is disconnected. Nodes without any arcs will be ignored. +// Each arc of the graph is interpreted as an undirected arc. +// Complexity of the algorithm is O(E * log(E)) where E is the number of arcs +// in the graph. Memory usage is O(E * log(E)). + +// TODO(user): Add a global Minimum Spanning Tree API automatically switching +// between Prim and Kruskal depending on problem size. + +// Version taking sorted graph arcs. Allows somewhat incremental recomputation +// of minimum spanning trees as most of the processing time is spent sorting +// arcs. +// Usage: +// ListGraph graph(...); +// std::vector sorted_arcs = ...; +// std::vector mst = BuildKruskalMinimumSpanningTreeFromSortedArcs( +// graph, sorted_arcs); +// +template +std::vector +BuildKruskalMinimumSpanningTreeFromSortedArcs( + const Graph& graph, + const std::vector& sorted_arcs) { + using ArcIndex = typename Graph::ArcIndex; + using NodeIndex = typename Graph::NodeIndex; + const int num_arcs = graph.num_arcs(); + int arc_index = 0; + std::vector tree_arcs; + if (graph.num_nodes() == 0) { + return tree_arcs; + } + const int expected_tree_size = graph.num_nodes() - 1; + tree_arcs.reserve(expected_tree_size); + ConnectedComponents components; + components.Init(graph.num_nodes()); + while (tree_arcs.size() != expected_tree_size && arc_index < num_arcs) { + const ArcIndex arc = sorted_arcs[arc_index]; + const NodeIndex tail_class = + components.GetClassRepresentative(graph.Tail(arc)); + const NodeIndex head_class = + components.GetClassRepresentative(graph.Head(arc)); + if (tail_class != head_class) { + components.MergeClasses(tail_class, head_class); + tree_arcs.push_back(arc); + } + ++arc_index; + } + return tree_arcs; +} + +// Version taking an arc comparator to sort graph arcs. +// Usage: +// ListGraph graph(...); +// const auto arc_cost = [&graph](int arc) { +// return f(graph.Tail(arc), graph.Head(arc)); +// }; +// std::vector mst = BuildKruskalMinimumSpanningTree( +// graph, +// [&arc_cost](int a, int b) { return arc_cost(a) < arc_cost(b); }); +// +template +std::vector BuildKruskalMinimumSpanningTree( + const Graph& graph, const ArcComparator& arc_comparator) { + using ArcIndex = typename Graph::ArcIndex; + std::vector sorted_arcs(graph.num_arcs()); + for (const ArcIndex arc : graph.AllForwardArcs()) { + sorted_arcs[arc] = arc; + } + std::sort(sorted_arcs.begin(), sorted_arcs.end(), arc_comparator); + return BuildKruskalMinimumSpanningTreeFromSortedArcs(graph, sorted_arcs); +} + +// Implementation of Prim's mininumum spanning tree algorithm (c.f. +// https://en.wikipedia.org/wiki/Prim's_algorithm) on undirected connected +// graphs. +// Returns the index of the arcs appearing in the tree. +// Complexity of the algorithm is O(E * log(V)) where E is the number of arcs +// in the graph, V is the number of vertices. Memory usage is O(V) + memory +// taken by the graph. +// Usage: +// ListGraph graph(...); +// const auto arc_cost = [&graph](int arc) -> int64 { +// return f(graph.Tail(arc), graph.Head(arc)); +// }; +// std::vector mst = BuildPrimMinimumSpanningTree(graph, arc_cost); +// +template +std::vector BuildPrimMinimumSpanningTree( + const Graph& graph, const ArcValue& arc_value) { + using ArcIndex = typename Graph::ArcIndex; + using NodeIndex = typename Graph::NodeIndex; + using ArcValueType = decltype(arc_value(0)); + std::vector tree_arcs; + if (graph.num_nodes() == 0) { + return tree_arcs; + } + const int expected_tree_size = graph.num_nodes() - 1; + tree_arcs.reserve(expected_tree_size); + std::vector node_neighbor(graph.num_nodes(), Graph::kNilArc); + std::vector node_active(graph.num_nodes(), true); + + // This struct represents entries in the adjustable priority queue which + // maintains active nodes (not added to the tree yet) in decreasing insertion + // cost order. AdjustablePriorityQueue requires the existence of the + // SetHeapIndex and GetHeapIndex methods. + struct Entry { + void SetHeapIndex(int index) { heap_index = index; } + int GetHeapIndex() const { return heap_index; } + bool operator<(const Entry& other) const { return value > other.value; } + + NodeIndex node; + ArcValueType value; + int heap_index; + }; + + AdjustablePriorityQueue pq; + std::vector entries; + for (NodeIndex node : graph.AllNodes()) { + entries.push_back({node, std::numeric_limits::max(), -1}); + } + entries[0].value = 0; + pq.Add(&entries[0]); + while (!pq.IsEmpty() && tree_arcs.size() != expected_tree_size) { + const Entry* best = pq.Top(); + const NodeIndex node = best->node; + pq.Pop(); + node_active[node] = false; + if (node_neighbor[node] != Graph::kNilArc) { + tree_arcs.push_back(node_neighbor[node]); + } + for (const ArcIndex arc : graph.OutgoingArcs(node)) { + const NodeIndex neighbor = graph.Head(arc); + if (node_active[neighbor]) { + const ArcValueType value = arc_value(arc); + Entry& entry = entries[neighbor]; + if (value < entry.value) { + node_neighbor[neighbor] = arc; + entry.value = value; + if (pq.Contains(&entry)) { + pq.NoteChangedPriority(&entry); + } else { + pq.Add(&entry); + } + } + } + } + } + return tree_arcs; +} + +} // namespace operations_research +#endif // OR_TOOLS_GRAPH_MINIMUM_SPANNING_TREE_H_ diff --git a/thirdparty/linux/include/ortools/graph/one_tree_lower_bound.h b/thirdparty/linux/include/ortools/graph/one_tree_lower_bound.h new file mode 100644 index 0000000..35f8cf1 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/one_tree_lower_bound.h @@ -0,0 +1,487 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// An implementation of the Held-Karp symmetric Traveling Salesman (TSP) lower +// bound algorithm, inspired by "Estimating the Held-Karp lower bound for the +// geometric TSP" by Christine L. Valenzuela and Antonia J. Jones, European +// Journal of Operational Research, Volume 102, Issue 1, 1 October 1997, +// Pages 157-175. +// +// The idea is to compute minimum 1-trees to evaluate a lower bound to the +// corresponding TSP. A minimum 1-tree is a minimum spanning tree on all nodes +// but one, to which are added the two shortest edges from the left-out node to +// the nodes of the spanning tree. The sum of the cost of the edges of the +// minimum 1-tree is a lower bound to the cost of the TSP. +// In order to improve (increase) this lower bound, the idea is to add weights +// to each nodes, weights which are added to the cost function used when +// computing the 1-tree. If weight[i] is the weight of node i, the cost function +// therefore becomes weighed_cost(i,j) = cost(i,j) + weight[i] + weight[j]. One +// can see that w = weighed_cost(minimum 1-tree) - Sum(2 * weight[i]) +// = cost(minimum 1-tree) + Sum(weight[i] * (degree[i] - 2)) +// is a valid lower bound to the TSP: +// 1) let T be the set of 1-trees on the nodes; +// 2) let U be the set of tours on the nodes; U is a subset of T (tours are +// 1-trees with all degrees equal to 2), therefore: +// std::min(t in T) Cost(t) <= std::min(t in U) Cost(t) +// and +// std::min(t in T) WeighedCost(t) <= std::min(t in U) WeighedCost(t) +// 3) weighed_cost(i,j) = cost(i,j) + weight[i] + weight[j], therefore: +// for all t in T, WeighedCost(t) = Cost(t) + Sum(weight[i] * degree[i]) +// and +// for all i in U, WeighedCost(t) = Cost(t) + Sum(weight[i] * 2) +// 4) let t* in U s.t. WeighedCost(t*) = std::min(t in U) WeighedCost(t), therefore: +// std::min(t in T) (Cost(t) + Sum(weight[i] * degree[i])) +// <= Cost(t*) + Sum(weight[i] * 2) +// and +// std::min(t in T) (Cost(t) + Sum(weight[i] * (degree[i] - 2))) <= Cost(t*) +// and +// cost(minimum 1-tree) + Sum(weight[i] * (degree[i] - 2)) <= Cost(t*) +// and +// w <= Cost(t*) +// 5) because t* is also the tour minimizing Cost(t) with t in U (weights do not +// affect the optimality of a tour), Cost(t*) is the cost of the optimal +// solution to the TSP and w is a lower bound to this cost. +// +// The best lower bound is the one for which weights maximize w. Intuitively as +// degrees get closer to 2 the minimum 1-trees gets closer to a tour. +// +// At each iteration m, weights are therefore updated as follows: +// weight(m+1)[i] = weight(m)[i] + step(m) * (degree(m)[i] - 2) +// where degree(m)[i] is the degree of node i in the 1-tree at iteration i, +// step(m) is a subgradient optimization step. +// +// This implementation uses two variants of Held-Karp's initial subgradient +// optimization iterative estimation approach described in "The +// traveling-salesman problem and minimum spanning trees: Part I and II", by +// Michael Held and Richard M. Karp, Operations Research Vol. 18, +// No. 6 (Nov. - Dec., 1970), pp. 1138-1162 and Mathematical Programming (1971). +// +// The first variant comes from Volgenant, T., and Jonker, R. (1982), "A branch +// and bound algorithm for the symmetric traveling salesman problem based on the +// 1-tree relaxation", European Journal of Operational Research. 9:83-89.". +// It suggests using +// step(m) = (1.0 * (m - 1) * (2 * M - 5) / (2 * (M - 1))) * step1 +// - (m - 2) * step1 +// + (0.5 * (m - 1) * (m - 2) / ((M - 1) * (M - 2))) * step1 +// where M is the maximum number of iterations and step1 is initially set to +// L / (2 * number of nodes), where L is the un-weighed cost of the 1-tree; +// step1 is updated each time a better w is found. The intuition is to have a +// positive decreasing step which is equal to 0 after M iterations; Volgenant +// and Jonker suggest that: +// step(m) - 2 * step(m-1) + t(m-2) = constant, +// step(M) = 0 +// and +// step(1) - step(2) = 3 * (step(M-1) - step(M)). +// The step(m) formula above derives from this recursive formulation. +// This is the default algorithm used in this implementation. +// +// The second variant comes from Held, M., Wolfe, P., and Crowder, H. P. (1974), +// "Validation of subgradient optimization", Mathematical Programming 6:62-88. +// It derives from the original Held-Karp formulation: +// step(m) = lambda(m) * (wlb - w(m)) / Sum((degree[i] - 2)^2), +// where wlb is a lower bound to std::max(w(m)) and lambda(m) in [0, 2]. +// Help-Karp prove that +// if w(m') > w(m) and 0 < step < 2 * (w(m') - w(m))/norm(degree(m) - 2)^2, +// then weight(m+1) is closer to w' than w from which they derive the above +// formula. +// Held-Wolfe-Crowder show that using an overestimate UB is as effective as +// using the underestimate wlb while UB is easier to compute. The resulting +// formula is: +// step(m) = lambda(m) * (UB - w(m)) / Sum((degree[i] - 2)^2), +// where UB is an upper bound to the TSP (here computed with the Christofides +// algorithm), and lambda(m) in [0, 2] initially set to 2. Held-Wolfe-Crowder +// suggest running the algorithm for M = 2 * number of nodes iterations, then +// dividing lambda and M by 2 until M is small enough (less than 2 in this +// implementation). +// +// To speed up the computation, minimum spanning trees are actually computed on +// a graph limited to the nearest neighbors of each node. Valenzuela-Jones 1997 +// experiments have shown that this does not harm the lower bound computation +// significantly. At the end of the algorithm a last iteration is run on the +// complete graph to ensure the bound is correct (the cost of a minimum 1-tree +// on a partial graph is an upper bound to the one on a complete graph). +// +// Usage: +// std::function cost_function =...; +// const double lower_bound = +// ComputeOneTreeLowerBound(number_of_nodes, cost_function); +// where number_of_nodes is the number of nodes in the TSP and cost_function +// is a function returning the cost between two nodes. + +#ifndef OR_TOOLS_GRAPH_ONE_TREE_LOWER_BOUND_H_ +#define OR_TOOLS_GRAPH_ONE_TREE_LOWER_BOUND_H_ + +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/graph/christofides.h" +#include "ortools/graph/minimum_spanning_tree.h" + +namespace operations_research { + +// Implementation of algorithms computing Held-Karp bounds. They have to provide +// the following methods: +// - bool Next(): returns false when the algorithm must stop; +// - double GetStep(): returns the current step computed by the algorithm; +// - void OnOneTree(CostType one_tree_cost, +// double w, +// const std::vector& degrees): +// called each time a new minimum 1-tree is computed; +// - one_tree_cost: the un-weighed cost of the 1-tree, +// - w the current value of w, +// - degrees: the degree of nodes in the 1-tree. +// - OnNewWMax(CostType one_tree_cost): called when a better value of w is +// found, one_tree_cost being the un-weighed cost of the corresponding +// minimum 1-tree. + +// Implementation of the Volgenant Jonker algorithm (see the comments at the +// head of the file for explanations). +template +class VolgenantJonkerEvaluator { + public: + VolgenantJonkerEvaluator(int number_of_nodes, int max_iterations) + : step1_initialized_(false), + step1_(0), + iteration_(0), + max_iterations_(max_iterations > 0 ? max_iterations + : MaxIterations(number_of_nodes)), + number_of_nodes_(number_of_nodes) {} + + bool Next() { return iteration_++ < max_iterations_; } + + double GetStep() const { + return (1.0 * (iteration_ - 1) * (2 * max_iterations_ - 5) / + (2 * (max_iterations_ - 1))) * + step1_ - + (iteration_ - 2) * step1_ + + (0.5 * (iteration_ - 1) * (iteration_ - 2) / + ((max_iterations_ - 1) * (max_iterations_ - 2))) * + step1_; + } + + void OnOneTree(CostType one_tree_cost, double w, + const std::vector& degrees) { + if (!step1_initialized_) { + step1_initialized_ = true; + UpdateStep(one_tree_cost); + } + } + + void OnNewWMax(CostType one_tree_cost) { UpdateStep(one_tree_cost); } + + private: + // Automatic computation of the number of iterations based on empirical + // results given in Valenzuela-Jones 1997. + static int MaxIterations(int number_of_nodes) { + return static_cast(28 * std::pow(number_of_nodes, 0.62)); + } + + void UpdateStep(CostType one_tree_cost) { + step1_ = one_tree_cost / (2 * number_of_nodes_); + } + + bool step1_initialized_; + double step1_; + int iteration_; + const int max_iterations_; + const int number_of_nodes_; +}; + +// Implementation of the Held-Wolfe-Crowder algorithm (see the comments at the +// head of the file for explanations). +template +class HeldWolfeCrowderEvaluator { + public: + HeldWolfeCrowderEvaluator(int number_of_nodes, const CostFunction& cost) + : iteration_(0), + number_of_iterations_(2 * number_of_nodes), + upper_bound_(0), + lambda_(2.0), + step_(0) { + // TODO(user): Improve upper bound with some local search; tighter upper + // bounds lead to faster convergence. + ChristofidesPathSolver solver( + number_of_nodes, cost); + upper_bound_ = solver.TravelingSalesmanCost(); + } + + bool Next() { + const int min_iterations = 2; + if (iteration_ >= number_of_iterations_) { + number_of_iterations_ /= 2; + if (number_of_iterations_ < min_iterations) return false; + iteration_ = 0; + lambda_ /= 2; + } else { + ++iteration_; + } + return true; + } + + double GetStep() const { return step_; } + + void OnOneTree(CostType one_tree_cost, double w, + const std::vector& degrees) { + double norm = 0; + for (int degree : degrees) { + const double delta = degree - 2; + norm += delta * delta; + } + step_ = lambda_ * (upper_bound_ - w) / norm; + } + + void OnNewWMax(CostType one_tree_cost) {} + + private: + int iteration_; + int number_of_iterations_; + CostType upper_bound_; + double lambda_; + double step_; +}; + +// Computes the nearest neighbors of each node for the given cost function. +// The ith element of the returned vector contains the indices of the nearest +// nodes to node i. Note that these indices contain the number_of_neighbors +// nearest neighbors as well as all the nodes for which i is a nearest +// neighbor. +template +std::set> NearestNeighbors(int number_of_nodes, + int number_of_neighbors, + const CostFunction& cost) { + using CostType = decltype(cost(0, 0)); + std::set> nearest; + for (int i = 0; i < number_of_nodes; ++i) { + std::vector> neighbors; + neighbors.reserve(number_of_nodes - 1); + for (int j = 0; j < number_of_nodes; ++j) { + if (i != j) { + neighbors.emplace_back(cost(i, j), j); + } + } + int size = neighbors.size(); + if (number_of_neighbors < size) { + std::nth_element(neighbors.begin(), + neighbors.begin() + number_of_neighbors - 1, + neighbors.end()); + size = number_of_neighbors; + } + for (int j = 0; j < size; ++j) { + nearest.insert({i, neighbors[j].second}); + nearest.insert({neighbors[j].second, i}); + } + } + return nearest; +} + +// Let G be the complete graph on nodes in [0, number_of_nodes - 1]. Adds arcs +// from the minimum spanning tree of G to the arcs set argument. +template +void AddArcsFromMinimumSpanningTree(int number_of_nodes, + const CostFunction& cost, + std::set>* arcs) { + CompleteGraph graph(number_of_nodes); + const std::vector mst = + BuildPrimMinimumSpanningTree(graph, [&cost, &graph](int arc) { + return cost(graph.Tail(arc), graph.Head(arc)); + }); + for (int arc : mst) { + arcs->insert({graph.Tail(arc), graph.Head(arc)}); + arcs->insert({graph.Head(arc), graph.Tail(arc)}); + } +} + +// Returns the index of the node in graph which minimizes cost(node, source) +// with the constraint that accept(node) is true. +template +int GetNodeMinimizingEdgeCostToSource(const GraphType& graph, int source, + const CostFunction& cost, + AcceptFunction accept) { + int best_node = -1; + double best_edge_cost = 0; + for (const auto node : graph.AllNodes()) { + if (accept(node)) { + const double edge_cost = cost(node, source); + if (best_node == -1 || edge_cost < best_edge_cost) { + best_node = node; + best_edge_cost = edge_cost; + } + } + } + return best_node; +} + +// Computes a 1-tree for the given graph, cost function and node weights. +// Returns the degree of each node in the 1-tree and the un-weighed cost of the +// 1-tree. +template +std::vector ComputeOneTree(const GraphType& graph, + const CostFunction& cost, + const std::vector& weights, + const std::vector& sorted_arcs, + CostType* one_tree_cost) { + const auto weighed_cost = [&cost, &weights](int from, int to) { + return cost(from, to) + weights[from] + weights[to]; + }; + // Compute MST on graph. + std::vector mst; + if (!sorted_arcs.empty()) { + mst = BuildKruskalMinimumSpanningTreeFromSortedArcs(graph, + sorted_arcs); + } else { + mst = BuildPrimMinimumSpanningTree( + graph, [&weighed_cost, &graph](int arc) { + return weighed_cost(graph.Tail(arc), graph.Head(arc)); + }); + } + std::vector degrees(graph.num_nodes() + 1, 0); + *one_tree_cost = 0; + for (int arc : mst) { + degrees[graph.Head(arc)]++; + degrees[graph.Tail(arc)]++; + *one_tree_cost += cost(graph.Tail(arc), graph.Head(arc)); + } + // Add 2 cheapest edges from the nodes in the graph to the extra node not in + // the graph. + const int extra_node = graph.num_nodes(); + const auto update_one_tree = [extra_node, one_tree_cost, °rees, + &cost](int node) { + *one_tree_cost += cost(node, extra_node); + degrees.back()++; + degrees[node]++; + }; + const int node = GetNodeMinimizingEdgeCostToSource( + graph, extra_node, weighed_cost, + [extra_node](int n) { return n != extra_node; }); + update_one_tree(node); + update_one_tree(GetNodeMinimizingEdgeCostToSource( + graph, extra_node, weighed_cost, + [extra_node, node](int n) { return n != extra_node && n != node; })); + return degrees; +} + +// Computes the lower bound of a TSP using a given subgradient algorithm. +template +double ComputeOneTreeLowerBoundWithAlgorithm(int number_of_nodes, + int nearest_neighbors, + const CostFunction& cost, + Algorithm* algorithm) { + if (number_of_nodes < 2) return 0; + if (number_of_nodes == 2) return cost(0, 1) + cost(1, 0); + using CostType = decltype(cost(0, 0)); + auto nearest = NearestNeighbors(number_of_nodes - 1, nearest_neighbors, cost); + // Ensure nearest arcs result in a connected graph by adding arcs from the + // minimum spanning tree; this will add arcs which are likely to be "good" + // 1-tree arcs. + AddArcsFromMinimumSpanningTree(number_of_nodes - 1, cost, &nearest); + ListGraph graph(number_of_nodes - 1, nearest.size()); + for (const auto& arc : nearest) { + graph.AddArc(arc.first, arc.second); + } + std::vector weights(number_of_nodes, 0); + std::vector best_weights(number_of_nodes, 0); + double max_w = -std::numeric_limits::infinity(); + double w = 0; + // Iteratively compute lower bound using a partial graph. + while (algorithm->Next()) { + CostType one_tree_cost = 0; + const std::vector degrees = + ComputeOneTree(graph, cost, weights, {}, &one_tree_cost); + algorithm->OnOneTree(one_tree_cost, w, degrees); + w = one_tree_cost; + for (int j = 0; j < number_of_nodes; ++j) { + w += weights[j] * (degrees[j] - 2); + } + if (w > max_w) { + max_w = w; + best_weights = weights; + algorithm->OnNewWMax(one_tree_cost); + } + const double step = algorithm->GetStep(); + for (int j = 0; j < number_of_nodes; ++j) { + weights[j] += step * (degrees[j] - 2); + } + } + // Compute lower bound using the complete graph on the best weights. This is + // necessary as the MSTs computed on nearest neighbors is not guaranteed to + // lead to a lower bound. + CompleteGraph complete_graph(number_of_nodes - 1); + CostType one_tree_cost = 0; + // TODO(user): We are not caching here since this would take O(n^2) memory; + // however the Kruskal algorithm will expand all arcs also consuming O(n^2) + // memory; investigate alternatives to expanding all arcs (Prim's algorithm). + const std::vector degrees = + ComputeOneTree(complete_graph, cost, best_weights, {}, &one_tree_cost); + w = one_tree_cost; + for (int j = 0; j < number_of_nodes; ++j) { + w += best_weights[j] * (degrees[j] - 2); + } + return w; +} + +// Parameters to configure the computation of the TSP lower bound. +struct TravelingSalesmanLowerBoundParameters { + enum Algorithm { + VolgenantJonker, + HeldWolfeCrowder, + }; + // Subgradient algorithm to use to compute the TSP lower bound. + Algorithm algorithm = VolgenantJonker; + // Number of iterations to use in the Volgenant-Jonker algorithm. Overrides + // automatic iteration computation if positive. + int volgenant_jonker_iterations = 0; + // Number of nearest neighbors to consider in the miminum spanning trees. + int nearest_neighbors = 40; +}; + +// Computes the lower bound of a TSP using given parameters. +template +double ComputeOneTreeLowerBoundWithParameters( + int number_of_nodes, const CostFunction& cost, + const TravelingSalesmanLowerBoundParameters& parameters) { + using CostType = decltype(cost(0, 0)); + switch (parameters.algorithm) { + case TravelingSalesmanLowerBoundParameters::VolgenantJonker: { + VolgenantJonkerEvaluator algorithm( + number_of_nodes, parameters.volgenant_jonker_iterations); + return ComputeOneTreeLowerBoundWithAlgorithm( + number_of_nodes, parameters.nearest_neighbors, cost, &algorithm); + break; + } + case TravelingSalesmanLowerBoundParameters::HeldWolfeCrowder: { + HeldWolfeCrowderEvaluator algorithm( + number_of_nodes, cost); + return ComputeOneTreeLowerBoundWithAlgorithm( + number_of_nodes, parameters.nearest_neighbors, cost, &algorithm); + } + default: + LOG(ERROR) << "Unsupported algorithm: " << parameters.algorithm; + return 0; + } +} + +// Computes the lower bound of a TSP using default parameters (Volgenant-Jonker +// algorithm, 200 iterations and 40 nearest neighbors) which have turned out to +// give good results on the TSPLIB. +template +double ComputeOneTreeLowerBound(int number_of_nodes, const CostFunction& cost) { + TravelingSalesmanLowerBoundParameters parameters; + return ComputeOneTreeLowerBoundWithParameters(number_of_nodes, cost, + parameters); +} + +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_ONE_TREE_LOWER_BOUND_H_ diff --git a/thirdparty/linux/include/ortools/graph/shortestpaths.h b/thirdparty/linux/include/ortools/graph/shortestpaths.h new file mode 100644 index 0000000..66a65d6 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/shortestpaths.h @@ -0,0 +1,70 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// This file contains various shortest paths utilities. +// +// Keywords: directed graph, cheapest path, shortest path, Dijkstra, spp. + +#ifndef OR_TOOLS_GRAPH_SHORTESTPATHS_H_ +#define OR_TOOLS_GRAPH_SHORTESTPATHS_H_ + +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/macros.h" + +namespace operations_research { + +// Dijsktra Shortest path with callback based description of the +// graph. The callback returns the distance between two nodes, a +// distance of 'disconnected_distance' indicates no arcs between these +// two nodes. Ownership of the callback is taken by the function that +// will delete it in the end. This function returns true if +// 'start_node' and 'end_node' are connected, false otherwise. +bool DijkstraShortestPath(int node_count, int start_node, int end_node, + std::function graph, + int64 disconnected_distance, std::vector* nodes); + +// Bellman-Ford Shortest path with callback-based description of the +// graph. The callback returns the distance between two nodes, a +// distance of 'disconnected_distance' indicates no arcs between these +// two nodes. Ownership of the callback is taken by the function that +// will delete it in the end. This function returns true if +// 'start_node' and 'end_node' are connected, false otherwise. If +// true, it will fill the 'nodes' vector with the sequence of nodes on +// the shortest path between 'start_node' and 'end_node'. +bool BellmanFordShortestPath(int node_count, int start_node, int end_node, + std::function graph, + int64 disconnected_distance, + std::vector* nodes); + +// A* Shortest path with function based description of the +// graph. The graph function returns the distance between two nodes, a +// distance of 'disconnected_distance' indicates no arcs between these +// two nodes. Additionally, the heuristic callback returns a +// an approximate distance between the node and the target, which guides +// the search. If the heuristic is admissible (ie. never overestimates cost), +// the A* algorithm returns an optimal solution. +// This function returns true if 'start_node' and 'end_node' are +// connected, false otherwise. +bool AStarShortestPath(int node_count, int start_node, int end_node, + std::function graph, + std::function heuristic, + int64 disconnected_distance, std::vector* nodes); + +} // namespace operations_research +#endif // OR_TOOLS_GRAPH_SHORTESTPATHS_H_ diff --git a/thirdparty/linux/include/ortools/graph/util.h b/thirdparty/linux/include/ortools/graph/util.h new file mode 100644 index 0000000..c305034 --- /dev/null +++ b/thirdparty/linux/include/ortools/graph/util.h @@ -0,0 +1,305 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// A collections of utilities for the Graph classes in ./graph.h. + +#ifndef OR_TOOLS_GRAPH_UTIL_H_ +#define OR_TOOLS_GRAPH_UTIL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ortools/base/map_util.h" +#include "ortools/base/hash.h" +#include "ortools/graph/graph.h" + +namespace operations_research { + +// Diagnoses whether a graph is symmetric. A graph is symmetric iff +// for all (a, b), the number of arcs a->b is equal to the number of arcs b->a. +// Works in O(graph size). +template +bool GraphIsSymmetric(const Graph& graph); + +// Returns a fresh copy of a given graph. +template +std::unique_ptr CopyGraph(const Graph& graph); + +// Creates a remapped copy of graph "graph", where node i becomes node +// new_node_index[i]. +// "new_node_index" must be a valid permutation of [0..num_nodes-1] or the +// behavior is undefined (it may die). +// Note that you can call IsValidPermutation() to check it yourself. +template +std::unique_ptr RemapGraph(const Graph& graph, + const std::vector& new_node_index); + +// Gets the induced subgraph of "graph" restricted to the nodes in "nodes": +// the resulting graph will have exactly nodes.size() nodes, and its +// node #0 will be the former graph's node #nodes[0], etc. +// See https://en.wikipedia.org/wiki/Induced_subgraph . +// The "nodes" must be a valid subset (no repetitions) of +// [0..graph.num_nodes()-1], or the behavior is undefined (it may die). +// Note that you can call IsSubsetOf0N() to check it yourself. +// +// Current complexity: O(num old nodes + num new arcs). It could easily +// be done in O(num new nodes + num new arcs) but with a higher constant. +template +std::unique_ptr GetSubgraphOfNodes(const Graph& graph, + const std::vector& nodes); + +// Returns true iff the given vector is a subset of [0..n-1], i.e. +// all elements i are such that 0 <= i < n and no two elements are equal. +// "n" must be >= 0 or the result is undefined. +bool IsSubsetOf0N(const std::vector& v, int n); + +// Returns true iff the given vector is a permutation of [0..size()-1]. +inline bool IsValidPermutation(const std::vector& v) { + return IsSubsetOf0N(v, v.size()); +} + +// Returns a copy of "graph", without self-arcs and duplicate arcs. +template +std::unique_ptr RemoveSelfArcsAndDuplicateArcs(const Graph& graph); + +// Given an arc path, changes it to a sub-path with the same source and +// destination but without any cycle. Nothing happen if the path was already +// without cycle. +// +// The graph class should support Tail(arc) and Head(arc). They should both +// return an integer representing the corresponding tail/head of the passed arc. +// +// TODO(user): In some cases, there is more than one possible solution. We could +// take some arc costs and return the cheapest path instead. Or return the +// shortest path in term of number of arcs. +template +void RemoveCyclesFromPath(const Graph& graph, std::vector* arc_path); + +// Returns true iff the given path contains a cycle. +template +bool PathHasCycle(const Graph& graph, const std::vector& arc_path); + +// Returns a vector representing a mapping from arcs to arcs such that each arc +// is mapped to another arc with its (tail, head) flipped, if such an arc +// exists (otherwise it is mapped to -1). +// If the graph is symmetric, the returned mapping is bijective and reflexive, +// i.e. out[out[arc]] = arc for all "arc", where "out" is the returned vector. +// If "die_if_not_symmetric" is true, this function CHECKs() that the graph +// is symmetric. +// +// Self-arcs are always mapped to themselves. +// +// Note that since graphs may have multi-arcs, the mapping isn't necessarily +// unique, hence the function name. +template +std::vector ComputeOnePossibleReverseArcMapping(const Graph& graph, + bool die_if_not_symmetric); + +// Implementations of the templated methods. + +template +bool GraphIsSymmetric(const Graph& graph) { + typedef typename Graph::NodeIndex NodeIndex; + typedef typename Graph::ArcIndex ArcIndex; + // Create a reverse copy of the graph. + StaticGraph reverse_graph(graph.num_nodes(), + graph.num_arcs()); + for (const NodeIndex node : graph.AllNodes()) { + for (const ArcIndex arc : graph.OutgoingArcs(node)) { + reverse_graph.AddArc(graph.Head(arc), node); + } + } + reverse_graph.Build(); + // Compare the graph to its reverse, one adjacency list at a time. + std::vector count(graph.num_nodes(), 0); + for (const NodeIndex node : graph.AllNodes()) { + for (const ArcIndex arc : graph.OutgoingArcs(node)) { + ++count[graph.Head(arc)]; + } + for (const ArcIndex arc : reverse_graph.OutgoingArcs(node)) { + if (--count[reverse_graph.Head(arc)] < 0) return false; + } + for (const ArcIndex arc : graph.OutgoingArcs(node)) { + if (count[graph.Head(arc)] != 0) return false; + } + } + return true; +} + +template +std::unique_ptr CopyGraph(const Graph& graph) { + std::unique_ptr new_graph( + new Graph(graph.num_nodes(), graph.num_arcs())); + for (const auto node : graph.AllNodes()) { + for (const auto arc : graph.OutgoingArcs(node)) { + new_graph->AddArc(node, graph.Head(arc)); + } + } + new_graph->Build(); + return new_graph; +} + +template +std::unique_ptr RemapGraph(const Graph& old_graph, + const std::vector& new_node_index) { + DCHECK(IsValidPermutation(new_node_index)) << "Invalid permutation"; + const int num_nodes = old_graph.num_nodes(); + CHECK_EQ(new_node_index.size(), num_nodes); + std::unique_ptr new_graph(new Graph(num_nodes, old_graph.num_arcs())); + typedef typename Graph::NodeIndex NodeIndex; + typedef typename Graph::ArcIndex ArcIndex; + for (const NodeIndex node : old_graph.AllNodes()) { + for (const ArcIndex arc : old_graph.OutgoingArcs(node)) { + new_graph->AddArc(new_node_index[node], + new_node_index[old_graph.Head(arc)]); + } + } + new_graph->Build(); + return new_graph; +} + +template +std::unique_ptr GetSubgraphOfNodes(const Graph& old_graph, + const std::vector& nodes) { + typedef typename Graph::NodeIndex NodeIndex; + typedef typename Graph::ArcIndex ArcIndex; + DCHECK(IsSubsetOf0N(nodes, old_graph.num_nodes())) << "Invalid subset"; + std::vector new_node_index(old_graph.num_nodes(), -1); + for (NodeIndex new_index = 0; new_index < nodes.size(); ++new_index) { + new_node_index[nodes[new_index]] = new_index; + } + // Do a first pass to count the arcs, so that we don't allocate more memory + // than needed. + ArcIndex num_arcs = 0; + for (const NodeIndex node : nodes) { + for (const ArcIndex arc : old_graph.OutgoingArcs(node)) { + if (new_node_index[old_graph.Head(arc)] != -1) ++num_arcs; + } + } + // A second pass where we actually copy the subgraph. + // NOTE(user): there might seem to be a bit of duplication with RemapGraph(), + // but there is a key difference: the loop below only iterates on "nodes", + // which could be much smaller than all the graph's nodes. + std::unique_ptr new_graph(new Graph(nodes.size(), num_arcs)); + for (NodeIndex new_tail = 0; new_tail < nodes.size(); ++new_tail) { + const NodeIndex old_tail = nodes[new_tail]; + for (const ArcIndex arc : old_graph.OutgoingArcs(old_tail)) { + const NodeIndex new_head = new_node_index[old_graph.Head(arc)]; + if (new_head != -1) new_graph->AddArc(new_tail, new_head); + } + } + new_graph->Build(); + return new_graph; +} + +template +std::unique_ptr RemoveSelfArcsAndDuplicateArcs(const Graph& graph) { + std::unique_ptr g(new Graph(graph.num_nodes(), graph.num_arcs())); + typedef typename Graph::ArcIndex ArcIndex; + typedef typename Graph::NodeIndex NodeIndex; + std::unordered_set> arcs; + for (const NodeIndex tail : graph.AllNodes()) { + for (const ArcIndex arc : graph.OutgoingArcs(tail)) { + const NodeIndex head = graph.Head(arc); + if (head != tail && arcs.insert({tail, head}).second) { + g->AddArc(tail, head); + } + } + } + g->Build(); + return g; +} + +template +void RemoveCyclesFromPath(const Graph& graph, std::vector* arc_path) { + if (arc_path->empty()) return; + + // This maps each node to the latest arc in the given path that leaves it. + std::map last_arc_leaving_node; + for (const int arc : *arc_path) last_arc_leaving_node[graph.Tail(arc)] = arc; + + // Special case for the destination. + // Note that this requires that -1 is not a valid arc of Graph. + last_arc_leaving_node[graph.Head(arc_path->back())] = -1; + + // Reconstruct the path by starting at the source and then following the + // "next" arcs. We override the given arc_path at the same time. + int node = graph.Tail(arc_path->front()); + int new_size = 0; + while (new_size < arc_path->size()) { // To prevent cycle on bad input. + const int arc = FindOrDie(last_arc_leaving_node, node); + if (arc == -1) break; + (*arc_path)[new_size++] = arc; + node = graph.Head(arc); + } + arc_path->resize(new_size); +} + +template +bool PathHasCycle(const Graph& graph, const std::vector& arc_path) { + if (arc_path.empty()) return false; + std::set seen; + seen.insert(graph.Tail(arc_path.front())); + for (const int arc : arc_path) { + if (!InsertIfNotPresent(&seen, graph.Head(arc))) return true; + } + return false; +} + +template +std::vector ComputeOnePossibleReverseArcMapping(const Graph& graph, + bool die_if_not_symmetric) { + std::vector reverse_arc(graph.num_arcs(), -1); + std::unordered_multimap, /*arc index*/ int> + arc_map; + for (int arc = 0; arc < graph.num_arcs(); ++arc) { + const int tail = graph.Tail(arc); + const int head = graph.Head(arc); + if (tail == head) { + // Special case: directly map any self-arc to itself. + reverse_arc[arc] = arc; + continue; + } + // Lookup for the reverse arc of the current one... + auto it = arc_map.find({head, tail}); + if (it != arc_map.end()) { + // Found a reverse arc! Store the mapping and remove the + // reverse arc from the map. + reverse_arc[arc] = it->second; + reverse_arc[it->second] = arc; + arc_map.erase(it); + } else { + // Reverse arc not in the map. Add the current arc to the map. + arc_map.insert({{tail, head}, arc}); + } + } + // Algorithm check, for debugging. + DCHECK_EQ(std::count(reverse_arc.begin(), reverse_arc.end(), -1), + arc_map.size()); + if (die_if_not_symmetric) { + CHECK_EQ(arc_map.size(), 0) + << "The graph is not symmetric: " << arc_map.size() << " of " + << graph.num_arcs() << " arcs did not have a reverse."; + } + return reverse_arc; +} + +} // namespace operations_research + +#endif // OR_TOOLS_GRAPH_UTIL_H_ diff --git a/thirdparty/linux/include/ortools/linear_solver/glop_utils.h b/thirdparty/linux/include/ortools/linear_solver/glop_utils.h new file mode 100644 index 0000000..aae257f --- /dev/null +++ b/thirdparty/linux/include/ortools/linear_solver/glop_utils.h @@ -0,0 +1,32 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_LINEAR_SOLVER_GLOP_UTILS_H_ +#define OR_TOOLS_LINEAR_SOLVER_GLOP_UTILS_H_ + +#include "ortools/linear_solver/linear_solver.h" +#include "ortools/lp_data/lp_types.h" + +namespace operations_research { + +MPSolver::ResultStatus GlopToMPSolverResultStatus(glop::ProblemStatus s); + +MPSolver::BasisStatus GlopToMPSolverVariableStatus(glop::VariableStatus s); +glop::VariableStatus MPSolverToGlopVariableStatus(MPSolver::BasisStatus s); + +MPSolver::BasisStatus GlopToMPSolverConstraintStatus(glop::ConstraintStatus s); +glop::ConstraintStatus MPSolverToGlopConstraintStatus(MPSolver::BasisStatus s); + +} // namespace operations_research + +#endif // OR_TOOLS_LINEAR_SOLVER_GLOP_UTILS_H_ diff --git a/thirdparty/linux/include/ortools/linear_solver/linear_expr.h b/thirdparty/linux/include/ortools/linear_solver/linear_expr.h new file mode 100644 index 0000000..610296a --- /dev/null +++ b/thirdparty/linux/include/ortools/linear_solver/linear_expr.h @@ -0,0 +1,178 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_LINEAR_SOLVER_LINEAR_EXPR_H_ +#define OR_TOOLS_LINEAR_SOLVER_LINEAR_EXPR_H_ + +// This file allows you to write natural code (like a mathematical equation) to +// model optimization problems with MPSolver. It is syntatic sugar on top of +// the MPSolver API, it provides no additional functionality. Use of these APIs +// makes it much easier to write code that is both simple and big-O optimal for +// creating your model, at the cost of some additional constant factor +// overhead. If model creation is a bottleneck in your problem, consider using +// the MPSolver API directly instead. +// +// This file contains two classes: +// 1. LinearExpr: models offset + sum_{i in S} a_i*x_i for decision var x_i, +// 2. LinearRange: models lb <= sum_{i in S} a_i*x_i <= ub, +// and it provides various operator overloads to build up "LinearExpr"s and +// then convert them to "LinearRange"s. +// +// Recommended use (avoids dangerous code): +// +// MPSolver solver = ...; +// const LinearExpr x = solver.MakeVar(...); // Note: implicit conversion +// const LinearExpr y = solver.MakeVar(...); +// const LinearExpr z = solver.MakeVar(...); +// const LinearExpr e1 = x + y; +// const LinearExpr e2 = (e1 + 7.0 + z)/3.0; +// const LinearRange r = e1 <= e2; +// solver.AddRowConstraint(r); +// +// WARNING, AVOID THIS TRAP: +// +// MPSolver solver = ...; +// MPVariable* x = solver.MakeVar(...); +// LinearExpr y = x + 5; +// +// In evaluating "x+5" above, x is NOT converted to a LinearExpr before the +// addition, but rather is treated as a pointer, so x+5 gives a new pointer to +// garbage memory. +// +// For this reason, when using LinearExpr, it is best practice to: +// 1. use double literals instead of ints (e.g. "x + 5.0", not "x + 5"), +// 2. Immediately convert all MPVariable* to LinearExpr on creation, and only +// hold references to the "LinearExpr"s. +// +// Likewise, the following code is NOT recommended: +// MPSolver solver = ...; +// MPVariable* x = solver.MakeVar(...); +// MPVariable* y = solver.MakeVar(...); +// LinearExpr e1 = LinearExpr(x) + y + 5; +// +// While it is correct, it violates the natural assumption that the + operator +// is associative. Thus you are setting a trap for future modifications of the +// code, as any of the following changes would lead to the above failure mode: +// * LinearExpr e1 = LinearExpr(x) + (y + 5); +// * LinearExpr e1 = y + 5 + LinearExpr(x); + +#include + +namespace operations_research { + +// NOTE(user): forward declaration is necessary due to cyclic dependencies, +// MPVariable is defined in linear_solver.h, which depends on LinearExpr. +class MPVariable; + +// LinearExpr models a quantity that is linear in the decision variables +// (MPVariable) of an optimization problem, i.e. +// +// offset + sum_{i in S} a_i*x_i, +// +// where the a_i and offset are constants and the x_i are MPVariables. You can +// use a LinearExpr "linear_expr" with an MPSolver "solver" to: +// * Set as the objective of your optimization problem, e.g. +// +// solver.MutableObjective()->MaximizeLinearExpr(linear_expr); +// +// * Create a constraint in your optimization, e.g. +// +// solver.AddRowConstraint(linear_expr1 <= linear_expr2); +// +// * Get the value of the quantity after solving, e.g. +// +// solver.Solve(); +// solver.SolutionValue(linear_expr); +// +// LinearExpr is allowed to delete variables with coefficient zero from the map, +// but is not obligated to do so. +class LinearExpr { + public: + LinearExpr(); + // Possible implicit conversions are intentional. + LinearExpr(double constant); // NOLINT + // Possible implicit conversions are intentional. + // Warning: var is not owned. + LinearExpr(const MPVariable* var); // NOLINT + + // Returns 1-var. + // NOTE(user): if var is binary variable, this corresponds to the logical + // negation of var. + // Passing by value is intentional, see the discussion on binary ops. + static LinearExpr NotVar(LinearExpr var); + + LinearExpr& operator+=(const LinearExpr& rhs); + LinearExpr& operator-=(const LinearExpr& rhs); + LinearExpr& operator*=(double rhs); + LinearExpr& operator/=(double rhs); + LinearExpr operator-() const; + + double offset() const { return offset_; } + const std::unordered_map& terms() const { + return terms_; + } + + private: + double offset_; + std::unordered_map terms_; +}; + +// NOTE(user): in the ops below, the non-"const LinearExpr&" are intentional. +// We need to create a new LinearExpr for the result, so we lose nothing by +// passing one argument by value, mutating it, and then returning it. In +// particular, this allows (with move semantics and RVO) an optimized +// evaluation of expressions such as +// a + b + c + d +// (see http://en.cppreference.com/w/cpp/language/operators). +LinearExpr operator+(LinearExpr lhs, const LinearExpr& rhs); +LinearExpr operator-(LinearExpr lhs, const LinearExpr& rhs); +LinearExpr operator*(LinearExpr lhs, double rhs); +LinearExpr operator/(LinearExpr lhs, double rhs); +LinearExpr operator*(double lhs, LinearExpr rhs); + +// An expression of the form: +// lower_bound <= sum_{i in S} a_i*x_i <= upper_bound. +// The sum is represented as a LinearExpr with offset 0. +// +// Must be added to model with +// MPSolver::AddRowConstraint(const LinearRange& range[, const std::string& name]); +class LinearRange { + public: + LinearRange(); + // The bounds of the linear range are updated so that they include the offset + // from "linear_expr", i.e., we form the range: + // lower_bound - offset <= linear_expr - offset <= upper_bound - offset. + LinearRange(double lower_bound, const LinearExpr& linear_expr, + double upper_bound); + + double lower_bound() const { return lower_bound_; } + const LinearExpr& linear_expr() const { return linear_expr_; } + double upper_bound() const { return upper_bound_; } + + private: + double lower_bound_; + // invariant: linear_expr_.offset() == 0. + LinearExpr linear_expr_; + double upper_bound_; +}; + +LinearRange operator<=(const LinearExpr& lhs, const LinearExpr& rhs); +LinearRange operator==(const LinearExpr& lhs, const LinearExpr& rhs); +LinearRange operator>=(const LinearExpr& lhs, const LinearExpr& rhs); + +// TODO(user, ondrasej): explore defining more overloads to support: +// solver.AddRowConstraint(0.0 <= x + y + z <= 1.0); + +} // namespace operations_research + +#endif // OR_TOOLS_LINEAR_SOLVER_LINEAR_EXPR_H_ diff --git a/thirdparty/linux/include/ortools/linear_solver/linear_solver.h b/thirdparty/linux/include/ortools/linear_solver/linear_solver.h new file mode 100644 index 0000000..fb5dc7e --- /dev/null +++ b/thirdparty/linux/include/ortools/linear_solver/linear_solver.h @@ -0,0 +1,1375 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// +// A C++ wrapper that provides a simple and unified interface to +// several linear programming and mixed integer programming solvers: +// GLOP, GLPK, CLP, CBC, and SCIP. The wrapper can also be used in Java, C#, +// and Python via SWIG. +// +// +// ----------------------------------- +// +// What is Linear Programming? +// +// In mathematics, linear programming (LP) is a technique for optimization of +// a linear objective function, subject to linear equality and linear +// inequality constraints. Informally, linear programming determines the way +// to achieve the best outcome (such as maximum profit or lowest cost) in a +// given mathematical model and given some list of requirements represented +// as linear equations. +// +// The most widely used technique for solving a linear program is the Simplex +// algorithm, devised by George Dantzig in 1947. It performs very well on +// most instances, for which its running time is polynomial. A lot of effort +// has been put into improving the algorithm and its implementation. As a +// byproduct, it has however been shown that one can always construct +// problems that take exponential time for the Simplex algorithm to solve. +// Research has thus focused on trying to find a polynomial algorithm for +// linear programming, or to prove that linear programming is indeed +// polynomial. +// +// Leonid Khachiyan first exhibited in 1979 a weakly polynomial algorithm for +// linear programming. "Weakly polynomial" means that the running time of the +// algorithm is in O(P(n) * 2^p) where P(n) is a polynomial of the size of the +// problem, and p is the precision of computations expressed in number of +// bits. With a fixed-precision, floating-point-based implementation, a weakly +// polynomial algorithm will thus run in polynomial time. No implementation +// of Khachiyan's algorithm has proved efficient, but a larger breakthrough in +// the field came in 1984 when Narendra Karmarkar introduced a new interior +// point method for solving linear programming problems. Interior point +// algorithms have proved efficient on very large linear programs. +// +// Check Wikipedia for more detail: +// http://en.wikipedia.org/wiki/Linear_programming +// +// ----------------------------------- +// +// Example of a Linear Program +// +// maximize: +// 3x + y +// subject to: +// 1.5 x + 2 y <= 12 +// 0 <= x <= 3 +// 0 <= y <= 5 +// +// A linear program has: +// 1) a linear objective function +// 2) linear constraints that can be equalities or inequalities +// 3) bounds on variables that can be positive, negative, finite or +// infinite. +// +// ----------------------------------- +// +// What is Mixed Integer Programming? +// +// Here, the constraints and the objective are still linear but +// there are additional integrality requirements for variables. If +// all variables are required to take integer values, then the +// problem is called an integer program (IP). In most cases, only +// some variables are required to be integer and the rest of the +// variables are continuous: this is called a mixed integer program +// (MIP). IPs and MIPs are generally NP-hard. +// +// Integer variables can be used to model discrete decisions (build a +// datacenter in city A or city B), logical relationships (only +// place machines in datacenter A if we have decided to build +// datacenter A) and approximate non-linear functions with piecewise +// linear functions (for example, the cost of machines as a function +// of how many machines are bought, or the latency of a server as a +// function of its load). +// +// ----------------------------------- +// +// How to use the wrapper +// +// The user builds the model and solves it through the MPSolver class, +// then queries the solution through the MPSolver, MPVariable and +// MPConstraint classes. To be able to query a solution, you need the +// following: +// - A solution exists: MPSolver::Solve has been called and a solution +// has been found. +// - The model has not been modified since the last time +// MPSolver::Solve was called. Otherwise, the solution obtained +// before the model modification may not longer be feasible or +// optimal. +// +// @see ../examples/linear_programming.cc for a simple LP example. +// +// @see ../examples/integer_programming.cc for a simple MIP example. +// +// All methods cannot be called successfully in all cases. For +// example: you cannot query a solution when no solution exists, you +// cannot query a reduced cost value (which makes sense only on +// continuous problems) on a discrete problem. When a method is +// called in an unsuitable context, it aborts with a +// LOG(FATAL). +// TODO(user): handle failures gracefully. +// +// ----------------------------------- +// +// For developers: How the wrapper works +// +// MPSolver stores a representation of the model (variables, +// constraints and objective) in its own data structures and a +// pointer to a MPSolverInterface that wraps the underlying solver +// (GLOP, CBC, CLP, GLPK, or SCIP) that does the actual work. The +// underlying solver also keeps a representation of the model in its +// own data structures. The model representations in MPSolver and in +// the underlying solver are kept in sync by the 'extraction' +// mechanism: synchronously for some changes and asynchronously +// (when MPSolver::Solve is called) for others. Synchronicity +// depends on the modification applied and on the underlying solver. + +#ifndef OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_ +#define OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/timer.h" +#include "ortools/glop/parameters.pb.h" +#include "ortools/linear_solver/linear_expr.h" +#include "ortools/linear_solver/linear_solver.pb.h" + + +namespace operations_research { + +class MPConstraint; +class MPObjective; +class MPSolverInterface; +class MPSolverParameters; +class MPVariable; + +// This mathematical programming (MP) solver class is the main class +// though which users build and solve problems. +class MPSolver { + public: + // The type of problems (LP or MIP) that will be solved and the + // underlying solver (GLOP, GLPK, CLP, CBC or SCIP) that will solve them. + // This must remain consistent with MPModelRequest::OptimizationProblemType + // (take particular care of the open-source version). + enum OptimizationProblemType { + // Linear programming problems. + #ifdef USE_CLP + CLP_LINEAR_PROGRAMMING = 0, // Recommended default value. + #endif + #ifdef USE_GLPK + GLPK_LINEAR_PROGRAMMING = 1, + #endif + #ifdef USE_GLOP + GLOP_LINEAR_PROGRAMMING = 2, + #endif + #ifdef USE_GUROBI + GUROBI_LINEAR_PROGRAMMING = 6, + #endif + #ifdef USE_CPLEX + CPLEX_LINEAR_PROGRAMMING = 10, + #endif + + // Integer programming problems. + #ifdef USE_SCIP + SCIP_MIXED_INTEGER_PROGRAMMING = 3, // Recommended default value. + #endif + #ifdef USE_GLPK + GLPK_MIXED_INTEGER_PROGRAMMING = 4, + #endif + #ifdef USE_CBC + CBC_MIXED_INTEGER_PROGRAMMING = 5, + #endif + #if defined(USE_GUROBI) + GUROBI_MIXED_INTEGER_PROGRAMMING = 7, + #endif + #if defined(USE_CPLEX) + CPLEX_MIXED_INTEGER_PROGRAMMING = 11, + #endif + #if defined(USE_BOP) + BOP_INTEGER_PROGRAMMING = 12, + #endif + }; + + MPSolver(const std::string& name, OptimizationProblemType problem_type); + virtual ~MPSolver(); + + // Whether the given problem type is supported (this will depend on the + // targets that you linked). + static bool SupportsProblemType(OptimizationProblemType problem_type); + + bool IsMIP() const; + + std::string Name() const { + return name_; // Set at construction. + } + + virtual OptimizationProblemType ProblemType() const { + return problem_type_; // Set at construction. + } + + // Clears the objective (including the optimization direction), all + // variables and constraints. All the other properties of the MPSolver + // (like the time limit) are kept untouched. + void Clear(); + + // ----- Variables ------ + // Returns the number of variables. + int NumVariables() const { return variables_.size(); } + // Returns the array of variables handled by the MPSolver. + // (They are listed in the order in which they were created.) + const std::vector& variables() const { return variables_; } + // Look up a variable by name, and return NULL if it does not exist. + MPVariable* LookupVariableOrNull(const std::string& var_name) const; + + // Creates a variable with the given bounds, integrality requirement + // and name. Bounds can be finite or +/- MPSolver::infinity(). + // The MPSolver owns the variable (i.e. the returned pointer is borrowed). + // Variable names must be unique (it may crash otherwise). Empty variable + // names are allowed, an automated variable name will then be assigned. + MPVariable* MakeVar(double lb, double ub, bool integer, const std::string& name); + // Creates a continuous variable. + MPVariable* MakeNumVar(double lb, double ub, const std::string& name); + // Creates an integer variable. + MPVariable* MakeIntVar(double lb, double ub, const std::string& name); + // Creates a boolean variable. + MPVariable* MakeBoolVar(const std::string& name); + + // Creates an array of variables. All variables created have the + // same bounds and integrality requirement. If nb <= 0, no variables are + // created, the function crashes in non-opt mode. + // @param name the prefix of the variable names. Variables are named + // name0, name1, ... + void MakeVarArray(int nb, double lb, double ub, bool integer, + const std::string& name_prefix, std::vector* vars); + // Creates an array of continuous variables. + void MakeNumVarArray(int nb, double lb, double ub, const std::string& name, + std::vector* vars); + // Creates an array of integer variables. + void MakeIntVarArray(int nb, double lb, double ub, const std::string& name, + std::vector* vars); + // Creates an array of boolean variables. + void MakeBoolVarArray(int nb, const std::string& name, + std::vector* vars); + + // ----- Constraints ----- + // Returns the number of constraints. + int NumConstraints() const { return constraints_.size(); } + // Returns the array of constraints handled by the MPSolver. + // (They are listed in the order in which they were created.) + const std::vector& constraints() const { return constraints_; } + // Look up a constraint by name, and return NULL if it does not exist. + MPConstraint* LookupConstraintOrNull(const std::string& constraint_name) const; + + // Creates a linear constraint with given bounds. Bounds can be + // finite or +/- MPSolver::infinity(). The MPSolver class assumes + // ownership of the constraint. + // @return a pointer to the newly created constraint. + MPConstraint* MakeRowConstraint(double lb, double ub); + // Creates a constraint with -infinity and +infinity bounds. + MPConstraint* MakeRowConstraint(); + // Creates a named constraint with given bounds. + MPConstraint* MakeRowConstraint(double lb, double ub, const std::string& name); + // Creates a named constraint with -infinity and +infinity bounds. + MPConstraint* MakeRowConstraint(const std::string& name); + + // Creates a constraint owned by MPSolver enforcing: + // range.lower_bound() <= range.linear_expr() <= range.upper_bound() + MPConstraint* MakeRowConstraint(const LinearRange& range); + // As above, but also names the constraint. + MPConstraint* MakeRowConstraint(const LinearRange& range, const std::string& name); + + // ----- Objective ----- + // Note that the objective is owned by the solver, and is initialized to + // its default value (see the MPObjective class below) at construction. + const MPObjective& Objective() const { return *objective_; } + MPObjective* MutableObjective() { return objective_.get(); } + + // ----- Solve ----- + + // The status of solving the problem. The straightforward translation to + // homonymous enum values of MPSolutionResponse::Status + // (see ./linear_solver.proto) is guaranteed by ./enum_consistency_test.cc, + // you may rely on it. + // TODO(user): Figure out once and for all what the status of + // underlying solvers exactly mean, especially for feasible and + // infeasible. + enum ResultStatus { + OPTIMAL, // optimal. + FEASIBLE, // feasible, or stopped by limit. + INFEASIBLE, // proven infeasible. + UNBOUNDED, // proven unbounded. + ABNORMAL, // abnormal, i.e., error of some kind. + MODEL_INVALID, // the model is trivially invalid (NaN coefficients, etc). + NOT_SOLVED = 6 // not been solved yet. + }; + + // Solves the problem using default parameter values. + ResultStatus Solve(); + // Solves the problem using the specified parameter values. + ResultStatus Solve(const MPSolverParameters& param); + + // Call only after calling MPSolver::Solve. Evaluates "linear_expr" for the + // variable values at the solution found by solving. + double SolutionValue(const LinearExpr& linear_expr) const; + + // Writes the model using the solver internal write function. Currently only + // available for Gurobi. + void Write(const std::string& file_name); + + // Advanced usage: compute the "activities" of all constraints, which are the + // sums of their linear terms. The activities are returned in the same order + // as constraints(), which is the order in which constraints were added; but + // you can also use MPConstraint::index() to get a constraint's index. + std::vector ComputeConstraintActivities() const; + + // Advanced usage: + // Verifies the *correctness* of the solution: all variables must be within + // their domains, all constraints must be satisfied, and the reported + // objective value must be accurate. + // Usage: + // - This can only be called after Solve() was called. + // - "tolerance" is interpreted as an absolute error threshold. + // - For the objective value only, if the absolute error is too large, + // the tolerance is interpreted as a relative error threshold instead. + // - If "log_errors" is true, every single violation will be logged. + // - If "tolerance" is negative, it will be set to infinity(). + // + // Most users should just set the --verify_solution flag and not bother + // using this method directly. + bool VerifySolution(double tolerance, bool log_errors) const; + + // Advanced usage: resets extracted model to solve from scratch. This won't + // reset the parameters that were set with + // SetSolverSpecificParametersAsString() or set_time_limit() or even clear the + // linear program. It will just make sure that next Solve() will be as if + // everything was reconstructed from scratch. + void Reset(); + + // Interrupts the Solve() execution to terminate processing early if possible. + // If the underlying interface supports interruption; it does that and returns + // true regardless of whether there's an ongoing Solve() or not. The Solve() + // call may still linger for a while depending on the conditions. If + // interruption is not supported; returns false and does nothing. + bool InterruptSolve(); + + // ----- Methods using protocol buffers ----- + + // Loads model from protocol buffer. Returns MPSOLVER_MODEL_IS_VALID if the + // model is valid, and another status otherwise (currently only + // MPSOLVER_MODEL_INVALID and MPSOLVER_INFEASIBLE). If the model isn't + // valid, populate "error_message". + MPSolverResponseStatus LoadModelFromProto(const MPModelProto& input_model, + std::string* error_message); + // The same as above, except that the loading keeps original variable and + // constraint names. Caller should make sure that all variable names and + // constraint names are unique, respectively. + MPSolverResponseStatus LoadModelFromProtoWithUniqueNamesOrDie( + const MPModelProto& input_model, std::string* error_message); + + // Encodes the current solution in a solution response protocol buffer. + + void FillSolutionResponseProto(MPSolutionResponse* response) const; + + // Solves the model encoded by a MPModelRequest protocol buffer and + // fills the solution encoded as a MPSolutionResponse. + // Note(user): This creates a temporary MPSolver and destroys it at the + // end. If you want to keep the MPSolver alive (for debugging, or for + // incremental solving), you should write another version of this function + // that creates the MPSolver object on the heap and returns it. + // + // TODO(user): populate an error message in the response. + static void SolveWithProto(const MPModelRequest& model_request, + MPSolutionResponse* response); + + // Exports model to protocol buffer. + void ExportModelToProto(MPModelProto* output_model) const; + + // Load a solution encoded in a protocol buffer onto this solver for easy + // access via the MPSolver interface. + // + // IMPORTANT: This may only be used in conjunction with ExportModel(), + // following this example: + // MPSolver my_solver; + // ... add variables and constraints ... + // MPModelProto model_proto; + // my_solver.ExportModelToProto(&model_proto); + // MPSolutionResponse solver_response; + // // This can be replaced by a stubby call to the linear solver server. + // MPSolver::SolveWithProto(model_proto, &solver_response); + // if (solver_response.result_status() == MPSolutionResponse::OPTIMAL) { + // CHECK(my_solver.LoadSolutionFromProto(solver_response)); + // ... inspect the solution using the usual API: solution_value(), etc... + // } + // + // This allows users of the pythonic API to conveniently communicate with + // a linear solver stubby server, via the MPSolver object as a proxy. + // See /.linear_solver_server_integration_test.py. + // + // The response must be in OPTIMAL or FEASIBLE status. + // Returns false if a problem arised (typically, if it wasn't used like + // it should be): + // - loading a solution whose variables don't correspond to the solver's + // current variables + // - loading a solution with a status other than OPTIMAL / FEASIBLE. + // Note: the variable and objective values aren't checked. You can use + // VerifySolution() for that. + bool LoadSolutionFromProto(const MPSolutionResponse& response); + + // ----- Export model to files or strings ----- +#ifndef ANDROID_JNI + // Shortcuts to the homonymous MPModelProtoExporter methods, via + // exporting to a MPModelProto with ExportModelToProto() (see above). + bool ExportModelAsLpFormat(bool obfuscated, std::string* model_str); + bool ExportModelAsMpsFormat(bool fixed_format, bool obfuscated, + std::string* model_str); +#endif + // ----- Misc ----- + + // Advanced usage: pass solver specific parameters in text format. The format + // is solver-specific and is the same as the corresponding solver + // configuration file format. Returns true if the operation was successful. + // + // TODO(user): Currently SCIP will always return true even if the format is + // wrong (you can check the log if you suspect an issue there). This seems to + // be a bug in SCIP though. + bool SetSolverSpecificParametersAsString(const std::string& parameters); + std::string GetSolverSpecificParametersAsString() const { + return solver_specific_parameter_string_; + } + + // Advanced usage: possible basis status values for a variable and the + // slack variable of a linear constraint. + enum BasisStatus { + FREE = 0, + AT_LOWER_BOUND, + AT_UPPER_BOUND, + FIXED_VALUE, + BASIC + }; + + // Advanced usage: Incrementality. This function takes a starting basis to be + // used in the next LP Solve() call. The statuses of a current solution can be + // retrieved via the basis_status() function of a MPVariable or a + // MPConstraint. + // + // WARNING: With Glop, you should disable presolve when using this because + // this information will not be modified in sync with the presolve and will + // likely not mean much on the presolved problem. + void SetStartingLpBasis( + const std::vector& variable_statuses, + const std::vector& constraint_statuses); + + // Infinity. You can use -MPSolver::infinity() for negative infinity. + static double infinity() { return std::numeric_limits::infinity(); } + + // Controls (or queries) the amount of output produced by the underlying + // solver. The output can surface to LOGs, or to stdout or stderr, depending + // on the implementation. The amount of output will greatly vary with each + // implementation and each problem. + // + // Output is suppressed by default. + bool OutputIsEnabled() const; + void EnableOutput(); + void SuppressOutput(); + + void set_time_limit(int64 time_limit_milliseconds) { + DCHECK_GE(time_limit_milliseconds, 0); + time_limit_ = time_limit_milliseconds; + } + + // In milliseconds. + int64 time_limit() const { return time_limit_; } + + // In seconds. Note that this returns a double. + double time_limit_in_secs() const { + // static_cast avoids a warning with -Wreal-conversion. This + // helps catching bugs with unwanted conversions from double to ints. + return static_cast(time_limit_) / 1000.0; + } + + // Returns wall_time() in milliseconds since the creation of the solver. + int64 wall_time() const { return timer_.GetInMs(); } + + // Returns the number of simplex iterations. + int64 iterations() const; + + // Returns the number of branch-and-bound nodes. Only available for + // discrete problems. + int64 nodes() const; + + // Returns a std::string describing the underlying solver and its version. + std::string SolverVersion() const; + + // Advanced usage: returns the underlying solver so that the user + // can use solver-specific features or features that are not exposed + // in the simple API of MPSolver. This method is for advanced users, + // use at your own risk! In particular, if you modify the model or + // the solution by accessing the underlying solver directly, then + // the underlying solver will be out of sync with the information + // kept in the wrapper (MPSolver, MPVariable, MPConstraint, + // MPObjective). You need to cast the void* returned back to its + // original type that depends on the interface (CBC: + // OsiClpSolverInterface*, CLP: ClpSimplex*, GLPK: glp_prob*, SCIP: + // SCIP*). + void* underlying_solver(); + + // Advanced usage: computes the exact condition number of the + // current scaled basis: L1norm(B) * L1norm(inverse(B)), where B is + // the scaled basis. + // This method requires that a basis exists: it should be called + // after Solve. It is only available for continuous problems. It is + // implemented for GLPK but not CLP because CLP does not provide the + // API for doing it. + // The condition number measures how well the constraint matrix is + // conditioned and can be used to predict whether numerical issues + // will arise during the solve: the model is declared infeasible + // whereas it is feasible (or vice-versa), the solution obtained is + // not optimal or violates some constraints, the resolution is slow + // because of repeated singularities. + // The rule of thumb to interpret the condition number kappa is: + // o kappa <= 1e7: virtually no chance of numerical issues + // o 1e7 < kappa <= 1e10: small chance of numerical issues + // o 1e10 < kappa <= 1e13: medium chance of numerical issues + // o kappa > 1e13: high chance of numerical issues + // The computation of the condition number depends on the quality of + // the LU decomposition, so it is not very accurate when the matrix + // is ill conditioned. + double ComputeExactConditionNumber() const; + + friend class GLPKInterface; + friend class CLPInterface; + friend class CBCInterface; + friend class SCIPInterface; + friend class GurobiInterface; + friend class CplexInterface; + friend class SLMInterface; + friend class MPSolverInterface; + friend class GLOPInterface; + friend class BopInterface; + friend class KnapsackInterface; + + // Debugging: verify that the given MPVariable* belongs to this solver. + bool OwnsVariable(const MPVariable* var) const; + + private: + // Computes the size of the constraint with the largest number of + // coefficients with index in [min_constraint_index, + // max_constraint_index) + int ComputeMaxConstraintSize(int min_constraint_index, + int max_constraint_index) const; + + // Returns true if the model has constraints with lower bound > upper bound. + bool HasInfeasibleConstraints() const; + + // The name of the linear programming problem. + const std::string name_; + + // The type of the linear programming problem. + const OptimizationProblemType problem_type_; + + // The solver interface. + std::unique_ptr interface_; + + // The vector of variables in the problem. + std::vector variables_; + // A map from a variable's name to its index in variables_. + std::unordered_map variable_name_to_index_; + // Whether constraints have been extracted to the underlying interface. + std::vector variable_is_extracted_; + + // The vector of constraints in the problem. + std::vector constraints_; + // A map from a constraint's name to its index in constraints_. + std::unordered_map constraint_name_to_index_; + // Whether constraints have been extracted to the underlying interface. + std::vector constraint_is_extracted_; + + // The linear objective function. + std::unique_ptr objective_; + + // Initial values for all or some of the problem variables that can be + // exploited as a starting hint by a solver. + // + // Note(user): as of 05/05/2015, we can't use >> because of some SWIG errors. + std::vector > solution_hint_; + + // Time limit in milliseconds (0 = no limit). + int64 time_limit_; + + WallTimer timer_; + + // Permanent storage for SetSolverSpecificParametersAsString(). + std::string solver_specific_parameter_string_; + + + MPSolverResponseStatus LoadModelFromProtoInternal( + const MPModelProto& input_model, bool clear_names, std::string* error_message); + + DISALLOW_COPY_AND_ASSIGN(MPSolver); +}; + +#ifndef ANDROID_JNI +inline std::ostream& operator<<(std::ostream& os, + MPSolver::ResultStatus status) { + return os << MPSolverResponseStatus_Name( + static_cast(status)); +} +#endif + +// The data structure used to store the coefficients of the contraints and of +// the objective. Also define a type to facilitate iteration over them with: +// for (CoeffEntry entry : coefficients_) { ... } +class CoeffMap : public std::unordered_map { + public: + explicit CoeffMap(int num_buckets) +#if !defined(_MSC_VER) // Visual C++ doesn't support this constructor + : std::unordered_map(num_buckets) +#endif // _MSC_VER + { + } +}; + +typedef std::pair CoeffEntry; + +// A class to express a linear objective. +class MPObjective { + public: + // Clears the offset, all variables and coefficients, and the optimization + // direction. + void Clear(); + + // Sets the coefficient of the variable in the objective. If the variable + // does not belong to the solver, the function just returns, or crashes in + // non-opt mode. + void SetCoefficient(const MPVariable* const var, double coeff); + // Gets the coefficient of a given variable in the objective (which + // is 0 if the variable does not appear in the objective). + double GetCoefficient(const MPVariable* const var) const; + + // Sets the constant term in the objective. + void SetOffset(double value); + // Gets the constant term in the objective. + double offset() const { return offset_; } + + // Adds a constant term to the objective. + // Note: please use the less ambiguous SetOffset() if possible! + // TODO(user): remove this. + void AddOffset(double value) { SetOffset(offset() + value); } + + // Resets the current objective to take the value of linear_expr, and sets + // the objective direction to maximize if "is_maximize", otherwise minimizes. + void OptimizeLinearExpr(const LinearExpr& linear_expr, bool is_maximize); + void MaximizeLinearExpr(const LinearExpr& linear_expr) { + OptimizeLinearExpr(linear_expr, true); + } + void MinimizeLinearExpr(const LinearExpr& linear_expr) { + OptimizeLinearExpr(linear_expr, false); + } + + // Adds linear_expr to the current objective, does not change the direction. + void AddLinearExpr(const LinearExpr& linear_expr); + + // Sets the optimization direction (maximize: true or minimize: false). + void SetOptimizationDirection(bool maximize); + // Sets the optimization direction to minimize. + void SetMinimization() { SetOptimizationDirection(false); } + // Sets the optimization direction to maximize. + void SetMaximization() { SetOptimizationDirection(true); } + // Is the optimization direction set to maximize? + bool maximization() const; + // Is the optimization direction set to minimize? + bool minimization() const; + + // Returns the objective value of the best solution found so far. It + // is the optimal objective value if the problem has been solved to + // optimality. + // + // Note: the objective value may be slightly different than what you + // could compute yourself using MPVariable::solution_value(); + // please use the --verify_solution flag to gain confidence about the + // numerical stability of your solution. + double Value() const; + + // Returns the best objective bound. In case of minimization, it is + // a lower bound on the objective value of the optimal integer + // solution. Only available for discrete problems. + double BestBound() const; + + private: + friend class MPSolver; + friend class MPSolverInterface; + friend class CBCInterface; + friend class CLPInterface; + friend class GLPKInterface; + friend class SCIPInterface; + friend class SLMInterface; + friend class GurobiInterface; + friend class CplexInterface; + friend class GLOPInterface; + friend class BopInterface; + friend class KnapsackInterface; + + // Constructor. An objective points to a single MPSolverInterface + // that is specified in the constructor. An objective cannot belong + // to several models. + // At construction, an MPObjective has no terms (which is equivalent + // on having a coefficient of 0 for all variables), and an offset of 0. + explicit MPObjective(MPSolverInterface* const interface) + : interface_(interface), coefficients_(1), offset_(0.0) {} + + MPSolverInterface* const interface_; + + // Mapping var -> coefficient. + CoeffMap coefficients_; + // Constant term. + double offset_; + + DISALLOW_COPY_AND_ASSIGN(MPObjective); +}; + +// The class for variables of a Mathematical Programming (MP) model. +class MPVariable { + public: + // Returns the name of the variable. + const std::string& name() const { return name_; } + + // Sets the integrality requirement of the variable. + void SetInteger(bool integer); + // Returns the integrality requirement of the variable. + bool integer() const { return integer_; } + + // Returns the value of the variable in the current solution. + // If the variable is integer, then the value will always be an integer + // (the underlying solver handles floating-point values only, but this + // function automatically rounds it to the nearest integer; see: man 3 round). + double solution_value() const; + + // Returns the index of the variable in the MPSolver::variables_. + int index() const { return index_; } + + // Returns the lower bound. + double lb() const { return lb_; } + // Returns the upper bound. + double ub() const { return ub_; } + // Sets the lower bound. + void SetLB(double lb) { SetBounds(lb, ub_); } + // Sets the upper bound. + void SetUB(double ub) { SetBounds(lb_, ub); } + // Sets both the lower and upper bounds. + void SetBounds(double lb, double ub); + + // Advanced usage: unrounded solution value, i.e. it won't be rounded to the + // nearest integer even if the variable is integer. + double unrounded_solution_value() const; + // Advanced usage: returns the reduced cost of the variable in the + // current solution (only available for continuous problems). + double reduced_cost() const; + // Advanced usage: returns the basis status of the variable in the + // current solution (only available for continuous problems). + // @see MPSolver::BasisStatus. + MPSolver::BasisStatus basis_status() const; + + protected: + friend class MPSolver; + friend class MPSolverInterface; + friend class CBCInterface; + friend class CLPInterface; + friend class GLPKInterface; + friend class SCIPInterface; + friend class SLMInterface; + friend class GurobiInterface; + friend class CplexInterface; + friend class GLOPInterface; + friend class MPVariableSolutionValueTest; + friend class BopInterface; + friend class KnapsackInterface; + + // Constructor. A variable points to a single MPSolverInterface that + // is specified in the constructor. A variable cannot belong to + // several models. + MPVariable(int index, double lb, double ub, bool integer, const std::string& name, + MPSolverInterface* const interface) + : index_(index), + lb_(lb), + ub_(ub), + integer_(integer), + name_(name), + solution_value_(0.0), + reduced_cost_(0.0), + interface_(interface) {} + + void set_solution_value(double value) { solution_value_ = value; } + void set_reduced_cost(double reduced_cost) { reduced_cost_ = reduced_cost; } + + private: + const int index_; + double lb_; + double ub_; + bool integer_; + const std::string name_; + double solution_value_; + double reduced_cost_; + MPSolverInterface* const interface_; + DISALLOW_COPY_AND_ASSIGN(MPVariable); +}; + +// The class for constraints of a Mathematical Programming (MP) model. +// A constraint is represented as a linear equation or inequality. +class MPConstraint { + public: + // Returns the name of the constraint. + const std::string& name() const { return name_; } + + // Clears all variables and coefficients. Does not clear the bounds. + void Clear(); + + // Sets the coefficient of the variable on the constraint. If the variable + // does not belong to the solver, the function just returns, or crashes in + // non-opt mode. + void SetCoefficient(const MPVariable* const var, double coeff); + // Gets the coefficient of a given variable on the constraint (which + // is 0 if the variable does not appear in the constraint). + double GetCoefficient(const MPVariable* const var) const; + + // Returns the lower bound. + double lb() const { return lb_; } + // Returns the upper bound. + double ub() const { return ub_; } + // Sets the lower bound. + void SetLB(double lb) { SetBounds(lb, ub_); } + // Sets the upper bound. + void SetUB(double ub) { SetBounds(lb_, ub); } + // Sets both the lower and upper bounds. + void SetBounds(double lb, double ub); + + // Advanced usage: returns true if the constraint is "lazy" (see below). + bool is_lazy() const { return is_lazy_; } + // Advanced usage: sets the constraint "laziness". + // *** This is only supported for SCIP and has no effect on other solvers. *** + // When 'laziness' is true, the constraint is only considered by the Linear + // Programming solver if its current solution violates the constraint. + // In this case, the constraint is definitively added to the problem. + // This may be useful in some MIP problems, and may have a dramatic impact + // on performance. + // For more info see: http://tinyurl.com/lazy-constraints. + void set_is_lazy(bool laziness) { is_lazy_ = laziness; } + + // Returns the index of the constraint in the MPSolver::constraints_. + int index() const { return index_; } + + // Advanced usage: returns the dual value of the constraint in the + // current solution (only available for continuous problems). + double dual_value() const; + + // Advanced usage: returns the basis status of the constraint (only available + // for continuous problems). Note that if a constraint "linear_expression in + // [lb, ub]" is transformed into "linear_expression + slack = 0" with slack in + // [-ub, -lb], then this status is the same as the status of the slack + // variable with AT_UPPER_BOUND and AT_LOWER_BOUND swapped. + // + // @see MPSolver::BasisStatus. + MPSolver::BasisStatus basis_status() const; + + protected: + friend class MPSolver; + friend class MPSolverInterface; + friend class CBCInterface; + friend class CLPInterface; + friend class GLPKInterface; + friend class SCIPInterface; + friend class SLMInterface; + friend class GurobiInterface; + friend class CplexInterface; + friend class GLOPInterface; + friend class BopInterface; + friend class KnapsackInterface; + + // Constructor. A constraint points to a single MPSolverInterface + // that is specified in the constructor. A constraint cannot belong + // to several models. + MPConstraint(int index, double lb, double ub, const std::string& name, + MPSolverInterface* const interface) + : coefficients_(1), + index_(index), + lb_(lb), + ub_(ub), + name_(name), + is_lazy_(false), + dual_value_(0.0), + interface_(interface) {} + + void set_dual_value(double dual_value) { dual_value_ = dual_value; } + + private: + // Returns true if the constraint contains variables that have not + // been extracted yet. + bool ContainsNewVariables(); + + // Mapping var -> coefficient. + CoeffMap coefficients_; + + const int index_; // See index(). + + // The lower bound for the linear constraint. + double lb_; + + // The upper bound for the linear constraint. + double ub_; + + // Name. + const std::string name_; + + // True if the constraint is "lazy", i.e. the constraint is added to the + // underlying Linear Programming solver only if it is violated. + // By default this parameter is 'false'. + bool is_lazy_; + double dual_value_; + MPSolverInterface* const interface_; + DISALLOW_COPY_AND_ASSIGN(MPConstraint); +}; + +// This class stores parameter settings for LP and MIP solvers. +// Some parameters are marked as advanced: do not change their values +// unless you know what you are doing! +// +// For developers: how to add a new parameter: +// - Add the new Foo parameter in the DoubleParam or IntegerParam enum. +// - If it is a categorical param, add a FooValues enum. +// - Decide if the wrapper should define a default value for it: yes +// if it controls the properties of the solution (example: +// tolerances) or if it consistently improves performance, no +// otherwise. If yes, define kDefaultFoo. +// - Add a foo_value_ member and, if no default value is defined, a +// foo_is_default_ member. +// - Add code to handle Foo in Set...Param, Reset...Param, +// Get...Param, Reset and the constructor. +// - In class MPSolverInterface, add a virtual method SetFoo, add it +// to SetCommonParameters or SetMIPParameters, and implement it for +// each solver. Sometimes, parameters need to be implemented +// differently, see for example the INCREMENTALITY implementation. +// - Add a test in linear_solver_test.cc. +// +// TODO(user): store the parameter values in a protocol buffer +// instead. We need to figure out how to deal with the subtleties of +// the default values. +class MPSolverParameters { + public: + // Enumeration of parameters that take continuous values. + enum DoubleParam { + // Limit for relative MIP gap. + RELATIVE_MIP_GAP = 0, + // Advanced usage: tolerance for primal feasibility of basic + // solutions. This does not control the integer feasibility + // tolerance of integer solutions for MIP or the tolerance used + // during presolve. + PRIMAL_TOLERANCE = 1, + // Advanced usage: tolerance for dual feasibility of basic solutions. + DUAL_TOLERANCE = 2 + }; + + // Enumeration of parameters that take integer or categorical values. + enum IntegerParam { + // Advanced usage: presolve mode. + PRESOLVE = 1000, + // Algorithm to solve linear programs. + LP_ALGORITHM = 1001, + // Advanced usage: incrementality from one solve to the next. + INCREMENTALITY = 1002, + // Advanced usage: enable or disable matrix scaling. + SCALING = 1003 + }; + + // For each categorical parameter, enumeration of possible values. + enum PresolveValues { + PRESOLVE_OFF = 0, // Presolve is off. + PRESOLVE_ON = 1 // Presolve is on. + }; + + enum LpAlgorithmValues { + DUAL = 10, // Dual simplex. + PRIMAL = 11, // Primal simplex. + BARRIER = 12 // Barrier algorithm. + }; + + enum IncrementalityValues { + // Start solve from scratch. + INCREMENTALITY_OFF = 0, + // Reuse results from previous solve as much as the underlying + // solver allows. + INCREMENTALITY_ON = 1 + }; + + enum ScalingValues { + SCALING_OFF = 0, // Scaling is off. + SCALING_ON = 1 // Scaling is on. + }; + + // @{ + // Placeholder value to indicate that a parameter is set to + // the default value defined in the wrapper. + static const double kDefaultDoubleParamValue; + static const int kDefaultIntegerParamValue; + // @} + + // @{ + // Placeholder value to indicate that a parameter is unknown. + static const double kUnknownDoubleParamValue; + static const int kUnknownIntegerParamValue; + // @} + + // @{ + // Default values for parameters. Only parameters that define the + // properties of the solution returned need to have a default value + // (that is the same for all solvers). You can also define a default + // value for performance parameters when you are confident it is a + // good choice (example: always turn presolve on). + static const double kDefaultRelativeMipGap; + static const double kDefaultPrimalTolerance; + static const double kDefaultDualTolerance; + static const PresolveValues kDefaultPresolve; + static const IncrementalityValues kDefaultIncrementality; + // @} + + // The constructor sets all parameters to their default value. + MPSolverParameters(); + + // @{ + // Sets a parameter to a specific value. + void SetDoubleParam(MPSolverParameters::DoubleParam param, double value); + void SetIntegerParam(MPSolverParameters::IntegerParam param, int value); + // @} + + // @{ + // Sets a parameter to its default value (default value defined + // in MPSolverParameters if it exists, otherwise the default value + // defined in the underlying solver). + void ResetDoubleParam(MPSolverParameters::DoubleParam param); + void ResetIntegerParam(MPSolverParameters::IntegerParam param); + // Sets all parameters to their default value. + void Reset(); + // @} + + // @{ + // Returns the value of a parameter. + double GetDoubleParam(MPSolverParameters::DoubleParam param) const; + int GetIntegerParam(MPSolverParameters::IntegerParam param) const; + // @} + + + private: + // @{ + // Parameter value for each parameter. + // @see DoubleParam + // @see IntegerParam + double relative_mip_gap_value_; + double primal_tolerance_value_; + double dual_tolerance_value_; + int presolve_value_; + int scaling_value_; + int lp_algorithm_value_; + int incrementality_value_; + // @} + + // Boolean value indicating whether each parameter is set to the + // solver's default value. Only parameters for which the wrapper + // does not define a default value need such an indicator. + bool lp_algorithm_is_default_; + + + DISALLOW_COPY_AND_ASSIGN(MPSolverParameters); +}; + +// This class wraps the actual mathematical programming solvers. Each +// solver (GLOP, CLP, CBC, GLPK, SCIP) has its own interface class that +// derives from this abstract class. This class is never directly +// accessed by the user. +// @see glop_interface.cc +// @see cbc_interface.cc +// @see clp_interface.cc +// @see glpk_interface.cc +// @see scip_interface.cc +class MPSolverInterface { + public: + enum SynchronizationStatus { + // The underlying solver (CLP, GLPK, ...) and MPSolver are not in + // sync for the model nor for the solution. + MUST_RELOAD, + // The underlying solver and MPSolver are in sync for the model + // but not for the solution: the model has changed since the + // solution was computed last. + MODEL_SYNCHRONIZED, + // The underlying solver and MPSolver are in sync for the model and + // the solution. + SOLUTION_SYNCHRONIZED + }; + + // When the underlying solver does not provide the number of simplex + // iterations. + static const int64 kUnknownNumberOfIterations = -1; + // When the underlying solver does not provide the number of + // branch-and-bound nodes. + static const int64 kUnknownNumberOfNodes = -1; + + // Constructor. The user will access the MPSolverInterface through the + // MPSolver passed as argument. + explicit MPSolverInterface(MPSolver* const solver); + virtual ~MPSolverInterface(); + + // ----- Solve ----- + // Solves problem with specified parameter values. Returns true if the + // solution is optimal. + virtual MPSolver::ResultStatus Solve(const MPSolverParameters& param) = 0; + + // Writes the model using the solver internal write function. Currently only + // available for GurobiInterface. + virtual void Write(const std::string& filename); + + // ----- Model modifications and extraction ----- + // Resets extracted model. + virtual void Reset() = 0; + + // Sets the optimization direction (min/max). + virtual void SetOptimizationDirection(bool maximize) = 0; + + // Modifies bounds of an extracted variable. + virtual void SetVariableBounds(int index, double lb, double ub) = 0; + + // Modifies integrality of an extracted variable. + virtual void SetVariableInteger(int index, bool integer) = 0; + + // Modify bounds of an extracted variable. + virtual void SetConstraintBounds(int index, double lb, double ub) = 0; + + // Adds a linear constraint. + virtual void AddRowConstraint(MPConstraint* const ct) = 0; + + // Add a variable. + virtual void AddVariable(MPVariable* const var) = 0; + + // Changes a coefficient in a constraint. + virtual void SetCoefficient(MPConstraint* const constraint, + const MPVariable* const variable, + double new_value, double old_value) = 0; + + // Clears a constraint from all its terms. + virtual void ClearConstraint(MPConstraint* const constraint) = 0; + + // Changes a coefficient in the linear objective. + virtual void SetObjectiveCoefficient(const MPVariable* const variable, + double coefficient) = 0; + + // Changes the constant term in the linear objective. + virtual void SetObjectiveOffset(double value) = 0; + + // Clears the objective from all its terms. + virtual void ClearObjective() = 0; + + // ------ Query statistics on the solution and the solve ------ + // Returns the number of simplex iterations. The problem must be discrete, + // otherwise it crashes, or returns kUnknownNumberOfIterations in NDEBUG mode. + virtual int64 iterations() const = 0; + // Returns the number of branch-and-bound nodes. The problem must be discrete, + // otherwise it crashes, or returns kUnknownNumberOfNodes in NDEBUG mode. + virtual int64 nodes() const = 0; + // Returns the best objective bound. The problem must be discrete, otherwise + // it crashes, or returns trivial_worst_objective_bound() in NDEBUG mode. + virtual double best_objective_bound() const = 0; + // A trivial objective bound: the worst possible value of the objective, + // which will be +infinity if minimizing and -infinity if maximing. + double trivial_worst_objective_bound() const; + // Returns the objective value of the best solution found so far. + double objective_value() const; + + // Returns the basis status of a row. + virtual MPSolver::BasisStatus row_status(int constraint_index) const = 0; + // Returns the basis status of a constraint. + virtual MPSolver::BasisStatus column_status(int variable_index) const = 0; + + // Checks whether the solution is synchronized with the model, i.e. whether + // the model has changed since the solution was computed last. + // If it isn't, it crashes in NDEBUG, and returns false othwerwise. + bool CheckSolutionIsSynchronized() const; + // Checks whether a feasible solution exists. The behavior is similar to + // CheckSolutionIsSynchronized() above. + virtual bool CheckSolutionExists() const; + // Handy shortcut to do both checks above (it is often used). + bool CheckSolutionIsSynchronizedAndExists() const { + return CheckSolutionIsSynchronized() && CheckSolutionExists(); + } + // Checks whether information on the best objective bound exists. The behavior + // is similar to CheckSolutionIsSynchronized() above. + virtual bool CheckBestObjectiveBoundExists() const; + + // ----- Misc ----- + // Queries problem type. For simplicity, the distinction between + // continuous and discrete is based on the declaration of the user + // when the solver is created (example: GLPK_LINEAR_PROGRAMMING + // vs. GLPK_MIXED_INTEGER_PROGRAMMING), not on the actual content of + // the model. + // Returns true if the problem is continuous. + virtual bool IsContinuous() const = 0; + // Returns true if the problem is continuous and linear. + virtual bool IsLP() const = 0; + // Returns true if the problem is discrete and linear. + virtual bool IsMIP() const = 0; + + // Returns the index of the last variable extracted. + int last_variable_index() const { return last_variable_index_; } + + bool variable_is_extracted(int var_index) const { + return solver_->variable_is_extracted_[var_index]; + } + void set_variable_as_extracted(int var_index, bool extracted) { + solver_->variable_is_extracted_[var_index] = extracted; + } + bool constraint_is_extracted(int ct_index) const { + return solver_->constraint_is_extracted_[ct_index]; + } + void set_constraint_as_extracted(int ct_index, bool extracted) { + solver_->constraint_is_extracted_[ct_index] = extracted; + } + + // Returns the boolean indicating the verbosity of the solver output. + bool quiet() const { return quiet_; } + // Sets the boolean indicating the verbosity of the solver output. + void set_quiet(bool quiet_value) { quiet_ = quiet_value; } + + // Returns the result status of the last solve. + MPSolver::ResultStatus result_status() const { + CheckSolutionIsSynchronized(); + return result_status_; + } + + // Returns a std::string describing the underlying solver and its version. + virtual std::string SolverVersion() const = 0; + + // Returns the underlying solver. + virtual void* underlying_solver() = 0; + + // Computes exact condition number. Only available for continuous + // problems and only implemented in GLPK. + virtual double ComputeExactConditionNumber() const; + + // See MPSolver::SetStartingLpBasis(). + virtual void SetStartingLpBasis( + const std::vector& variable_statuses, + const std::vector& constraint_statuses) { + LOG(FATAL) << "Not supported by this solver."; + } + + virtual bool InterruptSolve() { return false; } + + friend class MPSolver; + + // To access the maximize_ bool and the MPSolver. + friend class MPConstraint; + friend class MPObjective; + + protected: + MPSolver* const solver_; + // Indicates whether the model and the solution are synchronized. + SynchronizationStatus sync_status_; + // Indicates whether the solve has reached optimality, + // infeasibility, a limit, etc. + MPSolver::ResultStatus result_status_; + // Optimization direction. + bool maximize_; + + // Index in MPSolver::variables_ of last constraint extracted. + int last_constraint_index_; + // Index in MPSolver::constraints_ of last variable extracted. + int last_variable_index_; + + // The value of the objective function. + double objective_value_; + + // Boolean indicator for the verbosity of the solver output. + bool quiet_; + + // Index of dummy variable created for empty constraints or the + // objective offset. + static const int kDummyVariableIndex; + + // Extracts model stored in MPSolver. + void ExtractModel(); + // Extracts the variables that have not been extracted yet. + virtual void ExtractNewVariables() = 0; + // Extracts the constraints that have not been extracted yet. + virtual void ExtractNewConstraints() = 0; + // Extracts the objective. + virtual void ExtractObjective() = 0; + // Resets the extraction information. + void ResetExtractionInformation(); + // Change synchronization status from SOLUTION_SYNCHRONIZED to + // MODEL_SYNCHRONIZED. To be used for model changes. + void InvalidateSolutionSynchronization(); + + // Sets parameters common to LP and MIP in the underlying solver. + void SetCommonParameters(const MPSolverParameters& param); + // Sets MIP specific parameters in the underlying solver. + void SetMIPParameters(const MPSolverParameters& param); + // Sets all parameters in the underlying solver. + virtual void SetParameters(const MPSolverParameters& param) = 0; + // Sets an unsupported double parameter. + void SetUnsupportedDoubleParam(MPSolverParameters::DoubleParam param) const; + // Sets an unsupported integer parameter. + void SetUnsupportedIntegerParam(MPSolverParameters::IntegerParam param) const; + // Sets a supported double parameter to an unsupported value. + void SetDoubleParamToUnsupportedValue(MPSolverParameters::DoubleParam param, + double value) const; + // Sets a supported integer parameter to an unsupported value. + void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, + int value) const; + // Sets each parameter in the underlying solver. + virtual void SetRelativeMipGap(double value) = 0; + virtual void SetPrimalTolerance(double value) = 0; + virtual void SetDualTolerance(double value) = 0; + virtual void SetPresolveMode(int value) = 0; + + // Pass solver specific parameters in text format. The format is + // solver-specific and is the same as the corresponding solver configuration + // file format. Returns true if the operation was successful. + // + // The default implementation of this method stores the parameters in a + // temporary file and calls ReadParameterFile to import the parameter file + // into the solver. Solvers that support passing the parameters directly can + // override this method to skip the temporary file logic. + virtual bool SetSolverSpecificParametersAsString(const std::string& parameters); + + // Reads a solver-specific file of parameters and set them. + // Returns true if there was no errors. + virtual bool ReadParameterFile(const std::string& filename); + + // Returns a file extension like ".tmp", this is needed because some solvers + // require a given extension for the ReadParameterFile() filename and we need + // to know it to generate a temporary parameter file. + virtual std::string ValidFileExtensionForParameterFile() const; + + // Sets the scaling mode. + virtual void SetScalingMode(int value) = 0; + virtual void SetLpAlgorithm(int value) = 0; +}; + + +} // namespace operations_research + +#endif // OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_ diff --git a/thirdparty/linux/include/ortools/linear_solver/linear_solver.pb.h b/thirdparty/linux/include/ortools/linear_solver/linear_solver.pb.h new file mode 100644 index 0000000..d8f7603 --- /dev/null +++ b/thirdparty/linux/include/ortools/linear_solver/linear_solver.pb.h @@ -0,0 +1,2532 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/linear_solver/linear_solver.proto + +#ifndef PROTOBUF_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto__INCLUDED +#define PROTOBUF_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); +void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); +void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + +class MPConstraintProto; +class MPModelProto; +class MPModelRequest; +class MPSolutionResponse; +class MPSolverCommonParameters; +class MPVariableProto; +class OptionalDouble; +class PartialVariableAssignment; + +enum MPSolverCommonParameters_LPAlgorithmValues { + MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_UNSPECIFIED = 0, + MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_DUAL = 1, + MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_PRIMAL = 2, + MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_BARRIER = 3 +}; +bool MPSolverCommonParameters_LPAlgorithmValues_IsValid(int value); +const MPSolverCommonParameters_LPAlgorithmValues MPSolverCommonParameters_LPAlgorithmValues_LPAlgorithmValues_MIN = MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_UNSPECIFIED; +const MPSolverCommonParameters_LPAlgorithmValues MPSolverCommonParameters_LPAlgorithmValues_LPAlgorithmValues_MAX = MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_BARRIER; +const int MPSolverCommonParameters_LPAlgorithmValues_LPAlgorithmValues_ARRAYSIZE = MPSolverCommonParameters_LPAlgorithmValues_LPAlgorithmValues_MAX + 1; + +const ::google::protobuf::EnumDescriptor* MPSolverCommonParameters_LPAlgorithmValues_descriptor(); +inline const ::std::string& MPSolverCommonParameters_LPAlgorithmValues_Name(MPSolverCommonParameters_LPAlgorithmValues value) { + return ::google::protobuf::internal::NameOfEnum( + MPSolverCommonParameters_LPAlgorithmValues_descriptor(), value); +} +inline bool MPSolverCommonParameters_LPAlgorithmValues_Parse( + const ::std::string& name, MPSolverCommonParameters_LPAlgorithmValues* value) { + return ::google::protobuf::internal::ParseNamedEnum( + MPSolverCommonParameters_LPAlgorithmValues_descriptor(), name, value); +} +enum MPModelRequest_SolverType { + MPModelRequest_SolverType_GLOP_LINEAR_PROGRAMMING = 2, + MPModelRequest_SolverType_CLP_LINEAR_PROGRAMMING = 0, + MPModelRequest_SolverType_GLPK_LINEAR_PROGRAMMING = 1, + MPModelRequest_SolverType_GUROBI_LINEAR_PROGRAMMING = 6, + MPModelRequest_SolverType_CPLEX_LINEAR_PROGRAMMING = 10, + MPModelRequest_SolverType_SCIP_MIXED_INTEGER_PROGRAMMING = 3, + MPModelRequest_SolverType_GLPK_MIXED_INTEGER_PROGRAMMING = 4, + MPModelRequest_SolverType_CBC_MIXED_INTEGER_PROGRAMMING = 5, + MPModelRequest_SolverType_GUROBI_MIXED_INTEGER_PROGRAMMING = 7, + MPModelRequest_SolverType_CPLEX_MIXED_INTEGER_PROGRAMMING = 11, + MPModelRequest_SolverType_BOP_INTEGER_PROGRAMMING = 12, + MPModelRequest_SolverType_KNAPSACK_MIXED_INTEGER_PROGRAMMING = 13 +}; +bool MPModelRequest_SolverType_IsValid(int value); +const MPModelRequest_SolverType MPModelRequest_SolverType_SolverType_MIN = MPModelRequest_SolverType_CLP_LINEAR_PROGRAMMING; +const MPModelRequest_SolverType MPModelRequest_SolverType_SolverType_MAX = MPModelRequest_SolverType_KNAPSACK_MIXED_INTEGER_PROGRAMMING; +const int MPModelRequest_SolverType_SolverType_ARRAYSIZE = MPModelRequest_SolverType_SolverType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* MPModelRequest_SolverType_descriptor(); +inline const ::std::string& MPModelRequest_SolverType_Name(MPModelRequest_SolverType value) { + return ::google::protobuf::internal::NameOfEnum( + MPModelRequest_SolverType_descriptor(), value); +} +inline bool MPModelRequest_SolverType_Parse( + const ::std::string& name, MPModelRequest_SolverType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + MPModelRequest_SolverType_descriptor(), name, value); +} +enum OptionalBoolean { + BOOL_UNSPECIFIED = 0, + BOOL_FALSE = 1, + BOOL_TRUE = 2 +}; +bool OptionalBoolean_IsValid(int value); +const OptionalBoolean OptionalBoolean_MIN = BOOL_UNSPECIFIED; +const OptionalBoolean OptionalBoolean_MAX = BOOL_TRUE; +const int OptionalBoolean_ARRAYSIZE = OptionalBoolean_MAX + 1; + +const ::google::protobuf::EnumDescriptor* OptionalBoolean_descriptor(); +inline const ::std::string& OptionalBoolean_Name(OptionalBoolean value) { + return ::google::protobuf::internal::NameOfEnum( + OptionalBoolean_descriptor(), value); +} +inline bool OptionalBoolean_Parse( + const ::std::string& name, OptionalBoolean* value) { + return ::google::protobuf::internal::ParseNamedEnum( + OptionalBoolean_descriptor(), name, value); +} +enum MPSolverResponseStatus { + MPSOLVER_OPTIMAL = 0, + MPSOLVER_FEASIBLE = 1, + MPSOLVER_INFEASIBLE = 2, + MPSOLVER_UNBOUNDED = 3, + MPSOLVER_ABNORMAL = 4, + MPSOLVER_NOT_SOLVED = 6, + MPSOLVER_MODEL_IS_VALID = 97, + MPSOLVER_UNKNOWN_STATUS = 99, + MPSOLVER_MODEL_INVALID = 5, + MPSOLVER_MODEL_INVALID_SOLUTION_HINT = 84, + MPSOLVER_MODEL_INVALID_SOLVER_PARAMETERS = 85, + MPSOLVER_SOLVER_TYPE_UNAVAILABLE = 7 +}; +bool MPSolverResponseStatus_IsValid(int value); +const MPSolverResponseStatus MPSolverResponseStatus_MIN = MPSOLVER_OPTIMAL; +const MPSolverResponseStatus MPSolverResponseStatus_MAX = MPSOLVER_UNKNOWN_STATUS; +const int MPSolverResponseStatus_ARRAYSIZE = MPSolverResponseStatus_MAX + 1; + +const ::google::protobuf::EnumDescriptor* MPSolverResponseStatus_descriptor(); +inline const ::std::string& MPSolverResponseStatus_Name(MPSolverResponseStatus value) { + return ::google::protobuf::internal::NameOfEnum( + MPSolverResponseStatus_descriptor(), value); +} +inline bool MPSolverResponseStatus_Parse( + const ::std::string& name, MPSolverResponseStatus* value) { + return ::google::protobuf::internal::ParseNamedEnum( + MPSolverResponseStatus_descriptor(), name, value); +} +// =================================================================== + +class MPVariableProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.MPVariableProto) */ { + public: + MPVariableProto(); + virtual ~MPVariableProto(); + + MPVariableProto(const MPVariableProto& from); + + inline MPVariableProto& operator=(const MPVariableProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MPVariableProto& default_instance(); + + void Swap(MPVariableProto* other); + + // implements Message ---------------------------------------------- + + inline MPVariableProto* New() const { return New(NULL); } + + MPVariableProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MPVariableProto& from); + void MergeFrom(const MPVariableProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MPVariableProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional double lower_bound = 1 [default = -inf]; + bool has_lower_bound() const; + void clear_lower_bound(); + static const int kLowerBoundFieldNumber = 1; + double lower_bound() const; + void set_lower_bound(double value); + + // optional double upper_bound = 2 [default = inf]; + bool has_upper_bound() const; + void clear_upper_bound(); + static const int kUpperBoundFieldNumber = 2; + double upper_bound() const; + void set_upper_bound(double value); + + // optional double objective_coefficient = 3 [default = 0]; + bool has_objective_coefficient() const; + void clear_objective_coefficient(); + static const int kObjectiveCoefficientFieldNumber = 3; + double objective_coefficient() const; + void set_objective_coefficient(double value); + + // optional bool is_integer = 4 [default = false]; + bool has_is_integer() const; + void clear_is_integer(); + static const int kIsIntegerFieldNumber = 4; + bool is_integer() const; + void set_is_integer(bool value); + + // optional string name = 5 [default = ""]; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 5; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:operations_research.MPVariableProto) + private: + inline void set_has_lower_bound(); + inline void clear_has_lower_bound(); + inline void set_has_upper_bound(); + inline void clear_has_upper_bound(); + inline void set_has_objective_coefficient(); + inline void clear_has_objective_coefficient(); + inline void set_has_is_integer(); + inline void clear_has_is_integer(); + inline void set_has_name(); + inline void clear_has_name(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + double lower_bound_; + double upper_bound_; + double objective_coefficient_; + ::google::protobuf::internal::ArenaStringPtr name_; + bool is_integer_; + friend void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + + void InitAsDefaultInstance(); + static MPVariableProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class MPConstraintProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.MPConstraintProto) */ { + public: + MPConstraintProto(); + virtual ~MPConstraintProto(); + + MPConstraintProto(const MPConstraintProto& from); + + inline MPConstraintProto& operator=(const MPConstraintProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MPConstraintProto& default_instance(); + + void Swap(MPConstraintProto* other); + + // implements Message ---------------------------------------------- + + inline MPConstraintProto* New() const { return New(NULL); } + + MPConstraintProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MPConstraintProto& from); + void MergeFrom(const MPConstraintProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MPConstraintProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 var_index = 6 [packed = true]; + int var_index_size() const; + void clear_var_index(); + static const int kVarIndexFieldNumber = 6; + ::google::protobuf::int32 var_index(int index) const; + void set_var_index(int index, ::google::protobuf::int32 value); + void add_var_index(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + var_index() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_var_index(); + + // repeated double coefficient = 7 [packed = true]; + int coefficient_size() const; + void clear_coefficient(); + static const int kCoefficientFieldNumber = 7; + double coefficient(int index) const; + void set_coefficient(int index, double value); + void add_coefficient(double value); + const ::google::protobuf::RepeatedField< double >& + coefficient() const; + ::google::protobuf::RepeatedField< double >* + mutable_coefficient(); + + // optional double lower_bound = 2 [default = -inf]; + bool has_lower_bound() const; + void clear_lower_bound(); + static const int kLowerBoundFieldNumber = 2; + double lower_bound() const; + void set_lower_bound(double value); + + // optional double upper_bound = 3 [default = inf]; + bool has_upper_bound() const; + void clear_upper_bound(); + static const int kUpperBoundFieldNumber = 3; + double upper_bound() const; + void set_upper_bound(double value); + + // optional string name = 4 [default = ""]; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 4; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional bool is_lazy = 5 [default = false]; + bool has_is_lazy() const; + void clear_is_lazy(); + static const int kIsLazyFieldNumber = 5; + bool is_lazy() const; + void set_is_lazy(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.MPConstraintProto) + private: + inline void set_has_lower_bound(); + inline void clear_has_lower_bound(); + inline void set_has_upper_bound(); + inline void clear_has_upper_bound(); + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_is_lazy(); + inline void clear_has_is_lazy(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > var_index_; + mutable int _var_index_cached_byte_size_; + ::google::protobuf::RepeatedField< double > coefficient_; + mutable int _coefficient_cached_byte_size_; + double lower_bound_; + double upper_bound_; + ::google::protobuf::internal::ArenaStringPtr name_; + bool is_lazy_; + friend void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + + void InitAsDefaultInstance(); + static MPConstraintProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class PartialVariableAssignment : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.PartialVariableAssignment) */ { + public: + PartialVariableAssignment(); + virtual ~PartialVariableAssignment(); + + PartialVariableAssignment(const PartialVariableAssignment& from); + + inline PartialVariableAssignment& operator=(const PartialVariableAssignment& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const PartialVariableAssignment& default_instance(); + + void Swap(PartialVariableAssignment* other); + + // implements Message ---------------------------------------------- + + inline PartialVariableAssignment* New() const { return New(NULL); } + + PartialVariableAssignment* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const PartialVariableAssignment& from); + void MergeFrom(const PartialVariableAssignment& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(PartialVariableAssignment* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 var_index = 1 [packed = true]; + int var_index_size() const; + void clear_var_index(); + static const int kVarIndexFieldNumber = 1; + ::google::protobuf::int32 var_index(int index) const; + void set_var_index(int index, ::google::protobuf::int32 value); + void add_var_index(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + var_index() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_var_index(); + + // repeated double var_value = 2 [packed = true]; + int var_value_size() const; + void clear_var_value(); + static const int kVarValueFieldNumber = 2; + double var_value(int index) const; + void set_var_value(int index, double value); + void add_var_value(double value); + const ::google::protobuf::RepeatedField< double >& + var_value() const; + ::google::protobuf::RepeatedField< double >* + mutable_var_value(); + + // @@protoc_insertion_point(class_scope:operations_research.PartialVariableAssignment) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > var_index_; + mutable int _var_index_cached_byte_size_; + ::google::protobuf::RepeatedField< double > var_value_; + mutable int _var_value_cached_byte_size_; + friend void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + + void InitAsDefaultInstance(); + static PartialVariableAssignment* default_instance_; +}; +// ------------------------------------------------------------------- + +class MPModelProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.MPModelProto) */ { + public: + MPModelProto(); + virtual ~MPModelProto(); + + MPModelProto(const MPModelProto& from); + + inline MPModelProto& operator=(const MPModelProto& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MPModelProto& default_instance(); + + void Swap(MPModelProto* other); + + // implements Message ---------------------------------------------- + + inline MPModelProto* New() const { return New(NULL); } + + MPModelProto* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MPModelProto& from); + void MergeFrom(const MPModelProto& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MPModelProto* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool maximize = 1 [default = false]; + bool has_maximize() const; + void clear_maximize(); + static const int kMaximizeFieldNumber = 1; + bool maximize() const; + void set_maximize(bool value); + + // optional double objective_offset = 2 [default = 0]; + bool has_objective_offset() const; + void clear_objective_offset(); + static const int kObjectiveOffsetFieldNumber = 2; + double objective_offset() const; + void set_objective_offset(double value); + + // repeated .operations_research.MPVariableProto variable = 3; + int variable_size() const; + void clear_variable(); + static const int kVariableFieldNumber = 3; + const ::operations_research::MPVariableProto& variable(int index) const; + ::operations_research::MPVariableProto* mutable_variable(int index); + ::operations_research::MPVariableProto* add_variable(); + ::google::protobuf::RepeatedPtrField< ::operations_research::MPVariableProto >* + mutable_variable(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::MPVariableProto >& + variable() const; + + // repeated .operations_research.MPConstraintProto constraint = 4; + int constraint_size() const; + void clear_constraint(); + static const int kConstraintFieldNumber = 4; + const ::operations_research::MPConstraintProto& constraint(int index) const; + ::operations_research::MPConstraintProto* mutable_constraint(int index); + ::operations_research::MPConstraintProto* add_constraint(); + ::google::protobuf::RepeatedPtrField< ::operations_research::MPConstraintProto >* + mutable_constraint(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::MPConstraintProto >& + constraint() const; + + // optional string name = 5 [default = ""]; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 5; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional .operations_research.PartialVariableAssignment solution_hint = 6; + bool has_solution_hint() const; + void clear_solution_hint(); + static const int kSolutionHintFieldNumber = 6; + const ::operations_research::PartialVariableAssignment& solution_hint() const; + ::operations_research::PartialVariableAssignment* mutable_solution_hint(); + ::operations_research::PartialVariableAssignment* release_solution_hint(); + void set_allocated_solution_hint(::operations_research::PartialVariableAssignment* solution_hint); + + // @@protoc_insertion_point(class_scope:operations_research.MPModelProto) + private: + inline void set_has_maximize(); + inline void clear_has_maximize(); + inline void set_has_objective_offset(); + inline void clear_has_objective_offset(); + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_solution_hint(); + inline void clear_has_solution_hint(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + double objective_offset_; + ::google::protobuf::RepeatedPtrField< ::operations_research::MPVariableProto > variable_; + ::google::protobuf::RepeatedPtrField< ::operations_research::MPConstraintProto > constraint_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::operations_research::PartialVariableAssignment* solution_hint_; + bool maximize_; + friend void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + + void InitAsDefaultInstance(); + static MPModelProto* default_instance_; +}; +// ------------------------------------------------------------------- + +class OptionalDouble : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.OptionalDouble) */ { + public: + OptionalDouble(); + virtual ~OptionalDouble(); + + OptionalDouble(const OptionalDouble& from); + + inline OptionalDouble& operator=(const OptionalDouble& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const OptionalDouble& default_instance(); + + void Swap(OptionalDouble* other); + + // implements Message ---------------------------------------------- + + inline OptionalDouble* New() const { return New(NULL); } + + OptionalDouble* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const OptionalDouble& from); + void MergeFrom(const OptionalDouble& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(OptionalDouble* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional double value = 1; + bool has_value() const; + void clear_value(); + static const int kValueFieldNumber = 1; + double value() const; + void set_value(double value); + + // @@protoc_insertion_point(class_scope:operations_research.OptionalDouble) + private: + inline void set_has_value(); + inline void clear_has_value(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + double value_; + friend void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + + void InitAsDefaultInstance(); + static OptionalDouble* default_instance_; +}; +// ------------------------------------------------------------------- + +class MPSolverCommonParameters : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.MPSolverCommonParameters) */ { + public: + MPSolverCommonParameters(); + virtual ~MPSolverCommonParameters(); + + MPSolverCommonParameters(const MPSolverCommonParameters& from); + + inline MPSolverCommonParameters& operator=(const MPSolverCommonParameters& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MPSolverCommonParameters& default_instance(); + + void Swap(MPSolverCommonParameters* other); + + // implements Message ---------------------------------------------- + + inline MPSolverCommonParameters* New() const { return New(NULL); } + + MPSolverCommonParameters* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MPSolverCommonParameters& from); + void MergeFrom(const MPSolverCommonParameters& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MPSolverCommonParameters* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef MPSolverCommonParameters_LPAlgorithmValues LPAlgorithmValues; + static const LPAlgorithmValues LP_ALGO_UNSPECIFIED = + MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_UNSPECIFIED; + static const LPAlgorithmValues LP_ALGO_DUAL = + MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_DUAL; + static const LPAlgorithmValues LP_ALGO_PRIMAL = + MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_PRIMAL; + static const LPAlgorithmValues LP_ALGO_BARRIER = + MPSolverCommonParameters_LPAlgorithmValues_LP_ALGO_BARRIER; + static inline bool LPAlgorithmValues_IsValid(int value) { + return MPSolverCommonParameters_LPAlgorithmValues_IsValid(value); + } + static const LPAlgorithmValues LPAlgorithmValues_MIN = + MPSolverCommonParameters_LPAlgorithmValues_LPAlgorithmValues_MIN; + static const LPAlgorithmValues LPAlgorithmValues_MAX = + MPSolverCommonParameters_LPAlgorithmValues_LPAlgorithmValues_MAX; + static const int LPAlgorithmValues_ARRAYSIZE = + MPSolverCommonParameters_LPAlgorithmValues_LPAlgorithmValues_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + LPAlgorithmValues_descriptor() { + return MPSolverCommonParameters_LPAlgorithmValues_descriptor(); + } + static inline const ::std::string& LPAlgorithmValues_Name(LPAlgorithmValues value) { + return MPSolverCommonParameters_LPAlgorithmValues_Name(value); + } + static inline bool LPAlgorithmValues_Parse(const ::std::string& name, + LPAlgorithmValues* value) { + return MPSolverCommonParameters_LPAlgorithmValues_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .operations_research.OptionalDouble relative_mip_gap = 1; + bool has_relative_mip_gap() const; + void clear_relative_mip_gap(); + static const int kRelativeMipGapFieldNumber = 1; + const ::operations_research::OptionalDouble& relative_mip_gap() const; + ::operations_research::OptionalDouble* mutable_relative_mip_gap(); + ::operations_research::OptionalDouble* release_relative_mip_gap(); + void set_allocated_relative_mip_gap(::operations_research::OptionalDouble* relative_mip_gap); + + // optional .operations_research.OptionalDouble primal_tolerance = 2; + bool has_primal_tolerance() const; + void clear_primal_tolerance(); + static const int kPrimalToleranceFieldNumber = 2; + const ::operations_research::OptionalDouble& primal_tolerance() const; + ::operations_research::OptionalDouble* mutable_primal_tolerance(); + ::operations_research::OptionalDouble* release_primal_tolerance(); + void set_allocated_primal_tolerance(::operations_research::OptionalDouble* primal_tolerance); + + // optional .operations_research.OptionalDouble dual_tolerance = 3; + bool has_dual_tolerance() const; + void clear_dual_tolerance(); + static const int kDualToleranceFieldNumber = 3; + const ::operations_research::OptionalDouble& dual_tolerance() const; + ::operations_research::OptionalDouble* mutable_dual_tolerance(); + ::operations_research::OptionalDouble* release_dual_tolerance(); + void set_allocated_dual_tolerance(::operations_research::OptionalDouble* dual_tolerance); + + // optional .operations_research.MPSolverCommonParameters.LPAlgorithmValues lp_algorithm = 4 [default = LP_ALGO_UNSPECIFIED]; + bool has_lp_algorithm() const; + void clear_lp_algorithm(); + static const int kLpAlgorithmFieldNumber = 4; + ::operations_research::MPSolverCommonParameters_LPAlgorithmValues lp_algorithm() const; + void set_lp_algorithm(::operations_research::MPSolverCommonParameters_LPAlgorithmValues value); + + // optional .operations_research.OptionalBoolean presolve = 5 [default = BOOL_UNSPECIFIED]; + bool has_presolve() const; + void clear_presolve(); + static const int kPresolveFieldNumber = 5; + ::operations_research::OptionalBoolean presolve() const; + void set_presolve(::operations_research::OptionalBoolean value); + + // optional .operations_research.OptionalBoolean scaling = 7 [default = BOOL_UNSPECIFIED]; + bool has_scaling() const; + void clear_scaling(); + static const int kScalingFieldNumber = 7; + ::operations_research::OptionalBoolean scaling() const; + void set_scaling(::operations_research::OptionalBoolean value); + + // @@protoc_insertion_point(class_scope:operations_research.MPSolverCommonParameters) + private: + inline void set_has_relative_mip_gap(); + inline void clear_has_relative_mip_gap(); + inline void set_has_primal_tolerance(); + inline void clear_has_primal_tolerance(); + inline void set_has_dual_tolerance(); + inline void clear_has_dual_tolerance(); + inline void set_has_lp_algorithm(); + inline void clear_has_lp_algorithm(); + inline void set_has_presolve(); + inline void clear_has_presolve(); + inline void set_has_scaling(); + inline void clear_has_scaling(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::operations_research::OptionalDouble* relative_mip_gap_; + ::operations_research::OptionalDouble* primal_tolerance_; + ::operations_research::OptionalDouble* dual_tolerance_; + int lp_algorithm_; + int presolve_; + int scaling_; + friend void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + + void InitAsDefaultInstance(); + static MPSolverCommonParameters* default_instance_; +}; +// ------------------------------------------------------------------- + +class MPModelRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.MPModelRequest) */ { + public: + MPModelRequest(); + virtual ~MPModelRequest(); + + MPModelRequest(const MPModelRequest& from); + + inline MPModelRequest& operator=(const MPModelRequest& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MPModelRequest& default_instance(); + + void Swap(MPModelRequest* other); + + // implements Message ---------------------------------------------- + + inline MPModelRequest* New() const { return New(NULL); } + + MPModelRequest* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MPModelRequest& from); + void MergeFrom(const MPModelRequest& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MPModelRequest* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef MPModelRequest_SolverType SolverType; + static const SolverType GLOP_LINEAR_PROGRAMMING = + MPModelRequest_SolverType_GLOP_LINEAR_PROGRAMMING; + static const SolverType CLP_LINEAR_PROGRAMMING = + MPModelRequest_SolverType_CLP_LINEAR_PROGRAMMING; + static const SolverType GLPK_LINEAR_PROGRAMMING = + MPModelRequest_SolverType_GLPK_LINEAR_PROGRAMMING; + static const SolverType GUROBI_LINEAR_PROGRAMMING = + MPModelRequest_SolverType_GUROBI_LINEAR_PROGRAMMING; + static const SolverType CPLEX_LINEAR_PROGRAMMING = + MPModelRequest_SolverType_CPLEX_LINEAR_PROGRAMMING; + static const SolverType SCIP_MIXED_INTEGER_PROGRAMMING = + MPModelRequest_SolverType_SCIP_MIXED_INTEGER_PROGRAMMING; + static const SolverType GLPK_MIXED_INTEGER_PROGRAMMING = + MPModelRequest_SolverType_GLPK_MIXED_INTEGER_PROGRAMMING; + static const SolverType CBC_MIXED_INTEGER_PROGRAMMING = + MPModelRequest_SolverType_CBC_MIXED_INTEGER_PROGRAMMING; + static const SolverType GUROBI_MIXED_INTEGER_PROGRAMMING = + MPModelRequest_SolverType_GUROBI_MIXED_INTEGER_PROGRAMMING; + static const SolverType CPLEX_MIXED_INTEGER_PROGRAMMING = + MPModelRequest_SolverType_CPLEX_MIXED_INTEGER_PROGRAMMING; + static const SolverType BOP_INTEGER_PROGRAMMING = + MPModelRequest_SolverType_BOP_INTEGER_PROGRAMMING; + static const SolverType KNAPSACK_MIXED_INTEGER_PROGRAMMING = + MPModelRequest_SolverType_KNAPSACK_MIXED_INTEGER_PROGRAMMING; + static inline bool SolverType_IsValid(int value) { + return MPModelRequest_SolverType_IsValid(value); + } + static const SolverType SolverType_MIN = + MPModelRequest_SolverType_SolverType_MIN; + static const SolverType SolverType_MAX = + MPModelRequest_SolverType_SolverType_MAX; + static const int SolverType_ARRAYSIZE = + MPModelRequest_SolverType_SolverType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + SolverType_descriptor() { + return MPModelRequest_SolverType_descriptor(); + } + static inline const ::std::string& SolverType_Name(SolverType value) { + return MPModelRequest_SolverType_Name(value); + } + static inline bool SolverType_Parse(const ::std::string& name, + SolverType* value) { + return MPModelRequest_SolverType_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .operations_research.MPModelProto model = 1; + bool has_model() const; + void clear_model(); + static const int kModelFieldNumber = 1; + const ::operations_research::MPModelProto& model() const; + ::operations_research::MPModelProto* mutable_model(); + ::operations_research::MPModelProto* release_model(); + void set_allocated_model(::operations_research::MPModelProto* model); + + // optional .operations_research.MPModelRequest.SolverType solver_type = 2; + bool has_solver_type() const; + void clear_solver_type(); + static const int kSolverTypeFieldNumber = 2; + ::operations_research::MPModelRequest_SolverType solver_type() const; + void set_solver_type(::operations_research::MPModelRequest_SolverType value); + + // optional double solver_time_limit_seconds = 3; + bool has_solver_time_limit_seconds() const; + void clear_solver_time_limit_seconds(); + static const int kSolverTimeLimitSecondsFieldNumber = 3; + double solver_time_limit_seconds() const; + void set_solver_time_limit_seconds(double value); + + // optional bool enable_internal_solver_output = 4 [default = false]; + bool has_enable_internal_solver_output() const; + void clear_enable_internal_solver_output(); + static const int kEnableInternalSolverOutputFieldNumber = 4; + bool enable_internal_solver_output() const; + void set_enable_internal_solver_output(bool value); + + // optional string solver_specific_parameters = 5; + bool has_solver_specific_parameters() const; + void clear_solver_specific_parameters(); + static const int kSolverSpecificParametersFieldNumber = 5; + const ::std::string& solver_specific_parameters() const; + void set_solver_specific_parameters(const ::std::string& value); + void set_solver_specific_parameters(const char* value); + void set_solver_specific_parameters(const char* value, size_t size); + ::std::string* mutable_solver_specific_parameters(); + ::std::string* release_solver_specific_parameters(); + void set_allocated_solver_specific_parameters(::std::string* solver_specific_parameters); + + // @@protoc_insertion_point(class_scope:operations_research.MPModelRequest) + private: + inline void set_has_model(); + inline void clear_has_model(); + inline void set_has_solver_type(); + inline void clear_has_solver_type(); + inline void set_has_solver_time_limit_seconds(); + inline void clear_has_solver_time_limit_seconds(); + inline void set_has_enable_internal_solver_output(); + inline void clear_has_enable_internal_solver_output(); + inline void set_has_solver_specific_parameters(); + inline void clear_has_solver_specific_parameters(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::operations_research::MPModelProto* model_; + double solver_time_limit_seconds_; + int solver_type_; + bool enable_internal_solver_output_; + ::google::protobuf::internal::ArenaStringPtr solver_specific_parameters_; + friend void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + + void InitAsDefaultInstance(); + static MPModelRequest* default_instance_; +}; +// ------------------------------------------------------------------- + +class MPSolutionResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.MPSolutionResponse) */ { + public: + MPSolutionResponse(); + virtual ~MPSolutionResponse(); + + MPSolutionResponse(const MPSolutionResponse& from); + + inline MPSolutionResponse& operator=(const MPSolutionResponse& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MPSolutionResponse& default_instance(); + + void Swap(MPSolutionResponse* other); + + // implements Message ---------------------------------------------- + + inline MPSolutionResponse* New() const { return New(NULL); } + + MPSolutionResponse* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MPSolutionResponse& from); + void MergeFrom(const MPSolutionResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MPSolutionResponse* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .operations_research.MPSolverResponseStatus status = 1 [default = MPSOLVER_UNKNOWN_STATUS]; + bool has_status() const; + void clear_status(); + static const int kStatusFieldNumber = 1; + ::operations_research::MPSolverResponseStatus status() const; + void set_status(::operations_research::MPSolverResponseStatus value); + + // optional double objective_value = 2; + bool has_objective_value() const; + void clear_objective_value(); + static const int kObjectiveValueFieldNumber = 2; + double objective_value() const; + void set_objective_value(double value); + + // optional double best_objective_bound = 5; + bool has_best_objective_bound() const; + void clear_best_objective_bound(); + static const int kBestObjectiveBoundFieldNumber = 5; + double best_objective_bound() const; + void set_best_objective_bound(double value); + + // repeated double variable_value = 3 [packed = true]; + int variable_value_size() const; + void clear_variable_value(); + static const int kVariableValueFieldNumber = 3; + double variable_value(int index) const; + void set_variable_value(int index, double value); + void add_variable_value(double value); + const ::google::protobuf::RepeatedField< double >& + variable_value() const; + ::google::protobuf::RepeatedField< double >* + mutable_variable_value(); + + // repeated double dual_value = 4 [packed = true]; + int dual_value_size() const; + void clear_dual_value(); + static const int kDualValueFieldNumber = 4; + double dual_value(int index) const; + void set_dual_value(int index, double value); + void add_dual_value(double value); + const ::google::protobuf::RepeatedField< double >& + dual_value() const; + ::google::protobuf::RepeatedField< double >* + mutable_dual_value(); + + // @@protoc_insertion_point(class_scope:operations_research.MPSolutionResponse) + private: + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_objective_value(); + inline void clear_has_objective_value(); + inline void set_has_best_objective_bound(); + inline void clear_has_best_objective_bound(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + double objective_value_; + double best_objective_bound_; + ::google::protobuf::RepeatedField< double > variable_value_; + mutable int _variable_value_cached_byte_size_; + ::google::protobuf::RepeatedField< double > dual_value_; + mutable int _dual_value_cached_byte_size_; + int status_; + friend void protobuf_AddDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_AssignDesc_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + friend void protobuf_ShutdownFile_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto(); + + void InitAsDefaultInstance(); + static MPSolutionResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// MPVariableProto + +// optional double lower_bound = 1 [default = -inf]; +inline bool MPVariableProto::has_lower_bound() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MPVariableProto::set_has_lower_bound() { + _has_bits_[0] |= 0x00000001u; +} +inline void MPVariableProto::clear_has_lower_bound() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MPVariableProto::clear_lower_bound() { + lower_bound_ = -::google::protobuf::internal::Infinity(); + clear_has_lower_bound(); +} +inline double MPVariableProto::lower_bound() const { + // @@protoc_insertion_point(field_get:operations_research.MPVariableProto.lower_bound) + return lower_bound_; +} +inline void MPVariableProto::set_lower_bound(double value) { + set_has_lower_bound(); + lower_bound_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPVariableProto.lower_bound) +} + +// optional double upper_bound = 2 [default = inf]; +inline bool MPVariableProto::has_upper_bound() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MPVariableProto::set_has_upper_bound() { + _has_bits_[0] |= 0x00000002u; +} +inline void MPVariableProto::clear_has_upper_bound() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MPVariableProto::clear_upper_bound() { + upper_bound_ = ::google::protobuf::internal::Infinity(); + clear_has_upper_bound(); +} +inline double MPVariableProto::upper_bound() const { + // @@protoc_insertion_point(field_get:operations_research.MPVariableProto.upper_bound) + return upper_bound_; +} +inline void MPVariableProto::set_upper_bound(double value) { + set_has_upper_bound(); + upper_bound_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPVariableProto.upper_bound) +} + +// optional double objective_coefficient = 3 [default = 0]; +inline bool MPVariableProto::has_objective_coefficient() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MPVariableProto::set_has_objective_coefficient() { + _has_bits_[0] |= 0x00000004u; +} +inline void MPVariableProto::clear_has_objective_coefficient() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MPVariableProto::clear_objective_coefficient() { + objective_coefficient_ = 0; + clear_has_objective_coefficient(); +} +inline double MPVariableProto::objective_coefficient() const { + // @@protoc_insertion_point(field_get:operations_research.MPVariableProto.objective_coefficient) + return objective_coefficient_; +} +inline void MPVariableProto::set_objective_coefficient(double value) { + set_has_objective_coefficient(); + objective_coefficient_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPVariableProto.objective_coefficient) +} + +// optional bool is_integer = 4 [default = false]; +inline bool MPVariableProto::has_is_integer() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MPVariableProto::set_has_is_integer() { + _has_bits_[0] |= 0x00000008u; +} +inline void MPVariableProto::clear_has_is_integer() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MPVariableProto::clear_is_integer() { + is_integer_ = false; + clear_has_is_integer(); +} +inline bool MPVariableProto::is_integer() const { + // @@protoc_insertion_point(field_get:operations_research.MPVariableProto.is_integer) + return is_integer_; +} +inline void MPVariableProto::set_is_integer(bool value) { + set_has_is_integer(); + is_integer_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPVariableProto.is_integer) +} + +// optional string name = 5 [default = ""]; +inline bool MPVariableProto::has_name() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MPVariableProto::set_has_name() { + _has_bits_[0] |= 0x00000010u; +} +inline void MPVariableProto::clear_has_name() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MPVariableProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& MPVariableProto::name() const { + // @@protoc_insertion_point(field_get:operations_research.MPVariableProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MPVariableProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.MPVariableProto.name) +} +inline void MPVariableProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.MPVariableProto.name) +} +inline void MPVariableProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.MPVariableProto.name) +} +inline ::std::string* MPVariableProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:operations_research.MPVariableProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* MPVariableProto::release_name() { + // @@protoc_insertion_point(field_release:operations_research.MPVariableProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MPVariableProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.MPVariableProto.name) +} + +// ------------------------------------------------------------------- + +// MPConstraintProto + +// repeated int32 var_index = 6 [packed = true]; +inline int MPConstraintProto::var_index_size() const { + return var_index_.size(); +} +inline void MPConstraintProto::clear_var_index() { + var_index_.Clear(); +} +inline ::google::protobuf::int32 MPConstraintProto::var_index(int index) const { + // @@protoc_insertion_point(field_get:operations_research.MPConstraintProto.var_index) + return var_index_.Get(index); +} +inline void MPConstraintProto::set_var_index(int index, ::google::protobuf::int32 value) { + var_index_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.MPConstraintProto.var_index) +} +inline void MPConstraintProto::add_var_index(::google::protobuf::int32 value) { + var_index_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.MPConstraintProto.var_index) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +MPConstraintProto::var_index() const { + // @@protoc_insertion_point(field_list:operations_research.MPConstraintProto.var_index) + return var_index_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +MPConstraintProto::mutable_var_index() { + // @@protoc_insertion_point(field_mutable_list:operations_research.MPConstraintProto.var_index) + return &var_index_; +} + +// repeated double coefficient = 7 [packed = true]; +inline int MPConstraintProto::coefficient_size() const { + return coefficient_.size(); +} +inline void MPConstraintProto::clear_coefficient() { + coefficient_.Clear(); +} +inline double MPConstraintProto::coefficient(int index) const { + // @@protoc_insertion_point(field_get:operations_research.MPConstraintProto.coefficient) + return coefficient_.Get(index); +} +inline void MPConstraintProto::set_coefficient(int index, double value) { + coefficient_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.MPConstraintProto.coefficient) +} +inline void MPConstraintProto::add_coefficient(double value) { + coefficient_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.MPConstraintProto.coefficient) +} +inline const ::google::protobuf::RepeatedField< double >& +MPConstraintProto::coefficient() const { + // @@protoc_insertion_point(field_list:operations_research.MPConstraintProto.coefficient) + return coefficient_; +} +inline ::google::protobuf::RepeatedField< double >* +MPConstraintProto::mutable_coefficient() { + // @@protoc_insertion_point(field_mutable_list:operations_research.MPConstraintProto.coefficient) + return &coefficient_; +} + +// optional double lower_bound = 2 [default = -inf]; +inline bool MPConstraintProto::has_lower_bound() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MPConstraintProto::set_has_lower_bound() { + _has_bits_[0] |= 0x00000004u; +} +inline void MPConstraintProto::clear_has_lower_bound() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MPConstraintProto::clear_lower_bound() { + lower_bound_ = -::google::protobuf::internal::Infinity(); + clear_has_lower_bound(); +} +inline double MPConstraintProto::lower_bound() const { + // @@protoc_insertion_point(field_get:operations_research.MPConstraintProto.lower_bound) + return lower_bound_; +} +inline void MPConstraintProto::set_lower_bound(double value) { + set_has_lower_bound(); + lower_bound_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPConstraintProto.lower_bound) +} + +// optional double upper_bound = 3 [default = inf]; +inline bool MPConstraintProto::has_upper_bound() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MPConstraintProto::set_has_upper_bound() { + _has_bits_[0] |= 0x00000008u; +} +inline void MPConstraintProto::clear_has_upper_bound() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MPConstraintProto::clear_upper_bound() { + upper_bound_ = ::google::protobuf::internal::Infinity(); + clear_has_upper_bound(); +} +inline double MPConstraintProto::upper_bound() const { + // @@protoc_insertion_point(field_get:operations_research.MPConstraintProto.upper_bound) + return upper_bound_; +} +inline void MPConstraintProto::set_upper_bound(double value) { + set_has_upper_bound(); + upper_bound_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPConstraintProto.upper_bound) +} + +// optional string name = 4 [default = ""]; +inline bool MPConstraintProto::has_name() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MPConstraintProto::set_has_name() { + _has_bits_[0] |= 0x00000010u; +} +inline void MPConstraintProto::clear_has_name() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MPConstraintProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& MPConstraintProto::name() const { + // @@protoc_insertion_point(field_get:operations_research.MPConstraintProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MPConstraintProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.MPConstraintProto.name) +} +inline void MPConstraintProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.MPConstraintProto.name) +} +inline void MPConstraintProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.MPConstraintProto.name) +} +inline ::std::string* MPConstraintProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:operations_research.MPConstraintProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* MPConstraintProto::release_name() { + // @@protoc_insertion_point(field_release:operations_research.MPConstraintProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MPConstraintProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.MPConstraintProto.name) +} + +// optional bool is_lazy = 5 [default = false]; +inline bool MPConstraintProto::has_is_lazy() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void MPConstraintProto::set_has_is_lazy() { + _has_bits_[0] |= 0x00000020u; +} +inline void MPConstraintProto::clear_has_is_lazy() { + _has_bits_[0] &= ~0x00000020u; +} +inline void MPConstraintProto::clear_is_lazy() { + is_lazy_ = false; + clear_has_is_lazy(); +} +inline bool MPConstraintProto::is_lazy() const { + // @@protoc_insertion_point(field_get:operations_research.MPConstraintProto.is_lazy) + return is_lazy_; +} +inline void MPConstraintProto::set_is_lazy(bool value) { + set_has_is_lazy(); + is_lazy_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPConstraintProto.is_lazy) +} + +// ------------------------------------------------------------------- + +// PartialVariableAssignment + +// repeated int32 var_index = 1 [packed = true]; +inline int PartialVariableAssignment::var_index_size() const { + return var_index_.size(); +} +inline void PartialVariableAssignment::clear_var_index() { + var_index_.Clear(); +} +inline ::google::protobuf::int32 PartialVariableAssignment::var_index(int index) const { + // @@protoc_insertion_point(field_get:operations_research.PartialVariableAssignment.var_index) + return var_index_.Get(index); +} +inline void PartialVariableAssignment::set_var_index(int index, ::google::protobuf::int32 value) { + var_index_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.PartialVariableAssignment.var_index) +} +inline void PartialVariableAssignment::add_var_index(::google::protobuf::int32 value) { + var_index_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.PartialVariableAssignment.var_index) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +PartialVariableAssignment::var_index() const { + // @@protoc_insertion_point(field_list:operations_research.PartialVariableAssignment.var_index) + return var_index_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +PartialVariableAssignment::mutable_var_index() { + // @@protoc_insertion_point(field_mutable_list:operations_research.PartialVariableAssignment.var_index) + return &var_index_; +} + +// repeated double var_value = 2 [packed = true]; +inline int PartialVariableAssignment::var_value_size() const { + return var_value_.size(); +} +inline void PartialVariableAssignment::clear_var_value() { + var_value_.Clear(); +} +inline double PartialVariableAssignment::var_value(int index) const { + // @@protoc_insertion_point(field_get:operations_research.PartialVariableAssignment.var_value) + return var_value_.Get(index); +} +inline void PartialVariableAssignment::set_var_value(int index, double value) { + var_value_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.PartialVariableAssignment.var_value) +} +inline void PartialVariableAssignment::add_var_value(double value) { + var_value_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.PartialVariableAssignment.var_value) +} +inline const ::google::protobuf::RepeatedField< double >& +PartialVariableAssignment::var_value() const { + // @@protoc_insertion_point(field_list:operations_research.PartialVariableAssignment.var_value) + return var_value_; +} +inline ::google::protobuf::RepeatedField< double >* +PartialVariableAssignment::mutable_var_value() { + // @@protoc_insertion_point(field_mutable_list:operations_research.PartialVariableAssignment.var_value) + return &var_value_; +} + +// ------------------------------------------------------------------- + +// MPModelProto + +// optional bool maximize = 1 [default = false]; +inline bool MPModelProto::has_maximize() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MPModelProto::set_has_maximize() { + _has_bits_[0] |= 0x00000001u; +} +inline void MPModelProto::clear_has_maximize() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MPModelProto::clear_maximize() { + maximize_ = false; + clear_has_maximize(); +} +inline bool MPModelProto::maximize() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelProto.maximize) + return maximize_; +} +inline void MPModelProto::set_maximize(bool value) { + set_has_maximize(); + maximize_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPModelProto.maximize) +} + +// optional double objective_offset = 2 [default = 0]; +inline bool MPModelProto::has_objective_offset() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MPModelProto::set_has_objective_offset() { + _has_bits_[0] |= 0x00000002u; +} +inline void MPModelProto::clear_has_objective_offset() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MPModelProto::clear_objective_offset() { + objective_offset_ = 0; + clear_has_objective_offset(); +} +inline double MPModelProto::objective_offset() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelProto.objective_offset) + return objective_offset_; +} +inline void MPModelProto::set_objective_offset(double value) { + set_has_objective_offset(); + objective_offset_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPModelProto.objective_offset) +} + +// repeated .operations_research.MPVariableProto variable = 3; +inline int MPModelProto::variable_size() const { + return variable_.size(); +} +inline void MPModelProto::clear_variable() { + variable_.Clear(); +} +inline const ::operations_research::MPVariableProto& MPModelProto::variable(int index) const { + // @@protoc_insertion_point(field_get:operations_research.MPModelProto.variable) + return variable_.Get(index); +} +inline ::operations_research::MPVariableProto* MPModelProto::mutable_variable(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.MPModelProto.variable) + return variable_.Mutable(index); +} +inline ::operations_research::MPVariableProto* MPModelProto::add_variable() { + // @@protoc_insertion_point(field_add:operations_research.MPModelProto.variable) + return variable_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::MPVariableProto >* +MPModelProto::mutable_variable() { + // @@protoc_insertion_point(field_mutable_list:operations_research.MPModelProto.variable) + return &variable_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::MPVariableProto >& +MPModelProto::variable() const { + // @@protoc_insertion_point(field_list:operations_research.MPModelProto.variable) + return variable_; +} + +// repeated .operations_research.MPConstraintProto constraint = 4; +inline int MPModelProto::constraint_size() const { + return constraint_.size(); +} +inline void MPModelProto::clear_constraint() { + constraint_.Clear(); +} +inline const ::operations_research::MPConstraintProto& MPModelProto::constraint(int index) const { + // @@protoc_insertion_point(field_get:operations_research.MPModelProto.constraint) + return constraint_.Get(index); +} +inline ::operations_research::MPConstraintProto* MPModelProto::mutable_constraint(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.MPModelProto.constraint) + return constraint_.Mutable(index); +} +inline ::operations_research::MPConstraintProto* MPModelProto::add_constraint() { + // @@protoc_insertion_point(field_add:operations_research.MPModelProto.constraint) + return constraint_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::MPConstraintProto >* +MPModelProto::mutable_constraint() { + // @@protoc_insertion_point(field_mutable_list:operations_research.MPModelProto.constraint) + return &constraint_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::MPConstraintProto >& +MPModelProto::constraint() const { + // @@protoc_insertion_point(field_list:operations_research.MPModelProto.constraint) + return constraint_; +} + +// optional string name = 5 [default = ""]; +inline bool MPModelProto::has_name() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MPModelProto::set_has_name() { + _has_bits_[0] |= 0x00000010u; +} +inline void MPModelProto::clear_has_name() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MPModelProto::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& MPModelProto::name() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelProto.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MPModelProto::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.MPModelProto.name) +} +inline void MPModelProto::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.MPModelProto.name) +} +inline void MPModelProto::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.MPModelProto.name) +} +inline ::std::string* MPModelProto::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:operations_research.MPModelProto.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* MPModelProto::release_name() { + // @@protoc_insertion_point(field_release:operations_research.MPModelProto.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MPModelProto::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.MPModelProto.name) +} + +// optional .operations_research.PartialVariableAssignment solution_hint = 6; +inline bool MPModelProto::has_solution_hint() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void MPModelProto::set_has_solution_hint() { + _has_bits_[0] |= 0x00000020u; +} +inline void MPModelProto::clear_has_solution_hint() { + _has_bits_[0] &= ~0x00000020u; +} +inline void MPModelProto::clear_solution_hint() { + if (solution_hint_ != NULL) solution_hint_->::operations_research::PartialVariableAssignment::Clear(); + clear_has_solution_hint(); +} +inline const ::operations_research::PartialVariableAssignment& MPModelProto::solution_hint() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelProto.solution_hint) + return solution_hint_ != NULL ? *solution_hint_ : *default_instance_->solution_hint_; +} +inline ::operations_research::PartialVariableAssignment* MPModelProto::mutable_solution_hint() { + set_has_solution_hint(); + if (solution_hint_ == NULL) { + solution_hint_ = new ::operations_research::PartialVariableAssignment; + } + // @@protoc_insertion_point(field_mutable:operations_research.MPModelProto.solution_hint) + return solution_hint_; +} +inline ::operations_research::PartialVariableAssignment* MPModelProto::release_solution_hint() { + // @@protoc_insertion_point(field_release:operations_research.MPModelProto.solution_hint) + clear_has_solution_hint(); + ::operations_research::PartialVariableAssignment* temp = solution_hint_; + solution_hint_ = NULL; + return temp; +} +inline void MPModelProto::set_allocated_solution_hint(::operations_research::PartialVariableAssignment* solution_hint) { + delete solution_hint_; + solution_hint_ = solution_hint; + if (solution_hint) { + set_has_solution_hint(); + } else { + clear_has_solution_hint(); + } + // @@protoc_insertion_point(field_set_allocated:operations_research.MPModelProto.solution_hint) +} + +// ------------------------------------------------------------------- + +// OptionalDouble + +// optional double value = 1; +inline bool OptionalDouble::has_value() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void OptionalDouble::set_has_value() { + _has_bits_[0] |= 0x00000001u; +} +inline void OptionalDouble::clear_has_value() { + _has_bits_[0] &= ~0x00000001u; +} +inline void OptionalDouble::clear_value() { + value_ = 0; + clear_has_value(); +} +inline double OptionalDouble::value() const { + // @@protoc_insertion_point(field_get:operations_research.OptionalDouble.value) + return value_; +} +inline void OptionalDouble::set_value(double value) { + set_has_value(); + value_ = value; + // @@protoc_insertion_point(field_set:operations_research.OptionalDouble.value) +} + +// ------------------------------------------------------------------- + +// MPSolverCommonParameters + +// optional .operations_research.OptionalDouble relative_mip_gap = 1; +inline bool MPSolverCommonParameters::has_relative_mip_gap() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MPSolverCommonParameters::set_has_relative_mip_gap() { + _has_bits_[0] |= 0x00000001u; +} +inline void MPSolverCommonParameters::clear_has_relative_mip_gap() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MPSolverCommonParameters::clear_relative_mip_gap() { + if (relative_mip_gap_ != NULL) relative_mip_gap_->::operations_research::OptionalDouble::Clear(); + clear_has_relative_mip_gap(); +} +inline const ::operations_research::OptionalDouble& MPSolverCommonParameters::relative_mip_gap() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolverCommonParameters.relative_mip_gap) + return relative_mip_gap_ != NULL ? *relative_mip_gap_ : *default_instance_->relative_mip_gap_; +} +inline ::operations_research::OptionalDouble* MPSolverCommonParameters::mutable_relative_mip_gap() { + set_has_relative_mip_gap(); + if (relative_mip_gap_ == NULL) { + relative_mip_gap_ = new ::operations_research::OptionalDouble; + } + // @@protoc_insertion_point(field_mutable:operations_research.MPSolverCommonParameters.relative_mip_gap) + return relative_mip_gap_; +} +inline ::operations_research::OptionalDouble* MPSolverCommonParameters::release_relative_mip_gap() { + // @@protoc_insertion_point(field_release:operations_research.MPSolverCommonParameters.relative_mip_gap) + clear_has_relative_mip_gap(); + ::operations_research::OptionalDouble* temp = relative_mip_gap_; + relative_mip_gap_ = NULL; + return temp; +} +inline void MPSolverCommonParameters::set_allocated_relative_mip_gap(::operations_research::OptionalDouble* relative_mip_gap) { + delete relative_mip_gap_; + relative_mip_gap_ = relative_mip_gap; + if (relative_mip_gap) { + set_has_relative_mip_gap(); + } else { + clear_has_relative_mip_gap(); + } + // @@protoc_insertion_point(field_set_allocated:operations_research.MPSolverCommonParameters.relative_mip_gap) +} + +// optional .operations_research.OptionalDouble primal_tolerance = 2; +inline bool MPSolverCommonParameters::has_primal_tolerance() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MPSolverCommonParameters::set_has_primal_tolerance() { + _has_bits_[0] |= 0x00000002u; +} +inline void MPSolverCommonParameters::clear_has_primal_tolerance() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MPSolverCommonParameters::clear_primal_tolerance() { + if (primal_tolerance_ != NULL) primal_tolerance_->::operations_research::OptionalDouble::Clear(); + clear_has_primal_tolerance(); +} +inline const ::operations_research::OptionalDouble& MPSolverCommonParameters::primal_tolerance() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolverCommonParameters.primal_tolerance) + return primal_tolerance_ != NULL ? *primal_tolerance_ : *default_instance_->primal_tolerance_; +} +inline ::operations_research::OptionalDouble* MPSolverCommonParameters::mutable_primal_tolerance() { + set_has_primal_tolerance(); + if (primal_tolerance_ == NULL) { + primal_tolerance_ = new ::operations_research::OptionalDouble; + } + // @@protoc_insertion_point(field_mutable:operations_research.MPSolverCommonParameters.primal_tolerance) + return primal_tolerance_; +} +inline ::operations_research::OptionalDouble* MPSolverCommonParameters::release_primal_tolerance() { + // @@protoc_insertion_point(field_release:operations_research.MPSolverCommonParameters.primal_tolerance) + clear_has_primal_tolerance(); + ::operations_research::OptionalDouble* temp = primal_tolerance_; + primal_tolerance_ = NULL; + return temp; +} +inline void MPSolverCommonParameters::set_allocated_primal_tolerance(::operations_research::OptionalDouble* primal_tolerance) { + delete primal_tolerance_; + primal_tolerance_ = primal_tolerance; + if (primal_tolerance) { + set_has_primal_tolerance(); + } else { + clear_has_primal_tolerance(); + } + // @@protoc_insertion_point(field_set_allocated:operations_research.MPSolverCommonParameters.primal_tolerance) +} + +// optional .operations_research.OptionalDouble dual_tolerance = 3; +inline bool MPSolverCommonParameters::has_dual_tolerance() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MPSolverCommonParameters::set_has_dual_tolerance() { + _has_bits_[0] |= 0x00000004u; +} +inline void MPSolverCommonParameters::clear_has_dual_tolerance() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MPSolverCommonParameters::clear_dual_tolerance() { + if (dual_tolerance_ != NULL) dual_tolerance_->::operations_research::OptionalDouble::Clear(); + clear_has_dual_tolerance(); +} +inline const ::operations_research::OptionalDouble& MPSolverCommonParameters::dual_tolerance() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolverCommonParameters.dual_tolerance) + return dual_tolerance_ != NULL ? *dual_tolerance_ : *default_instance_->dual_tolerance_; +} +inline ::operations_research::OptionalDouble* MPSolverCommonParameters::mutable_dual_tolerance() { + set_has_dual_tolerance(); + if (dual_tolerance_ == NULL) { + dual_tolerance_ = new ::operations_research::OptionalDouble; + } + // @@protoc_insertion_point(field_mutable:operations_research.MPSolverCommonParameters.dual_tolerance) + return dual_tolerance_; +} +inline ::operations_research::OptionalDouble* MPSolverCommonParameters::release_dual_tolerance() { + // @@protoc_insertion_point(field_release:operations_research.MPSolverCommonParameters.dual_tolerance) + clear_has_dual_tolerance(); + ::operations_research::OptionalDouble* temp = dual_tolerance_; + dual_tolerance_ = NULL; + return temp; +} +inline void MPSolverCommonParameters::set_allocated_dual_tolerance(::operations_research::OptionalDouble* dual_tolerance) { + delete dual_tolerance_; + dual_tolerance_ = dual_tolerance; + if (dual_tolerance) { + set_has_dual_tolerance(); + } else { + clear_has_dual_tolerance(); + } + // @@protoc_insertion_point(field_set_allocated:operations_research.MPSolverCommonParameters.dual_tolerance) +} + +// optional .operations_research.MPSolverCommonParameters.LPAlgorithmValues lp_algorithm = 4 [default = LP_ALGO_UNSPECIFIED]; +inline bool MPSolverCommonParameters::has_lp_algorithm() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MPSolverCommonParameters::set_has_lp_algorithm() { + _has_bits_[0] |= 0x00000008u; +} +inline void MPSolverCommonParameters::clear_has_lp_algorithm() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MPSolverCommonParameters::clear_lp_algorithm() { + lp_algorithm_ = 0; + clear_has_lp_algorithm(); +} +inline ::operations_research::MPSolverCommonParameters_LPAlgorithmValues MPSolverCommonParameters::lp_algorithm() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolverCommonParameters.lp_algorithm) + return static_cast< ::operations_research::MPSolverCommonParameters_LPAlgorithmValues >(lp_algorithm_); +} +inline void MPSolverCommonParameters::set_lp_algorithm(::operations_research::MPSolverCommonParameters_LPAlgorithmValues value) { + assert(::operations_research::MPSolverCommonParameters_LPAlgorithmValues_IsValid(value)); + set_has_lp_algorithm(); + lp_algorithm_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPSolverCommonParameters.lp_algorithm) +} + +// optional .operations_research.OptionalBoolean presolve = 5 [default = BOOL_UNSPECIFIED]; +inline bool MPSolverCommonParameters::has_presolve() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MPSolverCommonParameters::set_has_presolve() { + _has_bits_[0] |= 0x00000010u; +} +inline void MPSolverCommonParameters::clear_has_presolve() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MPSolverCommonParameters::clear_presolve() { + presolve_ = 0; + clear_has_presolve(); +} +inline ::operations_research::OptionalBoolean MPSolverCommonParameters::presolve() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolverCommonParameters.presolve) + return static_cast< ::operations_research::OptionalBoolean >(presolve_); +} +inline void MPSolverCommonParameters::set_presolve(::operations_research::OptionalBoolean value) { + assert(::operations_research::OptionalBoolean_IsValid(value)); + set_has_presolve(); + presolve_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPSolverCommonParameters.presolve) +} + +// optional .operations_research.OptionalBoolean scaling = 7 [default = BOOL_UNSPECIFIED]; +inline bool MPSolverCommonParameters::has_scaling() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void MPSolverCommonParameters::set_has_scaling() { + _has_bits_[0] |= 0x00000020u; +} +inline void MPSolverCommonParameters::clear_has_scaling() { + _has_bits_[0] &= ~0x00000020u; +} +inline void MPSolverCommonParameters::clear_scaling() { + scaling_ = 0; + clear_has_scaling(); +} +inline ::operations_research::OptionalBoolean MPSolverCommonParameters::scaling() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolverCommonParameters.scaling) + return static_cast< ::operations_research::OptionalBoolean >(scaling_); +} +inline void MPSolverCommonParameters::set_scaling(::operations_research::OptionalBoolean value) { + assert(::operations_research::OptionalBoolean_IsValid(value)); + set_has_scaling(); + scaling_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPSolverCommonParameters.scaling) +} + +// ------------------------------------------------------------------- + +// MPModelRequest + +// optional .operations_research.MPModelProto model = 1; +inline bool MPModelRequest::has_model() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MPModelRequest::set_has_model() { + _has_bits_[0] |= 0x00000001u; +} +inline void MPModelRequest::clear_has_model() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MPModelRequest::clear_model() { + if (model_ != NULL) model_->::operations_research::MPModelProto::Clear(); + clear_has_model(); +} +inline const ::operations_research::MPModelProto& MPModelRequest::model() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelRequest.model) + return model_ != NULL ? *model_ : *default_instance_->model_; +} +inline ::operations_research::MPModelProto* MPModelRequest::mutable_model() { + set_has_model(); + if (model_ == NULL) { + model_ = new ::operations_research::MPModelProto; + } + // @@protoc_insertion_point(field_mutable:operations_research.MPModelRequest.model) + return model_; +} +inline ::operations_research::MPModelProto* MPModelRequest::release_model() { + // @@protoc_insertion_point(field_release:operations_research.MPModelRequest.model) + clear_has_model(); + ::operations_research::MPModelProto* temp = model_; + model_ = NULL; + return temp; +} +inline void MPModelRequest::set_allocated_model(::operations_research::MPModelProto* model) { + delete model_; + model_ = model; + if (model) { + set_has_model(); + } else { + clear_has_model(); + } + // @@protoc_insertion_point(field_set_allocated:operations_research.MPModelRequest.model) +} + +// optional .operations_research.MPModelRequest.SolverType solver_type = 2; +inline bool MPModelRequest::has_solver_type() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MPModelRequest::set_has_solver_type() { + _has_bits_[0] |= 0x00000002u; +} +inline void MPModelRequest::clear_has_solver_type() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MPModelRequest::clear_solver_type() { + solver_type_ = 2; + clear_has_solver_type(); +} +inline ::operations_research::MPModelRequest_SolverType MPModelRequest::solver_type() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelRequest.solver_type) + return static_cast< ::operations_research::MPModelRequest_SolverType >(solver_type_); +} +inline void MPModelRequest::set_solver_type(::operations_research::MPModelRequest_SolverType value) { + assert(::operations_research::MPModelRequest_SolverType_IsValid(value)); + set_has_solver_type(); + solver_type_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPModelRequest.solver_type) +} + +// optional double solver_time_limit_seconds = 3; +inline bool MPModelRequest::has_solver_time_limit_seconds() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MPModelRequest::set_has_solver_time_limit_seconds() { + _has_bits_[0] |= 0x00000004u; +} +inline void MPModelRequest::clear_has_solver_time_limit_seconds() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MPModelRequest::clear_solver_time_limit_seconds() { + solver_time_limit_seconds_ = 0; + clear_has_solver_time_limit_seconds(); +} +inline double MPModelRequest::solver_time_limit_seconds() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelRequest.solver_time_limit_seconds) + return solver_time_limit_seconds_; +} +inline void MPModelRequest::set_solver_time_limit_seconds(double value) { + set_has_solver_time_limit_seconds(); + solver_time_limit_seconds_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPModelRequest.solver_time_limit_seconds) +} + +// optional bool enable_internal_solver_output = 4 [default = false]; +inline bool MPModelRequest::has_enable_internal_solver_output() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MPModelRequest::set_has_enable_internal_solver_output() { + _has_bits_[0] |= 0x00000008u; +} +inline void MPModelRequest::clear_has_enable_internal_solver_output() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MPModelRequest::clear_enable_internal_solver_output() { + enable_internal_solver_output_ = false; + clear_has_enable_internal_solver_output(); +} +inline bool MPModelRequest::enable_internal_solver_output() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelRequest.enable_internal_solver_output) + return enable_internal_solver_output_; +} +inline void MPModelRequest::set_enable_internal_solver_output(bool value) { + set_has_enable_internal_solver_output(); + enable_internal_solver_output_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPModelRequest.enable_internal_solver_output) +} + +// optional string solver_specific_parameters = 5; +inline bool MPModelRequest::has_solver_specific_parameters() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MPModelRequest::set_has_solver_specific_parameters() { + _has_bits_[0] |= 0x00000010u; +} +inline void MPModelRequest::clear_has_solver_specific_parameters() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MPModelRequest::clear_solver_specific_parameters() { + solver_specific_parameters_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_solver_specific_parameters(); +} +inline const ::std::string& MPModelRequest::solver_specific_parameters() const { + // @@protoc_insertion_point(field_get:operations_research.MPModelRequest.solver_specific_parameters) + return solver_specific_parameters_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MPModelRequest::set_solver_specific_parameters(const ::std::string& value) { + set_has_solver_specific_parameters(); + solver_specific_parameters_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.MPModelRequest.solver_specific_parameters) +} +inline void MPModelRequest::set_solver_specific_parameters(const char* value) { + set_has_solver_specific_parameters(); + solver_specific_parameters_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.MPModelRequest.solver_specific_parameters) +} +inline void MPModelRequest::set_solver_specific_parameters(const char* value, size_t size) { + set_has_solver_specific_parameters(); + solver_specific_parameters_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.MPModelRequest.solver_specific_parameters) +} +inline ::std::string* MPModelRequest::mutable_solver_specific_parameters() { + set_has_solver_specific_parameters(); + // @@protoc_insertion_point(field_mutable:operations_research.MPModelRequest.solver_specific_parameters) + return solver_specific_parameters_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* MPModelRequest::release_solver_specific_parameters() { + // @@protoc_insertion_point(field_release:operations_research.MPModelRequest.solver_specific_parameters) + clear_has_solver_specific_parameters(); + return solver_specific_parameters_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MPModelRequest::set_allocated_solver_specific_parameters(::std::string* solver_specific_parameters) { + if (solver_specific_parameters != NULL) { + set_has_solver_specific_parameters(); + } else { + clear_has_solver_specific_parameters(); + } + solver_specific_parameters_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), solver_specific_parameters); + // @@protoc_insertion_point(field_set_allocated:operations_research.MPModelRequest.solver_specific_parameters) +} + +// ------------------------------------------------------------------- + +// MPSolutionResponse + +// optional .operations_research.MPSolverResponseStatus status = 1 [default = MPSOLVER_UNKNOWN_STATUS]; +inline bool MPSolutionResponse::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MPSolutionResponse::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void MPSolutionResponse::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MPSolutionResponse::clear_status() { + status_ = 99; + clear_has_status(); +} +inline ::operations_research::MPSolverResponseStatus MPSolutionResponse::status() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolutionResponse.status) + return static_cast< ::operations_research::MPSolverResponseStatus >(status_); +} +inline void MPSolutionResponse::set_status(::operations_research::MPSolverResponseStatus value) { + assert(::operations_research::MPSolverResponseStatus_IsValid(value)); + set_has_status(); + status_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPSolutionResponse.status) +} + +// optional double objective_value = 2; +inline bool MPSolutionResponse::has_objective_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MPSolutionResponse::set_has_objective_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void MPSolutionResponse::clear_has_objective_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MPSolutionResponse::clear_objective_value() { + objective_value_ = 0; + clear_has_objective_value(); +} +inline double MPSolutionResponse::objective_value() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolutionResponse.objective_value) + return objective_value_; +} +inline void MPSolutionResponse::set_objective_value(double value) { + set_has_objective_value(); + objective_value_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPSolutionResponse.objective_value) +} + +// optional double best_objective_bound = 5; +inline bool MPSolutionResponse::has_best_objective_bound() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MPSolutionResponse::set_has_best_objective_bound() { + _has_bits_[0] |= 0x00000004u; +} +inline void MPSolutionResponse::clear_has_best_objective_bound() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MPSolutionResponse::clear_best_objective_bound() { + best_objective_bound_ = 0; + clear_has_best_objective_bound(); +} +inline double MPSolutionResponse::best_objective_bound() const { + // @@protoc_insertion_point(field_get:operations_research.MPSolutionResponse.best_objective_bound) + return best_objective_bound_; +} +inline void MPSolutionResponse::set_best_objective_bound(double value) { + set_has_best_objective_bound(); + best_objective_bound_ = value; + // @@protoc_insertion_point(field_set:operations_research.MPSolutionResponse.best_objective_bound) +} + +// repeated double variable_value = 3 [packed = true]; +inline int MPSolutionResponse::variable_value_size() const { + return variable_value_.size(); +} +inline void MPSolutionResponse::clear_variable_value() { + variable_value_.Clear(); +} +inline double MPSolutionResponse::variable_value(int index) const { + // @@protoc_insertion_point(field_get:operations_research.MPSolutionResponse.variable_value) + return variable_value_.Get(index); +} +inline void MPSolutionResponse::set_variable_value(int index, double value) { + variable_value_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.MPSolutionResponse.variable_value) +} +inline void MPSolutionResponse::add_variable_value(double value) { + variable_value_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.MPSolutionResponse.variable_value) +} +inline const ::google::protobuf::RepeatedField< double >& +MPSolutionResponse::variable_value() const { + // @@protoc_insertion_point(field_list:operations_research.MPSolutionResponse.variable_value) + return variable_value_; +} +inline ::google::protobuf::RepeatedField< double >* +MPSolutionResponse::mutable_variable_value() { + // @@protoc_insertion_point(field_mutable_list:operations_research.MPSolutionResponse.variable_value) + return &variable_value_; +} + +// repeated double dual_value = 4 [packed = true]; +inline int MPSolutionResponse::dual_value_size() const { + return dual_value_.size(); +} +inline void MPSolutionResponse::clear_dual_value() { + dual_value_.Clear(); +} +inline double MPSolutionResponse::dual_value(int index) const { + // @@protoc_insertion_point(field_get:operations_research.MPSolutionResponse.dual_value) + return dual_value_.Get(index); +} +inline void MPSolutionResponse::set_dual_value(int index, double value) { + dual_value_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.MPSolutionResponse.dual_value) +} +inline void MPSolutionResponse::add_dual_value(double value) { + dual_value_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.MPSolutionResponse.dual_value) +} +inline const ::google::protobuf::RepeatedField< double >& +MPSolutionResponse::dual_value() const { + // @@protoc_insertion_point(field_list:operations_research.MPSolutionResponse.dual_value) + return dual_value_; +} +inline ::google::protobuf::RepeatedField< double >* +MPSolutionResponse::mutable_dual_value() { + // @@protoc_insertion_point(field_mutable_list:operations_research.MPSolutionResponse.dual_value) + return &dual_value_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::operations_research::MPSolverCommonParameters_LPAlgorithmValues> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::MPSolverCommonParameters_LPAlgorithmValues>() { + return ::operations_research::MPSolverCommonParameters_LPAlgorithmValues_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::MPModelRequest_SolverType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::MPModelRequest_SolverType>() { + return ::operations_research::MPModelRequest_SolverType_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::OptionalBoolean> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::OptionalBoolean>() { + return ::operations_research::OptionalBoolean_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::MPSolverResponseStatus> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::MPSolverResponseStatus>() { + return ::operations_research::MPSolverResponseStatus_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2flinear_5fsolver_2flinear_5fsolver_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/linear_solver/model_exporter.h b/thirdparty/linux/include/ortools/linear_solver/model_exporter.h new file mode 100644 index 0000000..b572dd6 --- /dev/null +++ b/thirdparty/linux/include/ortools/linear_solver/model_exporter.h @@ -0,0 +1,203 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_LINEAR_SOLVER_MODEL_EXPORTER_H_ +#define OR_TOOLS_LINEAR_SOLVER_MODEL_EXPORTER_H_ + +#include +#include +#include "ortools/base/macros.h" +#include "ortools/base/hash.h" + +namespace operations_research { + +class MPConstraint; +class MPObjective; +class MPVariable; + +class MPModelProto; + +class MPModelProtoExporter { + public: + // The argument must live as long as this class is active. + explicit MPModelProtoExporter(const MPModelProto& proto); + + // Outputs the current model (variables, constraints, objective) as a std::string + // encoded in the so-called "CPLEX LP file format" as generated by SCIP. + // The LP file format is easily readable by a human. + // + // Returns false if some error has occurred during execution. + // The validity of names is automatically checked. If a variable name or a + // constraint name is invalid or non-existent, a new valid name is + // automatically generated. + // + // If 'obfuscated' is true, the variable and constraint names of proto_ + // are not used. Variable and constraint names of the form "V12345" + // and "C12345" are used instead. + // + // For more information about the different LP file formats: + // http://lpsolve.sourceforge.net/5.5/lp-format.htm + // The following give a reasonable idea of the CPLEX LP file format: + // http://lpsolve.sourceforge.net/5.5/CPLEX-format.htm + // http://tinyurl.com/cplex-lp-format + // http://www.gurobi.com/documentation/5.1/reference-manual/node871 + bool ExportModelAsLpFormat(bool obfuscated, std::string* model_str); + + // Outputs the current model (variables, constraints, objective) as a std::string + // encoded in MPS file format, using the "fixed" MPS format if possible, + // and the "free" MPS format otherwise. + // + // Returns false if some error has occurred during execution. + // + // If fixed_format is true, the method tries to use the MPS fixed format (the + // use of which is discouraged as coefficients are printed with less + // precision). If it is not possible to use the fixed format, the method falls + // back to the so-called "free format". + // + // The validity of names is automatically checked. If a variable name or a + // constraint name is invalid or non-existent, a new valid name is + // automatically generated. + // + // Name validity and obfuscation works exactly as in ExportModelAsLpFormat(). + // + // For more information about the MPS format: + // http://en.wikipedia.org/wiki/MPS_(format) + // A close-to-original description coming from OSL: + // http://tinyurl.com/mps-format-by-osl + // A recent description from CPLEX: + // http://tinyurl.com/mps-format-by-cplex + // CPLEX extensions: + // http://tinyurl.com/mps-extensions-by-cplex + // Gurobi's description: + // http://www.gurobi.com/documentation/5.1/reference-manual/node869 + bool ExportModelAsMpsFormat(bool fixed_format, bool obfuscated, + std::string* model_str); + + private: + // Computes the number of continuous, integer and binary variables. + // Called by ExportModelAsLpFormat() and ExportModelAsMpsFormat(). + void Setup(); + + // Processes all the proto.name() fields and returns the result in a vector. + // + // If 'obfuscate' is true, none of names are actually used, and this just + // returns a vector of 'prefix' + proto index (1-based). + // + // If it is false, this tries to keep the original names, but: + // - if the first character is forbidden, '_' is added at the beginning of + // name. + // - all the other forbidden characters are replaced by '_'. + // To avoid name conflicts, a '_' followed by an integer is appended to the + // result. + // + // If a name is longer than the maximum allowed name length, the obfuscated + // name is used. + // + // This method also sets use_fixed_mps_format_ to false if one name is too + // long. + // + // Therefore, a name "$20<=40" for proto #3 could be "_$20__40_1". + template + std::vector ExtractAndProcessNames( + const ListOfProtosWithNameFields& proto, const std::string& prefix, + bool obfuscate); + + // Returns true when the fixed MPS format can be used. + // The fixed format is used when the variable and constraint names do not + // exceed 8 characters. In the case of an obfuscated file, this means that + // the maximum number of digits for constraints and variables is limited to 7. + bool CanUseFixedMpsFormat() const; + + // Appends a general "Comment" section with useful metadata about the model + // to "output". + // Note(user): there may be less variables in output than in the original + // model, as unused variables are not shown by default. Similarly, there + // may be more constraints in a .lp file as in the original model as + // a constraint lhs <= term <= rhs will be output as the two constraints + // term >= lhs and term <= rhs. + void AppendComments(const std::string& separator, std::string* output) const; + + // Clears "output" and writes a term to it, in "Lp" format. Returns false on + // error (for example, var_index is out of range). + bool WriteLpTerm(int var_index, double coefficient, std::string* output) const; + + // Appends a pair name, value to "output", formatted to comply with the MPS + // standard. + void AppendMpsPair(const std::string& name, double value, std::string* output) const; + + // Appends the head of a line, consisting of an id and a name to output. + void AppendMpsLineHeader(const std::string& id, const std::string& name, + std::string* output) const; + + // Same as AppendMpsLineHeader. Appends an extra new-line at the end the + // std::string pointed to by output. + void AppendMpsLineHeaderWithNewLine(const std::string& id, const std::string& name, + std::string* output) const; + + // Appends an MPS term in various contexts. The term consists of a head name, + // a name, and a value. If the line is not empty, then only the pair + // (name, value) is appended. The number of columns, limited to 2 by the MPS + // format is also taken care of. + void AppendMpsTermWithContext(const std::string& head_name, const std::string& name, + double value, std::string* output); + + // Appends a new-line if two columns are already present on the MPS line. + // Used by and in complement to AppendMpsTermWithContext. + void AppendNewLineIfTwoColumns(std::string* output); + + // When 'integrality' is true, appends columns corresponding to integer + // variables. Appends the columns for non-integer variables otherwise. + // The sparse matrix must be passed as a vector of columns ('transpose'). + void AppendMpsColumns( + bool integrality, + const std::vector>>& transpose, + std::string* output); + + // Appends a line describing the bound of a variablenew-line if two columns + // are already present on the MPS line. + // Used by and in complement to AppendMpsTermWithContext. + void AppendMpsBound(const std::string& bound_type, const std::string& name, + double value, std::string* output) const; + + const MPModelProto& proto_; + + // Vector of variable names as they will be exported. + std::vector exported_variable_names_; + + // Vector of constraint names as they will be exported. + std::vector exported_constraint_names_; + + // Number of integer variables in proto_. + int num_integer_variables_; + + // Number of binary variables in proto_. + int num_binary_variables_; + + // Number of continuous variables in proto_. + int num_continuous_variables_; + + // Current MPS file column number. + int current_mps_column_; + + // True is the fixed MPS format shall be used. + bool use_fixed_mps_format_; + + // True if the variable and constraint names will be obfuscated. + bool use_obfuscated_names_; + + DISALLOW_COPY_AND_ASSIGN(MPModelProtoExporter); +}; + +} // namespace operations_research + +#endif // OR_TOOLS_LINEAR_SOLVER_MODEL_EXPORTER_H_ diff --git a/thirdparty/linux/include/ortools/linear_solver/model_validator.h b/thirdparty/linux/include/ortools/linear_solver/model_validator.h new file mode 100644 index 0000000..02863c1 --- /dev/null +++ b/thirdparty/linux/include/ortools/linear_solver/model_validator.h @@ -0,0 +1,43 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_LINEAR_SOLVER_MODEL_VALIDATOR_H_ +#define OR_TOOLS_LINEAR_SOLVER_MODEL_VALIDATOR_H_ + +#include +#include "ortools/linear_solver/linear_solver.pb.h" + +namespace operations_research { +// Returns an empty std::string iff the model is valid and not trivially infeasible. +// Otherwise, returns a description of the first error or trivial infeasibility +// encountered. +// +// NOTE(user): the code of this method (and the client code too!) is +// considerably simplified by this std::string-based, simple API. If clients +// require it, we could add a formal error status enum. +std::string FindErrorInMPModelProto(const MPModelProto& model); + +// Returns an empty std::string if the solution hint given in the model is a feasible +// solution. Otherwise, returns a description of the first reason for +// infeasibility. +// +// This function can be useful for debugging/checking that the given solution +// hint is feasible when it is expected to be the case. The feasibility is +// checked up to the given tolerance using the +// ::operations_research::IsLowerWithinTolerance() function. +std::string FindFeasibilityErrorInSolutionHint(const MPModelProto& model, + double tolerance); + +} // namespace operations_research + +#endif // OR_TOOLS_LINEAR_SOLVER_MODEL_VALIDATOR_H_ diff --git a/thirdparty/linux/include/ortools/sat/boolean_problem.h b/thirdparty/linux/include/ortools/sat/boolean_problem.h new file mode 100644 index 0000000..8ab4325 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/boolean_problem.h @@ -0,0 +1,132 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_BOOLEAN_PROBLEM_H_ +#define OR_TOOLS_SAT_BOOLEAN_PROBLEM_H_ + +#include "ortools/algorithms/sparse_permutation.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/sat/simplification.h" +#include "ortools/base/status.h" + +namespace operations_research { +namespace sat { + +// Adds the offset and returns the scaled version of the given objective value. +inline double AddOffsetAndScaleObjectiveValue( + const LinearBooleanProblem& problem, Coefficient v) { + return (static_cast(v.value()) + problem.objective().offset()) * + problem.objective().scaling_factor(); +} + +// Keeps the same objective but change the optimization direction from a +// minimization problem to a maximization problem. +// +// Ex: if the problem was to minimize 2 + x, the new problem will be to maximize +// 2 + x subject to exactly the same constraints. +void ChangeOptimizationDirection(LinearBooleanProblem* problem); + +// Copies the assignment from the solver into the given Boolean vector. Note +// that variables with a greater index that the given num_variables are ignored. +void ExtractAssignment(const LinearBooleanProblem& problem, + const SatSolver& solver, std::vector* assignment); + +// Tests the preconditions of the given problem (as described in the proto) and +// returns an error if they are not all satisfied. +util::Status ValidateBooleanProblem(const LinearBooleanProblem& problem); + +// Loads a BooleanProblem into a given SatSolver instance. +bool LoadBooleanProblem(const LinearBooleanProblem& problem, SatSolver* solver); + +// Same as LoadBooleanProblem() but also free the memory used by the problem +// during the loading. This allows to use less peak memory. Note that this +// function clear all the constraints of the given problem (not the objective +// though). +bool LoadAndConsumeBooleanProblem(LinearBooleanProblem* problem, + SatSolver* solver); + +// Uses the objective coefficient to drive the SAT search towards an +// heuristically better solution. +void UseObjectiveForSatAssignmentPreference(const LinearBooleanProblem& problem, + SatSolver* solver); + +// Adds the constraint that the objective is smaller than the given upper bound. +bool AddObjectiveUpperBound(const LinearBooleanProblem& problem, + Coefficient upper_bound, SatSolver* solver); + +// Adds the constraint that the objective is smaller or equals to the given +// upper bound. +bool AddObjectiveConstraint(const LinearBooleanProblem& problem, + bool use_lower_bound, Coefficient lower_bound, + bool use_upper_bound, Coefficient upper_bound, + SatSolver* solver); + +// Returns the objective value under the current assignment. +Coefficient ComputeObjectiveValue(const LinearBooleanProblem& problem, + const std::vector& assignment); + +// Checks that an assignment is valid for the given BooleanProblem. +bool IsAssignmentValid(const LinearBooleanProblem& problem, + const std::vector& assignment); + +// Converts a LinearBooleanProblem to the cnf file format. +// Note that this only works for pure SAT problems (only clauses), max-sat or +// weighted max-sat problems. Returns an empty std::string on error. +std::string LinearBooleanProblemToCnfString(const LinearBooleanProblem& problem); + +// Store a variable assignment into the given BooleanAssignement proto. +// Note that only the assigned variables are stored, so the assignment may be +// incomplete. +void StoreAssignment(const VariablesAssignment& assignment, + BooleanAssignment* output); + +// Constructs a sub-problem formed by the constraints with given indices. +void ExtractSubproblem(const LinearBooleanProblem& problem, + const std::vector& constraint_indices, + LinearBooleanProblem* subproblem); + +// Modifies the given LinearBooleanProblem so that all the literals appearing +// inside are positive. +void MakeAllLiteralsPositive(LinearBooleanProblem* problem); + +// Returns a list of generators of the symmetry group of the given problem. Each +// generator is a permutation of the integer range [0, 2n) where n is the number +// of variables of the problem. They are permutations of the (index +// representation of the) problem literals. +void FindLinearBooleanProblemSymmetries( + const LinearBooleanProblem& problem, + std::vector>* generators); + +// Maps all the literals of the problem. Note that this converts the cost of a +// variable correctly, that is if a variable with cost is mapped to another, the +// cost of the later is updated. +// +// Preconditions: the mapping must map l and not(l) to the same variable and be +// of the correct size. It can also map a literal index to kTrueLiteralIndex +// or kFalseLiteralIndex in order to fix the variable. +void ApplyLiteralMappingToBooleanProblem( + const ITIVector& mapping, + LinearBooleanProblem* problem); + +// A simple preprocessing step that does basic probing and removes the fixed and +// equivalent variables. Note that the variable indices will also be remapped in +// order to be dense. The given postsolver will be updated with the information +// needed during postsolve. +void ProbeAndSimplifyProblem(SatPostsolver* postsolver, + LinearBooleanProblem* problem); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_BOOLEAN_PROBLEM_H_ diff --git a/thirdparty/linux/include/ortools/sat/boolean_problem.pb.h b/thirdparty/linux/include/ortools/sat/boolean_problem.pb.h new file mode 100644 index 0000000..08e3c03 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/boolean_problem.pb.h @@ -0,0 +1,1194 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/sat/boolean_problem.proto + +#ifndef PROTOBUF_ortools_2fsat_2fboolean_5fproblem_2eproto__INCLUDED +#define PROTOBUF_ortools_2fsat_2fboolean_5fproblem_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); +void protobuf_AssignDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); +void protobuf_ShutdownFile_ortools_2fsat_2fboolean_5fproblem_2eproto(); + +class BooleanAssignment; +class LinearBooleanConstraint; +class LinearBooleanProblem; +class LinearObjective; + +// =================================================================== + +class LinearBooleanConstraint : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.LinearBooleanConstraint) */ { + public: + LinearBooleanConstraint(); + virtual ~LinearBooleanConstraint(); + + LinearBooleanConstraint(const LinearBooleanConstraint& from); + + inline LinearBooleanConstraint& operator=(const LinearBooleanConstraint& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const LinearBooleanConstraint& default_instance(); + + void Swap(LinearBooleanConstraint* other); + + // implements Message ---------------------------------------------- + + inline LinearBooleanConstraint* New() const { return New(NULL); } + + LinearBooleanConstraint* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const LinearBooleanConstraint& from); + void MergeFrom(const LinearBooleanConstraint& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(LinearBooleanConstraint* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 literals = 1; + int literals_size() const; + void clear_literals(); + static const int kLiteralsFieldNumber = 1; + ::google::protobuf::int32 literals(int index) const; + void set_literals(int index, ::google::protobuf::int32 value); + void add_literals(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + literals() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_literals(); + + // repeated int64 coefficients = 2; + int coefficients_size() const; + void clear_coefficients(); + static const int kCoefficientsFieldNumber = 2; + ::google::protobuf::int64 coefficients(int index) const; + void set_coefficients(int index, ::google::protobuf::int64 value); + void add_coefficients(::google::protobuf::int64 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& + coefficients() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* + mutable_coefficients(); + + // optional int64 lower_bound = 3; + bool has_lower_bound() const; + void clear_lower_bound(); + static const int kLowerBoundFieldNumber = 3; + ::google::protobuf::int64 lower_bound() const; + void set_lower_bound(::google::protobuf::int64 value); + + // optional int64 upper_bound = 4; + bool has_upper_bound() const; + void clear_upper_bound(); + static const int kUpperBoundFieldNumber = 4; + ::google::protobuf::int64 upper_bound() const; + void set_upper_bound(::google::protobuf::int64 value); + + // optional string name = 5 [default = ""]; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 5; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // @@protoc_insertion_point(class_scope:operations_research.LinearBooleanConstraint) + private: + inline void set_has_lower_bound(); + inline void clear_has_lower_bound(); + inline void set_has_upper_bound(); + inline void clear_has_upper_bound(); + inline void set_has_name(); + inline void clear_has_name(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > literals_; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 > coefficients_; + ::google::protobuf::int64 lower_bound_; + ::google::protobuf::int64 upper_bound_; + ::google::protobuf::internal::ArenaStringPtr name_; + friend void protobuf_AddDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); + friend void protobuf_AssignDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fsat_2fboolean_5fproblem_2eproto(); + + void InitAsDefaultInstance(); + static LinearBooleanConstraint* default_instance_; +}; +// ------------------------------------------------------------------- + +class LinearObjective : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.LinearObjective) */ { + public: + LinearObjective(); + virtual ~LinearObjective(); + + LinearObjective(const LinearObjective& from); + + inline LinearObjective& operator=(const LinearObjective& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const LinearObjective& default_instance(); + + void Swap(LinearObjective* other); + + // implements Message ---------------------------------------------- + + inline LinearObjective* New() const { return New(NULL); } + + LinearObjective* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const LinearObjective& from); + void MergeFrom(const LinearObjective& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(LinearObjective* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 literals = 1; + int literals_size() const; + void clear_literals(); + static const int kLiteralsFieldNumber = 1; + ::google::protobuf::int32 literals(int index) const; + void set_literals(int index, ::google::protobuf::int32 value); + void add_literals(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + literals() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_literals(); + + // repeated int64 coefficients = 2; + int coefficients_size() const; + void clear_coefficients(); + static const int kCoefficientsFieldNumber = 2; + ::google::protobuf::int64 coefficients(int index) const; + void set_coefficients(int index, ::google::protobuf::int64 value); + void add_coefficients(::google::protobuf::int64 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& + coefficients() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* + mutable_coefficients(); + + // optional double offset = 3 [default = 0]; + bool has_offset() const; + void clear_offset(); + static const int kOffsetFieldNumber = 3; + double offset() const; + void set_offset(double value); + + // optional double scaling_factor = 4 [default = 1]; + bool has_scaling_factor() const; + void clear_scaling_factor(); + static const int kScalingFactorFieldNumber = 4; + double scaling_factor() const; + void set_scaling_factor(double value); + + // @@protoc_insertion_point(class_scope:operations_research.LinearObjective) + private: + inline void set_has_offset(); + inline void clear_has_offset(); + inline void set_has_scaling_factor(); + inline void clear_has_scaling_factor(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > literals_; + ::google::protobuf::RepeatedField< ::google::protobuf::int64 > coefficients_; + double offset_; + double scaling_factor_; + friend void protobuf_AddDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); + friend void protobuf_AssignDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fsat_2fboolean_5fproblem_2eproto(); + + void InitAsDefaultInstance(); + static LinearObjective* default_instance_; +}; +// ------------------------------------------------------------------- + +class BooleanAssignment : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.BooleanAssignment) */ { + public: + BooleanAssignment(); + virtual ~BooleanAssignment(); + + BooleanAssignment(const BooleanAssignment& from); + + inline BooleanAssignment& operator=(const BooleanAssignment& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const BooleanAssignment& default_instance(); + + void Swap(BooleanAssignment* other); + + // implements Message ---------------------------------------------- + + inline BooleanAssignment* New() const { return New(NULL); } + + BooleanAssignment* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BooleanAssignment& from); + void MergeFrom(const BooleanAssignment& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BooleanAssignment* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 literals = 1; + int literals_size() const; + void clear_literals(); + static const int kLiteralsFieldNumber = 1; + ::google::protobuf::int32 literals(int index) const; + void set_literals(int index, ::google::protobuf::int32 value); + void add_literals(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + literals() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_literals(); + + // @@protoc_insertion_point(class_scope:operations_research.BooleanAssignment) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > literals_; + friend void protobuf_AddDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); + friend void protobuf_AssignDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fsat_2fboolean_5fproblem_2eproto(); + + void InitAsDefaultInstance(); + static BooleanAssignment* default_instance_; +}; +// ------------------------------------------------------------------- + +class LinearBooleanProblem : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.LinearBooleanProblem) */ { + public: + LinearBooleanProblem(); + virtual ~LinearBooleanProblem(); + + LinearBooleanProblem(const LinearBooleanProblem& from); + + inline LinearBooleanProblem& operator=(const LinearBooleanProblem& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const LinearBooleanProblem& default_instance(); + + void Swap(LinearBooleanProblem* other); + + // implements Message ---------------------------------------------- + + inline LinearBooleanProblem* New() const { return New(NULL); } + + LinearBooleanProblem* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const LinearBooleanProblem& from); + void MergeFrom(const LinearBooleanProblem& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(LinearBooleanProblem* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1 [default = ""]; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional int32 num_variables = 3; + bool has_num_variables() const; + void clear_num_variables(); + static const int kNumVariablesFieldNumber = 3; + ::google::protobuf::int32 num_variables() const; + void set_num_variables(::google::protobuf::int32 value); + + // repeated .operations_research.LinearBooleanConstraint constraints = 4; + int constraints_size() const; + void clear_constraints(); + static const int kConstraintsFieldNumber = 4; + const ::operations_research::LinearBooleanConstraint& constraints(int index) const; + ::operations_research::LinearBooleanConstraint* mutable_constraints(int index); + ::operations_research::LinearBooleanConstraint* add_constraints(); + ::google::protobuf::RepeatedPtrField< ::operations_research::LinearBooleanConstraint >* + mutable_constraints(); + const ::google::protobuf::RepeatedPtrField< ::operations_research::LinearBooleanConstraint >& + constraints() const; + + // optional .operations_research.LinearObjective objective = 5; + bool has_objective() const; + void clear_objective(); + static const int kObjectiveFieldNumber = 5; + const ::operations_research::LinearObjective& objective() const; + ::operations_research::LinearObjective* mutable_objective(); + ::operations_research::LinearObjective* release_objective(); + void set_allocated_objective(::operations_research::LinearObjective* objective); + + // repeated string var_names = 6; + int var_names_size() const; + void clear_var_names(); + static const int kVarNamesFieldNumber = 6; + const ::std::string& var_names(int index) const; + ::std::string* mutable_var_names(int index); + void set_var_names(int index, const ::std::string& value); + void set_var_names(int index, const char* value); + void set_var_names(int index, const char* value, size_t size); + ::std::string* add_var_names(); + void add_var_names(const ::std::string& value); + void add_var_names(const char* value); + void add_var_names(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& var_names() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_var_names(); + + // optional .operations_research.BooleanAssignment assignment = 7; + bool has_assignment() const; + void clear_assignment(); + static const int kAssignmentFieldNumber = 7; + const ::operations_research::BooleanAssignment& assignment() const; + ::operations_research::BooleanAssignment* mutable_assignment(); + ::operations_research::BooleanAssignment* release_assignment(); + void set_allocated_assignment(::operations_research::BooleanAssignment* assignment); + + // optional int32 original_num_variables = 8; + bool has_original_num_variables() const; + void clear_original_num_variables(); + static const int kOriginalNumVariablesFieldNumber = 8; + ::google::protobuf::int32 original_num_variables() const; + void set_original_num_variables(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:operations_research.LinearBooleanProblem) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_num_variables(); + inline void clear_has_num_variables(); + inline void set_has_objective(); + inline void clear_has_objective(); + inline void set_has_assignment(); + inline void clear_has_assignment(); + inline void set_has_original_num_variables(); + inline void clear_has_original_num_variables(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::operations_research::LinearBooleanConstraint > constraints_; + ::operations_research::LinearObjective* objective_; + ::google::protobuf::int32 num_variables_; + ::google::protobuf::int32 original_num_variables_; + ::google::protobuf::RepeatedPtrField< ::std::string> var_names_; + ::operations_research::BooleanAssignment* assignment_; + friend void protobuf_AddDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); + friend void protobuf_AssignDesc_ortools_2fsat_2fboolean_5fproblem_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fsat_2fboolean_5fproblem_2eproto(); + + void InitAsDefaultInstance(); + static LinearBooleanProblem* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// LinearBooleanConstraint + +// repeated int32 literals = 1; +inline int LinearBooleanConstraint::literals_size() const { + return literals_.size(); +} +inline void LinearBooleanConstraint::clear_literals() { + literals_.Clear(); +} +inline ::google::protobuf::int32 LinearBooleanConstraint::literals(int index) const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanConstraint.literals) + return literals_.Get(index); +} +inline void LinearBooleanConstraint::set_literals(int index, ::google::protobuf::int32 value) { + literals_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanConstraint.literals) +} +inline void LinearBooleanConstraint::add_literals(::google::protobuf::int32 value) { + literals_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.LinearBooleanConstraint.literals) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +LinearBooleanConstraint::literals() const { + // @@protoc_insertion_point(field_list:operations_research.LinearBooleanConstraint.literals) + return literals_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +LinearBooleanConstraint::mutable_literals() { + // @@protoc_insertion_point(field_mutable_list:operations_research.LinearBooleanConstraint.literals) + return &literals_; +} + +// repeated int64 coefficients = 2; +inline int LinearBooleanConstraint::coefficients_size() const { + return coefficients_.size(); +} +inline void LinearBooleanConstraint::clear_coefficients() { + coefficients_.Clear(); +} +inline ::google::protobuf::int64 LinearBooleanConstraint::coefficients(int index) const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanConstraint.coefficients) + return coefficients_.Get(index); +} +inline void LinearBooleanConstraint::set_coefficients(int index, ::google::protobuf::int64 value) { + coefficients_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanConstraint.coefficients) +} +inline void LinearBooleanConstraint::add_coefficients(::google::protobuf::int64 value) { + coefficients_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.LinearBooleanConstraint.coefficients) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& +LinearBooleanConstraint::coefficients() const { + // @@protoc_insertion_point(field_list:operations_research.LinearBooleanConstraint.coefficients) + return coefficients_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* +LinearBooleanConstraint::mutable_coefficients() { + // @@protoc_insertion_point(field_mutable_list:operations_research.LinearBooleanConstraint.coefficients) + return &coefficients_; +} + +// optional int64 lower_bound = 3; +inline bool LinearBooleanConstraint::has_lower_bound() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void LinearBooleanConstraint::set_has_lower_bound() { + _has_bits_[0] |= 0x00000004u; +} +inline void LinearBooleanConstraint::clear_has_lower_bound() { + _has_bits_[0] &= ~0x00000004u; +} +inline void LinearBooleanConstraint::clear_lower_bound() { + lower_bound_ = GOOGLE_LONGLONG(0); + clear_has_lower_bound(); +} +inline ::google::protobuf::int64 LinearBooleanConstraint::lower_bound() const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanConstraint.lower_bound) + return lower_bound_; +} +inline void LinearBooleanConstraint::set_lower_bound(::google::protobuf::int64 value) { + set_has_lower_bound(); + lower_bound_ = value; + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanConstraint.lower_bound) +} + +// optional int64 upper_bound = 4; +inline bool LinearBooleanConstraint::has_upper_bound() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void LinearBooleanConstraint::set_has_upper_bound() { + _has_bits_[0] |= 0x00000008u; +} +inline void LinearBooleanConstraint::clear_has_upper_bound() { + _has_bits_[0] &= ~0x00000008u; +} +inline void LinearBooleanConstraint::clear_upper_bound() { + upper_bound_ = GOOGLE_LONGLONG(0); + clear_has_upper_bound(); +} +inline ::google::protobuf::int64 LinearBooleanConstraint::upper_bound() const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanConstraint.upper_bound) + return upper_bound_; +} +inline void LinearBooleanConstraint::set_upper_bound(::google::protobuf::int64 value) { + set_has_upper_bound(); + upper_bound_ = value; + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanConstraint.upper_bound) +} + +// optional string name = 5 [default = ""]; +inline bool LinearBooleanConstraint::has_name() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void LinearBooleanConstraint::set_has_name() { + _has_bits_[0] |= 0x00000010u; +} +inline void LinearBooleanConstraint::clear_has_name() { + _has_bits_[0] &= ~0x00000010u; +} +inline void LinearBooleanConstraint::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& LinearBooleanConstraint::name() const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanConstraint.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void LinearBooleanConstraint::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanConstraint.name) +} +inline void LinearBooleanConstraint::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.LinearBooleanConstraint.name) +} +inline void LinearBooleanConstraint::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.LinearBooleanConstraint.name) +} +inline ::std::string* LinearBooleanConstraint::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:operations_research.LinearBooleanConstraint.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* LinearBooleanConstraint::release_name() { + // @@protoc_insertion_point(field_release:operations_research.LinearBooleanConstraint.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void LinearBooleanConstraint::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.LinearBooleanConstraint.name) +} + +// ------------------------------------------------------------------- + +// LinearObjective + +// repeated int32 literals = 1; +inline int LinearObjective::literals_size() const { + return literals_.size(); +} +inline void LinearObjective::clear_literals() { + literals_.Clear(); +} +inline ::google::protobuf::int32 LinearObjective::literals(int index) const { + // @@protoc_insertion_point(field_get:operations_research.LinearObjective.literals) + return literals_.Get(index); +} +inline void LinearObjective::set_literals(int index, ::google::protobuf::int32 value) { + literals_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.LinearObjective.literals) +} +inline void LinearObjective::add_literals(::google::protobuf::int32 value) { + literals_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.LinearObjective.literals) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +LinearObjective::literals() const { + // @@protoc_insertion_point(field_list:operations_research.LinearObjective.literals) + return literals_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +LinearObjective::mutable_literals() { + // @@protoc_insertion_point(field_mutable_list:operations_research.LinearObjective.literals) + return &literals_; +} + +// repeated int64 coefficients = 2; +inline int LinearObjective::coefficients_size() const { + return coefficients_.size(); +} +inline void LinearObjective::clear_coefficients() { + coefficients_.Clear(); +} +inline ::google::protobuf::int64 LinearObjective::coefficients(int index) const { + // @@protoc_insertion_point(field_get:operations_research.LinearObjective.coefficients) + return coefficients_.Get(index); +} +inline void LinearObjective::set_coefficients(int index, ::google::protobuf::int64 value) { + coefficients_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.LinearObjective.coefficients) +} +inline void LinearObjective::add_coefficients(::google::protobuf::int64 value) { + coefficients_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.LinearObjective.coefficients) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int64 >& +LinearObjective::coefficients() const { + // @@protoc_insertion_point(field_list:operations_research.LinearObjective.coefficients) + return coefficients_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int64 >* +LinearObjective::mutable_coefficients() { + // @@protoc_insertion_point(field_mutable_list:operations_research.LinearObjective.coefficients) + return &coefficients_; +} + +// optional double offset = 3 [default = 0]; +inline bool LinearObjective::has_offset() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void LinearObjective::set_has_offset() { + _has_bits_[0] |= 0x00000004u; +} +inline void LinearObjective::clear_has_offset() { + _has_bits_[0] &= ~0x00000004u; +} +inline void LinearObjective::clear_offset() { + offset_ = 0; + clear_has_offset(); +} +inline double LinearObjective::offset() const { + // @@protoc_insertion_point(field_get:operations_research.LinearObjective.offset) + return offset_; +} +inline void LinearObjective::set_offset(double value) { + set_has_offset(); + offset_ = value; + // @@protoc_insertion_point(field_set:operations_research.LinearObjective.offset) +} + +// optional double scaling_factor = 4 [default = 1]; +inline bool LinearObjective::has_scaling_factor() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void LinearObjective::set_has_scaling_factor() { + _has_bits_[0] |= 0x00000008u; +} +inline void LinearObjective::clear_has_scaling_factor() { + _has_bits_[0] &= ~0x00000008u; +} +inline void LinearObjective::clear_scaling_factor() { + scaling_factor_ = 1; + clear_has_scaling_factor(); +} +inline double LinearObjective::scaling_factor() const { + // @@protoc_insertion_point(field_get:operations_research.LinearObjective.scaling_factor) + return scaling_factor_; +} +inline void LinearObjective::set_scaling_factor(double value) { + set_has_scaling_factor(); + scaling_factor_ = value; + // @@protoc_insertion_point(field_set:operations_research.LinearObjective.scaling_factor) +} + +// ------------------------------------------------------------------- + +// BooleanAssignment + +// repeated int32 literals = 1; +inline int BooleanAssignment::literals_size() const { + return literals_.size(); +} +inline void BooleanAssignment::clear_literals() { + literals_.Clear(); +} +inline ::google::protobuf::int32 BooleanAssignment::literals(int index) const { + // @@protoc_insertion_point(field_get:operations_research.BooleanAssignment.literals) + return literals_.Get(index); +} +inline void BooleanAssignment::set_literals(int index, ::google::protobuf::int32 value) { + literals_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.BooleanAssignment.literals) +} +inline void BooleanAssignment::add_literals(::google::protobuf::int32 value) { + literals_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.BooleanAssignment.literals) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +BooleanAssignment::literals() const { + // @@protoc_insertion_point(field_list:operations_research.BooleanAssignment.literals) + return literals_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +BooleanAssignment::mutable_literals() { + // @@protoc_insertion_point(field_mutable_list:operations_research.BooleanAssignment.literals) + return &literals_; +} + +// ------------------------------------------------------------------- + +// LinearBooleanProblem + +// optional string name = 1 [default = ""]; +inline bool LinearBooleanProblem::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void LinearBooleanProblem::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void LinearBooleanProblem::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void LinearBooleanProblem::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& LinearBooleanProblem::name() const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanProblem.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void LinearBooleanProblem::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanProblem.name) +} +inline void LinearBooleanProblem::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.LinearBooleanProblem.name) +} +inline void LinearBooleanProblem::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.LinearBooleanProblem.name) +} +inline ::std::string* LinearBooleanProblem::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:operations_research.LinearBooleanProblem.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* LinearBooleanProblem::release_name() { + // @@protoc_insertion_point(field_release:operations_research.LinearBooleanProblem.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void LinearBooleanProblem::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:operations_research.LinearBooleanProblem.name) +} + +// optional int32 num_variables = 3; +inline bool LinearBooleanProblem::has_num_variables() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void LinearBooleanProblem::set_has_num_variables() { + _has_bits_[0] |= 0x00000002u; +} +inline void LinearBooleanProblem::clear_has_num_variables() { + _has_bits_[0] &= ~0x00000002u; +} +inline void LinearBooleanProblem::clear_num_variables() { + num_variables_ = 0; + clear_has_num_variables(); +} +inline ::google::protobuf::int32 LinearBooleanProblem::num_variables() const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanProblem.num_variables) + return num_variables_; +} +inline void LinearBooleanProblem::set_num_variables(::google::protobuf::int32 value) { + set_has_num_variables(); + num_variables_ = value; + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanProblem.num_variables) +} + +// repeated .operations_research.LinearBooleanConstraint constraints = 4; +inline int LinearBooleanProblem::constraints_size() const { + return constraints_.size(); +} +inline void LinearBooleanProblem::clear_constraints() { + constraints_.Clear(); +} +inline const ::operations_research::LinearBooleanConstraint& LinearBooleanProblem::constraints(int index) const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanProblem.constraints) + return constraints_.Get(index); +} +inline ::operations_research::LinearBooleanConstraint* LinearBooleanProblem::mutable_constraints(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.LinearBooleanProblem.constraints) + return constraints_.Mutable(index); +} +inline ::operations_research::LinearBooleanConstraint* LinearBooleanProblem::add_constraints() { + // @@protoc_insertion_point(field_add:operations_research.LinearBooleanProblem.constraints) + return constraints_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::operations_research::LinearBooleanConstraint >* +LinearBooleanProblem::mutable_constraints() { + // @@protoc_insertion_point(field_mutable_list:operations_research.LinearBooleanProblem.constraints) + return &constraints_; +} +inline const ::google::protobuf::RepeatedPtrField< ::operations_research::LinearBooleanConstraint >& +LinearBooleanProblem::constraints() const { + // @@protoc_insertion_point(field_list:operations_research.LinearBooleanProblem.constraints) + return constraints_; +} + +// optional .operations_research.LinearObjective objective = 5; +inline bool LinearBooleanProblem::has_objective() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void LinearBooleanProblem::set_has_objective() { + _has_bits_[0] |= 0x00000008u; +} +inline void LinearBooleanProblem::clear_has_objective() { + _has_bits_[0] &= ~0x00000008u; +} +inline void LinearBooleanProblem::clear_objective() { + if (objective_ != NULL) objective_->::operations_research::LinearObjective::Clear(); + clear_has_objective(); +} +inline const ::operations_research::LinearObjective& LinearBooleanProblem::objective() const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanProblem.objective) + return objective_ != NULL ? *objective_ : *default_instance_->objective_; +} +inline ::operations_research::LinearObjective* LinearBooleanProblem::mutable_objective() { + set_has_objective(); + if (objective_ == NULL) { + objective_ = new ::operations_research::LinearObjective; + } + // @@protoc_insertion_point(field_mutable:operations_research.LinearBooleanProblem.objective) + return objective_; +} +inline ::operations_research::LinearObjective* LinearBooleanProblem::release_objective() { + // @@protoc_insertion_point(field_release:operations_research.LinearBooleanProblem.objective) + clear_has_objective(); + ::operations_research::LinearObjective* temp = objective_; + objective_ = NULL; + return temp; +} +inline void LinearBooleanProblem::set_allocated_objective(::operations_research::LinearObjective* objective) { + delete objective_; + objective_ = objective; + if (objective) { + set_has_objective(); + } else { + clear_has_objective(); + } + // @@protoc_insertion_point(field_set_allocated:operations_research.LinearBooleanProblem.objective) +} + +// repeated string var_names = 6; +inline int LinearBooleanProblem::var_names_size() const { + return var_names_.size(); +} +inline void LinearBooleanProblem::clear_var_names() { + var_names_.Clear(); +} +inline const ::std::string& LinearBooleanProblem::var_names(int index) const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanProblem.var_names) + return var_names_.Get(index); +} +inline ::std::string* LinearBooleanProblem::mutable_var_names(int index) { + // @@protoc_insertion_point(field_mutable:operations_research.LinearBooleanProblem.var_names) + return var_names_.Mutable(index); +} +inline void LinearBooleanProblem::set_var_names(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanProblem.var_names) + var_names_.Mutable(index)->assign(value); +} +inline void LinearBooleanProblem::set_var_names(int index, const char* value) { + var_names_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:operations_research.LinearBooleanProblem.var_names) +} +inline void LinearBooleanProblem::set_var_names(int index, const char* value, size_t size) { + var_names_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:operations_research.LinearBooleanProblem.var_names) +} +inline ::std::string* LinearBooleanProblem::add_var_names() { + // @@protoc_insertion_point(field_add_mutable:operations_research.LinearBooleanProblem.var_names) + return var_names_.Add(); +} +inline void LinearBooleanProblem::add_var_names(const ::std::string& value) { + var_names_.Add()->assign(value); + // @@protoc_insertion_point(field_add:operations_research.LinearBooleanProblem.var_names) +} +inline void LinearBooleanProblem::add_var_names(const char* value) { + var_names_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:operations_research.LinearBooleanProblem.var_names) +} +inline void LinearBooleanProblem::add_var_names(const char* value, size_t size) { + var_names_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:operations_research.LinearBooleanProblem.var_names) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +LinearBooleanProblem::var_names() const { + // @@protoc_insertion_point(field_list:operations_research.LinearBooleanProblem.var_names) + return var_names_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +LinearBooleanProblem::mutable_var_names() { + // @@protoc_insertion_point(field_mutable_list:operations_research.LinearBooleanProblem.var_names) + return &var_names_; +} + +// optional .operations_research.BooleanAssignment assignment = 7; +inline bool LinearBooleanProblem::has_assignment() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void LinearBooleanProblem::set_has_assignment() { + _has_bits_[0] |= 0x00000020u; +} +inline void LinearBooleanProblem::clear_has_assignment() { + _has_bits_[0] &= ~0x00000020u; +} +inline void LinearBooleanProblem::clear_assignment() { + if (assignment_ != NULL) assignment_->::operations_research::BooleanAssignment::Clear(); + clear_has_assignment(); +} +inline const ::operations_research::BooleanAssignment& LinearBooleanProblem::assignment() const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanProblem.assignment) + return assignment_ != NULL ? *assignment_ : *default_instance_->assignment_; +} +inline ::operations_research::BooleanAssignment* LinearBooleanProblem::mutable_assignment() { + set_has_assignment(); + if (assignment_ == NULL) { + assignment_ = new ::operations_research::BooleanAssignment; + } + // @@protoc_insertion_point(field_mutable:operations_research.LinearBooleanProblem.assignment) + return assignment_; +} +inline ::operations_research::BooleanAssignment* LinearBooleanProblem::release_assignment() { + // @@protoc_insertion_point(field_release:operations_research.LinearBooleanProblem.assignment) + clear_has_assignment(); + ::operations_research::BooleanAssignment* temp = assignment_; + assignment_ = NULL; + return temp; +} +inline void LinearBooleanProblem::set_allocated_assignment(::operations_research::BooleanAssignment* assignment) { + delete assignment_; + assignment_ = assignment; + if (assignment) { + set_has_assignment(); + } else { + clear_has_assignment(); + } + // @@protoc_insertion_point(field_set_allocated:operations_research.LinearBooleanProblem.assignment) +} + +// optional int32 original_num_variables = 8; +inline bool LinearBooleanProblem::has_original_num_variables() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void LinearBooleanProblem::set_has_original_num_variables() { + _has_bits_[0] |= 0x00000040u; +} +inline void LinearBooleanProblem::clear_has_original_num_variables() { + _has_bits_[0] &= ~0x00000040u; +} +inline void LinearBooleanProblem::clear_original_num_variables() { + original_num_variables_ = 0; + clear_has_original_num_variables(); +} +inline ::google::protobuf::int32 LinearBooleanProblem::original_num_variables() const { + // @@protoc_insertion_point(field_get:operations_research.LinearBooleanProblem.original_num_variables) + return original_num_variables_; +} +inline void LinearBooleanProblem::set_original_num_variables(::google::protobuf::int32 value) { + set_has_original_num_variables(); + original_num_variables_ = value; + // @@protoc_insertion_point(field_set:operations_research.LinearBooleanProblem.original_num_variables) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace operations_research + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fsat_2fboolean_5fproblem_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/sat/clause.h b/thirdparty/linux/include/ortools/sat/clause.h new file mode 100644 index 0000000..1e8c81b --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/clause.h @@ -0,0 +1,461 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains the solver internal representation of the clauses and the +// classes used for their propagation. + +#ifndef OR_TOOLS_SAT_CLAUSE_H_ +#define OR_TOOLS_SAT_CLAUSE_H_ + +#include +#include +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/stringprintf.h" +#include "ortools/base/timer.h" +#include "ortools/base/int_type.h" +#include "ortools/base/int_type_indexed_vector.h" +#include "ortools/base/hash.h" +#include "ortools/sat/sat_base.h" +#include "ortools/sat/sat_parameters.pb.h" +#include "ortools/util/bitset.h" +#include "ortools/util/stats.h" +#include "ortools/base/random.h" + +namespace operations_research { +namespace sat { + +// Forward declarations. +// TODO(user): This cyclic dependency can be relatively easily removed. +class LiteralWatchers; + +// Variable information. This is updated each time we attach/detach a clause. +struct VariableInfo { + VariableInfo() + : num_positive_clauses(0), + num_negative_clauses(0), + num_appearances(0), + weighted_num_appearances(0.0) {} + + int num_positive_clauses; + int num_negative_clauses; + int num_appearances; + double weighted_num_appearances; +}; + +// This is how the SatSolver stores a clause. A clause is just a disjunction of +// literals. In many places, we just use std::vector to encode one. However, +// the solver needs to keep a few extra fields attached to each clause. +class SatClause { + public: + // Creates a sat clause. There must be at least 2 literals. Smaller clause are + // treated separatly and never constructed. A redundant clause can be removed + // without changing the problem. + static SatClause* Create(const std::vector& literals, + bool is_redundant); + + // Non-sized delete because this is a tail-padded class. + void operator delete(void* p) { + ::operator delete(p); // non-sized delete + } + + // Number of literals in the clause. + int Size() const { return size_; } + + // Allows for range based iteration: for (Literal literal : clause) {}. + const Literal* const begin() const { return &(literals_[0]); } + const Literal* const end() const { return &(literals_[size_]); } + Literal* literals() { return &(literals_[0]); } + + // Returns the first and second literals. These are always the watched + // literals if the clause is attached in the LiteralWatchers. + Literal FirstLiteral() const { return literals_[0]; } + Literal SecondLiteral() const { return literals_[1]; } + + // Returns the literal that was propagated to true. This only works for a + // clause that just propagated this literal. Otherwise, this will just returns + // a literal of the clause. + Literal PropagatedLiteral() const { return literals_[0]; } + + // Returns the reason for the last unit propagation of this clause. The + // preconditions are the same as for PropagatedLiteral(). + ClauseRef PropagationReason() const { + // Note that we don't need to include the propagated literal. + return ClauseRef(&(literals_[1]), end()); + } + + // Removes literals that are fixed. This should only be called at level 0 + // where a literal is fixed iff it is assigned. Aborts and returns true if + // they are not all false. + // + // Note that the removed literal can still be accessed in the portion [size, + // old_size) of literals(). + bool RemoveFixedLiteralsAndTestIfTrue(const VariablesAssignment& assignment); + + // True if the clause can be safely removed without changing the current + // problem. Usually the clause we learn during the search are redundant since + // the original clauses are enough to define the problem. + bool IsRedundant() const { return is_redundant_; } + + // Returns true if the clause is satisfied for the given assignment. Note that + // the assignment may be partial, so false does not mean that the clause can't + // be satisfied by completing the assignment. + bool IsSatisfied(const VariablesAssignment& assignment) const; + + // Sorts the literals of the clause depending on the given parameters and + // statistics. Do not call this on an attached clause. + void SortLiterals(const ITIVector& statistics, + const SatParameters& parameters); + + // Sets up the 2-watchers data structure. It selects two non-false literals + // and attaches the clause to the event: one of the watched literals become + // false. It returns false if the clause only contains literals assigned to + // false. If only one literals is not false, it propagates it to true if it + // is not already assigned. + bool AttachAndEnqueuePotentialUnitPropagation(Trail* trail, + LiteralWatchers* demons); + + // Returns true if the clause is attached to a LiteralWatchers. + bool IsAttached() const { return is_attached_; } + + // Marks the clause so that the next call to CleanUpWatchers() can identify it + // and actually detach it. + void LazyDetach() { is_attached_ = false; } + + std::string DebugString() const; + + private: + // The data is packed so that only 4 bytes are used for these fields. + // + // TODO(user): It should be possible to remove one or both of the Booleans. + // That may speed up the code slightly. + bool is_redundant_ : 1; + bool is_attached_ : 1; + unsigned int size_ : 30; + + // This class store the literals inline, and literals_ mark the starts of the + // variable length portion. + Literal literals_[0]; + + DISALLOW_COPY_AND_ASSIGN(SatClause); +}; + +// Stores the 2-watched literals data structure. See +// http://www.cs.berkeley.edu/~necula/autded/lecture24-sat.pdf for +// detail. +class LiteralWatchers : public SatPropagator { + public: + LiteralWatchers(); + ~LiteralWatchers() override; + + bool Propagate(Trail* trail) final; + ClauseRef Reason(const Trail& trail, int trail_index) const final; + + // Resizes the data structure. + void Resize(int num_variables); + + // Attaches the given clause. This eventually propagates a literal which is + // enqueued on the trail. Returns false if a contradiction was encountered. + bool AttachAndPropagate(SatClause* clause, Trail* trail); + + // Lazily detach the given clause. The deletion will actually occur when + // CleanUpWatchers() is called. The later needs to be called before any other + // function in this class can be called. This is DCHECKed. + void LazyDetach(SatClause* clause); + void CleanUpWatchers(); + + // Returns the reason of the variable at given trail_index. + // This only works for variable propagated by this class. + SatClause* ReasonClause(int trail_index) const; + + // Total number of clauses inspected during calls to PropagateOnFalse(). + int64 num_inspected_clauses() const { return num_inspected_clauses_; } + int64 num_inspected_clause_literals() const { + return num_inspected_clause_literals_; + } + + // Number of clauses currently watched. + int64 num_watched_clauses() const { return num_watched_clauses_; } + + // Returns some statistics on the number of appearance of this variable in + // all the attached clauses. + const VariableInfo& VariableStatistic(BooleanVariable var) const { + return statistics_[var]; + } + + // Parameters management. + void SetParameters(const SatParameters& parameters) { + parameters_ = parameters; + } + + private: + // Launches all propagation when the given literal becomes false. + // Returns false if a contradiction was encountered. + bool PropagateOnFalse(Literal false_literal, Trail* trail); + + // Attaches the given clause to the event: the given literal becomes false. + // The blocking_literal can be any literal from the clause, it is used to + // speed up PropagateOnFalse() by skipping the clause if it is true. + void AttachOnFalse(Literal literal, Literal blocking_literal, + SatClause* clause); + + // AttachOnFalse and SetReasonClause() need to be called from + // SatClause::AttachAndEnqueuePotentialUnitPropagation(). + // + // TODO(user): This is not super clean, find a better way. + friend bool SatClause::AttachAndEnqueuePotentialUnitPropagation( + Trail* trail, LiteralWatchers* demons); + void SetReasonClause(int trail_index, SatClause* clause) { + reasons_[trail_index] = clause; + } + + // Updates statistics_ for the literals in the given clause. added indicates + // if we are adding the clause or deleting it. + void UpdateStatistics(const SatClause& clause, bool added); + + // Contains, for each literal, the list of clauses that need to be inspected + // when the corresponding literal becomes false. + struct Watcher { + Watcher() {} + Watcher(SatClause* c, Literal b) : clause(c), blocking_literal(b) {} + SatClause* clause; + Literal blocking_literal; + }; + ITIVector > watchers_on_false_; + + // SatClause reasons by trail_index. + std::vector reasons_; + + // Indicates if the corresponding watchers_on_false_ list need to be + // cleaned. The boolean is_clean_ is just used in DCHECKs. + SparseBitset needs_cleaning_; + bool is_clean_; + + ITIVector statistics_; + SatParameters parameters_; + int64 num_inspected_clauses_; + int64 num_inspected_clause_literals_; + int64 num_watched_clauses_; + mutable StatsGroup stats_; + DISALLOW_COPY_AND_ASSIGN(LiteralWatchers); +}; + +// A binary clause. This is used by BinaryClauseManager. +struct BinaryClause { + BinaryClause(Literal _a, Literal _b) : a(_a), b(_b) {} + bool operator==(BinaryClause o) const { return a == o.a && b == o.b; } + bool operator!=(BinaryClause o) const { return a != o.a || b != o.b; } + Literal a; + Literal b; +}; + +// A simple class to manage a set of binary clauses. +class BinaryClauseManager { + public: + BinaryClauseManager() {} + int NumClauses() const { return set_.size(); } + + // Adds a new binary clause to the manager and returns true if it wasn't + // already present. + bool Add(BinaryClause c) { + std::pair p(c.a.SignedValue(), c.b.SignedValue()); + if (p.first > p.second) std::swap(p.first, p.second); + if (set_.find(p) == set_.end()) { + set_.insert(p); + newly_added_.push_back(c); + return true; + } + return false; + } + + // Returns the newly added BinaryClause since the last ClearNewlyAdded() call. + const std::vector& newly_added() const { return newly_added_; } + void ClearNewlyAdded() { newly_added_.clear(); } + + private: + std::unordered_set> set_; + std::vector newly_added_; + DISALLOW_COPY_AND_ASSIGN(BinaryClauseManager); +}; + +// Special class to store and propagate clauses of size 2 (i.e. implication). +// Such clauses are never deleted. +// +// TODO(user): All the variables in a strongly connected component are +// equivalent and can be thus merged as one. This is relatively cheap to compute +// from time to time (linear complexity). We will also get contradiction (a <=> +// not a) this way. +// +// TODO(user): An implication (a => not a) implies that a is false. I am not +// sure it is worth detecting that because if the solver assign a to true, it +// will learn that right away. I don't think we can do it faster. +// +// TODO(user): The implication graph can be pruned. This is called the +// transitive reduction of a graph. For instance If a => {b,c} and b => {c}, +// then there is no need to store a => {c}. The transitive reduction is unique +// on an acyclic graph. Computing it will allow for a faster propagation and +// memory reduction. It is however not cheap. Maybe simple lazy heuristics to +// remove redundant arcs are better. Note that all the learned clauses we add +// will never be redundant (but they could introduce cycles). +// +// TODO(user): Add a preprocessor to remove duplicates in the implication lists. +// Note that all the learned clauses we had will never create duplicates. +// +// References for most of the above TODO and more: +// - Brafman RI, "A simplifier for propositional formulas with many binary +// clauses", IEEE Trans Syst Man Cybern B Cybern. 2004 Feb;34(1):52-9. +// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.28.4911 +// - Marijn J. H. Heule, Matti Järvisalo, Armin Biere, "Efficient CNF +// Simplification Based on Binary Implication Graphs", Theory and Applications +// of Satisfiability Testing - SAT 2011, Lecture Notes in Computer Science +// Volume 6695, 2011, pp 201-215 +// http://www.cs.helsinki.fi/u/mjarvisa/papers/heule-jarvisalo-biere.sat11.pdf +class BinaryImplicationGraph : public SatPropagator { + public: + BinaryImplicationGraph() + : SatPropagator("BinaryImplicationGraph"), + num_implications_(0), + num_propagations_(0), + num_inspections_(0), + num_minimization_(0), + num_literals_removed_(0), + num_redundant_implications_(0), + stats_("BinaryImplicationGraph") {} + ~BinaryImplicationGraph() override { + IF_STATS_ENABLED({ + LOG(INFO) << stats_.StatString(); + LOG(INFO) << "num_redundant_implications " << num_redundant_implications_; + }); + } + + bool Propagate(Trail* trail) final; + ClauseRef Reason(const Trail& trail, int trail_index) const final; + + // Resizes the data structure. + void Resize(int num_variables); + + // Adds the binary clause (a OR b), which is the same as (not a => b). + // Note that it is also equivalent to (not b => a). + void AddBinaryClause(Literal a, Literal b); + + // Same as AddBinaryClause() but enqueues a possible unit propagation. Note + // that if the binary clause propagates, it must do so at the last level, this + // is DCHECKed. + void AddBinaryClauseDuringSearch(Literal a, Literal b, Trail* trail); + + // Uses the binary implication graph to minimize the given conflict by + // removing literals that implies others. The idea is that if a and b are two + // literals from the given conflict and a => b (which is the same as not(b) => + // not(a)) then a is redundant and can be removed. + // + // Note that removing as many literals as possible is too time consuming, so + // we use different heuristics/algorithms to do this minimization. + // See the binary_minimization_algorithm SAT parameter and the .cc for more + // details about the different algorithms. + void MinimizeConflictWithReachability(std::vector* c); + void MinimizeConflictExperimental(const Trail& trail, + std::vector* c); + void MinimizeConflictFirst(const Trail& trail, std::vector* c, + SparseBitset* marked); + void MinimizeConflictFirstWithTransitiveReduction( + const Trail& trail, std::vector* c, + SparseBitset* marked, RandomBase* random); + + // This must only be called at decision level 0 after all the possible + // propagations. It: + // - Removes the variable at true from the implications lists. + // - Frees the propagation list of the assigned literals. + void RemoveFixedVariables(int first_unprocessed_trail_index, + const Trail& trail); + + // Number of literal propagated by this class (including conflicts). + int64 num_propagations() const { return num_propagations_; } + + // Number of literals inspected by this class during propagation. + int64 num_inspections() const { return num_inspections_; } + + // MinimizeClause() stats. + int64 num_minimization() const { return num_minimization_; } + int64 num_literals_removed() const { return num_literals_removed_; } + + // Number of implications removed by transitive reduction. + int64 num_redundant_implications() const { + return num_redundant_implications_; + } + + // Returns the number of current implications. + int64 NumberOfImplications() const { return num_implications_; } + + // Extract all the binary clauses managed by this class. The Output type must + // support an AddBinaryClause(Literal a, Literal b) function. + template + void ExtractAllBinaryClauses(Output* out) const { + for (LiteralIndex i(0); i < implications_.size(); ++i) { + const Literal a = Literal(i).Negated(); + for (const Literal b : implications_[i]) { + // Because we store implications, the clause will actually appear twice + // as (a, b) and (b, a). We output only one. + if (a < b) out->AddBinaryClause(a, b); + } + } + } + + private: + // Propagates all the direct implications of the given literal becoming true. + // Returns false if a conflict was encountered, in which case + // trail->SetFailingClause() will be called with the correct size 2 clause. + // This calls trail->Enqueue() on the newly assigned literals. + bool PropagateOnTrue(Literal true_literal, Trail* trail); + + // Remove any literal whose negation is marked (except the first one). + void RemoveRedundantLiterals(std::vector* conflict); + + // Binary reasons by trail_index. We need a deque because we kept pointers to + // elements of this array and this can dynamically change size. + std::deque reasons_; + + // This is indexed by the Index() of a literal. Each list stores the + // literals that are implied if the index literal becomes true. + ITIVector> implications_; + int64 num_implications_; + + // Some stats. + int64 num_propagations_; + int64 num_inspections_; + int64 num_minimization_; + int64 num_literals_removed_; + int64 num_redundant_implications_; + + // Bitset used by MinimizeClause(). + // TODO(user): use the same one as the one used in the classic minimization + // because they are already initialized. Moreover they contains more + // information. + SparseBitset is_marked_; + SparseBitset is_removed_; + + // Temporary stack used by MinimizeClauseWithReachability(). + std::vector dfs_stack_; + + mutable StatsGroup stats_; + DISALLOW_COPY_AND_ASSIGN(BinaryImplicationGraph); +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_CLAUSE_H_ diff --git a/thirdparty/linux/include/ortools/sat/cp_constraints.h b/thirdparty/linux/include/ortools/sat/cp_constraints.h new file mode 100644 index 0000000..98fe796 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/cp_constraints.h @@ -0,0 +1,480 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_CP_CONSTRAINTS_H_ +#define OR_TOOLS_SAT_CP_CONSTRAINTS_H_ + +#include + +#include "ortools/sat/integer.h" +#include "ortools/sat/model.h" +#include "ortools/util/sorted_interval_list.h" + +namespace operations_research { +namespace sat { + +// Propagate the fact that a XOR of literals is equal to the given value. +// The complexity is in O(n). +// +// TODO(user): By using a two watcher mechanism, we can propagate this a lot +// faster. +class BooleanXorPropagator : public PropagatorInterface { + public: + BooleanXorPropagator(const std::vector& literals, bool value, + Trail* trail, IntegerTrail* integer_trail) + : literals_(literals), + value_(value), + trail_(trail), + integer_trail_(integer_trail) {} + + bool Propagate() final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + const std::vector literals_; + const bool value_; + std::vector literal_reason_; + Trail* trail_; + IntegerTrail* integer_trail_; + + DISALLOW_COPY_AND_ASSIGN(BooleanXorPropagator); +}; + +// Implement the all different bound consistent propagator with explanation. +// That is, given n variables that must be all different, this propagates the +// bounds of each variables as much as possible. The key is to detect the so +// called Hall interval which are interval of size k that contains the domain +// of k variables. Because all the variables must take different values, we can +// deduce that the domain of the other variables cannot contains such Hall +// interval. +// +// We use a "simple" O(n log n) algorithm. +// +// TODO(user): implement the faster algorithm described in: +// https://cs.uwaterloo.ca/~vanbeek/Publications/ijcai03_TR.pdf +// Note that the algorithms are similar, the gain comes by replacing our +// SortedDisjointIntervalList with a more customized class for our operations. +// It is even possible to get an O(n) complexity if the values of the bounds are +// in a range of size O(n). +class AllDifferentBoundsPropagator : public PropagatorInterface { + public: + AllDifferentBoundsPropagator(const std::vector& vars, + IntegerTrail* integer_trail); + + bool Propagate() final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + // Fills integer_reason_ with the reason why we have the given hall interval. + void FillHallReason(IntegerValue hall_lb, IntegerValue hall_ub); + + // Do half the job of Propagate(). + bool PropagateLowerBounds(); + + std::vector vars_; + std::vector negated_vars_; + IntegerTrail* integer_trail_; + + // The sets of "critical" intervals. This has the same meaning as in the + // disjunctive constraint. + SortedDisjointIntervalList critical_intervals_; + + // The list of Hall intervalls detected so far, sorted. + std::vector hall_starts_; + std::vector hall_ends_; + + // Members needed for explaining the propagation. + // + // The IntegerVariable in an hall interval [lb, ub] are the variables with key + // in [lb, ub] in this map. Note(user): if the set of bounds is small, we + // could use a std::vector here. The O(ub - lb) to create the reason is fine + // since this is the size of the reason. + // + // Optimization: we only insert the entry in the map lazily when the reason + // is needed. + int64 num_calls_; + std::vector> to_insert_; + std::unordered_map value_to_variable_; + std::vector integer_reason_; + + DISALLOW_COPY_AND_ASSIGN(AllDifferentBoundsPropagator); +}; + +// Initial version of the circuit/sub-circuit constraint. +// It mainly report conflicts and do not propagate much. +class CircuitPropagator : PropagatorInterface, ReversibleInterface { + public: + // The constraints take a dense representation of a graph on [0, n). Each arc + // being present when the given literal is true. The special values + // kTrueLiteralIndex and kFalseLiteralIndex can be used for arcs that are + // either always there or never there. + CircuitPropagator(const std::vector>& graph, + bool allow_subcircuit, Trail* trail); + + void SetLevel(int level) final; + bool Propagate() final; + bool IncrementalPropagate(const std::vector& watch_indices) final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + // Clears and fills trail_->MutableConflict() with the literals of the arcs + // that form a cycle containing the given node. + void FillConflictFromCircuitAt(int start); + + const int num_nodes_; + const bool allow_subcircuit_; + Trail* trail_; + + // Internal representation of the graph given at construction. Const. + struct Arc { + int tail; + int head; + }; + std::vector self_arcs_; + + std::vector watch_index_to_literal_; + std::vector> watch_index_to_arcs_; + + // Index in trail_ up to which we propagated all the assigned Literals. + int propagation_trail_index_; + + // Current partial chains of arc that are present. + std::vector next_; // -1 if not assigned yet. + std::vector prev_; // -1 if not assigned yet. + std::vector next_literal_; + + // Backtrack support for the partial chains of arcs, level_ends_[level] is an + // index in added_arcs_; + std::vector level_ends_; + std::vector added_arcs_; + + // Temporary vector. + std::vector in_circuit_; + + DISALLOW_COPY_AND_ASSIGN(CircuitPropagator); +}; + +// Base class to help writing CP inspired constraints. +class CpPropagator : public PropagatorInterface { + public: + explicit CpPropagator(IntegerTrail* integer_trail); + ~CpPropagator() override; + + // ----- Shortcuts to integer variables ----- + + // Bound getters. + IntegerValue Min(IntegerVariable v) const; + IntegerValue Max(IntegerVariable v) const; + IntegerValue Min(IntegerValue v) const { return v; } + IntegerValue Max(IntegerValue v) const { return v; } + + // Bound setters. They expects integer_reason to be filled and it will be + // used to create the conflicts. These setters are monotonic, i.e. setting a + // min value lower or equal to the current min of the variable will result + // in a no-op. + bool SetMin(IntegerVariable v, IntegerValue value, + const std::vector& reason); + bool SetMax(IntegerVariable v, IntegerValue value, + const std::vector& reason); + bool SetMin(IntegerValue v, IntegerValue value, + const std::vector& reason); + bool SetMax(IntegerValue v, IntegerValue value, + const std::vector& reason); + + // ----- Conflict management ----- + + // Manage the list of integer bounds used to build the reason of propagation. + void AddLowerBoundReason(IntegerVariable v, + std::vector* reason) const; + void AddUpperBoundReason(IntegerVariable v, + std::vector* reason) const; + void AddBoundsReason(IntegerVariable v, + std::vector* reason) const; + + void AddLowerBoundReason(IntegerValue v, + std::vector* reason) const {} + void AddUpperBoundReason(IntegerValue v, + std::vector* reason) const {} + void AddBoundsReason(IntegerValue v, + std::vector* reason) const {} + + protected: + IntegerTrail* integer_trail_; + + private: + DISALLOW_COPY_AND_ASSIGN(CpPropagator); +}; + +// Non overlapping rectangles. +template +class NonOverlappingRectanglesPropagator : public CpPropagator { + public: + // The strict parameters indicates how to place zero width or zero height + // boxes. If strict is true, these boxes must not 'cross' another box, and are + // pushed by the other boxes. + NonOverlappingRectanglesPropagator(const std::vector& x, + const std::vector& y, + const std::vector& dx, + const std::vector& dy, bool strict, + IntegerTrail* integer_trail); + ~NonOverlappingRectanglesPropagator() override; + + // TODO(user): Look at intervals to to store x and dx, y and dy. + bool Propagate() final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + void UpdateNeighbors(int box); + bool FailWhenEnergyIsTooLarge(int box); + bool PushOneBox(int box, int other); + void AddBoxReason(int box); + void AddBoxReason(int box, IntegerValue xmin, IntegerValue xmax, + IntegerValue ymin, IntegerValue ymax); + + // Updates the boxes positions and size when the given box is before other in + // the passed direction. This will fill integer_reason_ if it is empty, + // otherwise, it will reuse its current value. + bool FirstBoxIsBeforeSecondBox(const std::vector& pos, + const std::vector& size, int box, int other, + std::vector* min_end); + + const std::vector x_; + const std::vector y_; + const std::vector dx_; + const std::vector dy_; + const bool strict_; + + // The neighbors_ of a box will be in + // [neighbors_[begin[box]], neighbors_[end[box]]) + std::vector neighbors_; + std::vector neighbors_begins_; + std::vector neighbors_ends_; + std::vector tmp_removed_; + + std::vector cached_areas_; + std::vector cached_min_end_x_; + std::vector cached_min_end_y_; + std::vector cached_distance_to_bounding_box_; + std::vector integer_reason_; + + DISALLOW_COPY_AND_ASSIGN(NonOverlappingRectanglesPropagator); +}; + +// In an "int element" constraint, a target variable is equal to one of a given +// set of candidate variables, each selected by a given literal. This propagator +// is reponsible for updating the min of the target variable using the min of +// the candidate variables that can still be choosen. +class OneOfVarMinPropagator : public PropagatorInterface { + public: + OneOfVarMinPropagator(IntegerVariable target_var, + const std::vector& vars, + const std::vector& selectors, Trail* trail, + IntegerTrail* integer_trail); + + bool Propagate() final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + const IntegerVariable target_var_; + const std::vector vars_; + const std::vector selectors_; + Trail* trail_; + IntegerTrail* integer_trail_; + + std::vector literal_reason_; + std::vector integer_reason_; + + DISALLOW_COPY_AND_ASSIGN(OneOfVarMinPropagator); +}; + +// ============================================================================ +// Model based functions. +// ============================================================================ + +inline std::vector ToIntegerValueVector( + const std::vector& input) { + std::vector result(input.size()); + for (int i = 0; i < input.size(); ++i) { + result[i] = IntegerValue(input[i]); + } + return result; +} + +// Enforces the XOR of a set of literals to be equal to the given value. +inline std::function LiteralXorIs( + const std::vector& literals, bool value) { + return [=](Model* model) { + Trail* trail = model->GetOrCreate(); + IntegerTrail* integer_trail = model->GetOrCreate(); + BooleanXorPropagator* constraint = + new BooleanXorPropagator(literals, value, trail, integer_trail); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Enforces that the given tuple of variables takes different values. +std::function AllDifferent( + const std::vector& vars); + +// Enforces that the given tuple of variables takes different values. +// Same as AllDifferent() but use a different propagator that only enforce +// the so called "bound consistency" on the variable domains. +// +// Compared to AllDifferent() this doesn't require fully encoding the variables +// and it is also quite fast. Note that the propagation is different, this will +// not remove already taken values from inside a domain, but it will propagates +// more the domain bounds. +inline std::function AllDifferentOnBounds( + const std::vector& vars) { + return [=](Model* model) { + AllDifferentBoundsPropagator* constraint = new AllDifferentBoundsPropagator( + vars, model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Enforces that the boxes with corners in (x, y), (x + dx, y), (x, y + dy) +// and (x + dx, y + dy) do not overlap. +// If one box has a zero dimension, then it can be placed anywhere. +inline std::function NonOverlappingRectangles( + const std::vector& x, + const std::vector& y, + const std::vector& dx, + const std::vector& dy) { + return [=](Model* model) { + NonOverlappingRectanglesPropagator* constraint = + new NonOverlappingRectanglesPropagator( + x, y, dx, dy, false, model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Enforces that the boxes with corners in (x, y), (x + dx, y), (x, y + dy) +// and (x + dx, y + dy) do not overlap. +// If one box has a zero dimension, then it can be placed anywhere. +inline std::function NonOverlappingFixedSizeRectangles( + const std::vector& x, + const std::vector& y, const std::vector& dx, + const std::vector& dy) { + return [=](Model* model) { + NonOverlappingRectanglesPropagator* constraint = + new NonOverlappingRectanglesPropagator( + x, y, ToIntegerValueVector(dx), ToIntegerValueVector(dy), false, + model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Enforces that the boxes with corners in (x, y), (x + dx, y), (x, y + dy) +// and (x + dx, y + dy) do not overlap. +// If one box has a zero dimension, it still cannot intersect another box. +inline std::function StrictNonOverlappingRectangles( + const std::vector& x, + const std::vector& y, + const std::vector& dx, + const std::vector& dy) { + return [=](Model* model) { + NonOverlappingRectanglesPropagator* constraint = + new NonOverlappingRectanglesPropagator( + x, y, dx, dy, true, model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Enforces that the boxes with corners in (x, y), (x + dx, y), (x, y + dy) +// and (x + dx, y + dy) do not overlap. +// If one box has a zero dimension, it still cannot intersect another box. +inline std::function StrictNonOverlappingFixedSizeRectangles( + const std::vector& x, + const std::vector& y, const std::vector& dx, + const std::vector& dy) { + return [=](Model* model) { + NonOverlappingRectanglesPropagator* constraint = + new NonOverlappingRectanglesPropagator( + x, y, ToIntegerValueVector(dx), ToIntegerValueVector(dy), true, + model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Enforces that exactly one literal per rows and per columns is true. +// This only work for a square matrix (but could easily be generalized). +std::function ExactlyOnePerRowAndPerColumn( + const std::vector>& square_matrix); + +inline std::function CircuitConstraint( + const std::vector>& graph) { + return [=](Model* model) { + if (graph.empty()) return; + model->Add(ExactlyOnePerRowAndPerColumn(graph)); + CircuitPropagator* constraint = new CircuitPropagator( + graph, /*allow_subcircuit=*/false, model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +inline std::function SubcircuitConstraint( + const std::vector>& graph) { + return [=](Model* model) { + if (graph.empty()) return; + model->Add(ExactlyOnePerRowAndPerColumn(graph)); + CircuitPropagator* constraint = new CircuitPropagator( + graph, /*allow_subcircuit=*/true, model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// The target variable is equal to exactly one of the candidate variable. The +// equality is controlled by the given "selector" literals. +// +// Note(user): This only propagate from the min/max of still possible candidates +// to the min/max of the target variable. The full constraint also requires +// to deal with the case when one of the literal is true. +// +// Note(user): If there is just one or two candiates, this doesn't add anything. +inline std::function PartialIsOneOfVar( + IntegerVariable target_var, const std::vector& vars, + const std::vector& selectors) { + CHECK_EQ(vars.size(), selectors.size()); + return [=](Model* model) { + if (vars.size() > 2) { + // Propagate the min. + OneOfVarMinPropagator* constraint = new OneOfVarMinPropagator( + target_var, vars, selectors, model->GetOrCreate(), + model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + } + if (vars.size() > 2) { + // Propagate the max. + OneOfVarMinPropagator* constraint = new OneOfVarMinPropagator( + NegationOf(target_var), NegationOf(vars), selectors, + model->GetOrCreate(), model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + } + }; +} + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_CP_CONSTRAINTS_H_ diff --git a/thirdparty/linux/include/ortools/sat/cumulative.h b/thirdparty/linux/include/ortools/sat/cumulative.h new file mode 100644 index 0000000..bbe2f29 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/cumulative.h @@ -0,0 +1,59 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_CUMULATIVE_H_ +#define OR_TOOLS_SAT_CUMULATIVE_H_ + +#include "ortools/sat/integer.h" +#include "ortools/sat/intervals.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" + +namespace operations_research { +namespace sat { + +// Adds a cumulative constraint on the given intervals, the associated demands +// and the capacity variables. +// +// Each interval represents a task to be scheduled in time such that the task +// consumes the resource during the time range [lb, ub) where lb and ub +// respectively represent the lower and upper bounds of the corresponding +// interval variable. The amount of resource consumed by the task is the value +// of its associated demand variable. +// +// The cumulative constraint forces the set of task to be scheduled such that +// the sum of the demands of all the tasks that overlap any time point cannot +// exceed the capacity of the resource. +// +// This constraint assumes that an interval can be optional or have a duration +// of zero. The demands and the capacity can be any non-negative number. +std::function Cumulative( + const std::vector& vars, + const std::vector& demand_vars, + const IntegerVariable& capacity_var); + +// Adds a simple cumulative constraint on the given intervals, the associated +// demands and the capacity variables. See the comment of Cumulative() above for +// a definition of the constraint. +// +// This constraint assumes that task demands and the resource capacity must be +// assigned to a non-negative number. +std::function CumulativeTimeDecomposition( + const std::vector& vars, + const std::vector& demand_vars, + const IntegerVariable& capacity_var); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_CUMULATIVE_H_ diff --git a/thirdparty/linux/include/ortools/sat/disjunctive.h b/thirdparty/linux/include/ortools/sat/disjunctive.h new file mode 100644 index 0000000..636fe5e --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/disjunctive.h @@ -0,0 +1,214 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_DISJUNCTIVE_H_ +#define OR_TOOLS_SAT_DISJUNCTIVE_H_ + +#include "ortools/sat/integer.h" +#include "ortools/sat/intervals.h" +#include "ortools/sat/model.h" +#include "ortools/sat/precedences.h" +#include "ortools/sat/sat_base.h" +#include "ortools/sat/theta_tree.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace sat { + +// Enforces a disjunctive (or no overlap) constraint on the given interval +// variables. The intervals are interpreted as [start, end) and the constraint +// enforces that no time point belongs to two intervals. +// +// TODO(user): This is not completely true for empty intervals (start == end). +// Make sure such intervals are ignored by the constraint. +std::function Disjunctive( + const std::vector& vars); + +// Creates Boolean variables for all the possible precedences of the form (task +// i is before task j) and forces that, for each couple of task (i,j), either i +// is before j or j is before i. Do not create any other propagators. +std::function DisjunctiveWithBooleanPrecedencesOnly( + const std::vector& vars); + +// Same as Disjunctive() + DisjunctiveWithBooleanPrecedencesOnly(). +std::function DisjunctiveWithBooleanPrecedences( + const std::vector& vars); + +// Helper class to compute the end-min of a set of tasks given their start-min +// and duration-min. In Petr Vilim's PhD "Global Constraints in Scheduling", +// this corresponds to his Theta-tree except that we use a O(n) implementation +// for most of the function here, not a O(log(n)) one. +class TaskSet { + public: + TaskSet() : optimized_restart_(0) {} + struct Entry { + int task; + IntegerValue min_start; + IntegerValue min_duration; + + // Note that the tie-breaking is not important here. + bool operator<(Entry other) const { return min_start < other.min_start; } + }; + + // Insertion and modification. These leave sorted_tasks_ sorted. + void Clear() { + sorted_tasks_.clear(); + optimized_restart_ = 0; + } + void AddEntry(const Entry& e); + void NotifyEntryIsNowLastIfPresent(const Entry& e); + void RemoveEntryWithIndex(int index); + + // Like AddEntry() when we already know that e.min_start will be the largest + // one. This is checked in debug mode. + void AddOrderedLastEntry(const Entry& e); + + // Advanced usage. Instead of calling many AddEntry(), it is more efficient to + // call AddUnsortedEntry() instead, but then Sort() MUST be called just after + // the insertions. Nothing is checked here, so it is up to the client to do + // that properly. + void AddUnsortedEntry(const Entry& e) { sorted_tasks_.push_back(e); } + void Sort() { std::sort(sorted_tasks_.begin(), sorted_tasks_.end()); } + + // Returns the end-min for the task in the set. The time profile of the tasks + // packed to the left will always be a set of contiguous tasks separated by + // empty space: + // + // [Bunch of tasks] ... [Bunch of tasks] ... [critical tasks]. + // + // We call "critical tasks" the last group. These tasks will be solely + // responsible for for the end-min of the whole set. The returned + // critical_index will be the index of the first critical task in + // SortedTasks(). + // + // A reason for the min end is: + // - The duration-min of all the critical tasks. + // - The fact that all critical tasks have a start-min greater or equal to the + // first of them, that is SortedTasks()[critical_index].min_start. + // + // It is possible to behave like if one task was not in the set by setting + // task_to_ignore to the id of this task. This returns 0 if the set is empty + // in which case critical_index will be left unchanged. + IntegerValue ComputeEndMin(int task_to_ignore, int* critical_index) const; + const std::vector& SortedTasks() const { return sorted_tasks_; } + + private: + std::vector sorted_tasks_; + mutable int optimized_restart_; + DISALLOW_COPY_AND_ASSIGN(TaskSet); +}; + +// ============================================================================ +// Below are many of the known propagation techniques for the disjunctive, each +// implemented in only one time direction and in its own propagator class. The +// Disjunctive() model function above will instanciate the used ones (according +// to the solver parameters) in both time directions. +// +// See Petr Vilim PhD "Global Constraints in Scheduling" for a description of +// some of the algorithm. +// ============================================================================ + +class DisjunctiveOverloadChecker : public PropagatorInterface { + public: + DisjunctiveOverloadChecker(bool time_direction, + SchedulingConstraintHelper* helper) + : time_direction_(time_direction), helper_(helper), theta_tree_() { + // Resize this once and for all. + task_to_start_event_.resize(helper_->NumTasks()); + } + bool Propagate() final; + int RegisterWith(GenericLiteralWatcher* watcher); + + private: + const bool time_direction_; + SchedulingConstraintHelper* helper_; + ThetaLambdaTree theta_tree_; + std::vector task_to_start_event_; + std::vector start_event_to_task_; + std::vector start_event_time_; + std::vector start_event_is_present_; +}; + +class DisjunctiveDetectablePrecedences : public PropagatorInterface { + public: + DisjunctiveDetectablePrecedences(bool time_direction, + SchedulingConstraintHelper* helper) + : time_direction_(time_direction), helper_(helper) {} + bool Propagate() final; + int RegisterWith(GenericLiteralWatcher* watcher); + + private: + const bool time_direction_; + SchedulingConstraintHelper* helper_; + TaskSet task_set_; +}; + +class DisjunctiveNotLast : public PropagatorInterface { + public: + DisjunctiveNotLast(bool time_direction, SchedulingConstraintHelper* helper) + : time_direction_(time_direction), helper_(helper) {} + bool Propagate() final; + int RegisterWith(GenericLiteralWatcher* watcher); + + private: + const bool time_direction_; + SchedulingConstraintHelper* helper_; + TaskSet task_set_; +}; + +class DisjunctiveEdgeFinding : public PropagatorInterface { + public: + DisjunctiveEdgeFinding(bool time_direction, + SchedulingConstraintHelper* helper) + : time_direction_(time_direction), helper_(helper) {} + bool Propagate() final; + int RegisterWith(GenericLiteralWatcher* watcher); + + private: + const bool time_direction_; + SchedulingConstraintHelper* helper_; + TaskSet task_set_; + std::vector is_gray_; +}; + +// Exploits the precedences relations of the form "this set of disjoint +// IntervalVariables must be performed before a given IntegerVariable". The +// relations are computed with PrecedencesPropagator::ComputePrecedences(). +class DisjunctivePrecedences : public PropagatorInterface { + public: + DisjunctivePrecedences(bool time_direction, + SchedulingConstraintHelper* helper, + IntegerTrail* integer_trail, + PrecedencesPropagator* precedences) + : time_direction_(time_direction), + helper_(helper), + integer_trail_(integer_trail), + precedences_(precedences) {} + bool Propagate() final; + int RegisterWith(GenericLiteralWatcher* watcher); + + private: + const bool time_direction_; + SchedulingConstraintHelper* helper_; + IntegerTrail* integer_trail_; + PrecedencesPropagator* precedences_; + + TaskSet task_set_; + std::vector reason_for_beeing_before_; + std::vector before_; +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_DISJUNCTIVE_H_ diff --git a/thirdparty/linux/include/ortools/sat/drat.h b/thirdparty/linux/include/ortools/sat/drat.h new file mode 100644 index 0000000..d751773 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/drat.h @@ -0,0 +1,98 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_DRAT_H_ +#define OR_TOOLS_SAT_DRAT_H_ + +#include "ortools/base/file.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" + +namespace operations_research { +namespace sat { + +// DRAT is a SAT proof format that allows a simple program to check that the +// problem is really UNSAT. The description of the format and a checker are +// available at: // http://www.cs.utexas.edu/~marijn/drat-trim/ +// +// Note that DRAT proofs are often huge (can be GB), and take about as much time +// to check as it takes for the solver to find the proof in the first place! +class DratWriter { + public: + DratWriter(bool in_binary_format, File* output) + : variable_index_(0), + in_binary_format_(in_binary_format), + output_(output) {} + ~DratWriter(); + + // This tries to open the FLAGS_drat_file file and if it succeed it will + // return a non-nullptr DratWriter class. + static DratWriter* CreateInModel(Model* model); + + // During the presolve step, variable get deleted and the set of non-deleted + // variable is remaped in a dense set. This allows to keep track of that and + // always output the DRAT clauses in term of the original variables. + // + // TODO(user): This is exactly the same mecanism as in the SatPostsolver + // class. Factor out the code. + void ApplyMapping(const ITIVector& mapping); + + // This need to be called when new variables are created. + void SetNumVariables(int num_variables); + void AddOneVariable(); + + // Writes a new clause to the DRAT output. The output clause is sorted so that + // newer variables always comes first. This is needed because in the DRAT + // format, the clause is checked for the RAT property with only its first + // literal. + void AddClause(ClauseRef clause); + + // Writes a "deletion" information about a clause that has been added before + // to the DRAT output. Note that it is also possible to delete a clause from + // the problem. + // + // Because of a limitation a the DRAT-trim tool, it seems the order of the + // literals during addition and deletion should be EXACTLY the same. Because + // of that, we currently can't delete problem clauses since we don't keep the + // literal order in our memory representation. We use the ignore_call argument + // to simply do nothing by default, and we only set it to false in the places + // where we are sure the clause was outputed by an AddClause() call. + // + // TODO(user): an alternative would be to call AddClause() on all the problem + // clause first. + void DeleteClause(ClauseRef clause, bool ignore_call = true); + + private: + void WriteClause(ClauseRef clause); + + // We need to keep track of the variable newly created. + int variable_index_; + + // TODO(user): Support binary format as proof in text format can be large. + bool in_binary_format_; + File* output_; + + std::string buffer_; + + // Temporary vector used for sorting the outputed clauses. + std::vector values_; + + // This mapping will be applied to all clause passed to AddClause() or + // DeleteClause() so that they are in term of the original problem. + ITIVector reverse_mapping_; +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_DRAT_H_ diff --git a/thirdparty/linux/include/ortools/sat/encoding.h b/thirdparty/linux/include/ortools/sat/encoding.h new file mode 100644 index 0000000..d41d2d4 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/encoding.h @@ -0,0 +1,195 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Algorithms to encode constraints into their SAT representation. Currently, +// this contains one possible encoding of a cardinality constraint as used by +// the core-based optimization algorithm in optimization.h. + +#ifndef OR_TOOLS_SAT_ENCODING_H_ +#define OR_TOOLS_SAT_ENCODING_H_ + +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/sat_solver.h" + +namespace operations_research { +namespace sat { + +// This class represents a number in [0, ub]. The encoding uses ub binary +// variables x_i with i in [0, ub) where x_i means that the number is > i. It is +// called an EncodingNode, because it represents one node of the tree used to +// encode a cardinality constraint. +// +// In practice, not all literals are explicitly created: +// - Only the literals in [lb, current_ub) are "active" at a given time. +// - The represented number is known to be >= lb. +// - It may be greater than current_ub, but the extra literals will be only +// created lazily. In all our solves, the literal current_ub - 1, will always +// be assumed to false (i.e. the number will be <= current_ub - 1). +// - Note that lb may increase and ub decrease as more information is learned +// about this node by the sat solver. +// +// This is roughly based on the cardinality constraint encoding described in: +// Bailleux and Yacine Boufkhad, "Efficient CNF Encoding of Boolean Cardinality +// Constraints", In Proc. of CP 2003, pages 108-122, 2003. +class EncodingNode { + public: + EncodingNode() {} + + // Constructs a EncodingNode of size one, just formed by the given literal. + explicit EncodingNode(Literal l); + + // Creates a "full" encoding node on n new variables, the represented number + // beeing in [lb, ub = lb + n). The variables are added to the given solver + // with the basic implications linking them: + // literal(0) >= ... >= literal(n-1) + void InitializeFullNode(int n, EncodingNode* a, EncodingNode* b, + SatSolver* solver); + + // Creates a "lazy" encoding node representing the sum of a and b. + // Only one literals will be created by this operation. Note that no clauses + // linking it with a or b are added by this function. + void InitializeLazyNode(EncodingNode* a, EncodingNode* b, SatSolver* solver); + + // Returns a literal with the meaning 'this node number is > i'. + // The given i must be in [lb_, current_ub). + Literal GreaterThan(int i) const { return literal(i - lb_); } + + // Accessors to size() and literals in [lb, current_ub). + int size() const { return literals_.size(); } + Literal literal(int i) const { + CHECK_GE(i, 0); + CHECK_LT(i, literals_.size()); + return literals_[i]; + } + + // Sort by decreasing depth first and then by increasing variable index. + // This is meant to be used by the priority queue in MergeAllNodesWithPQ(). + bool operator<(const EncodingNode& other) const { + return depth_ > other.depth_ || + (depth_ == other.depth_ && other.for_sorting_ > for_sorting_); + } + + // Creates a new literals and increases current_ub. + // Returns false if we were already at the upper bound for this node. + bool IncreaseCurrentUB(SatSolver* solver); + + // Removes the left-side literals fixed to 1 and returns the number of + // literals removed this way. Note that this increases lb_ and reduces the + // number of active literals. It also removes any right-side literals fixed to + // 0. If such a literal exists, ub is updated accordingly. + int Reduce(const SatSolver& solver); + + // Fix the right-side variables with indices >= to the given upper_bound to + // false. + void ApplyUpperBound(int64 upper_bound, SatSolver* solver); + + void set_weight(Coefficient w) { weight_ = w; } + Coefficient weight() const { return weight_; } + + int depth() const { return depth_; } + int lb() const { return lb_; } + int current_ub() const { return lb_ + literals_.size(); } + int ub() const { return ub_; } + EncodingNode* child_a() const { return child_a_; } + EncodingNode* child_b() const { return child_b_; } + + private: + int depth_; + int lb_; + int ub_; + BooleanVariable for_sorting_; + + Coefficient weight_; + EncodingNode* child_a_; + EncodingNode* child_b_; + + // The literals of this node in order. + std::vector literals_; +}; + +// Note that we use <= because on 32 bits architecture, the size will actually +// be smaller than 64 bytes. +COMPILE_ASSERT(sizeof(EncodingNode) <= 64, + ERROR_EncodingNode_is_not_well_compacted); + +// Merges the two given EncodingNodes by creating a new node that corresponds to +// the sum of the two given ones. Only the left-most binary variable is created +// for the parent node, the other ones will be created later when needed. +EncodingNode LazyMerge(EncodingNode* a, EncodingNode* b, SatSolver* solver); + +// Increases the size of the given node by one. To keep all the needed relations +// with its children, we also need to increase their size by one, and so on +// recursively. Also adds all the necessary clauses linking the newly added +// literals. +void IncreaseNodeSize(EncodingNode* node, SatSolver* solver); + +// Merges the two given EncodingNode by creating a new node that corresponds to +// the sum of the two given ones. The given upper_bound is interpreted as a +// bound on this sum, and allows creating fewer binary variables. +EncodingNode FullMerge(Coefficient upper_bound, EncodingNode* a, + EncodingNode* b, SatSolver* solver); + +// Merges all the given nodes two by two until there is only one left. Returns +// the final node which encodes the sum of all the given nodes. +EncodingNode* MergeAllNodesWithDeque(Coefficient upper_bound, + const std::vector& nodes, + SatSolver* solver, + std::deque* repository); + +// Same as MergeAllNodesWithDeque() but use a priority queue to merge in +// priority nodes with smaller sizes. +EncodingNode* LazyMergeAllNodeWithPQ(const std::vector& nodes, + SatSolver* solver, + std::deque* repository); + +// Returns a vector with one new EncodingNode by variable in the given +// objective. Sets the offset to the negated sum of the negative coefficient, +// because in this case we negate the literals to have only positive +// coefficients. +std::vector CreateInitialEncodingNodes( + const std::vector& literals, + const std::vector& coeffs, Coefficient* offset, + std::deque* repository); +std::vector CreateInitialEncodingNodes( + const LinearObjective& objective_proto, Coefficient* offset, + std::deque* repository); + +// Reduces the nodes using the now fixed literals, update the lower-bound, and +// returns the set of assumptions for the next round of the core-based +// algorithm. Returns an empty set of assumptions if everything is fixed. +std::vector ReduceNodesAndExtractAssumptions( + Coefficient upper_bound, Coefficient stratified_lower_bound, + Coefficient* lower_bound, std::vector* nodes, + SatSolver* solver); + +// Returns the minimum weight of the nodes in the core. Note that the literal in +// the core must appear in the same order as the one in nodes. +Coefficient ComputeCoreMinWeight(const std::vector& nodes, + const std::vector& core); + +// Returns the maximum node weight under the given upper_bound. Returns zero if +// no such weight exist (note that a node weight is strictly positive, so this +// make sense). +Coefficient MaxNodeWeightSmallerThan(const std::vector& nodes, + Coefficient upper_bound); + +// Updates the encoding using the given core. The literals in the core must +// match the order in nodes. +void ProcessCore(const std::vector& core, Coefficient min_weight, + std::deque* repository, + std::vector* nodes, SatSolver* solver); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_ENCODING_H_ diff --git a/thirdparty/linux/include/ortools/sat/flow_costs.h b/thirdparty/linux/include/ortools/sat/flow_costs.h new file mode 100644 index 0000000..1882689 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/flow_costs.h @@ -0,0 +1,134 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_FLOW_COSTS_H_ +#define OR_TOOLS_SAT_FLOW_COSTS_H_ + +#include + +#include "ortools/linear_solver/linear_solver.h" +#include "ortools/sat/integer.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" + +namespace operations_research { +namespace sat { + +// Propagator for the flow-cost constraint, see the doc of FlowCostsConstraint() +// for a description. This use the LP relaxation to propagates bounds on the +// demands and possible flows. +// Inspired by Downing, Feydy & Stuckey "Explaining Flow-Based Propagation". +// https://doi.org/10.1007/978-3-642-29828-8_10 +// The Reduced Cost Strengthening technique is a classic in mixed integer +// programming, for instance see the thesis of Tobias Achterberg, +// "Constraint Integer Programming", sections 7.7 and 8.8, algorithm 7.11. +// http://nbn-resolving.de/urn:nbn:de:0297-zib-11129 +class FlowCosts : public PropagatorInterface { + public: + FlowCosts(const std::vector& demands, + const std::vector& flow, + const std::vector& tails, const std::vector& heads, + const std::vector>& arc_costs_per_cost_type, + const std::vector& costs, + IntegerTrail* integer_trail); + + bool Propagate() override; + + bool IncrementalPropagate(const std::vector& watch_indices) override; + + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + // Fills the deductions vector with reduced cost deductions + // that can be made from the current state of the LP solver. + // This should be called after Solve(): + // if the optimization was a minimization, the direction variable should be + // 1.0 and objective_delta the objective's upper bound minus the optimal; + // if the optimization was a maximization, direction should be -1.0 + // and objective_delta the optimal minus the objective's lower bound. + void ReducedCostStrengtheningDeductions(double direction, + double objective_delta); + + // Fills the integer_reason_ vector with literals that explain the current + // state of the LP solver, i.e. why it failed or why the optimal value cannot + // be better. Parameter direction should be 1.0 or -1.0, + // see ReducedCostStrengtheningDeductions(). + void FillIntegerReason(double direction); + + std::vector integer_reason_; + std::vector deductions_; + + const int num_nodes_; + const int num_arcs_; + const int num_costs_; + const int num_vars_; + static const double kEpsilon; + + // CP variables representing the flow cost. + std::vector demands_cp_; + std::vector flow_cp_; + std::vector total_costs_per_cost_type_cp_; + + IntegerTrail* integer_trail_; + + // Underlying LP solver and variables that mirror the CP variables. + MPSolver lp_solver_; + MPObjective* objective_lp_; + std::vector demands_lp_; + std::vector flow_lp_; + std::vector total_costs_per_cost_type_lp_; + MPVariable* violation_; + + // The propagator treats all variables the same way, thus we aggregate + // CP variables and LP variables to copy state from CP to LP easily, + // generate explanations, etc... + std::vector all_cp_variables_; + std::vector all_lp_variables_; + + // Current solution of the LP problem, + // that supports the existence of a CP solution. + // This is used to prevent fruitless LP solve(): + // as long as a CP bound change leaves the LP solution within bounds, + // the propagator will not find failure or deduce anything new. + std::vector lp_solution_; +}; + +// Given a graph whose arcs are given by tails/heads, +// enforces that flow variables model a flow respecting demands, +// and several costs reflecting flow usage. +// +// The input must be as follows: +// - demands must be a vector of num_nodes_ IntegerVariable, +// - flow must be a vector of num_arcs_ IntegerVariable, +// - tails and heads must be vectors of num_arcs_ ints within [0, num_nodes_), +// - arc_costs_per_cost_type must be a num_costs_ * num_arcs_ ints matrix. +// - total_costs_per_cost_type must be a vector of num_costs_ IntegerVariables, +// Note that all IntegerVariables can have arbitrary domain. +// +// Formally, the constraint enforces flow conservation: +// forall node, demands[node] - sum_{arc = node->_} flow[arc] +// + sum_{arc = _->node} flow[arc] = 0 +// +// It also enforces the costs for every cost type: forall c, +// costs[c] = sum_arc arc_cost[c][arc] * flow[arc]. +std::function FlowCostsConstraint( + const std::vector& demands, + const std::vector& flow, const std::vector& tails, + const std::vector& heads, + const std::vector>& arc_costs_per_cost_type, + const std::vector& total_costs_per_cost_type); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_FLOW_COSTS_H_ diff --git a/thirdparty/linux/include/ortools/sat/integer.h b/thirdparty/linux/include/ortools/sat/integer.h new file mode 100644 index 0000000..29896de --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/integer.h @@ -0,0 +1,1155 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_INTEGER_H_ +#define OR_TOOLS_SAT_INTEGER_H_ + +#include +#include + +#include "ortools/base/port.h" +#include "ortools/base/logging.h" +#include "ortools/base/join.h" +#include "ortools/base/int_type.h" +#include "ortools/base/map_util.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/util/bitset.h" +#include "ortools/util/iterators.h" +#include "ortools/util/rev.h" +#include "ortools/util/saturated_arithmetic.h" +#include "ortools/util/sorted_interval_list.h" + +namespace operations_research { +namespace sat { + +// Value type of an integer variable. An integer variable is always bounded +// on both sides, and this type is also used to store the bounds [lb, ub] of the +// range of each integer variable. +// +// Note that both bounds are inclusive, which allows to write many propagation +// algorithms for just one of the bound and apply it to the negated variables to +// get the symmetric algorithm for the other bound. +DEFINE_INT_TYPE(IntegerValue, int64); + +// The max range of an integer variable is [kMinIntegerValue, kMaxIntegerValue]. +// +// It is symmetric so the set of possible ranges stays the same when we take the +// negation of a variable. Moreover, we need some IntegerValue that fall outside +// this range on both side so that we can usally take care of integer overflow +// by simply doing "saturated arithmetic" and if one of the bound overflow, the +// two bounds will "cross" each others and we will get an empty range. +const IntegerValue kMaxIntegerValue( + std::numeric_limits::max() - 1); +const IntegerValue kMinIntegerValue(-kMaxIntegerValue); + +// IntegerValue version of the function in saturated_arithmetic.h +// +// The functions are not "sticky" to the min/max possible values so it is up to +// us to properly use them so that we never get an overflow and then go back to +// a feasible value. Hence the DCHECK(). +inline IntegerValue CapAdd(IntegerValue a, IntegerValue b) { + DCHECK(a >= kMinIntegerValue || b <= 0) << "Adding wrong sign to overflow."; + DCHECK(a <= kMaxIntegerValue || b >= 0) << "Adding wrong sign to overflow."; + DCHECK(b >= kMinIntegerValue || a <= 0) << "Adding wrong sign to overflow."; + DCHECK(b <= kMaxIntegerValue || a >= 0) << "Adding wrong sign to overflow."; + return IntegerValue(operations_research::CapAdd(a.value(), b.value())); +} +inline IntegerValue CapSub(IntegerValue a, IntegerValue b) { + DCHECK(a >= kMinIntegerValue || b >= 0) << "Adding wrong sign to overflow."; + DCHECK(a <= kMaxIntegerValue || b <= 0) << "Adding wrong sign to overflow."; + DCHECK(b >= kMinIntegerValue || a >= 0) << "Adding wrong sign to overflow."; + DCHECK(b <= kMaxIntegerValue || a <= 0) << "Adding wrong sign to overflow."; + return IntegerValue(operations_research::CapSub(a.value(), b.value())); +} + +// Index of an IntegerVariable. +// +// Each time we create an IntegerVariable we also create its negation. This is +// done like that so internally we only stores and deal with lower bound. The +// upper bound beeing the lower bound of the negated variable. +DEFINE_INT_TYPE(IntegerVariable, int32); +const IntegerVariable kNoIntegerVariable(-1); +inline IntegerVariable NegationOf(IntegerVariable i) { + return IntegerVariable(i.value() ^ 1); +} + +// Returns the vector of the negated variables. +std::vector NegationOf( + const std::vector& vars); + +class IntegerEncoder; +class IntegerTrail; + +// The integer equivalent of a literal. +// It represents an IntegerVariable and an upper/lower bound on it. +// +// Overflow: all the bounds below kMinIntegerValue and kMaxIntegerValue are +// treated as kMinIntegerValue - 1 and kMaxIntegerValue + 1. +struct IntegerLiteral { + // This default constructor is needed for std::vector. + IntegerLiteral() : var(-1), bound(0) {} + + // Because IntegerLiteral should never be created at a bound less constrained + // than an existing IntegerVariable bound, we don't allow GreaterOrEqual() to + // have a bound lower than kMinIntegerValue, and LowerOrEqual() to have a + // bound greater than kMaxIntegerValue. The other side is not constrained + // to allow for a computed bound to overflow. Note that both the full initial + // domain and the empty domain can always be represented. + static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound); + static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound); + + // The negation of x >= bound is x <= bound - 1. + IntegerLiteral Negated() const; + + bool operator==(IntegerLiteral o) const { + return var == o.var && bound == o.bound; + } + bool operator!=(IntegerLiteral o) const { + return var != o.var || bound != o.bound; + } + + IntegerVariable Var() const { return IntegerVariable(var); } + IntegerValue Bound() const { return bound; } + + std::string DebugString() const { + return StrCat("I", var, ">=", bound.value()); + } + + private: + friend class IntegerEncoder; + friend class IntegerTrail; + + IntegerLiteral(IntegerVariable v, IntegerValue b) : var(v.value()), bound(b) { + DCHECK_GE(bound, kMinIntegerValue); + DCHECK_LE(bound, kMaxIntegerValue + 1); + } + + // Our external API uses IntegerVariable but internally we only use an int for + // simplicity. TODO(user): change this? + // + // Note that bound is always in [kMinIntegerValue, kMaxIntegerValue + 1]. + /*const*/ int var; + /*const*/ IntegerValue bound; +}; + +inline std::ostream& operator<<(std::ostream& os, IntegerLiteral i_lit) { + os << i_lit.DebugString(); + return os; +} + +using InlinedIntegerLiteralVector = std::vector; + +// Each integer variable x will be associated with a set of literals encoding +// (x >= v) for some values of v. This class maintains the relationship between +// the integer variables and such literals which can be created by a call to +// CreateAssociatedLiteral(). +// +// The advantage of creating such Boolean variables is that the SatSolver which +// is driving the search can then take this variable as a decision and maintain +// these variables activity and so on. These variables can also be propagated +// directly by the learned clauses. +// +// This class also support a non-lazy full domain encoding which will create one +// literal per possible value in the domain. See FullyEncodeVariable(). This is +// meant to be called by constraints that directly work on the variable values +// like a table constraint or an all-diff constraint. +// +// TODO(user): We could also lazily create precedences Booleans between two +// arbitrary IntegerVariable. This is better done in the PrecedencesPropagator +// though. +class IntegerEncoder { + public: + explicit IntegerEncoder(SatSolver* sat_solver) + : sat_solver_(sat_solver), num_created_variables_(0) {} + + ~IntegerEncoder() { + VLOG(1) << "#variables created = " << num_created_variables_; + } + + static IntegerEncoder* CreateInModel(Model* model) { + SatSolver* sat_solver = model->GetOrCreate(); + IntegerEncoder* encoder = new IntegerEncoder(sat_solver); + model->TakeOwnership(encoder); + return encoder; + } + + // This has 3 effects: + // 1/ It restricts the given variable to only take values amongst the given + // ones. + // 2/ It creates one Boolean variable per value that convey the fact that the + // var is equal to this value iff the Boolean is true. If there is only + // 2 values, then just one Boolean variable is created. For more than two + // values, a constraint is also added to enforce that exactly one Boolean + // variable is true. + // 3/ The encoding for NegationOf(var) is automatically created too. It reuses + // the same Boolean variable as the encoding of var. + // + // Calling this more than once will take the intersection of all the given + // values arguments. However, this is not optimal because the first calls may + // creates new Boolean variables that will later be fixed, so we log a warning + // when this happen. Ideally, the intersection should be done in a presolve + // step to be as efficient as possible here. + // + // Note(user): There is currently no relation here between + // FullyEncodeVariable() and CreateAssociatedLiteral(). However the + // IntegerTrail class will automatically link the two representations and do + // the right thing. + // + // Note(user): Calling this with just one value will cause a CHECK fail. One + // need to fix the IntegerVariable inside the IntegerTrail instead of calling + // this. + // + // TODO(user): It is currently only possible to call that at the decision + // level zero. This is Checked. + void FullyEncodeVariable(IntegerVariable var, + std::vector values); + void FullyEncodeVariable(IntegerVariable var, IntegerValue lb, + IntegerValue ub); + + // Similar to FullyEncodeVariable() but use the given literal for each values. + // This can only be called on variable that are not fully encoded yet, This is + // checked. + // + // Note that duplicate values are supported, but exactly one literal must be + // true at the same time. The "exactly one" constraint will implicitely be + // enforced by the code in IntegerTrail. + void FullyEncodeVariableUsingGivenLiterals( + IntegerVariable var, const std::vector& literals, + const std::vector& values); + + // Gets the full encoding of a variable on which FullyEncodeVariable() has + // been called. The returned elements are always sorted by increasing + // IntegerValue. Once created, the encoding never changes, but some Boolean + // variables may become fixed. + // + // IMPORTANT: the returned vector will be sorted by value, but may contain + // duplicates values! IntegerTrail is doing the correct thing in this case. + // This allows us to direcly support the "int element" constraint and its + // variant at the core level. + struct ValueLiteralPair { + ValueLiteralPair(IntegerValue v, Literal l) : value(v), literal(l) {} + bool operator==(const ValueLiteralPair& o) const { + return value == o.value && literal == o.literal; + } + bool operator<(const ValueLiteralPair& o) const { return value < o.value; } + IntegerValue value; + Literal literal; + }; + const std::vector& FullDomainEncoding( + IntegerVariable var) const { + return full_encoding_[FindOrDie(full_encoding_index_, var)]; + } + + // Returns true if a variable is fully encoded. + bool VariableIsFullyEncoded(IntegerVariable var) const { + return ContainsKey(full_encoding_index_, var); + } + + // Returns the set of variable encoded as the keys in a map. The map values + // only have an internal meaning. The set of encoded variables is returned + // with this "weird" api for efficiency. + const std::unordered_map& GetFullyEncodedVariables() const { + return full_encoding_index_; + } + + // Creates a new Boolean variable 'var' such that + // - if true, then the IntegerLiteral is true. + // - if false, then the negated IntegerLiteral is true. + // + // Returns Literal(var, true). + // + // This add the proper implications with the two "neighbor" literals of this + // one if they exist. This is the "list encoding" in: Thibaut Feydy, Peter J. + // Stuckey, "Lazy Clause Generation Reengineered", CP 2009. + // + // It is an error to call this with an already created literal. This is + // Checked. + // + // The second version use the given literal instead of creating a new + // variable. + Literal CreateAssociatedLiteral(IntegerLiteral i_lit); + void AssociateGivenLiteral(IntegerLiteral i_lit, Literal wanted); + + // Return true iff the given integer literal is associated. + bool LiteralIsAssociated(IntegerLiteral i_lit) const; + + // Same as CreateAssociatedLiteral() but safe to call if already created. + Literal GetOrCreateAssociatedLiteral(IntegerLiteral i_lit); + + // Returns the IntegerLiterals that were associated with the given Literal. + const InlinedIntegerLiteralVector& GetIntegerLiterals(Literal lit) const { + if (lit.Index() >= reverse_encoding_.size()) { + return empty_integer_literal_vector_; + } + return reverse_encoding_[lit.Index()]; + } + + // Returns a Boolean literal associated with a bound lower than or equal to + // the one of the given IntegerLiteral. If the given IntegerLiteral is true, + // then the returned literal should be true too. Returns kNoLiteralIndex if no + // such literal was created. + // + // Ex: if 'i' is (x >= 4) and we already created a literal associated to + // (x >= 2) but not to (x >= 3), we will return the literal associated with + // (x >= 2). + LiteralIndex SearchForLiteralAtOrBefore(IntegerLiteral i) const; + + private: + // Adds the new associated_lit to encoding_by_var_. + // Adds the implications: Literal(before) <= associated_lit <= Literal(after). + void AddImplications(IntegerLiteral i, Literal associated_lit); + + SatSolver* sat_solver_; + int64 num_created_variables_; + + // We keep all the literals associated to an Integer variable in a map ordered + // by bound (so we can properly add implications between the literals + // corresponding to the same variable). + ITIVector> encoding_by_var_; + + // Store for a given LiteralIndex the list of its associated IntegerLiterals. + const InlinedIntegerLiteralVector empty_integer_literal_vector_; + ITIVector reverse_encoding_; + + // Full domain encoding. The map contains the index in full_encoding_ of + // the fully encoded variable. Each entry in full_encoding_ is sorted by + // IntegerValue and contains the encoding of one IntegerVariable. + std::unordered_map full_encoding_index_; + std::vector> full_encoding_; + + DISALLOW_COPY_AND_ASSIGN(IntegerEncoder); +}; + +// This class maintains a set of integer variables with their current bounds. +// Bounds can be propagated from an external "source" and this class helps +// to maintain the reason for each propagation. +class IntegerTrail : public SatPropagator { + public: + IntegerTrail(IntegerEncoder* encoder, Trail* trail) + : SatPropagator("IntegerTrail"), + num_enqueues_(0), + encoder_(encoder), + trail_(trail) {} + ~IntegerTrail() final {} + + static IntegerTrail* CreateInModel(Model* model) { + IntegerEncoder* encoder = model->GetOrCreate(); + Trail* trail = model->GetOrCreate(); + IntegerTrail* integer_trail = new IntegerTrail(encoder, trail); + model->GetOrCreate()->AddPropagator( + std::unique_ptr(integer_trail)); + return integer_trail; + } + + // SatPropagator interface. These functions make sure the current bounds + // information is in sync with the current solver literal trail. Any + // class/propagator using this class must make sure it is synced to the + // correct state before calling any of its functions. + bool Propagate(Trail* trail) final; + void Untrail(const Trail& trail, int literal_trail_index) final; + ClauseRef Reason(const Trail& trail, int trail_index) const final; + + // Returns the number of created integer variables. + // + // Note that this is twice the number of call to AddIntegerVariable() since + // we automatically create the NegationOf() variable too. + IntegerVariable NumIntegerVariables() const { + return IntegerVariable(vars_.size()); + } + + // Adds a new integer variable. Adding integer variable can only be done when + // the decision level is zero (checked). The given bounds are INCLUSIVE. + IntegerVariable AddIntegerVariable(IntegerValue lower_bound, + IntegerValue upper_bound); + + // Same as above but for a more complex domain specified as a sorted list of + // disjoint intervals. Note that the ClosedInterval struct use int64 instead + // of integer values (but we will convert them internally). + // + // Precondition: we check that IntervalsAreSortedAndDisjoint(domain) is true. + IntegerVariable AddIntegerVariable(const std::vector& domain); + + // Returns the initial domain of the given variable. Note that for variables + // whose domain is a single interval, this is updated with level zero + // propagations, but not if the domain is more complex. + std::vector InitialVariableDomain(IntegerVariable var) const; + + // Same as AddIntegerVariable(value, value), but this is a bit more efficient + // because it reuses another constant with the same value if its exist. + // + // Note(user): Creating constant integer variable is a bit wasteful, but not + // that much, and it allows to simplify a lot of constraints that do not need + // to handle this case any differently than the general one. Maybe there is a + // better solution, but this is not really high priority as of December 2016. + IntegerVariable GetOrCreateConstantIntegerVariable(IntegerValue value); + int NumConstantVariables() const; + + // Same as AddIntegerVariable() but uses the maximum possible range. Note + // that since we take negation of bounds in various places, we make sure that + // we don't have overflow when we take the negation of the lower bound or of + // the upper bound. + IntegerVariable AddIntegerVariable() { + return AddIntegerVariable(kMinIntegerValue, kMaxIntegerValue); + } + + // The domain [lb, ub] of an "optional" variable is allowed to be empty (i.e. + // ub < lb) if the given is_ignored literal is true. Moreover, if is_ignored + // is true, then the bound of such variable should NOT impact any non-ignored + // variable in any way (but the reverse is not true). + bool IsOptional(IntegerVariable i) const { + return is_ignored_literals_[i] != kNoLiteralIndex; + } + bool IsCurrentlyIgnored(IntegerVariable i) const { + const LiteralIndex is_ignored_literal = is_ignored_literals_[i]; + return is_ignored_literal != kNoLiteralIndex && + trail_->Assignment().LiteralIsTrue(Literal(is_ignored_literal)); + } + Literal IsIgnoredLiteral(IntegerVariable i) const { + DCHECK(IsOptional(i)); + return Literal(is_ignored_literals_[i]); + } + void MarkIntegerVariableAsOptional(IntegerVariable i, Literal is_considered) { + is_ignored_literals_[i] = is_considered.NegatedIndex(); + is_ignored_literals_[NegationOf(i)] = is_considered.NegatedIndex(); + } + + // Returns the current lower/upper bound of the given integer variable. + IntegerValue LowerBound(IntegerVariable i) const; + IntegerValue UpperBound(IntegerVariable i) const; + + // Returns the value of the lower bound before the last Enqueue() that changed + // it. Note that PreviousLowerBound() == LowerBound() iff this is the level + // zero bound. + IntegerValue PreviousLowerBound(IntegerVariable i) const; + + // Returns the integer literal that represent the current lower/upper bound of + // the given integer variable. + IntegerLiteral LowerBoundAsLiteral(IntegerVariable i) const; + IntegerLiteral UpperBoundAsLiteral(IntegerVariable i) const; + + // Enqueue new information about a variable bound. Calling this with a less + // restrictive bound than the current one will have no effect. + // + // The reason for this "assignment" must be provided as: + // - A set of Literal currently beeing all false. + // - A set of IntegerLiteral currently beeing all true. + // + // IMPORTANT: Notice the inversed sign in the literal reason. This is a bit + // confusing but internally SAT use this direction for efficiency. + // + // TODO(user): provide an API to give the reason lazily. + // + // TODO(user): If the given bound is equal to the current bound, maybe the new + // reason is better? how to decide and what to do in this case? to think about + // it. Currently we simply don't do anything. + MUST_USE_RESULT bool Enqueue( + IntegerLiteral bound, const std::vector& literal_reason, + const std::vector& integer_reason); + + // Enqueues the given literal on the trail. + // See the comment of Enqueue() for the reason format. + void EnqueueLiteral(Literal literal, + const std::vector& literal_reason, + const std::vector& integer_reason); + + // Returns the reason (as set of Literal currently false) for a given integer + // literal. Note that the bound must be less restrictive than the current + // bound (checked). + std::vector ReasonFor(IntegerLiteral bound) const; + + // Appends the reason for the given integer literals to the output and call + // STLSortAndRemoveDuplicates() on it. + void MergeReasonInto(const std::vector& bounds, + std::vector* output) const; + + // Returns the number of enqueues that changed a variable bounds. We don't + // count enqueues called with a less restrictive bound than the current one. + // + // Note(user): this can be used to see if any of the bounds changed. Just + // looking at the integer trail index is not enough because at level zero it + // doesn't change since we directly update the "fixed" bounds. + int64 num_enqueues() const { return num_enqueues_; } + + // All the registered bitsets will be set to one each time a LbVar is + // modified. It is up to the client to clear it if it wants to be notified + // with the newly modified variables. + void RegisterWatcher(SparseBitset* p) { + p->ClearAndResize(NumIntegerVariables()); + watchers_.push_back(p); + } + + // Helper functions to report a conflict. Always return false so a client can + // simply do: return integer_trail_->ReportConflict(...); + bool ReportConflict(const std::vector& literal_reason, + const std::vector& integer_reason) { + std::vector* conflict = trail_->MutableConflict(); + *conflict = literal_reason; + MergeReasonInto(integer_reason, conflict); + return false; + } + bool ReportConflict(const std::vector& integer_reason) { + std::vector* conflict = trail_->MutableConflict(); + conflict->clear(); + MergeReasonInto(integer_reason, conflict); + return false; + } + + // Returns true if the variable lower bound is still the one from level zero. + bool VariableLowerBoundIsFromLevelZero(IntegerVariable var) const { + return vars_[var.value()].current_trail_index < vars_.size(); + } + + private: + // Tests that all the literals in the given reason are assigned to false. + // This is used to DCHECK the given reasons to the Enqueue*() functions. + bool AllLiteralsAreFalse(const std::vector& literals) const; + + // Does the work of MergeReasonInto() when queue_ is already initialized. + void MergeReasonIntoInternal(std::vector* output) const; + + // Helper used by Enqueue() to propagate one of the literal associated to + // the given i_lit and maintained by encoder_. + bool EnqueueAssociatedLiteral( + Literal literal, IntegerLiteral i_lit, + const std::vector& literal_reason, + const std::vector& integer_reason, + BooleanVariable* variable_with_same_reason); + + // Returns a lower bound on the given var that will always be valid. + IntegerValue LevelZeroBound(int var) const { + // The level zero bounds are stored at the begining of the trail and they + // also serves as sentinels. Their index match the variables index. + return integer_trail_[var].bound; + } + + // Returns the lowest trail index of a TrailEntry that can be used to explain + // the given IntegerLiteral. The literal must be currently true (CHECKed). + // Returns -1 if the explanation is trivial. + int FindLowestTrailIndexThatExplainBound(IntegerLiteral bound) const; + + // Helper function to return the "dependencies" of a bound assignment. + // All the TrailEntry at these indices are part of the reason for this + // assignment. + BeginEndWrapper::const_iterator> Dependencies( + int trail_index) const; + + // Helper function to append the Literal part of the reason for this bound + // assignment. + void AppendLiteralsReason(int trail_index, + std::vector* output) const; + + // Returns some debuging info. + std::string DebugString(); + + // Information for each internal variable about its current bound. + struct VarInfo { + // The current bound on this variable. + IntegerValue current_bound; + + // Trail index of the last TrailEntry in the trail refering to this var. + int current_trail_index; + }; + std::vector vars_; + + // Used by GetOrCreateConstantIntegerVariable() to return already created + // constant variables that share the same value. + std::unordered_map constant_map_; + + // The integer trail. It always start by num_vars sentinel values with the + // level 0 bounds (in one to one correspondance with vars_). + struct TrailEntry { + IntegerValue bound; + int32 var; + int32 prev_trail_index; + + // Start index in the respective *_buffer_ vectors below. + int32 literals_reason_start_index; + int32 dependencies_start_index; + }; + std::vector integer_trail_; + + // Start of each decision levels in integer_trail_. + std::vector integer_decision_levels_; + + // Buffer to store the reason of each trail entry. + // Note that bounds_reason_buffer_ is an "union". It initially contains the + // IntegerLiteral, and is lazily replaced by the result of + // FindLowestTrailIndexThatExplainBound() applied to these literals. The + // encoding is a bit hacky, see Dependencies(). + std::vector literals_reason_buffer_; + mutable std::vector bounds_reason_buffer_; + + // The "is_ignored" literal of the optional variables or kNoLiteralIndex. + ITIVector is_ignored_literals_; + + // Data used to support the propagation of fully encoded variable. We keep + // for each variable the index in encoder_.GetDomainEncoding() of the first + // literal that is not assigned to false, and call this the "min". + int64 num_encoded_variables_ = 0; + std::vector tmp_literals_reason_; + RevGrowingMultiMap watched_min_; + RevMap> current_min_; + + // This is only filled for variables with a domain more complex than a single + // interval of values. All intervals are stored in a vector, and we keep + // indices to the current interval of the lower bound, and to the end index + // which is exclusive. + // + // TODO(user): Avoid using hash_map here and above, a simple vector should + // be more efficient. Except if there is really little variables like this. + // + // TODO(user): We could share the std::vector entry between a + // variable and its negations instead of having duplicates. + RevMap> var_to_current_lb_interval_index_; + std::unordered_map var_to_end_interval_index_; // const entries. + std::vector all_intervals_; // const entries. + + // Temporary data used by MergeReasonInto(). + mutable std::vector tmp_queue_; + mutable std::vector tmp_trail_indices_; + mutable std::vector tmp_var_to_highest_explained_trail_index_; + + // For EnqueueLiteral(), we store a special TrailEntry to recover the reason + // lazily. This vector indicates the correspondance between a literal that + // was pushed by this class at a given trail index, and the index of its + // TrailEntry in integer_trail_. + std::vector boolean_trail_index_to_integer_one_; + + int64 num_enqueues_; + + std::vector*> watchers_; + + IntegerEncoder* encoder_; + Trail* trail_; + + DISALLOW_COPY_AND_ASSIGN(IntegerTrail); +}; + +// Base class for CP like propagators. +// +// TODO(user): Think about an incremental Propagate() interface. +// +// TODO(user): Add shortcuts for the most used functions? like +// Min(IntegerVariable) and Max(IntegerVariable)? +class PropagatorInterface { + public: + PropagatorInterface() {} + virtual ~PropagatorInterface() {} + + // This will be called after one or more literals that are watched by this + // propagator changed. It will also always be called on the first propagation + // cycle after registration. + virtual bool Propagate() = 0; + + // This will only be called on a non-empty vector, otherwise Propagate() will + // be called. The passed vector will contain the "watch index" of all the + // literals that were given one at registration and that changed since the + // last call to Propagate(). This is only true when going down in the search + // tree, on backjump this list will be cleared. + // + // Notes: + // - The indices may contain duplicates if the same integer variable as been + // updated many times or if different watched literals have the same + // watch_index. + // - At level zero, it will not contain any indices associated with literals + // that where already fixed when the propagator was registered. Only the + // indices of the literals modified after the registration will be present. + virtual bool IncrementalPropagate(const std::vector& watch_indices) { + LOG(FATAL) << "Not implemented."; + return false; // Remove warning in Windows + } +}; + +// This class allows registering Propagator that will be called if a +// watched Literal or LbVar changes. +// +// TODO(user): Move this to its own file. Add unit tests! +class GenericLiteralWatcher : public SatPropagator { + public: + explicit GenericLiteralWatcher(IntegerTrail* trail, + RevRepository* rev_int_repository); + ~GenericLiteralWatcher() final {} + + static GenericLiteralWatcher* CreateInModel(Model* model) { + // TODO(user): Have a general mecanism to register "global" reversible + // classes and keep them synchronized with the search. + std::unique_ptr> rev_int_repository( + new RevRepository()); + GenericLiteralWatcher* watcher = new GenericLiteralWatcher( + model->GetOrCreate(), rev_int_repository.get()); + model->SetSingleton(std::move(rev_int_repository)); + + // TODO(user): This propagator currently needs to be last because it is the + // only one enforcing that a fix-point is reached on the integer variables. + // Figure out a better interaction between the sat propagation loop and + // this one. + model->GetOrCreate()->AddLastPropagator( + std::unique_ptr(watcher)); + return watcher; + } + + // On propagate, the registered propagators will be called if they need to + // until a fixed point is reached. Propagators with low ids will tend to be + // called first, but it ultimately depends on their "waking" order. + bool Propagate(Trail* trail) final; + void Untrail(const Trail& trail, int literal_trail_index) final; + + // Registers a propagator and returns its unique ids. + int Register(PropagatorInterface* propagator); + + // Changes the priority of the propagator with given id. The priority is a + // non-negative integer. Propagators with a lower priority will always be + // run before the ones with a higher one. The default priority is one. + void SetPropagatorPriority(int id, int priority); + + // The default behavior is to assume that a propagator does not need to be + // called twice in a row. However, propagators on which this is called will be + // called again if they change one of their own watched variables. + void NotifyThatPropagatorMayNotReachFixedPointInOnePass(int id); + + // Watches the corresponding quantity. The propagator with given id will be + // called if it changes. Note that WatchLiteral() only trigger when the + // literal becomes true. + // + // If watch_index is specified, it is associated with the watched literal. + // Doing this will cause IncrementalPropagate() to be called (see the + // documentation of this interface for more detail). + void WatchLiteral(Literal l, int id, int watch_index = -1); + void WatchLowerBound(IntegerVariable i, int id, int watch_index = -1); + void WatchUpperBound(IntegerVariable i, int id, int watch_index = -1); + void WatchIntegerVariable(IntegerVariable i, int id, int watch_index = -1); + + // No-op overload for "constant" IntegerVariable that are sometimes templated + // as an IntegerValue. + void WatchLowerBound(IntegerValue i, int id) {} + void WatchUpperBound(IntegerValue i, int id) {} + void WatchIntegerVariable(IntegerValue v, int id) {} + + // Registers a reversible class with a given propagator. This class will be + // changed to the correct state just before the propagator is called. + // + // Doing it just before should minimize cache-misses and bundle as much as + // possible the "backtracking" together. Many propagators only watches a + // few variables and will not be called at each decision levels. + void RegisterReversibleClass(int id, ReversibleInterface* rev); + + // Registers a reversible int with a given propagator. The int will be changed + // to its correct value just before Propagate() is called. + // + // Note that this will work in O(num_rev_int_of_propagator_id) per call to + // Propagate() and happens at most once per decision level. As such this is + // meant for classes that have just a few reversible ints or that will have a + // similar complexity anyway. + // + // Alternatively, one can directly get the underlying RevRepository with + // a call to model.Get<>(), and use SaveWithStamp() before each modification + // to have just a slight overhead per int updates. This later option is what + // is usually done in a CP solver at the cost of a sligthly more complex API. + void RegisterReversibleInt(int id, int* rev); + + // Returns the number of registered propagators. + int NumPropagators() const { return in_queue_.size(); } + + private: + // Updates queue_ and in_queue_ with the propagator ids that need to be + // called. + void UpdateCallingNeeds(Trail* trail); + + IntegerTrail* integer_trail_; + RevRepository* rev_int_repository_; + + struct WatchData { + int id; + int watch_index; + }; + ITIVector> literal_to_watcher_; + ITIVector> var_to_watcher_; + std::vector watchers_; + SparseBitset modified_vars_; + + // Propagator ids that needs to be called. There is one queue per priority but + // just one Boolean to indicate if a propagator is in one of them. + std::vector> queue_by_priority_; + std::vector in_queue_; + + // Data for each propagator. + std::vector id_to_level_at_last_call_; + std::vector id_to_greatest_common_level_since_last_call_; + std::vector> id_to_reversible_classes_; + std::vector> id_to_reversible_ints_; + std::vector> id_to_watch_indices_; + std::vector id_to_priority_; + std::vector id_to_idempotence_; + + DISALLOW_COPY_AND_ASSIGN(GenericLiteralWatcher); +}; + +// ============================================================================ +// Implementation. +// ============================================================================ + +inline IntegerLiteral IntegerLiteral::GreaterOrEqual(IntegerVariable i, + IntegerValue bound) { + return IntegerLiteral( + i, bound > kMaxIntegerValue ? kMaxIntegerValue + 1 : bound); +} + +inline IntegerLiteral IntegerLiteral::LowerOrEqual(IntegerVariable i, + IntegerValue bound) { + return IntegerLiteral( + NegationOf(i), bound < kMinIntegerValue ? kMaxIntegerValue + 1 : -bound); +} + +inline IntegerLiteral IntegerLiteral::Negated() const { + // Note that bound >= kMinIntegerValue, so -bound + 1 will have the correct + // capped value. + return IntegerLiteral( + NegationOf(IntegerVariable(var)), + bound > kMaxIntegerValue ? kMinIntegerValue : -bound + 1); +} + +inline IntegerValue IntegerTrail::LowerBound(IntegerVariable i) const { + return vars_[i.value()].current_bound; +} + +inline IntegerValue IntegerTrail::PreviousLowerBound(IntegerVariable i) const { + const int index = vars_[i.value()].current_trail_index; + if (index < vars_.size()) return LowerBound(i); + return integer_trail_[integer_trail_[index].prev_trail_index].bound; +} + +inline IntegerValue IntegerTrail::UpperBound(IntegerVariable i) const { + return -vars_[NegationOf(i).value()].current_bound; +} + +inline IntegerLiteral IntegerTrail::LowerBoundAsLiteral( + IntegerVariable i) const { + return IntegerLiteral::GreaterOrEqual(i, LowerBound(i)); +} + +inline IntegerLiteral IntegerTrail::UpperBoundAsLiteral( + IntegerVariable i) const { + return IntegerLiteral::LowerOrEqual(i, UpperBound(i)); +} + +inline void GenericLiteralWatcher::WatchLiteral(Literal l, int id, + int watch_index) { + if (l.Index() >= literal_to_watcher_.size()) { + literal_to_watcher_.resize(l.Index().value() + 1); + } + literal_to_watcher_[l.Index()].push_back({id, watch_index}); +} + +inline void GenericLiteralWatcher::WatchLowerBound(IntegerVariable var, int id, + int watch_index) { + if (var.value() >= var_to_watcher_.size()) { + var_to_watcher_.resize(var.value() + 1); + } + var_to_watcher_[var].push_back({id, watch_index}); +} + +inline void GenericLiteralWatcher::WatchUpperBound(IntegerVariable var, int id, + int watch_index) { + WatchLowerBound(NegationOf(var), id, watch_index); +} + +inline void GenericLiteralWatcher::WatchIntegerVariable(IntegerVariable i, + int id, + int watch_index) { + WatchLowerBound(i, id, watch_index); + WatchUpperBound(i, id, watch_index); +} + +// ============================================================================ +// Model based functions. +// +// Note that in the model API, we simply use int64 for the integer values, so +// that it is nicer for the client. Internally these are converted to +// IntegerValue which is typechecked. +// ============================================================================ + +inline std::function NewBooleanVariable() { + return [=](Model* model) { + return model->GetOrCreate()->NewBooleanVariable(); + }; +} + +inline std::function NewIntegerVariable() { + return [=](Model* model) { + return model->GetOrCreate()->AddIntegerVariable(); + }; +} + +inline std::function ConstantIntegerVariable( + int64 value) { + return [=](Model* model) { + return model->GetOrCreate() + ->GetOrCreateConstantIntegerVariable(IntegerValue(value)); + }; +} + +inline std::function NewIntegerVariable(int64 lb, + int64 ub) { + return [=](Model* model) { + CHECK_LE(lb, ub); + return model->GetOrCreate()->AddIntegerVariable( + IntegerValue(lb), IntegerValue(ub)); + }; +} + +inline std::function NewIntegerVariable( + const std::vector& domain) { + return [=](Model* model) { + return model->GetOrCreate()->AddIntegerVariable(domain); + }; +} + +// Constraints might not accept Literals as input, forcing the user to pass +// 0-1 integer views of a literal. +// This class contains all such literal views of a given model, so that asking +// for a view of a literal will always return the same IntegerVariable. +class LiteralViews { + public: + explicit LiteralViews(Model* model) : model_(model) {} + + static LiteralViews* CreateInModel(Model* model) { + LiteralViews* const views = new LiteralViews(model); + model->TakeOwnership(views); + return views; + } + + IntegerVariable GetIntegerView(const Literal lit) { + const LiteralIndex index = lit.Index(); + + if (!ContainsKey(literal_index_to_integer_, index)) { + const IntegerVariable int_var = model_->Add(NewIntegerVariable(0, 1)); + model_->GetOrCreate() + ->FullyEncodeVariableUsingGivenLiterals( + int_var, {lit.Negated(), lit}, + {IntegerValue(0), IntegerValue(1)}); + literal_index_to_integer_[index] = int_var; + } + + return literal_index_to_integer_[index]; + } + + private: + std::unordered_map literal_index_to_integer_; + Model* model_; +}; + +// Creates a 0-1 integer variable "view" of the given literal. It will have a +// value of 1 when the literal is true, and 0 when the literal is false. +inline std::function NewIntegerVariableFromLiteral( + Literal lit) { + return [=](Model* model) { + return model->GetOrCreate()->GetIntegerView(lit); + }; +} + +inline std::function LowerBound(IntegerVariable v) { + return [=](const Model& model) { + return model.Get()->LowerBound(v).value(); + }; +} + +inline std::function UpperBound(IntegerVariable v) { + return [=](const Model& model) { + return model.Get()->UpperBound(v).value(); + }; +} + +inline std::function IsFixed(IntegerVariable v) { + return [=](const Model& model) { + const IntegerTrail* trail = model.Get(); + return trail->LowerBound(v) == trail->UpperBound(v); + }; +} + +// This checks that the variable is fixed. +inline std::function Value(IntegerVariable v) { + return [=](const Model& model) { + const IntegerTrail* trail = model.Get(); + CHECK_EQ(trail->LowerBound(v), trail->UpperBound(v)) << v; + return trail->LowerBound(v).value(); + }; +} + +inline std::function GreaterOrEqual(IntegerVariable v, int64 lb) { + return [=](Model* model) { + if (!model->GetOrCreate()->Enqueue( + IntegerLiteral::GreaterOrEqual(v, IntegerValue(lb)), + std::vector(), std::vector())) { + model->GetOrCreate()->NotifyThatModelIsUnsat(); + LOG(WARNING) << "Model trivially infeasible, variable " << v + << " has upper bound " << model->Get(UpperBound(v)) + << " and GreaterOrEqual() was called with a lower bound of " + << lb; + } + }; +} + +inline std::function LowerOrEqual(IntegerVariable v, int64 ub) { + return [=](Model* model) { + if (!model->GetOrCreate()->Enqueue( + IntegerLiteral::LowerOrEqual(v, IntegerValue(ub)), + std::vector(), std::vector())) { + model->GetOrCreate()->NotifyThatModelIsUnsat(); + LOG(WARNING) << "Model trivially infeasible, variable " << v + << " has lower bound " << model->Get(LowerBound(v)) + << " and LowerOrEqual() was called with an upper bound of " + << ub; + } + }; +} + +// Fix v to a given value. +inline std::function Equality(IntegerVariable v, int64 value) { + return [=](Model* model) { + model->Add(LowerOrEqual(v, value)); + model->Add(GreaterOrEqual(v, value)); + }; +} + +// Associate the given literal to the given integer inequality. +inline std::function Equality(IntegerLiteral i, Literal l) { + return [=](Model* model) { + IntegerEncoder* encoder = model->GetOrCreate(); + if (encoder->LiteralIsAssociated(i)) { + const Literal current = encoder->GetOrCreateAssociatedLiteral(i); + model->Add(Equality(current, l)); + } else { + encoder->AssociateGivenLiteral(i, l); + } + }; +} + +// TODO(user): This is one of the rare case where it is better to use Equality() +// rather than two Implications(). Maybe we should modify our internal +// implementation to use half-reified encoding? that is do not propagate the +// direction integer-bound => literal, but just literal => integer-bound? This +// is the same as using different underlying variable for an integer literal and +// its negation. +inline std::function Implication(Literal l, IntegerLiteral i) { + return [=](Model* model) { + IntegerTrail* integer_trail = model->GetOrCreate(); + if (i.Bound() <= integer_trail->LowerBound(i.Var())) { + // Always true! nothing to do. + } else if (i.Bound() > integer_trail->UpperBound(i.Var())) { + // Always false. + model->Add(ClauseConstraint({l.Negated()})); + } else { + // TODO(user): Double check what happen when we associate a trivially + // true or false literal. This applies to Equality() too. + IntegerEncoder* encoder = model->GetOrCreate(); + const Literal current = encoder->GetOrCreateAssociatedLiteral(i); + model->Add(Implication(l, current)); + } + }; +} + +// in_interval <=> v in [lb, ub]. +inline std::function ReifiedInInterval(IntegerVariable v, + int64 lb, int64 ub, + Literal in_interval) { + return [=](Model* model) { + IntegerEncoder* encoder = model->GetOrCreate(); + const auto lb_lit = IntegerLiteral::GreaterOrEqual(v, IntegerValue(lb)); + const auto ub_lit = IntegerLiteral::LowerOrEqual(v, IntegerValue(ub)); + if (lb <= model->Get(LowerBound(v))) { + if (ub >= model->Get(UpperBound(v))) { + model->GetOrCreate()->AddUnitClause(in_interval); + } else { + model->Add(Equality(ub_lit, in_interval)); + } + } else if (ub >= model->Get(UpperBound(v))) { + model->Add(Equality(lb_lit, in_interval)); + } else { + const Literal is_ge_lb = encoder->GetOrCreateAssociatedLiteral(lb_lit); + const Literal is_le_ub = encoder->GetOrCreateAssociatedLiteral(ub_lit); + model->Add(ReifiedBoolAnd({is_ge_lb, is_le_ub}, in_interval)); + } + }; +} + +// Calling model.Add(FullyEncodeVariable(var)) will create one literal per value +// in the domain of var (if not already done), and wire everything correctly. +// This also returns the full encoding, see the FullDomainEncoding() method of +// the IntegerEncoder class. +inline std::function(Model*)> +FullyEncodeVariable(IntegerVariable var) { + return [=](Model* model) { + IntegerEncoder* encoder = model->GetOrCreate(); + if (!encoder->VariableIsFullyEncoded(var)) { + IntegerTrail* integer_trail = model->GetOrCreate(); + std::vector values; + for (const ClosedInterval interval : + integer_trail->InitialVariableDomain(var)) { + for (IntegerValue v(interval.start); v <= interval.end; ++v) { + values.push_back(v); + } + } + encoder->FullyEncodeVariable(var, values); + } + return encoder->FullDomainEncoding(var); + }; +} + +// A wrapper around SatSolver::Solve that handles integer variable with lazy +// encoding. Repeatedly calls SatSolver::Solve() on the model until the given +// next_decision() function return kNoLiteralIndex or the model is proved to +// be UNSAT. +// +// Returns the status of the last call to SatSolver::Solve(). +// +// Note that the next_decision() function must always return an unassigned +// literal or kNoLiteralIndex to end the search. +SatSolver::Status SolveIntegerProblemWithLazyEncoding( + const std::vector& assumptions, + const std::function& next_decision, Model* model); + +// Shortcut for SolveIntegerProblemWithLazyEncoding() when there is no +// assumption and we consider all variables in their index order for the next +// search decision. +SatSolver::Status SolveIntegerProblemWithLazyEncoding(Model* model); + +// Decision heuristic for SolveIntegerProblemWithLazyEncoding(). Returns a +// function that will return the literal corresponding to the fact that the +// first currently non-fixed variable value is <= its min. The function will +// return kNoLiteralIndex if all the given variables are fixed. +// +// Note that this function will create the associated literal if needed. +std::function FirstUnassignedVarAtItsMinHeuristic( + const std::vector& vars, Model* model); + +// Decision heuristic for SolveIntegerProblemWithLazyEncoding(). Like +// FirstUnassignedVarAtItsMinHeuristic() but the function will return the +// literal corresponding to the fact that the currently non-assigned variable +// with the lowest min has a value <= this min. +std::function UnassignedVarWithLowestMinAtItsMinHeuristic( + const std::vector& vars, Model* model); + +// Same as ExcludeCurrentSolutionAndBacktrack() but this version works for an +// integer problem with optional variables. The issue is that an optional +// variable that is ignored can basically take any value, and we don't really +// want to enumerate them. This function should exclude all solutions where +// only the ignored variable values change. +std::function +ExcludeCurrentSolutionWithoutIgnoredVariableAndBacktrack(); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_INTEGER_H_ diff --git a/thirdparty/linux/include/ortools/sat/integer_expr.h b/thirdparty/linux/include/ortools/sat/integer_expr.h new file mode 100644 index 0000000..e736346 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/integer_expr.h @@ -0,0 +1,543 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_INTEGER_EXPR_H_ +#define OR_TOOLS_SAT_INTEGER_EXPR_H_ + +#include "ortools/sat/integer.h" +#include "ortools/sat/model.h" +#include "ortools/sat/precedences.h" +#include "ortools/sat/sat_base.h" + +namespace operations_research { +namespace sat { + +// A really basic implementation of an upper-bounded sum of integer variables. +// The complexity is in O(num_variables) at each propagation. +// +// TODO(user): If one has many such constraint, it will be more efficient to +// propagate all of them at once rather than doing it one at the time. +// +// TODO(user): Handle integer overflow! The easiest is probably to check at +// construction that overflow cannot happen. +// +// TODO(user): Explore tree structure to get a log(n) complexity. +// +// TODO(user): When the variables are Boolean, use directly the pseudo-Boolean +// constraint implementation. +class IntegerSumLE : public PropagatorInterface { + public: + // If refied_literal is kNoLiteralIndex then this is a normal constraint, + // otherwise we enforce the implication refied_literal => constraint is true. + // Note that we don't do the reverse implication here, it is usually done by + // another IntegerSumLE constraint on the negated variables. + IntegerSumLE(LiteralIndex reified_literal, + const std::vector& vars, + const std::vector& coefficients, + IntegerValue upper_bound, Trail* trail, + IntegerTrail* integer_trail); + + // We propagate: + // - If the sum of the individual lower-bound is > upper_bound, we fail. + // - For all i, upper-bound of i + // <= upper_bound - Sum {individual lower-bound excluding i). + bool Propagate() final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + // Fills integer_reason_ with all the current lower_bounds. The real + // explanation may require removing one of them, but as an optimization, we + // always keep all the IntegerLiteral in integer_reason_, and swap them as + // needed just before pushing something. + void FillIntegerReason(); + + const LiteralIndex reified_literal_; // kNoLiteralIndex if not reified. + const IntegerValue upper_bound_; + + Trail* trail_; + IntegerTrail* integer_trail_; + + RevRepository rev_repository_integer_value_; + + // Reversible sum of the lower bound of the fixed variables. + IntegerValue rev_lb_fixed_vars_; + + // Reversible number of fixed variables. + int rev_num_fixed_vars_; + + // Those vectors are shuffled during search to ensure that the variables + // (resp. coefficients) contained in the range [0, rev_num_fixed_vars_) of + // vars_ (resp. coeffs_) are fixed (resp. belong to fixed variables). + std::vector vars_; + std::vector coeffs_; + + std::vector literal_reason_; + std::vector integer_reason_; + std::vector index_in_integer_reason_; + + DISALLOW_COPY_AND_ASSIGN(IntegerSumLE); +}; + +// A min (resp max) contraint of the form min == MIN(vars) can be decomposed +// into two inequalities: +// 1/ min <= MIN(vars), which is the same as for all v in vars, "min <= v". +// This can be taken care of by the LowerOrEqual(min, v) constraint. +// 2/ min >= MIN(vars). +// +// And in turn, 2/ can be decomposed in: +// a) lb(min) >= lb(MIN(vars)) = MIN(lb(var)); +// b) ub(min) >= ub(MIN(vars)) and we can't propagate anything here unless +// there is just one possible variable 'v' that can be the min: +// for all u != v, lb(u) > ub(min); +// In this case, ub(min) >= ub(v). +// +// This constraint take care of a) and b). That is: +// - If the min of the lower bound of the vars increase, then the lower bound of +// the min_var will be >= to it. +// - If there is only one candidate for the min, then if the ub(min) decrease, +// the ub of the only candidate will be <= to it. +// +// Complexity: This is a basic implementation in O(num_vars) on each call to +// Propagate(), which will happen each time one or more variables in vars_ +// changed. +// +// TODO(user): Implement a more efficient algorithm when the need arise. +class MinPropagator : public PropagatorInterface { + public: + MinPropagator(const std::vector& vars, + IntegerVariable min_var, IntegerTrail* integer_trail); + + bool Propagate() final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + const std::vector vars_; + const IntegerVariable min_var_; + IntegerTrail* integer_trail_; + + std::vector integer_reason_; + + DISALLOW_COPY_AND_ASSIGN(MinPropagator); +}; + +// Propagates a * b = c. Basic version, we don't extract any special cases, and +// we only propagates the bounds. +// +// TODO(user): For now this only works on variables that are non-negative. +// TODO(user): Deal with overflow. +class PositiveProductPropagator : public PropagatorInterface { + public: + PositiveProductPropagator(IntegerVariable a, IntegerVariable b, + IntegerVariable p, IntegerTrail* integer_trail); + + bool Propagate() final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + const IntegerVariable a_; + const IntegerVariable b_; + const IntegerVariable p_; + IntegerTrail* integer_trail_; + + DISALLOW_COPY_AND_ASSIGN(PositiveProductPropagator); +}; + +// Propagates a / b = c. Basic version, we don't extract any special cases, and +// we only propagates the bounds. +// +// TODO(user): For now this only works on variables that are non-negative. +// TODO(user): This only propagate the direction => c, do the reverse. +// TODO(user): Deal with overflow. +// TODO(user): Unit-test this like the ProductPropagator. +class DivisionPropagator : public PropagatorInterface { + public: + DivisionPropagator(IntegerVariable a, IntegerVariable b, IntegerVariable c, + IntegerTrail* integer_trail); + + bool Propagate() final; + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + const IntegerVariable a_; + const IntegerVariable b_; + const IntegerVariable c_; + IntegerTrail* integer_trail_; + + DISALLOW_COPY_AND_ASSIGN(DivisionPropagator); +}; + +// ============================================================================= +// Model based functions. +// ============================================================================= + +// Weighted sum <= constant. +template +inline std::function WeightedSumLowerOrEqual( + const std::vector& vars, const VectorInt& coefficients, + int64 upper_bound) { + // Special cases. + CHECK_GE(vars.size(), 1); + if (vars.size() == 1) { + CHECK_NE(coefficients[0], 0); + if (coefficients[0] > 0) { + return LowerOrEqual(vars[0], upper_bound / coefficients[0]); + } else { + return GreaterOrEqual(vars[0], upper_bound / coefficients[0]); + } + } + if (vars.size() == 2 && (coefficients[0] == 1 || coefficients[0] == -1) && + (coefficients[1] == 1 || coefficients[1] == -1)) { + return Sum2LowerOrEqual( + coefficients[0] == 1 ? vars[0] : NegationOf(vars[0]), + coefficients[1] == 1 ? vars[1] : NegationOf(vars[1]), upper_bound); + } + if (vars.size() == 3 && (coefficients[0] == 1 || coefficients[0] == -1) && + (coefficients[1] == 1 || coefficients[1] == -1) && + (coefficients[2] == 1 || coefficients[2] == -1)) { + return Sum3LowerOrEqual( + coefficients[0] == 1 ? vars[0] : NegationOf(vars[0]), + coefficients[1] == 1 ? vars[1] : NegationOf(vars[1]), + coefficients[2] == 1 ? vars[2] : NegationOf(vars[2]), upper_bound); + } + return [=](Model* model) { + IntegerSumLE* constraint = new IntegerSumLE( + kNoLiteralIndex, vars, + std::vector(coefficients.begin(), coefficients.end()), + IntegerValue(upper_bound), model->GetOrCreate(), + model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Weighted sum >= constant. +template +inline std::function WeightedSumGreaterOrEqual( + const std::vector& vars, const VectorInt& coefficients, + int64 lower_bound) { + // We just negate everything and use an <= constraints. + std::vector negated_coeffs(coefficients.begin(), coefficients.end()); + for (int64& ref : negated_coeffs) ref = -ref; + return WeightedSumLowerOrEqual(vars, negated_coeffs, -lower_bound); +} + +// Weighted sum == constant. +template +inline std::function FixedWeightedSum( + const std::vector& vars, const VectorInt& coefficients, + int64 value) { + return [=](Model* model) { + model->Add(WeightedSumGreaterOrEqual(vars, coefficients, value)); + model->Add(WeightedSumLowerOrEqual(vars, coefficients, value)); + }; +} + +// is_le => sum <= upper_bound +template +inline std::function ConditionalWeightedSumLowerOrEqual( + Literal is_le, const std::vector& vars, + const VectorInt& coefficients, int64 upper_bound) { + // Special cases. + CHECK_GE(vars.size(), 1); + if (vars.size() == 1) { + CHECK_NE(coefficients[0], 0); + if (coefficients[0] > 0) { + return Implication( + is_le, IntegerLiteral::LowerOrEqual( + vars[0], IntegerValue(upper_bound / coefficients[0]))); + } else { + return Implication( + is_le, IntegerLiteral::GreaterOrEqual( + vars[0], IntegerValue(upper_bound / coefficients[0]))); + } + } + if (vars.size() == 2 && (coefficients[0] == 1 || coefficients[0] == -1) && + (coefficients[1] == 1 || coefficients[1] == -1)) { + return ConditionalSum2LowerOrEqual( + coefficients[0] == 1 ? vars[0] : NegationOf(vars[0]), + coefficients[1] == 1 ? vars[1] : NegationOf(vars[1]), upper_bound, + is_le); + } + if (vars.size() == 3 && (coefficients[0] == 1 || coefficients[0] == -1) && + (coefficients[1] == 1 || coefficients[1] == -1) && + (coefficients[2] == 1 || coefficients[2] == -1)) { + return ConditionalSum3LowerOrEqual( + coefficients[0] == 1 ? vars[0] : NegationOf(vars[0]), + coefficients[1] == 1 ? vars[1] : NegationOf(vars[1]), + coefficients[2] == 1 ? vars[2] : NegationOf(vars[2]), upper_bound, + is_le); + } + return [=](Model* model) { + IntegerSumLE* constraint = new IntegerSumLE( + is_le.Index(), vars, + std::vector(coefficients.begin(), coefficients.end()), + IntegerValue(upper_bound), model->GetOrCreate(), + model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// is_ge => sum >= lower_bound +template +inline std::function ConditionalWeightedSumGreaterOrEqual( + Literal is_ge, const std::vector& vars, + const VectorInt& coefficients, int64 lower_bound) { + // We just negate everything and use an <= constraint. + std::vector negated_coeffs(coefficients.begin(), coefficients.end()); + for (int64& ref : negated_coeffs) ref = -ref; + return ConditionalWeightedSumLowerOrEqual(is_ge, vars, negated_coeffs, + -lower_bound); +} + +// Weighted sum <= constant reified. +template +inline std::function WeightedSumLowerOrEqualReif( + Literal is_le, const std::vector& vars, + const VectorInt& coefficients, int64 upper_bound) { + return [=](Model* model) { + model->Add(ConditionalWeightedSumLowerOrEqual(is_le, vars, coefficients, + upper_bound)); + model->Add(ConditionalWeightedSumGreaterOrEqual( + is_le.Negated(), vars, coefficients, upper_bound + 1)); + }; +} + +// Weighted sum >= constant reified. +template +inline std::function WeightedSumGreaterOrEqualReif( + Literal is_ge, const std::vector& vars, + const VectorInt& coefficients, int64 lower_bound) { + return [=](Model* model) { + model->Add(ConditionalWeightedSumGreaterOrEqual(is_ge, vars, coefficients, + lower_bound)); + model->Add(ConditionalWeightedSumLowerOrEqual( + is_ge.Negated(), vars, coefficients, lower_bound - 1)); + }; +} + +// Weighted sum == constant reified. +// TODO(user): Simplify if the constant is at the edge of the possible values. +template +inline std::function FixedWeightedSumReif( + Literal is_eq, const std::vector& vars, + const VectorInt& coefficients, int64 value) { + return [=](Model* model) { + // We creates two extra Boolean variables in this case. The alternative is + // to code a custom propagator for the direction equality => reified. + const Literal is_le = Literal(model->Add(NewBooleanVariable()), true); + const Literal is_ge = Literal(model->Add(NewBooleanVariable()), true); + model->Add(ReifiedBoolAnd({is_le, is_ge}, is_eq)); + model->Add(WeightedSumLowerOrEqualReif(is_le, vars, coefficients, value)); + model->Add(WeightedSumGreaterOrEqualReif(is_ge, vars, coefficients, value)); + }; +} + +// Weighted sum != constant. +// TODO(user): Simplify if the constant is at the edge of the possible values. +template +inline std::function WeightedSumNotEqual( + const std::vector& vars, const VectorInt& coefficients, + int64 value) { + return [=](Model* model) { + // Exactly one of these alternative must be true. + const Literal is_lt = Literal(model->Add(NewBooleanVariable()), true); + const Literal is_gt = is_lt.Negated(); + model->Add(ConditionalWeightedSumLowerOrEqual(is_lt, vars, coefficients, + value - 1)); + model->Add(ConditionalWeightedSumGreaterOrEqual(is_gt, vars, coefficients, + value + 1)); + }; +} + +// Model-based function to create an IntegerVariable that corresponds to the +// given weighted sum of other IntegerVariables. +// +// Note that this is templated so that it can seemlessly accept std::vector or +// std::vector. +// +// TODO(user): invert the coefficients/vars arguments. +template +inline std::function NewWeightedSum( + const VectorInt& coefficients, const std::vector& vars) { + return [=](Model* model) { + std::vector new_vars = vars; + // To avoid overflow in the FixedWeightedSum() constraint, we need to + // compute the basic bounds on the sum. + // + // TODO(user): deal with overflow here too! + int64 sum_lb(0); + int64 sum_ub(0); + for (int i = 0; i < new_vars.size(); ++i) { + if (coefficients[i] > 0) { + sum_lb += coefficients[i] * model->Get(LowerBound(new_vars[i])); + sum_ub += coefficients[i] * model->Get(UpperBound(new_vars[i])); + } else { + sum_lb += coefficients[i] * model->Get(UpperBound(new_vars[i])); + sum_ub += coefficients[i] * model->Get(LowerBound(new_vars[i])); + } + } + + const IntegerVariable sum = model->Add(NewIntegerVariable(sum_lb, sum_ub)); + new_vars.push_back(sum); + std::vector new_coeffs(coefficients.begin(), coefficients.end()); + new_coeffs.push_back(-1); + model->Add(FixedWeightedSum(new_vars, new_coeffs, 0)); + return sum; + }; +} + +// Expresses the fact that an existing integer variable is equal to the minimum +// of other integer variables. +inline std::function IsEqualToMinOf( + IntegerVariable min_var, const std::vector& vars) { + return [=](Model* model) { + for (const IntegerVariable& var : vars) { + model->Add(LowerOrEqual(min_var, var)); + } + + MinPropagator* constraint = + new MinPropagator(vars, min_var, model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Expresses the fact that an existing integer variable is equal to the maximum +// of other integer variables. +inline std::function IsEqualToMaxOf( + IntegerVariable max_var, const std::vector& vars) { + return [=](Model* model) { + std::vector negated_vars; + for (const IntegerVariable& var : vars) { + negated_vars.push_back(NegationOf(var)); + model->Add(GreaterOrEqual(max_var, var)); + } + + MinPropagator* constraint = new MinPropagator( + negated_vars, NegationOf(max_var), model->GetOrCreate()); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +// Creates an integer variable equal to the minimum of other integer variables. +inline std::function NewMin( + const std::vector& vars) { + return [=](Model* model) { + IntegerTrail* integer_trail = model->GetOrCreate(); + + // The trival bounds will be propagated correctly at level zero. + IntegerVariable min_var = integer_trail->AddIntegerVariable(); + model->Add(IsEqualToMinOf(min_var, vars)); + return min_var; + }; +} + +// Creates an IntegerVariable equal to the maximum of a set of IntegerVariables. +inline std::function NewMax( + const std::vector& vars) { + return [=](Model* model) { + IntegerTrail* integer_trail = model->GetOrCreate(); + + // The trival bounds will be propagated correctly at level zero. + IntegerVariable max_var = integer_trail->AddIntegerVariable(); + model->Add(IsEqualToMaxOf(max_var, vars)); + return max_var; + }; +} + +// Expresses the fact that an existing integer variable is equal to one of +// the given values, each selected by a given literal. +inline std::function IsOneOf( + IntegerVariable var, const std::vector& selectors, + const std::vector& values) { + return [=](Model* model) { + CHECK(!values.empty()); + CHECK_EQ(values.size(), selectors.size()); + IntegerValue min_value = values[0]; + IntegerValue max_value = values[1]; + for (const IntegerValue v : values) { + min_value = std::min(min_value, v); + max_value = std::max(max_value, v); + } + IntegerTrail* integer_trail = model->GetOrCreate(); + CHECK(integer_trail->Enqueue(IntegerLiteral::GreaterOrEqual(var, min_value), + {}, {})); + CHECK(integer_trail->Enqueue(IntegerLiteral::LowerOrEqual(var, max_value), + {}, {})); + + IntegerEncoder* encoder = model->GetOrCreate(); + if (!encoder->VariableIsFullyEncoded(var)) { + encoder->FullyEncodeVariableUsingGivenLiterals(var, selectors, values); + } else { + // TODO(user): copy the sat_fz_solver code of the int element here. + // And use this function instead because the first branch will be more + // efficient). + LOG(FATAL) << "TODO(fdid): Not implemented."; + } + }; +} + +template +void RegisterAndTransferOwnership(Model* model, T* ct) { + ct->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(ct); +} +// Adds the constraint: a * b = p. +inline std::function ProductConstraint(IntegerVariable a, + IntegerVariable b, + IntegerVariable p) { + return [=](Model* model) { + IntegerTrail* integer_trail = model->GetOrCreate(); + if (model->Get(LowerBound(a)) >= 0 && model->Get(LowerBound(b)) >= 0) { + RegisterAndTransferOwnership( + model, new PositiveProductPropagator(a, b, p, integer_trail)); + } else if (model->Get(LowerBound(a)) >= 0 && + model->Get(UpperBound(b)) <= 0) { + RegisterAndTransferOwnership( + model, new PositiveProductPropagator(a, NegationOf(b), NegationOf(p), + integer_trail)); + } else if (model->Get(UpperBound(a)) <= 0 && + model->Get(LowerBound(b)) >= 0) { + RegisterAndTransferOwnership( + model, new PositiveProductPropagator(NegationOf(a), b, NegationOf(p), + integer_trail)); + } else if (model->Get(UpperBound(a)) <= 0 && + model->Get(UpperBound(b)) <= 0) { + RegisterAndTransferOwnership( + model, new PositiveProductPropagator(NegationOf(a), NegationOf(b), p, + integer_trail)); + } else { + LOG(FATAL) << "Not supported"; + } + }; +} + +// Adds the constraint: a / b = d. +inline std::function DivisionConstraint(IntegerVariable a, + IntegerVariable b, + IntegerVariable c) { + return [=](Model* model) { + IntegerTrail* integer_trail = model->GetOrCreate(); + DivisionPropagator* constraint = + new DivisionPropagator(a, b, c, integer_trail); + constraint->RegisterWith(model->GetOrCreate()); + model->TakeOwnership(constraint); + }; +} + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_INTEGER_EXPR_H_ diff --git a/thirdparty/linux/include/ortools/sat/intervals.h b/thirdparty/linux/include/ortools/sat/intervals.h new file mode 100644 index 0000000..a6bcd80 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/intervals.h @@ -0,0 +1,479 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_INTERVALS_H_ +#define OR_TOOLS_SAT_INTERVALS_H_ + +#include "ortools/sat/cp_constraints.h" +#include "ortools/sat/integer.h" +#include "ortools/sat/integer_expr.h" +#include "ortools/sat/model.h" +#include "ortools/sat/precedences.h" +#include "ortools/sat/sat_base.h" +#include "ortools/sat/sat_solver.h" + +namespace operations_research { +namespace sat { + +DEFINE_INT_TYPE(IntervalVariable, int32); +const IntervalVariable kNoIntervalVariable(-1); + +// This class maintains a set of intervals which correspond to three integer +// variables (start, end and size). It automatically registers with the +// PrecedencesPropagator the relation between the bounds of each interval and +// provides many helper functions to add precedences relation between intervals. +class IntervalsRepository { + public: + IntervalsRepository(IntegerTrail* integer_trail, + PrecedencesPropagator* precedences) + : integer_trail_(integer_trail), precedences_(precedences) {} + + static IntervalsRepository* CreateInModel(Model* model) { + IntervalsRepository* intervals = + new IntervalsRepository(model->GetOrCreate(), + model->GetOrCreate()); + model->TakeOwnership(intervals); + return intervals; + } + + // Returns the current number of intervals in the repository. + // The interval will always be identified by an integer in [0, num_intervals). + int NumIntervals() const { return start_vars_.size(); } + + // Functions to add a new interval to the repository. + // - If size == kNoIntegerVariable, then the size is assumed to be fixed + // to fixed_size. + // - If is_present != kNoLiteralIndex, then this is an optional interval. + IntervalVariable CreateInterval(IntegerVariable start, IntegerVariable end, + IntegerVariable size, IntegerValue fixed_size, + LiteralIndex is_present); + + // Returns whether or not a interval is optional and the associated literal. + bool IsOptional(IntervalVariable i) const { + return is_present_[i] != kNoLiteralIndex; + } + Literal IsPresentLiteral(IntervalVariable i) const { + return Literal(is_present_[i]); + } + + // The 3 integer variables associated to a interval. + // Fixed size intervals will have a kNoIntegerVariable as size. + // + // Note: For an optional interval, the start/end variables are propagated + // asssuming the interval is present. Because of that, these variables can + // cross each other or have an empty domain. If any of this happen, then the + // IsPresentLiteral() of this interval will be propagated to false. + IntegerVariable SizeVar(IntervalVariable i) const { return size_vars_[i]; } + IntegerVariable StartVar(IntervalVariable i) const { return start_vars_[i]; } + IntegerVariable EndVar(IntervalVariable i) const { return end_vars_[i]; } + + // Return the minimum size of the given IntervalVariable. + IntegerValue MinSize(IntervalVariable i) const { + const IntegerVariable size_var = size_vars_[i]; + if (size_var == kNoIntegerVariable) return fixed_sizes_[i]; + return integer_trail_->LowerBound(size_var); + } + + // Return the maximum size of the given IntervalVariable. + IntegerValue MaxSize(IntervalVariable i) const { + const IntegerVariable size_var = size_vars_[i]; + if (size_var == kNoIntegerVariable) return fixed_sizes_[i]; + return integer_trail_->UpperBound(size_var); + } + + private: + // External classes needed. + IntegerTrail* integer_trail_; + PrecedencesPropagator* precedences_; + + // Literal indicating if the tasks is executed. Tasks that are always executed + // will have a kNoLiteralIndex entry in this vector. + ITIVector is_present_; + + // The integer variables for each tasks. + ITIVector start_vars_; + ITIVector end_vars_; + ITIVector size_vars_; + ITIVector fixed_sizes_; + + DISALLOW_COPY_AND_ASSIGN(IntervalsRepository); +}; + +// Helper class shared by the propagators that manage a given list of tasks. +// +// One of the main advantage of this class is that it allows to share the +// vectors of tasks sorted by various criteria between propagator for a faster +// code. +class SchedulingConstraintHelper { + public: + // All the functions below refer to a task by its index t in the tasks + // vector given at construction. + SchedulingConstraintHelper(const std::vector& tasks, + Trail* trail, IntegerTrail* integer_trail, + IntervalsRepository* intervals_repository); + + // Returns the number of task. + int NumTasks() const { return start_vars_.size(); } + + // Sets the time direction to either forward/backward. This will impact all + // the functions below. + void SetTimeDirection(bool is_forward); + + // Helpers for the current bounds on the current task time window. + // [(duration-min) ... (duration-min)] + // ^ ^ ^ ^ + // start-min end-min start-max end-max + // + // Note that for tasks with variable durations, we don't necessarily have + // duration-min between the the XXX-min and XXX-max value. + IntegerValue DurationMin(int t) const; + IntegerValue DurationMax(int t) const; + IntegerValue StartMin(int t) const; + IntegerValue StartMax(int t) const; + IntegerValue EndMin(int t) const; + IntegerValue EndMax(int t) const; + + // Returns true if the corresponding fact is known for sure. A normal task is + // always present. For optional task for which the presence is still unknown, + // both of these function will return false. + bool IsPresent(int t) const; + bool IsAbsent(int t) const; + + // Sorts and returns the tasks in corresponding order at the time of the call. + // Note that we do not mean strictly-increasing/strictly-decreasing, there + // will be duplicate time values in these vectors. + // + // TODO(user): we could merge the first loop of IncrementalSort() with the + // loop that fill TaskTime.time at each call. + struct TaskTime { + int task_index; + IntegerValue time; + bool operator<(TaskTime other) const { return time < other.time; } + bool operator>(TaskTime other) const { return time > other.time; } + }; + const std::vector& TaskByIncreasingStartMin(); + const std::vector& TaskByIncreasingEndMin(); + const std::vector& TaskByDecreasingStartMax(); + const std::vector& TaskByDecreasingEndMax(); + + // Functions to clear and then set the current reason. + void ClearReason(); + void AddPresenceReason(int t); + void AddDurationMinReason(int t); + void AddDurationMinReason(int t, IntegerValue lower_bound); + void AddStartMinReason(int t, IntegerValue lower_bound); + void AddStartMaxReason(int t, IntegerValue upper_bound); + void AddEndMinReason(int t, IntegerValue lower_bound); + void AddEndMaxReason(int t, IntegerValue upper_bound); + + // It is also possible to directly manipulates the underlying reason vectors + // that will be used when pushing something. + std::vector* MutableLiteralReason() { return &literal_reason_; } + std::vector* MutableIntegerReason() { + return &integer_reason_; + } + + // Push something using the current reason. Note that IncreaseStartMin() will + // also increase the end-min, and DecreaseEndMax() will also decrease the + // start-max. + bool IncreaseStartMin(int t, IntegerValue new_min_start); + bool DecreaseEndMax(int t, IntegerValue new_max_end); + void PushTaskAbsence(int t); + bool PushIntegerLiteral(IntegerLiteral bound); + bool ReportConflict(); + + // Returns the underlying integer variables. + const std::vector& StartVars() const { return start_vars_; } + const std::vector& EndVars() const { return end_vars_; } + + // Registers the given propagator id to be called if any of the tasks + // in this class change. + void WatchAllTasks(int id, GenericLiteralWatcher* watcher) const; + + private: + Trail* trail_; + IntegerTrail* integer_trail_; + + // All the underlying variables of the tasks. + // The vectors are indexed by the task index t. + std::vector start_vars_; + std::vector end_vars_; + std::vector duration_vars_; + std::vector fixed_durations_; + std::vector reason_for_presence_; + + // The current direction of time, true for forward, false for backward. + bool current_time_direction_; + + // The negation of the start/end variable so that SetTimeDirection() + // can do its job in O(1) instead of calling NegationOf() on each entry. + std::vector minus_start_vars_; + std::vector minus_end_vars_; + + // Sorted vectors returned by the TasksBy*() functions. + std::vector task_by_increasing_min_start_; + std::vector task_by_increasing_min_end_; + std::vector task_by_decreasing_max_start_; + std::vector task_by_decreasing_max_end_; + + // Reason vectors. + std::vector literal_reason_; + std::vector integer_reason_; +}; + +// ============================================================================= +// SchedulingConstraintHelper inlined functions. +// ============================================================================= + +inline IntegerValue SchedulingConstraintHelper::DurationMin(int t) const { + return duration_vars_[t] == kNoIntegerVariable + ? fixed_durations_[t] + : integer_trail_->LowerBound(duration_vars_[t]); +} + +inline IntegerValue SchedulingConstraintHelper::DurationMax(int t) const { + return duration_vars_[t] == kNoIntegerVariable + ? fixed_durations_[t] + : integer_trail_->UpperBound(duration_vars_[t]); +} + +inline IntegerValue SchedulingConstraintHelper::StartMin(int t) const { + return integer_trail_->LowerBound(start_vars_[t]); +} + +inline IntegerValue SchedulingConstraintHelper::StartMax(int t) const { + return integer_trail_->UpperBound(start_vars_[t]); +} + +inline IntegerValue SchedulingConstraintHelper::EndMin(int t) const { + return integer_trail_->LowerBound(end_vars_[t]); +} + +inline IntegerValue SchedulingConstraintHelper::EndMax(int t) const { + return integer_trail_->UpperBound(end_vars_[t]); +} + +inline bool SchedulingConstraintHelper::IsPresent(int t) const { + if (reason_for_presence_[t] == kNoLiteralIndex) return true; + return trail_->Assignment().LiteralIsTrue(Literal(reason_for_presence_[t])); +} + +inline bool SchedulingConstraintHelper::IsAbsent(int t) const { + if (reason_for_presence_[t] == kNoLiteralIndex) return false; + return trail_->Assignment().LiteralIsFalse(Literal(reason_for_presence_[t])); +} + +inline void SchedulingConstraintHelper::ClearReason() { + integer_reason_.clear(); + literal_reason_.clear(); +} + +inline void SchedulingConstraintHelper::AddPresenceReason(int t) { + if (reason_for_presence_[t] != kNoLiteralIndex) { + literal_reason_.push_back(Literal(reason_for_presence_[t]).Negated()); + } +} + +inline void SchedulingConstraintHelper::AddDurationMinReason(int t) { + if (duration_vars_[t] != kNoIntegerVariable) { + integer_reason_.push_back( + integer_trail_->LowerBoundAsLiteral(duration_vars_[t])); + } +} + +inline void SchedulingConstraintHelper::AddDurationMinReason( + int t, IntegerValue lower_bound) { + if (duration_vars_[t] != kNoIntegerVariable) { + integer_reason_.push_back( + IntegerLiteral::GreaterOrEqual(duration_vars_[t], lower_bound)); + } +} + +inline void SchedulingConstraintHelper::AddStartMinReason( + int t, IntegerValue lower_bound) { + integer_reason_.push_back( + IntegerLiteral::GreaterOrEqual(start_vars_[t], lower_bound)); +} + +inline void SchedulingConstraintHelper::AddStartMaxReason( + int t, IntegerValue upper_bound) { + integer_reason_.push_back( + IntegerLiteral::LowerOrEqual(start_vars_[t], upper_bound)); +} + +inline void SchedulingConstraintHelper::AddEndMinReason( + int t, IntegerValue lower_bound) { + integer_reason_.push_back( + IntegerLiteral::GreaterOrEqual(end_vars_[t], lower_bound)); +} + +inline void SchedulingConstraintHelper::AddEndMaxReason( + int t, IntegerValue upper_bound) { + integer_reason_.push_back( + IntegerLiteral::LowerOrEqual(end_vars_[t], upper_bound)); +} + +// ============================================================================= +// Model based functions. +// ============================================================================= + +inline std::function StartVar( + IntervalVariable v) { + return [=](const Model& model) { + return model.Get()->StartVar(v); + }; +} + +inline std::function EndVar(IntervalVariable v) { + return [=](const Model& model) { + return model.Get()->EndVar(v); + }; +} + +inline std::function SizeVar( + IntervalVariable v) { + return [=](const Model& model) { + return model.Get()->SizeVar(v); + }; +} + +inline std::function IsOptional(IntervalVariable v) { + return [=](const Model& model) { + return model.Get()->IsOptional(v); + }; +} + +inline std::function IsPresentLiteral( + IntervalVariable v) { + return [=](const Model& model) { + return model.Get()->IsPresentLiteral(v); + }; +} + +inline std::function NewInterval(int64 min_start, + int64 max_end, + int64 size) { + return [=](Model* model) { + return model->GetOrCreate()->CreateInterval( + model->Add(NewIntegerVariable(min_start, max_end)), + model->Add(NewIntegerVariable(min_start, max_end)), kNoIntegerVariable, + IntegerValue(size), kNoLiteralIndex); + }; +} + +inline std::function NewInterval( + IntegerVariable start, IntegerVariable end, IntegerVariable size) { + return [=](Model* model) { + return model->GetOrCreate()->CreateInterval( + start, end, size, IntegerValue(0), kNoLiteralIndex); + }; +} + +inline std::function NewIntervalWithVariableSize( + int64 min_start, int64 max_end, int64 min_size, int64 max_size) { + return [=](Model* model) { + return model->GetOrCreate()->CreateInterval( + model->Add(NewIntegerVariable(min_start, max_end)), + model->Add(NewIntegerVariable(min_start, max_end)), + model->Add(NewIntegerVariable(min_size, max_size)), IntegerValue(0), + kNoLiteralIndex); + }; +} + +inline std::function NewOptionalInterval( + int64 min_start, int64 max_end, int64 size, Literal is_present) { + return [=](Model* model) { + return model->GetOrCreate()->CreateInterval( + model->Add(NewIntegerVariable(min_start, max_end)), + model->Add(NewIntegerVariable(min_start, max_end)), kNoIntegerVariable, + IntegerValue(size), is_present.Index()); + }; +} + +inline std::function NewOptionalInterval( + IntegerVariable start, IntegerVariable end, IntegerVariable size, + Literal is_present) { + return [=](Model* model) { + return model->GetOrCreate()->CreateInterval( + start, end, size, IntegerValue(0), is_present.Index()); + }; +} + +inline std::function NewIntervalFromStartAndSizeVars( + IntegerVariable start, IntegerVariable size) { + return [=](Model* model) { + // Create the "end" variable. + // TODO(user): deal with overflow. + IntegerTrail* t = model->GetOrCreate(); + const IntegerValue end_lb = t->LowerBound(start) + t->LowerBound(size); + const IntegerValue end_ub = t->UpperBound(start) + t->UpperBound(size); + const IntegerVariable end = t->AddIntegerVariable(end_lb, end_ub); + return model->GetOrCreate()->CreateInterval( + start, end, size, IntegerValue(0), kNoLiteralIndex); + }; +} + +// This requires that all the alternatives are optional tasks. +inline std::function IntervalWithAlternatives( + IntervalVariable master, const std::vector& members) { + return [=](Model* model) { + IntervalsRepository* intervals = model->GetOrCreate(); + + std::vector presences; + std::vector durations; + + // Create an "exactly one executed" constraint on the alternatives. + std::vector sat_ct; + for (const IntervalVariable member : members) { + CHECK(intervals->IsOptional(member)); + const Literal is_present = intervals->IsPresentLiteral(member); + sat_ct.push_back({is_present, Coefficient(1)}); + model->Add( + Equality(model->Get(StartVar(master)), model->Get(StartVar(member)))); + model->Add( + Equality(model->Get(EndVar(master)), model->Get(EndVar(member)))); + + // TODO(user): IsOneOf() only work for members with fixed size. + // Generalize to an "int_var_element" constraint. + CHECK_EQ(intervals->SizeVar(member), kNoIntegerVariable); + presences.push_back(is_present); + durations.push_back(intervals->MinSize(member)); + } + if (intervals->SizeVar(master) != kNoIntegerVariable) { + model->Add(IsOneOf(intervals->SizeVar(master), presences, durations)); + } + model->Add(BooleanLinearConstraint(1, 1, &sat_ct)); + + // Propagate from the candidate bounds to the master interval ones. + { + std::vector starts; + for (const IntervalVariable member : members) { + starts.push_back(intervals->StartVar(member)); + } + model->Add( + PartialIsOneOfVar(intervals->StartVar(master), starts, presences)); + } + { + std::vector ends; + for (const IntervalVariable member : members) { + ends.push_back(intervals->EndVar(member)); + } + model->Add(PartialIsOneOfVar(intervals->EndVar(master), ends, presences)); + } + }; +} + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_INTERVALS_H_ diff --git a/thirdparty/linux/include/ortools/sat/linear_programming_constraint.h b/thirdparty/linux/include/ortools/sat/linear_programming_constraint.h new file mode 100644 index 0000000..3be12a8 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/linear_programming_constraint.h @@ -0,0 +1,178 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_LINEAR_PROGRAMMING_CONSTRAINT_H_ +#define OR_TOOLS_SAT_LINEAR_PROGRAMMING_CONSTRAINT_H_ + +#include +#include + +#include "ortools/glop/revised_simplex.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/sat/integer.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" + +namespace operations_research { +namespace sat { + +// A SAT constraint that enforces a set of linear inequality constraints on +// integer variables using an LP solver. +// +// The propagator uses glop's revised simplex for feasibility and propagation. +// It uses the Reduced Cost Strengthening technique, a classic in mixed integer +// programming, for instance see the thesis of Tobias Achterberg, +// "Constraint Integer Programming", sections 7.7 and 8.8, algorithm 7.11. +// http://nbn-resolving.de/urn:nbn:de:0297-zib-11129 +// Feasibility propagation is done with this technique by setting total +// constraint violation as an objective, i.e. by dualizing all constraints. +// Per-constraint bounds propagation is NOT done by this constraint, +// it should be done by redundant constraints, as reduced cost propagation +// may miss some filtering. +// +// Workflow: create a LinearProgrammingConstraint instance, make linear +// inequality constraints, call RegisterWith() to finalize the set of linear +// constraints. A linear constraint a x + b y + c z <= k, with x y z +// IntegerVariables, can be created by calling: +// auto ct = lp->CreateNewConstraint(-std::numeric_limits::infinity(), +// k); +// lp->SetCoefficient(ct, x, a); +// lp->SetCoefficient(ct, y, b); +// lp->SetCoefficient(ct, z, c); +// +// Note that this constraint works with double floating-point numbers, so one +// could be worried that it may filter too much in case of precision issues. +// However, the underlying LP solver reports infeasibility only if the problem +// is still infeasible by relaxing the bounds by some small relative value. +// Thus the constraint will tend to filter less than it could, not the opposite. +// +// TODO(user): Work with scaled version of the model, maybe by using +// LPSolver instead of RevisedSimplex. +class LinearProgrammingConstraint : public PropagatorInterface { + public: + typedef glop::RowIndex ConstraintIndex; + + explicit LinearProgrammingConstraint(IntegerTrail* integer_trail); + + // Creates a LinearProgrammingConstraint for templated GetOrCreate idiom. + static LinearProgrammingConstraint* CreateInModel(Model* model) { + IntegerTrail* trail = model->GetOrCreate(); + LinearProgrammingConstraint* constraint = + new LinearProgrammingConstraint(trail); + model->TakeOwnership(constraint); + return constraint; + } + + // User API, see header description. + ConstraintIndex CreateNewConstraint(double lb, double ub); + + void SetCoefficient(ConstraintIndex ct, IntegerVariable ivar, + double coefficient); + + // TODO(user): Allow Literals to appear in linear constraints. + // TODO(user): Calling SetCoefficient() twice on the same + // (constraint, variable) pair will overwrite coefficients where accumulating + // them might be desired, this is a common mistake, change API. + + // Objective may or may not be defined. It can be defined only once, + // must be exactly one IntegerVariable, and can be either + // minimized (is_minimization = true) or maximized (is_minimization = false). + // TODO(user): change API for always minimization, so that + // maximization(var) = minimization(Negation(var)). + void SetObjective(IntegerVariable ivar, bool is_minimization); + + // PropagatorInterface API. + bool Propagate() override; + + bool IncrementalPropagate(const std::vector& watch_indices) override; + + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + // Generates a set of IntegerLiterals explaining why the best solution can not + // be improved using reduced costs. This is used to generate explanations for + // both infeasibility and bounds deductions. The direction variable should be + // 1.0 if the last Solve() was a minimization, -1.0 if it was a maximization. + void FillIntegerReason(double direction); + + // Same as FillIntegerReason() but for the case of a DUAL_UNBOUNDED problem. + // This exploit the dual ray as a reason for the primal infeasiblity. + void FillDualRayReason(); + + // Fills the deductions vector with reduced cost deductions that can be made + // from the current state of the LP solver. This should be called after + // Solve(): if the optimization was a minimization, the direction variable + // should be 1.0 and lp_objective_delta the objective's upper bound minus the + // optimal; if the optimization was a maximization, direction should be -1.0 + // and lp_objective_delta the optimal minus the objective's lower bound. + void ReducedCostStrengtheningDeductions(double direction, + double lp_objective_delta); + + // Gets or creates an LP variable that mirrors a CP variable. + // TODO(user): only accept positive variables to prevent having different + // LP variables for the same CP variable. + glop::ColIndex GetOrCreateMirrorVariable(IntegerVariable ivar); + + // Returns the variable value on the same scale as the CP variable value. + glop::Fractional GetVariableValueAtCpScale(glop::ColIndex var); + + // TODO(user): use solver's precision epsilon. + static const double kEpsilon; + + // Underlying LP solver API. + glop::LinearProgram lp_data_; + glop::RevisedSimplex simplex_; + + // For the scaling. + glop::SparseMatrixScaler scaler_; + + // violation_sum_ is used to simulate phase I of the simplex and be able to + // do reduced cost strengthening on problem feasibility by using the sum of + // constraint violations as an optimization objective. + glop::ColIndex violation_sum_; + ConstraintIndex violation_sum_constraint_; + + // Structures used for mirroring IntegerVariables inside the underlying LP + // solver: integer_variables_[i] is mirrored by mirror_lp_variables_[i], + // both are used in IncrementalPropagate() and Propagate() calls; + // integer_variable_to_index_ is used to find which mirroring variable's + // coefficient must be modified on SetCoefficient(). + std::unordered_map integer_variable_to_index_; + std::vector integer_variables_; + std::vector mirror_lp_variables_; + + // We need to remember what to optimize if an objective is given, because + // then we will switch the objective between feasibility and optimization. + bool objective_is_defined_ = false; + IntegerVariable objective_cp_; + glop::ColIndex objective_lp_; + bool objective_is_minimization_; + + // Structures for propagators. + IntegerTrail* integer_trail_; + std::vector integer_reason_; + std::vector deductions_; + + // Last solution found by a call to the underlying LP solver. + // On IncrementalPropagate(), if the bound updates do not invalidate this + // solution, Propagate() will not find domain reductions, no need to call it. + std::vector lp_solution_; + + // Linear constraints cannot be created or modified after this is registered. + bool lp_constraint_is_registered_ = false; +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_LINEAR_PROGRAMMING_CONSTRAINT_H_ diff --git a/thirdparty/linux/include/ortools/sat/lp_utils.h b/thirdparty/linux/include/ortools/sat/lp_utils.h new file mode 100644 index 0000000..d845a1e --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/lp_utils.h @@ -0,0 +1,60 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Utility functions to interact with an lp solver from the SAT context. + +#ifndef OR_TOOLS_SAT_LP_UTILS_H_ +#define OR_TOOLS_SAT_LP_UTILS_H_ + +#include "ortools/linear_solver/linear_solver.pb.h" +#include "ortools/lp_data/lp_data.h" +#include "ortools/sat/boolean_problem.pb.h" +#include "ortools/sat/sat_solver.h" + +namespace operations_research { +namespace sat { + +// Converts an integer program with only binary variables to a Boolean +// optimization problem. Returns false if the problem didn't contains only +// binary integer variable, or if the coefficients couldn't be converted to +// integer with a good enough precision. +bool ConvertBinaryMPModelProtoToBooleanProblem(const MPModelProto& mp_model, + LinearBooleanProblem* problem); + +// Converts a Boolean optimization problem to its lp formulation. +void ConvertBooleanProblemToLinearProgram(const LinearBooleanProblem& problem, + glop::LinearProgram* lp); + +// Changes the variable bounds of the lp to reflect the variables that have been +// fixed by the SAT solver (i.e. assigned at decision level 0). Returns the +// number of variables fixed this way. +int FixVariablesFromSat(const SatSolver& solver, glop::LinearProgram* lp); + +// Solves the given lp problem and uses the lp solution to drive the SAT solver +// polarity choices. The variable must have the same index in the solved lp +// problem and in SAT for this to make sense. +// +// Returns false if a problem occured while trying to solve the lp. +bool SolveLpAndUseSolutionForSatAssignmentPreference( + const glop::LinearProgram& lp, SatSolver* sat_solver, + double max_time_in_seconds); + +// Solves the lp and add constraints to fix the integer variable of the lp in +// the LinearBoolean problem. +bool SolveLpAndUseIntegerVariableToStartLNS(const glop::LinearProgram& lp, + LinearBooleanProblem* problem); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_LP_UTILS_H_ diff --git a/thirdparty/linux/include/ortools/sat/model.h b/thirdparty/linux/include/ortools/sat/model.h new file mode 100644 index 0000000..ad4aae0 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/model.h @@ -0,0 +1,157 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_MODEL_H_ +#define OR_TOOLS_SAT_MODEL_H_ + +#include +#include +#include +#include + +#include "ortools/base/map_util.h" +#include "ortools/base/typeid.h" + +namespace operations_research { +namespace sat { + +// Class that owns everything related to a particular optimization model. +// +// This class is actually a fully generic wrapper that can hold any type of +// constraints, watchers, solvers and provide a mecanism to wire them together. +class Model { + public: + Model() {} + + // This allows to have a nicer API on the client side, and it allows both of + // these forms: + // - ConstraintCreationFunction(contraint_args, &model); + // - model.Add(ConstraintCreationFunction(contraint_args)); + // + // The second form is a bit nicer for the client and it also allows to store + // constraints and add them later. However, the function creating the + // constraint is slighly more involved: + // + // std::function ConstraintCreationFunction(contraint_args) { + // return [=] (Model* model) { + // ... the same code ... + // }; + // } + // + // We also have a templated return value for the functions that need it like + // const BooleanVariable b = model.Add(NewBooleanVariable()); + // const IntegerVariable i = model.Add(NewWeightedSum(weigths, variables)); + template + T Add(std::function f) { + return f(this); + } + + // Similar to Add() but this is const. + template + T Get(std::function f) const { + return f(*this); + } + + // Returns an object of type T that is unique to this model (this is a bit + // like a "local" singleton). This returns an already created instance or + // create a new one if needed using the T::CreateInModel(Model* model) + // function of the class T. + // + // This works a bit like in a dependency injection framework and allows to + // really easily wire all the classes that make up a solver together. For + // instance a constraint can depends on the LiteralTrail, or the IntegerTrail + // or both, it can depend on a Watcher class to register itself in order to + // be called when needed and so on. + // + // IMPORTANT: the CreateInModel() functiond shouldn't form a cycle between + // each other, otherwise this will crash the program. + template + T* GetOrCreate() { + const size_t type_id = FastTypeId(); + if (!ContainsKey(singletons_, type_id)) { + // Note that it is up to CreateInModel() to call model->TakeOwnership() + // of the returned pointer. + // + // TODO(user): Always take ownership of the pointer instead. That would + // requires some cleanup, but it is probably a safer solution and would + // allow SetSingleton() to change an instance dynamically. + T* new_t = T::CreateInModel(this); + singletons_[type_id] = new_t; + return new_t; + } + return static_cast(FindOrDie(singletons_, type_id)); + } + + // Registers a given instance of type T as a "local singleton" for this type. + // For now this CHECKs that the object was not yet created. + template + void SetSingleton(std::unique_ptr t) { + const size_t type_id = FastTypeId(); + CHECK(!ContainsKey(singletons_, type_id)); + singletons_[type_id] = t.get(); + TakeOwnership(t.release()); + } + + // Likes GetOrCreate() but do not create the object if it is non-existing. + // This returns a const version of the object. + template + const T* Get() const { + return static_cast( + FindWithDefault(singletons_, FastTypeId(), nullptr)); + } + + // Same as Get(), but returns a mutable version of the object. + template + T* Mutable() const { + return static_cast( + FindWithDefault(singletons_, FastTypeId(), nullptr)); + } + + // Gives ownership of a pointer to this model. + // It will be destroyed when the model is. + template + void TakeOwnership(T* t) { + cleanup_list_.emplace_back(new Delete(t)); + } + + private: + // Map of FastTypeId to a "singleton" of type T. + std::map singletons_; + + struct DeleteInterface { + virtual ~DeleteInterface() = default; + }; + template + class Delete : public DeleteInterface { + public: + explicit Delete(T* t) : to_delete_(t) {} + ~Delete() override = default; + + private: + std::unique_ptr to_delete_; + }; + + // The list of items to delete. + // + // TODO(user): I don't think we need the two layers of unique_ptr, but we + // don't care too much about efficiency here and this was easier to get + // working. + std::vector> cleanup_list_; + + DISALLOW_COPY_AND_ASSIGN(Model); +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_MODEL_H_ diff --git a/thirdparty/linux/include/ortools/sat/no_cycle.h b/thirdparty/linux/include/ortools/sat/no_cycle.h new file mode 100644 index 0000000..3500427 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/no_cycle.h @@ -0,0 +1,184 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_NO_CYCLE_H_ +#define OR_TOOLS_SAT_NO_CYCLE_H_ + +#include + +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" +#include "ortools/sat/sat_solver.h" + +namespace operations_research { +namespace sat { + +// The "no-cycle" constraint. +// +// Each arc will be associated to a literal and this propagator will make sure +// that there is no cycle in the graph with only the arcs whose associated +// literal is set to true. +class NoCyclePropagator : public SatPropagator { + public: + NoCyclePropagator() + : SatPropagator("NoCyclePropagator"), + num_arcs_(0), + problem_is_unsat_(false), + initialization_is_done_(false), + num_arcs_threshold_(std::numeric_limits::max()), + include_propagated_arcs_in_graph_(true) {} + ~NoCyclePropagator() final {} + + static NoCyclePropagator* CreateInModel(Model* model) { + NoCyclePropagator* no_cycle = new NoCyclePropagator(); + model->GetOrCreate()->AddPropagator( + std::unique_ptr(no_cycle)); + return no_cycle; + } + + bool Propagate(Trail* trail) final; + void Untrail(const Trail& trail, int trail_index) final; + ClauseRef Reason(const Trail& trail, int trail_index) const final; + + // Stops doing anything when the number of arcs in the graph becomes greater + // that the given value. This allows to use this class to model a circuit + // constraint on n nodes: we don't want any cycle, but it is okay to have one + // when we add the n-th arc. Of course we also need to make sure that each + // node as an unique successor using at-most-one constraints. + void AllowCycleWhenNumArcsIsGreaterThan(int64 value) { + num_arcs_threshold_ = value; + } + + // If this is false, then we don't track inside our graphs the arcs that we + // propagated. This is meant to be turned on if an arc and its reverse are + // controlled by a literal and its negation. When this is the case, then we + // know that all the arcs propagated by this class don't change the + // reachability of the graph. + void IncludePropagatedArcsInGraph(bool value) { + include_propagated_arcs_in_graph_ = value; + } + + // Adds a "constant" arc to the graph. + // Self-arc are not allowed (it would create a trivial cycle). + void AddArc(int tail, int head); + + // Registers an arc that will be present in the graph iff 'literal' is true. + // Self-arc are not allowed (it would fix the given literal to false). + // + // TODO(user): support more than one arc associated to the same literal. + void AddPotentialArc(int tail, int head, Literal literal); + + // Getters for the current graph. This is only in sync with the trail iff + // SatPropagator::PropagationIsDone() is true. + // + // Note that these graphs will NOT contain all the arcs but will correctly + // encode the reachability of every node. More specifically, when an arc (tail + // -> head) is about to be added but a path from tail to head already exists + // in the graph, this arc will not be added. + struct Arc { + int head; + LiteralIndex literal_index; + }; + const std::vector>& Graph() const { return graph_; } + const std::vector>& ReverseGraph() const { + return reverse_graph_; + } + + // Getters for the "potential" arcs. That is the arcs that could be added to + // the graph or not depending on their associated literal value. Note that + // some already added arcs may not appear here for optimization purposes. + const std::vector>& PotentialGraph() const { + return potential_graph_; + } + const ITIVector>>& + PotentialArcs() const { + return potential_arcs_; + } + + private: + // Adjust the internal data structures when a new arc is added. + void AdjustSizes(int tail, int head, int literal_index); + + // Returns true if destination is reachable from source in graph_. + // Warning: this modifies node_is_reached_ and reached_nodes_. + bool IsReachable(int source, int destination) const; + + // Returns the set of node from which source can be reached (included). + // Warning: this modifies node_is_reached_ and reached_nodes_. + void FillNodeIsReachedWithAntecedentOf(int source) const; + + // Returns the vector of node that are reachable from source (included), but + // not in the given already_reached. The already_reached vector is not const + // because this function temporarily modifies it before restoring it to its + // original value for performance reason. + std::vector NewlyReachable(int source, + std::vector* already_reached) const; + + // Finds a path from source to target and output its reason. + // Only the arcs whose associated literal is assigned before the given + // trail_limit are considered. + // + // Warning: this modifies node_is_reached_ and reached_nodes_. + void FindReasonForPath(const Trail& trail, int source, int target, + int trail_limit, std::vector* reason) const; + + // The number of arcs in graph_ and reverse_graph_. + int64 num_arcs_; + + // Just used to detect the corner case of a cycle with fixed arcs. + bool problem_is_unsat_; + bool initialization_is_done_; + + // Control the options of this class. + int64 num_arcs_threshold_; + bool include_propagated_arcs_in_graph_; + + // The current graph wich is kept in sync with the literal trail. For each + // node, graph_[node] list the pair (head, literal_index) of the outgoing + // arcs. + // + // Important: this will always be kept acyclic. + std::vector> graph_; + std::vector> reverse_graph_; + + // The graph formed by all the potential arcs in the same format as graph_. + std::vector> potential_graph_; + + // The set of potential arc (tail, head) indexed by literal_index. + // + // TODO(user): Introduce a struct with .tail and .head to make the code more + // readable. + ITIVector>> potential_arcs_; + + // Temporary vectors used by the various BFS computations. We always have: + // node_is_reached_[node] is true iff reached_nodes_ contains node. + mutable std::vector reached_nodes_; + mutable std::vector node_is_reached_; + + // Temporary vector to hold the result of NewlyReachable(). + std::vector newly_reachable_; + + // Temporary vector used by FindReasonForPath(). + mutable std::vector> parent_index_with_literal_; + + // The arc that caused the literal at a given trail_index to be propagated. + std::vector> reason_arc_; + std::vector reason_trail_limit_; + + DISALLOW_COPY_AND_ASSIGN(NoCyclePropagator); +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_NO_CYCLE_H_ diff --git a/thirdparty/linux/include/ortools/sat/optimization.h b/thirdparty/linux/include/ortools/sat/optimization.h new file mode 100644 index 0000000..32a4fec --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/optimization.h @@ -0,0 +1,165 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Optimization algorithms to solve a LinearBooleanProblem by using the SAT +// solver as a black-box. +// +// TODO(user): Currently, only the MINIMIZATION problem type is supported. + +#ifndef OR_TOOLS_SAT_OPTIMIZATION_H_ +#define OR_TOOLS_SAT_OPTIMIZATION_H_ + +#include "ortools/sat/boolean_problem.h" +#include "ortools/sat/integer.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_solver.h" + +namespace operations_research { +namespace sat { + +// Tries to minimize the given UNSAT core with a really simple heuristic. +// The idea is to remove literals that are consequences of others in the core. +// We already know that in the initial order, no literal is propagated by the +// one before it, so we just look for propagation in the reverse order. +// +// Important: The given SatSolver must be the one that just produced the given +// core. +void MinimizeCore(SatSolver* solver, std::vector* core); + +// Because the Solve*() functions below are also used in scripts that requires a +// special output format, we use this to tell them whether or not to use the +// default logging framework or simply stdout. Most users should just use +// DEFAULT_LOG. +enum LogBehavior { DEFAULT_LOG, STDOUT_LOG }; + +// All the Solve*() functions below reuse the SatSolver::Status with a slightly +// different meaning: +// - MODEL_SAT: The problem has been solved to optimality. +// - MODEL_UNSAT: Same meaning, the decision version is already unsat. +// - LIMIT_REACHED: we may have some feasible solution (if solution is +// non-empty), but the optimality is not proved. + +// Implements the "Fu & Malik" algorithm described in: +// Zhaohui Fu, Sharad Malik, "On solving the Partial MAX-SAT problem", 2006, +// International Conference on Theory and Applications of Satisfiability +// Testing. (SAT’06), LNCS 4121. +// +// This algorithm requires all the objective weights to be the same (CHECKed) +// and currently only works on minization problems. The problem is assumed to be +// already loaded into the given solver. +// +// TODO(user): double-check the correctness if the objective coefficients are +// negative. +SatSolver::Status SolveWithFuMalik(LogBehavior log, + const LinearBooleanProblem& problem, + SatSolver* solver, + std::vector* solution); + +// The WPM1 algorithm is a generalization of the Fu & Malik algorithm to +// weighted problems. Note that if all objective weights are the same, this is +// almost the same as SolveWithFuMalik() but the encoding of the constraints is +// slightly different. +// +// Ansotegui, C., Bonet, M.L., Levy, J.: Solving (weighted) partial MaxSAT +// through satisfiability testing. In: Proc. of the 12th Int. Conf. on Theory and +// Applications of Satisfiability Testing (SAT’09). pp. 427–440 (2009) +SatSolver::Status SolveWithWPM1(LogBehavior log, + const LinearBooleanProblem& problem, + SatSolver* solver, std::vector* solution); + +// Solves num_times the decision version of the given problem with different +// random parameters. Keep the best solution (regarding the objective) and +// returns it in solution. The problem is assumed to be already loaded into the +// given solver. +SatSolver::Status SolveWithRandomParameters(LogBehavior log, + const LinearBooleanProblem& problem, + int num_times, SatSolver* solver, + std::vector* solution); + +// Starts by solving the decision version of the given LinearBooleanProblem and +// then simply add a constraint to find a lower objective that the current best +// solution and repeat until the problem becomes unsat. +// +// The problem is assumed to be already loaded into the given solver. If +// solution is initially a feasible solution, the search will starts from there. +// solution will be updated with the best solution found so far. +SatSolver::Status SolveWithLinearScan(LogBehavior log, + const LinearBooleanProblem& problem, + SatSolver* solver, + std::vector* solution); + +// Similar algorithm as the one used by qmaxsat, this is a linear scan with the +// at-most k constraint encoded in SAT. This only works on problem with constant +// weights. +SatSolver::Status SolveWithCardinalityEncoding( + LogBehavior log, const LinearBooleanProblem& problem, SatSolver* solver, + std::vector* solution); + +// This is an original algorithm. It is a mix between the cardinality encoding +// and the Fu & Malik algorithm. It also works on general weighted instances. +SatSolver::Status SolveWithCardinalityEncodingAndCore( + LogBehavior log, const LinearBooleanProblem& problem, SatSolver* solver, + std::vector* solution); + +// Model-based API, for now we just provide a basic algorithm that minimize a +// given IntegerVariable by solving a sequence of decision problem. +// +// The "observer" function will be called each time a new feasible solution is +// found. +SatSolver::Status MinimizeIntegerVariableWithLinearScan( + IntegerVariable objective_var, + const std::function& feasible_solution_observer, + Model* model); + +// Same as MinimizeIntegerVariableWithLinearScan() but keep solving the problem +// as long as next_decision() do not return kNoLiteralIndex and hence lazily +// encode new variables. See the doc of SolveIntegerProblemWithLazyEncoding() +// for more details. +SatSolver::Status MinimizeIntegerVariableWithLinearScanAndLazyEncoding( + bool log_info, IntegerVariable objective_var, + const std::function& next_decision, + const std::function& feasible_solution_observer, + Model* model); + +// Same as MinimizeIntegerVariableWithLinearScanAndLazyEncoding() but use +// a core-based approach instead. The given objective_var must be equal to the +// sum of the given variables using the given coefficients. +// +// TODO(user): It is not needed to have objective_var and the linear objective +// constraint encoded in the model. Remove this preconditions in order to +// improve the solving time. +SatSolver::Status MinimizeWithCoreAndLazyEncoding( + bool log_info, IntegerVariable objective_var, + const std::vector& variables, + const std::vector& coefficients, + const std::function& next_decision, + const std::function& feasible_solution_observer, + Model* model); + +// Similar to MinimizeIntegerVariableWithLinearScanAndLazyEncoding() but use +// a core based approach. Note that this require the objective to be given as +// a weighted sum of literals +// +// TODO(user): The function above is more general, remove this one after +// checking that the performances are similar. +SatSolver::Status MinimizeWeightedLiteralSumWithCoreAndLazyEncoding( + bool log_info, const std::vector& literals, + const std::vector& coeffs, + const std::function& next_decision, + const std::function& feasible_solution_observer, + Model* model); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_OPTIMIZATION_H_ diff --git a/thirdparty/linux/include/ortools/sat/overload_checker.h b/thirdparty/linux/include/ortools/sat/overload_checker.h new file mode 100644 index 0000000..36034e1 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/overload_checker.h @@ -0,0 +1,158 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_OVERLOAD_CHECKER_H_ +#define OR_TOOLS_SAT_OVERLOAD_CHECKER_H_ + +#include "ortools/sat/integer.h" +#include "ortools/sat/intervals.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" + +namespace operations_research { +namespace sat { + +// Overload Checker +// +// This propagator implements the overload checker filtering rule presented in +// Vilim Petr, "Max Energy Filtering Algorithm for Discrete Cumulative +// Constraint", CPAIOR 2009, http://vilim.eu/petr/cpaior2009.pdf. +// +// This propagator only increases the minimum of the capacity variable or fails +// if the minimum capacity cannot be increased. It has a time complexity of +// O(n log n). +// +// The propagator relies on a Theta-tree to maintain the energy and envelope of +// several set of tasks. +// +// The energy of a task can be seen as its surface and is the product of its +// minimum demand and minimum duration. The energy of a set of tasks is the sum +// of the energy of its tasks. +// +// The envelope of a task is the sum of the task energy and the total amount of +// energy available before the minimum starting time of the task, i.e., the +// product of its minimum start time by the maximum capacity of the resource. +// +// An overload, meaning that there is no solution, occurs when a set of tasks +// requires more energy than what is available between its starting and ending +// times. +// +// Be aware that overload checker is not enough to ensure that the cumulative +// constraint holds. This propagator should thus always be used with a +// timetabling propagator at least. +class OverloadChecker : public PropagatorInterface { + public: + OverloadChecker(const std::vector& interval_vars, + const std::vector& demand_vars, + IntegerVariable capacity, Trail* trail, + IntegerTrail* integer_trail, + IntervalsRepository* intervals_repository); + + bool Propagate() final; + + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + struct TaskTime { + /* const */ int task_id; + IntegerValue time; + TaskTime(int task_id, IntegerValue time) : task_id(task_id), time(time) {} + bool operator<(TaskTime other) const { return time < other.time; } + }; + + // Inserts the task at leaf_id with the given energy and envelope. The change + // is propagated to the top of the Theta-tree by recomputing the energy and + // the envelope of all the leaf's ancestors. + void InsertTaskInThetaTree(int leaf_id, IntegerValue energy, + IntegerValue envelope); + + // Remove the task at leaf_id from the Theta-tree. + void RemoveTaskFromThetaTree(int leaf_id); + + // Resets the theta-tree such that its deepest level is the first that can + // contain at least num_tasks leaves. All nodes are resets to energy = 0 and + // envelope = kMinIntegerValue. + void ResetThetaTree(int num_tasks); + + // Searches for the leaf that contains the task that has the smallest minimum + // start time and that is involved in the value of the root node envelope. + int LeftMostInvolvedLeaf() const; + + IntegerValue StartMin(int task_id) const { + return integer_trail_->LowerBound(start_vars_[task_id]); + } + + IntegerValue EndMax(int task_id) const { + return integer_trail_->UpperBound(end_vars_[task_id]); + } + + IntegerValue DemandMin(int task_id) const { + return integer_trail_->LowerBound(demand_vars_[task_id]); + } + + IntegerValue DurationMin(int task_id) const { + return intervals_repository_->MinSize(interval_vars_[task_id]); + } + + // An optional task can be present, absent or its status still unknown. Normal + // tasks are always present. + bool IsPresent(int task_id) const; + bool IsAbsent(int task_id) const; + void AddPresenceReasonIfNeeded(int task_id); + + // Number of tasks. + const int num_tasks_; + + // IntervalVariable and IntegerVariable of each tasks that must be considered + // by this propagator. + std::vector interval_vars_; + std::vector start_vars_; + std::vector end_vars_; + std::vector demand_vars_; + std::vector duration_vars_; + + // Capacity of the resource. + const IntegerVariable capacity_var_; + + // Reason vector. + std::vector literal_reason_; + std::vector integer_reason_; + + Trail* trail_; + IntegerTrail* integer_trail_; + IntervalsRepository* intervals_repository_; + + std::vector by_start_min_; + std::vector by_end_max_; + std::vector task_to_index_in_start_min_; + + // The Theta-tree is a complete binary tree that stores the tasks from left to + // right in the leaves of its deepest level. We implement the Theta-tree in a + // vector such that the root node is at position 1. The left and right + // children of a node at position p are respectively stored at positions 2*p + // and 2*p + 1. + + // Position of the first leaf. + int first_leaf_; + // Energy of each node in the Theta-tree. + std::vector node_energies_; + // Envelope of each node in the Theta-tree. + std::vector node_envelopes_; + + DISALLOW_COPY_AND_ASSIGN(OverloadChecker); +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_OVERLOAD_CHECKER_H_ diff --git a/thirdparty/linux/include/ortools/sat/pb_constraint.h b/thirdparty/linux/include/ortools/sat/pb_constraint.h new file mode 100644 index 0000000..64ccbbe --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/pb_constraint.h @@ -0,0 +1,710 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_PB_CONSTRAINT_H_ +#define OR_TOOLS_SAT_PB_CONSTRAINT_H_ + +#include +#include +#include "ortools/sat/sat_base.h" +#include "ortools/sat/sat_parameters.pb.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace sat { + +// The type of the integer coefficients in a pseudo-Boolean constraint. +// This is also used for the current value of a constraint or its bounds. +DEFINE_INT_TYPE(Coefficient, int64); + +// IMPORTANT: We can't use numeric_limits::max() which will compile +// but just returns zero!! +const Coefficient kCoefficientMax( + std::numeric_limits::max()); + +// Represents a term in a pseudo-Boolean formula. +struct LiteralWithCoeff { + LiteralWithCoeff() {} + LiteralWithCoeff(Literal l, Coefficient c) : literal(l), coefficient(c) {} + LiteralWithCoeff(Literal l, int64 c) : literal(l), coefficient(c) {} + Literal literal; + Coefficient coefficient; + bool operator==(const LiteralWithCoeff& other) const { + return literal.Index() == other.literal.Index() && + coefficient == other.coefficient; + } +}; +inline std::ostream& operator<<(std::ostream& os, LiteralWithCoeff term) { + os << term.coefficient << "[" << term.literal.DebugString() << "]"; + return os; +} + +// Puts the given Boolean linear expression in canonical form: +// - Merge all the literal corresponding to the same variable. +// - Remove zero coefficients. +// - Make all the coefficients positive. +// - Sort the terms by increasing coefficient values. +// +// This function also computes: +// - max_value: the maximum possible value of the formula. +// - bound_shift: which allows to updates initial bounds. That is, if an +// initial pseudo-Boolean constraint was +// lhs < initial_pb_formula < rhs +// then the new one is: +// lhs + bound_shift < canonical_form < rhs + bound_shift +// +// Finally, this will return false, if some integer overflow or underflow +// occured during the reduction to the canonical form. +bool ComputeBooleanLinearExpressionCanonicalForm( + std::vector* cst, Coefficient* bound_shift, + Coefficient* max_value); + +// Maps all the literals of the given constraint using the given mapping. The +// mapping may map a literal index to kTrueLiteralIndex or kFalseLiteralIndex in +// which case the literal will be considered fixed to the appropriate value. +// +// Note that this function also canonicalizes the constraint and updates +// bound_shift and max_value like ComputeBooleanLinearExpressionCanonicalForm() +// does. +// +// Finally, this will return false if some integer overflow or underflow occured +// during the constraint simplification. +bool ApplyLiteralMapping(const ITIVector& mapping, + std::vector* cst, + Coefficient* bound_shift, Coefficient* max_value); + +// From a constraint 'expr <= ub' and the result (bound_shift, max_value) of +// calling ComputeBooleanLinearExpressionCanonicalForm() on 'expr', this returns +// a new rhs such that 'canonical expression <= rhs' is an equivalent +// constraint. This function deals with all the possible overflow corner cases. +// +// The result will be in [-1, max_value] where -1 means unsatisfiable and +// max_value means trivialy satisfiable. +Coefficient ComputeCanonicalRhs(Coefficient upper_bound, + Coefficient bound_shift, Coefficient max_value); + +// Same as ComputeCanonicalRhs(), but uses the initial constraint lower bound +// instead. From a constraint 'lb <= expression', this returns a rhs such that +// 'canonical expression with literals negated <= rhs'. +// +// Note that the range is also [-1, max_value] with the same meaning. +Coefficient ComputeNegatedCanonicalRhs(Coefficient lower_bound, + Coefficient bound_shift, + Coefficient max_value); + +// Returns true iff the Boolean linear expression is in canonical form. +bool BooleanLinearExpressionIsCanonical( + const std::vector& cst); + +// Given a Boolean linear constraint in canonical form, simplify its +// coefficients using simple heuristics. +void SimplifyCanonicalBooleanLinearConstraint( + std::vector* cst, Coefficient* rhs); + +// Holds a set of boolean linear constraints in canonical form: +// - The constraint is a linear sum of LiteralWithCoeff <= rhs. +// - The linear sum satisfies the properties described in +// ComputeBooleanLinearExpressionCanonicalForm(). +// +// TODO(user): Simplify further the constraints. +// +// TODO(user): Remove the duplication between this and what the sat solver +// is doing in AddLinearConstraint() which is basically the same. +// +// TODO(user): Remove duplicate constraints? some problems have them, and +// this is not ideal for the symmetry computation since it leads to a lot of +// symmetries of the associated graph that are not useful. +class CanonicalBooleanLinearProblem { + public: + CanonicalBooleanLinearProblem() {} + + // Adds a new constraint to the problem. The bounds are inclusive. + // Returns false in case of a possible overflow or if the constraint is + // never satisfiable. + // + // TODO(user): Use a return status to distinguish errors if needed. + bool AddLinearConstraint(bool use_lower_bound, Coefficient lower_bound, + bool use_upper_bound, Coefficient upper_bound, + std::vector* cst); + + // Getters. All the constraints are guaranteed to be in canonical form. + int NumConstraints() const { return constraints_.size(); } + const Coefficient Rhs(int i) const { return rhs_[i]; } + const std::vector& Constraint(int i) const { + return constraints_[i]; + } + + private: + bool AddConstraint(const std::vector& cst, + Coefficient max_value, Coefficient rhs); + + std::vector rhs_; + std::vector> constraints_; + DISALLOW_COPY_AND_ASSIGN(CanonicalBooleanLinearProblem); +}; + +// Encode a constraint sum term <= rhs, where each term is a positive +// Coefficient times a literal. This class allows efficient modification of the +// constraint and is used during pseudo-Boolean resolution. +class MutableUpperBoundedLinearConstraint { + public: + // This must be called before any other functions is used with an higher + // variable index. + void ClearAndResize(int num_variables); + + // Reset the constraint to 0 <= 0. + // Note that the contraint size stays the same. + void ClearAll(); + + // Returns the coefficient (>= 0) of the given variable. + Coefficient GetCoefficient(BooleanVariable var) const { + return AbsCoefficient(terms_[var]); + } + + // Returns the literal under which the given variable appear in the + // constraint. Note that if GetCoefficient(var) == 0 this just returns + // Literal(var, true). + Literal GetLiteral(BooleanVariable var) const { + return Literal(var, terms_[var] > 0); + } + + // If we have a lower bounded constraint sum terms >= rhs, then it is trivial + // to see that the coefficient of any term can be reduced to rhs if it is + // bigger. This does exactly this operation, but on the upper bounded + // representation. + // + // If we take a constraint sum ci.xi <= rhs, take its negation and add max_sum + // on both side, we have sum ci.(1 - xi) >= max_sum - rhs + // So every ci > (max_sum - rhs) can be replacend by (max_sum - rhs). + // Not that this operation also change the original rhs of the constraint. + void ReduceCoefficients(); + + // Same as ReduceCoefficients() but only consider the coefficient of the given + // variable. + void ReduceGivenCoefficient(BooleanVariable var) { + const Coefficient bound = max_sum_ - rhs_; + const Coefficient diff = GetCoefficient(var) - bound; + if (diff > 0) { + rhs_ -= diff; + max_sum_ -= diff; + terms_[var] = (terms_[var] > 0) ? bound : -bound; + } + } + + // Compute the constraint slack assuming that only the variables with index < + // trail_index are assigned. + Coefficient ComputeSlackForTrailPrefix(const Trail& trail, + int trail_index) const; + + // Same as ReduceCoefficients() followed by ComputeSlackForTrailPrefix(). It + // allows to loop only once over all the terms of the constraint instead of + // doing it twice. This helps since doing that can be the main bottleneck. + // + // Note that this function assumes that the returned slack will be negative. + // This allow to DCHECK some assumptions on what coefficients can be reduced + // or not. + // + // TODO(user): Ideally the slack should be maitainable incrementally. + Coefficient ReduceCoefficientsAndComputeSlackForTrailPrefix( + const Trail& trail, int trail_index); + + // Relaxes the constraint so that: + // - ComputeSlackForTrailPrefix(trail, trail_index) == target; + // - All the variable that where propagated given the assignment < trail_index + // are still propagated. + // + // As a precondition, ComputeSlackForTrailPrefix(trail, trail_index) >= target + // Note that nothing happen if the slack is already equals to target. + // + // Algorithm: Let diff = slack - target (>= 0). We will split the constraint + // linear expression in 3 parts: + // - P1: the true variables (only the one assigned < trail_index). + // - P2: the other variables with a coeff > diff. + // Note that all these variables where the propagated ones. + // - P3: the other variables with a coeff <= diff. + // We can then transform P1 + P2 + P3 <= rhs_ into P1 + P2' <= rhs_ - diff + // Where P2' is the same sum as P2 with all the coefficient reduced by diff. + // + // Proof: Given the old constraint, we want to show that the relaxed one is + // always true. If all the variable in P2' are false, then + // P1 <= rhs_ - slack <= rhs_ - diff is always true. If at least one of the + // P2' variable is true, then P2 >= P2' + diff and we have + // P1 + P2' + diff <= P1 + P2 <= rhs_. + void ReduceSlackTo(const Trail& trail, int trail_index, + Coefficient initial_slack, Coefficient target); + + // Copies this constraint into a std::vector representation. + void CopyIntoVector(std::vector* output); + + // Adds a non-negative value to this constraint Rhs(). + void AddToRhs(Coefficient value) { + CHECK_GE(value, 0); + rhs_ += value; + } + Coefficient Rhs() const { return rhs_; } + Coefficient MaxSum() const { return max_sum_; } + + // Adds a term to this constraint. This is in the .h for efficiency. + // The encoding used internally is described below in the terms_ comment. + void AddTerm(Literal literal, Coefficient coeff) { + CHECK_GT(coeff, 0); + const BooleanVariable var = literal.Variable(); + const Coefficient term_encoding = literal.IsPositive() ? coeff : -coeff; + if (literal != GetLiteral(var)) { + // The two terms are of opposite sign, a "cancelation" happens. + // We need to change the encoding of the lower magnitude term. + // - If term > 0, term . x -> term . (x - 1) + term + // - If term < 0, term . (x - 1) -> term . x - term + // In both cases, rhs -= abs(term). + rhs_ -= std::min(coeff, AbsCoefficient(terms_[var])); + max_sum_ += AbsCoefficient(term_encoding + terms_[var]) - + AbsCoefficient(terms_[var]); + } else { + // Both terms are of the same sign (or terms_[var] is zero). + max_sum_ += coeff; + } + CHECK_GE(max_sum_, 0) << "Overflow"; + terms_[var] += term_encoding; + non_zeros_.Set(var); + } + + // Returns the "cancelation" amount of AddTerm(literal, coeff). + Coefficient CancelationAmount(Literal literal, Coefficient coeff) const { + DCHECK_GT(coeff, 0); + const BooleanVariable var = literal.Variable(); + if (literal == GetLiteral(var)) return Coefficient(0); + return std::min(coeff, AbsCoefficient(terms_[var])); + } + + // Returns a set of positions that contains all the non-zeros terms of the + // constraint. Note that this set can also contains some zero terms. + const std::vector& PossibleNonZeros() const { + return non_zeros_.PositionsSetAtLeastOnce(); + } + + // Returns a std::string representation of the constraint. + std::string DebugString(); + + private: + Coefficient AbsCoefficient(Coefficient a) const { return a > 0 ? a : -a; } + + // Only used for DCHECK_EQ(max_sum_, ComputeMaxSum()); + Coefficient ComputeMaxSum() const; + + // The encoding is special: + // - If terms_[x] > 0, then the associated term is 'terms_[x] . x' + // - If terms_[x] < 0, then the associated term is 'terms_[x] . (x - 1)' + ITIVector terms_; + + // The right hand side of the constraint (sum terms <= rhs_). + Coefficient rhs_; + + // The constraint maximum sum (i.e. sum of the absolute term coefficients). + // Note that checking the integer overflow on this sum is enough. + Coefficient max_sum_; + + // Contains the possibly non-zeros terms_ value. + SparseBitset non_zeros_; +}; + +// A simple "helper" class to enqueue a propagated literal on the trail and +// keep the information needed to explain it when requested. +class UpperBoundedLinearConstraint; +struct PbConstraintsEnqueueHelper { + void Enqueue(Literal l, int source_trail_index, + UpperBoundedLinearConstraint* ct, Trail* trail) { + reasons[trail->Index()] = {source_trail_index, ct}; + trail->Enqueue(l, propagator_id); + } + + // The propagator id of PbConstraints. + int propagator_id; + + // A temporary vector to store the last conflict. + std::vector conflict; + + // Information needed to recover the reason of an Enqueue(). + // Indexed by trail_index. + struct ReasonInfo { + int source_trail_index; + UpperBoundedLinearConstraint* pb_constraint; + }; + std::vector reasons; +}; + +// This class contains half the propagation logic for a constraint of the form +// +// sum ci * li <= rhs, ci positive coefficients, li literals. +// +// The other half is implemented by the PbConstraints class below which takes +// care of updating the 'threshold' value of this constraint: +// - 'slack' is rhs minus all the ci of the variables xi assigned to +// true. Note that it is not updated as soon as xi is assigned, but only +// later when this assignment is "processed" by the PbConstraints class. +// - 'threshold' is the distance from 'slack' to the largest coefficient ci +// smaller or equal to slack. By definition, all the literals with +// even larger coefficients that are yet 'processed' must be false for the +// constraint to be satisfiable. +class UpperBoundedLinearConstraint { + public: + // Takes a pseudo-Boolean formula in canonical form. + explicit UpperBoundedLinearConstraint( + const std::vector& cst); + + // Returns true if the given terms are the same as the one in this constraint. + bool HasIdenticalTerms(const std::vector& cst); + Coefficient Rhs() const { return rhs_; } + + // Sets the rhs of this constraint. Compute the initial threshold value using + // only the literal with a trail index smaller than the given one. Enqueues on + // the trail any propagated literals. + // + // Returns false if the preconditions described in + // PbConstraints::AddConstraint() are not meet. + bool InitializeRhs(Coefficient rhs, int trail_index, Coefficient* threshold, + Trail* trail, PbConstraintsEnqueueHelper* helper); + + // Tests for propagation and enqueues propagated literals on the trail. + // Returns false if a conflict was detected, in which case conflict is filled. + // + // Preconditions: + // - For each "processed" literal, the given threshold value must have been + // decreased by its associated coefficient in the constraint. It must now + // be stricly negative. + // - The given trail_index is the index of a true literal in the trail which + // just caused threshold to become stricly negative. All literals with + // smaller index must have been "processed". All assigned literals with + // greater trail index are not yet "processed". + // + // The threshold is updated to its new value. + bool Propagate(int trail_index, Coefficient* threshold, Trail* trail, + PbConstraintsEnqueueHelper* helper); + + // Updates the given threshold and the internal state. This is the opposite of + // Propagate(). Each time a literal in unassigned, the threshold value must + // have been increased by its coefficient. This update the threshold to its + // new value. + void Untrail(Coefficient* threshold, int trail_index); + + // Provided that the literal with given source_trail_index was the one that + // propagated the conflict or the literal we wants to explain, then this will + // compute the reason. + // + // Some properties of the reason: + // - Literals of level 0 are removed. + // - It will always contain the literal with given source_trail_index (except + // if it is of level 0). + // - We make the reason more compact by greedily removing terms with small + // coefficients that would not have changed the propagation. + // + // TODO(user): Maybe it is possible to derive a better reason by using more + // information. For instance one could use the mask of literals that are + // better to use during conflict minimization (namely the one already in the + // 1-UIP conflict). + void FillReason(const Trail& trail, int source_trail_index, + BooleanVariable propagated_variable, + std::vector* reason); + + // Same operation as SatSolver::ResolvePBConflict(), the only difference is + // that here the reason for var is *this. + void ResolvePBConflict(const Trail& trail, BooleanVariable var, + MutableUpperBoundedLinearConstraint* conflict, + Coefficient* conflict_slack); + + // Adds this pb constraint into the given mutable one. + // + // TODO(user): Provides instead an easy to use iterator over an + // UpperBoundedLinearConstraint and move this function to + // MutableUpperBoundedLinearConstraint. + void AddToConflict(MutableUpperBoundedLinearConstraint* conflict); + + // Compute the sum of the "cancelation" in AddTerm() if *this is added to + // the given conflict. The sum doesn't take into account literal assigned with + // a trail index smaller than the given one. + // + // Note(user): Currently, this is only used in DCHECKs. + Coefficient ComputeCancelation( + const Trail& trail, int trail_index, + const MutableUpperBoundedLinearConstraint& conflict); + + // API to mark a constraint for deletion before actually deleting it. + void MarkForDeletion() { is_marked_for_deletion_ = true; } + bool is_marked_for_deletion() const { return is_marked_for_deletion_; } + + // Only learned constraints are considered for deletion during the constraint + // cleanup phase. We also can't delete variables used as a reason. + void set_is_learned(bool is_learned) { is_learned_ = is_learned; } + bool is_learned() const { return is_learned_; } + bool is_used_as_a_reason() const { return first_reason_trail_index_ != -1; } + + // Activity of the constraint. Only low activity constraint will be deleted + // during the constraint cleanup phase. + void set_activity(double activity) { activity_ = activity; } + double activity() const { return activity_; } + + // Returns a fingerprint of the constraint linear expression (without rhs). + // This is used for duplicate detection. + int64 hash() const { return hash_; } + + // This is used to get statistics of the number of literals inspected by a + // Propagate() call. + int already_propagated_end() const { return already_propagated_end_; } + + private: + Coefficient GetSlackFromThreshold(Coefficient threshold) { + return (index_ < 0) ? threshold : coeffs_[index_] + threshold; + } + void Update(Coefficient slack, Coefficient* threshold) { + *threshold = (index_ < 0) ? slack : slack - coeffs_[index_]; + already_propagated_end_ = starts_[index_ + 1]; + } + + // Constraint management fields. + // TODO(user): Rearrange and specify bit size to minimize memory usage. + bool is_marked_for_deletion_; + bool is_learned_; + int first_reason_trail_index_; + double activity_; + + // Constraint propagation fields. + int index_; + int already_propagated_end_; + + // In the internal representation, we merge the terms with the same + // coefficient. + // - literals_ contains all the literal of the constraint sorted by increasing + // coefficients. + // - coeffs_ contains unique increasing coefficients. + // - starts_[i] is the index in literals_ of the first literal with + // coefficient coeffs_[i]. + std::vector coeffs_; + std::vector starts_; + std::vector literals_; + Coefficient rhs_; + + int64 hash_; +}; + +// Class responsible for managing a set of pseudo-Boolean constraints and their +// propagation. +class PbConstraints : public SatPropagator { + public: + PbConstraints() + : SatPropagator("PbConstraints"), + conflicting_constraint_index_(-1), + num_learned_constraint_before_cleanup_(0), + constraint_activity_increment_(1.0), + stats_("PbConstraints"), + num_constraint_lookups_(0), + num_inspected_constraint_literals_(0), + num_threshold_updates_(0) {} + ~PbConstraints() override { + IF_STATS_ENABLED({ + LOG(INFO) << stats_.StatString(); + LOG(INFO) << "num_constraint_lookups_: " << num_constraint_lookups_; + LOG(INFO) << "num_threshold_updates_: " << num_threshold_updates_; + }); + } + + bool Propagate(Trail* trail) final; + void Untrail(const Trail& trail, int trail_index) final; + ClauseRef Reason(const Trail& trail, int trail_index) const final; + + // Changes the number of variables. + void Resize(int num_variables) { + // Note that we avoid using up memory in the common case where there is no + // pb constraints at all. If there is 10 million variables, this vector + // alone will take 480 MB! + if (!constraints_.empty()) { + to_update_.resize(num_variables << 1); + enqueue_helper_.reasons.resize(num_variables); + } + } + + // Parameter management. + void SetParameters(const SatParameters& parameters) { + parameters_ = parameters; + } + + // Adds a constraint in canonical form to the set of managed constraints. Note + // that this detects constraints with exactly the same terms. In this case, + // the constraint rhs is updated if the new one is lower or nothing is done + // otherwise. + // + // There are some preconditions, and the function will return false if they + // are not met. The constraint can be added when the trail is not empty, + // however given the current propagated assignment: + // - The constraint cannot be conflicting. + // - The constraint cannot have propagated at an earlier decision level. + bool AddConstraint(const std::vector& cst, Coefficient rhs, + Trail* trail); + + // Same as AddConstraint(), but also marks the added constraint as learned + // so that it can be deleted during the constraint cleanup phase. + bool AddLearnedConstraint(const std::vector& cst, + Coefficient rhs, Trail* trail); + + // Returns the number of constraints managed by this class. + int NumberOfConstraints() const { return constraints_.size(); } + + // ConflictingConstraint() returns the last PB constraint that caused a + // conflict. Calling ClearConflictingConstraint() reset this to nullptr. + // + // TODO(user): This is a hack to get the PB conflict, because the rest of + // the solver API assume only clause conflict. Find a cleaner way? + void ClearConflictingConstraint() { conflicting_constraint_index_ = -1; } + UpperBoundedLinearConstraint* ConflictingConstraint() { + if (conflicting_constraint_index_ == -1) return nullptr; + return constraints_[conflicting_constraint_index_.value()].get(); + } + + // Returns the underlying UpperBoundedLinearConstraint responsible for + // assigning the literal at given trail index. + UpperBoundedLinearConstraint* ReasonPbConstraint(int trail_index) const; + + // Activity update functions. + // TODO(user): Remove duplication with other activity update functions. + void BumpActivity(UpperBoundedLinearConstraint* constraint); + void RescaleActivities(double scaling_factor); + void UpdateActivityIncrement(); + + // Only used for testing. + void DeleteConstraint(int index) { + constraints_[index]->MarkForDeletion(); + DeleteConstraintMarkedForDeletion(); + } + + // Some statistics. + int64 num_constraint_lookups() const { return num_constraint_lookups_; } + int64 num_inspected_constraint_literals() const { + return num_inspected_constraint_literals_; + } + int64 num_threshold_updates() const { return num_threshold_updates_; } + + private: + bool PropagateNext(Trail* trail); + + // Same function as the clause related one is SatSolver(). + // TODO(user): Remove duplication. + void ComputeNewLearnedConstraintLimit(); + void DeleteSomeLearnedConstraintIfNeeded(); + + // Deletes all the UpperBoundedLinearConstraint for which + // is_marked_for_deletion() is true. This is relatively slow in O(number of + // terms in all constraints). + void DeleteConstraintMarkedForDeletion(); + + // Each constraint managed by this class is associated with an index. + // The set of indices is always [0, num_constraints_). + // + // Note(user): this complicate things during deletion, but the propagation is + // about two times faster with this implementation than one with direct + // pointer to an UpperBoundedLinearConstraint. The main reason for this is + // probably that the thresholds_ vector is a lot more efficient cache-wise. + DEFINE_INT_TYPE(ConstraintIndex, int32); + struct ConstraintIndexWithCoeff { + ConstraintIndexWithCoeff() {} // Needed for vector.resize() + ConstraintIndexWithCoeff(bool n, ConstraintIndex i, Coefficient c) + : need_untrail_inspection(n), index(i), coefficient(c) {} + bool need_untrail_inspection; + ConstraintIndex index; + Coefficient coefficient; + }; + + // The set of all pseudo-boolean constraint managed by this class. + std::vector> constraints_; + + // The current value of the threshold for each constraints. + ITIVector thresholds_; + + // For each literal, the list of all the constraints that contains it together + // with the literal coefficient in these constraints. + ITIVector> to_update_; + + // Bitset used to optimize the Untrail() function. + SparseBitset to_untrail_; + + // Pointers to the constraints grouped by their hash. + // This is used to find duplicate constraints by AddConstraint(). + std::unordered_map> + possible_duplicates_; + + // Helper to enqueue propagated literals on the trail and store their reasons. + PbConstraintsEnqueueHelper enqueue_helper_; + + // Last conflicting PB constraint index. This is reset to -1 when + // ClearConflictingConstraint() is called. + ConstraintIndex conflicting_constraint_index_; + + // Used for the constraint cleaning policy. + int target_number_of_learned_constraint_; + int num_learned_constraint_before_cleanup_; + double constraint_activity_increment_; + + // Algorithm parameters. + SatParameters parameters_; + + // Some statistics. + mutable StatsGroup stats_; + int64 num_constraint_lookups_; + int64 num_inspected_constraint_literals_; + int64 num_threshold_updates_; + DISALLOW_COPY_AND_ASSIGN(PbConstraints); +}; + +// Boolean linear constraints can propagate a lot of literals at the same time. +// As a result, all these literals will have exactly the same reason. It is +// important to take advantage of that during the conflict +// computation/minimization. On some problem, this can have a huge impact. +// +// TODO(user): With the new SAME_REASON_AS mechanism, this is more general so +// move out of pb_constraint. +class VariableWithSameReasonIdentifier { + public: + explicit VariableWithSameReasonIdentifier(const Trail& trail) + : trail_(trail) {} + + void Resize(int num_variables) { + first_variable_.resize(num_variables); + seen_.ClearAndResize(BooleanVariable(num_variables)); + } + + // Clears the cache. Call this before each conflict analysis. + void Clear() { seen_.ClearAll(); } + + // Returns the first variable with exactly the same reason as 'var' on which + // this function was called since the last Clear(). Note that if no variable + // had the same reason, then var is returned. + BooleanVariable FirstVariableWithSameReason(BooleanVariable var) { + if (seen_[var]) return first_variable_[var]; + const BooleanVariable reference_var = + trail_.ReferenceVarWithSameReason(var); + if (reference_var == var) return var; + if (seen_[reference_var]) return first_variable_[reference_var]; + seen_.Set(reference_var); + first_variable_[reference_var] = var; + return var; + } + + private: + const Trail& trail_; + ITIVector first_variable_; + SparseBitset seen_; + + DISALLOW_COPY_AND_ASSIGN(VariableWithSameReasonIdentifier); +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_PB_CONSTRAINT_H_ diff --git a/thirdparty/linux/include/ortools/sat/precedences.h b/thirdparty/linux/include/ortools/sat/precedences.h new file mode 100644 index 0000000..aff1995 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/precedences.h @@ -0,0 +1,496 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_PRECEDENCES_H_ +#define OR_TOOLS_SAT_PRECEDENCES_H_ + +#include +#include + +#include "ortools/sat/integer.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" +#include "ortools/sat/sat_solver.h" +#include "ortools/util/bitset.h" + +namespace operations_research { +namespace sat { + +// This class implement a propagator on simple inequalities between integer +// variables of the form (i1 + offset <= i2). The offset can be constant or +// given by the value of a third integer variable. Offsets can also be negative. +// +// The algorithm work by mapping the problem onto a graph where the edges carry +// the offset and the nodes correspond to one of the two bounds of an integer +// variable (lower_bound or -upper_bound). It then find the fixed point using an +// incremental variant of the Bellman-Ford(-Tarjan) algorithm. +// +// This is also known as an "integer difference logic theory" in the SMT world. +// Another word is "separation logic". +class PrecedencesPropagator : public SatPropagator, PropagatorInterface { + public: + PrecedencesPropagator(Trail* trail, IntegerTrail* integer_trail, + GenericLiteralWatcher* watcher) + : SatPropagator("PrecedencesPropagator"), + trail_(trail), + integer_trail_(integer_trail), + watcher_(watcher), + watcher_id_(watcher->Register(this)) { + integer_trail_->RegisterWatcher(&modified_vars_); + watcher->SetPropagatorPriority(watcher_id_, 0); + } + + static PrecedencesPropagator* CreateInModel(Model* model) { + PrecedencesPropagator* precedences = new PrecedencesPropagator( + model->GetOrCreate(), model->GetOrCreate(), + model->GetOrCreate()); + + // TODO(user): Find a way to have more control on the order in which + // the propagators are added. + model->GetOrCreate()->AddPropagator( + std::unique_ptr(precedences)); + return precedences; + } + + bool Propagate() final; + bool Propagate(Trail* trail) final; + void Untrail(const Trail& trail, int trail_index) final; + + // Add a precedence relation (i1 + offset <= i2) between integer variables. + void AddPrecedence(IntegerVariable i1, IntegerVariable i2); + void AddPrecedenceWithOffset(IntegerVariable i1, IntegerVariable i2, + IntegerValue offset); + + // Same as above, but the relation is only true when the given literal is. + void AddConditionalPrecedence(IntegerVariable i1, IntegerVariable i2, + Literal l); + void AddConditionalPrecedenceWithOffset(IntegerVariable i1, + IntegerVariable i2, + IntegerValue offset, Literal l); + + // Note that we currently do not support marking a variable appearing as + // an offset_var as optional (with MarkIntegerVariableAsOptional()). We could + // give it a meaning (like the arcs are not propagated if it is optional), but + // the code currently do not implement this. + // + // TODO(user): support optional offset_var? + // + // TODO(user): the variable offset should probably be tested more because + // when I wrote this, I just had a couple of problems to test this on. + void AddPrecedenceWithVariableOffset(IntegerVariable i1, IntegerVariable i2, + IntegerVariable offset_var); + + // Generic function that cover all of the above case and more. + void AddPrecedenceWithAllOptions(IntegerVariable i1, IntegerVariable i2, + IntegerValue offset, + IntegerVariable offset_var, LiteralIndex l); + + // An optional integer variable has a special behavior: + // - If the bounds on i cross each other, then is_present must be false. + // - It will only propagate any outgoing arcs if is_present is true. + // + // TODO(user): Accept a BinaryImplicationGraph* here, so that and arc + // (tail -> head) can still propagate if tail.is_present => head.is_present. + // Note that such propagation is only useful if the status of tail presence + // is still undecided. Note that we do propagate if tail and head have the + // same presence literal (see ArcShouldPropagate()). + // + // TODO(user): use instead integer_trail_->VariableIsOptional()? Note that the + // meaning is not exactly the same, because here we also do not propagate the + // outgoing arcs. And we need to watch the is_present variable, so we still + // need to call this function. + void MarkIntegerVariableAsOptional(IntegerVariable i, Literal is_present); + + // Finds all the IntegerVariable that are "after" one of the IntegerVariable + // in vars. Returns a vector of these precedences relation sorted by + // IntegerPrecedences.var so that it is efficient to find all the + // IntegerVariable "before" another one. + // + // Note that we only consider direct precedences here. Given our usage, it may + // be better to compute the full reachability in the precedence graph, but in + // pratice that may be too slow. On a good note, because we have all the + // potential precedences between tasks in disjunctions, on a single machine, + // both notion should be the same since we automatically work on the + // transitive closure. + // + // Note that the IntegerVariable in the vector are also returned in + // topological order for a more efficient propagation in + // DisjunctiveConstraint::PrecedencesPass() where this is used. + struct IntegerPrecedences { + int index; // in vars. + IntegerVariable var; // An IntegerVariable that is >= to vars[index]. + LiteralIndex reason; // The reaon for it to be >= or kNoLiteralIndex. + + // Only needed for testing. + bool operator==(const IntegerPrecedences& o) const { + return index == o.index && var == o.var && reason == o.reason; + } + }; + void ComputePrecedences(const std::vector& vars, + const std::vector& to_consider, + std::vector* output); + + private: + // Information about an individual arc. + struct ArcInfo { + IntegerVariable tail_var; + IntegerVariable head_var; + + IntegerValue offset; + IntegerVariable offset_var; // kNoIntegerVariable if none. + LiteralIndex presence_l; // kNoLiteralIndex if none. + + // Used temporarily by our implementation of the Bellman-Ford algorithm. It + // should be false at the beginning of BellmanFordTarjan(). + mutable bool is_marked; + }; + + // Internal functions to add new precedence relations. + // + // Note that internally, we only propagate lower bounds, so each time we add + // an arc, we actually create two of them: one on the given variables, and one + // on their negation. + void AdjustSizeFor(IntegerVariable i); + void AddArc(IntegerVariable tail, IntegerVariable head, IntegerValue offset, + IntegerVariable offset_var, LiteralIndex l); + + // Helper function for a slightly more readable code. + LiteralIndex OptionalLiteralOf(IntegerVariable var) const { + return optional_literals_[var]; + } + + // Enqueue a new lower bound for the variable arc.head_lb that was deduced + // from the current value of arc.tail_lb and the offset of this arc. + bool EnqueueAndCheck(const ArcInfo& arc, IntegerValue new_head_lb, + Trail* trail); + IntegerValue ArcOffset(const ArcInfo& arc) const; + + // Returns true iff this arc should propagate. For now, this is true when: + // - tail node is non-optional + // - tail node is optional and present. + // - tail node is optional, its presence is unknown, and its presence literal + // is the same as the one of head. + bool ArcShouldPropagate(const ArcInfo& arc, const Trail& trail) const; + + // Inspect all the optional arcs that needs inspection (to stay sparse) and + // check if their presence literal can be propagated to false. + void PropagateOptionalArcs(Trail* trail); + + // The core algorithm implementation is split in these functions. One must + // first call InitializeBFQueueWithModifiedNodes() that will push all the + // IntegerVariable whose lower bound has been modified since the last call. + // Then, BellmanFordTarjan() will take care of all the propagation and returns + // false in case of conflict. Internally, it uses DisassembleSubtree() which + // is the Tarjan variant to detect a possible positive cycle. Before exiting, + // it will call CleanUpMarkedArcsAndParents(). + // + // The Tarjan version of the Bellam-Ford algorithm is really nice in our + // context because it was really easy to make it incremental. Moreover, it + // supports batch increment! + // + // This implementation is kind of unique because of our context and the fact + // that it is incremental, but a good reference is "Negative-cycle detection + // algorithms", Boris V. Cherkassky, Andrew V. Goldberg, 1996, + // http://people.cs.nctu.edu.tw/~tjshen/doc/ne.pdf + void InitializeBFQueueWithModifiedNodes(); + bool BellmanFordTarjan(Trail* trail); + bool DisassembleSubtree(int source, int target, + std::vector* can_be_skipped); + void ReportPositiveCycle(int first_arc, Trail* trail); + void CleanUpMarkedArcsAndParents(); + + // Loops over all the arcs and verify that there is no propagation left. + // This is only meant to be used in a DCHECK() and is not optimized. + bool NoPropagationLeft(const Trail& trail) const; + + // External class needed to get the IntegerVariable lower bounds and Enqueue + // new ones. + Trail* trail_; + IntegerTrail* integer_trail_; + GenericLiteralWatcher* watcher_; + int watcher_id_; + + // The key to our incrementality. This will be cleared once the propagation + // is done, and automatically updated by the integer_trail_ with all the + // IntegerVariable that changed since the last clear. + SparseBitset modified_vars_; + + // An arc needs to be inspected for propagation (i.e. is impacted) if: + // - Its tail_var changed. + // - Its offset_var changed. + // + // All the int are arc indices in the arcs_ vector. + // + // The first vector (impacted_arcs_) correspond to the arc currently present + // whereas the second vector (impacted_potential_arcs_) list all the potential + // arcs (the one not allways present) and is just used for propagation of the + // arc presence literals. + ITIVector> impacted_arcs_; + ITIVector> impacted_potential_arcs_; + + // Temporary vectors used by ComputePrecedences(). + ITIVector var_to_degree_; + ITIVector var_to_last_index_; + struct SortedVar { + IntegerVariable var; + IntegerValue lower_bound; + bool operator<(const SortedVar& other) const { + return lower_bound < other.lower_bound; + } + }; + std::vector tmp_sorted_vars_; + std::vector tmp_precedences_; + + // The set of arcs that must be added to impacted_arcs_ when a literal become + // true. + ITIVector> potential_arcs_; + + // Used for MarkIntegerVariableAsOptional(). The nodes associated to an + // IntegerVariable whose entry is not kNoLiteralIndex will only propagate + // something to its neighbors if the coresponding literal is assigned to true. + ITIVector optional_literals_; + ITIVector> potential_nodes_; + + // TODO(user): rearranging the index so that the arc of the same node are + // consecutive like in StaticGraph should have a big performance impact. + std::vector arcs_; + + // Temp vectors to hold the reason of an assignment. + std::vector literal_reason_; + std::vector integer_reason_; + + // Temp vectors for the Bellman-Ford algorithm. The graph in which this + // algorithm works is in one to one correspondance with the IntegerVariable in + // impacted_arcs_. + std::deque bf_queue_; + std::vector bf_in_queue_; + std::vector bf_can_be_skipped_; + std::vector bf_parent_arc_of_; + + // Temp vector used by the tree traversal in DisassembleSubtree(). + std::vector tmp_vector_; + + DISALLOW_COPY_AND_ASSIGN(PrecedencesPropagator); +}; + +// ============================================================================= +// Implementation of the small API functions below. +// ============================================================================= + +inline void PrecedencesPropagator::AddPrecedence(IntegerVariable i1, + IntegerVariable i2) { + AddArc(i1, i2, /*offset=*/IntegerValue(0), /*offset_var=*/kNoIntegerVariable, + /*l=*/kNoLiteralIndex); +} + +inline void PrecedencesPropagator::AddPrecedenceWithOffset( + IntegerVariable i1, IntegerVariable i2, IntegerValue offset) { + AddArc(i1, i2, offset, /*offset_var=*/kNoIntegerVariable, + /*l=*/kNoLiteralIndex); +} + +inline void PrecedencesPropagator::AddConditionalPrecedence(IntegerVariable i1, + IntegerVariable i2, + Literal l) { + AddArc(i1, i2, /*offset=*/IntegerValue(0), /*offset_var=*/kNoIntegerVariable, + l.Index()); +} + +inline void PrecedencesPropagator::AddConditionalPrecedenceWithOffset( + IntegerVariable i1, IntegerVariable i2, IntegerValue offset, Literal l) { + AddArc(i1, i2, offset, /*offset_var=*/kNoIntegerVariable, l.Index()); +} + +inline void PrecedencesPropagator::AddPrecedenceWithVariableOffset( + IntegerVariable i1, IntegerVariable i2, IntegerVariable offset_var) { + AddArc(i1, i2, /*offset=*/IntegerValue(0), offset_var, /*l=*/kNoLiteralIndex); +} + +inline void PrecedencesPropagator::AddPrecedenceWithAllOptions( + IntegerVariable i1, IntegerVariable i2, IntegerValue offset, + IntegerVariable offset_var, LiteralIndex r) { + AddArc(i1, i2, offset, offset_var, r); +} + +// ============================================================================= +// Model based functions. +// ============================================================================= + +// a <= b. +inline std::function LowerOrEqual(IntegerVariable a, + IntegerVariable b) { + return [=](Model* model) { + return model->GetOrCreate()->AddPrecedence(a, b); + }; +} + +// a + offset <= b. +inline std::function LowerOrEqualWithOffset(IntegerVariable a, + IntegerVariable b, + int64 offset) { + return [=](Model* model) { + return model->GetOrCreate()->AddPrecedenceWithOffset( + a, b, IntegerValue(offset)); + }; +} + +// a + b <= ub. +inline std::function Sum2LowerOrEqual(IntegerVariable a, + IntegerVariable b, + int64 ub) { + return LowerOrEqualWithOffset(a, NegationOf(b), -ub); +} + +// l => (a + b <= ub). +inline std::function ConditionalSum2LowerOrEqual( + IntegerVariable a, IntegerVariable b, int64 ub, Literal l) { + return [=](Model* model) { + PrecedencesPropagator* p = model->GetOrCreate(); + p->AddPrecedenceWithAllOptions(a, NegationOf(b), IntegerValue(-ub), + kNoIntegerVariable, l.Index()); + }; +} + +// a + b + c <= ub. +inline std::function Sum3LowerOrEqual(IntegerVariable a, + IntegerVariable b, + IntegerVariable c, + int64 ub) { + return [=](Model* model) { + PrecedencesPropagator* p = model->GetOrCreate(); + p->AddPrecedenceWithAllOptions(a, NegationOf(c), IntegerValue(-ub), b, + kNoLiteralIndex); + }; +} + +// l => (a + b + c <= ub). +inline std::function ConditionalSum3LowerOrEqual( + IntegerVariable a, IntegerVariable b, IntegerVariable c, int64 ub, + Literal l) { + return [=](Model* model) { + PrecedencesPropagator* p = model->GetOrCreate(); + p->AddPrecedenceWithAllOptions(a, NegationOf(c), IntegerValue(-ub), b, + l.Index()); + }; +} + +// a >= b. +inline std::function GreaterOrEqual(IntegerVariable a, + IntegerVariable b) { + return [=](Model* model) { + return model->GetOrCreate()->AddPrecedence(b, a); + }; +} + +// a == b. +inline std::function Equality(IntegerVariable a, + IntegerVariable b) { + return [=](Model* model) { + model->Add(LowerOrEqual(a, b)); + model->Add(LowerOrEqual(b, a)); + }; +} + +// a + offset == b. +inline std::function EqualityWithOffset(IntegerVariable a, + IntegerVariable b, + int64 offset) { + return [=](Model* model) { + model->Add(LowerOrEqualWithOffset(a, b, offset)); + model->Add(LowerOrEqualWithOffset(b, a, -offset)); + }; +} + +// is_le => (a + offset <= b). +inline std::function ConditionalLowerOrEqualWithOffset( + IntegerVariable a, IntegerVariable b, int64 offset, Literal is_le) { + return [=](Model* model) { + PrecedencesPropagator* p = model->GetOrCreate(); + p->AddConditionalPrecedenceWithOffset(a, b, IntegerValue(offset), is_le); + }; +} + +// is_le => (a <= b). +inline std::function ConditionalLowerOrEqual(IntegerVariable a, + IntegerVariable b, + Literal is_le) { + return ConditionalLowerOrEqualWithOffset(a, b, 0, is_le); +} + +// is_le <=> (a + offset <= b). +inline std::function ReifiedLowerOrEqualWithOffset( + IntegerVariable a, IntegerVariable b, int64 offset, Literal is_le) { + return [=](Model* model) { + PrecedencesPropagator* p = model->GetOrCreate(); + p->AddConditionalPrecedenceWithOffset(a, b, IntegerValue(offset), is_le); + + // The negation of (a + offset <= b) is (a + offset > b) which can be + // rewritten as (b + 1 - offset <= a). + p->AddConditionalPrecedenceWithOffset(b, a, IntegerValue(1 - offset), + is_le.Negated()); + }; +} + +// is_eq <=> (a == b). +inline std::function ReifiedEquality(IntegerVariable a, + IntegerVariable b, + Literal is_eq) { + return [=](Model* model) { + // We creates two extra Boolean variables in this case. + // + // TODO(user): Avoid creating them if we already have some literal that + // have the same meaning. For instance if a client also wanted to know if + // a <= b, he would have called ReifiedLowerOrEqualWithOffset() directly. + const Literal is_le = Literal(model->Add(NewBooleanVariable()), true); + const Literal is_ge = Literal(model->Add(NewBooleanVariable()), true); + model->Add(ReifiedBoolAnd({is_le, is_ge}, is_eq)); + model->Add(ReifiedLowerOrEqualWithOffset(a, b, 0, is_le)); + model->Add(ReifiedLowerOrEqualWithOffset(b, a, 0, is_ge)); + }; +} + +// is_eq <=> (a + offset == b). +inline std::function ReifiedEqualityWithOffset(IntegerVariable a, + IntegerVariable b, + int64 offset, + Literal is_eq) { + return [=](Model* model) { + // We creates two extra Boolean variables in this case. + // + // TODO(user): Avoid creating them if we already have some literal that + // have the same meaning. For instance if a client also wanted to know if + // a <= b, he would have called ReifiedLowerOrEqualWithOffset() directly. + const Literal is_le = Literal(model->Add(NewBooleanVariable()), true); + const Literal is_ge = Literal(model->Add(NewBooleanVariable()), true); + model->Add(ReifiedBoolAnd({is_le, is_ge}, is_eq)); + model->Add(ReifiedLowerOrEqualWithOffset(a, b, offset, is_le)); + model->Add(ReifiedLowerOrEqualWithOffset(b, a, -offset, is_ge)); + }; +} + +// a != b. +inline std::function NotEqual(IntegerVariable a, + IntegerVariable b) { + return [=](Model* model) { + // We have two options (is_gt or is_lt) and one must be true. + const Literal is_lt = Literal(model->Add(NewBooleanVariable()), true); + const Literal is_gt = is_lt.Negated(); + model->Add(ConditionalLowerOrEqualWithOffset(a, b, 1, is_lt)); + model->Add(ConditionalLowerOrEqualWithOffset(b, a, 1, is_gt)); + }; +} + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_PRECEDENCES_H_ diff --git a/thirdparty/linux/include/ortools/sat/sat_base.h b/thirdparty/linux/include/ortools/sat/sat_base.h new file mode 100644 index 0000000..544b2d7 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/sat_base.h @@ -0,0 +1,600 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Basic types and classes used by the sat solver. + +#ifndef OR_TOOLS_SAT_SAT_BASE_H_ +#define OR_TOOLS_SAT_SAT_BASE_H_ + +#include +#include +#include +#include + +#include "ortools/base/stringprintf.h" +#include "ortools/base/int_type.h" +#include "ortools/base/int_type_indexed_vector.h" +#include "ortools/sat/model.h" +#include "ortools/util/bitset.h" + +namespace operations_research { +namespace sat { + +// Index of a variable (>= 0). +DEFINE_INT_TYPE(BooleanVariable, int); +const BooleanVariable kNoBooleanVariable(-1); + +// Index of a literal (>= 0), see Literal below. +DEFINE_INT_TYPE(LiteralIndex, int); +const LiteralIndex kNoLiteralIndex(-1); + +// Special values used in some API to indicate a literal that is always true +// or always false. +const LiteralIndex kTrueLiteralIndex(-2); +const LiteralIndex kFalseLiteralIndex(-3); + +// A literal is used to represent a variable or its negation. If it represents +// the variable it is said to be positive. If it represent its negation, it is +// said to be negative. We support two representations as an integer. +// +// The "signed" encoding of a literal is convenient for input/output and is used +// in the cnf file format. For a 0-based variable index x, (x + 1) represent the +// variable x and -(x + 1) represent its negation. The signed value 0 is an +// undefined literal and this class can never contain it. +// +// The "index" encoding of a literal is convenient as an index to an array +// and is the one used internally for efficiency. It is always positive or zero, +// and for a 0-based variable index x, (x << 1) encode the variable x and the +// same number XOR 1 encode its negation. +class Literal { + public: + // Not explicit for tests so we can write: + // std::vector literal = {+1, -3, +4, -9}; + Literal(int signed_value) // NOLINT + : index_(signed_value > 0 ? ((signed_value - 1) << 1) + : ((-signed_value - 1) << 1) ^ 1) { + CHECK_NE(signed_value, 0); + } + + Literal() {} + explicit Literal(LiteralIndex index) : index_(index.value()) {} + Literal(BooleanVariable variable, bool is_positive) + : index_(is_positive ? (variable.value() << 1) + : (variable.value() << 1) ^ 1) {} + + BooleanVariable Variable() const { return BooleanVariable(index_ >> 1); } + bool IsPositive() const { return !(index_ & 1); } + bool IsNegative() const { return (index_ & 1); } + + LiteralIndex Index() const { return LiteralIndex(index_); } + LiteralIndex NegatedIndex() const { return LiteralIndex(index_ ^ 1); } + + int SignedValue() const { + return (index_ & 1) ? -((index_ >> 1) + 1) : ((index_ >> 1) + 1); + } + + Literal Negated() const { return Literal(NegatedIndex()); } + + std::string DebugString() const { return StringPrintf("%+d", SignedValue()); } + bool operator==(Literal other) const { return index_ == other.index_; } + bool operator!=(Literal other) const { return index_ != other.index_; } + + bool operator<(const Literal& literal) const { + return Index() < literal.Index(); + } + + private: + int index_; +}; + +inline std::ostream& operator<<(std::ostream& os, Literal literal) { + os << literal.DebugString(); + return os; +} + +// Holds the current variable assignment of the solver. +// Each variable can be unassigned or be assigned to true or false. +class VariablesAssignment { + public: + VariablesAssignment() {} + explicit VariablesAssignment(int num_variables) { Resize(num_variables); } + void Resize(int num_variables) { + assignment_.Resize(LiteralIndex(num_variables << 1)); + } + + // Makes the given literal true by assigning its underlying variable to either + // true or false depending on the literal sign. This can only be called on an + // unassigned variable. + void AssignFromTrueLiteral(Literal literal) { + DCHECK(!VariableIsAssigned(literal.Variable())); + assignment_.Set(literal.Index()); + } + + // Unassign the variable corresponding to the given literal. + // This can only be called on an assigned variable. + void UnassignLiteral(Literal literal) { + DCHECK(VariableIsAssigned(literal.Variable())); + assignment_.ClearTwoBits(literal.Index()); + } + + // Literal getters. Note that both can be false, in which case the + // corresponding variable is not assigned. + bool LiteralIsFalse(Literal literal) const { + return assignment_.IsSet(literal.NegatedIndex()); + } + bool LiteralIsTrue(Literal literal) const { + return assignment_.IsSet(literal.Index()); + } + bool IsLiteralAssigned(Literal literal) const { + return assignment_.AreOneOfTwoBitsSet(literal.Index()); + } + + // Returns true iff the given variable is assigned. + bool VariableIsAssigned(BooleanVariable var) const { + return assignment_.AreOneOfTwoBitsSet(LiteralIndex(var.value() << 1)); + } + + // Returns the literal of the given variable that is assigned to true. + // That is, depending on the variable, it can be the positive literal or the + // negative one. Only call this on an assigned variable. + Literal GetTrueLiteralForAssignedVariable(BooleanVariable var) const { + DCHECK(VariableIsAssigned(var)); + return Literal(var, assignment_.IsSet(LiteralIndex(var.value() << 1))); + } + + int NumberOfVariables() const { return assignment_.size().value() / 2; } + + private: + // The encoding is as follows: + // - assignment_.IsSet(literal.Index()) means literal is true. + // - assignment_.IsSet(literal.Index() ^ 1]) means literal is false. + // - If both are false, then the variable (and the literal) is unassigned. + Bitset64 assignment_; + + DISALLOW_COPY_AND_ASSIGN(VariablesAssignment); +}; + +// A simple wrapper used to pass a reference to a clause. This +// abstraction is needed because not all clauses come from an underlying +// SatClause or are encoded with a std::vector. +// +// This class should be passed by value. +class ClauseRef { + public: + ClauseRef() : begin_(nullptr), end_(nullptr) {} + ClauseRef(Literal const* b, Literal const* e) : begin_(b), end_(e) {} + explicit ClauseRef(const std::vector& literals) + : begin_(literals.empty() ? nullptr : &literals[0]), + end_(literals.empty() ? nullptr : &literals[0] + literals.size()) {} + + // For testing so this can be used with EXPECT_THAT(). + typedef Literal value_type; + typedef const Literal* const_iterator; + + // Allows for range based iteration: for (Literal literal : clause_ref) {}. + Literal const* begin() const { return begin_; } + Literal const* end() const { return end_; } + + // Returns true if this clause contains no literal. + bool IsEmpty() const { return begin_ == end_; } + int size() const { return end_ - begin_; } + + private: + Literal const* begin_; + Literal const* end_; +}; + +// Forward declaration. +class SatClause; +class SatPropagator; + +// Information about a variable assignment. +struct AssignmentInfo { + // The decision level at which this assignment was made. This starts at 0 and + // increases each time the solver takes a search decision. + // + // TODO(user): We may be able to get rid of that for faster enqueues. Most of + // the code only need to know if this is 0 or the highest level, and for the + // LBD computation, the literal of the conflict are already ordered by level, + // so we could do it fairly efficiently. + // + // TODO(user): We currently don't support more than 134M decision levels. That + // should be enough for most practical problem, but we should fail properly if + // this limit is reached. + bool last_polarity : 1; + uint32 level : 27; + + // The type of assignment (see AssignmentType below). + // + // Note(user): We currently don't support more than 16 types of assignment. + // This is checked in RegisterPropagator(). + mutable uint32 type : 4; + + // The index of this assignment in the trail. + int32 trail_index; + + std::string DebugString() const { + return StringPrintf("level:%d type:%d trail_index:%d", level, type, + trail_index); + } +}; +COMPILE_ASSERT(sizeof(AssignmentInfo) == 8, + ERROR_AssignmentInfo_is_not_well_compacted); + +// Each literal on the trail will have an associated propagation "type" which is +// either one of these special types or the id of a propagator. +struct AssignmentType { + static const int kCachedReason = 0; + static const int kUnitReason = 1; + static const int kSearchDecision = 2; + static const int kSameReasonAs = 3; + + // Propagator ids starts from there and are created dynamically. + static const int kFirstFreePropagationId = 4; +}; + +// The solver trail stores the assignment made by the solver in order. +// This class is responsible for maintaining the assignment of each variable +// and the information of each assignment. +class Trail { + public: + Trail() : num_enqueues_(0) { + current_info_.trail_index = 0; + current_info_.level = 0; + } + + static Trail* CreateInModel(Model* model) { + Trail* trail = new Trail(); + model->TakeOwnership(trail); + return trail; + } + + void Resize(int num_variables); + + // Registers a propagator. This assigns a unique id to this propagator and + // calls SetPropagatorId() on it. + void RegisterPropagator(SatPropagator* propagator); + + // Enqueues the assignment that make the given literal true on the trail. This + // should only be called on unassigned variables. + void Enqueue(Literal true_literal, int propagator_id) { + DCHECK(!assignment_.VariableIsAssigned(true_literal.Variable())); + trail_[current_info_.trail_index] = true_literal; + current_info_.last_polarity = true_literal.IsPositive(); + current_info_.type = propagator_id; + info_[true_literal.Variable()] = current_info_; + assignment_.AssignFromTrueLiteral(true_literal); + ++num_enqueues_; + ++current_info_.trail_index; + } + + // Specific Enqueue() version for the search decision. + void EnqueueSearchDecision(Literal true_literal) { + Enqueue(true_literal, AssignmentType::kSearchDecision); + } + + // Specific Enqueue() version for a fixed variable. + void EnqueueWithUnitReason(Literal true_literal) { + Enqueue(true_literal, AssignmentType::kUnitReason); + } + + // Some constraints propagate a lot of literals at once. In these cases, it is + // more efficient to have all the propagated literals except the first one + // referring to the reason of the first of them. + void EnqueueWithSameReasonAs(Literal true_literal, + BooleanVariable reference_var) { + reference_var_with_same_reason_as_[true_literal.Variable()] = reference_var; + Enqueue(true_literal, AssignmentType::kSameReasonAs); + } + + // Returns the reason why this variable was assigned. + ClauseRef Reason(BooleanVariable var) const; + + // Returns the "type" of an assignment (see AssignmentType). Note that this + // function never returns kSameReasonAs or kCachedReason, it instead returns + // the initial type that caused this assignment. As such, it is different + // from Info(var).type and the latter should not be used outside this class. + int AssignmentType(BooleanVariable var) const; + + // If a variable was propagated with EnqueueWithSameReasonAs(), returns its + // reference variable. Otherwise return the given variable. + BooleanVariable ReferenceVarWithSameReason(BooleanVariable var) const; + + // This can be used to get a location at which the reason for the literal + // at trail_index on the trail can be stored. + std::vector* GetVectorToStoreReason(int trail_index) const { + if (trail_index >= reasons_repository_.size()) { + reasons_repository_.resize(trail_index + 1); + } + return &reasons_repository_[trail_index]; + } + + // After this is called, Reason(var) will return the content of the + // GetVectorToStoreReason(trail_index_of_var) and will not call the virtual + // Reason() function of the associated propagator. + void NotifyThatReasonIsCached(BooleanVariable var) const { + DCHECK(assignment_.VariableIsAssigned(var)); + const std::vector& reason = + reasons_repository_[info_[var].trail_index]; + reasons_[var] = reason.empty() ? ClauseRef() : ClauseRef(reason); + old_type_[var] = info_[var].type; + info_[var].type = AssignmentType::kCachedReason; + } + + // Dequeues the last assigned literal and returns it. + // Note that we do not touch its assignment info. + Literal Dequeue() { + const Literal l = trail_[--current_info_.trail_index]; + assignment_.UnassignLiteral(l); + return l; + } + + // Changes the decision level used by the next Enqueue(). + void SetDecisionLevel(int level) { current_info_.level = level; } + int CurrentDecisionLevel() const { return current_info_.level; } + + // Generic interface to set the current failing clause. + // + // Returns the address of a vector where a client can store the current + // conflict. This vector will be returned by the FailingClause() call. + std::vector* MutableConflict() { + failing_sat_clause_ = nullptr; + return &conflict_; + } + + // Returns the last conflict. + ClauseRef FailingClause() const { + return conflict_.empty() ? ClauseRef() : ClauseRef(conflict_); + } + + // Specific SatClause interface so we can update the conflict clause activity. + // Note that MutableConflict() automatically sets this to nullptr, so we can + // know whether or not the last conflict was caused by a clause. + void SetFailingSatClause(SatClause* clause) { failing_sat_clause_ = clause; } + SatClause* FailingSatClause() const { return failing_sat_clause_; } + + // Getters. + int NumVariables() const { return trail_.size(); } + int64 NumberOfEnqueues() const { return num_enqueues_; } + int Index() const { return current_info_.trail_index; } + const Literal operator[](int index) const { return trail_[index]; } + const VariablesAssignment& Assignment() const { return assignment_; } + const AssignmentInfo& Info(BooleanVariable var) const { + DCHECK_GE(var, 0); + DCHECK_LT(var, info_.size()); + return info_[var]; + } + + // Print the current literals on the trail. + std::string DebugString() { + std::string result; + for (int i = 0; i < current_info_.trail_index; ++i) { + if (!result.empty()) result += " "; + result += trail_[i].DebugString(); + } + return result; + } + + void SetLastPolarity(BooleanVariable var, bool polarity) { + info_[var].last_polarity = polarity; + } + + private: + int64 num_enqueues_; + AssignmentInfo current_info_; + VariablesAssignment assignment_; + std::vector trail_; + std::vector conflict_; + ITIVector info_; + SatClause* failing_sat_clause_; + + // Data used by EnqueueWithSameReasonAs(). + ITIVector + reference_var_with_same_reason_as_; + + // Reason cache. Mutable since we want the API to be the same whether the + // reason are cached or not. + // + // When a reason is computed for the first time, we change the type of the + // variable assignment to kCachedReason so that we know that if it is needed + // again the reason can just be retrieved by a direct access to reasons_. The + // old type is saved in old_type_ and can be retrieved by + // AssignmentType(). + // + // Note(user): Changing the type is not "clean" but it is efficient. The idea + // is that it is important to do as little as possible when pushing/popping + // literals on the trail. Computing the reason happens a lot less often, so it + // is okay to do slightly more work then. Note also, that we don't need to + // do anything on "untrail", the kCachedReason type will be overwritten when + // the same variable is assigned again. + // + // TODO(user): An alternative would be to change the sign of the type. This + // would remove the need for a separate old_type_ vector, but it requires + // more bits for the type filed in AssignmentInfo. + // + // Note that we use a deque for the reason repository so that if we add + // variables, the memory address of the vectors (kept in reasons_) are still + // valid. + mutable std::deque> reasons_repository_; + mutable ITIVector reasons_; + mutable ITIVector old_type_; + + // This is used by RegisterPropagator() and Reason(). + std::vector propagators_; + + DISALLOW_COPY_AND_ASSIGN(Trail); +}; + +// Base class for all the SAT constraints. +class SatPropagator { + public: + explicit SatPropagator(const std::string& name) + : name_(name), propagator_id_(-1), propagation_trail_index_(0) {} + virtual ~SatPropagator() {} + + // Sets/Gets this propagator unique id. + void SetPropagatorId(int id) { propagator_id_ = id; } + int PropagatorId() const { return propagator_id_; } + + // Inspects the trail from propagation_trail_index_ until at least one literal + // is propagated. Returns false iff a conflict is detected (in which case + // trail->SetFailingClause() must be called). + // + // This must update propagation_trail_index_ so that all the literals before + // it have been propagated. In particular, if nothing was propagated, then + // PropagationIsDone() must return true. + virtual bool Propagate(Trail* trail) = 0; + + // Reverts the state so that all the literals with a trail index greater or + // equal to the given one are not processed for propagation. Note that the + // trail current decision level is already reverted before this is called. + // + // TODO(user): Currently this is called at each Backtrack(), but we could + // bundle the calls in case multiple conflict one after the other are detected + // even before the Propagate() call of a SatPropagator is called. + // + // TODO(user): It is not yet 100% the case, but this can be guaranteed to be + // called with a trail index that will always be the start of a new decision + // level. + virtual void Untrail(const Trail& trail, int trail_index) { + propagation_trail_index_ = std::min(propagation_trail_index_, trail_index); + } + + // Explains why the literal at given trail_index was propagated by returning + // a reason ClauseRef for this propagation. This will only be called for + // literals that are on the trail and were propagated by this class. + // + // The interpretation is that because all the literals of a reason were + // assigned to false, we could deduce the assignement of the given variable. + // + // The returned ClauseRef has to be valid until the literal is untrailed. + // A client can use trail_.GetVectorToStoreReason() if it doesn't have a + // memory location that already contains the reason. + virtual ClauseRef Reason(const Trail& trail, int trail_index) const { + LOG(FATAL) << "Not implemented."; +#if !defined(__linux__) // for Mac OS and MSVC++. + return ClauseRef(); +#endif + } + + // Returns true if all the preconditions for Propagate() are satisfied. + // This is just meant to be used in a DCHECK. + bool PropagatePreconditionsAreSatisfied(const Trail& trail) const; + + // Returns true iff all the trail was inspected by this propagator. + bool PropagationIsDone(const Trail& trail) const { + return propagation_trail_index_ == trail.Index(); + } + + protected: + const std::string name_; + int propagator_id_; + int propagation_trail_index_; + + private: + DISALLOW_COPY_AND_ASSIGN(SatPropagator); +}; + +// ######################## Implementations below ######################## + +// TODO(user): A few of these method should be moved in a .cc + +inline bool SatPropagator::PropagatePreconditionsAreSatisfied( + const Trail& trail) const { + if (propagation_trail_index_ > trail.Index()) { + LOG(INFO) << "Issue in '" << name_ << ":" + << " propagation_trail_index_=" << propagation_trail_index_ + << " trail_.Index()=" << trail.Index(); + return false; + } + if (propagation_trail_index_ < trail.Index() && + trail.Info(trail[propagation_trail_index_].Variable()).level != + trail.CurrentDecisionLevel()) { + LOG(INFO) << "Issue in '" << name_ << "':" + << " propagation_trail_index_=" << propagation_trail_index_ + << " trail_.Index()=" << trail.Index() + << " level_at_propagation_index=" + << trail.Info(trail[propagation_trail_index_].Variable()).level + << " current_decision_level=" << trail.CurrentDecisionLevel(); + return false; + } + return true; +} + +inline void Trail::Resize(int num_variables) { + assignment_.Resize(num_variables); + info_.resize(num_variables); + trail_.resize(num_variables); + reasons_.resize(num_variables); + + // TODO(user): these vectors are not always used. Initialize them + // dynamically. + old_type_.resize(num_variables); + reference_var_with_same_reason_as_.resize(num_variables); +} + +inline void Trail::RegisterPropagator(SatPropagator* propagator) { + if (propagators_.empty()) { + propagators_.resize(AssignmentType::kFirstFreePropagationId); + } + CHECK_LT(propagators_.size(), 16); + propagator->SetPropagatorId(propagators_.size()); + propagators_.push_back(propagator); +} + +inline BooleanVariable Trail::ReferenceVarWithSameReason( + BooleanVariable var) const { + DCHECK(Assignment().VariableIsAssigned(var)); + // Note that we don't use AssignmentType() here. + if (info_[var].type == AssignmentType::kSameReasonAs) { + var = reference_var_with_same_reason_as_[var]; + DCHECK(Assignment().VariableIsAssigned(var)); + DCHECK_NE(info_[var].type, AssignmentType::kSameReasonAs); + } + return var; +} + +inline int Trail::AssignmentType(BooleanVariable var) const { + if (info_[var].type == AssignmentType::kSameReasonAs) { + var = reference_var_with_same_reason_as_[var]; + DCHECK_NE(info_[var].type, AssignmentType::kSameReasonAs); + } + const int type = info_[var].type; + return type != AssignmentType::kCachedReason ? type : old_type_[var]; +} + +inline ClauseRef Trail::Reason(BooleanVariable var) const { + // Special case for AssignmentType::kSameReasonAs to avoid a recursive call. + var = ReferenceVarWithSameReason(var); + + // Fast-track for cached reason. + if (info_[var].type == AssignmentType::kCachedReason) return reasons_[var]; + + const AssignmentInfo& info = info_[var]; + if (info.type == AssignmentType::kUnitReason || + info.type == AssignmentType::kSearchDecision) { + reasons_[var] = ClauseRef(); + } else { + DCHECK_LT(info.type, propagators_.size()); + DCHECK(propagators_[info.type] != nullptr) << info.type; + reasons_[var] = propagators_[info.type]->Reason(*this, info.trail_index); + } + old_type_[var] = info.type; + info_[var].type = AssignmentType::kCachedReason; + return reasons_[var]; +} + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_SAT_BASE_H_ diff --git a/thirdparty/linux/include/ortools/sat/sat_parameters.pb.h b/thirdparty/linux/include/ortools/sat/sat_parameters.pb.h new file mode 100644 index 0000000..105ce49 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/sat_parameters.pb.h @@ -0,0 +1,2961 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ortools/sat/sat_parameters.proto + +#ifndef PROTOBUF_ortools_2fsat_2fsat_5fparameters_2eproto__INCLUDED +#define PROTOBUF_ortools_2fsat_2fsat_5fparameters_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace operations_research { +namespace sat { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_ortools_2fsat_2fsat_5fparameters_2eproto(); +void protobuf_AssignDesc_ortools_2fsat_2fsat_5fparameters_2eproto(); +void protobuf_ShutdownFile_ortools_2fsat_2fsat_5fparameters_2eproto(); + +class SatParameters; + +enum SatParameters_VariableOrder { + SatParameters_VariableOrder_IN_ORDER = 0, + SatParameters_VariableOrder_IN_REVERSE_ORDER = 1, + SatParameters_VariableOrder_IN_RANDOM_ORDER = 2 +}; +bool SatParameters_VariableOrder_IsValid(int value); +const SatParameters_VariableOrder SatParameters_VariableOrder_VariableOrder_MIN = SatParameters_VariableOrder_IN_ORDER; +const SatParameters_VariableOrder SatParameters_VariableOrder_VariableOrder_MAX = SatParameters_VariableOrder_IN_RANDOM_ORDER; +const int SatParameters_VariableOrder_VariableOrder_ARRAYSIZE = SatParameters_VariableOrder_VariableOrder_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_VariableOrder_descriptor(); +inline const ::std::string& SatParameters_VariableOrder_Name(SatParameters_VariableOrder value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_VariableOrder_descriptor(), value); +} +inline bool SatParameters_VariableOrder_Parse( + const ::std::string& name, SatParameters_VariableOrder* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_VariableOrder_descriptor(), name, value); +} +enum SatParameters_Polarity { + SatParameters_Polarity_POLARITY_TRUE = 0, + SatParameters_Polarity_POLARITY_FALSE = 1, + SatParameters_Polarity_POLARITY_RANDOM = 2, + SatParameters_Polarity_POLARITY_WEIGHTED_SIGN = 3, + SatParameters_Polarity_POLARITY_REVERSE_WEIGHTED_SIGN = 4 +}; +bool SatParameters_Polarity_IsValid(int value); +const SatParameters_Polarity SatParameters_Polarity_Polarity_MIN = SatParameters_Polarity_POLARITY_TRUE; +const SatParameters_Polarity SatParameters_Polarity_Polarity_MAX = SatParameters_Polarity_POLARITY_REVERSE_WEIGHTED_SIGN; +const int SatParameters_Polarity_Polarity_ARRAYSIZE = SatParameters_Polarity_Polarity_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_Polarity_descriptor(); +inline const ::std::string& SatParameters_Polarity_Name(SatParameters_Polarity value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_Polarity_descriptor(), value); +} +inline bool SatParameters_Polarity_Parse( + const ::std::string& name, SatParameters_Polarity* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_Polarity_descriptor(), name, value); +} +enum SatParameters_LiteralOrdering { + SatParameters_LiteralOrdering_LITERAL_IN_ORDER = 0, + SatParameters_LiteralOrdering_VAR_MIN_USAGE = 1, + SatParameters_LiteralOrdering_VAR_MAX_USAGE = 2 +}; +bool SatParameters_LiteralOrdering_IsValid(int value); +const SatParameters_LiteralOrdering SatParameters_LiteralOrdering_LiteralOrdering_MIN = SatParameters_LiteralOrdering_LITERAL_IN_ORDER; +const SatParameters_LiteralOrdering SatParameters_LiteralOrdering_LiteralOrdering_MAX = SatParameters_LiteralOrdering_VAR_MAX_USAGE; +const int SatParameters_LiteralOrdering_LiteralOrdering_ARRAYSIZE = SatParameters_LiteralOrdering_LiteralOrdering_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_LiteralOrdering_descriptor(); +inline const ::std::string& SatParameters_LiteralOrdering_Name(SatParameters_LiteralOrdering value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_LiteralOrdering_descriptor(), value); +} +inline bool SatParameters_LiteralOrdering_Parse( + const ::std::string& name, SatParameters_LiteralOrdering* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_LiteralOrdering_descriptor(), name, value); +} +enum SatParameters_ConflictMinimizationAlgorithm { + SatParameters_ConflictMinimizationAlgorithm_NONE = 0, + SatParameters_ConflictMinimizationAlgorithm_SIMPLE = 1, + SatParameters_ConflictMinimizationAlgorithm_RECURSIVE = 2, + SatParameters_ConflictMinimizationAlgorithm_EXPERIMENTAL = 3 +}; +bool SatParameters_ConflictMinimizationAlgorithm_IsValid(int value); +const SatParameters_ConflictMinimizationAlgorithm SatParameters_ConflictMinimizationAlgorithm_ConflictMinimizationAlgorithm_MIN = SatParameters_ConflictMinimizationAlgorithm_NONE; +const SatParameters_ConflictMinimizationAlgorithm SatParameters_ConflictMinimizationAlgorithm_ConflictMinimizationAlgorithm_MAX = SatParameters_ConflictMinimizationAlgorithm_EXPERIMENTAL; +const int SatParameters_ConflictMinimizationAlgorithm_ConflictMinimizationAlgorithm_ARRAYSIZE = SatParameters_ConflictMinimizationAlgorithm_ConflictMinimizationAlgorithm_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_ConflictMinimizationAlgorithm_descriptor(); +inline const ::std::string& SatParameters_ConflictMinimizationAlgorithm_Name(SatParameters_ConflictMinimizationAlgorithm value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_ConflictMinimizationAlgorithm_descriptor(), value); +} +inline bool SatParameters_ConflictMinimizationAlgorithm_Parse( + const ::std::string& name, SatParameters_ConflictMinimizationAlgorithm* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_ConflictMinimizationAlgorithm_descriptor(), name, value); +} +enum SatParameters_BinaryMinizationAlgorithm { + SatParameters_BinaryMinizationAlgorithm_NO_BINARY_MINIMIZATION = 0, + SatParameters_BinaryMinizationAlgorithm_BINARY_MINIMIZATION_FIRST = 1, + SatParameters_BinaryMinizationAlgorithm_BINARY_MINIMIZATION_FIRST_WITH_TRANSITIVE_REDUCTION = 4, + SatParameters_BinaryMinizationAlgorithm_BINARY_MINIMIZATION_WITH_REACHABILITY = 2, + SatParameters_BinaryMinizationAlgorithm_EXPERIMENTAL_BINARY_MINIMIZATION = 3 +}; +bool SatParameters_BinaryMinizationAlgorithm_IsValid(int value); +const SatParameters_BinaryMinizationAlgorithm SatParameters_BinaryMinizationAlgorithm_BinaryMinizationAlgorithm_MIN = SatParameters_BinaryMinizationAlgorithm_NO_BINARY_MINIMIZATION; +const SatParameters_BinaryMinizationAlgorithm SatParameters_BinaryMinizationAlgorithm_BinaryMinizationAlgorithm_MAX = SatParameters_BinaryMinizationAlgorithm_BINARY_MINIMIZATION_FIRST_WITH_TRANSITIVE_REDUCTION; +const int SatParameters_BinaryMinizationAlgorithm_BinaryMinizationAlgorithm_ARRAYSIZE = SatParameters_BinaryMinizationAlgorithm_BinaryMinizationAlgorithm_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_BinaryMinizationAlgorithm_descriptor(); +inline const ::std::string& SatParameters_BinaryMinizationAlgorithm_Name(SatParameters_BinaryMinizationAlgorithm value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_BinaryMinizationAlgorithm_descriptor(), value); +} +inline bool SatParameters_BinaryMinizationAlgorithm_Parse( + const ::std::string& name, SatParameters_BinaryMinizationAlgorithm* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_BinaryMinizationAlgorithm_descriptor(), name, value); +} +enum SatParameters_ClauseProtection { + SatParameters_ClauseProtection_PROTECTION_NONE = 0, + SatParameters_ClauseProtection_PROTECTION_ALWAYS = 1, + SatParameters_ClauseProtection_PROTECTION_LBD = 2 +}; +bool SatParameters_ClauseProtection_IsValid(int value); +const SatParameters_ClauseProtection SatParameters_ClauseProtection_ClauseProtection_MIN = SatParameters_ClauseProtection_PROTECTION_NONE; +const SatParameters_ClauseProtection SatParameters_ClauseProtection_ClauseProtection_MAX = SatParameters_ClauseProtection_PROTECTION_LBD; +const int SatParameters_ClauseProtection_ClauseProtection_ARRAYSIZE = SatParameters_ClauseProtection_ClauseProtection_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_ClauseProtection_descriptor(); +inline const ::std::string& SatParameters_ClauseProtection_Name(SatParameters_ClauseProtection value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_ClauseProtection_descriptor(), value); +} +inline bool SatParameters_ClauseProtection_Parse( + const ::std::string& name, SatParameters_ClauseProtection* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_ClauseProtection_descriptor(), name, value); +} +enum SatParameters_ClauseOrdering { + SatParameters_ClauseOrdering_CLAUSE_ACTIVITY = 0, + SatParameters_ClauseOrdering_CLAUSE_LBD = 1 +}; +bool SatParameters_ClauseOrdering_IsValid(int value); +const SatParameters_ClauseOrdering SatParameters_ClauseOrdering_ClauseOrdering_MIN = SatParameters_ClauseOrdering_CLAUSE_ACTIVITY; +const SatParameters_ClauseOrdering SatParameters_ClauseOrdering_ClauseOrdering_MAX = SatParameters_ClauseOrdering_CLAUSE_LBD; +const int SatParameters_ClauseOrdering_ClauseOrdering_ARRAYSIZE = SatParameters_ClauseOrdering_ClauseOrdering_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_ClauseOrdering_descriptor(); +inline const ::std::string& SatParameters_ClauseOrdering_Name(SatParameters_ClauseOrdering value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_ClauseOrdering_descriptor(), value); +} +inline bool SatParameters_ClauseOrdering_Parse( + const ::std::string& name, SatParameters_ClauseOrdering* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_ClauseOrdering_descriptor(), name, value); +} +enum SatParameters_RestartAlgorithm { + SatParameters_RestartAlgorithm_NO_RESTART = 0, + SatParameters_RestartAlgorithm_LUBY_RESTART = 1, + SatParameters_RestartAlgorithm_DL_MOVING_AVERAGE_RESTART = 2, + SatParameters_RestartAlgorithm_LBD_MOVING_AVERAGE_RESTART = 3 +}; +bool SatParameters_RestartAlgorithm_IsValid(int value); +const SatParameters_RestartAlgorithm SatParameters_RestartAlgorithm_RestartAlgorithm_MIN = SatParameters_RestartAlgorithm_NO_RESTART; +const SatParameters_RestartAlgorithm SatParameters_RestartAlgorithm_RestartAlgorithm_MAX = SatParameters_RestartAlgorithm_LBD_MOVING_AVERAGE_RESTART; +const int SatParameters_RestartAlgorithm_RestartAlgorithm_ARRAYSIZE = SatParameters_RestartAlgorithm_RestartAlgorithm_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_RestartAlgorithm_descriptor(); +inline const ::std::string& SatParameters_RestartAlgorithm_Name(SatParameters_RestartAlgorithm value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_RestartAlgorithm_descriptor(), value); +} +inline bool SatParameters_RestartAlgorithm_Parse( + const ::std::string& name, SatParameters_RestartAlgorithm* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_RestartAlgorithm_descriptor(), name, value); +} +enum SatParameters_MaxSatAssumptionOrder { + SatParameters_MaxSatAssumptionOrder_DEFAULT_ASSUMPTION_ORDER = 0, + SatParameters_MaxSatAssumptionOrder_ORDER_ASSUMPTION_BY_DEPTH = 1, + SatParameters_MaxSatAssumptionOrder_ORDER_ASSUMPTION_BY_WEIGHT = 2 +}; +bool SatParameters_MaxSatAssumptionOrder_IsValid(int value); +const SatParameters_MaxSatAssumptionOrder SatParameters_MaxSatAssumptionOrder_MaxSatAssumptionOrder_MIN = SatParameters_MaxSatAssumptionOrder_DEFAULT_ASSUMPTION_ORDER; +const SatParameters_MaxSatAssumptionOrder SatParameters_MaxSatAssumptionOrder_MaxSatAssumptionOrder_MAX = SatParameters_MaxSatAssumptionOrder_ORDER_ASSUMPTION_BY_WEIGHT; +const int SatParameters_MaxSatAssumptionOrder_MaxSatAssumptionOrder_ARRAYSIZE = SatParameters_MaxSatAssumptionOrder_MaxSatAssumptionOrder_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_MaxSatAssumptionOrder_descriptor(); +inline const ::std::string& SatParameters_MaxSatAssumptionOrder_Name(SatParameters_MaxSatAssumptionOrder value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_MaxSatAssumptionOrder_descriptor(), value); +} +inline bool SatParameters_MaxSatAssumptionOrder_Parse( + const ::std::string& name, SatParameters_MaxSatAssumptionOrder* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_MaxSatAssumptionOrder_descriptor(), name, value); +} +enum SatParameters_MaxSatStratificationAlgorithm { + SatParameters_MaxSatStratificationAlgorithm_STRATIFICATION_NONE = 0, + SatParameters_MaxSatStratificationAlgorithm_STRATIFICATION_DESCENT = 1, + SatParameters_MaxSatStratificationAlgorithm_STRATIFICATION_ASCENT = 2 +}; +bool SatParameters_MaxSatStratificationAlgorithm_IsValid(int value); +const SatParameters_MaxSatStratificationAlgorithm SatParameters_MaxSatStratificationAlgorithm_MaxSatStratificationAlgorithm_MIN = SatParameters_MaxSatStratificationAlgorithm_STRATIFICATION_NONE; +const SatParameters_MaxSatStratificationAlgorithm SatParameters_MaxSatStratificationAlgorithm_MaxSatStratificationAlgorithm_MAX = SatParameters_MaxSatStratificationAlgorithm_STRATIFICATION_ASCENT; +const int SatParameters_MaxSatStratificationAlgorithm_MaxSatStratificationAlgorithm_ARRAYSIZE = SatParameters_MaxSatStratificationAlgorithm_MaxSatStratificationAlgorithm_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SatParameters_MaxSatStratificationAlgorithm_descriptor(); +inline const ::std::string& SatParameters_MaxSatStratificationAlgorithm_Name(SatParameters_MaxSatStratificationAlgorithm value) { + return ::google::protobuf::internal::NameOfEnum( + SatParameters_MaxSatStratificationAlgorithm_descriptor(), value); +} +inline bool SatParameters_MaxSatStratificationAlgorithm_Parse( + const ::std::string& name, SatParameters_MaxSatStratificationAlgorithm* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SatParameters_MaxSatStratificationAlgorithm_descriptor(), name, value); +} +// =================================================================== + +class SatParameters : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:operations_research.sat.SatParameters) */ { + public: + SatParameters(); + virtual ~SatParameters(); + + SatParameters(const SatParameters& from); + + inline SatParameters& operator=(const SatParameters& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SatParameters& default_instance(); + + void Swap(SatParameters* other); + + // implements Message ---------------------------------------------- + + inline SatParameters* New() const { return New(NULL); } + + SatParameters* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SatParameters& from); + void MergeFrom(const SatParameters& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(SatParameters* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef SatParameters_VariableOrder VariableOrder; + static const VariableOrder IN_ORDER = + SatParameters_VariableOrder_IN_ORDER; + static const VariableOrder IN_REVERSE_ORDER = + SatParameters_VariableOrder_IN_REVERSE_ORDER; + static const VariableOrder IN_RANDOM_ORDER = + SatParameters_VariableOrder_IN_RANDOM_ORDER; + static inline bool VariableOrder_IsValid(int value) { + return SatParameters_VariableOrder_IsValid(value); + } + static const VariableOrder VariableOrder_MIN = + SatParameters_VariableOrder_VariableOrder_MIN; + static const VariableOrder VariableOrder_MAX = + SatParameters_VariableOrder_VariableOrder_MAX; + static const int VariableOrder_ARRAYSIZE = + SatParameters_VariableOrder_VariableOrder_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + VariableOrder_descriptor() { + return SatParameters_VariableOrder_descriptor(); + } + static inline const ::std::string& VariableOrder_Name(VariableOrder value) { + return SatParameters_VariableOrder_Name(value); + } + static inline bool VariableOrder_Parse(const ::std::string& name, + VariableOrder* value) { + return SatParameters_VariableOrder_Parse(name, value); + } + + typedef SatParameters_Polarity Polarity; + static const Polarity POLARITY_TRUE = + SatParameters_Polarity_POLARITY_TRUE; + static const Polarity POLARITY_FALSE = + SatParameters_Polarity_POLARITY_FALSE; + static const Polarity POLARITY_RANDOM = + SatParameters_Polarity_POLARITY_RANDOM; + static const Polarity POLARITY_WEIGHTED_SIGN = + SatParameters_Polarity_POLARITY_WEIGHTED_SIGN; + static const Polarity POLARITY_REVERSE_WEIGHTED_SIGN = + SatParameters_Polarity_POLARITY_REVERSE_WEIGHTED_SIGN; + static inline bool Polarity_IsValid(int value) { + return SatParameters_Polarity_IsValid(value); + } + static const Polarity Polarity_MIN = + SatParameters_Polarity_Polarity_MIN; + static const Polarity Polarity_MAX = + SatParameters_Polarity_Polarity_MAX; + static const int Polarity_ARRAYSIZE = + SatParameters_Polarity_Polarity_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Polarity_descriptor() { + return SatParameters_Polarity_descriptor(); + } + static inline const ::std::string& Polarity_Name(Polarity value) { + return SatParameters_Polarity_Name(value); + } + static inline bool Polarity_Parse(const ::std::string& name, + Polarity* value) { + return SatParameters_Polarity_Parse(name, value); + } + + typedef SatParameters_LiteralOrdering LiteralOrdering; + static const LiteralOrdering LITERAL_IN_ORDER = + SatParameters_LiteralOrdering_LITERAL_IN_ORDER; + static const LiteralOrdering VAR_MIN_USAGE = + SatParameters_LiteralOrdering_VAR_MIN_USAGE; + static const LiteralOrdering VAR_MAX_USAGE = + SatParameters_LiteralOrdering_VAR_MAX_USAGE; + static inline bool LiteralOrdering_IsValid(int value) { + return SatParameters_LiteralOrdering_IsValid(value); + } + static const LiteralOrdering LiteralOrdering_MIN = + SatParameters_LiteralOrdering_LiteralOrdering_MIN; + static const LiteralOrdering LiteralOrdering_MAX = + SatParameters_LiteralOrdering_LiteralOrdering_MAX; + static const int LiteralOrdering_ARRAYSIZE = + SatParameters_LiteralOrdering_LiteralOrdering_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + LiteralOrdering_descriptor() { + return SatParameters_LiteralOrdering_descriptor(); + } + static inline const ::std::string& LiteralOrdering_Name(LiteralOrdering value) { + return SatParameters_LiteralOrdering_Name(value); + } + static inline bool LiteralOrdering_Parse(const ::std::string& name, + LiteralOrdering* value) { + return SatParameters_LiteralOrdering_Parse(name, value); + } + + typedef SatParameters_ConflictMinimizationAlgorithm ConflictMinimizationAlgorithm; + static const ConflictMinimizationAlgorithm NONE = + SatParameters_ConflictMinimizationAlgorithm_NONE; + static const ConflictMinimizationAlgorithm SIMPLE = + SatParameters_ConflictMinimizationAlgorithm_SIMPLE; + static const ConflictMinimizationAlgorithm RECURSIVE = + SatParameters_ConflictMinimizationAlgorithm_RECURSIVE; + static const ConflictMinimizationAlgorithm EXPERIMENTAL = + SatParameters_ConflictMinimizationAlgorithm_EXPERIMENTAL; + static inline bool ConflictMinimizationAlgorithm_IsValid(int value) { + return SatParameters_ConflictMinimizationAlgorithm_IsValid(value); + } + static const ConflictMinimizationAlgorithm ConflictMinimizationAlgorithm_MIN = + SatParameters_ConflictMinimizationAlgorithm_ConflictMinimizationAlgorithm_MIN; + static const ConflictMinimizationAlgorithm ConflictMinimizationAlgorithm_MAX = + SatParameters_ConflictMinimizationAlgorithm_ConflictMinimizationAlgorithm_MAX; + static const int ConflictMinimizationAlgorithm_ARRAYSIZE = + SatParameters_ConflictMinimizationAlgorithm_ConflictMinimizationAlgorithm_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + ConflictMinimizationAlgorithm_descriptor() { + return SatParameters_ConflictMinimizationAlgorithm_descriptor(); + } + static inline const ::std::string& ConflictMinimizationAlgorithm_Name(ConflictMinimizationAlgorithm value) { + return SatParameters_ConflictMinimizationAlgorithm_Name(value); + } + static inline bool ConflictMinimizationAlgorithm_Parse(const ::std::string& name, + ConflictMinimizationAlgorithm* value) { + return SatParameters_ConflictMinimizationAlgorithm_Parse(name, value); + } + + typedef SatParameters_BinaryMinizationAlgorithm BinaryMinizationAlgorithm; + static const BinaryMinizationAlgorithm NO_BINARY_MINIMIZATION = + SatParameters_BinaryMinizationAlgorithm_NO_BINARY_MINIMIZATION; + static const BinaryMinizationAlgorithm BINARY_MINIMIZATION_FIRST = + SatParameters_BinaryMinizationAlgorithm_BINARY_MINIMIZATION_FIRST; + static const BinaryMinizationAlgorithm BINARY_MINIMIZATION_FIRST_WITH_TRANSITIVE_REDUCTION = + SatParameters_BinaryMinizationAlgorithm_BINARY_MINIMIZATION_FIRST_WITH_TRANSITIVE_REDUCTION; + static const BinaryMinizationAlgorithm BINARY_MINIMIZATION_WITH_REACHABILITY = + SatParameters_BinaryMinizationAlgorithm_BINARY_MINIMIZATION_WITH_REACHABILITY; + static const BinaryMinizationAlgorithm EXPERIMENTAL_BINARY_MINIMIZATION = + SatParameters_BinaryMinizationAlgorithm_EXPERIMENTAL_BINARY_MINIMIZATION; + static inline bool BinaryMinizationAlgorithm_IsValid(int value) { + return SatParameters_BinaryMinizationAlgorithm_IsValid(value); + } + static const BinaryMinizationAlgorithm BinaryMinizationAlgorithm_MIN = + SatParameters_BinaryMinizationAlgorithm_BinaryMinizationAlgorithm_MIN; + static const BinaryMinizationAlgorithm BinaryMinizationAlgorithm_MAX = + SatParameters_BinaryMinizationAlgorithm_BinaryMinizationAlgorithm_MAX; + static const int BinaryMinizationAlgorithm_ARRAYSIZE = + SatParameters_BinaryMinizationAlgorithm_BinaryMinizationAlgorithm_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + BinaryMinizationAlgorithm_descriptor() { + return SatParameters_BinaryMinizationAlgorithm_descriptor(); + } + static inline const ::std::string& BinaryMinizationAlgorithm_Name(BinaryMinizationAlgorithm value) { + return SatParameters_BinaryMinizationAlgorithm_Name(value); + } + static inline bool BinaryMinizationAlgorithm_Parse(const ::std::string& name, + BinaryMinizationAlgorithm* value) { + return SatParameters_BinaryMinizationAlgorithm_Parse(name, value); + } + + typedef SatParameters_ClauseProtection ClauseProtection; + static const ClauseProtection PROTECTION_NONE = + SatParameters_ClauseProtection_PROTECTION_NONE; + static const ClauseProtection PROTECTION_ALWAYS = + SatParameters_ClauseProtection_PROTECTION_ALWAYS; + static const ClauseProtection PROTECTION_LBD = + SatParameters_ClauseProtection_PROTECTION_LBD; + static inline bool ClauseProtection_IsValid(int value) { + return SatParameters_ClauseProtection_IsValid(value); + } + static const ClauseProtection ClauseProtection_MIN = + SatParameters_ClauseProtection_ClauseProtection_MIN; + static const ClauseProtection ClauseProtection_MAX = + SatParameters_ClauseProtection_ClauseProtection_MAX; + static const int ClauseProtection_ARRAYSIZE = + SatParameters_ClauseProtection_ClauseProtection_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + ClauseProtection_descriptor() { + return SatParameters_ClauseProtection_descriptor(); + } + static inline const ::std::string& ClauseProtection_Name(ClauseProtection value) { + return SatParameters_ClauseProtection_Name(value); + } + static inline bool ClauseProtection_Parse(const ::std::string& name, + ClauseProtection* value) { + return SatParameters_ClauseProtection_Parse(name, value); + } + + typedef SatParameters_ClauseOrdering ClauseOrdering; + static const ClauseOrdering CLAUSE_ACTIVITY = + SatParameters_ClauseOrdering_CLAUSE_ACTIVITY; + static const ClauseOrdering CLAUSE_LBD = + SatParameters_ClauseOrdering_CLAUSE_LBD; + static inline bool ClauseOrdering_IsValid(int value) { + return SatParameters_ClauseOrdering_IsValid(value); + } + static const ClauseOrdering ClauseOrdering_MIN = + SatParameters_ClauseOrdering_ClauseOrdering_MIN; + static const ClauseOrdering ClauseOrdering_MAX = + SatParameters_ClauseOrdering_ClauseOrdering_MAX; + static const int ClauseOrdering_ARRAYSIZE = + SatParameters_ClauseOrdering_ClauseOrdering_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + ClauseOrdering_descriptor() { + return SatParameters_ClauseOrdering_descriptor(); + } + static inline const ::std::string& ClauseOrdering_Name(ClauseOrdering value) { + return SatParameters_ClauseOrdering_Name(value); + } + static inline bool ClauseOrdering_Parse(const ::std::string& name, + ClauseOrdering* value) { + return SatParameters_ClauseOrdering_Parse(name, value); + } + + typedef SatParameters_RestartAlgorithm RestartAlgorithm; + static const RestartAlgorithm NO_RESTART = + SatParameters_RestartAlgorithm_NO_RESTART; + static const RestartAlgorithm LUBY_RESTART = + SatParameters_RestartAlgorithm_LUBY_RESTART; + static const RestartAlgorithm DL_MOVING_AVERAGE_RESTART = + SatParameters_RestartAlgorithm_DL_MOVING_AVERAGE_RESTART; + static const RestartAlgorithm LBD_MOVING_AVERAGE_RESTART = + SatParameters_RestartAlgorithm_LBD_MOVING_AVERAGE_RESTART; + static inline bool RestartAlgorithm_IsValid(int value) { + return SatParameters_RestartAlgorithm_IsValid(value); + } + static const RestartAlgorithm RestartAlgorithm_MIN = + SatParameters_RestartAlgorithm_RestartAlgorithm_MIN; + static const RestartAlgorithm RestartAlgorithm_MAX = + SatParameters_RestartAlgorithm_RestartAlgorithm_MAX; + static const int RestartAlgorithm_ARRAYSIZE = + SatParameters_RestartAlgorithm_RestartAlgorithm_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + RestartAlgorithm_descriptor() { + return SatParameters_RestartAlgorithm_descriptor(); + } + static inline const ::std::string& RestartAlgorithm_Name(RestartAlgorithm value) { + return SatParameters_RestartAlgorithm_Name(value); + } + static inline bool RestartAlgorithm_Parse(const ::std::string& name, + RestartAlgorithm* value) { + return SatParameters_RestartAlgorithm_Parse(name, value); + } + + typedef SatParameters_MaxSatAssumptionOrder MaxSatAssumptionOrder; + static const MaxSatAssumptionOrder DEFAULT_ASSUMPTION_ORDER = + SatParameters_MaxSatAssumptionOrder_DEFAULT_ASSUMPTION_ORDER; + static const MaxSatAssumptionOrder ORDER_ASSUMPTION_BY_DEPTH = + SatParameters_MaxSatAssumptionOrder_ORDER_ASSUMPTION_BY_DEPTH; + static const MaxSatAssumptionOrder ORDER_ASSUMPTION_BY_WEIGHT = + SatParameters_MaxSatAssumptionOrder_ORDER_ASSUMPTION_BY_WEIGHT; + static inline bool MaxSatAssumptionOrder_IsValid(int value) { + return SatParameters_MaxSatAssumptionOrder_IsValid(value); + } + static const MaxSatAssumptionOrder MaxSatAssumptionOrder_MIN = + SatParameters_MaxSatAssumptionOrder_MaxSatAssumptionOrder_MIN; + static const MaxSatAssumptionOrder MaxSatAssumptionOrder_MAX = + SatParameters_MaxSatAssumptionOrder_MaxSatAssumptionOrder_MAX; + static const int MaxSatAssumptionOrder_ARRAYSIZE = + SatParameters_MaxSatAssumptionOrder_MaxSatAssumptionOrder_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + MaxSatAssumptionOrder_descriptor() { + return SatParameters_MaxSatAssumptionOrder_descriptor(); + } + static inline const ::std::string& MaxSatAssumptionOrder_Name(MaxSatAssumptionOrder value) { + return SatParameters_MaxSatAssumptionOrder_Name(value); + } + static inline bool MaxSatAssumptionOrder_Parse(const ::std::string& name, + MaxSatAssumptionOrder* value) { + return SatParameters_MaxSatAssumptionOrder_Parse(name, value); + } + + typedef SatParameters_MaxSatStratificationAlgorithm MaxSatStratificationAlgorithm; + static const MaxSatStratificationAlgorithm STRATIFICATION_NONE = + SatParameters_MaxSatStratificationAlgorithm_STRATIFICATION_NONE; + static const MaxSatStratificationAlgorithm STRATIFICATION_DESCENT = + SatParameters_MaxSatStratificationAlgorithm_STRATIFICATION_DESCENT; + static const MaxSatStratificationAlgorithm STRATIFICATION_ASCENT = + SatParameters_MaxSatStratificationAlgorithm_STRATIFICATION_ASCENT; + static inline bool MaxSatStratificationAlgorithm_IsValid(int value) { + return SatParameters_MaxSatStratificationAlgorithm_IsValid(value); + } + static const MaxSatStratificationAlgorithm MaxSatStratificationAlgorithm_MIN = + SatParameters_MaxSatStratificationAlgorithm_MaxSatStratificationAlgorithm_MIN; + static const MaxSatStratificationAlgorithm MaxSatStratificationAlgorithm_MAX = + SatParameters_MaxSatStratificationAlgorithm_MaxSatStratificationAlgorithm_MAX; + static const int MaxSatStratificationAlgorithm_ARRAYSIZE = + SatParameters_MaxSatStratificationAlgorithm_MaxSatStratificationAlgorithm_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + MaxSatStratificationAlgorithm_descriptor() { + return SatParameters_MaxSatStratificationAlgorithm_descriptor(); + } + static inline const ::std::string& MaxSatStratificationAlgorithm_Name(MaxSatStratificationAlgorithm value) { + return SatParameters_MaxSatStratificationAlgorithm_Name(value); + } + static inline bool MaxSatStratificationAlgorithm_Parse(const ::std::string& name, + MaxSatStratificationAlgorithm* value) { + return SatParameters_MaxSatStratificationAlgorithm_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .operations_research.sat.SatParameters.VariableOrder preferred_variable_order = 1 [default = IN_ORDER]; + bool has_preferred_variable_order() const; + void clear_preferred_variable_order(); + static const int kPreferredVariableOrderFieldNumber = 1; + ::operations_research::sat::SatParameters_VariableOrder preferred_variable_order() const; + void set_preferred_variable_order(::operations_research::sat::SatParameters_VariableOrder value); + + // optional .operations_research.sat.SatParameters.Polarity initial_polarity = 2 [default = POLARITY_FALSE]; + bool has_initial_polarity() const; + void clear_initial_polarity(); + static const int kInitialPolarityFieldNumber = 2; + ::operations_research::sat::SatParameters_Polarity initial_polarity() const; + void set_initial_polarity(::operations_research::sat::SatParameters_Polarity value); + + // optional bool use_phase_saving = 44 [default = true]; + bool has_use_phase_saving() const; + void clear_use_phase_saving(); + static const int kUsePhaseSavingFieldNumber = 44; + bool use_phase_saving() const; + void set_use_phase_saving(bool value); + + // optional double random_polarity_ratio = 45 [default = 0]; + bool has_random_polarity_ratio() const; + void clear_random_polarity_ratio(); + static const int kRandomPolarityRatioFieldNumber = 45; + double random_polarity_ratio() const; + void set_random_polarity_ratio(double value); + + // optional double random_branches_ratio = 32 [default = 0]; + bool has_random_branches_ratio() const; + void clear_random_branches_ratio(); + static const int kRandomBranchesRatioFieldNumber = 32; + double random_branches_ratio() const; + void set_random_branches_ratio(double value); + + // optional .operations_research.sat.SatParameters.LiteralOrdering literal_ordering = 3 [default = LITERAL_IN_ORDER]; + bool has_literal_ordering() const; + void clear_literal_ordering(); + static const int kLiteralOrderingFieldNumber = 3; + ::operations_research::sat::SatParameters_LiteralOrdering literal_ordering() const; + void set_literal_ordering(::operations_research::sat::SatParameters_LiteralOrdering value); + + // optional bool use_erwa_heuristic = 75 [default = false]; + bool has_use_erwa_heuristic() const; + void clear_use_erwa_heuristic(); + static const int kUseErwaHeuristicFieldNumber = 75; + bool use_erwa_heuristic() const; + void set_use_erwa_heuristic(bool value); + + // optional double initial_variables_activity = 76 [default = 0]; + bool has_initial_variables_activity() const; + void clear_initial_variables_activity(); + static const int kInitialVariablesActivityFieldNumber = 76; + double initial_variables_activity() const; + void set_initial_variables_activity(double value); + + // optional bool also_bump_variables_in_conflict_reasons = 77 [default = false]; + bool has_also_bump_variables_in_conflict_reasons() const; + void clear_also_bump_variables_in_conflict_reasons(); + static const int kAlsoBumpVariablesInConflictReasonsFieldNumber = 77; + bool also_bump_variables_in_conflict_reasons() const; + void set_also_bump_variables_in_conflict_reasons(bool value); + + // optional .operations_research.sat.SatParameters.ConflictMinimizationAlgorithm minimization_algorithm = 4 [default = RECURSIVE]; + bool has_minimization_algorithm() const; + void clear_minimization_algorithm(); + static const int kMinimizationAlgorithmFieldNumber = 4; + ::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm minimization_algorithm() const; + void set_minimization_algorithm(::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm value); + + // optional .operations_research.sat.SatParameters.BinaryMinizationAlgorithm binary_minimization_algorithm = 34 [default = BINARY_MINIMIZATION_FIRST]; + bool has_binary_minimization_algorithm() const; + void clear_binary_minimization_algorithm(); + static const int kBinaryMinimizationAlgorithmFieldNumber = 34; + ::operations_research::sat::SatParameters_BinaryMinizationAlgorithm binary_minimization_algorithm() const; + void set_binary_minimization_algorithm(::operations_research::sat::SatParameters_BinaryMinizationAlgorithm value); + + // optional bool subsumption_during_conflict_analysis = 56 [default = true]; + bool has_subsumption_during_conflict_analysis() const; + void clear_subsumption_during_conflict_analysis(); + static const int kSubsumptionDuringConflictAnalysisFieldNumber = 56; + bool subsumption_during_conflict_analysis() const; + void set_subsumption_during_conflict_analysis(bool value); + + // optional int32 clause_cleanup_period = 11 [default = 10000]; + bool has_clause_cleanup_period() const; + void clear_clause_cleanup_period(); + static const int kClauseCleanupPeriodFieldNumber = 11; + ::google::protobuf::int32 clause_cleanup_period() const; + void set_clause_cleanup_period(::google::protobuf::int32 value); + + // optional int32 clause_cleanup_target = 13 [default = 10000]; + bool has_clause_cleanup_target() const; + void clear_clause_cleanup_target(); + static const int kClauseCleanupTargetFieldNumber = 13; + ::google::protobuf::int32 clause_cleanup_target() const; + void set_clause_cleanup_target(::google::protobuf::int32 value); + + // optional .operations_research.sat.SatParameters.ClauseProtection clause_cleanup_protection = 58 [default = PROTECTION_NONE]; + bool has_clause_cleanup_protection() const; + void clear_clause_cleanup_protection(); + static const int kClauseCleanupProtectionFieldNumber = 58; + ::operations_research::sat::SatParameters_ClauseProtection clause_cleanup_protection() const; + void set_clause_cleanup_protection(::operations_research::sat::SatParameters_ClauseProtection value); + + // optional int32 clause_cleanup_lbd_bound = 59 [default = 5]; + bool has_clause_cleanup_lbd_bound() const; + void clear_clause_cleanup_lbd_bound(); + static const int kClauseCleanupLbdBoundFieldNumber = 59; + ::google::protobuf::int32 clause_cleanup_lbd_bound() const; + void set_clause_cleanup_lbd_bound(::google::protobuf::int32 value); + + // optional .operations_research.sat.SatParameters.ClauseOrdering clause_cleanup_ordering = 60 [default = CLAUSE_ACTIVITY]; + bool has_clause_cleanup_ordering() const; + void clear_clause_cleanup_ordering(); + static const int kClauseCleanupOrderingFieldNumber = 60; + ::operations_research::sat::SatParameters_ClauseOrdering clause_cleanup_ordering() const; + void set_clause_cleanup_ordering(::operations_research::sat::SatParameters_ClauseOrdering value); + + // optional int32 pb_cleanup_increment = 46 [default = 200]; + bool has_pb_cleanup_increment() const; + void clear_pb_cleanup_increment(); + static const int kPbCleanupIncrementFieldNumber = 46; + ::google::protobuf::int32 pb_cleanup_increment() const; + void set_pb_cleanup_increment(::google::protobuf::int32 value); + + // optional double pb_cleanup_ratio = 47 [default = 0.5]; + bool has_pb_cleanup_ratio() const; + void clear_pb_cleanup_ratio(); + static const int kPbCleanupRatioFieldNumber = 47; + double pb_cleanup_ratio() const; + void set_pb_cleanup_ratio(double value); + + // optional double variable_activity_decay = 15 [default = 0.8]; + bool has_variable_activity_decay() const; + void clear_variable_activity_decay(); + static const int kVariableActivityDecayFieldNumber = 15; + double variable_activity_decay() const; + void set_variable_activity_decay(double value); + + // optional double max_variable_activity_value = 16 [default = 1e+100]; + bool has_max_variable_activity_value() const; + void clear_max_variable_activity_value(); + static const int kMaxVariableActivityValueFieldNumber = 16; + double max_variable_activity_value() const; + void set_max_variable_activity_value(double value); + + // optional double glucose_max_decay = 22 [default = 0.95]; + bool has_glucose_max_decay() const; + void clear_glucose_max_decay(); + static const int kGlucoseMaxDecayFieldNumber = 22; + double glucose_max_decay() const; + void set_glucose_max_decay(double value); + + // optional double glucose_decay_increment = 23 [default = 0.01]; + bool has_glucose_decay_increment() const; + void clear_glucose_decay_increment(); + static const int kGlucoseDecayIncrementFieldNumber = 23; + double glucose_decay_increment() const; + void set_glucose_decay_increment(double value); + + // optional int32 glucose_decay_increment_period = 24 [default = 5000]; + bool has_glucose_decay_increment_period() const; + void clear_glucose_decay_increment_period(); + static const int kGlucoseDecayIncrementPeriodFieldNumber = 24; + ::google::protobuf::int32 glucose_decay_increment_period() const; + void set_glucose_decay_increment_period(::google::protobuf::int32 value); + + // optional double clause_activity_decay = 17 [default = 0.999]; + bool has_clause_activity_decay() const; + void clear_clause_activity_decay(); + static const int kClauseActivityDecayFieldNumber = 17; + double clause_activity_decay() const; + void set_clause_activity_decay(double value); + + // optional double max_clause_activity_value = 18 [default = 1e+20]; + bool has_max_clause_activity_value() const; + void clear_max_clause_activity_value(); + static const int kMaxClauseActivityValueFieldNumber = 18; + double max_clause_activity_value() const; + void set_max_clause_activity_value(double value); + + // optional bool use_glucose_bump_again_strategy = 21 [default = false]; + bool has_use_glucose_bump_again_strategy() const; + void clear_use_glucose_bump_again_strategy(); + static const int kUseGlucoseBumpAgainStrategyFieldNumber = 21; + bool use_glucose_bump_again_strategy() const; + void set_use_glucose_bump_again_strategy(bool value); + + // repeated .operations_research.sat.SatParameters.RestartAlgorithm restart_algorithms = 61; + int restart_algorithms_size() const; + void clear_restart_algorithms(); + static const int kRestartAlgorithmsFieldNumber = 61; + ::operations_research::sat::SatParameters_RestartAlgorithm restart_algorithms(int index) const; + void set_restart_algorithms(int index, ::operations_research::sat::SatParameters_RestartAlgorithm value); + void add_restart_algorithms(::operations_research::sat::SatParameters_RestartAlgorithm value); + const ::google::protobuf::RepeatedField& restart_algorithms() const; + ::google::protobuf::RepeatedField* mutable_restart_algorithms(); + + // optional string default_restart_algorithms = 70 [default = "LUBY_RESTART,LBD_MOVING_AVERAGE_RESTART,DL_MOVING_AVERAGE_RESTART"]; + bool has_default_restart_algorithms() const; + void clear_default_restart_algorithms(); + static const int kDefaultRestartAlgorithmsFieldNumber = 70; + const ::std::string& default_restart_algorithms() const; + void set_default_restart_algorithms(const ::std::string& value); + void set_default_restart_algorithms(const char* value); + void set_default_restart_algorithms(const char* value, size_t size); + ::std::string* mutable_default_restart_algorithms(); + ::std::string* release_default_restart_algorithms(); + void set_allocated_default_restart_algorithms(::std::string* default_restart_algorithms); + + // optional int32 luby_restart_period = 30 [default = 50]; + bool has_luby_restart_period() const; + void clear_luby_restart_period(); + static const int kLubyRestartPeriodFieldNumber = 30; + ::google::protobuf::int32 luby_restart_period() const; + void set_luby_restart_period(::google::protobuf::int32 value); + + // optional int32 restart_running_window_size = 62 [default = 50]; + bool has_restart_running_window_size() const; + void clear_restart_running_window_size(); + static const int kRestartRunningWindowSizeFieldNumber = 62; + ::google::protobuf::int32 restart_running_window_size() const; + void set_restart_running_window_size(::google::protobuf::int32 value); + + // optional double restart_dl_average_ratio = 63 [default = 1]; + bool has_restart_dl_average_ratio() const; + void clear_restart_dl_average_ratio(); + static const int kRestartDlAverageRatioFieldNumber = 63; + double restart_dl_average_ratio() const; + void set_restart_dl_average_ratio(double value); + + // optional double restart_lbd_average_ratio = 71 [default = 0.8]; + bool has_restart_lbd_average_ratio() const; + void clear_restart_lbd_average_ratio(); + static const int kRestartLbdAverageRatioFieldNumber = 71; + double restart_lbd_average_ratio() const; + void set_restart_lbd_average_ratio(double value); + + // optional bool use_blocking_restart = 64 [default = false]; + bool has_use_blocking_restart() const; + void clear_use_blocking_restart(); + static const int kUseBlockingRestartFieldNumber = 64; + bool use_blocking_restart() const; + void set_use_blocking_restart(bool value); + + // optional int32 blocking_restart_window_size = 65 [default = 5000]; + bool has_blocking_restart_window_size() const; + void clear_blocking_restart_window_size(); + static const int kBlockingRestartWindowSizeFieldNumber = 65; + ::google::protobuf::int32 blocking_restart_window_size() const; + void set_blocking_restart_window_size(::google::protobuf::int32 value); + + // optional double blocking_restart_multiplier = 66 [default = 1.4]; + bool has_blocking_restart_multiplier() const; + void clear_blocking_restart_multiplier(); + static const int kBlockingRestartMultiplierFieldNumber = 66; + double blocking_restart_multiplier() const; + void set_blocking_restart_multiplier(double value); + + // optional int32 num_conflicts_before_strategy_changes = 68 [default = 0]; + bool has_num_conflicts_before_strategy_changes() const; + void clear_num_conflicts_before_strategy_changes(); + static const int kNumConflictsBeforeStrategyChangesFieldNumber = 68; + ::google::protobuf::int32 num_conflicts_before_strategy_changes() const; + void set_num_conflicts_before_strategy_changes(::google::protobuf::int32 value); + + // optional double strategy_change_increase_ratio = 69 [default = 0]; + bool has_strategy_change_increase_ratio() const; + void clear_strategy_change_increase_ratio(); + static const int kStrategyChangeIncreaseRatioFieldNumber = 69; + double strategy_change_increase_ratio() const; + void set_strategy_change_increase_ratio(double value); + + // optional double max_time_in_seconds = 36 [default = inf]; + bool has_max_time_in_seconds() const; + void clear_max_time_in_seconds(); + static const int kMaxTimeInSecondsFieldNumber = 36; + double max_time_in_seconds() const; + void set_max_time_in_seconds(double value); + + // optional double max_deterministic_time = 67 [default = inf]; + bool has_max_deterministic_time() const; + void clear_max_deterministic_time(); + static const int kMaxDeterministicTimeFieldNumber = 67; + double max_deterministic_time() const; + void set_max_deterministic_time(double value); + + // optional int64 max_number_of_conflicts = 37 [default = 9223372036854775807]; + bool has_max_number_of_conflicts() const; + void clear_max_number_of_conflicts(); + static const int kMaxNumberOfConflictsFieldNumber = 37; + ::google::protobuf::int64 max_number_of_conflicts() const; + void set_max_number_of_conflicts(::google::protobuf::int64 value); + + // optional int64 max_memory_in_mb = 40 [default = 10000]; + bool has_max_memory_in_mb() const; + void clear_max_memory_in_mb(); + static const int kMaxMemoryInMbFieldNumber = 40; + ::google::protobuf::int64 max_memory_in_mb() const; + void set_max_memory_in_mb(::google::protobuf::int64 value); + + // optional bool treat_binary_clauses_separately = 33 [default = true]; + bool has_treat_binary_clauses_separately() const; + void clear_treat_binary_clauses_separately(); + static const int kTreatBinaryClausesSeparatelyFieldNumber = 33; + bool treat_binary_clauses_separately() const; + void set_treat_binary_clauses_separately(bool value); + + // optional int32 random_seed = 31 [default = 1]; + bool has_random_seed() const; + void clear_random_seed(); + static const int kRandomSeedFieldNumber = 31; + ::google::protobuf::int32 random_seed() const; + void set_random_seed(::google::protobuf::int32 value); + + // optional bool log_search_progress = 41 [default = false]; + bool has_log_search_progress() const; + void clear_log_search_progress(); + static const int kLogSearchProgressFieldNumber = 41; + bool log_search_progress() const; + void set_log_search_progress(bool value); + + // optional bool use_pb_resolution = 43 [default = false]; + bool has_use_pb_resolution() const; + void clear_use_pb_resolution(); + static const int kUsePbResolutionFieldNumber = 43; + bool use_pb_resolution() const; + void set_use_pb_resolution(bool value); + + // optional bool minimize_reduction_during_pb_resolution = 48 [default = false]; + bool has_minimize_reduction_during_pb_resolution() const; + void clear_minimize_reduction_during_pb_resolution(); + static const int kMinimizeReductionDuringPbResolutionFieldNumber = 48; + bool minimize_reduction_during_pb_resolution() const; + void set_minimize_reduction_during_pb_resolution(bool value); + + // optional bool count_assumption_levels_in_lbd = 49 [default = true]; + bool has_count_assumption_levels_in_lbd() const; + void clear_count_assumption_levels_in_lbd(); + static const int kCountAssumptionLevelsInLbdFieldNumber = 49; + bool count_assumption_levels_in_lbd() const; + void set_count_assumption_levels_in_lbd(bool value); + + // optional int32 presolve_bve_threshold = 54 [default = 500]; + bool has_presolve_bve_threshold() const; + void clear_presolve_bve_threshold(); + static const int kPresolveBveThresholdFieldNumber = 54; + ::google::protobuf::int32 presolve_bve_threshold() const; + void set_presolve_bve_threshold(::google::protobuf::int32 value); + + // optional int32 presolve_bve_clause_weight = 55 [default = 3]; + bool has_presolve_bve_clause_weight() const; + void clear_presolve_bve_clause_weight(); + static const int kPresolveBveClauseWeightFieldNumber = 55; + ::google::protobuf::int32 presolve_bve_clause_weight() const; + void set_presolve_bve_clause_weight(::google::protobuf::int32 value); + + // optional double presolve_probing_deterministic_time_limit = 57 [default = 30]; + bool has_presolve_probing_deterministic_time_limit() const; + void clear_presolve_probing_deterministic_time_limit(); + static const int kPresolveProbingDeterministicTimeLimitFieldNumber = 57; + double presolve_probing_deterministic_time_limit() const; + void set_presolve_probing_deterministic_time_limit(double value); + + // optional bool presolve_use_bva = 72 [default = true]; + bool has_presolve_use_bva() const; + void clear_presolve_use_bva(); + static const int kPresolveUseBvaFieldNumber = 72; + bool presolve_use_bva() const; + void set_presolve_use_bva(bool value); + + // optional int32 presolve_bva_threshold = 73 [default = 1]; + bool has_presolve_bva_threshold() const; + void clear_presolve_bva_threshold(); + static const int kPresolveBvaThresholdFieldNumber = 73; + ::google::protobuf::int32 presolve_bva_threshold() const; + void set_presolve_bva_threshold(::google::protobuf::int32 value); + + // optional bool use_optimization_hints = 35 [default = true]; + bool has_use_optimization_hints() const; + void clear_use_optimization_hints(); + static const int kUseOptimizationHintsFieldNumber = 35; + bool use_optimization_hints() const; + void set_use_optimization_hints(bool value); + + // optional bool minimize_core = 50 [default = true]; + bool has_minimize_core() const; + void clear_minimize_core(); + static const int kMinimizeCoreFieldNumber = 50; + bool minimize_core() const; + void set_minimize_core(bool value); + + // optional .operations_research.sat.SatParameters.MaxSatAssumptionOrder max_sat_assumption_order = 51 [default = DEFAULT_ASSUMPTION_ORDER]; + bool has_max_sat_assumption_order() const; + void clear_max_sat_assumption_order(); + static const int kMaxSatAssumptionOrderFieldNumber = 51; + ::operations_research::sat::SatParameters_MaxSatAssumptionOrder max_sat_assumption_order() const; + void set_max_sat_assumption_order(::operations_research::sat::SatParameters_MaxSatAssumptionOrder value); + + // optional bool max_sat_reverse_assumption_order = 52 [default = false]; + bool has_max_sat_reverse_assumption_order() const; + void clear_max_sat_reverse_assumption_order(); + static const int kMaxSatReverseAssumptionOrderFieldNumber = 52; + bool max_sat_reverse_assumption_order() const; + void set_max_sat_reverse_assumption_order(bool value); + + // optional .operations_research.sat.SatParameters.MaxSatStratificationAlgorithm max_sat_stratification = 53 [default = STRATIFICATION_DESCENT]; + bool has_max_sat_stratification() const; + void clear_max_sat_stratification(); + static const int kMaxSatStratificationFieldNumber = 53; + ::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm max_sat_stratification() const; + void set_max_sat_stratification(::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm value); + + // optional bool use_precedences_in_disjunctive_constraint = 74 [default = true]; + bool has_use_precedences_in_disjunctive_constraint() const; + void clear_use_precedences_in_disjunctive_constraint(); + static const int kUsePrecedencesInDisjunctiveConstraintFieldNumber = 74; + bool use_precedences_in_disjunctive_constraint() const; + void set_use_precedences_in_disjunctive_constraint(bool value); + + // optional bool use_overload_checker_in_cumulative_constraint = 78 [default = false]; + bool has_use_overload_checker_in_cumulative_constraint() const; + void clear_use_overload_checker_in_cumulative_constraint(); + static const int kUseOverloadCheckerInCumulativeConstraintFieldNumber = 78; + bool use_overload_checker_in_cumulative_constraint() const; + void set_use_overload_checker_in_cumulative_constraint(bool value); + + // optional bool use_timetable_edge_finding_in_cumulative_constraint = 79 [default = false]; + bool has_use_timetable_edge_finding_in_cumulative_constraint() const; + void clear_use_timetable_edge_finding_in_cumulative_constraint(); + static const int kUseTimetableEdgeFindingInCumulativeConstraintFieldNumber = 79; + bool use_timetable_edge_finding_in_cumulative_constraint() const; + void set_use_timetable_edge_finding_in_cumulative_constraint(bool value); + + // optional bool use_disjunctive_constraint_in_cumulative_constraint = 80 [default = false]; + bool has_use_disjunctive_constraint_in_cumulative_constraint() const; + void clear_use_disjunctive_constraint_in_cumulative_constraint(); + static const int kUseDisjunctiveConstraintInCumulativeConstraintFieldNumber = 80; + bool use_disjunctive_constraint_in_cumulative_constraint() const; + void set_use_disjunctive_constraint_in_cumulative_constraint(bool value); + + // optional bool use_global_lp_constraint = 81 [default = true]; + bool has_use_global_lp_constraint() const; + void clear_use_global_lp_constraint(); + static const int kUseGlobalLpConstraintFieldNumber = 81; + bool use_global_lp_constraint() const; + void set_use_global_lp_constraint(bool value); + + // optional bool use_fixed_search = 82 [default = false]; + bool has_use_fixed_search() const; + void clear_use_fixed_search(); + static const int kUseFixedSearchFieldNumber = 82; + bool use_fixed_search() const; + void set_use_fixed_search(bool value); + + // optional bool optimize_with_core = 83 [default = false]; + bool has_optimize_with_core() const; + void clear_optimize_with_core(); + static const int kOptimizeWithCoreFieldNumber = 83; + bool optimize_with_core() const; + void set_optimize_with_core(bool value); + + // @@protoc_insertion_point(class_scope:operations_research.sat.SatParameters) + private: + inline void set_has_preferred_variable_order(); + inline void clear_has_preferred_variable_order(); + inline void set_has_initial_polarity(); + inline void clear_has_initial_polarity(); + inline void set_has_use_phase_saving(); + inline void clear_has_use_phase_saving(); + inline void set_has_random_polarity_ratio(); + inline void clear_has_random_polarity_ratio(); + inline void set_has_random_branches_ratio(); + inline void clear_has_random_branches_ratio(); + inline void set_has_literal_ordering(); + inline void clear_has_literal_ordering(); + inline void set_has_use_erwa_heuristic(); + inline void clear_has_use_erwa_heuristic(); + inline void set_has_initial_variables_activity(); + inline void clear_has_initial_variables_activity(); + inline void set_has_also_bump_variables_in_conflict_reasons(); + inline void clear_has_also_bump_variables_in_conflict_reasons(); + inline void set_has_minimization_algorithm(); + inline void clear_has_minimization_algorithm(); + inline void set_has_binary_minimization_algorithm(); + inline void clear_has_binary_minimization_algorithm(); + inline void set_has_subsumption_during_conflict_analysis(); + inline void clear_has_subsumption_during_conflict_analysis(); + inline void set_has_clause_cleanup_period(); + inline void clear_has_clause_cleanup_period(); + inline void set_has_clause_cleanup_target(); + inline void clear_has_clause_cleanup_target(); + inline void set_has_clause_cleanup_protection(); + inline void clear_has_clause_cleanup_protection(); + inline void set_has_clause_cleanup_lbd_bound(); + inline void clear_has_clause_cleanup_lbd_bound(); + inline void set_has_clause_cleanup_ordering(); + inline void clear_has_clause_cleanup_ordering(); + inline void set_has_pb_cleanup_increment(); + inline void clear_has_pb_cleanup_increment(); + inline void set_has_pb_cleanup_ratio(); + inline void clear_has_pb_cleanup_ratio(); + inline void set_has_variable_activity_decay(); + inline void clear_has_variable_activity_decay(); + inline void set_has_max_variable_activity_value(); + inline void clear_has_max_variable_activity_value(); + inline void set_has_glucose_max_decay(); + inline void clear_has_glucose_max_decay(); + inline void set_has_glucose_decay_increment(); + inline void clear_has_glucose_decay_increment(); + inline void set_has_glucose_decay_increment_period(); + inline void clear_has_glucose_decay_increment_period(); + inline void set_has_clause_activity_decay(); + inline void clear_has_clause_activity_decay(); + inline void set_has_max_clause_activity_value(); + inline void clear_has_max_clause_activity_value(); + inline void set_has_use_glucose_bump_again_strategy(); + inline void clear_has_use_glucose_bump_again_strategy(); + inline void set_has_default_restart_algorithms(); + inline void clear_has_default_restart_algorithms(); + inline void set_has_luby_restart_period(); + inline void clear_has_luby_restart_period(); + inline void set_has_restart_running_window_size(); + inline void clear_has_restart_running_window_size(); + inline void set_has_restart_dl_average_ratio(); + inline void clear_has_restart_dl_average_ratio(); + inline void set_has_restart_lbd_average_ratio(); + inline void clear_has_restart_lbd_average_ratio(); + inline void set_has_use_blocking_restart(); + inline void clear_has_use_blocking_restart(); + inline void set_has_blocking_restart_window_size(); + inline void clear_has_blocking_restart_window_size(); + inline void set_has_blocking_restart_multiplier(); + inline void clear_has_blocking_restart_multiplier(); + inline void set_has_num_conflicts_before_strategy_changes(); + inline void clear_has_num_conflicts_before_strategy_changes(); + inline void set_has_strategy_change_increase_ratio(); + inline void clear_has_strategy_change_increase_ratio(); + inline void set_has_max_time_in_seconds(); + inline void clear_has_max_time_in_seconds(); + inline void set_has_max_deterministic_time(); + inline void clear_has_max_deterministic_time(); + inline void set_has_max_number_of_conflicts(); + inline void clear_has_max_number_of_conflicts(); + inline void set_has_max_memory_in_mb(); + inline void clear_has_max_memory_in_mb(); + inline void set_has_treat_binary_clauses_separately(); + inline void clear_has_treat_binary_clauses_separately(); + inline void set_has_random_seed(); + inline void clear_has_random_seed(); + inline void set_has_log_search_progress(); + inline void clear_has_log_search_progress(); + inline void set_has_use_pb_resolution(); + inline void clear_has_use_pb_resolution(); + inline void set_has_minimize_reduction_during_pb_resolution(); + inline void clear_has_minimize_reduction_during_pb_resolution(); + inline void set_has_count_assumption_levels_in_lbd(); + inline void clear_has_count_assumption_levels_in_lbd(); + inline void set_has_presolve_bve_threshold(); + inline void clear_has_presolve_bve_threshold(); + inline void set_has_presolve_bve_clause_weight(); + inline void clear_has_presolve_bve_clause_weight(); + inline void set_has_presolve_probing_deterministic_time_limit(); + inline void clear_has_presolve_probing_deterministic_time_limit(); + inline void set_has_presolve_use_bva(); + inline void clear_has_presolve_use_bva(); + inline void set_has_presolve_bva_threshold(); + inline void clear_has_presolve_bva_threshold(); + inline void set_has_use_optimization_hints(); + inline void clear_has_use_optimization_hints(); + inline void set_has_minimize_core(); + inline void clear_has_minimize_core(); + inline void set_has_max_sat_assumption_order(); + inline void clear_has_max_sat_assumption_order(); + inline void set_has_max_sat_reverse_assumption_order(); + inline void clear_has_max_sat_reverse_assumption_order(); + inline void set_has_max_sat_stratification(); + inline void clear_has_max_sat_stratification(); + inline void set_has_use_precedences_in_disjunctive_constraint(); + inline void clear_has_use_precedences_in_disjunctive_constraint(); + inline void set_has_use_overload_checker_in_cumulative_constraint(); + inline void clear_has_use_overload_checker_in_cumulative_constraint(); + inline void set_has_use_timetable_edge_finding_in_cumulative_constraint(); + inline void clear_has_use_timetable_edge_finding_in_cumulative_constraint(); + inline void set_has_use_disjunctive_constraint_in_cumulative_constraint(); + inline void clear_has_use_disjunctive_constraint_in_cumulative_constraint(); + inline void set_has_use_global_lp_constraint(); + inline void clear_has_use_global_lp_constraint(); + inline void set_has_use_fixed_search(); + inline void clear_has_use_fixed_search(); + inline void set_has_optimize_with_core(); + inline void clear_has_optimize_with_core(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[3]; + mutable int _cached_size_; + int preferred_variable_order_; + int initial_polarity_; + double random_polarity_ratio_; + double random_branches_ratio_; + int literal_ordering_; + bool use_phase_saving_; + bool use_erwa_heuristic_; + bool also_bump_variables_in_conflict_reasons_; + bool subsumption_during_conflict_analysis_; + double initial_variables_activity_; + int minimization_algorithm_; + int binary_minimization_algorithm_; + ::google::protobuf::int32 clause_cleanup_period_; + ::google::protobuf::int32 clause_cleanup_target_; + int clause_cleanup_protection_; + ::google::protobuf::int32 clause_cleanup_lbd_bound_; + int clause_cleanup_ordering_; + ::google::protobuf::int32 pb_cleanup_increment_; + double pb_cleanup_ratio_; + double variable_activity_decay_; + double max_variable_activity_value_; + double glucose_max_decay_; + double glucose_decay_increment_; + double clause_activity_decay_; + double max_clause_activity_value_; + ::google::protobuf::int32 glucose_decay_increment_period_; + ::google::protobuf::int32 luby_restart_period_; + ::google::protobuf::RepeatedField restart_algorithms_; + static ::std::string* _default_default_restart_algorithms_; + ::google::protobuf::internal::ArenaStringPtr default_restart_algorithms_; + double restart_dl_average_ratio_; + double restart_lbd_average_ratio_; + ::google::protobuf::int32 restart_running_window_size_; + ::google::protobuf::int32 blocking_restart_window_size_; + double blocking_restart_multiplier_; + ::google::protobuf::int32 num_conflicts_before_strategy_changes_; + bool use_glucose_bump_again_strategy_; + bool use_blocking_restart_; + bool treat_binary_clauses_separately_; + bool log_search_progress_; + double strategy_change_increase_ratio_; + double max_time_in_seconds_; + double max_deterministic_time_; + ::google::protobuf::int64 max_number_of_conflicts_; + ::google::protobuf::int64 max_memory_in_mb_; + ::google::protobuf::int32 random_seed_; + bool use_pb_resolution_; + bool minimize_reduction_during_pb_resolution_; + bool count_assumption_levels_in_lbd_; + bool presolve_use_bva_; + ::google::protobuf::int32 presolve_bve_threshold_; + ::google::protobuf::int32 presolve_bve_clause_weight_; + double presolve_probing_deterministic_time_limit_; + ::google::protobuf::int32 presolve_bva_threshold_; + int max_sat_assumption_order_; + bool use_optimization_hints_; + bool minimize_core_; + bool max_sat_reverse_assumption_order_; + bool use_precedences_in_disjunctive_constraint_; + int max_sat_stratification_; + bool use_overload_checker_in_cumulative_constraint_; + bool use_timetable_edge_finding_in_cumulative_constraint_; + bool use_disjunctive_constraint_in_cumulative_constraint_; + bool use_global_lp_constraint_; + bool use_fixed_search_; + bool optimize_with_core_; + friend void protobuf_AddDesc_ortools_2fsat_2fsat_5fparameters_2eproto(); + friend void protobuf_AssignDesc_ortools_2fsat_2fsat_5fparameters_2eproto(); + friend void protobuf_ShutdownFile_ortools_2fsat_2fsat_5fparameters_2eproto(); + + void InitAsDefaultInstance(); + static SatParameters* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// SatParameters + +// optional .operations_research.sat.SatParameters.VariableOrder preferred_variable_order = 1 [default = IN_ORDER]; +inline bool SatParameters::has_preferred_variable_order() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void SatParameters::set_has_preferred_variable_order() { + _has_bits_[0] |= 0x00000001u; +} +inline void SatParameters::clear_has_preferred_variable_order() { + _has_bits_[0] &= ~0x00000001u; +} +inline void SatParameters::clear_preferred_variable_order() { + preferred_variable_order_ = 0; + clear_has_preferred_variable_order(); +} +inline ::operations_research::sat::SatParameters_VariableOrder SatParameters::preferred_variable_order() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.preferred_variable_order) + return static_cast< ::operations_research::sat::SatParameters_VariableOrder >(preferred_variable_order_); +} +inline void SatParameters::set_preferred_variable_order(::operations_research::sat::SatParameters_VariableOrder value) { + assert(::operations_research::sat::SatParameters_VariableOrder_IsValid(value)); + set_has_preferred_variable_order(); + preferred_variable_order_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.preferred_variable_order) +} + +// optional .operations_research.sat.SatParameters.Polarity initial_polarity = 2 [default = POLARITY_FALSE]; +inline bool SatParameters::has_initial_polarity() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void SatParameters::set_has_initial_polarity() { + _has_bits_[0] |= 0x00000002u; +} +inline void SatParameters::clear_has_initial_polarity() { + _has_bits_[0] &= ~0x00000002u; +} +inline void SatParameters::clear_initial_polarity() { + initial_polarity_ = 1; + clear_has_initial_polarity(); +} +inline ::operations_research::sat::SatParameters_Polarity SatParameters::initial_polarity() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.initial_polarity) + return static_cast< ::operations_research::sat::SatParameters_Polarity >(initial_polarity_); +} +inline void SatParameters::set_initial_polarity(::operations_research::sat::SatParameters_Polarity value) { + assert(::operations_research::sat::SatParameters_Polarity_IsValid(value)); + set_has_initial_polarity(); + initial_polarity_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.initial_polarity) +} + +// optional bool use_phase_saving = 44 [default = true]; +inline bool SatParameters::has_use_phase_saving() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void SatParameters::set_has_use_phase_saving() { + _has_bits_[0] |= 0x00000004u; +} +inline void SatParameters::clear_has_use_phase_saving() { + _has_bits_[0] &= ~0x00000004u; +} +inline void SatParameters::clear_use_phase_saving() { + use_phase_saving_ = true; + clear_has_use_phase_saving(); +} +inline bool SatParameters::use_phase_saving() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_phase_saving) + return use_phase_saving_; +} +inline void SatParameters::set_use_phase_saving(bool value) { + set_has_use_phase_saving(); + use_phase_saving_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_phase_saving) +} + +// optional double random_polarity_ratio = 45 [default = 0]; +inline bool SatParameters::has_random_polarity_ratio() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void SatParameters::set_has_random_polarity_ratio() { + _has_bits_[0] |= 0x00000008u; +} +inline void SatParameters::clear_has_random_polarity_ratio() { + _has_bits_[0] &= ~0x00000008u; +} +inline void SatParameters::clear_random_polarity_ratio() { + random_polarity_ratio_ = 0; + clear_has_random_polarity_ratio(); +} +inline double SatParameters::random_polarity_ratio() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.random_polarity_ratio) + return random_polarity_ratio_; +} +inline void SatParameters::set_random_polarity_ratio(double value) { + set_has_random_polarity_ratio(); + random_polarity_ratio_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.random_polarity_ratio) +} + +// optional double random_branches_ratio = 32 [default = 0]; +inline bool SatParameters::has_random_branches_ratio() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void SatParameters::set_has_random_branches_ratio() { + _has_bits_[0] |= 0x00000010u; +} +inline void SatParameters::clear_has_random_branches_ratio() { + _has_bits_[0] &= ~0x00000010u; +} +inline void SatParameters::clear_random_branches_ratio() { + random_branches_ratio_ = 0; + clear_has_random_branches_ratio(); +} +inline double SatParameters::random_branches_ratio() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.random_branches_ratio) + return random_branches_ratio_; +} +inline void SatParameters::set_random_branches_ratio(double value) { + set_has_random_branches_ratio(); + random_branches_ratio_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.random_branches_ratio) +} + +// optional .operations_research.sat.SatParameters.LiteralOrdering literal_ordering = 3 [default = LITERAL_IN_ORDER]; +inline bool SatParameters::has_literal_ordering() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void SatParameters::set_has_literal_ordering() { + _has_bits_[0] |= 0x00000020u; +} +inline void SatParameters::clear_has_literal_ordering() { + _has_bits_[0] &= ~0x00000020u; +} +inline void SatParameters::clear_literal_ordering() { + literal_ordering_ = 0; + clear_has_literal_ordering(); +} +inline ::operations_research::sat::SatParameters_LiteralOrdering SatParameters::literal_ordering() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.literal_ordering) + return static_cast< ::operations_research::sat::SatParameters_LiteralOrdering >(literal_ordering_); +} +inline void SatParameters::set_literal_ordering(::operations_research::sat::SatParameters_LiteralOrdering value) { + assert(::operations_research::sat::SatParameters_LiteralOrdering_IsValid(value)); + set_has_literal_ordering(); + literal_ordering_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.literal_ordering) +} + +// optional bool use_erwa_heuristic = 75 [default = false]; +inline bool SatParameters::has_use_erwa_heuristic() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void SatParameters::set_has_use_erwa_heuristic() { + _has_bits_[0] |= 0x00000040u; +} +inline void SatParameters::clear_has_use_erwa_heuristic() { + _has_bits_[0] &= ~0x00000040u; +} +inline void SatParameters::clear_use_erwa_heuristic() { + use_erwa_heuristic_ = false; + clear_has_use_erwa_heuristic(); +} +inline bool SatParameters::use_erwa_heuristic() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_erwa_heuristic) + return use_erwa_heuristic_; +} +inline void SatParameters::set_use_erwa_heuristic(bool value) { + set_has_use_erwa_heuristic(); + use_erwa_heuristic_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_erwa_heuristic) +} + +// optional double initial_variables_activity = 76 [default = 0]; +inline bool SatParameters::has_initial_variables_activity() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void SatParameters::set_has_initial_variables_activity() { + _has_bits_[0] |= 0x00000080u; +} +inline void SatParameters::clear_has_initial_variables_activity() { + _has_bits_[0] &= ~0x00000080u; +} +inline void SatParameters::clear_initial_variables_activity() { + initial_variables_activity_ = 0; + clear_has_initial_variables_activity(); +} +inline double SatParameters::initial_variables_activity() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.initial_variables_activity) + return initial_variables_activity_; +} +inline void SatParameters::set_initial_variables_activity(double value) { + set_has_initial_variables_activity(); + initial_variables_activity_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.initial_variables_activity) +} + +// optional bool also_bump_variables_in_conflict_reasons = 77 [default = false]; +inline bool SatParameters::has_also_bump_variables_in_conflict_reasons() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void SatParameters::set_has_also_bump_variables_in_conflict_reasons() { + _has_bits_[0] |= 0x00000100u; +} +inline void SatParameters::clear_has_also_bump_variables_in_conflict_reasons() { + _has_bits_[0] &= ~0x00000100u; +} +inline void SatParameters::clear_also_bump_variables_in_conflict_reasons() { + also_bump_variables_in_conflict_reasons_ = false; + clear_has_also_bump_variables_in_conflict_reasons(); +} +inline bool SatParameters::also_bump_variables_in_conflict_reasons() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.also_bump_variables_in_conflict_reasons) + return also_bump_variables_in_conflict_reasons_; +} +inline void SatParameters::set_also_bump_variables_in_conflict_reasons(bool value) { + set_has_also_bump_variables_in_conflict_reasons(); + also_bump_variables_in_conflict_reasons_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.also_bump_variables_in_conflict_reasons) +} + +// optional .operations_research.sat.SatParameters.ConflictMinimizationAlgorithm minimization_algorithm = 4 [default = RECURSIVE]; +inline bool SatParameters::has_minimization_algorithm() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void SatParameters::set_has_minimization_algorithm() { + _has_bits_[0] |= 0x00000200u; +} +inline void SatParameters::clear_has_minimization_algorithm() { + _has_bits_[0] &= ~0x00000200u; +} +inline void SatParameters::clear_minimization_algorithm() { + minimization_algorithm_ = 2; + clear_has_minimization_algorithm(); +} +inline ::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm SatParameters::minimization_algorithm() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.minimization_algorithm) + return static_cast< ::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm >(minimization_algorithm_); +} +inline void SatParameters::set_minimization_algorithm(::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm value) { + assert(::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm_IsValid(value)); + set_has_minimization_algorithm(); + minimization_algorithm_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.minimization_algorithm) +} + +// optional .operations_research.sat.SatParameters.BinaryMinizationAlgorithm binary_minimization_algorithm = 34 [default = BINARY_MINIMIZATION_FIRST]; +inline bool SatParameters::has_binary_minimization_algorithm() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void SatParameters::set_has_binary_minimization_algorithm() { + _has_bits_[0] |= 0x00000400u; +} +inline void SatParameters::clear_has_binary_minimization_algorithm() { + _has_bits_[0] &= ~0x00000400u; +} +inline void SatParameters::clear_binary_minimization_algorithm() { + binary_minimization_algorithm_ = 1; + clear_has_binary_minimization_algorithm(); +} +inline ::operations_research::sat::SatParameters_BinaryMinizationAlgorithm SatParameters::binary_minimization_algorithm() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.binary_minimization_algorithm) + return static_cast< ::operations_research::sat::SatParameters_BinaryMinizationAlgorithm >(binary_minimization_algorithm_); +} +inline void SatParameters::set_binary_minimization_algorithm(::operations_research::sat::SatParameters_BinaryMinizationAlgorithm value) { + assert(::operations_research::sat::SatParameters_BinaryMinizationAlgorithm_IsValid(value)); + set_has_binary_minimization_algorithm(); + binary_minimization_algorithm_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.binary_minimization_algorithm) +} + +// optional bool subsumption_during_conflict_analysis = 56 [default = true]; +inline bool SatParameters::has_subsumption_during_conflict_analysis() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void SatParameters::set_has_subsumption_during_conflict_analysis() { + _has_bits_[0] |= 0x00000800u; +} +inline void SatParameters::clear_has_subsumption_during_conflict_analysis() { + _has_bits_[0] &= ~0x00000800u; +} +inline void SatParameters::clear_subsumption_during_conflict_analysis() { + subsumption_during_conflict_analysis_ = true; + clear_has_subsumption_during_conflict_analysis(); +} +inline bool SatParameters::subsumption_during_conflict_analysis() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.subsumption_during_conflict_analysis) + return subsumption_during_conflict_analysis_; +} +inline void SatParameters::set_subsumption_during_conflict_analysis(bool value) { + set_has_subsumption_during_conflict_analysis(); + subsumption_during_conflict_analysis_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.subsumption_during_conflict_analysis) +} + +// optional int32 clause_cleanup_period = 11 [default = 10000]; +inline bool SatParameters::has_clause_cleanup_period() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void SatParameters::set_has_clause_cleanup_period() { + _has_bits_[0] |= 0x00001000u; +} +inline void SatParameters::clear_has_clause_cleanup_period() { + _has_bits_[0] &= ~0x00001000u; +} +inline void SatParameters::clear_clause_cleanup_period() { + clause_cleanup_period_ = 10000; + clear_has_clause_cleanup_period(); +} +inline ::google::protobuf::int32 SatParameters::clause_cleanup_period() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.clause_cleanup_period) + return clause_cleanup_period_; +} +inline void SatParameters::set_clause_cleanup_period(::google::protobuf::int32 value) { + set_has_clause_cleanup_period(); + clause_cleanup_period_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.clause_cleanup_period) +} + +// optional int32 clause_cleanup_target = 13 [default = 10000]; +inline bool SatParameters::has_clause_cleanup_target() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void SatParameters::set_has_clause_cleanup_target() { + _has_bits_[0] |= 0x00002000u; +} +inline void SatParameters::clear_has_clause_cleanup_target() { + _has_bits_[0] &= ~0x00002000u; +} +inline void SatParameters::clear_clause_cleanup_target() { + clause_cleanup_target_ = 10000; + clear_has_clause_cleanup_target(); +} +inline ::google::protobuf::int32 SatParameters::clause_cleanup_target() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.clause_cleanup_target) + return clause_cleanup_target_; +} +inline void SatParameters::set_clause_cleanup_target(::google::protobuf::int32 value) { + set_has_clause_cleanup_target(); + clause_cleanup_target_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.clause_cleanup_target) +} + +// optional .operations_research.sat.SatParameters.ClauseProtection clause_cleanup_protection = 58 [default = PROTECTION_NONE]; +inline bool SatParameters::has_clause_cleanup_protection() const { + return (_has_bits_[0] & 0x00004000u) != 0; +} +inline void SatParameters::set_has_clause_cleanup_protection() { + _has_bits_[0] |= 0x00004000u; +} +inline void SatParameters::clear_has_clause_cleanup_protection() { + _has_bits_[0] &= ~0x00004000u; +} +inline void SatParameters::clear_clause_cleanup_protection() { + clause_cleanup_protection_ = 0; + clear_has_clause_cleanup_protection(); +} +inline ::operations_research::sat::SatParameters_ClauseProtection SatParameters::clause_cleanup_protection() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.clause_cleanup_protection) + return static_cast< ::operations_research::sat::SatParameters_ClauseProtection >(clause_cleanup_protection_); +} +inline void SatParameters::set_clause_cleanup_protection(::operations_research::sat::SatParameters_ClauseProtection value) { + assert(::operations_research::sat::SatParameters_ClauseProtection_IsValid(value)); + set_has_clause_cleanup_protection(); + clause_cleanup_protection_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.clause_cleanup_protection) +} + +// optional int32 clause_cleanup_lbd_bound = 59 [default = 5]; +inline bool SatParameters::has_clause_cleanup_lbd_bound() const { + return (_has_bits_[0] & 0x00008000u) != 0; +} +inline void SatParameters::set_has_clause_cleanup_lbd_bound() { + _has_bits_[0] |= 0x00008000u; +} +inline void SatParameters::clear_has_clause_cleanup_lbd_bound() { + _has_bits_[0] &= ~0x00008000u; +} +inline void SatParameters::clear_clause_cleanup_lbd_bound() { + clause_cleanup_lbd_bound_ = 5; + clear_has_clause_cleanup_lbd_bound(); +} +inline ::google::protobuf::int32 SatParameters::clause_cleanup_lbd_bound() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.clause_cleanup_lbd_bound) + return clause_cleanup_lbd_bound_; +} +inline void SatParameters::set_clause_cleanup_lbd_bound(::google::protobuf::int32 value) { + set_has_clause_cleanup_lbd_bound(); + clause_cleanup_lbd_bound_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.clause_cleanup_lbd_bound) +} + +// optional .operations_research.sat.SatParameters.ClauseOrdering clause_cleanup_ordering = 60 [default = CLAUSE_ACTIVITY]; +inline bool SatParameters::has_clause_cleanup_ordering() const { + return (_has_bits_[0] & 0x00010000u) != 0; +} +inline void SatParameters::set_has_clause_cleanup_ordering() { + _has_bits_[0] |= 0x00010000u; +} +inline void SatParameters::clear_has_clause_cleanup_ordering() { + _has_bits_[0] &= ~0x00010000u; +} +inline void SatParameters::clear_clause_cleanup_ordering() { + clause_cleanup_ordering_ = 0; + clear_has_clause_cleanup_ordering(); +} +inline ::operations_research::sat::SatParameters_ClauseOrdering SatParameters::clause_cleanup_ordering() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.clause_cleanup_ordering) + return static_cast< ::operations_research::sat::SatParameters_ClauseOrdering >(clause_cleanup_ordering_); +} +inline void SatParameters::set_clause_cleanup_ordering(::operations_research::sat::SatParameters_ClauseOrdering value) { + assert(::operations_research::sat::SatParameters_ClauseOrdering_IsValid(value)); + set_has_clause_cleanup_ordering(); + clause_cleanup_ordering_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.clause_cleanup_ordering) +} + +// optional int32 pb_cleanup_increment = 46 [default = 200]; +inline bool SatParameters::has_pb_cleanup_increment() const { + return (_has_bits_[0] & 0x00020000u) != 0; +} +inline void SatParameters::set_has_pb_cleanup_increment() { + _has_bits_[0] |= 0x00020000u; +} +inline void SatParameters::clear_has_pb_cleanup_increment() { + _has_bits_[0] &= ~0x00020000u; +} +inline void SatParameters::clear_pb_cleanup_increment() { + pb_cleanup_increment_ = 200; + clear_has_pb_cleanup_increment(); +} +inline ::google::protobuf::int32 SatParameters::pb_cleanup_increment() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.pb_cleanup_increment) + return pb_cleanup_increment_; +} +inline void SatParameters::set_pb_cleanup_increment(::google::protobuf::int32 value) { + set_has_pb_cleanup_increment(); + pb_cleanup_increment_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.pb_cleanup_increment) +} + +// optional double pb_cleanup_ratio = 47 [default = 0.5]; +inline bool SatParameters::has_pb_cleanup_ratio() const { + return (_has_bits_[0] & 0x00040000u) != 0; +} +inline void SatParameters::set_has_pb_cleanup_ratio() { + _has_bits_[0] |= 0x00040000u; +} +inline void SatParameters::clear_has_pb_cleanup_ratio() { + _has_bits_[0] &= ~0x00040000u; +} +inline void SatParameters::clear_pb_cleanup_ratio() { + pb_cleanup_ratio_ = 0.5; + clear_has_pb_cleanup_ratio(); +} +inline double SatParameters::pb_cleanup_ratio() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.pb_cleanup_ratio) + return pb_cleanup_ratio_; +} +inline void SatParameters::set_pb_cleanup_ratio(double value) { + set_has_pb_cleanup_ratio(); + pb_cleanup_ratio_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.pb_cleanup_ratio) +} + +// optional double variable_activity_decay = 15 [default = 0.8]; +inline bool SatParameters::has_variable_activity_decay() const { + return (_has_bits_[0] & 0x00080000u) != 0; +} +inline void SatParameters::set_has_variable_activity_decay() { + _has_bits_[0] |= 0x00080000u; +} +inline void SatParameters::clear_has_variable_activity_decay() { + _has_bits_[0] &= ~0x00080000u; +} +inline void SatParameters::clear_variable_activity_decay() { + variable_activity_decay_ = 0.8; + clear_has_variable_activity_decay(); +} +inline double SatParameters::variable_activity_decay() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.variable_activity_decay) + return variable_activity_decay_; +} +inline void SatParameters::set_variable_activity_decay(double value) { + set_has_variable_activity_decay(); + variable_activity_decay_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.variable_activity_decay) +} + +// optional double max_variable_activity_value = 16 [default = 1e+100]; +inline bool SatParameters::has_max_variable_activity_value() const { + return (_has_bits_[0] & 0x00100000u) != 0; +} +inline void SatParameters::set_has_max_variable_activity_value() { + _has_bits_[0] |= 0x00100000u; +} +inline void SatParameters::clear_has_max_variable_activity_value() { + _has_bits_[0] &= ~0x00100000u; +} +inline void SatParameters::clear_max_variable_activity_value() { + max_variable_activity_value_ = 1e+100; + clear_has_max_variable_activity_value(); +} +inline double SatParameters::max_variable_activity_value() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_variable_activity_value) + return max_variable_activity_value_; +} +inline void SatParameters::set_max_variable_activity_value(double value) { + set_has_max_variable_activity_value(); + max_variable_activity_value_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_variable_activity_value) +} + +// optional double glucose_max_decay = 22 [default = 0.95]; +inline bool SatParameters::has_glucose_max_decay() const { + return (_has_bits_[0] & 0x00200000u) != 0; +} +inline void SatParameters::set_has_glucose_max_decay() { + _has_bits_[0] |= 0x00200000u; +} +inline void SatParameters::clear_has_glucose_max_decay() { + _has_bits_[0] &= ~0x00200000u; +} +inline void SatParameters::clear_glucose_max_decay() { + glucose_max_decay_ = 0.95; + clear_has_glucose_max_decay(); +} +inline double SatParameters::glucose_max_decay() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.glucose_max_decay) + return glucose_max_decay_; +} +inline void SatParameters::set_glucose_max_decay(double value) { + set_has_glucose_max_decay(); + glucose_max_decay_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.glucose_max_decay) +} + +// optional double glucose_decay_increment = 23 [default = 0.01]; +inline bool SatParameters::has_glucose_decay_increment() const { + return (_has_bits_[0] & 0x00400000u) != 0; +} +inline void SatParameters::set_has_glucose_decay_increment() { + _has_bits_[0] |= 0x00400000u; +} +inline void SatParameters::clear_has_glucose_decay_increment() { + _has_bits_[0] &= ~0x00400000u; +} +inline void SatParameters::clear_glucose_decay_increment() { + glucose_decay_increment_ = 0.01; + clear_has_glucose_decay_increment(); +} +inline double SatParameters::glucose_decay_increment() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.glucose_decay_increment) + return glucose_decay_increment_; +} +inline void SatParameters::set_glucose_decay_increment(double value) { + set_has_glucose_decay_increment(); + glucose_decay_increment_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.glucose_decay_increment) +} + +// optional int32 glucose_decay_increment_period = 24 [default = 5000]; +inline bool SatParameters::has_glucose_decay_increment_period() const { + return (_has_bits_[0] & 0x00800000u) != 0; +} +inline void SatParameters::set_has_glucose_decay_increment_period() { + _has_bits_[0] |= 0x00800000u; +} +inline void SatParameters::clear_has_glucose_decay_increment_period() { + _has_bits_[0] &= ~0x00800000u; +} +inline void SatParameters::clear_glucose_decay_increment_period() { + glucose_decay_increment_period_ = 5000; + clear_has_glucose_decay_increment_period(); +} +inline ::google::protobuf::int32 SatParameters::glucose_decay_increment_period() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.glucose_decay_increment_period) + return glucose_decay_increment_period_; +} +inline void SatParameters::set_glucose_decay_increment_period(::google::protobuf::int32 value) { + set_has_glucose_decay_increment_period(); + glucose_decay_increment_period_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.glucose_decay_increment_period) +} + +// optional double clause_activity_decay = 17 [default = 0.999]; +inline bool SatParameters::has_clause_activity_decay() const { + return (_has_bits_[0] & 0x01000000u) != 0; +} +inline void SatParameters::set_has_clause_activity_decay() { + _has_bits_[0] |= 0x01000000u; +} +inline void SatParameters::clear_has_clause_activity_decay() { + _has_bits_[0] &= ~0x01000000u; +} +inline void SatParameters::clear_clause_activity_decay() { + clause_activity_decay_ = 0.999; + clear_has_clause_activity_decay(); +} +inline double SatParameters::clause_activity_decay() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.clause_activity_decay) + return clause_activity_decay_; +} +inline void SatParameters::set_clause_activity_decay(double value) { + set_has_clause_activity_decay(); + clause_activity_decay_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.clause_activity_decay) +} + +// optional double max_clause_activity_value = 18 [default = 1e+20]; +inline bool SatParameters::has_max_clause_activity_value() const { + return (_has_bits_[0] & 0x02000000u) != 0; +} +inline void SatParameters::set_has_max_clause_activity_value() { + _has_bits_[0] |= 0x02000000u; +} +inline void SatParameters::clear_has_max_clause_activity_value() { + _has_bits_[0] &= ~0x02000000u; +} +inline void SatParameters::clear_max_clause_activity_value() { + max_clause_activity_value_ = 1e+20; + clear_has_max_clause_activity_value(); +} +inline double SatParameters::max_clause_activity_value() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_clause_activity_value) + return max_clause_activity_value_; +} +inline void SatParameters::set_max_clause_activity_value(double value) { + set_has_max_clause_activity_value(); + max_clause_activity_value_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_clause_activity_value) +} + +// optional bool use_glucose_bump_again_strategy = 21 [default = false]; +inline bool SatParameters::has_use_glucose_bump_again_strategy() const { + return (_has_bits_[0] & 0x04000000u) != 0; +} +inline void SatParameters::set_has_use_glucose_bump_again_strategy() { + _has_bits_[0] |= 0x04000000u; +} +inline void SatParameters::clear_has_use_glucose_bump_again_strategy() { + _has_bits_[0] &= ~0x04000000u; +} +inline void SatParameters::clear_use_glucose_bump_again_strategy() { + use_glucose_bump_again_strategy_ = false; + clear_has_use_glucose_bump_again_strategy(); +} +inline bool SatParameters::use_glucose_bump_again_strategy() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_glucose_bump_again_strategy) + return use_glucose_bump_again_strategy_; +} +inline void SatParameters::set_use_glucose_bump_again_strategy(bool value) { + set_has_use_glucose_bump_again_strategy(); + use_glucose_bump_again_strategy_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_glucose_bump_again_strategy) +} + +// repeated .operations_research.sat.SatParameters.RestartAlgorithm restart_algorithms = 61; +inline int SatParameters::restart_algorithms_size() const { + return restart_algorithms_.size(); +} +inline void SatParameters::clear_restart_algorithms() { + restart_algorithms_.Clear(); +} +inline ::operations_research::sat::SatParameters_RestartAlgorithm SatParameters::restart_algorithms(int index) const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.restart_algorithms) + return static_cast< ::operations_research::sat::SatParameters_RestartAlgorithm >(restart_algorithms_.Get(index)); +} +inline void SatParameters::set_restart_algorithms(int index, ::operations_research::sat::SatParameters_RestartAlgorithm value) { + assert(::operations_research::sat::SatParameters_RestartAlgorithm_IsValid(value)); + restart_algorithms_.Set(index, value); + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.restart_algorithms) +} +inline void SatParameters::add_restart_algorithms(::operations_research::sat::SatParameters_RestartAlgorithm value) { + assert(::operations_research::sat::SatParameters_RestartAlgorithm_IsValid(value)); + restart_algorithms_.Add(value); + // @@protoc_insertion_point(field_add:operations_research.sat.SatParameters.restart_algorithms) +} +inline const ::google::protobuf::RepeatedField& +SatParameters::restart_algorithms() const { + // @@protoc_insertion_point(field_list:operations_research.sat.SatParameters.restart_algorithms) + return restart_algorithms_; +} +inline ::google::protobuf::RepeatedField* +SatParameters::mutable_restart_algorithms() { + // @@protoc_insertion_point(field_mutable_list:operations_research.sat.SatParameters.restart_algorithms) + return &restart_algorithms_; +} + +// optional string default_restart_algorithms = 70 [default = "LUBY_RESTART,LBD_MOVING_AVERAGE_RESTART,DL_MOVING_AVERAGE_RESTART"]; +inline bool SatParameters::has_default_restart_algorithms() const { + return (_has_bits_[0] & 0x10000000u) != 0; +} +inline void SatParameters::set_has_default_restart_algorithms() { + _has_bits_[0] |= 0x10000000u; +} +inline void SatParameters::clear_has_default_restart_algorithms() { + _has_bits_[0] &= ~0x10000000u; +} +inline void SatParameters::clear_default_restart_algorithms() { + default_restart_algorithms_.ClearToDefaultNoArena(_default_default_restart_algorithms_); + clear_has_default_restart_algorithms(); +} +inline const ::std::string& SatParameters::default_restart_algorithms() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.default_restart_algorithms) + return default_restart_algorithms_.GetNoArena(_default_default_restart_algorithms_); +} +inline void SatParameters::set_default_restart_algorithms(const ::std::string& value) { + set_has_default_restart_algorithms(); + default_restart_algorithms_.SetNoArena(_default_default_restart_algorithms_, value); + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.default_restart_algorithms) +} +inline void SatParameters::set_default_restart_algorithms(const char* value) { + set_has_default_restart_algorithms(); + default_restart_algorithms_.SetNoArena(_default_default_restart_algorithms_, ::std::string(value)); + // @@protoc_insertion_point(field_set_char:operations_research.sat.SatParameters.default_restart_algorithms) +} +inline void SatParameters::set_default_restart_algorithms(const char* value, size_t size) { + set_has_default_restart_algorithms(); + default_restart_algorithms_.SetNoArena(_default_default_restart_algorithms_, + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:operations_research.sat.SatParameters.default_restart_algorithms) +} +inline ::std::string* SatParameters::mutable_default_restart_algorithms() { + set_has_default_restart_algorithms(); + // @@protoc_insertion_point(field_mutable:operations_research.sat.SatParameters.default_restart_algorithms) + return default_restart_algorithms_.MutableNoArena(_default_default_restart_algorithms_); +} +inline ::std::string* SatParameters::release_default_restart_algorithms() { + // @@protoc_insertion_point(field_release:operations_research.sat.SatParameters.default_restart_algorithms) + clear_has_default_restart_algorithms(); + return default_restart_algorithms_.ReleaseNoArena(_default_default_restart_algorithms_); +} +inline void SatParameters::set_allocated_default_restart_algorithms(::std::string* default_restart_algorithms) { + if (default_restart_algorithms != NULL) { + set_has_default_restart_algorithms(); + } else { + clear_has_default_restart_algorithms(); + } + default_restart_algorithms_.SetAllocatedNoArena(_default_default_restart_algorithms_, default_restart_algorithms); + // @@protoc_insertion_point(field_set_allocated:operations_research.sat.SatParameters.default_restart_algorithms) +} + +// optional int32 luby_restart_period = 30 [default = 50]; +inline bool SatParameters::has_luby_restart_period() const { + return (_has_bits_[0] & 0x20000000u) != 0; +} +inline void SatParameters::set_has_luby_restart_period() { + _has_bits_[0] |= 0x20000000u; +} +inline void SatParameters::clear_has_luby_restart_period() { + _has_bits_[0] &= ~0x20000000u; +} +inline void SatParameters::clear_luby_restart_period() { + luby_restart_period_ = 50; + clear_has_luby_restart_period(); +} +inline ::google::protobuf::int32 SatParameters::luby_restart_period() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.luby_restart_period) + return luby_restart_period_; +} +inline void SatParameters::set_luby_restart_period(::google::protobuf::int32 value) { + set_has_luby_restart_period(); + luby_restart_period_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.luby_restart_period) +} + +// optional int32 restart_running_window_size = 62 [default = 50]; +inline bool SatParameters::has_restart_running_window_size() const { + return (_has_bits_[0] & 0x40000000u) != 0; +} +inline void SatParameters::set_has_restart_running_window_size() { + _has_bits_[0] |= 0x40000000u; +} +inline void SatParameters::clear_has_restart_running_window_size() { + _has_bits_[0] &= ~0x40000000u; +} +inline void SatParameters::clear_restart_running_window_size() { + restart_running_window_size_ = 50; + clear_has_restart_running_window_size(); +} +inline ::google::protobuf::int32 SatParameters::restart_running_window_size() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.restart_running_window_size) + return restart_running_window_size_; +} +inline void SatParameters::set_restart_running_window_size(::google::protobuf::int32 value) { + set_has_restart_running_window_size(); + restart_running_window_size_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.restart_running_window_size) +} + +// optional double restart_dl_average_ratio = 63 [default = 1]; +inline bool SatParameters::has_restart_dl_average_ratio() const { + return (_has_bits_[0] & 0x80000000u) != 0; +} +inline void SatParameters::set_has_restart_dl_average_ratio() { + _has_bits_[0] |= 0x80000000u; +} +inline void SatParameters::clear_has_restart_dl_average_ratio() { + _has_bits_[0] &= ~0x80000000u; +} +inline void SatParameters::clear_restart_dl_average_ratio() { + restart_dl_average_ratio_ = 1; + clear_has_restart_dl_average_ratio(); +} +inline double SatParameters::restart_dl_average_ratio() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.restart_dl_average_ratio) + return restart_dl_average_ratio_; +} +inline void SatParameters::set_restart_dl_average_ratio(double value) { + set_has_restart_dl_average_ratio(); + restart_dl_average_ratio_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.restart_dl_average_ratio) +} + +// optional double restart_lbd_average_ratio = 71 [default = 0.8]; +inline bool SatParameters::has_restart_lbd_average_ratio() const { + return (_has_bits_[1] & 0x00000001u) != 0; +} +inline void SatParameters::set_has_restart_lbd_average_ratio() { + _has_bits_[1] |= 0x00000001u; +} +inline void SatParameters::clear_has_restart_lbd_average_ratio() { + _has_bits_[1] &= ~0x00000001u; +} +inline void SatParameters::clear_restart_lbd_average_ratio() { + restart_lbd_average_ratio_ = 0.8; + clear_has_restart_lbd_average_ratio(); +} +inline double SatParameters::restart_lbd_average_ratio() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.restart_lbd_average_ratio) + return restart_lbd_average_ratio_; +} +inline void SatParameters::set_restart_lbd_average_ratio(double value) { + set_has_restart_lbd_average_ratio(); + restart_lbd_average_ratio_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.restart_lbd_average_ratio) +} + +// optional bool use_blocking_restart = 64 [default = false]; +inline bool SatParameters::has_use_blocking_restart() const { + return (_has_bits_[1] & 0x00000002u) != 0; +} +inline void SatParameters::set_has_use_blocking_restart() { + _has_bits_[1] |= 0x00000002u; +} +inline void SatParameters::clear_has_use_blocking_restart() { + _has_bits_[1] &= ~0x00000002u; +} +inline void SatParameters::clear_use_blocking_restart() { + use_blocking_restart_ = false; + clear_has_use_blocking_restart(); +} +inline bool SatParameters::use_blocking_restart() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_blocking_restart) + return use_blocking_restart_; +} +inline void SatParameters::set_use_blocking_restart(bool value) { + set_has_use_blocking_restart(); + use_blocking_restart_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_blocking_restart) +} + +// optional int32 blocking_restart_window_size = 65 [default = 5000]; +inline bool SatParameters::has_blocking_restart_window_size() const { + return (_has_bits_[1] & 0x00000004u) != 0; +} +inline void SatParameters::set_has_blocking_restart_window_size() { + _has_bits_[1] |= 0x00000004u; +} +inline void SatParameters::clear_has_blocking_restart_window_size() { + _has_bits_[1] &= ~0x00000004u; +} +inline void SatParameters::clear_blocking_restart_window_size() { + blocking_restart_window_size_ = 5000; + clear_has_blocking_restart_window_size(); +} +inline ::google::protobuf::int32 SatParameters::blocking_restart_window_size() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.blocking_restart_window_size) + return blocking_restart_window_size_; +} +inline void SatParameters::set_blocking_restart_window_size(::google::protobuf::int32 value) { + set_has_blocking_restart_window_size(); + blocking_restart_window_size_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.blocking_restart_window_size) +} + +// optional double blocking_restart_multiplier = 66 [default = 1.4]; +inline bool SatParameters::has_blocking_restart_multiplier() const { + return (_has_bits_[1] & 0x00000008u) != 0; +} +inline void SatParameters::set_has_blocking_restart_multiplier() { + _has_bits_[1] |= 0x00000008u; +} +inline void SatParameters::clear_has_blocking_restart_multiplier() { + _has_bits_[1] &= ~0x00000008u; +} +inline void SatParameters::clear_blocking_restart_multiplier() { + blocking_restart_multiplier_ = 1.4; + clear_has_blocking_restart_multiplier(); +} +inline double SatParameters::blocking_restart_multiplier() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.blocking_restart_multiplier) + return blocking_restart_multiplier_; +} +inline void SatParameters::set_blocking_restart_multiplier(double value) { + set_has_blocking_restart_multiplier(); + blocking_restart_multiplier_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.blocking_restart_multiplier) +} + +// optional int32 num_conflicts_before_strategy_changes = 68 [default = 0]; +inline bool SatParameters::has_num_conflicts_before_strategy_changes() const { + return (_has_bits_[1] & 0x00000010u) != 0; +} +inline void SatParameters::set_has_num_conflicts_before_strategy_changes() { + _has_bits_[1] |= 0x00000010u; +} +inline void SatParameters::clear_has_num_conflicts_before_strategy_changes() { + _has_bits_[1] &= ~0x00000010u; +} +inline void SatParameters::clear_num_conflicts_before_strategy_changes() { + num_conflicts_before_strategy_changes_ = 0; + clear_has_num_conflicts_before_strategy_changes(); +} +inline ::google::protobuf::int32 SatParameters::num_conflicts_before_strategy_changes() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.num_conflicts_before_strategy_changes) + return num_conflicts_before_strategy_changes_; +} +inline void SatParameters::set_num_conflicts_before_strategy_changes(::google::protobuf::int32 value) { + set_has_num_conflicts_before_strategy_changes(); + num_conflicts_before_strategy_changes_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.num_conflicts_before_strategy_changes) +} + +// optional double strategy_change_increase_ratio = 69 [default = 0]; +inline bool SatParameters::has_strategy_change_increase_ratio() const { + return (_has_bits_[1] & 0x00000020u) != 0; +} +inline void SatParameters::set_has_strategy_change_increase_ratio() { + _has_bits_[1] |= 0x00000020u; +} +inline void SatParameters::clear_has_strategy_change_increase_ratio() { + _has_bits_[1] &= ~0x00000020u; +} +inline void SatParameters::clear_strategy_change_increase_ratio() { + strategy_change_increase_ratio_ = 0; + clear_has_strategy_change_increase_ratio(); +} +inline double SatParameters::strategy_change_increase_ratio() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.strategy_change_increase_ratio) + return strategy_change_increase_ratio_; +} +inline void SatParameters::set_strategy_change_increase_ratio(double value) { + set_has_strategy_change_increase_ratio(); + strategy_change_increase_ratio_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.strategy_change_increase_ratio) +} + +// optional double max_time_in_seconds = 36 [default = inf]; +inline bool SatParameters::has_max_time_in_seconds() const { + return (_has_bits_[1] & 0x00000040u) != 0; +} +inline void SatParameters::set_has_max_time_in_seconds() { + _has_bits_[1] |= 0x00000040u; +} +inline void SatParameters::clear_has_max_time_in_seconds() { + _has_bits_[1] &= ~0x00000040u; +} +inline void SatParameters::clear_max_time_in_seconds() { + max_time_in_seconds_ = ::google::protobuf::internal::Infinity(); + clear_has_max_time_in_seconds(); +} +inline double SatParameters::max_time_in_seconds() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_time_in_seconds) + return max_time_in_seconds_; +} +inline void SatParameters::set_max_time_in_seconds(double value) { + set_has_max_time_in_seconds(); + max_time_in_seconds_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_time_in_seconds) +} + +// optional double max_deterministic_time = 67 [default = inf]; +inline bool SatParameters::has_max_deterministic_time() const { + return (_has_bits_[1] & 0x00000080u) != 0; +} +inline void SatParameters::set_has_max_deterministic_time() { + _has_bits_[1] |= 0x00000080u; +} +inline void SatParameters::clear_has_max_deterministic_time() { + _has_bits_[1] &= ~0x00000080u; +} +inline void SatParameters::clear_max_deterministic_time() { + max_deterministic_time_ = ::google::protobuf::internal::Infinity(); + clear_has_max_deterministic_time(); +} +inline double SatParameters::max_deterministic_time() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_deterministic_time) + return max_deterministic_time_; +} +inline void SatParameters::set_max_deterministic_time(double value) { + set_has_max_deterministic_time(); + max_deterministic_time_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_deterministic_time) +} + +// optional int64 max_number_of_conflicts = 37 [default = 9223372036854775807]; +inline bool SatParameters::has_max_number_of_conflicts() const { + return (_has_bits_[1] & 0x00000100u) != 0; +} +inline void SatParameters::set_has_max_number_of_conflicts() { + _has_bits_[1] |= 0x00000100u; +} +inline void SatParameters::clear_has_max_number_of_conflicts() { + _has_bits_[1] &= ~0x00000100u; +} +inline void SatParameters::clear_max_number_of_conflicts() { + max_number_of_conflicts_ = GOOGLE_LONGLONG(9223372036854775807); + clear_has_max_number_of_conflicts(); +} +inline ::google::protobuf::int64 SatParameters::max_number_of_conflicts() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_number_of_conflicts) + return max_number_of_conflicts_; +} +inline void SatParameters::set_max_number_of_conflicts(::google::protobuf::int64 value) { + set_has_max_number_of_conflicts(); + max_number_of_conflicts_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_number_of_conflicts) +} + +// optional int64 max_memory_in_mb = 40 [default = 10000]; +inline bool SatParameters::has_max_memory_in_mb() const { + return (_has_bits_[1] & 0x00000200u) != 0; +} +inline void SatParameters::set_has_max_memory_in_mb() { + _has_bits_[1] |= 0x00000200u; +} +inline void SatParameters::clear_has_max_memory_in_mb() { + _has_bits_[1] &= ~0x00000200u; +} +inline void SatParameters::clear_max_memory_in_mb() { + max_memory_in_mb_ = GOOGLE_LONGLONG(10000); + clear_has_max_memory_in_mb(); +} +inline ::google::protobuf::int64 SatParameters::max_memory_in_mb() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_memory_in_mb) + return max_memory_in_mb_; +} +inline void SatParameters::set_max_memory_in_mb(::google::protobuf::int64 value) { + set_has_max_memory_in_mb(); + max_memory_in_mb_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_memory_in_mb) +} + +// optional bool treat_binary_clauses_separately = 33 [default = true]; +inline bool SatParameters::has_treat_binary_clauses_separately() const { + return (_has_bits_[1] & 0x00000400u) != 0; +} +inline void SatParameters::set_has_treat_binary_clauses_separately() { + _has_bits_[1] |= 0x00000400u; +} +inline void SatParameters::clear_has_treat_binary_clauses_separately() { + _has_bits_[1] &= ~0x00000400u; +} +inline void SatParameters::clear_treat_binary_clauses_separately() { + treat_binary_clauses_separately_ = true; + clear_has_treat_binary_clauses_separately(); +} +inline bool SatParameters::treat_binary_clauses_separately() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.treat_binary_clauses_separately) + return treat_binary_clauses_separately_; +} +inline void SatParameters::set_treat_binary_clauses_separately(bool value) { + set_has_treat_binary_clauses_separately(); + treat_binary_clauses_separately_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.treat_binary_clauses_separately) +} + +// optional int32 random_seed = 31 [default = 1]; +inline bool SatParameters::has_random_seed() const { + return (_has_bits_[1] & 0x00000800u) != 0; +} +inline void SatParameters::set_has_random_seed() { + _has_bits_[1] |= 0x00000800u; +} +inline void SatParameters::clear_has_random_seed() { + _has_bits_[1] &= ~0x00000800u; +} +inline void SatParameters::clear_random_seed() { + random_seed_ = 1; + clear_has_random_seed(); +} +inline ::google::protobuf::int32 SatParameters::random_seed() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.random_seed) + return random_seed_; +} +inline void SatParameters::set_random_seed(::google::protobuf::int32 value) { + set_has_random_seed(); + random_seed_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.random_seed) +} + +// optional bool log_search_progress = 41 [default = false]; +inline bool SatParameters::has_log_search_progress() const { + return (_has_bits_[1] & 0x00001000u) != 0; +} +inline void SatParameters::set_has_log_search_progress() { + _has_bits_[1] |= 0x00001000u; +} +inline void SatParameters::clear_has_log_search_progress() { + _has_bits_[1] &= ~0x00001000u; +} +inline void SatParameters::clear_log_search_progress() { + log_search_progress_ = false; + clear_has_log_search_progress(); +} +inline bool SatParameters::log_search_progress() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.log_search_progress) + return log_search_progress_; +} +inline void SatParameters::set_log_search_progress(bool value) { + set_has_log_search_progress(); + log_search_progress_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.log_search_progress) +} + +// optional bool use_pb_resolution = 43 [default = false]; +inline bool SatParameters::has_use_pb_resolution() const { + return (_has_bits_[1] & 0x00002000u) != 0; +} +inline void SatParameters::set_has_use_pb_resolution() { + _has_bits_[1] |= 0x00002000u; +} +inline void SatParameters::clear_has_use_pb_resolution() { + _has_bits_[1] &= ~0x00002000u; +} +inline void SatParameters::clear_use_pb_resolution() { + use_pb_resolution_ = false; + clear_has_use_pb_resolution(); +} +inline bool SatParameters::use_pb_resolution() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_pb_resolution) + return use_pb_resolution_; +} +inline void SatParameters::set_use_pb_resolution(bool value) { + set_has_use_pb_resolution(); + use_pb_resolution_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_pb_resolution) +} + +// optional bool minimize_reduction_during_pb_resolution = 48 [default = false]; +inline bool SatParameters::has_minimize_reduction_during_pb_resolution() const { + return (_has_bits_[1] & 0x00004000u) != 0; +} +inline void SatParameters::set_has_minimize_reduction_during_pb_resolution() { + _has_bits_[1] |= 0x00004000u; +} +inline void SatParameters::clear_has_minimize_reduction_during_pb_resolution() { + _has_bits_[1] &= ~0x00004000u; +} +inline void SatParameters::clear_minimize_reduction_during_pb_resolution() { + minimize_reduction_during_pb_resolution_ = false; + clear_has_minimize_reduction_during_pb_resolution(); +} +inline bool SatParameters::minimize_reduction_during_pb_resolution() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.minimize_reduction_during_pb_resolution) + return minimize_reduction_during_pb_resolution_; +} +inline void SatParameters::set_minimize_reduction_during_pb_resolution(bool value) { + set_has_minimize_reduction_during_pb_resolution(); + minimize_reduction_during_pb_resolution_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.minimize_reduction_during_pb_resolution) +} + +// optional bool count_assumption_levels_in_lbd = 49 [default = true]; +inline bool SatParameters::has_count_assumption_levels_in_lbd() const { + return (_has_bits_[1] & 0x00008000u) != 0; +} +inline void SatParameters::set_has_count_assumption_levels_in_lbd() { + _has_bits_[1] |= 0x00008000u; +} +inline void SatParameters::clear_has_count_assumption_levels_in_lbd() { + _has_bits_[1] &= ~0x00008000u; +} +inline void SatParameters::clear_count_assumption_levels_in_lbd() { + count_assumption_levels_in_lbd_ = true; + clear_has_count_assumption_levels_in_lbd(); +} +inline bool SatParameters::count_assumption_levels_in_lbd() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.count_assumption_levels_in_lbd) + return count_assumption_levels_in_lbd_; +} +inline void SatParameters::set_count_assumption_levels_in_lbd(bool value) { + set_has_count_assumption_levels_in_lbd(); + count_assumption_levels_in_lbd_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.count_assumption_levels_in_lbd) +} + +// optional int32 presolve_bve_threshold = 54 [default = 500]; +inline bool SatParameters::has_presolve_bve_threshold() const { + return (_has_bits_[1] & 0x00010000u) != 0; +} +inline void SatParameters::set_has_presolve_bve_threshold() { + _has_bits_[1] |= 0x00010000u; +} +inline void SatParameters::clear_has_presolve_bve_threshold() { + _has_bits_[1] &= ~0x00010000u; +} +inline void SatParameters::clear_presolve_bve_threshold() { + presolve_bve_threshold_ = 500; + clear_has_presolve_bve_threshold(); +} +inline ::google::protobuf::int32 SatParameters::presolve_bve_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.presolve_bve_threshold) + return presolve_bve_threshold_; +} +inline void SatParameters::set_presolve_bve_threshold(::google::protobuf::int32 value) { + set_has_presolve_bve_threshold(); + presolve_bve_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.presolve_bve_threshold) +} + +// optional int32 presolve_bve_clause_weight = 55 [default = 3]; +inline bool SatParameters::has_presolve_bve_clause_weight() const { + return (_has_bits_[1] & 0x00020000u) != 0; +} +inline void SatParameters::set_has_presolve_bve_clause_weight() { + _has_bits_[1] |= 0x00020000u; +} +inline void SatParameters::clear_has_presolve_bve_clause_weight() { + _has_bits_[1] &= ~0x00020000u; +} +inline void SatParameters::clear_presolve_bve_clause_weight() { + presolve_bve_clause_weight_ = 3; + clear_has_presolve_bve_clause_weight(); +} +inline ::google::protobuf::int32 SatParameters::presolve_bve_clause_weight() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.presolve_bve_clause_weight) + return presolve_bve_clause_weight_; +} +inline void SatParameters::set_presolve_bve_clause_weight(::google::protobuf::int32 value) { + set_has_presolve_bve_clause_weight(); + presolve_bve_clause_weight_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.presolve_bve_clause_weight) +} + +// optional double presolve_probing_deterministic_time_limit = 57 [default = 30]; +inline bool SatParameters::has_presolve_probing_deterministic_time_limit() const { + return (_has_bits_[1] & 0x00040000u) != 0; +} +inline void SatParameters::set_has_presolve_probing_deterministic_time_limit() { + _has_bits_[1] |= 0x00040000u; +} +inline void SatParameters::clear_has_presolve_probing_deterministic_time_limit() { + _has_bits_[1] &= ~0x00040000u; +} +inline void SatParameters::clear_presolve_probing_deterministic_time_limit() { + presolve_probing_deterministic_time_limit_ = 30; + clear_has_presolve_probing_deterministic_time_limit(); +} +inline double SatParameters::presolve_probing_deterministic_time_limit() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.presolve_probing_deterministic_time_limit) + return presolve_probing_deterministic_time_limit_; +} +inline void SatParameters::set_presolve_probing_deterministic_time_limit(double value) { + set_has_presolve_probing_deterministic_time_limit(); + presolve_probing_deterministic_time_limit_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.presolve_probing_deterministic_time_limit) +} + +// optional bool presolve_use_bva = 72 [default = true]; +inline bool SatParameters::has_presolve_use_bva() const { + return (_has_bits_[1] & 0x00080000u) != 0; +} +inline void SatParameters::set_has_presolve_use_bva() { + _has_bits_[1] |= 0x00080000u; +} +inline void SatParameters::clear_has_presolve_use_bva() { + _has_bits_[1] &= ~0x00080000u; +} +inline void SatParameters::clear_presolve_use_bva() { + presolve_use_bva_ = true; + clear_has_presolve_use_bva(); +} +inline bool SatParameters::presolve_use_bva() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.presolve_use_bva) + return presolve_use_bva_; +} +inline void SatParameters::set_presolve_use_bva(bool value) { + set_has_presolve_use_bva(); + presolve_use_bva_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.presolve_use_bva) +} + +// optional int32 presolve_bva_threshold = 73 [default = 1]; +inline bool SatParameters::has_presolve_bva_threshold() const { + return (_has_bits_[1] & 0x00100000u) != 0; +} +inline void SatParameters::set_has_presolve_bva_threshold() { + _has_bits_[1] |= 0x00100000u; +} +inline void SatParameters::clear_has_presolve_bva_threshold() { + _has_bits_[1] &= ~0x00100000u; +} +inline void SatParameters::clear_presolve_bva_threshold() { + presolve_bva_threshold_ = 1; + clear_has_presolve_bva_threshold(); +} +inline ::google::protobuf::int32 SatParameters::presolve_bva_threshold() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.presolve_bva_threshold) + return presolve_bva_threshold_; +} +inline void SatParameters::set_presolve_bva_threshold(::google::protobuf::int32 value) { + set_has_presolve_bva_threshold(); + presolve_bva_threshold_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.presolve_bva_threshold) +} + +// optional bool use_optimization_hints = 35 [default = true]; +inline bool SatParameters::has_use_optimization_hints() const { + return (_has_bits_[1] & 0x00200000u) != 0; +} +inline void SatParameters::set_has_use_optimization_hints() { + _has_bits_[1] |= 0x00200000u; +} +inline void SatParameters::clear_has_use_optimization_hints() { + _has_bits_[1] &= ~0x00200000u; +} +inline void SatParameters::clear_use_optimization_hints() { + use_optimization_hints_ = true; + clear_has_use_optimization_hints(); +} +inline bool SatParameters::use_optimization_hints() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_optimization_hints) + return use_optimization_hints_; +} +inline void SatParameters::set_use_optimization_hints(bool value) { + set_has_use_optimization_hints(); + use_optimization_hints_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_optimization_hints) +} + +// optional bool minimize_core = 50 [default = true]; +inline bool SatParameters::has_minimize_core() const { + return (_has_bits_[1] & 0x00400000u) != 0; +} +inline void SatParameters::set_has_minimize_core() { + _has_bits_[1] |= 0x00400000u; +} +inline void SatParameters::clear_has_minimize_core() { + _has_bits_[1] &= ~0x00400000u; +} +inline void SatParameters::clear_minimize_core() { + minimize_core_ = true; + clear_has_minimize_core(); +} +inline bool SatParameters::minimize_core() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.minimize_core) + return minimize_core_; +} +inline void SatParameters::set_minimize_core(bool value) { + set_has_minimize_core(); + minimize_core_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.minimize_core) +} + +// optional .operations_research.sat.SatParameters.MaxSatAssumptionOrder max_sat_assumption_order = 51 [default = DEFAULT_ASSUMPTION_ORDER]; +inline bool SatParameters::has_max_sat_assumption_order() const { + return (_has_bits_[1] & 0x00800000u) != 0; +} +inline void SatParameters::set_has_max_sat_assumption_order() { + _has_bits_[1] |= 0x00800000u; +} +inline void SatParameters::clear_has_max_sat_assumption_order() { + _has_bits_[1] &= ~0x00800000u; +} +inline void SatParameters::clear_max_sat_assumption_order() { + max_sat_assumption_order_ = 0; + clear_has_max_sat_assumption_order(); +} +inline ::operations_research::sat::SatParameters_MaxSatAssumptionOrder SatParameters::max_sat_assumption_order() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_sat_assumption_order) + return static_cast< ::operations_research::sat::SatParameters_MaxSatAssumptionOrder >(max_sat_assumption_order_); +} +inline void SatParameters::set_max_sat_assumption_order(::operations_research::sat::SatParameters_MaxSatAssumptionOrder value) { + assert(::operations_research::sat::SatParameters_MaxSatAssumptionOrder_IsValid(value)); + set_has_max_sat_assumption_order(); + max_sat_assumption_order_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_sat_assumption_order) +} + +// optional bool max_sat_reverse_assumption_order = 52 [default = false]; +inline bool SatParameters::has_max_sat_reverse_assumption_order() const { + return (_has_bits_[1] & 0x01000000u) != 0; +} +inline void SatParameters::set_has_max_sat_reverse_assumption_order() { + _has_bits_[1] |= 0x01000000u; +} +inline void SatParameters::clear_has_max_sat_reverse_assumption_order() { + _has_bits_[1] &= ~0x01000000u; +} +inline void SatParameters::clear_max_sat_reverse_assumption_order() { + max_sat_reverse_assumption_order_ = false; + clear_has_max_sat_reverse_assumption_order(); +} +inline bool SatParameters::max_sat_reverse_assumption_order() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_sat_reverse_assumption_order) + return max_sat_reverse_assumption_order_; +} +inline void SatParameters::set_max_sat_reverse_assumption_order(bool value) { + set_has_max_sat_reverse_assumption_order(); + max_sat_reverse_assumption_order_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_sat_reverse_assumption_order) +} + +// optional .operations_research.sat.SatParameters.MaxSatStratificationAlgorithm max_sat_stratification = 53 [default = STRATIFICATION_DESCENT]; +inline bool SatParameters::has_max_sat_stratification() const { + return (_has_bits_[1] & 0x02000000u) != 0; +} +inline void SatParameters::set_has_max_sat_stratification() { + _has_bits_[1] |= 0x02000000u; +} +inline void SatParameters::clear_has_max_sat_stratification() { + _has_bits_[1] &= ~0x02000000u; +} +inline void SatParameters::clear_max_sat_stratification() { + max_sat_stratification_ = 1; + clear_has_max_sat_stratification(); +} +inline ::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm SatParameters::max_sat_stratification() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.max_sat_stratification) + return static_cast< ::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm >(max_sat_stratification_); +} +inline void SatParameters::set_max_sat_stratification(::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm value) { + assert(::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm_IsValid(value)); + set_has_max_sat_stratification(); + max_sat_stratification_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.max_sat_stratification) +} + +// optional bool use_precedences_in_disjunctive_constraint = 74 [default = true]; +inline bool SatParameters::has_use_precedences_in_disjunctive_constraint() const { + return (_has_bits_[1] & 0x04000000u) != 0; +} +inline void SatParameters::set_has_use_precedences_in_disjunctive_constraint() { + _has_bits_[1] |= 0x04000000u; +} +inline void SatParameters::clear_has_use_precedences_in_disjunctive_constraint() { + _has_bits_[1] &= ~0x04000000u; +} +inline void SatParameters::clear_use_precedences_in_disjunctive_constraint() { + use_precedences_in_disjunctive_constraint_ = true; + clear_has_use_precedences_in_disjunctive_constraint(); +} +inline bool SatParameters::use_precedences_in_disjunctive_constraint() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_precedences_in_disjunctive_constraint) + return use_precedences_in_disjunctive_constraint_; +} +inline void SatParameters::set_use_precedences_in_disjunctive_constraint(bool value) { + set_has_use_precedences_in_disjunctive_constraint(); + use_precedences_in_disjunctive_constraint_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_precedences_in_disjunctive_constraint) +} + +// optional bool use_overload_checker_in_cumulative_constraint = 78 [default = false]; +inline bool SatParameters::has_use_overload_checker_in_cumulative_constraint() const { + return (_has_bits_[1] & 0x08000000u) != 0; +} +inline void SatParameters::set_has_use_overload_checker_in_cumulative_constraint() { + _has_bits_[1] |= 0x08000000u; +} +inline void SatParameters::clear_has_use_overload_checker_in_cumulative_constraint() { + _has_bits_[1] &= ~0x08000000u; +} +inline void SatParameters::clear_use_overload_checker_in_cumulative_constraint() { + use_overload_checker_in_cumulative_constraint_ = false; + clear_has_use_overload_checker_in_cumulative_constraint(); +} +inline bool SatParameters::use_overload_checker_in_cumulative_constraint() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_overload_checker_in_cumulative_constraint) + return use_overload_checker_in_cumulative_constraint_; +} +inline void SatParameters::set_use_overload_checker_in_cumulative_constraint(bool value) { + set_has_use_overload_checker_in_cumulative_constraint(); + use_overload_checker_in_cumulative_constraint_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_overload_checker_in_cumulative_constraint) +} + +// optional bool use_timetable_edge_finding_in_cumulative_constraint = 79 [default = false]; +inline bool SatParameters::has_use_timetable_edge_finding_in_cumulative_constraint() const { + return (_has_bits_[1] & 0x10000000u) != 0; +} +inline void SatParameters::set_has_use_timetable_edge_finding_in_cumulative_constraint() { + _has_bits_[1] |= 0x10000000u; +} +inline void SatParameters::clear_has_use_timetable_edge_finding_in_cumulative_constraint() { + _has_bits_[1] &= ~0x10000000u; +} +inline void SatParameters::clear_use_timetable_edge_finding_in_cumulative_constraint() { + use_timetable_edge_finding_in_cumulative_constraint_ = false; + clear_has_use_timetable_edge_finding_in_cumulative_constraint(); +} +inline bool SatParameters::use_timetable_edge_finding_in_cumulative_constraint() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_timetable_edge_finding_in_cumulative_constraint) + return use_timetable_edge_finding_in_cumulative_constraint_; +} +inline void SatParameters::set_use_timetable_edge_finding_in_cumulative_constraint(bool value) { + set_has_use_timetable_edge_finding_in_cumulative_constraint(); + use_timetable_edge_finding_in_cumulative_constraint_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_timetable_edge_finding_in_cumulative_constraint) +} + +// optional bool use_disjunctive_constraint_in_cumulative_constraint = 80 [default = false]; +inline bool SatParameters::has_use_disjunctive_constraint_in_cumulative_constraint() const { + return (_has_bits_[1] & 0x20000000u) != 0; +} +inline void SatParameters::set_has_use_disjunctive_constraint_in_cumulative_constraint() { + _has_bits_[1] |= 0x20000000u; +} +inline void SatParameters::clear_has_use_disjunctive_constraint_in_cumulative_constraint() { + _has_bits_[1] &= ~0x20000000u; +} +inline void SatParameters::clear_use_disjunctive_constraint_in_cumulative_constraint() { + use_disjunctive_constraint_in_cumulative_constraint_ = false; + clear_has_use_disjunctive_constraint_in_cumulative_constraint(); +} +inline bool SatParameters::use_disjunctive_constraint_in_cumulative_constraint() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_disjunctive_constraint_in_cumulative_constraint) + return use_disjunctive_constraint_in_cumulative_constraint_; +} +inline void SatParameters::set_use_disjunctive_constraint_in_cumulative_constraint(bool value) { + set_has_use_disjunctive_constraint_in_cumulative_constraint(); + use_disjunctive_constraint_in_cumulative_constraint_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_disjunctive_constraint_in_cumulative_constraint) +} + +// optional bool use_global_lp_constraint = 81 [default = true]; +inline bool SatParameters::has_use_global_lp_constraint() const { + return (_has_bits_[1] & 0x40000000u) != 0; +} +inline void SatParameters::set_has_use_global_lp_constraint() { + _has_bits_[1] |= 0x40000000u; +} +inline void SatParameters::clear_has_use_global_lp_constraint() { + _has_bits_[1] &= ~0x40000000u; +} +inline void SatParameters::clear_use_global_lp_constraint() { + use_global_lp_constraint_ = true; + clear_has_use_global_lp_constraint(); +} +inline bool SatParameters::use_global_lp_constraint() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_global_lp_constraint) + return use_global_lp_constraint_; +} +inline void SatParameters::set_use_global_lp_constraint(bool value) { + set_has_use_global_lp_constraint(); + use_global_lp_constraint_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_global_lp_constraint) +} + +// optional bool use_fixed_search = 82 [default = false]; +inline bool SatParameters::has_use_fixed_search() const { + return (_has_bits_[1] & 0x80000000u) != 0; +} +inline void SatParameters::set_has_use_fixed_search() { + _has_bits_[1] |= 0x80000000u; +} +inline void SatParameters::clear_has_use_fixed_search() { + _has_bits_[1] &= ~0x80000000u; +} +inline void SatParameters::clear_use_fixed_search() { + use_fixed_search_ = false; + clear_has_use_fixed_search(); +} +inline bool SatParameters::use_fixed_search() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.use_fixed_search) + return use_fixed_search_; +} +inline void SatParameters::set_use_fixed_search(bool value) { + set_has_use_fixed_search(); + use_fixed_search_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.use_fixed_search) +} + +// optional bool optimize_with_core = 83 [default = false]; +inline bool SatParameters::has_optimize_with_core() const { + return (_has_bits_[2] & 0x00000001u) != 0; +} +inline void SatParameters::set_has_optimize_with_core() { + _has_bits_[2] |= 0x00000001u; +} +inline void SatParameters::clear_has_optimize_with_core() { + _has_bits_[2] &= ~0x00000001u; +} +inline void SatParameters::clear_optimize_with_core() { + optimize_with_core_ = false; + clear_has_optimize_with_core(); +} +inline bool SatParameters::optimize_with_core() const { + // @@protoc_insertion_point(field_get:operations_research.sat.SatParameters.optimize_with_core) + return optimize_with_core_; +} +inline void SatParameters::set_optimize_with_core(bool value) { + set_has_optimize_with_core(); + optimize_with_core_ = value; + // @@protoc_insertion_point(field_set:operations_research.sat.SatParameters.optimize_with_core) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace sat +} // namespace operations_research + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_VariableOrder> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_VariableOrder>() { + return ::operations_research::sat::SatParameters_VariableOrder_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_Polarity> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_Polarity>() { + return ::operations_research::sat::SatParameters_Polarity_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_LiteralOrdering> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_LiteralOrdering>() { + return ::operations_research::sat::SatParameters_LiteralOrdering_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm>() { + return ::operations_research::sat::SatParameters_ConflictMinimizationAlgorithm_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_BinaryMinizationAlgorithm> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_BinaryMinizationAlgorithm>() { + return ::operations_research::sat::SatParameters_BinaryMinizationAlgorithm_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_ClauseProtection> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_ClauseProtection>() { + return ::operations_research::sat::SatParameters_ClauseProtection_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_ClauseOrdering> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_ClauseOrdering>() { + return ::operations_research::sat::SatParameters_ClauseOrdering_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_RestartAlgorithm> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_RestartAlgorithm>() { + return ::operations_research::sat::SatParameters_RestartAlgorithm_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_MaxSatAssumptionOrder> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_MaxSatAssumptionOrder>() { + return ::operations_research::sat::SatParameters_MaxSatAssumptionOrder_descriptor(); +} +template <> struct is_proto_enum< ::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm>() { + return ::operations_research::sat::SatParameters_MaxSatStratificationAlgorithm_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ortools_2fsat_2fsat_5fparameters_2eproto__INCLUDED diff --git a/thirdparty/linux/include/ortools/sat/sat_solver.h b/thirdparty/linux/include/ortools/sat/sat_solver.h new file mode 100644 index 0000000..6eab085 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/sat_solver.h @@ -0,0 +1,1149 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file implements a SAT solver. +// see http://en.wikipedia.org/wiki/Boolean_satisfiability_problem +// for more detail. +// TODO(user): Expand. + +#ifndef OR_TOOLS_SAT_SAT_SOLVER_H_ +#define OR_TOOLS_SAT_SAT_SOLVER_H_ + +#include +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/stringprintf.h" +#include "ortools/base/timer.h" +#include "google/protobuf/text_format.h" +#include "ortools/base/int_type.h" +#include "ortools/base/int_type_indexed_vector.h" +#include "ortools/base/map_util.h" +#include "ortools/sat/clause.h" +#include "ortools/sat/drat.h" +#include "ortools/sat/model.h" +#include "ortools/sat/pb_constraint.h" +#include "ortools/sat/sat_parameters.pb.h" +#include "ortools/util/bitset.h" +#include "ortools/util/running_stat.h" +#include "ortools/util/stats.h" +#include "ortools/util/time_limit.h" +#include "ortools/base/random.h" +#include "ortools/base/adjustable_priority_queue.h" + +namespace operations_research { +namespace sat { + +// A constant used by the EnqueueDecision*() API. +const int kUnsatTrailIndex = -1; + +// The main SAT solver. +// It currently implements the CDCL algorithm. See +// http://en.wikipedia.org/wiki/Conflict_Driven_Clause_Learning +class SatSolver { + public: + SatSolver(); + explicit SatSolver(Trail* trail); + ~SatSolver(); + + static SatSolver* CreateInModel(Model* model) { + Trail* trail = model->GetOrCreate(); + SatSolver* solver = new SatSolver(trail); + model->TakeOwnership(solver); + return solver; + } + + // Parameters management. Note that calling SetParameters() will reset the + // value of many heuristics. For instance: + // - The restart strategy will be reinitialized. + // - The random seed will be reset to the value given in parameters. + // - The time limit will be reset and counted from there. + void SetParameters(const SatParameters& parameters); + const SatParameters& parameters() const; + + // Increases the number of variables of the current problem. + // + // TODO(user): Rename to IncreaseNumVariablesTo() until we support removing + // variables... + void SetNumVariables(int num_variables); + int NumVariables() const { return num_variables_.value(); } + BooleanVariable NewBooleanVariable() { + const int num_vars = NumVariables(); + + // We need to be able to encode the variable as a literal. + CHECK_LT(2 * num_vars, std::numeric_limits::max()); + SetNumVariables(num_vars + 1); + return BooleanVariable(num_vars); + } + + // Fixes a variable so that the given literal is true. This can be used to + // solve a subproblem where some variables are fixed. Note that it is more + // efficient to add such unit clause before all the others. + // Returns false if the problem is detected to be UNSAT. + bool AddUnitClause(Literal true_literal); + + // Same as AddProblemClause() below, but for small clauses. + // + // TODO(user): Remove this and AddUnitClause() when initializer lists can be + // used in the open-source code like in AddClause({a, b}). + bool AddBinaryClause(Literal a, Literal b); + bool AddTernaryClause(Literal a, Literal b, Literal c); + + // Adds a clause to the problem. Returns false if the problem is detected to + // be UNSAT. + // + // TODO(user): Rename this to AddClause(). + bool AddProblemClause(const std::vector& literals); + + // Adds a pseudo-Boolean constraint to the problem. Returns false if the + // problem is detected to be UNSAT. If the constraint is always true, this + // detects it and does nothing. + // + // Note(user): There is an optimization if the same constraint is added + // consecutively (even if the bounds are different). This is particularly + // useful for an optimization problem when we want to constrain the objective + // of the problem more and more. Just re-adding such constraint is relatively + // efficient. + // + // OVERFLOW: The sum of the absolute value of all the coefficients + // in the constraint must not overflow. This is currently CHECKed(). + // TODO(user): Instead of failing, implement an error handling code. + bool AddLinearConstraint(bool use_lower_bound, Coefficient lower_bound, + bool use_upper_bound, Coefficient upper_bound, + std::vector* cst); + + // Returns true if the model is UNSAT. Note that currently the status is + // "sticky" and once this happen, nothing else can be done with the solver. + // + // Thanks to this function, a client can safely ignore the return value of any + // Add*() functions. If one of them return false, then IsModelUnsat() will + // return true. + bool IsModelUnsat() const { return is_model_unsat_; } + + // Adds and registers the given propagator with the sat solver. Note that + // during propagation, they will be called in the order they where added. + void AddPropagator(std::unique_ptr propagator); + void AddLastPropagator(std::unique_ptr propagator); + + // Gives a hint so the solver tries to find a solution with the given literal + // set to true. Currently this take precedence over the phase saving heuristic + // and a variable with a preference will always be branched on according to + // this preference. + // + // The weight is used as a tie-breaker between variable with the same + // activities. Larger weight will be selected first. A weight of zero is the + // default value for the other variables. + // + // Note(user): Having a lot of different weights may slow down the priority + // queue operations if there is millions of variables. + void SetAssignmentPreference(Literal literal, double weight); + + // Returns the vector of the current assignment preferences. + std::vector> AllPreferences() const; + + // Reinitializes the decision heuristics (which variables to choose with which + // polarity) according to the current parameters. Note that this also resets + // the activity of the variables to 0. + void ResetDecisionHeuristic(); + void ResetDecisionHeuristicAndSetAllPreferences( + const std::vector>& prefs); + + // Solves the problem and returns its status. + // An empty problem is considered to be SAT. + // + // Note that the conflict limit applies only to this function and starts + // counting from the time it is called. + // + // This will restart from the current solver configuration. If a previous call + // to Solve() was interrupted by a conflict or time limit, calling this again + // will resume the search exactly as it would have continued. + // + // Note that if a time limit has been defined earlier, using the SAT + // parameters or the SolveWithTimeLimit() method, it is still in use in this + // solve. To override the timelimit one should reset the parameters or use the + // SolveWithTimeLimit() with a new time limit. + enum Status { + ASSUMPTIONS_UNSAT, + MODEL_UNSAT, + MODEL_SAT, + LIMIT_REACHED, + }; + Status Solve(); + + // Same as Solve(), but with a given time limit. Note that this is slightly + // redundant with the max_time_in_seconds() and + // max_time_in_deterministic_seconds() parameters, but because SetParameters() + // resets more than just the time limit, it is useful to have this more + // specific api. + Status SolveWithTimeLimit(TimeLimit* time_limit); + + // Simple interface to solve a problem under the given assumptions. This + // simply ask the solver to solve a problem given a set of variables fixed to + // a given value (the assumptions). Compared to simply calling AddUnitClause() + // and fixing the variables once and for all, this allow to backtrack over the + // assumptions and thus exploit the incrementally between subsequent solves. + // + // This function backtrack over all the current decision, tries to enqueue the + // given assumptions, sets the assumption level accordingly and finally calls + // Solve(). + // + // If, given these assumptions, the model is UNSAT, this returns the + // ASSUMPTIONS_UNSAT status. MODEL_UNSAT is reserved for the case where the + // model is proven to be unsat without any assumptions. + // + // If ASSUMPTIONS_UNSAT is returned, it is possible to get a "core" of unsat + // assumptions by calling GetLastIncompatibleDecisions(). + Status ResetAndSolveWithGivenAssumptions( + const std::vector& assumptions); + Status ResetAndSolveWithGivenAssumptions( + const std::vector& assumptions, TimeLimit* time_limit); + + // Changes the assumption level. All the decisions below this level will be + // treated as assumptions by the next Solve(). Note that this may impact some + // heuristics, like the LBD value of a clause. + void SetAssumptionLevel(int assumption_level); + + // Returns the current assumption level. Note that if a solve was done since + // the last SetAssumptionLevel(), then the returned level may be lower than + // the one that was set. This is because some assumptions may now be + // consequences of others before them due to the newly learned clauses. + int AssumptionLevel() const { return assumption_level_; } + + // This can be called just after SolveWithAssumptions() returned + // ASSUMPTION_UNSAT or after EnqueueDecisionAndBacktrackOnConflict() leaded + // to a conflict. It returns a subsequence (in the correct order) of the + // previously enqueued decisions that cannot be taken together without making + // the problem UNSAT. + std::vector GetLastIncompatibleDecisions(); + + // Advanced usage. The next 3 functions allow to drive the search from outside + // the solver. + + // Takes a new decision (the given true_literal must be unassigned) and + // propagates it. Returns the trail index of the first newly propagated + // literal. If there is a conflict and the problem is detected to be UNSAT, + // returns kUnsatTrailIndex. + // + // A client can determine if there is a conflict by checking if the + // CurrentDecisionLevel() was increased by 1 or not. + // + // If there is a conflict, the given decision is not applied and: + // - The conflict is learned. + // - The decisions are potentially backtracked to the first decision that + // propagates more variables because of the newly learned conflict. + // - The returned value is equal to trail_->Index() after this backtracking + // and just before the new propagation (due to the conflict) which is also + // performed by this function. + int EnqueueDecisionAndBackjumpOnConflict(Literal true_literal); + + // This function starts by calling EnqueueDecisionAndBackjumpOnConflict(). If + // there is no conflict, it stops there. Otherwise, it tries to reapply all + // the decisions that where backjumped over until the first one that can't be + // taken because it is incompatible. Note that during this process, more + // conflicts may happen and the trail may be backtracked even further. + // + // In any case, the new decisions stack will be the largest valid "prefix" + // of the old stack. Note that decisions that are now consequence of the ones + // before them will no longer be decisions. + // + // Note(user): This function can be called with an already assigned literal, + // in which case, it will just do nothing. + int EnqueueDecisionAndBacktrackOnConflict(Literal true_literal); + + // Tries to enqueue the given decision and performs the propagation. + // Returns true if no conflict occured. Otherwise, returns false and restores + // the solver to the state just before this was called. + // + // Note(user): With this function, the solver doesn't learn anything. + bool EnqueueDecisionIfNotConflicting(Literal true_literal); + + // Restores the state to the given target decision level. The decision at that + // level and all its propagation will not be undone. But all the trail after + // this will be cleared. Calling this with 0 will revert all the decisions and + // only the fixed variables will be left on the trail. + void Backtrack(int target_level); + + // Advanced usage. This is meant to restore the solver to a "proper" state + // after a solve was interupted due to a limit reached. + // + // Without assumption (i.e. if AssumptionLevel() is 0), this will revert all + // decisions and make sure that all the fixed literals are propagated. In + // presence of assumptions, this will either backtrack to the assumption level + // or re-enqueue any assumptions that may have been backtracked over due to + // conflits resolution. In both cases, the propagation is finished. + // + // Note that this may prove the model to be UNSAT (check IsModelUnsat()). + void RestoreSolverToAssumptionLevel(); + + // Extract the current problem clauses. The Output type must support the two + // functions: + // - void AddBinaryClause(Literal a, Literal b); + // - void AddClause(ClauseRef clause); + // + // TODO(user): also copy the learned clauses? + template + void ExtractClauses(Output* out) { + CHECK(!IsModelUnsat()); + Backtrack(0); + out->SetNumVariables(NumVariables()); + + // It is important to process the newly fixed variables, so they are not + // present in the clauses we export. + if (num_processed_fixed_variables_ < trail_->Index()) { + ProcessNewlyFixedVariables(); + } + DeleteDetachedClauses(); + + // Note(user): Putting the binary clauses first help because the presolver + // currently process the clauses in order. + binary_implication_graph_.ExtractAllBinaryClauses(out); + for (SatClause* clause : clauses_) { + if (!clause->IsRedundant()) { + out->AddClause(ClauseRef(clause->begin(), clause->end())); + } + } + } + + // Functions to manage the set of learned binary clauses. + // Only clauses added/learned when TrackBinaryClause() is true are managed. + void TrackBinaryClauses(bool value) { track_binary_clauses_ = value; } + bool AddBinaryClauses(const std::vector& clauses); + const std::vector& NewlyAddedBinaryClauses(); + void ClearNewlyAddedBinaryClauses(); + + struct Decision { + Decision() : trail_index(-1) {} + Decision(int i, Literal l) : trail_index(i), literal(l) {} + int trail_index; + Literal literal; + }; + + // Note that the Decisions() vector is always of size NumVariables(), and that + // only the first CurrentDecisionLevel() entries have a meaning. + const std::vector& Decisions() const { return decisions_; } + int CurrentDecisionLevel() const { return current_decision_level_; } + const Trail& LiteralTrail() const { return *trail_; } + const VariablesAssignment& Assignment() const { return trail_->Assignment(); } + + // Some statistics since the creation of the solver. + int64 num_branches() const; + int64 num_failures() const; + int64 num_propagations() const; + + // A deterministic number that should be correlated with the time spent in + // the Solve() function. The order of magnitude should be close to the time + // in seconds. + double deterministic_time() const; + + // Only used for debugging. Save the current assignment in debug_assignment_. + // The idea is that if we know that a given assignment is satisfiable, then + // all the learned clauses or PB constraints must be satisfiable by it. In + // debug mode, and after this is called, all the learned clauses are tested to + // satisfy this saved assignement. + void SaveDebugAssignment(); + + // Returns true iff the loaded problem only contains clauses. + bool ProblemIsPureSat() const { return problem_is_pure_sat_; } + + void SetDratWriter(DratWriter* drat_writer) { drat_writer_ = drat_writer; } + + // This function is here to deal with the case where a SAT/CP model is found + // to be trivially UNSAT while the user is constructing the model. Instead of + // having to test the status of all the lines adding a constraint, one can + // just check if the solver is not UNSAT once the model is constructed. Note + // that we usually log a warning on the first constraint that caused a + // "trival" unsatisfiability. + void NotifyThatModelIsUnsat() { is_model_unsat_ = true; } + + // TODO(user): This internal function should probably not be exposed here. + void AddBinaryClauseDuringSearch(Literal a, Literal b) { + // The new clause should not propagate. + CHECK(!trail_->Assignment().LiteralIsFalse(a)); + CHECK(!trail_->Assignment().LiteralIsFalse(b)); + binary_implication_graph_.AddBinaryClauseDuringSearch(a, b, trail_); + if (binary_implication_graph_.NumberOfImplications() == 1) { + // This is needed because we just added the first binary clause. + InitializePropagators(); + } + } + + // Performs propagation of the recently enqueued elements. + // Mainly visible for testing. + bool Propagate(); + + private: + // Calls Propagate() and returns true if no conflict occured. Otherwise, + // learns the conflict, backtracks, enqueues the consequence of the learned + // conflict and returns false. + bool PropagateAndStopAfterOneConflictResolution(); + + // All Solve() functions end up calling this one. + Status SolveInternal(TimeLimit* time_limit); + + // Adds a binary clause to the BinaryImplicationGraph and to the + // BinaryClauseManager when track_binary_clauses_ is true. + void AddBinaryClauseInternal(Literal a, Literal b); + + // See SaveDebugAssignment(). Note that these functions only consider the + // variables at the time the debug_assignment_ was saved. If new variables + // where added since that time, they will be considered unassigned. + bool ClauseIsValidUnderDebugAssignement( + const std::vector& clause) const; + bool PBConstraintIsValidUnderDebugAssignment( + const std::vector& cst, const Coefficient rhs) const; + + // Logs the given status if parameters_.log_search_progress() is true. + // Also returns it. + Status StatusWithLog(Status status); + + // Main function called from SolveWithAssumptions() or from Solve() with an + // assumption_level of 0 (meaning no assumptions). + Status SolveInternal(int assumption_level); + + // Applies the previous decisions (which are still on decisions_), in order, + // starting from the one at the current decision level. Stops at the one at + // decisions_[level] or on the first decision already propagated to "false" + // and thus incompatible. + // + // Note that during this process, conflicts may arise which will lead to + // backjumps. In this case, we will simply keep reapplying decisions from the + // last one backtracked over and so on. + // + // Returns MODEL_STAT if no conflict occured, MODEL_UNSAT if the model was + // proven unsat and ASSUMPTION_UNSAT otherwise. In the last case the first non + // taken old decision will be propagated to false by the ones before. + // + // first_propagation_index will be filled with the trail index of the first + // newly propagated literal, or with -1 if MODEL_UNSAT is returned. + Status ReapplyDecisionsUpTo(int level, int* first_propagation_index); + + // Returns false if the thread memory is over the limit. + bool IsMemoryLimitReached() const; + + // Sets is_model_unsat_ to true and return false. + bool SetModelUnsat(); + + // Utility function to insert spaces proportional to the search depth. + // It is used in the pretty print of the search. + std::string Indent() const; + + // Returns the decision level of a given variable. + int DecisionLevel(BooleanVariable var) const { + return trail_->Info(var).level; + } + + // Returns the relevant pointer if the given variable was propagated by the + // constraint in question. This is used to bump the activity of the learned + // clauses or pb constraints. + SatClause* ReasonClauseOrNull(BooleanVariable var) const; + UpperBoundedLinearConstraint* ReasonPbConstraintOrNull( + BooleanVariable var) const; + + // This does one step of a pseudo-Boolean resolution: + // - The variable var has been assigned to l at a given trail_index. + // - The reason for var propagates it to l. + // - The conflict propagates it to not(l) + // The goal of the operation is to combine the two constraints in order to + // have a new conflict at a lower trail_index. + // + // Returns true if the reason for var was a normal clause. In this case, + // the *slack is updated to its new value. + bool ResolvePBConflict(BooleanVariable var, + MutableUpperBoundedLinearConstraint* conflict, + Coefficient* slack); + + // Returns true iff the clause is the reason for an assigned variable. + // + // TODO(user): With our current data structures, we could also return true + // for clauses that where just used as a reason (like just before an untrail). + // This may be beneficial, but should properly be defined so that we can + // have the same behavior if we change the implementation. + bool ClauseIsUsedAsReason(SatClause* clause) const { + const BooleanVariable var = clause->PropagatedLiteral().Variable(); + return trail_->Info(var).trail_index < trail_->Index() && + (*trail_)[trail_->Info(var).trail_index].Variable() == var && + ReasonClauseOrNull(var) == clause; + } + + // Add a problem clause. Not that the clause is assumed to be "cleaned", that + // is no duplicate variables (not strictly required) and not empty. + bool AddProblemClauseInternal(const std::vector& literals); + + // This is used by all the Add*LinearConstraint() functions. It detects + // infeasible/trivial constraints or clause constraints and takes the proper + // action. + bool AddLinearConstraintInternal(const std::vector& cst, + Coefficient rhs, Coefficient max_value); + + // Adds a learned clause to the problem. This should be called after + // Backtrack(). The backtrack is such that after it is applied, all the + // literals of the learned close except one will be false. Thus the last one + // will be implied True. This function also Enqueue() the implied literal. + void AddLearnedClauseAndEnqueueUnitPropagation( + const std::vector& literals, bool must_be_kept); + + // Creates a new decision which corresponds to setting the given literal to + // True and Enqueue() this change. + void EnqueueNewDecision(Literal literal); + + // Returns true if everything has been propagated. + // + // TODO(user): This test is fast but not exhaustive, especially regarding the + // integer propagators. Fix. + bool PropagationIsDone() const; + + // Update the propagators_ list with the relevant propagators. + void InitializePropagators(); + + // Asks for the next decision to branch upon. This shouldn't be called if + // there is no active variable (i.e. unassigned variable). + Literal NextBranch(); + + // Unrolls the trail until a given point. This unassign the assigned variables + // and add them to the priority queue with the correct weight. + void Untrail(int target_trail_index); + + // Deletes all the clauses that are detached. + void DeleteDetachedClauses(); + + // Simplifies the problem when new variables are assigned at level 0. + void ProcessNewlyFixedVariables(); + + // Compute an initial variable ordering. + void InitializeVariableOrdering(); + + // Returns the maximum trail_index of the literals in the given clause. + // All the literals must be assigned. Returns -1 if the clause is empty. + int ComputeMaxTrailIndex(ClauseRef clause) const; + + // Computes what is known as the first UIP (Unique implication point) conflict + // clause starting from the failing clause. For a definition of UIP and a + // comparison of the different possible conflict clause computation, see the + // reference below. + // + // The conflict will have only one literal at the highest decision level, and + // this literal will always be the first in the conflict vector. + // + // L Zhang, CF Madigan, MH Moskewicz, S Malik, "Efficient conflict driven + // learning in a boolean satisfiability solver" Proceedings of the 2001 + // IEEE/ACM international conference on Computer-aided design, Pages 279-285. + // http://www.cs.tau.ac.il/~msagiv/courses/ATP/iccad2001_final.pdf + void ComputeFirstUIPConflict( + int max_trail_index, std::vector* conflict, + std::vector* reason_used_to_infer_the_conflict, + std::vector* subsumed_clauses); + + // Fills literals with all the literals in the reasons of the literals in the + // given input. The output vector will have no duplicates and will not contain + // the literals already present in the input. + void ComputeUnionOfReasons(const std::vector& input, + std::vector* literals); + + // Given an assumption (i.e. literal) currently assigned to false, this will + // returns the set of all assumptions that caused this particular assignment. + // + // This is useful to get a small set of assumptions that can't be all + // satisfied together. + void FillUnsatAssumptions(Literal false_assumption, + std::vector* unsat_assumptions); + + // Do the full pseudo-Boolean constraint analysis. This calls multiple + // time ResolvePBConflict() on the current conflict until we have a conflict + // that allow us to propagate more at a lower decision level. This level + // is the one returned in backjump_level. + void ComputePBConflict(int max_trail_index, Coefficient initial_slack, + MutableUpperBoundedLinearConstraint* conflict, + int* backjump_level); + + // Applies some heuristics to a conflict in order to minimize its size and/or + // replace literals by other literals from lower decision levels. The first + // function choose which one of the other functions to call depending on the + // parameters. + // + // Precondidtion: is_marked_ should be set to true for all the variables of + // the conflict. It can also contains false non-conflict variables that + // are implied by the negation of the 1-UIP conflict literal. + void MinimizeConflict( + std::vector* conflict, + std::vector* reason_used_to_infer_the_conflict); + void MinimizeConflictExperimental(std::vector* conflict); + void MinimizeConflictSimple(std::vector* conflict); + void MinimizeConflictRecursively(std::vector* conflict); + + // Utility function used by MinimizeConflictRecursively(). + bool CanBeInferedFromConflictVariables(BooleanVariable variable); + + // To be used in DCHECK(). Verifies some property of the conflict clause: + // - There is an unique literal with the highest decision level. + // - This literal appears in the first position. + // - All the other literals are of smaller decision level. + // - Ther is no literal with a decision level of zero. + bool IsConflictValid(const std::vector& literals); + + // Given the learned clause after a conflict, this computes the correct + // backtrack level to call Backtrack() with. + int ComputeBacktrackLevel(const std::vector& literals); + + // The LBD (Literal Blocks Distance) is the number of different decision + // levels at which the literals of the clause were assigned. Note that we + // ignore the decision level 0 whereas the definition in the paper below + // doesn't: + // + // G. Audemard, L. Simon, "Predicting Learnt Clauses Quality in Modern SAT + // Solver" in Twenty-first International Joint Conference on Artificial + // Intelligence (IJCAI'09), july 2009. + // http://www.ijcai.org/papers09/Papers/IJCAI09-074.pdf + // + // IMPORTANT: All the literals of the clause must be assigned, and the first + // literal must be of the highest decision level. This will be the case for + // all the reason clauses. + template + int ComputeLbd(const LiteralList& literals); + + // Checks if we need to reduce the number of learned clauses and do + // it if needed. Also updates the learned clause limit for the next cleanup. + void CleanClauseDatabaseIfNeeded(); + + // Bumps the activity of all variables appearing in the conflict. + // See VSIDS decision heuristic: Chaff: Engineering an Efficient SAT Solver. + // M.W. Moskewicz et al. ANNUAL ACM IEEE DESIGN AUTOMATION CONFERENCE 2001. + // + // The second argument implements the Glucose strategy to reward good + // variables. Variables from the last decision level and with a reason of LBD + // lower than this limit and learned are bumped twice. Note that setting + // bump_again_lbd_limit to 0 disable this feature. + void BumpVariableActivities(const std::vector& literals, + int bump_again_lbd_limit); + + // Rescales activity value of all variables when one of them reached the max. + void RescaleVariableActivities(double scaling_factor); + + // Updates the increment used for activity bumps. This is basically the same + // as decaying all the variable activities, but it is a lot more efficient. + void UpdateVariableActivityIncrement(); + + // Activity managment for clauses. This work the same way at the ones for + // variables, but with different parameters. + void BumpReasonActivities(const std::vector& literals); + void BumpClauseActivity(SatClause* clause); + void RescaleClauseActivities(double scaling_factor); + void UpdateClauseActivityIncrement(); + + // Reinitializes the polarity of all the variables with an index greater than + // or equal to the given one. + void ResetPolarity(BooleanVariable from); + + // Init restart period. + void InitRestart(); + + std::string DebugString(const SatClause& clause) const; + std::string StatusString(Status status) const; + std::string RunningStatisticsString() const; + + BooleanVariable num_variables_; + + // All the clauses managed by the solver (initial and learned). This vector + // has ownership of the pointers. We currently do not use + // std::unique_ptr because it can't be used with some STL + // algorithms like std::partition. + // + // Note that the unit clauses are not kept here and if the parameter + // treat_binary_clauses_separately is true, the binary clause are not kept + // here either. + std::vector clauses_; + + // Clause information used for the clause database management. + // Note that only the clauses that can be removed need to appear here. + struct ClauseInfo { + double activity = 0.0; + int32 lbd = 0; + bool protected_during_next_cleanup = false; + }; + std::unordered_map clauses_info_; + + // Internal propagators. We keep them here because we need more than the + // SatPropagator interface for them. + LiteralWatchers clauses_propagator_; + BinaryImplicationGraph binary_implication_graph_; + PbConstraints pb_constraints_; + + // Ordered list of propagators used by Propagate()/Untrail(). + std::vector propagators_; + + // Ordered list of propagators added with AddPropagator(). + std::vector> external_propagators_; + std::unique_ptr last_propagator_; + + // Keep track of all binary clauses so they can be exported. + bool track_binary_clauses_; + BinaryClauseManager binary_clauses_; + + // The solver trail. + Trail* trail_; + + // This is used by the non-model constructor to properly cleanup trail_. + std::unique_ptr owned_trail_; + + // Used for debugging only. See SaveDebugAssignment(). + VariablesAssignment debug_assignment_; + + // The stack of decisions taken by the solver. They are stored in [0, + // current_decision_level_). The vector is of size num_variables_ so it can + // store all the decisions. This is done this way because in some situation we + // need to remember the previously taken decisions after a backtrack. + int current_decision_level_; + std::vector decisions_; + + // The trail index after the last Backtrack() call or before the last + // EnqueueNewDecision() call. + int last_decision_or_backtrack_trail_index_; + + // The assumption level. See SolveWithAssumptions(). + int assumption_level_; + + // The size of the trail when ProcessNewlyFixedVariables() was last called. + // Note that the trail contains only fixed literals (that is literals of + // decision levels 0) before this point. + int num_processed_fixed_variables_; + double deterministic_time_of_last_fixed_variables_cleanup_; + + // Tracks various information about the solver progress. + struct Counters { + int64 num_branches; + int64 num_random_branches; + int64 num_failures; + + // Minimization stats. + int64 num_minimizations; + int64 num_literals_removed; + + // PB constraints. + int64 num_learned_pb_literals_; + + // Clause learning /deletion stats. + int64 num_literals_learned; + int64 num_literals_forgotten; + int64 num_subsumed_clauses; + + Counters() + : num_branches(0), + num_random_branches(0), + num_failures(0), + num_minimizations(0), + num_literals_removed(0), + num_learned_pb_literals_(0), + num_literals_learned(0), + num_literals_forgotten(0), + num_subsumed_clauses(0) {} + }; + Counters counters_; + + // Solver information. + WallTimer timer_; + + // This is set to true if the model is found to be UNSAT when adding new + // constraints. + bool is_model_unsat_; + + // Parameters. + SatParameters parameters_; + + // Variable ordering (priority will be adjusted dynamically). queue_elements_ + // holds the elements used by var_ordering_ (it uses pointers). + // + // Note that we recover the variable that a WeightedVarQueueElement refers to + // by its position in the queue_elements_ vector, and we can recover the later + // using (pointer - &queue_elements_[0]). + struct WeightedVarQueueElement { + WeightedVarQueueElement() : heap_index(-1), tie_breaker(0.0), weight(0.0) {} + + // Interface for the AdjustablePriorityQueue. + void SetHeapIndex(int h) { heap_index = h; } + int GetHeapIndex() const { return heap_index; } + + // Priority order. The AdjustablePriorityQueue returns the largest element + // first. + // + // Note(user): We used to also break ties using the variable index, however + // this has two drawbacks: + // - On problem with many variables, this slow down quite a lot the priority + // queue operations (which do as little work as possible and hence benefit + // from having the majority of elements with a priority of 0). + // - It seems to be a bad heuristics. One reason could be that the priority + // queue will automatically diversify the choice of the top variables + // amongst the ones with the same priority. + // + // Note(user): For the same reason as explained above, it is probably a good + // idea not to have too many different values for the tie_breaker field. I + // am not even sure we should have such a field... + bool operator<(const WeightedVarQueueElement& other) const { + return weight < other.weight || + (weight == other.weight && (tie_breaker < other.tie_breaker)); + } + + int32 heap_index; + float tie_breaker; + + // TODO(user): Experiment with float. In the rest of the code, we use + // double, but maybe we don't need that much precision. Using float here may + // save memory and make the PQ operations faster. + double weight; + }; + COMPILE_ASSERT(sizeof(WeightedVarQueueElement) == 16, + ERROR_WeightedVarQueueElement_is_not_well_compacted); + + bool var_ordering_is_initialized_; + AdjustablePriorityQueue var_ordering_; + ITIVector queue_elements_; + + // This is used for the branching heuristic described in "Learning Rate Based + // Branching Heuristic for SAT solvers", J.H.Liang, V. Ganesh, P. Poupart, + // K.Czarnecki, SAT 2016. + // + // The entries are sorted by trail index, and one can get the number of + // conflicts during which a variable at a given trail index i was assigned by + // summing the entry.count for all entries with a trail index greater than i. + struct NumConflictsStackEntry { + int trail_index; + int64 count; + }; + std::vector num_conflicts_stack_; + + // Whether the priority of the given variable needs to be updated in + // var_ordering_. Note that this is only accessed for assigned variables and + // that for efficiency it is indexed by trail indices. If + // pq_need_update_for_var_at_trail_index_[trail_->Info(var).trail_index] is + // true when we untrail var, then either var need to be inserted in the queue, + // or we need to notify that its priority has changed. + BitQueue64 pq_need_update_for_var_at_trail_index_; + + // Increment used to bump the variable activities. + double variable_activity_increment_; + double clause_activity_increment_; + + // Stores variable activity and the number of time each variable was "bumped". + // The later is only used with the ERWA heuristic. + ITIVector activities_; + ITIVector num_bumps_; + + // Used by NextBranch() to choose the polarity of the next decision. For the + // phase saving, the last polarity is stored in trail_->Info(var). + bool decision_heuristic_is_initialized_; + ITIVector var_use_phase_saving_; + ITIVector var_polarity_; + ITIVector weighted_sign_; + + // If true, leave the initial variable activities to their current value. + bool leave_initial_activities_unchanged_; + + // This counter is decremented each time we learn a clause that can be + // deleted. When it reaches zero, a clause cleanup is triggered. + int num_learned_clause_before_cleanup_; + + // Conflicts credit to create until the next restart. + int conflicts_until_next_restart_; + int restart_count_; + int luby_count_; + + // Conflicts credit until the next strategy change. + int conflicts_until_next_strategy_change_; + int strategy_change_conflicts_; + int strategy_counter_; + + // Temporary members used during conflict analysis. + SparseBitset is_marked_; + SparseBitset is_independent_; + SparseBitset tmp_mark_; + std::vector min_trail_index_per_level_; + + // Temporary members used by CanBeInferedFromConflictVariables(). + std::vector dfs_stack_; + std::vector variable_to_process_; + + // Temporary member used by AddLinearConstraintInternal(). + std::vector literals_scratchpad_; + + // A boolean vector used to temporarily mark decision levels. + DEFINE_INT_TYPE(SatDecisionLevel, int); + SparseBitset is_level_marked_; + + // Temporary vectors used by EnqueueDecisionAndBackjumpOnConflict(). + std::vector learned_conflict_; + std::vector reason_used_to_infer_the_conflict_; + std::vector extra_reason_literals_; + std::vector subsumed_clauses_; + + // "cache" to avoid inspecting many times the same reason during conflict + // analysis. + VariableWithSameReasonIdentifier same_reason_identifier_; + + // A random number generator. + mutable MTRandom random_; + + // Temporary vector used by AddProblemClause(). + std::vector tmp_pb_constraint_; + + // Boolean used to include/exclude constraints from the core computation. + bool is_relevant_for_core_computation_; + + // The current pseudo-Boolean conflict used in PB conflict analysis. + MutableUpperBoundedLinearConstraint pb_conflict_; + + // Running average used by some restart algorithms. + RunningAverage dl_running_average_; + RunningAverage lbd_running_average_; + RunningAverage trail_size_running_average_; + + // The solver time limit. + std::unique_ptr time_limit_; + + // The deterministic time when the time limit was updated. + // As the deterministic time in the time limit has to be advanced manually, + // it is necessary to keep track of the last time the time was advanced. + double deterministic_time_at_last_advanced_time_limit_; + + // This is true iff the loaded problem only contains clauses. + bool problem_is_pure_sat_; + + DratWriter* drat_writer_; + + mutable StatsGroup stats_; + DISALLOW_COPY_AND_ASSIGN(SatSolver); +}; + +// Returns the ith element of the strategy S^univ proposed by M. Luby et al. in +// Optimal Speedup of Las Vegas Algorithms, Information Processing Letters 1993. +// This is used to decide the number of conflicts allowed before the next +// restart. This method, used by most SAT solvers, is usually referenced as +// Luby. +// Returns 2^{k-1} when i == 2^k - 1 +// and SUniv(i - 2^{k-1} + 1) when 2^{k-1} <= i < 2^k - 1. +// The sequence is defined for i > 0 and starts with: +// {1, 1, 2, 1, 1, 2, 4, 1, 1, 2, 1, 1, 2, 4, 8, ...} +inline int SUniv(int i) { + DCHECK_GT(i, 0); + while (i > 2) { + const int most_significant_bit_position = + MostSignificantBitPosition64(i + 1); + if ((1 << most_significant_bit_position) == i + 1) { + return 1 << (most_significant_bit_position - 1); + } + i -= (1 << most_significant_bit_position) - 1; + } + return 1; +} + +// ============================================================================ +// Model based functions. +// +// TODO(user): move them in another file, and unit-test them. +// ============================================================================ + +inline std::function BooleanLinearConstraint( + int64 lower_bound, int64 upper_bound, std::vector* cst) { + return [=](Model* model) { + model->GetOrCreate()->AddLinearConstraint( + /*use_lower_bound=*/true, Coefficient(lower_bound), + /*use_upper_bound=*/true, Coefficient(upper_bound), cst); + }; +} + +inline std::function CardinalityConstraint( + int64 lower_bound, int64 upper_bound, + const std::vector& literals) { + return [=](Model* model) { + std::vector cst(literals.size()); + for (int i = 0; i < literals.size(); ++i) { + cst[i] = LiteralWithCoeff(literals[i], 1); + } + model->GetOrCreate()->AddLinearConstraint( + /*use_lower_bound=*/true, Coefficient(lower_bound), + /*use_upper_bound=*/true, Coefficient(upper_bound), &cst); + }; +} + +inline std::function ExactlyOneConstraint( + const std::vector& literals) { + return [=](Model* model) { + std::vector cst; + for (const Literal l : literals) { + cst.push_back(LiteralWithCoeff(l, Coefficient(1))); + } + model->GetOrCreate()->AddLinearConstraint( + /*use_lower_bound=*/true, Coefficient(1), + /*use_upper_bound=*/true, Coefficient(1), &cst); + }; +} + +inline std::function AtMostOneConstraint( + const std::vector& literals) { + return [=](Model* model) { + std::vector cst; + for (const Literal l : literals) { + cst.push_back(LiteralWithCoeff(l, Coefficient(1))); + } + model->GetOrCreate()->AddLinearConstraint( + /*use_lower_bound=*/false, Coefficient(0), + /*use_upper_bound=*/true, Coefficient(1), &cst); + }; +} + +inline std::function ClauseConstraint( + const std::vector& literals) { + return [=](Model* model) { + std::vector cst; + for (const Literal l : literals) { + cst.push_back(LiteralWithCoeff(l, Coefficient(1))); + } + model->GetOrCreate()->AddLinearConstraint( + /*use_lower_bound=*/true, Coefficient(1), + /*use_upper_bound=*/false, Coefficient(1), &cst); + }; +} + +// a => b. +inline std::function Implication(Literal a, Literal b) { + return [=](Model* model) { + model->GetOrCreate()->AddBinaryClause(a.Negated(), b); + }; +} + +// a == b. +inline std::function Equality(Literal a, Literal b) { + return [=](Model* model) { + model->GetOrCreate()->AddBinaryClause(a.Negated(), b); + model->GetOrCreate()->AddBinaryClause(a, b.Negated()); + }; +} + +// r <=> (at least one literal is true). This is a reified clause. +inline std::function ReifiedBoolOr( + const std::vector& literals, Literal r) { + return [=](Model* model) { + std::vector clause; + for (const Literal l : literals) { + model->Add(Implication(l, r)); // l => r. + clause.push_back(l); + } + + // All false => r false. + clause.push_back(r.Negated()); + model->Add(ClauseConstraint(clause)); + }; +} + +// r <=> (all literals are true). +// +// Note(user): we could have called ReifiedBoolOr() with everything negated. +inline std::function ReifiedBoolAnd( + const std::vector& literals, Literal r) { + return [=](Model* model) { + std::vector clause; + for (const Literal l : literals) { + model->Add(Implication(r, l)); // r => l. + clause.push_back(l.Negated()); + } + + // All true => r true. + clause.push_back(r); + model->Add(ClauseConstraint(clause)); + }; +} + +// r <=> (a <= b). +inline std::function ReifiedBoolLe(Literal a, Literal b, + Literal r) { + return [=](Model* model) { + // r <=> (a <= b) is the same as r <=> not(a=1 and b=0). + // So r <=> a=0 OR b=1. + model->Add(ReifiedBoolOr({a.Negated(), b}, r)); + }; +} + +// This checks that the variable is fixed. +inline std::function Value(Literal l) { + return [=](const Model& model) { + const Trail* trail = model.Get(); + CHECK(trail->Assignment().VariableIsAssigned(l.Variable())); + return trail->Assignment().LiteralIsTrue(l); + }; +} + +// This checks that the variable is fixed. +inline std::function Value(BooleanVariable b) { + return [=](const Model& model) { + const Trail* trail = model.Get(); + CHECK(trail->Assignment().VariableIsAssigned(b)); + return trail->Assignment().LiteralIsTrue(Literal(b, true)); + }; +} + +// This can be used to enumerate all the solutions. After each SAT call to +// Solve(), calling this will reset the solver and exclude the current solution +// so that the next call to Solve() will give a new solution or UNSAT is there +// is no more new solutions. +inline std::function ExcludeCurrentSolutionAndBacktrack() { + return [=](Model* model) { + SatSolver* sat_solver = model->GetOrCreate(); + + // Note that we only exclude the current decisions, which is an efficient + // way to not get the same SAT assignment. + const int current_level = sat_solver->CurrentDecisionLevel(); + std::vector clause_to_exclude_solution; + clause_to_exclude_solution.reserve(current_level); + for (int i = 0; i < current_level; ++i) { + clause_to_exclude_solution.push_back( + sat_solver->Decisions()[i].literal.Negated()); + } + sat_solver->Backtrack(0); + model->Add(ClauseConstraint(clause_to_exclude_solution)); + }; +} + +inline std::function NewSatParameters( + const std::string& params) { + return [=](Model* model) { + sat::SatParameters parameters; + if (!params.empty()) { + CHECK(google::protobuf::TextFormat::ParseFromString(params, ¶meters)) << params; + model->GetOrCreate()->SetParameters(parameters); + model->SetSingleton(TimeLimit::FromParameters(parameters)); + } + return parameters; + }; +} + +inline std::function NewSatParameters( + const sat::SatParameters& parameters) { + return [=](Model* model) { + model->GetOrCreate()->SetParameters(parameters); + model->SetSingleton(TimeLimit::FromParameters(parameters)); + return parameters; + }; +} + +// Returns a std::string representation of a SatSolver::Status. +std::string SatStatusString(SatSolver::Status status); +inline std::ostream& operator<<(std::ostream& os, SatSolver::Status status) { + os << SatStatusString(status); + return os; +} + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_SAT_SOLVER_H_ diff --git a/thirdparty/linux/include/ortools/sat/simplification.h b/thirdparty/linux/include/ortools/sat/simplification.h new file mode 100644 index 0000000..76d8940 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/simplification.h @@ -0,0 +1,380 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Implementation of a pure SAT presolver. This roughly follows the paper: +// +// "Effective Preprocessing in SAT through Variable and Clause Elimination", +// Niklas Een and Armin Biere, published in the SAT 2005 proceedings. + +#ifndef OR_TOOLS_SAT_SIMPLIFICATION_H_ +#define OR_TOOLS_SAT_SIMPLIFICATION_H_ + +#include +#include + +#include "ortools/sat/drat.h" +#include "ortools/sat/sat_base.h" +#include "ortools/sat/sat_parameters.pb.h" +#include "ortools/sat/sat_solver.h" + +#include "ortools/base/adjustable_priority_queue.h" + +namespace operations_research { +namespace sat { + +// A simple sat postsolver. +// +// The idea is that any presolve algorithm can just update this class, and at +// the end, this class will recover a solution of the initial problem from a +// solution of the presolved problem. +class SatPostsolver { + public: + explicit SatPostsolver(int num_variables); + + // The postsolver will process the Add() calls in reverse order. If the given + // clause has all its literals at false, it simply sets the literal x to true. + // Note that x must be a literal of the given clause. + void Add(Literal x, const std::vector& clause); + + // Tells the postsolver that the given literal must be true in any solution. + // We currently check that the variable is not already fixed. + void FixVariable(Literal x); + + // This assumes that the given variable mapping has been applied to the + // problem. All the subsequent Add() and FixVariable() will refer to the new + // problem. During postsolve, the initial solution must also correspond to + // this new problem. Note that if mapping[v] == -1, then the literal v is + // assumed to be deleted. + // + // This can be called more than once. But each call must refer to the current + // variables set (after all the previous mapping have been applied). + void ApplyMapping(const ITIVector& mapping); + + // Extracts the current assignment of the given solver and postsolve it. + // + // Node(fdid): This can currently be called only once (but this is easy to + // change since only some CHECK will fail). + std::vector ExtractAndPostsolveSolution(const SatSolver& solver); + std::vector PostsolveSolution(const std::vector& solution); + + private: + Literal ApplyReverseMapping(Literal l); + void Postsolve(VariablesAssignment* assignment) const; + + // The presolve can add new variables, so we need to store the number of + // original variables in order to return a solution with the correct number + // of variables. + const int initial_num_variables_; + int num_variables_; + + // Stores the arguments of the Add() calls: clauses_start_[i] is the index of + // the first literal of the clause #i in the clauses_literals_ deque. + std::vector clauses_start_; + std::deque clauses_literals_; + std::vector associated_literal_; + + // All the added clauses will be mapped back to the initial variables using + // this reverse mapping. This way, clauses_ and associated_literal_ are only + // in term of the initial problem. + ITIVector reverse_mapping_; + + // This will stores the fixed variables value and later the postsolved + // assignment. + VariablesAssignment assignment_; + + DISALLOW_COPY_AND_ASSIGN(SatPostsolver); +}; + +// This class holds a SAT problem (i.e. a set of clauses) and the logic to +// presolve it by a series of subsumption, self-subsuming resolution, and +// variable elimination by clause distribution. +// +// Note that this does propagate unit-clauses, but probably much +// less efficiently than the propagation code in the SAT solver. So it is better +// to use a SAT solver to fix variables before using this class. +// +// TODO(user): Interact more with a SAT solver to reuse its propagation logic. +// +// TODO(user): Forbid the removal of some variables. This way we can presolve +// only the clause part of a general Boolean problem by not removing variables +// appearing in pseudo-Boolean constraints. +class SatPresolver { + public: + // TODO(user): use IntType? not sure because that complexify the code, and + // it is not really needed here. + typedef int32 ClauseIndex; + + explicit SatPresolver(SatPostsolver* postsolver) + : postsolver_(postsolver), + num_trivial_clauses_(0), + drat_writer_(nullptr) {} + void SetParameters(const SatParameters& params) { parameters_ = params; } + + // Registers a mapping to encode equivalent literals. + // See ProbeAndFindEquivalentLiteral(). + void SetEquivalentLiteralMapping( + const ITIVector& mapping) { + equiv_mapping_ = mapping; + } + + // Adds new clause to the SatPresolver. + void SetNumVariables(int num_variables); + void AddBinaryClause(Literal a, Literal b); + void AddClause(ClauseRef clause); + + // Presolves the problem currently loaded. Returns false if the model is + // proven to be UNSAT during the presolving. + // + // TODO(user): Add support for a time limit and some kind of iterations limit + // so that this can never take too much time. + bool Presolve(); + + // All the clauses managed by this class. + // Note that deleted clauses keep their indices (they are just empty). + int NumClauses() const { return clauses_.size(); } + const std::vector& Clause(ClauseIndex ci) const { + return clauses_[ci]; + } + + // The number of variables. This is computed automatically from the clauses + // added to the SatPresolver. + int NumVariables() const { return literal_to_clause_sizes_.size() / 2; } + + // After presolving, Some variables in [0, NumVariables()) have no longer any + // clause pointing to them. This return a mapping that maps this interval to + // [0, new_size) such that now all variables are used. The unused variable + // will be mapped to BooleanVariable(-1). + ITIVector VariableMapping() const; + + // Loads the current presolved problem in to the given sat solver. + // Note that the variables will be re-indexed according to the mapping given + // by GetMapping() so that they form a dense set. + // + // IMPORTANT: This is not const because it deletes the presolver clauses as + // they are added to the SatSolver in order to save memory. After this is + // called, only VariableMapping() will still works. + void LoadProblemIntoSatSolver(SatSolver* solver); + + // Visible for Testing. Takes a given clause index and looks for clause that + // can be subsumed or strengthened using this clause. Returns false if the + // model is proven to be unsat. + bool ProcessClauseToSimplifyOthers(ClauseIndex clause_index); + + // Visible for testing. Tries to eliminate x by clause distribution. + // This is also known as bounded variable elimination. + // + // It is always possible to remove x by resolving each clause containing x + // with all the clauses containing not(x). Hence the cross-product name. Note + // that this function only do that if the number of clauses is reduced. + bool CrossProduct(Literal x); + + // Visible for testing. Just applies the BVA step of the presolve. + void PresolveWithBva(); + + void SetDratWriter(DratWriter* drat_writer) { drat_writer_ = drat_writer; } + + private: + // Internal function to add clauses generated during the presolve. The clause + // must already be sorted with the default Literal order and will be cleared + // after this call. + void AddClauseInternal(std::vector* clause); + + // Clause removal function. + void Remove(ClauseIndex ci); + void RemoveAndRegisterForPostsolve(ClauseIndex ci, Literal x); + void RemoveAndRegisterForPostsolveAllClauseContaining(Literal x); + + // Call ProcessClauseToSimplifyOthers() on all the clauses in + // clause_to_process_ and empty the list afterwards. Note that while some + // clauses are processed, new ones may be added to the list. Returns false if + // the problem is shown to be UNSAT. + bool ProcessAllClauses(); + + // Finds the literal from the clause that occur the less in the clause + // database. + Literal FindLiteralWithShortestOccurenceList( + const std::vector& clause); + LiteralIndex FindLiteralWithShortestOccurenceListExcluding( + const std::vector& clause, Literal to_exclude); + + // Tests and maybe perform a Simple Bounded Variable addition starting from + // the given literal as described in the paper: "Automated Reencoding of + // Boolean Formulas", Norbert Manthey, Marijn J. H. Heule, and Armin Biere, + // Volume 7857 of the series Lecture Notes in Computer Science pp 102-117, + // 2013. + // https://www.research.ibm.com/haifa/conferences/hvc2012/papers/paper16.pdf + // + // This seems to have a mostly postive effect, except on the crafted problem + // familly mugrauer_balint--GI.crafted_nxx_d6_cx_numxx where the reduction + // is big, but apparently the problem is harder to prove UNSAT for the solver. + void SimpleBva(LiteralIndex l); + + // Display some statistics on the current clause database. + void DisplayStats(double elapsed_seconds); + + // The "active" variables on which we want to call CrossProduct() are kept + // in a priority queue so that we process first the ones that occur the least + // often in the clause database. + void InitializePriorityQueue(); + void UpdatePriorityQueue(BooleanVariable var); + struct PQElement { + PQElement() : heap_index(-1), variable(-1), weight(0.0) {} + + // Interface for the AdjustablePriorityQueue. + void SetHeapIndex(int h) { heap_index = h; } + int GetHeapIndex() const { return heap_index; } + + // Priority order. The AdjustablePriorityQueue returns the largest element + // first, but our weight goes this other way around (smaller is better). + bool operator<(const PQElement& other) const { + return weight > other.weight; + } + + int heap_index; + BooleanVariable variable; + double weight; + }; + ITIVector var_pq_elements_; + AdjustablePriorityQueue var_pq_; + + // Literal priority queue for BVA. The literals are ordered by descending + // number of occurences in clauses. + void InitializeBvaPriorityQueue(); + void UpdateBvaPriorityQueue(LiteralIndex var); + void AddToBvaPriorityQueue(LiteralIndex var); + struct BvaPqElement { + BvaPqElement() : heap_index(-1), literal(-1), weight(0.0) {} + + // Interface for the AdjustablePriorityQueue. + void SetHeapIndex(int h) { heap_index = h; } + int GetHeapIndex() const { return heap_index; } + + // Priority order. + // The AdjustablePriorityQueue returns the largest element first. + bool operator<(const BvaPqElement& other) const { + return weight < other.weight; + } + + int heap_index; + LiteralIndex literal; + double weight; + }; + std::deque bva_pq_elements_; // deque because we add variables. + AdjustablePriorityQueue bva_pq_; + + // Temporary data for SimpleBva(). + std::set m_lit_; + std::vector m_cls_; + std::unordered_map> p_; + std::vector tmp_new_clause_; + + // List of clauses on which we need to call ProcessClauseToSimplifyOthers(). + // See ProcessAllClauses(). + std::vector in_clause_to_process_; + std::deque clause_to_process_; + + // The set of all clauses. + // An empty clause means that it has been removed. + std::vector> clauses_; // Indexed by ClauseIndex + + // Occurence list. For each literal, contains the ClauseIndex of the clause + // that contains it (ordered by clause index). + ITIVector> literal_to_clauses_; + + // Because we only lazily clean the occurence list after clause deletions, + // we keep the size of the occurence list (without the deleted clause) here. + ITIVector literal_to_clause_sizes_; + + // Used for postsolve. + SatPostsolver* postsolver_; + + // Equivalent literal mapping. + ITIVector equiv_mapping_; + + int num_trivial_clauses_; + SatParameters parameters_; + DratWriter* drat_writer_; + + DISALLOW_COPY_AND_ASSIGN(SatPresolver); +}; + +// Visible for testing. Returns true iff: +// - a subsume b (subsumption): the clause a is a subset of b, in which case +// opposite_literal is set to -1. +// - b is strengthened by self-subsumption using a (self-subsuming resolution): +// the clause a with one of its literal negated is a subset of b, in which +// case opposite_literal is set to this negated literal index. Moreover, this +// opposite_literal is then removed from b. +bool SimplifyClause(const std::vector& a, std::vector* b, + LiteralIndex* opposite_literal); + +// Visible for testing. Returns kNoLiteralIndex except if: +// - a and b differ in only one literal. +// - For a it is the given literal l. +// In which case, returns the LiteralIndex of the literal in b that is not in a. +LiteralIndex DifferAtGivenLiteral(const std::vector& a, + const std::vector& b, Literal l); + +// Visible for testing. Computes the resolvant of 'a' and 'b' obtained by +// performing the resolution on 'x'. If the resolvant is trivially true this +// returns false, otherwise it returns true and fill 'out' with the resolvant. +// +// Note that the resolvant is just 'a' union 'b' with the literals 'x' and +// not(x) removed. The two clauses are assumed to be sorted, and the computed +// resolvant will also be sorted. +// +// This is the basic operation when a variable is eliminated by clause +// distribution. +bool ComputeResolvant(Literal x, const std::vector& a, + const std::vector& b, std::vector* out); + +// Same as ComputeResolvant() but just returns the resolvant size. +// Returns -1 when ComputeResolvant() returns false. +int ComputeResolvantSize(Literal x, const std::vector& a, + const std::vector& b); + +// Presolver that does literals probing and finds equivalent literals by +// computing the strongly connected components of the graph: +// literal l -> literals propagated by l. +// +// Clears the mapping if there are no equivalent literals. Otherwise, mapping[l] +// is the representative of the equivalent class of l. Note that mapping[l] may +// be equal to l. +// +// The postsolver will be updated so it can recover a solution of the mapped +// problem. Note that this works on any problem the SatSolver can handle, not +// only pure SAT problem, but the returned mapping do need to be applied to all +// constraints. +void ProbeAndFindEquivalentLiteral( + SatSolver* solver, SatPostsolver* postsolver, DratWriter* drat_writer, + ITIVector* mapping); + +// Given a 'solver' with a problem already loaded, this will try to simplify the +// problem (i.e. presolve it) before calling solver->Solve(). In the process, +// because of the way the presolve is implemented, the underlying SatSolver may +// change (it is why we use this unique_ptr interface). In particular, the final +// variables and 'solver' state may have nothing to do with the problem +// originaly present in the solver. That said, if the problem is shown to be +// SAT, then the returned solution will be in term of the original variables. +// +// Note that the full presolve is only executed if the problem is a pure SAT +// problem with only clauses. +SatSolver::Status SolveWithPresolve( + std::unique_ptr* solver, + std::vector* solution /* only filled if SAT */, + DratWriter* drat_writer /* can be nullptr */); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_SIMPLIFICATION_H_ diff --git a/thirdparty/linux/include/ortools/sat/symmetry.h b/thirdparty/linux/include/ortools/sat/symmetry.h new file mode 100644 index 0000000..977ed82 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/symmetry.h @@ -0,0 +1,154 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_SYMMETRY_H_ +#define OR_TOOLS_SAT_SYMMETRY_H_ + +#include "ortools/algorithms/sparse_permutation.h" +#include "ortools/sat/sat_base.h" +#include "ortools/util/stats.h" + +namespace operations_research { +namespace sat { + +// This class implements more or less the strategy described in the paper: +// Devriendt J., Bogaerts B., De Cat B., Denecker M., Mears C. "Symmetry +// propagation: Improved Dynamic Symmetry Breaking in SAT", 2012, +// IEEE 24th International Conference on Tools with Artificial Intelligence. +// +// Basically, each time a literal is propagated, this class tries to detect +// if another literal could also be propagated by symmetry. Note that this uses +// a heuristic in order to be efficient and that it is not exhaustive in the +// sense that it doesn't detect all possible propagations. +// +// Algorithm details: +// +// Given the current solver trail (i.e. the assigned literals and their +// assignment order) the idea is to compute (as efficiently as possible) for +// each permutation added to this class what is called the first (under the +// trail assignment order) non-symmetric literal. A literal 'l' is said to be +// non-symmetric under a given assignement and for a given permutation 'p' if +// 'l' is assigned to true but not 'p(l)'. +// +// If a first non-symmetric literal 'l' for a permutation 'p' is not a decision, +// then: +// - Because it is not a decision, 'l' has been implied by a reason formed by +// literals assigned to true at lower trail indices. +// - Because this is the first non-symmetric literal for 'p', the permuted +// reason only contains literal that are also assigned to true. +// - Because of this, 'p(l)' is also implied by the current assignment. +// Of course, this assume that p is a symmetry of the full problem. +// Note that if it is already assigned to false, then we have a conflict. +// +// TODO(user): Implement the optimizations mentioned in the paper? +// TODO(user): Instrument and see if the code can be optimized. +class SymmetryPropagator : public SatPropagator { + public: + SymmetryPropagator(); + ~SymmetryPropagator() override; + + bool Propagate(Trail* trail) final; + void Untrail(const Trail& trail, int trail_index) final; + ClauseRef Reason(const Trail& trail, int trail_index) const final; + + // Adds a new permutation to this symmetry propagator. The ownership is + // transfered. This must be an integer permutation such that: + // - Its domain is [0, 2 * num_variables) and corresponds to the index + // representation of the literals over num_variables variables. + // - It must be compatible with the negation, for any literal l; not(p(l)) + // must be the same as p(not(l)), where p(x) represents the image of x by + // the permutation. + // + // Remark: Any permutation which is a symmetry of the main SAT problem can be + // added here. However, since the number of permutations is usually not + // manageable, a good alternative is to only add the generators of the + // permutation group. It is also important to add permutations with a support + // as small as possible. + // + // TODO(user): Currently this can only be called before PropagateNext() is + // called (DCHECKed). Not sure if we need more incrementality though. + void AddSymmetry(std::unique_ptr permutation); + int num_permutations() const { return permutations_.size(); } + + // Visible for testing. + // + // Permutes a list of literals from input into output using the permutation + // with given index. This uses tmp_literal_mapping_ and has a complexity in + // O(permutation_support + input_size). + void Permute(int index, ClauseRef input, std::vector* output) const; + + private: + // Propagates the literal at propagation_trail_index_ from the trail. + bool PropagateNext(Trail* trail); + + // The permutations. + // The index of a permutation is its position in this vector. + std::vector> permutations_; + + // Reverse mapping (source literal) -> list of (permutation_index, image). + struct ImageInfo { + ImageInfo(int p, Literal i) : permutation_index(p), image(i) {} + + int permutation_index; + Literal image; + }; + ITIVector> images_; + + // For each permutation p, we maintain the list of all assigned literals + // affected by p whose trail index is < propagation_trail_index_; sorted by + // trail index. Next to each such literal, we also store: + struct AssignedLiteralInfo { + AssignedLiteralInfo(Literal l, Literal i, int index) + : literal(l), image(i), first_non_symmetric_info_index_so_far(index) {} + + // The literal in question (assigned to true and in the support of p). + Literal literal; + + // The image by p of the literal above. + Literal image; + + // Previous AssignedLiteralInfos are considered 'symmetric' iff both their + // 'literal' and 'image' were assigned to true at the time the current + // AssignedLiteralInfo's literal was assigned (i.e. earlier in the trail). + int first_non_symmetric_info_index_so_far; + }; + std::vector> permutation_trails_; + + // Adds an AssignedLiteralInfo to the given permutation trail. + // Returns false if there is a non-symmetric literal in this trail with its + // image not already assigned to true by the solver. + bool Enqueue(const Trail& trail, Literal literal, Literal image, + std::vector* permutation_trail); + + // The identity permutation over all the literals. + // This is temporary modified to encode a sparse permutation and then always + // restored to the identity. + mutable ITIVector tmp_literal_mapping_; + + // Symmetry reason indexed by trail_index. + struct ReasonInfo { + int source_trail_index; + int symmetry_index; + }; + std::vector reasons_; + + mutable StatsGroup stats_; + int num_propagations_; + int num_conflicts_; + DISALLOW_COPY_AND_ASSIGN(SymmetryPropagator); +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_SYMMETRY_H_ diff --git a/thirdparty/linux/include/ortools/sat/table.h b/thirdparty/linux/include/ortools/sat/table.h new file mode 100644 index 0000000..6171b00 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/table.h @@ -0,0 +1,58 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_TABLE_H_ +#define OR_TOOLS_SAT_TABLE_H_ + +#include "ortools/sat/integer.h" +#include "ortools/sat/model.h" + +namespace operations_research { +namespace sat { + +// Enforces that the given tuple of variables is equal to one of the given +// tuples. All the tuples must have the same size as var.size(), this is +// Checked. +std::function TableConstraint( + const std::vector& vars, + const std::vector>& tuples); + +// Enforces that exactly one literal in line_literals is true, and that +// all literals in the corresponding line of the literal_tuples matrix are true. +// This constraint assumes that exactly one literal per column of the +// literal_tuples matrix is true. +std::function LiteralTableConstraint( + const std::vector>& literal_tuples, + const std::vector& line_literals); + +// Given an automata defined by a set of 3-tuples: +// (state, transition_with_value_as_label, next_state) +// this accepts the sequences of vars.size() variables that are recognized by +// this automata. That is: +// - We start from the initial state. +// - For each variable, we move along the transition labeled by this variable +// value. Moreover, the variable must take a value that correspond to a +// feasible transition. +// - We only accept sequences that ends in one of the final states. +// +// We CHECK that there is only one possible transition for a state/value pair. +// See the test for some examples. +std::function TransitionConstraint( + const std::vector& vars, + const std::vector>& automata, int64 initial_state, + const std::vector& final_states); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_TABLE_H_ diff --git a/thirdparty/linux/include/ortools/sat/theta_tree.h b/thirdparty/linux/include/ortools/sat/theta_tree.h new file mode 100644 index 0000000..e04370e --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/theta_tree.h @@ -0,0 +1,198 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_THETA_TREE_H_ +#define OR_TOOLS_SAT_THETA_TREE_H_ + +#include +#include +#include + +#include "ortools/sat/integer.h" + +namespace operations_research { +namespace sat { + +// The Theta-Lambda tree can be used to implement several scheduling algorithms. +// +// The tree structure itself is a binary tree coded in a vector, where node 0 is +// unused, node 1 is the root, node 2 is the left child of the root, node 3 its +// right child, etc. To represent num_events events, we use the smallest +// possible amount of leaves, num_leaves = 2^k >= num_events. The unused leaves +// are filled with dummy values, as if they were absent events. +// The API gives access to rightmost events that realize a given envelope. +// +// See: +// _ (0) Petr Vilim's PhD thesis "Global Constraints in Scheduling". +// _ (1) Petr Vilim "Edge Finding Filtering Algorithm for Discrete Cumulative +// Resources in O(kn log n)" +// _ (2) Petr Vilim "Max energy filtering algorithm for discrete cumulative +// resources". +// _ (3) Wolf & Schrader "O(n log n) Overload Checking for the Cumulative +// Constraint and Its Application". +// _ (4) Kameugne & Fotso "A cumulative not-first/not-last filtering algorithm +// in O(n^2 log n)". +// _ (5) Ouellet & Quimper "Time-table extended-edge-finding for the cumulative +// constraint". +// +// Instead of providing one declination of the theta-tree per possible filtering +// algorithm, this generalization intends to provide a data structure that can +// fit several algorithms. +// This tree is based around the notion of events. It has events at its leaves +// that can be present or absent, and present events come with an +// initial_envelope, a minimal and a maximal energy. +// All nodes maintain values on the set of present events under them: +// _ energy_min(node) = sum_{leaf \in leaves(node)} energy_min(leaf) +// _ envelope(node) = +// max_{leaf \in leaves(node)} +// initial_envelope(leaf) + +// sum_{leaf' \in leaves(node), leaf' >= leaf} energy_min(leaf'). +// +// Thus, the envelope of a leaf representing an event, when present, is +// initial_envelope(event) + energy_min(event). +// +// envelope_opt and energy_opt are similar, but represent the maximum value +// a node could have if one leaf took its maximum energy: +// _ energy_opt(node) = sum_{leaf \in leaves(node)} energy_min(leaf) +// + max_{leaf \in leaves(node)} +// energy_max(leaf) - energy_min(leaf) +// _ envelope_opt(node) = +// max_{leaf \in leaves(node)} +// initial_envelope(leaf) + +// sum_{leaf' \in leaves(node), leaf' >= leaf} energy_min(leaf') + +// max_{leaf_opt \in leaves(node)} +// . (energy_max(leaf_opt) - energy_min(leaf_opt)) +// max_{leaf_opt \in leaves(node)} +// initial_envelope(leaf_opt) + +// energy_max(leaf_opt) - energy_min(leaf_opt) + +// sum_{leaf' \in leaves(node), leaf' >= leaf_opt} energy_min(leaf') +// +// Most articles using theta-tree variants hack Vilim's original theta tree +// for the disjunctive resource constraint by manipulating envelope and +// energy: +// _ in (0), initial_envelope = start_min, energy = duration +// _ in (3), initial_envelope = C * start_min, energy = demand * duration +// _ in (5), there are several trees in parallel: +// initial_envelope = C * start_min or (C - h) * start_min +// energy = demand * duration, h * (Horizon - start_min), +// or h * (end_min). +// _ in (2), same as (3), but putting the max energy instead of min in lambda. +// _ in OscaR's TimeTableOverloadChecker, +// initial_envelope = C * start_min - +// energy of mandatory profile before start_min, +// energy = demand * duration +// +// There is hope to unify the variants of these algorithms by abstracting the +// tasks away to reason only on events. +class ThetaLambdaTree { + public: + // Builds a reusable tree. Initialization is done with Reset(). + ThetaLambdaTree(); + + // Initializes this class for events in [0, num_events) and makes all of them + // absent. Instead of allocating and de-allocating trees at every usage, i.e. + // at every Propagate() of the scheduling algorithms that uses it, this class + // allows to keep the same memory for each call. + void Reset(int num_events); + + // Makes event present and updates its initial envelope and min/max energies. + // This updates the tree in O(log n). + void AddOrUpdateEvent(int event, IntegerValue initial_envelope, + IntegerValue energy_min, IntegerValue energy_max); + + // Makes event absent, compute the new envelope in O(log n). + void RemoveEvent(int event); + + // Returns the maximum envelope using all the energy_min in O(1). + IntegerValue GetEnvelope() const; + + // Returns the maximum envelope using the energy min of all task but + // one and the energy max of the last one in O(1). + IntegerValue GetOptionalEnvelope() const; + + // Computes the maximum event s.t. GetEnvelopeOf(event) > envelope_max. + // There must be such an event, i.e. GetEnvelope() > envelope_max. + // This finds the maximum event e such that + // initial_envelope(e) + sum_{e' >= e} energy_min(e') > target_envelope. + // This operation is O(log n). + int GetMaxEventWithEnvelopeGreaterThan(IntegerValue target_envelope) const; + + // Returns initial_envelope(event) + sum_{event' >= event} energy_min(event'), + // in time O(log n). + IntegerValue GetEnvelopeOf(int event) const; + + // Computes a pair of events (critical_event, optional_event) such that + // if optional_event was at its maximum energy, the envelope of critical_event + // would be greater than target_envelope. + // This assumes that such a pair exists, i.e. GetOptionalEnvelope() + // should be greater than target_envelope. + // More formally, this finds events such that + // initial_envelope(critical_event) + + // sum_{event' >= critical_event} energy_min(event') + + // max_{optional_event >= critical_event} + // (energy_max(optional_event) - energy_min(optional_event)) + // > target envelope. + // For efficiency reasons, this also fills available_energy with the maximum + // value such that the optional envelope of the pair would be target_envelope, + // i.e. target_envelope - GetEnvelopeOf(event) + energy_min(optional_event). + // This operation is O(log n). + void GetEventsWithOptionalEnvelopeGreaterThan( + IntegerValue target_envelope, int* critical_event, int* optional_event, + IntegerValue* available_energy) const; + + private: + // Propagates the change of leaf energies and envelopes towards the root. + void RefreshNode(int leaf); + + // Finds the maximum leaf under node such that + // initial_envelope(leaf) + sum_{leaf' >= leaf} energy_min(leaf') + // > target_envelope. + int GetMaxLeafWithEnvelopeGreaterThan(int node, + IntegerValue target_envelope) const; + + // Returns the maximum leaf under node whose optional energy would overload + // node. + // Finds the maximum leaf under node such that + // sum_{leaf' under node} energy_min(leaf') + + // energy_max(leaf) - energy_min(leaf) > node_available_energy. + // available_energy will be the energy available for this leaf, + // i.e. node_available_energy - sum_{leaf' under node} energy_min(leaf') + + // energy_min(leaf). + int GetMaxLeafWithOptionalEnergyGreaterThan( + int node, IntegerValue node_available_energy, + IntegerValue* available_energy) const; + + // Finds the leaves and energy relevant for + // GetEventsWithOptionalEnvelopeGreaterThan(). + void GetLeavesWithOptionalEnvelopeGreaterThan( + IntegerValue target_envelope, int* critical_leaf, int* optional_leaf, + IntegerValue* available_energy) const; + + // Number of events of the last Reset(); + int num_events_; + + // Number of leaves used by the last Reset(), the smallest power of 2 such + // that 2 <= num_leaves_ and num_events_ <= num_leaves_. + int num_leaves_; + + // Envelopes and energies of nodes. + std::vector tree_envelope_; + std::vector tree_energy_min_; + std::vector tree_envelope_opt_; + std::vector tree_energy_opt_; +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_THETA_TREE_H_ diff --git a/thirdparty/linux/include/ortools/sat/timetable.h b/thirdparty/linux/include/ortools/sat/timetable.h new file mode 100644 index 0000000..79b2503 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/timetable.h @@ -0,0 +1,179 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_TIMETABLE_H_ +#define OR_TOOLS_SAT_TIMETABLE_H_ + +#include "ortools/sat/integer.h" +#include "ortools/sat/intervals.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" + +namespace operations_research { +namespace sat { + +// A strongly quadratic version of Time Tabling filtering. This propagator +// is similar to the CumulativeTimeTable propagator of the constraint solver. +class TimeTablingPerTask : public PropagatorInterface { + public: + TimeTablingPerTask(const std::vector& demand_vars, + IntegerVariable capacity, IntegerTrail* integer_trail, + SchedulingConstraintHelper* helper); + + bool Propagate() final; + + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + struct ProfileRectangle { + /* const */ IntegerValue start; + /* const */ IntegerValue end; + /* const */ IntegerValue height; + ProfileRectangle(IntegerValue start, IntegerValue end, IntegerValue height) + : start(start), end(end), height(height) {} + }; + + // Builds the profile and increases the lower bound of the capacity + // variable accordingly. + bool BuildProfile(); + + // Reduces the set of tasks to be considered by BuildProfile(). This is done + // by not considering parts of mandatory part that are overlaped by no task. + // The set of tasks to consider is restored to its previous state each time a + // backtrack occurs. This function must be called only if the by_start_max_ + // and by_end_min_ vectors are up to date and if the profile contains no + // profile rectangle that can exceed the capacity of the resource. + void ReduceProfile(); + + // Reverses the profile. This is needed to reuse a given profile to update + // both the start and end times. + void ReverseProfile(); + + // Tries to increase the minimum start time of each task according to the + // current profile. This function can be called after ReverseProfile() and + // ReverseVariables to update the maximum end time of each task. + bool SweepAllTasks(); + + // Tries to increase the minimum start time of task_id. + bool SweepTask(int task_id); + + // Updates the starting time of task_id to right and explain it. The reason is + // all the mandatory parts contained in [left, right). + bool UpdateStartingTime(int task_id, IntegerValue left, IntegerValue right); + + // Increases the minimum capacity to new_min and explain it. The reason is all + // the mandatory parts that overlap time. + bool IncreaseCapacity(IntegerValue time, IntegerValue new_min); + + // Explains the resource overload at time or removes task_id if it is + // optional. + bool OverloadOrRemove(int task_id, IntegerValue time); + + // Explains the state of the profile in the time interval [left, right). The + // reason is all the mandatory parts that overlap the interval. The current + // reason is not cleared when this method is called. + void AddProfileReason(IntegerValue left, IntegerValue right); + + IntegerValue CapacityMin() const { + return integer_trail_->LowerBound(capacity_var_); + } + + IntegerValue CapacityMax() const { + return integer_trail_->UpperBound(capacity_var_); + } + + IntegerValue DemandMin(int task_id) const { + return integer_trail_->LowerBound(demand_vars_[task_id]); + } + + IntegerValue DemandMax(int task_id) const { + return integer_trail_->UpperBound(demand_vars_[task_id]); + } + + // Returns true if the tasks is present and has a mantatory part. + bool IsInProfile(int t) const { + return positions_in_profile_tasks_[t] < num_profile_tasks_; + } + + // Number of tasks. + const int num_tasks_; + + // The demand variables of the tasks. + std::vector demand_vars_; + + // Capacity of the resource. + const IntegerVariable capacity_var_; + + IntegerTrail* integer_trail_; + SchedulingConstraintHelper* helper_; + + RevRepository rev_repository_int_; + RevRepository rev_repository_integer_value_; + + // Vector of tasks sorted by maximum starting (resp. minimum ending) time. + std::vector by_start_max_; + std::vector by_end_min_; + + // Tasks contained in the range [left_start_, right_start_) of by_start_max_ + // must be sorted and considered when building the profile. The state of these + // bounds is restored when a backtrack occurs. + int left_start_; + int right_start_; + + // Tasks contained in the range [left_end_, right_end_) of by_end_min_ must be + // sorted and considered when building the profile. The state of these bounds + // is restored when a backtrack occurs. + int left_end_; + int right_end_; + + // Start (resp. end) of the compulsory parts used to build the profile. + std::vector scp_; + std::vector ecp_; + + // Optimistic profile of the resource consumption over time. + std::vector profile_; + IntegerValue profile_max_height_; + + // Reversible starting height of the reduced profile. This corresponds to the + // height of the leftmost profile rectangle that can be used for propagation. + IntegerValue starting_profile_height_; + + // True if the last call of the propagator has filtered the domain of a task + // and changed the shape of the profile. + bool profile_changed_; + + // Reversible set of tasks to consider for propagation. The set contains the + // tasks in the [0, num_tasks_to_sweep_) prefix of tasks_to_sweep_. + std::vector tasks_to_sweep_; + int num_tasks_to_sweep_; + + // Reversible set of tasks to consider for reducing the profile. The set + // contains the [0, num_active_tasks_) prefix of active_tasks_. + std::vector active_tasks_; + int num_active_tasks_; + + // Reversible set (with random access) of tasks to consider for building the + // profile. The set contains the tasks in the [0, num_profile_tasks_) prefix + // of profile_tasks_. The positions of a task in profile_tasks_ is contained + // in positions_in_profile_tasks_. + std::vector profile_tasks_; + std::vector positions_in_profile_tasks_; + int num_profile_tasks_; + + DISALLOW_COPY_AND_ASSIGN(TimeTablingPerTask); +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_TIMETABLE_H_ diff --git a/thirdparty/linux/include/ortools/sat/timetable_edgefinding.h b/thirdparty/linux/include/ortools/sat/timetable_edgefinding.h new file mode 100644 index 0000000..7758429 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/timetable_edgefinding.h @@ -0,0 +1,197 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_TIMETABLE_EDGEFINDING_H_ +#define OR_TOOLS_SAT_TIMETABLE_EDGEFINDING_H_ + +#include "ortools/sat/integer.h" +#include "ortools/sat/intervals.h" +#include "ortools/sat/model.h" +#include "ortools/sat/sat_base.h" + +namespace operations_research { +namespace sat { + +// TimeTableEdgeFinding implements the timetable edge finding filtering rule +// presented in Vilim Petr, "Timetable edge finding filtering algorithm for +// discrete cumulative resources", CPAIOR 2011, +// http://vilim.eu/petr/cpaior2011.pdf. +// +// This propagator runs in O(n^2) where n is the number of tasks. It increases +// both the start times and decreases the ending times of the tasks. +// +// Note that this propagator does not ensure that the cumulative constraint +// holds. It should thus always be used with at least a timetable propagator. +// +// ALOGRITHM: +// +// The algorithm relies on free tasks. A free task is basically a task without +// its mandatory part. For instance: +// +// s_min s_max e_min e_max +// v v v v +// task: ============================= +// ^ ^ ^ +// | free part | Mandatory part | +// +// Obviously, the free part of a task that has no mandatory part is equal to the +// task itself. Also, a free part cannot have a mandatory part by definition. A +// fixed task thus have no free part. +// +// The idea of the algorithm is to use free and mandatory parts separately to +// have a better estimation of the energy contained in a task interval. +// +// If the sum of the energy of all the free parts and mandatory subparts +// contained in a task interval exceeds the amount of energy available, then the +// problem is unfeasible. A task thus cannot be scheduled at its minimum start +// time if this would cause an overload in one of the task intervals. +class TimeTableEdgeFinding : public PropagatorInterface { + public: + TimeTableEdgeFinding(const std::vector& interval_vars, + const std::vector& demand_vars, + IntegerVariable capacity, Trail* trail, + IntegerTrail* integer_trail, + IntervalsRepository* intervals_repository); + + bool Propagate() final; + + void RegisterWith(GenericLiteralWatcher* watcher); + + private: + struct TaskTime { + /* const */ int task_id; + IntegerValue time; + TaskTime(int task_id, IntegerValue time) : task_id(task_id), time(time) {} + bool operator<(TaskTime other) const { return time < other.time; } + }; + + // Build the timetable and fills the mandatory_energy_before_start_min_ and + // mandatory_energy_before_end_max_. This method assumes that by_start_max_ + // and by_end_min_ are sorted and up-to-date. + void BuildTimeTable(); + + // Performs a single pass of the Timetable Edge Finding filtering rule to + // updates the start time of the tasks. This same function can be used to + // update the end times by calling the SwitchToMirrorProblem method first. + bool TimeTableEdgeFindingPass(); + + // Increases the start min of task_id with the proper explanation. + bool IncreaseStartMin(IntegerValue begin, IntegerValue end, int task_id, + IntegerValue new_start); + + // Adds the reason that explain the presence of the task to reason_. + // This method does not reset the content of reason_. + void AddPresenceReasonIfNeeded(int task_id); + + // Configures the propagator to update the start variables of the mirrored + // tasks. This is needed to update the start and end times of the tasks. + void SwitchToMirrorProblem(); + + // Returns true if the task uses the resource. + bool IsPresent(int task_id) const; + + // Returns true if the task does not use the resource. + bool IsAbsent(int task_id) const; + + IntegerValue StartMin(int task_id) const { + return integer_trail_->LowerBound(start_vars_[task_id]); + } + + IntegerValue StartMax(int task_id) const { + return integer_trail_->UpperBound(start_vars_[task_id]); + } + + IntegerValue EndMin(int task_id) const { + return integer_trail_->LowerBound(end_vars_[task_id]); + } + + IntegerValue EndMax(int task_id) const { + return integer_trail_->UpperBound(end_vars_[task_id]); + } + + IntegerValue DemandMin(int task_id) const { + return integer_trail_->LowerBound(demand_vars_[task_id]); + } + + IntegerValue DurationMin(int task_id) const { + return intervals_repository_->MinSize(interval_vars_[task_id]); + } + + IntegerValue CapacityMin() const { + return integer_trail_->LowerBound(capacity_var_); + } + + IntegerValue CapacityMax() const { + return integer_trail_->UpperBound(capacity_var_); + } + + // Number of tasks. + const int num_tasks_; + + // IntervalVariable and IntegerVariable of each tasks that must be considered + // in this constraint. + std::vector interval_vars_; + std::vector start_vars_; + std::vector end_vars_; + std::vector demand_vars_; + std::vector duration_vars_; + + // Mirror variables + std::vector mirror_start_vars_; + std::vector mirror_end_vars_; + + // Capacity of the resource. + const IntegerVariable capacity_var_; + + // Reason vector. + std::vector literal_reason_; + std::vector reason_; + + Trail* trail_; + IntegerTrail* integer_trail_; + IntervalsRepository* intervals_repository_; + + // Used for fast access and to maintain the actual value of end_min since + // updating start_vars_[t] does not directly update end_vars_[t]. + std::vector start_min_; + std::vector start_max_; + std::vector end_min_; + std::vector end_max_; + std::vector duration_min_; + std::vector demand_min_; + + // Tasks sorted by start (resp. end) min (resp. max). + std::vector by_start_min_; + std::vector by_start_max_; + std::vector by_end_min_; + std::vector by_end_max_; + + // Start (resp. end) of the compulsory parts used to build the profile. + std::vector scp_; + std::vector ecp_; + + // Energy of the free parts. + std::vector energy_free_; + + // Energy contained in the time table before the start min (resp. end max) + // of each task. + std::vector mandatory_energy_before_start_min_; + std::vector mandatory_energy_before_end_max_; + + DISALLOW_COPY_AND_ASSIGN(TimeTableEdgeFinding); +}; + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_TIMETABLE_EDGEFINDING_H_ diff --git a/thirdparty/linux/include/ortools/sat/util.h b/thirdparty/linux/include/ortools/sat/util.h new file mode 100644 index 0000000..e87cdd4 --- /dev/null +++ b/thirdparty/linux/include/ortools/sat/util.h @@ -0,0 +1,29 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_SAT_UTIL_H_ +#define OR_TOOLS_SAT_UTIL_H_ + +#include "ortools/sat/sat_parameters.pb.h" +#include "ortools/base/random.h" + +namespace operations_research { +namespace sat { + +// Randomizes the decision heuristic of the given SatParameters. +void RandomizeDecisionHeuristic(MTRandom* random, SatParameters* parameters); + +} // namespace sat +} // namespace operations_research + +#endif // OR_TOOLS_SAT_UTIL_H_ diff --git a/thirdparty/linux/include/ortools/util/bitset.h b/thirdparty/linux/include/ortools/util/bitset.h new file mode 100644 index 0000000..34ba376 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/bitset.h @@ -0,0 +1,836 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Various utility functions on bitsets. + +#ifndef OR_TOOLS_UTIL_BITSET_H_ +#define OR_TOOLS_UTIL_BITSET_H_ + +#include +#include +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" + +namespace operations_research { + +// Basic bit operations + +// Useful constants: word and double word will all bits set. +static const uint64 kAllBits64 = GG_ULONGLONG(0xFFFFFFFFFFFFFFFF); +static const uint64 kAllBitsButLsb64 = GG_ULONGLONG(0xFFFFFFFFFFFFFFFE); +static const uint32 kAllBits32 = 0xFFFFFFFFU; + +// Returns a word with only bit pos set. +inline uint64 OneBit64(int pos) { return GG_ULONGLONG(1) << pos; } +inline uint32 OneBit32(int pos) { return 1U << pos; } + +// Returns the number of bits set in n. +inline uint64 BitCount64(uint64 n) { + const uint64 m1 = GG_ULONGLONG(0x5555555555555555); + const uint64 m2 = GG_ULONGLONG(0x3333333333333333); + const uint64 m4 = GG_ULONGLONG(0x0F0F0F0F0F0F0F0F); + const uint64 h01 = GG_ULONGLONG(0x0101010101010101); + n -= (n >> 1) & m1; + n = (n & m2) + ((n >> 2) & m2); + n = (n + (n >> 4)) & m4; + n = (n * h01) >> 56; + return n; +} +inline uint32 BitCount32(uint32 n) { + n -= (n >> 1) & 0x55555555UL; + n = (n & 0x33333333) + ((n >> 2) & 0x33333333UL); + n = (n + (n >> 4)) & 0x0F0F0F0FUL; + n = n + (n >> 8); + n = n + (n >> 16); + return n & 0x0000003FUL; +} + +// Returns a word with only the least significant bit of n set. +inline uint64 LeastSignificantBitWord64(uint64 n) { return n & ~(n - 1); } +inline uint32 LeastSignificantBitWord32(uint32 n) { return n & ~(n - 1); } + +// Returns the least significant bit position in n. +// Discussion around lsb computation: +// De Bruijn is almost as fast as the bsr/bsf-instruction-based intrinsics. +// Both are always much faster than the Default algorithm. +#define USE_DEBRUIJN true // if true, use de Bruijn bit forward scanner. +#if defined(__GNUC__) || defined(__llvm__) +#define USE_FAST_LEAST_SIGNIFICANT_BIT true // if true, use fast lsb. +#endif + +#if defined(USE_FAST_LEAST_SIGNIFICANT_BIT) +inline int LeastSignificantBitPosition64Fast(uint64 n) { + // Note(user): Do not change the order of instructions. Other patterns were + // tried, and the second best was: + // return n == 0 ? 0 : __builtin_ctzll(n) which results in an 2x increase of + // computation time. + const int lsb = __builtin_ctzll(n); + return n == 0 ? 0 : lsb; +} +#endif + +inline int LeastSignificantBitPosition64DeBruijn(uint64 n) { + static const uint64 kSeq = GG_ULONGLONG(0x0218a392dd5fb34f); + static const int kTab[64] = { + // initialized by 'kTab[(kSeq << i) >> 58] = i + 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 52, 20, 58, + 5, 17, 26, 56, 15, 38, 29, 40, 10, 49, 53, 31, 21, 34, 59, 42, + 63, 6, 12, 18, 24, 27, 51, 57, 16, 55, 37, 39, 48, 30, 33, 41, + 62, 11, 23, 50, 54, 36, 47, 32, 61, 22, 35, 46, 60, 45, 44, 43, }; + return kTab[((n & (~n + 1)) * kSeq) >> 58]; +} + +inline int LeastSignificantBitPosition64Default(uint64 n) { + if (n == 0) return 0; + int pos = 63; + if (n & 0x00000000FFFFFFFFLL) { + pos -= 32; + } else { + n >>= 32; + } + if (n & 0x000000000000FFFFLL) { + pos -= 16; + } else { + n >>= 16; + } + if (n & 0x00000000000000FFLL) { + pos -= 8; + } else { + n >>= 8; + } + if (n & 0x000000000000000FLL) { + pos -= 4; + } else { + n >>= 4; + } + if (n & 0x0000000000000003LL) { + pos -= 2; + } else { + n >>= 2; + } + if (n & 0x0000000000000001LL) { + pos -= 1; + } + return pos; +} + +inline int LeastSignificantBitPosition64(uint64 n) { + DCHECK_NE(n, 0); +#ifdef USE_FAST_LEAST_SIGNIFICANT_BIT + return LeastSignificantBitPosition64Fast(n); +#elif defined(USE_DEBRUIJN) + return LeastSignificantBitPosition64DeBruijn(n); +#else + return LeastSignificantBitPosition64Default(n); +#endif +} + +#if defined(USE_FAST_LEAST_SIGNIFICANT_BIT) +inline int LeastSignificantBitPosition32Fast(uint32 n) { + const int lsb = __builtin_ctzl(n); + return n == 0 ? 0 : lsb; +} +#endif + +inline int LeastSignificantBitPosition32DeBruijn(uint32 n) { + static const uint32 kSeq = 0x077CB531U; // de Bruijn sequence + static const int kTab[32] = { + // initialized by 'kTab[(kSeq << i) >> 27] = i + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; + return kTab[((n & (~n + 1)) * kSeq) >> 27]; +} + +inline int LeastSignificantBitPosition32Default(uint32 n) { + if (n == 0) return 0; + int pos = 31; + if (n & 0x0000FFFFL) { + pos -= 16; + } else { + n >>= 16; + } + if (n & 0x000000FFL) { + pos -= 8; + } else { + n >>= 8; + } + if (n & 0x0000000FL) { + pos -= 4; + } else { + n >>= 4; + } + if (n & 0x00000003L) { + pos -= 2; + } else { + n >>= 2; + } + if (n & 0x00000001L) { + pos -= 1; + } + return pos; +} + +inline int LeastSignificantBitPosition32(uint32 n) { + DCHECK_NE(n, 0); +#ifdef USE_FAST_LEAST_SIGNIFICANT_BIT + return LeastSignificantBitPosition32Fast(n); +#elif defined(USE_DEBRUIJN) + return LeastSignificantBitPosition32DeBruijn(n); +#else + return LeastSignificantBitPosition32Default(n); +#endif +} + +// Returns the most significant bit position in n. +#if USE_FAST_LEAST_SIGNIFICANT_BIT +inline int MostSignificantBitPosition64Fast(uint64 n) { + // __builtin_clzll(1) should always return 63. There is no penalty in + // using offset, and the code looks more like its uint32 counterpart. + const int offset = __builtin_clzll(1); + const int msb = offset - __builtin_clzll(n); + return n == 0 ? 0 : msb; +} +#endif + +inline int MostSignificantBitPosition64Default(uint64 n) { + int b = 0; + if (0 != (n & (kAllBits64 << (1 << 5)))) { + b |= (1 << 5); + n >>= (1 << 5); + } + if (0 != (n & (kAllBits64 << (1 << 4)))) { + b |= (1 << 4); + n >>= (1 << 4); + } + if (0 != (n & (kAllBits64 << (1 << 3)))) { + b |= (1 << 3); + n >>= (1 << 3); + } + if (0 != (n & (kAllBits64 << (1 << 2)))) { + b |= (1 << 2); + n >>= (1 << 2); + } + if (0 != (n & (kAllBits64 << (1 << 1)))) { + b |= (1 << 1); + n >>= (1 << 1); + } + if (0 != (n & (kAllBits64 << (1 << 0)))) { + b |= (1 << 0); + } + return b; +} + +inline int MostSignificantBitPosition64(uint64 n) { +#ifdef USE_FAST_LEAST_SIGNIFICANT_BIT + return MostSignificantBitPosition64Fast(n); +#else + return MostSignificantBitPosition64Default(n); +#endif +} + +#if USE_FAST_LEAST_SIGNIFICANT_BIT +inline int MostSignificantBitPosition32Fast(uint32 n) { + // The constant here depends on whether we are on a 32-bit or 64-bit machine. + // __builtin_clzl(1) returns 63 on a 64-bit machine and 31 on a 32-bit + // machine. + const int offset = __builtin_clzl(1); + const int msb = offset - __builtin_clzl(n); + return n == 0 ? 0 : msb; +} +#endif + +inline int MostSignificantBitPosition32Default(uint32 n) { + int b = 0; + if (0 != (n & (kAllBits32 << (1 << 4)))) { + b |= (1 << 4); + n >>= (1 << 4); + } + if (0 != (n & (kAllBits32 << (1 << 3)))) { + b |= (1 << 3); + n >>= (1 << 3); + } + if (0 != (n & (kAllBits32 << (1 << 2)))) { + b |= (1 << 2); + n >>= (1 << 2); + } + if (0 != (n & (kAllBits32 << (1 << 1)))) { + b |= (1 << 1); + n >>= (1 << 1); + } + if (0 != (n & (kAllBits32 << (1 << 0)))) { + b |= (1 << 0); + } + return b; +} + +inline int MostSignificantBitPosition32(uint32 n) { +#ifdef USE_FAST_LEAST_SIGNIFICANT_BIT + return MostSignificantBitPosition32Fast(n); +#else + return MostSignificantBitPosition32Default(n); +#endif +} + +#undef USE_DEBRUIJN +#undef USE_FAST_LEAST_SIGNIFICANT_BIT + +// Returns a word with bits from s to e set. +inline uint64 OneRange64(uint64 s, uint64 e) { + DCHECK_LE(s, 63); + DCHECK_LE(e, 63); + DCHECK_LE(s, e); + return (kAllBits64 << s) ^ ((kAllBits64 - 1) << e); +} + +inline uint32 OneRange32(uint32 s, uint32 e) { + DCHECK_LE(s, 31); + DCHECK_LE(e, 31); + DCHECK_LE(s, e); + return (kAllBits32 << s) ^ ((kAllBits32 - 1) << e); +} + +// Returns a word with s least significant bits unset. +inline uint64 IntervalUp64(uint64 s) { + DCHECK_LE(s, 63); + return kAllBits64 << s; +} + +inline uint32 IntervalUp32(uint32 s) { + DCHECK_LE(s, 31); + return kAllBits32 << s; +} + +// Returns a word with the s most significant bits unset. +inline uint64 IntervalDown64(uint64 s) { + DCHECK_LE(s, 63); + return kAllBits64 >> (63 - s); +} + +inline uint32 IntervalDown32(uint32 s) { + DCHECK_LE(s, 31); + return kAllBits32 >> (31 - s); +} + +// ----- Bitset operators ----- +// Bitset: array of uint32/uint64 words + +// Bit operators used to manipulates bitsets. + +// Returns the bit number in the word computed by BitOffsetXX, +// corresponding to the bit at position pos in the bitset. +// Note: '& 63' is faster than '% 64' +// TODO(user): rename BitPos and BitOffset to something more understandable. +inline uint64 BitPos64(uint64 pos) { return (pos & 63); } +inline uint32 BitPos32(uint32 pos) { return (pos & 31); } + +// Returns the word number corresponding to bit number pos. +inline uint64 BitOffset64(uint64 pos) { return (pos >> 6); } +inline uint32 BitOffset32(uint32 pos) { return (pos >> 5); } + +// Returns the number of words needed to store size bits. +inline uint64 BitLength64(uint64 size) { return ((size + 63) >> 6); } +inline uint32 BitLength32(uint32 size) { return ((size + 31) >> 5); } + +// Returns the bit number in the bitset of the first bit of word number v. +inline uint64 BitShift64(uint64 v) { return v << 6; } +inline uint32 BitShift32(uint32 v) { return v << 5; } + +// Returns true if the bit pos is set in bitset. +inline bool IsBitSet64(const uint64* const bitset, uint64 pos) { + return (bitset[BitOffset64(pos)] & OneBit64(BitPos64(pos))); +} +inline bool IsBitSet32(const uint32* const bitset, uint32 pos) { + return (bitset[BitOffset32(pos)] & OneBit32(BitPos32(pos))); +} + +// Sets the bit pos to true in bitset. +inline void SetBit64(uint64* const bitset, uint64 pos) { + bitset[BitOffset64(pos)] |= OneBit64(BitPos64(pos)); +} +inline void SetBit32(uint32* const bitset, uint32 pos) { + bitset[BitOffset32(pos)] |= OneBit32(BitPos32(pos)); +} + +// Sets the bit pos to false in bitset. +inline void ClearBit64(uint64* const bitset, uint64 pos) { + bitset[BitOffset64(pos)] &= ~OneBit64(BitPos64(pos)); +} +inline void ClearBit32(uint32* const bitset, uint32 pos) { + bitset[BitOffset32(pos)] &= ~OneBit32(BitPos32(pos)); +} + +// Returns the number of bits set in bitset between positions start and end. +uint64 BitCountRange64(const uint64* const bitset, uint64 start, uint64 end); +uint32 BitCountRange32(const uint32* const bitset, uint32 start, uint32 end); + +// Returns true if no bits are set in bitset between start and end. +bool IsEmptyRange64(const uint64* const bitset, uint64 start, uint64 end); +bool IsEmptyRange32(const uint32* const bitset, uint32 start, uint32 end); + +// Returns the first bit set in bitset between start and max_bit. +int64 LeastSignificantBitPosition64(const uint64* const bitset, uint64 start, + uint64 end); +int LeastSignificantBitPosition32(const uint32* const bitset, uint32 start, + uint32 end); + +// Returns the last bit set in bitset between min_bit and start. +int64 MostSignificantBitPosition64(const uint64* const bitset, uint64 start, + uint64 end); +int MostSignificantBitPosition32(const uint32* const bitset, uint32 start, + uint32 end); + +// Unsafe versions of the functions above where respectively end and start +// are supposed to be set. +int64 UnsafeLeastSignificantBitPosition64(const uint64* const bitset, + uint64 start, uint64 end); +int32 UnsafeLeastSignificantBitPosition32(const uint32* const bitset, + uint32 start, uint32 end); + +int64 UnsafeMostSignificantBitPosition64(const uint64* const bitset, + uint64 start, uint64 end); +int32 UnsafeMostSignificantBitPosition32(const uint32* const bitset, + uint32 start, uint32 end); + +// Returns a mask with the bits pos % 64 and (pos ^ 1) % 64 sets. +inline uint64 TwoBitsFromPos64(uint64 pos) { + return GG_ULONGLONG(3) << (pos & 62); +} + +// This class is like an ITIVector except that it provides a +// more efficient way to iterate over the positions set to true. It achieves +// this by caching the current uint64 bucket in the Iterator and using +// LeastSignificantBitPosition64() to iterate over the positions at 1 in this +// bucket. +template +class Bitset64 { + public: + Bitset64() : size_(), data_(), end_(*this, /*at_end=*/true) {} + explicit Bitset64(IndexType size) + : size_(Value(size) > 0 ? size : IndexType(0)), + data_(BitLength64(Value(size_))), + end_(*this, /*at_end=*/true) {} + + // Returns how many bits this Bitset64 can hold. + IndexType size() const { return size_; } + + // Appends value at the end of the bitset. + void PushBack(bool value) { + ++size_; + data_.resize(BitLength64(Value(size_)), 0); + Set(size_ - 1, value); + } + + // Resizes the Bitset64 to the given number of bits. New bits are sets to 0. + void Resize(IndexType size) { + DCHECK_GE(Value(size), 0); + size_ = Value(size) > 0 ? size : IndexType(0); + data_.resize(BitLength64(Value(size_)), 0); + } + + // Changes the number of bits the Bitset64 can hold and set all of them to 0. + void ClearAndResize(IndexType size) { + DCHECK_GE(Value(size), 0); + size_ = Value(size) > 0 ? size : IndexType(0); + + // Memset is 4x faster than data_.assign() as of 19/03/2014. + // TODO(user): Ideally if a realloc happens, we don't need to copy the old + // data... + const size_t bit_length = static_cast(BitLength64(Value(size_))); + const size_t to_clear = std::min(data_.size(), bit_length); + data_.resize(bit_length, 0); + memset(data_.data(), 0, to_clear * sizeof(int64)); + } + + // Sets all bits to 0. + void ClearAll() { + memset(data_.data(), 0, data_.size() * sizeof(int64)); + } + + // Sets the bit at position i to 0. + void Clear(IndexType i) { + DCHECK_GE(Value(i), 0); + DCHECK_LT(Value(i), Value(size_)); + data_[BitOffset64(Value(i))] &= ~OneBit64(BitPos64(Value(i))); + } + + // Sets bucket containing bit i to 0. + void ClearBucket(IndexType i) { + DCHECK_GE(Value(i), 0); + DCHECK_LT(Value(i), Value(size_)); + data_[BitOffset64(Value(i))] = 0; + } + + // Clears the bits at position i and i ^ 1. + void ClearTwoBits(IndexType i) { + DCHECK_GE(Value(i), 0); + DCHECK_LT(Value(i), Value(size_)); + data_[BitOffset64(Value(i))] &= ~TwoBitsFromPos64(Value(i)); + } + + // Returns true if the bit at position i or the one at position i ^ 1 is set. + bool AreOneOfTwoBitsSet(IndexType i) const { + DCHECK_GE(Value(i), 0); + DCHECK_LT(Value(i), Value(size_)); + return data_[BitOffset64(Value(i))] & TwoBitsFromPos64(Value(i)); + } + + // Returns true if the bit at position i is set. + bool IsSet(IndexType i) const { + DCHECK_GE(Value(i), 0); + DCHECK_LT(Value(i), Value(size_)); + return data_[BitOffset64(Value(i))] & OneBit64(BitPos64(Value(i))); + } + + // Same as IsSet(). + bool operator[](IndexType i) const { return IsSet(i); } + + // Sets the bit at position i to 1. + void Set(IndexType i) { + DCHECK_GE(Value(i), 0); + DCHECK_LT(Value(i), size_); + data_[BitOffset64(Value(i))] |= OneBit64(BitPos64(Value(i))); + } + + // If value is true, sets the bit at position i to 1, sets it to 0 otherwise. + void Set(IndexType i, bool value) { + if (value) { + Set(i); + } else { + Clear(i); + } + } + + // Copies bucket containing bit i from "other" to "this". + void CopyBucket(const Bitset64& other, IndexType i) { + const uint64 offset = BitOffset64(Value(i)); + data_[offset] = other.data_[offset]; + } + + // Copies "other" to "this". The bitsets do not have to be of the same size. + // If "other" is smaller, high order bits are not changed. If "other" is + // larger, its high order bits are ignored. In any case "this" is not resized. + template + void SetContentFromBitset(const Bitset64& other) { + const int64 min_size = std::min(data_.size(), other.data_.size()); + if (min_size == 0) return; + const uint64 last_common_bucket = data_[min_size - 1]; + memcpy(data_.data(), other.data_.data(), min_size * sizeof(uint64)); + if (data_.size() >= other.data_.size()) { + const uint64 bitmask = kAllBitsButLsb64 + << BitPos64(other.Value(other.size() - 1)); + data_[min_size - 1] &= ~bitmask; + data_[min_size - 1] |= (bitmask & last_common_bucket); + } + } + + // Same as SetContentFromBitset where "this" and "other" have the same size. + template + void SetContentFromBitsetOfSameSize(const Bitset64& other) { + DCHECK_EQ(Value(size()), other.Value(other.size())); + memcpy(data_.data(), other.data_.data(), data_.size() * sizeof(uint64)); + } + + // Sets "this" to be the intersection of "this" and "other". The + // bitsets do not have to be the same size. If other is smaller, all + // the higher order bits are assumed to be 0. + void Intersection(const Bitset64& other) { + const int min_size = std::min(data_.size(), other.data_.size()); + for (int i = 0; i < min_size; ++i) { + data_[i] &= other.data_[i]; + } + for (int i = min_size; i < data_.size(); ++i) { + data_[i] = 0; + } + } + + // Sets "this" to be the union of "this" and "other". The + // bitsets do not have to be the same size. If other is smaller, all + // the higher order bits are assumed to be 0. + void Union(const Bitset64& other) { + const int min_size = std::min(data_.size(), other.data_.size()); + for (int i = 0; i < min_size; ++i) { + data_[i] |= other.data_[i]; + } + } + + // Class to iterate over the bit positions at 1 of a Bitset64. + // + // IMPORTANT: Because the iterator "caches" the current uint64 bucket, this + // will probably not do what you want if Bitset64 is modified while iterating. + class Iterator { + public: + explicit Iterator(const Bitset64& data_) + : bitset_(data_), index_(0), base_index_(0), current_(0) { + if (bitset_.data_.empty()) { + index_ = -1; + } else { + current_ = bitset_.data_[0]; + Next(); + } + } + + // Returns true if the Iterator is at a valid position. + bool Ok() const { return index_ != -1; } + + // Returns the current position of the iterator. + IndexType Index() const { + DCHECK(Ok()); + return IndexType(index_); + } + + // Moves the iterator the the next position at 1 of the Bitset64. + void Next() { + DCHECK(Ok()); + if (current_ == 0) { + int bucket = BitOffset64(base_index_); + const int size = bitset_.data_.size(); + do { + bucket++; + } while (bucket < size && bitset_.data_[bucket] == 0); + if (bucket == size) { + index_ = -1; + return; + } + current_ = bitset_.data_[bucket]; + base_index_ = BitShift64(bucket); + } + + // Computes the index and clear the least significant bit of current_. + index_ = base_index_ + LeastSignificantBitPosition64(current_); + current_ &= current_ - 1; + } + + // STL version of the functions above to support range-based "for" loop. + Iterator(const Bitset64& data_, bool at_end) + : bitset_(data_), index_(0), base_index_(0), current_(0) { + if (at_end || bitset_.data_.empty()) { + index_ = -1; + } else { + current_ = bitset_.data_[0]; + Next(); + } + } + bool operator!=(const Iterator& other) const { + return index_ != other.index_; + } + IndexType operator*() const { return IndexType(index_); } + void operator++() { Next(); } + + private: + const Bitset64& bitset_; + int index_; + int base_index_; + uint64 current_; + }; + + // Allows range-based "for" loop on the non-zero positions: + // for (const IndexType index : bitset) {} + // instead of: + // for (Bitset64::Iterator it(bitset); it.Ok(); it.Next()) { + // const IndexType index = it.Index(); + Iterator begin() const { return Iterator(*this); } + Iterator end() const { return end_; } + + // Cryptic function! + // This is just an optimized version of a given piece of code and has probably + // little general use. Sets the bit at position i to the result of + // (other1[i] && use1) XOR (other2[i] && use2). + void SetBitFromOtherBitSets(IndexType i, const Bitset64& other1, + uint64 use1, const Bitset64& other2, + uint64 use2) { + DCHECK_EQ(data_.size(), other1.data_.size()); + DCHECK_EQ(data_.size(), other2.data_.size()); + DCHECK(use1 == 0 || use1 == 1); + DCHECK(use2 == 0 || use2 == 1); + const int bucket = BitOffset64(Value(i)); + const int pos = BitPos64(Value(i)); + data_[bucket] ^= ((1ull << pos) & data_[bucket]) ^ + ((use1 << pos) & other1.data_[bucket]) ^ + ((use2 << pos) & other2.data_[bucket]); + } + + // Returns a 0/1 std::string representing the bitset. + std::string DebugString() const { + std::string output; + for (IndexType i(0); i < size(); ++i) { + output += IsSet(i) ? "1" : "0"; + } + return output; + } + + private: + // Returns the value of the index type. + // This function is specialized below to work with IntType and int64. + int64 Value(IndexType input) const; + + IndexType size_; + std::vector data_; + + // It is faster to store the end() Iterator than to recompute it every time. + // Note that we cannot do the same for begin(). + const Iterator end_; + + template + friend class Bitset64; + DISALLOW_COPY_AND_ASSIGN(Bitset64); +}; + +// Specialized version of Bitset64 that allows to query the last bit set more +// efficiently. +class BitQueue64 { + public: + BitQueue64() : size_(), top_(-1), data_() {} + explicit BitQueue64(int size) + : size_(size), top_(-1), data_(BitLength64(size), 0) {} + + void IncreaseSize(int size) { + CHECK_GE(size, size_); + size_ = size; + data_.resize(BitLength64(size), 0); + } + + void ClearAndResize(int size) { + top_ = -1; + size_ = size; + data_.assign(BitLength64(size), 0); + } + + void Set(int i) { + DCHECK_GE(i, 0); + DCHECK_LT(i, size_); + top_ = std::max(top_, i); + data_[BitOffset64(i)] |= OneBit64(BitPos64(i)); + } + + // Returns the position of the highest bit set in O(1) or -1 if no bit is set. + int Top() const { return top_; } + + // Clears the Top() bit and recomputes the position of the next Top(). + void ClearTop() { + DCHECK_NE(top_, -1); + int bucket_index = BitOffset64(top_); + uint64 bucket = data_[bucket_index] &= ~OneBit64(BitPos64(top_)); + while (!bucket) { + if (bucket_index == 0) { + top_ = -1; + return; + } + bucket = data_[--bucket_index]; + } + + // Note(user): I experimented with reversing the bit order in a bucket to + // use LeastSignificantBitPosition64() and it is only slightly faster at the + // cost of a lower Set() speed. So I prefered this version. + top_ = BitShift64(bucket_index) + MostSignificantBitPosition64(bucket); + } + + private: + int size_; + int top_; + std::vector data_; + DISALLOW_COPY_AND_ASSIGN(BitQueue64); +}; + +// The specialization of Value() for IntType and int64. +template +inline int64 Bitset64::Value(IntType input) const { + DCHECK_GE(input.value(), 0); + return input.value(); +} +template <> +inline int64 Bitset64::Value(int64 input) const { + DCHECK_GE(input, 0); + return input; +} + +// A simple utility class to set/unset integer in a range [0, size). +// This is optimized for sparsity. +template +class SparseBitset { + public: + SparseBitset() {} + explicit SparseBitset(IntegerType size) : bitset_(size) {} + IntegerType size() const { return bitset_.size(); } + void SparseClearAll() { + for (const IntegerType i : to_clear_) bitset_.ClearBucket(i); + to_clear_.clear(); + } + void ClearAll() { + bitset_.ClearAll(); + to_clear_.clear(); + } + void ClearAndResize(IntegerType size) { + // As of 19/03/2014, experiments show that this is a reasonable threshold. + const int kSparseThreshold = 300; + if (to_clear_.size() * kSparseThreshold < size) { + SparseClearAll(); + bitset_.Resize(size); + } else { + bitset_.ClearAndResize(size); + to_clear_.clear(); + } + } + void Resize(IntegerType size) { + if (size < bitset_.size()) { + int new_index = 0; + for (IntegerType index : to_clear_) { + if (index < size) { + to_clear_[new_index] = index; + ++new_index; + } + } + to_clear_.resize(new_index); + } + bitset_.Resize(size); + } + bool operator[](IntegerType index) const { return bitset_[index]; } + void Set(IntegerType index) { + if (!bitset_[index]) { + bitset_.Set(index); + to_clear_.push_back(index); + } + } + void Clear(IntegerType index) { bitset_.Clear(index); } + int NumberOfSetCallsWithDifferentArguments() const { + return to_clear_.size(); + } + const std::vector& PositionsSetAtLeastOnce() const { + return to_clear_; + } + + // Tells the class that all its bits are cleared, so it can reset to_clear_ + // to the empty vector. Note that this call is "unsafe" since the fact that + // the class is actually all cleared is only checked in debug mode. + // + // This is useful to iterate on the "set" positions while clearing them for + // instance. This way, after the loop, a client can call this for efficiency. + void NotifyAllClear() { + if (DEBUG_MODE) { + for (IntegerType index : to_clear_) CHECK(!bitset_[index]); + } + to_clear_.clear(); + } + + private: + Bitset64 bitset_; + std::vector to_clear_; + DISALLOW_COPY_AND_ASSIGN(SparseBitset); +}; + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_BITSET_H_ diff --git a/thirdparty/linux/include/ortools/util/cached_log.h b/thirdparty/linux/include/ortools/util/cached_log.h new file mode 100644 index 0000000..baaf86b --- /dev/null +++ b/thirdparty/linux/include/ortools/util/cached_log.h @@ -0,0 +1,50 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_UTIL_CACHED_LOG_H_ +#define OR_TOOLS_UTIL_CACHED_LOG_H_ + +#include +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" + +namespace operations_research { +// This class is used when manipulating search space estimations. It +// provides fast access to log of a domain size. +// Future Extensions: +// - Sum of log on an array. +// - Sum of log on an array with callback. + +class CachedLog { + public: + CachedLog(); + ~CachedLog(); + + // This method can only be called once, and with a cache_size > 0. + void Init(int cache_size); + + // Returns the log2 of 'input'. + double Log2(int64 input) const; + + private: + std::vector cache_; + DISALLOW_COPY_AND_ASSIGN(CachedLog); +}; +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_CACHED_LOG_H_ diff --git a/thirdparty/linux/include/ortools/util/filelineiter.h b/thirdparty/linux/include/ortools/util/filelineiter.h new file mode 100644 index 0000000..7ede53a --- /dev/null +++ b/thirdparty/linux/include/ortools/util/filelineiter.h @@ -0,0 +1,137 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Allows to read a text file line by line with: +// for (const std::string& line : FileLines("myfile.txt")) { ... } +// +// More details: +// * The lines are separated by '\n' (which is removed by default) and have no +// size limits. +// * Consecutive '\n' result in empty lines being produced. +// * If not empty, the std::string after the last '\n' is produced as the last line. +// * Options are available to keep the trailing '\n' for each line, to remove +// carriage-return chararters ('\r'), and to remove blank lines. +// +#ifndef OR_TOOLS_UTIL_FILELINEITER_H_ +#define OR_TOOLS_UTIL_FILELINEITER_H_ + +#include "ortools/base/logging.h" +#include "ortools/base/file.h" +#include "ortools/base/stringpiece_utils.h" +#include "ortools/base/strutil.h" + +namespace operations_research { + +// Implements the minimum interface for a range-based for loop iterator. +class FileLineIterator { + public: + enum { + DEFAULT = 0x0000, + KEEP_LINEFEED = 0x0001, // Terminating \n in result. + REMOVE_INLINE_CR = 0x0002, // Remove \r characters. + REMOVE_BLANK_LINES = 0x0004, // Remove empty or \n-only lines. + }; + + FileLineIterator(File* file, int options) + : next_position_after_eol_(0), + buffer_size_(0), + file_(file), + options_(options) { + ReadNextLine(); + } + const std::string& operator*() const { return line_; } + bool operator!=(const FileLineIterator& other) const { + return file_ != other.file_; + } + void operator++() { ReadNextLine(); } + + private: + bool HasOption(int option) const { return options_ & option; } + + void ReadNextLine() { + line_.clear(); + if (file_ == nullptr) return; + do { + while (true) { + int i = next_position_after_eol_; + for (; i < buffer_size_; ++i) { + if (buffer_[i] == '\n') break; + } + if (i == buffer_size_) { + line_.append(&buffer_[next_position_after_eol_], + i - next_position_after_eol_); + buffer_size_ = file_->Read(&buffer_, kBufferSize); + if (buffer_size_ < 0) { + LOG(WARNING) << "Error while reading file."; + file_ = nullptr; + break; + } + next_position_after_eol_ = 0; + if (buffer_size_ == 0) { + if (line_.empty()) { + file_ = nullptr; + } + break; + } + } else { + line_.append(&buffer_[next_position_after_eol_], + i - next_position_after_eol_ + 1); + next_position_after_eol_ = i + 1; + break; + } + } + PostProcessLine(); + } while (file_ != nullptr && HasOption(REMOVE_BLANK_LINES) && + (line_.empty() || line_ == "\n")); + } + + void PostProcessLine() { + if (HasOption(REMOVE_INLINE_CR)) { + line_.erase(std::remove(line_.begin(), line_.end(), '\r'), line_.end()); + } + const auto eol = std::find(line_.begin(), line_.end(), '\n'); + if (!HasOption(KEEP_LINEFEED) && eol != line_.end()) { + line_.erase(eol); + } + } + + static const int kBufferSize = 5 * 1024; + char buffer_[kBufferSize]; + int next_position_after_eol_; + int64 buffer_size_; + File* file_; + std::string line_; + const int options_; +}; + +class FileLines { + public: + FileLines(const std::string& filename, int options) : options_(options) { + file_ = File::Open(filename, "r"); + } + explicit FileLines(const std::string& filename) + : FileLines(filename, FileLineIterator::DEFAULT) {} + ~FileLines() { + if (file_ != nullptr) file_->Close(file::Defaults()).IgnoreError(); + } + FileLineIterator begin() { return FileLineIterator(file_, options_); } + FileLineIterator end() const { return FileLineIterator(nullptr, options_); } + + private: + File* file_; + const int options_; + DISALLOW_COPY_AND_ASSIGN(FileLines); +}; + +} // namespace operations_research +#endif // OR_TOOLS_UTIL_FILELINEITER_H_ diff --git a/thirdparty/linux/include/ortools/util/fp_utils.h b/thirdparty/linux/include/ortools/util/fp_utils.h new file mode 100644 index 0000000..04952bc --- /dev/null +++ b/thirdparty/linux/include/ortools/util/fp_utils.h @@ -0,0 +1,277 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Utility functions on IEEE floating-point numbers. +// Implemented on float, double, and long double. +// +// Also a placeholder for tools controlling and checking FPU rounding modes. +// +// IMPORTANT NOTICE: you need to compile your binary with -frounding-math if +// you want to use rounding modes. + +#ifndef OR_TOOLS_UTIL_FP_UTILS_H_ +#define OR_TOOLS_UTIL_FP_UTILS_H_ + +#if defined(_MSC_VER) +#pragma fenv_access (on) // NOLINT +#else +#include // NOLINT +#endif +#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(_MSC_VER) +#include +#endif + +#ifdef __SSE__ +#include +#endif + +#include +#include +#include + +#include "ortools/base/logging.h" + +#if defined(_MSC_VER) +static inline double isnan(double value) { return _isnan(value); } +static inline double round(double value) { return floor(value + 0.5); } +#elif defined(__APPLE__) || __GNUC__ >= 5 +using std::isnan; +#endif + +namespace operations_research { + +// ScopedFloatingPointEnv is used to easily enable Floating-point exceptions. +// The initial state is automatically restored when the object is deleted. +// +// Note(user): For some reason, this causes an FPE exception to be triggered for +// unknown reasons when compiled in 32 bits. Because of this, we do not turn +// on FPE exception if ARCH_K8 is not defined. +// +// TODO(user): Make it work on 32 bits. +// TODO(user): Make it work on msvc, currently calls to _controlfp crash. + +class ScopedFloatingPointEnv { + public: + ScopedFloatingPointEnv() { +#if defined(_MSC_VER) + // saved_control_ = _controlfp(0, 0); +#elif defined(ARCH_K8) + CHECK_EQ(0, fegetenv(&saved_fenv_)); +#endif + } + + ~ScopedFloatingPointEnv() { +#if defined(_MSC_VER) + // CHECK_EQ(saved_control_, _controlfp(saved_control_, 0xFFFFFFFF)); +#elif defined(ARCH_K8) + CHECK_EQ(0, fesetenv(&saved_fenv_)); +#endif + } + + void EnableExceptions(int excepts) { +#if defined(_MSC_VER) + // _controlfp(static_cast(excepts), _MCW_EM); +#elif defined(ARCH_K8) + CHECK_EQ(0, fegetenv(&fenv_)); + excepts &= FE_ALL_EXCEPT; +#ifdef __APPLE__ + fenv_.__control &= ~excepts; +#else // Linux + fenv_.__control_word &= ~excepts; +#endif + fenv_.__mxcsr &= ~(excepts << 7); + CHECK_EQ(0, fesetenv(&fenv_)); +#endif + } + + private: +#if defined(_MSC_VER) + // unsigned int saved_control_; +#elif defined(ARCH_K8) + fenv_t fenv_; + mutable fenv_t saved_fenv_; +#endif +}; + +// The following macro does not change "var", but forces gcc to consider it +// being modified. This can be used to avoid wrong over-optimizations by gcc. +// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47617 for an explanation. +#ifdef NDEBUG +#define TOUCH(var) asm volatile("" : "+X"(var)) +#else +#define TOUCH(var) +#endif + +#if (defined(__i386__) || defined(__x86_64__)) && defined(__linux__) && \ + !defined(__ANDROID__) +inline fpu_control_t GetFPPrecision() { + fpu_control_t status = 0; // Initialized to zero to please memory sanitizer. + _FPU_GETCW(status); + return status & (_FPU_EXTENDED | _FPU_DOUBLE | _FPU_SINGLE); +} + + +// CPU precision control. Parameters can be: +// _FPU_EXTENDED, _FPU_DOUBLE or _FPU_SINGLE. +inline void SetFPPrecision(fpu_control_t precision) { + fpu_control_t status = 0; // Initialized to zero to please memory sanitizer. + _FPU_GETCW(status); + TOUCH(status); + status &= ~(_FPU_EXTENDED | _FPU_DOUBLE | _FPU_SINGLE); + status |= precision; + _FPU_SETCW(status); + DCHECK_EQ(precision, GetFPPrecision()); +} +#endif // (defined(__i386__) || defined(__x86_64__)) && defined(__linux__) && \ + // !defined(__ANDROID__) + +#undef TOUCH + +template +inline bool IsPositiveOrNegativeInfinity(FloatType x) { + return x == std::numeric_limits::infinity() || + x == -std::numeric_limits::infinity(); +} + +// Tests whether x and y are close to one another using absolute and relative +// tolerances. +// Returns true if |x - y| <= a (with a being the absolute_tolerance). +// The above case is useful for values that are close to zero. +// Returns true if |x - y| <= std::max(|x|, |y|) * r. (with r being the relative +// tolerance.) +// The cases for infinities are treated separately to avoid generating NaNs. +template +bool AreWithinAbsoluteOrRelativeTolerances(FloatType x, FloatType y, + FloatType relative_tolerance, + FloatType absolute_tolerance) { + DCHECK_LE(0.0, relative_tolerance); + DCHECK_LE(0.0, absolute_tolerance); + DCHECK_GT(1.0, relative_tolerance); + if (IsPositiveOrNegativeInfinity(x) || IsPositiveOrNegativeInfinity(y)) { + return x == y; + } + const FloatType difference = fabs(x - y); + if (difference <= absolute_tolerance) { + return true; + } + const FloatType largest_magnitude = std::max(fabs(x), fabs(y)); + return difference <= largest_magnitude * relative_tolerance; +} + +// Tests whether x and y are close to one another using an absolute tolerance. +// Returns true if |x - y| <= a (with a being the absolute_tolerance). +// The cases for infinities are treated separately to avoid generating NaNs. +template +bool AreWithinAbsoluteTolerance(FloatType x, FloatType y, + FloatType absolute_tolerance) { + DCHECK_LE(0.0, absolute_tolerance); + if (IsPositiveOrNegativeInfinity(x) || IsPositiveOrNegativeInfinity(y)) { + return x == y; + } + return fabs(x - y) <= absolute_tolerance; +} + +// Returns true if x is less than y or slighlty greater than y with the given +// absolute or relative tolerance. +template +bool IsSmallerWithinTolerance(FloatType x, FloatType y, FloatType tolerance) { + if (IsPositiveOrNegativeInfinity(y)) return x <= y; + return x <= y + tolerance * std::max(1.0, std::min(std::abs(x), std::abs(y))); +} + +// Returns true if x is within tolerance of any integer. Always returns +// false for x equal to +/- infinity. +template +inline bool IsIntegerWithinTolerance(FloatType x, FloatType tolerance) { + DCHECK_LE(0.0, tolerance); + if (IsPositiveOrNegativeInfinity(x)) return false; + return std::abs(x - std::round(x)) <= tolerance; +} + +// Handy alternatives to EXPECT_NEAR(), using relative and absolute tolerance +// instead of relative tolerance only, and with a proper support for infinity. +// TODO(user): investigate moving this to ortools/base/ or some other place. +#define EXPECT_COMPARABLE(expected, obtained, epsilon) \ + EXPECT_TRUE(operations_research::AreWithinAbsoluteOrRelativeTolerances( \ + expected, obtained, epsilon, epsilon)) \ + << obtained << " != expected value " << expected \ + << " within epsilon = " << epsilon; + +#define EXPECT_NOTCOMPARABLE(expected, obtained, epsilon) \ + EXPECT_FALSE(operations_research::AreWithinAbsoluteOrRelativeTolerances( \ + expected, obtained, epsilon, epsilon)) \ + << obtained << " == expected value " << expected \ + << " within epsilon = " << epsilon; + +// Given an array of doubles, this computes a positive scaling factor such that +// the scaled doubles can then be rounded to integers with little or no loss of +// precision, and so that the L1 norm of these integers is <= max_sum. More +// precisely, the following formulas will hold: +// - For all i, |round(factor * x[i]) / factor - x[i]| <= error * |x[i]| +// - The sum over i of |round(factor * x[i])| <= max_sum. +// +// The algorithm tries to minimize "error" (which is the relative error for one +// coefficient). Note however than in really broken cases, the error might be +// infinity and the factor zero. +// +// Note on the algorithm: +// - It only uses factors of the form 2^n (i.e. ldexp(1.0, n)) for simplicity. +// - The error will be zero in many practical instances. For example, if x +// contains only integers with low magnitude; or if x contains doubles whose +// exponents cover a small range. +// - It chooses the factor as high as possible under the given constraints, as +// a result the numbers produced may be large. To balance this, we recommend +// to divide the scaled integers by their gcd() which will result in no loss +// of precision and will help in many practical cases. +// +// TODO(user): incorporate the gcd computation here? The issue is that I am +// not sure if I just do factor /= gcd that round(x * factor) will be the same. +void GetBestScalingOfDoublesToInt64(const std::vector& x, + int64 max_absolute_sum, + double* scaling_factor, + double* max_relative_coeff_error); + +// Same as the function above, but enforces that +// - The sum over i of std::min(0, round(factor * x[i])) >= -max_sum. +// - The sum over i of std::max(0, round(factor * x[i])) <= max_sum. +// For any possible values of the x[i] such that x[i] is in [lb[i], ub[i]]. +// +// This also computes the max_scaled_sum_error which is a bound on the maximum +// difference between the exact scaled sum and the rounded one. One needs to +// divide this by scaling_factor to have the maximum absolute error on the +// original sum. +void GetBestScalingOfDoublesToInt64(const std::vector& x, + const std::vector& lb, + const std::vector& ub, + int64 max_absolute_sum, + double* scaling_factor, + double* max_relative_coeff_error, + double* max_scaled_sum_error); + +// Returns the Greatest Common Divisor of the numbers +// round(fabs(x[i] * scaling_factor)). The numbers 0 are ignored and if they are +// all zero then the result is 1. Note that round(fabs()) is the same as +// fabs(round()) since the numbers are rounded away from zero. +int64 ComputeGcdOfRoundedDoubles(const std::vector& x, + double scaling_factor); + +// Returns alpha * x + (1 - alpha) * y. +template +inline FloatType Interpolate(FloatType x, FloatType y, FloatType alpha) { + return alpha * x + (1 - alpha) * y; +} + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_FP_UTILS_H_ diff --git a/thirdparty/linux/include/ortools/util/functions_swig_helpers.h b/thirdparty/linux/include/ortools/util/functions_swig_helpers.h new file mode 100644 index 0000000..eed56e4 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/functions_swig_helpers.h @@ -0,0 +1,89 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_FUNCTIONS_SWIG_HELPERS_H_ +#define OR_TOOLS_UTIL_FUNCTIONS_SWIG_HELPERS_H_ + +// This file contains class definitions for the wrapping of C++ std::functions +// in Java and C#. It is #included by java/functions.i and +// csharp/functions.i. + +#include +#include + +#include "ortools/base/integral_types.h" + +namespace operations_research { +namespace swig_util { +class LongToLong { + public: + virtual ~LongToLong() {} + virtual int64 Run(int64) = 0; +}; + +class LongLongToLong { + public: + virtual ~LongLongToLong() {} + virtual int64 Run(int64, int64) = 0; +}; + +class IntIntToLong { + public: + virtual ~IntIntToLong() {} + virtual int64 Run(int, int) = 0; +}; + +class LongLongLongToLong { + public: + virtual ~LongLongLongToLong() {} + virtual int64 Run(int64, int64, int64) = 0; +}; + +class LongToBoolean { + public: + virtual ~LongToBoolean() {} + virtual bool Run(int64) = 0; +}; + +class VoidToString { + public: + virtual ~VoidToString() {} + virtual std::string Run() = 0; +}; + +class VoidToBoolean { + public: + virtual ~VoidToBoolean() {} + virtual bool Run() = 0; +}; + +class LongLongLongToBoolean { + public: + virtual ~LongLongLongToBoolean() {} + virtual bool Run(int64 i, int64 j, int64 k) = 0; +}; + +class LongToVoid { + public: + virtual ~LongToVoid() {} + virtual void Run(int64 i) = 0; +}; + +class VoidToVoid { + public: + virtual ~VoidToVoid() {} + virtual void Run() = 0; +}; +} // namespace swig_util +} // namespace operations_research +#endif // OR_TOOLS_UTIL_FUNCTIONS_SWIG_HELPERS_H_ diff --git a/thirdparty/linux/include/ortools/util/functions_swig_test_helpers.h b/thirdparty/linux/include/ortools/util/functions_swig_test_helpers.h new file mode 100644 index 0000000..433a122 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/functions_swig_test_helpers.h @@ -0,0 +1,74 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_FUNCTIONS_SWIG_TEST_HELPERS_H_ +#define OR_TOOLS_UTIL_FUNCTIONS_SWIG_TEST_HELPERS_H_ + +// These are simple static methods to test std::function in the swig wrapper +// tests. +// +// NOTE: It was simpler to use static methods of a public class rather than +// simple static methods; because the Java wrapping of the latter made them hard +// to find (whereas the class methods are easy to find). + +#include +#include "ortools/base/integral_types.h" + +namespace operations_research { +class FunctionSwigTestHelpers { + public: + static std::string NoOpVoidToString(std::function fun) { return fun(); } + + static int64 NoOpInt64ToInt64(std::function fun, int64 x) { + return fun(x); + } + + static int64 NoOpInt64PairToInt64(std::function fun, + int64 x, int64 y) { + return fun(x, y); + } + + static int64 NoOpIntPairToInt64(std::function fun, int x, + int y) { + return fun(x, y); + } + + static int64 NoOpInt64TripleToInt64( + std::function fun, int64 x, int64 y, + int64 z) { + return fun(x, y, z); + } + + static bool NoOpInt64TripleToBool( + std::function fun, int64 x, int64 y, int64 z) { + return fun(x, y, z); + } + + static bool NoOpInt64ToBool(std::function fun, int64 x) { + return fun(x); + } + + static bool NoOpVoidToBool(std::function fun) { return fun(); } + + static void NoOpInt64ToVoid(std::function fun, int64 x) { + fun(x); + } + + static void NoOpVoidToVoid(std::function fun) { fun(); } + + static void NoOpStringToVoid(std::function fun, std::string x) { + fun(x); + } +}; +} // namespace operations_research +#endif // OR_TOOLS_UTIL_FUNCTIONS_SWIG_TEST_HELPERS_H_ diff --git a/thirdparty/linux/include/ortools/util/graph_export.h b/thirdparty/linux/include/ortools/util/graph_export.h new file mode 100644 index 0000000..01d7df2 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/graph_export.h @@ -0,0 +1,59 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_UTIL_GRAPH_EXPORT_H_ +#define OR_TOOLS_UTIL_GRAPH_EXPORT_H_ + +#include + +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/file.h" + +namespace operations_research { +// ----- Export to graph file ----- + +// This class will allow the creation of a graph representation. +// It supports different formats (see GraphFormat). +class GraphExporter { + public: + // Supported graph formats. + enum GraphFormat { + DOT_FORMAT, + GML_FORMAT, + }; + + virtual ~GraphExporter(); + + // Write the header of the graph file. + virtual void WriteHeader(const std::string& name) = 0; + + // Write the footer of the graph file. + virtual void WriteFooter() = 0; + + // Write node in GML or DOT format. + virtual void WriteNode(const std::string& name, const std::string& label, + const std::string& shape, const std::string& color) = 0; + + // Adds one link in the generated graph. + virtual void WriteLink(const std::string& source, const std::string& destination, + const std::string& label) = 0; + + // Creates a graph exporter that will write to file with a given format. + static GraphExporter* MakeFileExporter(File* const file, + GraphExporter::GraphFormat format); +}; +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_GRAPH_EXPORT_H_ diff --git a/thirdparty/linux/include/ortools/util/iterators.h b/thirdparty/linux/include/ortools/util/iterators.h new file mode 100644 index 0000000..fbd5495 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/iterators.h @@ -0,0 +1,179 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Helper classes to make it easy to implement range-based for loops. + +#ifndef OR_TOOLS_UTIL_ITERATORS_H_ +#define OR_TOOLS_UTIL_ITERATORS_H_ + +#include +#include + +namespace operations_research { + +// This is useful for wrapping iterators of a class that support many different +// iterations. For instance, on a Graph class, one can write: +// +// BeginEndWrapper Graph::OutgoingArcs(NodeInde node) +// const { +// return BeginEndRange( +// OutgoingArcIterator(*this, node, /*at_end=*/false), +// OutgoingArcIterator(*this, node, /*at_end=*/true)); +// } +// +// And a client will use it like this: +// +// for (const ArcIndex arc : graph.OutgoingArcs(node)) { ... } +template +class BeginEndWrapper { + public: + using const_iterator = Iterator; + using value_type = typename std::iterator_traits::value_type; + + BeginEndWrapper(Iterator begin, Iterator end) : begin_(begin), end_(end) {} + Iterator begin() const { return begin_; } + Iterator end() const { return end_; } + + bool empty() const { return begin() == end(); } + + private: + const Iterator begin_; + const Iterator end_; +}; + +// Inline wrapper methods, to make the client code even simpler. +// The harm of overloading is probably less than the benefit of the nice, +// compact name, in this special case. +template +inline BeginEndWrapper BeginEndRange(Iterator begin, Iterator end) { + return BeginEndWrapper(begin, end); +} +template +inline BeginEndWrapper BeginEndRange( + std::pair begin_end) { + return BeginEndWrapper(begin_end.first, begin_end.second); +} + +// Shortcut for BeginEndRange(multimap::equal_range(key)). +// TODO(user): go further and expose only the values, not the pairs (key, +// values) since the caller already knows the key. +template +inline BeginEndWrapper EqualRange( + MultiMap& multi_map, const typename MultiMap::key_type& key) { + return BeginEndRange(multi_map.equal_range(key)); +} +template +inline BeginEndWrapper EqualRange( + const MultiMap& multi_map, const typename MultiMap::key_type& key) { + return BeginEndRange(multi_map.equal_range(key)); +} + +// The Reverse() function allows to reverse the iteration order of a range-based +// for loop over a container that support STL reverse iterators. +// The syntax is: +// for (const type& t : Reverse(container_of_t)) { ... } +template +class BeginEndReverseIteratorWrapper { + public: + explicit BeginEndReverseIteratorWrapper(const Container& c) : c_(c) {} + typename Container::const_reverse_iterator begin() const { + return c_.rbegin(); + } + typename Container::const_reverse_iterator end() const { return c_.rend(); } + + private: + const Container& c_; +}; +template +BeginEndReverseIteratorWrapper Reverse(const Container& c) { + return BeginEndReverseIteratorWrapper(c); +} + +// Simple iterator on an integer range, see IntegerRange below. +template +class IntegerRangeIterator + : public std::iterator { + public: + explicit IntegerRangeIterator(IntegerType value) : index_(value) {} + IntegerRangeIterator(const IntegerRangeIterator& other) + : index_(other.index_) {} + IntegerRangeIterator& operator=(const IntegerRangeIterator& other) { + index_ = other.index_; + } + bool operator!=(const IntegerRangeIterator& other) const { + // This may seems weird, but using < instead of != avoid almost-infinite + // loop if one use IntegerRange(1, 0) below for instance. + return index_ < other.index_; + } + bool operator==(const IntegerRangeIterator& other) const { + return index_ == other.index_; + } + IntegerType operator*() const { return index_; } + IntegerRangeIterator& operator++() { + ++index_; + return *this; + } + IntegerRangeIterator operator++(int) { + IntegerRangeIterator previous_position(*this); + ++index_; + return previous_position; + } + + private: + IntegerType index_; +}; + +// Allows to easily construct nice functions for range-based for loop. +// This can be used like this: +// +// for (const int i : IntegerRange(0, 10)) { ... } +// +// But it main purpose is to be used as return value for more complex classes: +// +// for (const ArcIndex arc : graph.AllOutgoingArcs()); +// for (const NodeIndex node : graph.AllNodes()); +// for (const EntryIndex i : sparse_column.AllEntryIndex()); +template +class IntegerRange : public BeginEndWrapper> { + public: + IntegerRange(IntegerType begin, IntegerType end) + : BeginEndWrapper>( + IntegerRangeIterator(begin), + IntegerRangeIterator(end)) {} +}; + +// Allow iterating over a std::vector as a mutable std::vector. +template +struct MutableVectorIteration { + explicit MutableVectorIteration(std::vector* v) : v_(v) {} + struct Iterator { + explicit Iterator(typename std::vector::iterator it) : it_(it) {} + T* operator*() { return &*it_; } + Iterator& operator++() { + it_++; + return *this; + } + bool operator!=(const Iterator& other) const { return other.it_ != it_; } + + private: + typename std::vector::iterator it_; + }; + Iterator begin() { return Iterator(v_->begin()); } + Iterator end() { return Iterator(v_->end()); } + + private: + std::vector* const v_; +}; +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_ITERATORS_H_ diff --git a/thirdparty/linux/include/ortools/util/monoid_operation_tree.h b/thirdparty/linux/include/ortools/util/monoid_operation_tree.h new file mode 100644 index 0000000..49b31cf --- /dev/null +++ b/thirdparty/linux/include/ortools/util/monoid_operation_tree.h @@ -0,0 +1,251 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_UTIL_MONOID_OPERATION_TREE_H_ +#define OR_TOOLS_UTIL_MONOID_OPERATION_TREE_H_ + +#include +#include + +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/stringprintf.h" + +namespace operations_research { + +// A monoid is an algebraic structure consisting of a set S with an associative +// binary operation * :S x S -> S that has an identity element. +// Associative means a*(b*c) = (a*b)*c for all a,b,c in S. +// An identity element is an element e in S such that for all a in S, +// e*a = a*e = a. +// See http://en.wikipedia.org/wiki/Monoid for more details. +// +// A MonoidOperationTree is a data structure that maintains a product +// a_1 * a_2 * ... * a_n for a given (fixed) n, and that supports the +// following functions: +// - Setting the k-th operand to a given value in O(log n) calls to the * +// operation +// - Querying the result in O(1) +// +// Note that the monoid is not required to be commutative. +// +// The parameter class T represents an element of the set S. +// It must: +// * Have a public no-argument constructor producing the identity element. +// * Have a = operator method that sets its value to the given one. +// * Have a Compute(const T& left, const T& right) method that sets its value +// to the result of the binary operation for the two given operands. +// * Have a std::string DebugString() const method. +// +// Possible use cases are: +// * Maintain a sum or a product of doubles, with a guarantee that the queried +// result is independent of the order of past numerical issues +// * Maintain a product of identically sized square matrices, which is an +// example of use with non-commutative operations. +template +class MonoidOperationTree { + public: + // Constructs a MonoidOperationTree able to store 'size' operands. + explicit MonoidOperationTree(int size); + + // Returns the root of the tree, containing the result of the operation. + const T& result() const { return *result_; } + + // Resets the argument of given index. + void Reset(int argument_index); + + // Sets the argument of given index. + void Set(int argument_index, const T& argument); + + // Resets all arguments. + void Clear(); + + // Returns the leaf node corresponding to the given argument index. + const T& GetOperand(int argument_index) const { + return nodes_[PositionOfLeaf(argument_index)]; + } + + // Dive down a branch of the operation tree, and then come back up. + template + void DiveInTree(Diver* const diver) const { + DiveInTree(0, diver); + } + + std::string DebugString() const; + + private: + // Computes the index of the first leaf for the given size. + static int ComputeLeafOffset(int size); + + // Computes the total number of nodes we need to store non-leaf nodes and + // leaf nodes. + static int ComputeNumberOfNodes(int leaf_offset); + + // Computes the whole path from the node of given position up to the root, + // excluding the bottom node. + void ComputeAbove(int position); + + // Computes the node of given position, and no other. + void Compute(int position); + + // Returns the position of the leaf node of given index. + int PositionOfLeaf(int index) const { return leaf_offset_ + index; } + + // Returns true if the node of given position is a leaf. + bool IsLeaf(int position) const { return position >= leaf_offset_; } + + // Returns the index of the argument stored in the node of given position. + int ArgumentIndexOfLeafPosition(int position) const { + DCHECK(IsLeaf(position)); + return position - leaf_offset_; + } + + template + void DiveInTree(int position, Diver* diver) const; + + static int father(int pos) { return (pos - 1) >> 1; } + static int left(int pos) { return (pos << 1) + 1; } + static int right(int pos) { return (pos + 1) << 1; } + + // The number of arguments that can be stored in this tree. That is, the + // number of used leaves. (There may be unused leaves, too) + const int size_; + + // The index of the first leaf. + const int leaf_offset_; + + // Number of nodes, both non-leaves and leaves. + const int num_nodes_; + + // All the nodes, both non-leaves and leaves. + std::vector nodes_; + + // A pointer to the root node + T const* result_; + + DISALLOW_COPY_AND_ASSIGN(MonoidOperationTree); +}; + +// --------------------------------------------------------------------- // +// Implementation +// --------------------------------------------------------------------- // + +template +int MonoidOperationTree::ComputeLeafOffset(int size) { + int smallest_pow_two_not_less_than_size = 1; + while (smallest_pow_two_not_less_than_size < size) { + smallest_pow_two_not_less_than_size <<= 1; + } + return std::max(1, smallest_pow_two_not_less_than_size - 1); +} + +template +int MonoidOperationTree::ComputeNumberOfNodes(int leaf_offset) { + // leaf_offset should be a power of 2 minus 1. + DCHECK_EQ(0, (leaf_offset) & (leaf_offset + 1)); + const int num_leaves = leaf_offset + 1; + const int num_nodes = leaf_offset + num_leaves; + DCHECK_GE(num_nodes, 3); // We need at least the root and its 2 children + return num_nodes; +} + +template +MonoidOperationTree::MonoidOperationTree(int size) + : size_(size), + leaf_offset_(ComputeLeafOffset(size)), + num_nodes_(ComputeNumberOfNodes(leaf_offset_)), + nodes_(num_nodes_, T()), + result_(&(nodes_[0])) {} + +template +void MonoidOperationTree::Clear() { + const int size = nodes_.size(); + nodes_.assign(size, T()); +} + +template +void MonoidOperationTree::Reset(int argument_index) { + Set(argument_index, T()); +} + +template +void MonoidOperationTree::Set(int argument_index, const T& argument) { + CHECK_LT(argument_index, size_); + const int position = leaf_offset_ + argument_index; + nodes_[position] = argument; + ComputeAbove(position); +} + +template +void MonoidOperationTree::ComputeAbove(int position) { + int pos = father(position); + while (pos > 0) { + Compute(pos); + pos = father(pos); + } + Compute(0); +} + +template +void MonoidOperationTree::Compute(int position) { + const T& left_child = nodes_[left(position)]; + const T& right_child = nodes_[right(position)]; + nodes_[position].Compute(left_child, right_child); +} + +template +std::string MonoidOperationTree::DebugString() const { + std::string out; + int layer = 0; + for (int i = 0; i < num_nodes_; ++i) { + if (((i + 1) & i) == 0) { + // New layer + StringAppendF(&out, "-------------- Layer %d ---------------\n", layer); + ++layer; + } + StringAppendF(&out, "Position %d: %s\n", i, + nodes_[i].DebugString().c_str()); + } + return out; +} + +template +template +void MonoidOperationTree::DiveInTree(int position, Diver* diver) const { + // Are we at a leaf? + if (IsLeaf(position)) { + const int index = ArgumentIndexOfLeafPosition(position); + const T& argument = nodes_[position]; + diver->OnArgumentReached(index, argument); + } else { + const T& current = nodes_[position]; + const T& left_child = nodes_[left(position)]; + const T& right_child = nodes_[right(position)]; + if (diver->ChooseGoLeft(current, left_child, right_child)) { + // Go left + DiveInTree(left(position), diver); + // Come back up + diver->OnComeBackFromLeft(current, left_child, right_child); + } else { + // Go right + DiveInTree(right(position), diver); + // Come back up + diver->OnComeBackFromRight(current, left_child, right_child); + } + } +} + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_MONOID_OPERATION_TREE_H_ diff --git a/thirdparty/linux/include/ortools/util/permutation.h b/thirdparty/linux/include/ortools/util/permutation.h new file mode 100644 index 0000000..8e7898c --- /dev/null +++ b/thirdparty/linux/include/ortools/util/permutation.h @@ -0,0 +1,217 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +// Classes for permuting indexable, ordered containers of data without +// depending on that data to be accessible in any particular way. The +// client needs to give us two things: +// 1. a permutation to apply to some container(s) of data, and +// 2. a description of how to move data around in the container(s). +// +// The permutation (1) comes to us in the form of an array argument to +// PermutationApplier::Apply(), along with index values that tell us +// where in that array the permutation of interest lies. Typically +// those index values will span the entire array that describes the +// permutation. +// +// Applying a permutation involves decomposing the permutation into +// disjoint cycles and walking each element of the underlying data one +// step around the unique cycle in which it participates. The +// decomposition into disjoint cycles is done implicitly on the fly as +// the code in PermutationApplier::Apply() advances through the array +// describing the permutation. As an important piece of bookkeeping to +// support the decomposition into cycles, the elements of the +// permutation array typically get modified somehow to indicate which +// ones have already been used. +// +// At first glance, it would seem that if the containers are +// indexable, we don't need anything more complicated than just the +// permutation and the container of data we want to permute; it would +// seem we can just use the container's operator[] to retrieve and +// assign elements within the container. Unfortunately it's not so +// simple because the containers of interest can be indexable without +// providing any consistent way of accessing their contents that +// applies to all the containers of interest. For instance, if we +// could insist that every indexable container must define an lvalue +// operator[]() we could simply use that for the assignments we need +// to do while walking around cycles of the permutation. But we cannot +// insist on any such thing. To see why, consider the PackedArray +// class template in ortools/util/packed_array.h +// where operator[] is supplied for rvalues, but because each logical +// array element is packed across potentially multiple instances of +// the underlying data type that the C++ language knows about, there +// is no way to have a C++ reference to an element of a +// PackedArray. There are other such examples besides PackedArray, +// too. This is the main reason we need a codified description (2) of +// how to move data around in the indexable container. That +// description comes to us via the PermutationApplier constructor's +// argument which is a PermutationCycleHandler instance. Such an +// object has three important methods defined: SetTempFromIndex(), +// SetIndexFromIndex(), and SetIndexFromTemp(). Those methods embody +// all we need to know about how to move data in the indexable +// container(s) underlying the PermutationCycleHandler. +// +// Another reason we need the description (2) of how to move elements +// around in the container(s) is that it is often important to permute +// side-by-side containers of elements according to the same +// permutation. This situation, too, is covered by defining a +// PermutationCycleHandler that knows about multiple underlying +// indexable containers. +// +// The above-mentioned PermutationCycleHandler methods embody +// knowledge of how to assign elements. It happens that +// PermutationCycleHandler is also a convenient place to embody the +// knowledge of how to keep track of which permutation elements have +// been consumed by the process of walking data around cycles. We +// depend on the PermutationCycleHandler instance we're given to +// define SetSeen() and Unseen() methods for that purpose. +// +// For the common case in which elements can be accessed using +// operator[](), we provide the class template +// ArrayIndexCycleHandler. + +#ifndef OR_TOOLS_UTIL_PERMUTATION_H_ +#define OR_TOOLS_UTIL_PERMUTATION_H_ + +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" + +namespace operations_research { + +// Abstract base class template defining the interface needed by +// PermutationApplier to handle a single cycle of a permutation. +template +class PermutationCycleHandler { + public: + // Sets the internal temporary storage from the given index in the + // underlying container(s). + virtual void SetTempFromIndex(IndexType source) = 0; + + // Moves a data element one step along its cycle. + virtual void SetIndexFromIndex(IndexType source, + IndexType destination) const = 0; + + // Sets a data element from the temporary. + virtual void SetIndexFromTemp(IndexType destination) const = 0; + + // Marks an element of the permutation as handled by + // PermutationHandler::Apply(), meaning that we have read the + // corresponding value from the data to be permuted, and put that + // value somewhere (either in the temp or in its ultimate + // destination in the data. + // + // This method must be overridden in implementations where it is + // called. If an implementation doesn't call it, no need to + // override. + virtual void SetSeen(IndexType* unused_permutation_element) const { + LOG(FATAL) << "Base implementation of SetSeen() must not be called."; + } + + // Returns true iff the given element of the permutation is unseen, + // meaning that it has not yet been handled by + // PermutationApplier::Apply(). + // + // This method must be overridden in implementations where it is + // called. If an implementation doesn't call it, no need to + // override. + virtual bool Unseen(IndexType unused_permutation_element) const { + LOG(FATAL) << "Base implementation of Unseen() must not be called."; + return false; + } + + virtual ~PermutationCycleHandler() {} + + protected: + PermutationCycleHandler() {} + + private: + DISALLOW_COPY_AND_ASSIGN(PermutationCycleHandler); +}; + +// A generic cycle handler class for the common case in which the +// object to be permuted is indexable with T& operator[](int), and the +// permutation is represented by a mutable array of nonnegative +// int-typed index values. To mark a permutation element as seen, we +// replace it by its ones-complement value. +template +class ArrayIndexCycleHandler : public PermutationCycleHandler { + public: + explicit ArrayIndexCycleHandler(DataType* data) : data_(data) {} + + void SetTempFromIndex(IndexType source) override { temp_ = data_[source]; } + void SetIndexFromIndex(IndexType source, + IndexType destination) const override { + data_[destination] = data_[source]; + } + void SetIndexFromTemp(IndexType destination) const override { + data_[destination] = temp_; + } + void SetSeen(IndexType* permutation_element) const override { + *permutation_element = -*permutation_element - 1; + } + bool Unseen(IndexType permutation_element) const override { + return permutation_element >= 0; + } + + private: + // Pointer to the base of the array of data to be permuted. + DataType* data_; + + // Temporary storage for the one extra element we need. + DataType temp_; + + DISALLOW_COPY_AND_ASSIGN(ArrayIndexCycleHandler); +}; + +// Note that this template is not implemented in an especially +// performance-sensitive way. In particular, it makes multiple virtual +// method calls for each element of the permutation. +template +class PermutationApplier { + public: + explicit PermutationApplier(PermutationCycleHandler* cycle_handler) + : cycle_handler_(cycle_handler) {} + + void Apply(IndexType permutation[], int permutation_start, + int permutation_end) { + for (IndexType current = permutation_start; current < permutation_end; + ++current) { + IndexType next = permutation[current]; + // cycle_start is only for debugging. + const IndexType cycle_start = current; + if (cycle_handler_->Unseen(next)) { + cycle_handler_->SetSeen(&permutation[current]); + DCHECK(!cycle_handler_->Unseen(permutation[current])); + cycle_handler_->SetTempFromIndex(current); + while (cycle_handler_->Unseen(permutation[next])) { + cycle_handler_->SetIndexFromIndex(next, current); + current = next; + next = permutation[next]; + cycle_handler_->SetSeen(&permutation[current]); + DCHECK(!cycle_handler_->Unseen(permutation[current])); + } + cycle_handler_->SetIndexFromTemp(current); + // Set current back to the start of this cycle. + current = next; + } + DCHECK_EQ(cycle_start, current); + } + } + + private: + PermutationCycleHandler* cycle_handler_; + + DISALLOW_COPY_AND_ASSIGN(PermutationApplier); +}; +} // namespace operations_research +#endif // OR_TOOLS_UTIL_PERMUTATION_H_ diff --git a/thirdparty/linux/include/ortools/util/piecewise_linear_function.h b/thirdparty/linux/include/ortools/util/piecewise_linear_function.h new file mode 100644 index 0000000..15b02c7 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/piecewise_linear_function.h @@ -0,0 +1,283 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file implements piecewise linear functions over int64. It is built +// by inserting segments. +// +// This class maintains a minimal internal representation and checks for +// overflow. + +#ifndef OR_TOOLS_UTIL_PIECEWISE_LINEAR_FUNCTION_H_ +#define OR_TOOLS_UTIL_PIECEWISE_LINEAR_FUNCTION_H_ + +#include +#include +#include +#include +#include + +#include "ortools/base/basictypes.h" +#include "ortools/base/integral_types.h" +#include "ortools/base/macros.h" + +#include "ortools/util/saturated_arithmetic.h" + +namespace operations_research { +// This structure stores one straight line. It contains the start point, the +// end point and the slope. +// It is defined for x values between start_x and end_x. +class PiecewiseSegment { + public: + PiecewiseSegment(int64 point_x, int64 point_y, int64 slope, + int64 other_point_x); + + // Returns the value of the segment at point x. + int64 Value(int64 x) const; + // Returns the start of the segment's domain. + int64 start_x() const { return start_x_; } + // Returns the end of the segment's domain. + int64 end_x() const { return end_x_; } + // Returns the value at the start of the segment's domain. + int64 start_y() const { return Value(start_x_); } + // Returns the value at the end of the segment's domain. + int64 end_y() const { return Value(end_x_); } + // Returns the segment's slope. + int64 slope() const { return slope_; } + // Returns the intersection of the segment's extension with the y axis. + int64 intersection_y() const { return intersection_y_; } + + // Comparison method useful for sorting a sequence of segments. + static bool SortComparator(const PiecewiseSegment& segment1, + const PiecewiseSegment& segment2); + // Comparison method useful for finding in which segment a point belongs. + static bool FindComparator(int64 point, const PiecewiseSegment& segment); + + // Expands segment to the specified endpoint, if it is further + // than the current endpoint. The reference point of the segment + // doesn't change for overflow reasons. + void ExpandEnd(int64 end_x); + // Adds 'constant' to the 'x' the segments. + void AddConstantToX(int64 constant); + // Adds 'constant' to the 'y' the segments. + void AddConstantToY(int64 constant); + + std::string DebugString() const; + + private: + // Computes the value of the segment at point x, taking care of possible + // overflows when the value x follow the x coordinate of the segment's + // reference point. + int64 SafeValuePostReference(int64 x) const; + // Computes the value of the segment at point x, taking care of possible + // overflows when the value x follow the x coordinate of the segment's + // reference point. + int64 SafeValuePreReference(int64 x) const; + + // The x coordinate of the segment's left endpoint. + int64 start_x_; + // The x coordinate of the segment's right endpoint. + int64 end_x_; + // The segment's slope. + int64 slope_; + // The x coordinate of the segment's finite reference point. + int64 reference_x_; + // The y coordinate of the segment's finite reference point. + int64 reference_y_; + // The intersection of the segment's extension with the y axis. + int64 intersection_y_; +}; + +// In mathematics, a piecewise linear function is a function composed +// of straight-line, non overlapping sections. +class PiecewiseLinearFunction { + public: + static const int kNotFound; + + // This API provides a factory for creating different families of Piecewise + // Linear Functions based on specific properties of each family. The + // PiecewiseLinearFunction is composed by a set of PiecwiseSegments and upon + // creation is not modifiable but with the provided function operations. + // The object returned by any of these builders in the factory is owned by + // the client code. + + // Builds the most generic form of multiple-segment piecewise linear function + // supporting domain holes. For a fixed index i the elements in points_x[i] + // points_y[i], slopes[i], other_points_x[i] represent a segment. + // The point (points_x[i], points_y[i]) represents one of the endpoints of + // the segment and the other_points_x[i] represents the x coordinate of the + // other endpoint which may precede, follow or coincide with points_x[i]. + // The segments represented by these vectors should not be overlapping. + // Common endpoints are allowed. + static PiecewiseLinearFunction* CreatePiecewiseLinearFunction( + std::vector points_x, std::vector points_y, + std::vector slopes, std::vector other_points_x); + + // Builds a multiple-segment step function with continuous or non continuous + // domain. The arguments have the same semantics with the generic builder of + // the piecewise linear function. In the step function all the slopes are 0. + static PiecewiseLinearFunction* CreateStepFunction( + std::vector points_x, std::vector points_y, + std::vector other_points_x); + + // Builds a multiple-segment piecewise linear function with domain from + // from kint64min to kint64max with n points and n+1 slopes. Each slope + // stops at the point with the corresponding index apart from the last one + // which stops at kint64max. The first slope stops at the first point at + // the level specified. + static PiecewiseLinearFunction* CreateFullDomainFunction( + int64 initial_level, std::vector points_x, + std::vector slopes); + + // Builds a function consisting of one segment. + static PiecewiseLinearFunction* CreateOneSegmentFunction(int64 point_x, + int64 point_y, + int64 slope, + int64 other_point_x); + + // Builds a function consisting of one ray starting at the specified + // x and y coordinates with the specified slope. + static PiecewiseLinearFunction* CreateRightRayFunction(int64 point_x, + int64 point_y, + int64 slope); + + // Builds a function consisting of one ray starting at the specified + // x and y coordinates with the specified slope. + static PiecewiseLinearFunction* CreateLeftRayFunction(int64 point_x, + int64 point_y, + int64 slope); + + // Builds a two-segment fixed charge piecewise linear cost function. For + // values less than zero, the cost is zero. For values greater than zero, + // cost follows the line specified by the slope and the value given as + // arguments. The slope and value are positive. + static PiecewiseLinearFunction* CreateFixedChargeFunction(int64 slope, + int64 value); + + // Builds an earliness-tardiness two-segment piecewise linear cost function. + // The reference specifies the point where the cost is zero. Before the + // reference, the cost increases with the earliness slope and after the + // referece, it increases with the tardiness slope. The absolute values of + // the slopes are given. + static PiecewiseLinearFunction* CreateEarlyTardyFunction( + int64 reference, int64 earliness_slope, int64 tardiness_slope); + + // Builds an earliness-tardiness three-segment piecewise linear cost function + // with a slack period around the due date. The early slack is the point + // before which the cost increases with the ealiness slope specified. The + // late slack is the point after which the cost increases with the late slope + // specified. Between the early and the late slack point, the cost is zero. + // The absolute values of the slopes are given. + static PiecewiseLinearFunction* CreateEarlyTardyFunctionWithSlack( + int64 early_slack, int64 late_slack, int64 earliness_slope, + int64 tardiness_slope); + + // Returns if x is in the domain of the function. + bool InDomain(int64 x) const; + // Determines whether the piecewise linear function is convex or non-convex + // and returns true when the function is convex. + bool IsConvex() const; + // Returns true if the piecewise linear function is non-decreasing. + bool IsNonDecreasing() const; + // Returns true if the piecewise linear function is non-increasing. + bool IsNonIncreasing() const; + // Returns the value of the piecewise linear function for x. + int64 Value(int64 x) const; + // Returns the maximum value of all the segments in the function. + int64 GetMaximum() const; + // Returns the minimum value of all the segments in the function. + int64 GetMinimum() const; + // Returns the maximum endpoint value of the segments in the specified + // range. If the range is disjoint from the segments in the function, it + // returns kint64max. + int64 GetMaximum(int64 range_start, int64 range_end) const; + // Returns the minimum endpoint value of the segments in the specified + // range. If the range is disjoint from the segments in the function, it + // returns kint64max. + int64 GetMinimum(int64 range_start, int64 range_end) const; + // Returns the smallest range within a given range containing all values + // greater than a given value. + std::pair GetSmallestRangeGreaterThanValue(int64 range_start, + int64 range_end, + int64 value) const; + // Returns the smallest range within a given range containing all values + // less than a given value. + std::pair GetSmallestRangeLessThanValue(int64 range_start, + int64 range_end, + int64 value) const; + // Returns the smallest range within a given range containing all values + // greater than value_min and less than value_max. + std::pair GetSmallestRangeInValueRange(int64 range_start, + int64 range_end, + int64 value_min, + int64 value_max) const; + + // Adds 'constant' to the 'x' of all segments. If the argument is positive, + // the translation is to the right and when it's negative, to the left. The + // overflows and the underflows are sticky. + void AddConstantToX(int64 constant); + // Adds 'constant' to the 'y' of all segments. If the argument is positive, + // the translation is up and when it's negative, down. The overflows and the + // underflows are sticky. + void AddConstantToY(int64 constant); + // Adds the function to the existing one. The domain of the resulting + // function is the intersection of the two domains. The overflows and + // the underflows are sticky. + void Add(const PiecewiseLinearFunction& function); + // Subtracts the function to the existing one. The domain of the + // resulting function is the intersection of the two domains. The + // overflows and the underflows are sticky. + void Subtract(const PiecewiseLinearFunction& function); + // Decomposes the piecewise linear function in a set of convex piecewise + // linear functions. The objects in the vector are owned by the client code. + std::vector DecomposeToConvexFunctions() const; + + const std::vector& segments() const { return segments_; } + + std::string DebugString() const; + + private: + // Takes the sequence of segments, sorts them on increasing start and inserts + // them in the piecewise linear function. + explicit PiecewiseLinearFunction(std::vector segments); + // Inserts a segment in the function. + void InsertSegment(const PiecewiseSegment& segment); + // Operation between two functions. In any operation between two functions the + // final domain is the intersection between the two domains. + void Operation(const PiecewiseLinearFunction& other, + const std::function& operation); + // Finds start and end segment indices from a range; returns false if the + // range is outside the domain of the function. + bool FindSegmentIndicesFromRange(int64 range_start, int64 range_end, + int* start_segment, int* end_segment) const; + void UpdateStatus() { + if (is_modified_) { + is_convex_ = IsConvexInternal(); + is_non_decreasing_ = IsNonDecreasingInternal(); + is_non_increasing_ = IsNonIncreasingInternal(); + is_modified_ = false; + } + } + bool IsConvexInternal() const; + bool IsNonDecreasingInternal() const; + bool IsNonIncreasingInternal() const; + + // The vector of segments in the function, sorted in ascending order of start + // points. + std::vector segments_; + bool is_modified_; + bool is_convex_; + bool is_non_decreasing_; + bool is_non_increasing_; +}; +} // namespace operations_research +#endif // OR_TOOLS_UTIL_PIECEWISE_LINEAR_FUNCTION_H_ diff --git a/thirdparty/linux/include/ortools/util/proto_tools.h b/thirdparty/linux/include/ortools/util/proto_tools.h new file mode 100644 index 0000000..6bc5216 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/proto_tools.h @@ -0,0 +1,43 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_PROTO_TOOLS_H_ +#define OR_TOOLS_UTIL_PROTO_TOOLS_H_ + +#include +#include "google/protobuf/message.h" + +namespace operations_research { + +enum class ProtoWriteFormat { kProtoText, kProtoBinary, kJson }; + +// Exactly like file::ReadFileToProto() but also supports GZipped files and +// JSON. +bool ReadFileToProto(const std::string& file_name, google::protobuf::Message* proto); + +// Like file::WriteProtoToFile() or file::WriteProtoToASCIIFile(), but also +// supports JSON and GZipped output. +// If 'proto_write_format' is kProtoBinary, ".bin" is appended to file_name. +// If 'proto_write_format' is kJson, ".json" is appended to file_name. +// If 'gzipped' is true, ".gz" is appended to file_name. +bool WriteProtoToFile(const std::string& file_name, const google::protobuf::Message& proto, + ProtoWriteFormat proto_write_format, bool gzipped); + +// Prints a proto2 message as a std::string, it behaves like TextFormat::Print() +// but also prints the default values of unset fields which is useful for +// printing parameters. +std::string FullProtocolMessageAsString(const google::protobuf::Message& message, + int indent_level); + +} // namespace operations_research +#endif // OR_TOOLS_UTIL_PROTO_TOOLS_H_ diff --git a/thirdparty/linux/include/ortools/util/range_minimum_query.h b/thirdparty/linux/include/ortools/util/range_minimum_query.h new file mode 100644 index 0000000..e8040b8 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/range_minimum_query.h @@ -0,0 +1,173 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// We use the notation std::min(arr, i, j) for the minimum arr[x] such that i <= x +// and x < j. +// Range Minimum Query (RMQ) is a data structure preprocessing an array arr so +// that querying std::min(arr, i, j) takes O(1) time. The preprocessing takes +// O(n*log(n)) time and memory. + +// Note: There exists an O(n) preprocessing algorithm, but it is considerably +// more involved and the hidden constants behind it are much higher. +// +// The algorithms are well explained in Wikipedia: +// https://en.wikipedia.org/wiki/Range_minimum_query. +// +// +// Implementation: The idea is to cache every std::min(arr, i, j) where j - i is a +// power of two, i.e. j = i + 2^k for some k. Provided this information, we can +// answer all queries in O(1): given a pair (i, j) find the maximum k such that +// i + 2^k < j and note that +// std::min(std::min(arr, i, i+2^k), std::min(arr, j-2^k, j)) = std::min(arr, i, j). + +#ifndef OR_TOOLS_UTIL_RANGE_MINIMUM_QUERY_H_ +#define OR_TOOLS_UTIL_RANGE_MINIMUM_QUERY_H_ + +#include +#include +#include +#include +#include + +#include "ortools/util/bitset.h" + +namespace operations_research { +template > +class RangeMinimumQuery { + public: + explicit RangeMinimumQuery(std::vector array); + RangeMinimumQuery(std::vector array, Compare cmp); + + // Returns the minimum (w.r.t. Compare) arr[x], where x is contained in + // [from, to). + T GetMinimumFromRange(int from, int to) const; + + const std::vector& array() const; + + private: + // cache_[k][i] = std::min(arr, i, i+2^k). + std::vector> cache_; + Compare cmp_; + + DISALLOW_COPY_AND_ASSIGN(RangeMinimumQuery); +}; + +// RangeMinimumIndexQuery is similar to RangeMinimumQuery, but +// GetMinimumIndexFromRange returns the index for which the minimum is attained. +template > +class RangeMinimumIndexQuery { + public: + explicit RangeMinimumIndexQuery(std::vector array); + RangeMinimumIndexQuery(std::vector array, Compare cmp); + + // Returns an index idx from [from, to) such that arr[idx] is the minimum + // value of arr over the interval [from, to). + int GetMinimumIndexFromRange(int from, int to) const; + + // Returns the original array. + const std::vector& array() const; + + private: + // Returns a vector with values 0, 1, ... n - 1 for a given n. + static std::vector CreateIndexVector(int n); + struct IndexComparator { + bool operator()(int lhs_idx, int rhs_idx) const; + const std::vector array; + Compare cmp; + } cmp_; + const RangeMinimumQuery rmq_; + DISALLOW_COPY_AND_ASSIGN(RangeMinimumIndexQuery); +}; + +// RangeMinimumQuery implementation +template +inline RangeMinimumQuery::RangeMinimumQuery(std::vector array) + : RangeMinimumQuery(std::move(array), Compare()) {} + +// Reminder: The task is to fill cache_ so that +// cache_[k][i] = std::min(arr, i, i+2^k) for every k <= Log2(n) and i <= n-2^k. +// Note that cache_[k+1][i] = std::min(cache_[k][i], cache_[k][i+2^k]), hence every +// row can be efficiently computed from the previous. +template +RangeMinimumQuery::RangeMinimumQuery(std::vector array, + Compare cmp) + : cache_(MostSignificantBitPosition32(array.size()) + 1), + cmp_(std::move(cmp)) { + const int array_size = array.size(); + cache_[0] = std::move(array); + for (int row_idx = 1; row_idx < cache_.size(); ++row_idx) { + const int row_length = array_size - (1 << row_idx) + 1; + const int window = 1 << (row_idx - 1); + cache_[row_idx].resize(row_length); + for (int col_idx = 0; col_idx < row_length; ++col_idx) { + cache_[row_idx][col_idx] = + std::min(cache_[row_idx - 1][col_idx], + cache_[row_idx - 1][col_idx + window], cmp_); + } + } +} + +template +inline T RangeMinimumQuery::GetMinimumFromRange(int from, + int to) const { + DCHECK_LE(0, from); + DCHECK_LT(from, to); + DCHECK_LE(to, array().size()); + const int log_diff = MostSignificantBitPosition32(to - from); + const int window = 1 << log_diff; + const std::vector& row = cache_[log_diff]; + return std::min(row[from], row[to - window], cmp_); +} + +template +inline const std::vector& RangeMinimumQuery::array() const { + return cache_[0]; +} + +// RangeMinimumIndexQuery implementation +template +inline RangeMinimumIndexQuery::RangeMinimumIndexQuery( + std::vector array) + : RangeMinimumIndexQuery(std::move(array), Compare()) {} + +template +RangeMinimumIndexQuery::RangeMinimumIndexQuery(std::vector array, + Compare cmp) + : cmp_({std::move(array), std::move(cmp)}), + rmq_(CreateIndexVector(cmp_.array.size()), cmp_) {} + +template +inline int RangeMinimumIndexQuery::GetMinimumIndexFromRange( + int from, int to) const { + return rmq_.GetMinimumFromRange(from, to); +} + +template +inline bool RangeMinimumIndexQuery::IndexComparator::operator()( + int lhs_idx, int rhs_idx) const { + return cmp(array[lhs_idx], array[rhs_idx]); +} + +template +std::vector RangeMinimumIndexQuery::CreateIndexVector(int n) { + std::vector result(n, 0); + std::iota(result.begin(), result.end(), 0); + return result; +} + +template +inline const std::vector& RangeMinimumIndexQuery::array() const { + return cmp_.array; +} +} // namespace operations_research +#endif // OR_TOOLS_UTIL_RANGE_MINIMUM_QUERY_H_ diff --git a/thirdparty/linux/include/ortools/util/range_query_function.h b/thirdparty/linux/include/ortools/util/range_query_function.h new file mode 100644 index 0000000..2ccd1a5 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/range_query_function.h @@ -0,0 +1,84 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// The header defines an interface for functions taking and returning an int64 +// and supporting range queries over their domain and codomain. + +#ifndef OR_TOOLS_UTIL_RANGE_QUERY_FUNCTION_H_ +#define OR_TOOLS_UTIL_RANGE_QUERY_FUNCTION_H_ + +#include +#include + +#include "ortools/base/integral_types.h" + +namespace operations_research { +// RangeIntToIntFunction is an interface to int64->int64 functions supporting +// fast answer to range queries about their domain/codomain. +class RangeIntToIntFunction { + public: + virtual ~RangeIntToIntFunction() = default; + + // Suppose f is the abstract underlying function. + // Returns f(argument). + // TODO(user): Rename to Run + virtual int64 Query(int64 argument) const = 0; + // Returns min_x f(x), where x is in [from, to). + virtual int64 RangeMin(int64 from, int64 to) const = 0; + // Returns max_x f(x), where x is in [from, to). + virtual int64 RangeMax(int64 from, int64 to) const = 0; + // Returns the first x from [range_begin, range_end) for which f(x) is in + // [interval_begin, interval_end), or range_end if there is no such x. + virtual int64 RangeFirstInsideInterval(int64 range_begin, int64 range_end, + int64 interval_begin, + int64 interval_end) const = 0; + // Returns the last x from [range_begin, range_end) for which f(x) is in + // [interval_begin, interval_end), or range_begin-1 if there is no such x. + virtual int64 RangeLastInsideInterval(int64 range_begin, int64 range_end, + int64 interval_begin, + int64 interval_end) const = 0; +}; + +// RangeMinMaxIndexFunction is different from RangeIntToIntFunction in two ways: +// +// 1. It does not support codomain or value queries. +// +// 2. For domain queries it returns an argument where the minimum/maximum is +// attained, rather than the minimum/maximum value. +class RangeMinMaxIndexFunction { + public: + virtual ~RangeMinMaxIndexFunction() = default; + // Suppose f is the abstract underlying function. + // Returns an x from [from, to), such that f(x) => f(y) for every y from + // [from, to). + virtual int64 RangeMaxArgument(int64 from, int64 to) const = 0; + // Returns an x from [from, to), such that f(x) <= f(y) for every y from + // [from, to). + virtual int64 RangeMinArgument(int64 from, int64 to) const = 0; +}; + +// A copy of f is going to be stored in the returned object, so its closure +// should remain intact as long as the returned object is being used. +RangeIntToIntFunction* MakeBareIntToIntFunction(std::function f); +// It is assumed that f is defined over the interval [domain_start, domain_end). +// The function scans f once and it is safe to destroy f and its closure after +// MakeCachedIntToIntFunction returns. +RangeIntToIntFunction* MakeCachedIntToIntFunction( + const std::function& f, int64 domain_start, int64 domain_end); +// It is safe to destroy the first argument and its closure after +// MakeCachedRangeMinMaxIndexFunction returns. +RangeMinMaxIndexFunction* MakeCachedRangeMinMaxIndexFunction( + const std::function& f, int64 domain_start, int64 domain_end); +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_RANGE_QUERY_FUNCTION_H_ diff --git a/thirdparty/linux/include/ortools/util/rational_approximation.h b/thirdparty/linux/include/ortools/util/rational_approximation.h new file mode 100644 index 0000000..8e4b2a9 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/rational_approximation.h @@ -0,0 +1,37 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_RATIONAL_APPROXIMATION_H_ +#define OR_TOOLS_UTIL_RATIONAL_APPROXIMATION_H_ + +#include + +#include "ortools/base/integral_types.h" + +namespace operations_research { + +// The type Fraction represents a number in the form of two integers: numerator +// and denominator. This type is used to display the rational approximation +// of a Fractional number. +typedef std::pair Fraction; + +// Computes a rational approximation numerator/denominator for value x +// using a continued fraction algorithm. The absolute difference between the +// output fraction and the input "x" will not exceed "precision". +// TODO(user): make a parameterized template with integer and floating-point +// type parameters. +Fraction RationalApproximation(const double x, const double precision); + +} // namespace operations_research +#endif // OR_TOOLS_UTIL_RATIONAL_APPROXIMATION_H_ + diff --git a/thirdparty/linux/include/ortools/util/rcpsp_parser.h b/thirdparty/linux/include/ortools/util/rcpsp_parser.h new file mode 100644 index 0000000..8979e1c --- /dev/null +++ b/thirdparty/linux/include/ortools/util/rcpsp_parser.h @@ -0,0 +1,177 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// A Project Scheduling Library parser. +// See: http://www.om-db.wi.tum.de/psplib/ # PSP-Lib homepage. + +#ifndef OR_TOOLS_UTIL_RCPSP_PARSER_H_ +#define OR_TOOLS_UTIL_RCPSP_PARSER_H_ + +#include +#include + +#include "ortools/base/integral_types.h" + +namespace operations_research { + +// RCPSP parser. +// +// The problem description is as follows: +// +// You have a set of resources. They all have a maximum capacity, and +// can be renewable or not. +// +// You have a set of tasks. Each task has a list of successors, and a +// list of recipes. Each recipe consists of a duration, and a list of +// demands, one per resource. +// +// The tasks dependencies form a DAG with a single source and a single end. +// Both source and end tasks have a zero duration, and no resource consumption. +// +// In case the problem is of type RCPSP/Max. The data contains an additional +// array of delays per task. This flattened array contains the following +// information for task i with mode mi and successor j with mode mj, then +// start(i) + delay[i, mi, j, mj] <= start(j). This subsumes the normal +// successor predecence of the non RCPSP/Max variation, i.e.: +// start(i) + duration(i, mi) <= start(j). +// +// In the normal case, the objective is to minimize the makespan of the problem. +// +// In the resource investment problem, there is no makespan. It is +// replaced by a strict deadline, and each task must finish before +// this deadline. In that case, resources have a unit cost, and the +// objective is to minimize the sum of resource cost. +// +// In the consumer/producer case, tasks have a zero duration, and demands can be +// negative. The constraint states that at each time point, the sum of demands +// happening before or during this time must be between the min and max +// capacity. Note that in that case, both min and max capacity can be negative. +// Furthermore, if 0 is not in [min_capacity, max_capacity], then a sufficient +// set of events must happen at time 0 such that the sum of their demands must +// fall inside the capacity interval. +// +// The supported file formats are: +// - standard psplib (.sm and .mm): +// http://www.om-db.wi.tum.de/psplib/data.html +// - rcpsp problem in the patterson format (.rcp): +// http://www.om-db.wi.tum.de/psplib/dataob.html +// - rcpsp/max (.sch): +// https://www.wiwi.tu-clausthal.de/de/abteilungen/produktion/forschung/ +// schwerpunkte/project-generator/rcpspmax/ +// https://www.wiwi.tu-clausthal.de/de/abteilungen/produktion/forschung/ +// schwerpunkte/project-generator/mrcpspmax/ +// - resource investment problem with max delay (.sch): +// https://www.wiwi.tu-clausthal.de/de/abteilungen/produktion/forschung/ +// schwerpunkte/project-generator/ripmax/ +class RcpspParser { + public: + struct Resource { + // The max capacity of the cumulative. + int max_capacity; + // This field is used only in the consumer/producer case. It states the + // minimum capacity that must be valid at each time point. + int min_capacity; + bool renewable; + // If non zero, then each unit of capacity will incur a cost of unit_cost. + int unit_cost; + }; + + struct Recipe { + int duration; + // In the general case, demand must be >= 0. In the consumer/producer case, + // it can be < 0. Note that in this case, the tasks always have a duration + // of zero. Thus the effect of the demand (increase or decrease of the + // current usage) happens at the start of the task. + std::vector demands_per_resource; + }; + + struct Task { + std::vector successors; + // If the current task has n successors and m modes then this is + // an n x m matrix where each entry at line i is a vector with the + // same length as the number of modes for the task successor[i]. If + // mode m1 is chosen for the current task, and mode m2 is chosen + // for its successor i, we have: + // start(current_task) + delay[i][m1][m2] <= start(successor_task). + std::vector>> delays; + std::vector recipes; + }; + + RcpspParser(); + + std::string name() const { return name_; } + const std::vector& resources() const { return resources_; } + const std::vector& tasks() const { return tasks_; } + // The horizon is a date where we are sure that all tasks can fit before it. + int horizon() const { return horizon_; } + // The release date is defined in the rcpsp base format, but is not used. + int release_date() const { return release_date_; } + // The due date is defined in the rcpsp base format, but is not used. + int due_date() const { return due_date_; } + // The tardiness cost is defined in the rcpsp base format, but is not used. + int tardiness_cost() const { return tardiness_cost_; } + // The mpm_time is defined in the rcpsp base format, but is not used. + // It is defined as the minimum makespan in case of interruptible tasks. + int mpm_time() const { return mpm_time_; } + // If set, it defines a strict date, and each task must finish before this. + int deadline() const { return deadline_; } + // Define the problem type. + bool is_rcpsp_max() const { return is_rcpsp_max_; } + bool is_resource_investment() const { return is_resource_investment_; } + bool is_consumer_producer() const { return is_consumer_producer_; } + + bool LoadFile(const std::string& file_name); + + private: + enum LoadStatus { + NOT_STARTED, + HEADER_SECTION, + PROJECT_SECTION, + INFO_SECTION, + PRECEDENCE_SECTION, + REQUEST_SECTION, + RESOURCE_SECTION, + RESOURCE_MIN_SECTION, + PARSING_FINISHED, + ERROR_FOUND + }; + + void ProcessRcpspLine(const std::string& line); + void ProcessPattersonLine(const std::string& line); + void ProcessRcpspMaxLine(const std::string& line); + void ReportError(const std::string& line); + + std::string name_; + std::string basedata_; + int64 seed_; + std::vector resources_; + std::vector tasks_; + int horizon_; + int release_date_; + int due_date_; + int tardiness_cost_; + int mpm_time_; + int deadline_; + LoadStatus load_status_; + int declared_tasks_; + int current_task_; + bool is_rcpsp_max_; + bool is_resource_investment_; + bool is_consumer_producer_; + std::vector> temp_delays_; + int unreads_; +}; + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_RCPSP_PARSER_H_ diff --git a/thirdparty/linux/include/ortools/util/return_macros.h b/thirdparty/linux/include/ortools/util/return_macros.h new file mode 100644 index 0000000..1cdcc5c --- /dev/null +++ b/thirdparty/linux/include/ortools/util/return_macros.h @@ -0,0 +1,32 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_RETURN_MACROS_H_ +#define OR_TOOLS_UTIL_RETURN_MACROS_H_ + +// Macros to replace CHECK_NOTNULL() so we don't crash in production. +// Logs a FATAL message in debug mode, and an ERROR message in production. +// It is not perfect, but more robust than crashing right away. +#define RETURN_IF_NULL(x) \ + if (x == nullptr) { \ + LOG(DFATAL) << #x << " == NULL"; \ + return; \ + } + +#define RETURN_VALUE_IF_NULL(x, v) \ + if (x == nullptr) { \ + LOG(DFATAL) << #x << " == NULL"; \ + return v; \ + } + +#endif // OR_TOOLS_UTIL_RETURN_MACROS_H_ diff --git a/thirdparty/linux/include/ortools/util/rev.h b/thirdparty/linux/include/ortools/util/rev.h new file mode 100644 index 0000000..e31dd3f --- /dev/null +++ b/thirdparty/linux/include/ortools/util/rev.h @@ -0,0 +1,270 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Reversible (i.e Backtrackable) classes, used to simplify coding propagators. +#ifndef OR_TOOLS_UTIL_REV_H_ +#define OR_TOOLS_UTIL_REV_H_ + +#include +#include + +#include "ortools/base/logging.h" +#include "ortools/base/map_util.h" + +namespace operations_research { + +// Interface for reversible objects used to maintain them in sync with a tree +// search organized by decision levels. +class ReversibleInterface { + public: + ReversibleInterface() {} + virtual ~ReversibleInterface() {} + + // Initially a reversible class starts at level zero. Increasing the level + // saves the state of the current old level. Decreasing the level restores the + // state to what it was at this level and all higher levels are forgotten. + // Everything done at level zero cannot be backtracked over. + // + // The level is assumed to be non-negative. + virtual void SetLevel(int level) = 0; +}; + +// A repository that maintains a set of reversible objects of type T. +// This is meant to be used for small types that are efficient to copy, like +// all the basic types, std::pair and things like this. +template +class RevRepository : public ReversibleInterface { + public: + RevRepository() : stamp_(0) {} + + // This works in O(level_diff) on level increase. + // For level decrease, it is in O(level_diff + num_restored_states). + void SetLevel(int level) final; + int Level() const { return end_of_level_.size(); } + + // Saves the given object value for the current level. If this is called + // multiple time by level, only the value of the first call matter. This is + // NOT optimized for many calls by level and should mainly be used just once + // for a given level. If a client cannot do that efficiently, it can use the + // SaveStateWithStamp() function below. + void SaveState(T* object) { + if (end_of_level_.empty()) return; // Not useful for level zero. + stack_.push_back({object, *object}); + } + + // Calls SaveState() if the given stamp is not the same as the current one. + // This also sets the given stamp to the current one. The current stamp is + // maintained by this class and is updated on each level changes. The whole + // process make sure that only one SaveValue() par level will ever be called, + // so it is efficient to call this before each update to the object T. + void SaveStateWithStamp(T* object, int64* stamp) { + if (*stamp == stamp_) return; + *stamp = stamp_; + SaveState(object); + } + + private: + int64 stamp_; + std::vector end_of_level_; // In stack_. + + // TODO(user): If we ever see this in any cpu profile, consider using two + // vectors for a better memory packing in case sizeof(T) is not sizeof(T*). + std::vector> stack_; +}; + +template +void RevRepository::SetLevel(int level) { + DCHECK_GE(level, 0); + if (level == Level()) return; + ++stamp_; + if (level < Level()) { + const int index = end_of_level_[level]; + end_of_level_.resize(level); // Shrinks. + while (stack_.size() > index) { + const auto& p = stack_.back(); + *p.first = p.second; + stack_.pop_back(); + } + } else { + end_of_level_.resize(level, stack_.size()); // Grows. + } +} + +// Like a normal map but support backtrackable operations. +// +// This works on any class "Map" that supports: begin(), end(), find(), erase(), +// insert(), key_type, value_type, mapped_type and const_iterator. +template +class RevMap : ReversibleInterface { + public: + typedef typename Map::key_type key_type; + typedef typename Map::mapped_type mapped_type; + typedef typename Map::value_type value_type; + typedef typename Map::const_iterator const_iterator; + + // Backtracking support: changes the current "level" (always non-negative). + // + // Initially the class starts at level zero. Increasing the level works in + // O(level diff) and saves the state of the current old level. Decreasing the + // level restores the state to what it was at this level and all higher levels + // are forgotten. Everything done at level zero cannot be backtracked over. + void SetLevel(int level) final; + int Level() const { return first_op_index_of_next_level_.size(); } + + bool ContainsKey(key_type key) const { return operations_research::ContainsKey(map_, key); } + const mapped_type& FindOrDie(key_type key) const { + return operations_research::FindOrDie(map_, key); + } + + void EraseOrDie(key_type key); + void Set(key_type key, mapped_type value); // Adds or overwrites. + + // Wrapper to the underlying const map functions. + int size() const { return map_.size(); } + bool empty() const { return map_.empty(); } + const_iterator find(const key_type& k) const { return map_.find(k); } + const_iterator begin() const { return map_.begin(); } + const_iterator end() const { return map_.end(); } + + private: + Map map_; + + // The operation that needs to be performed to reverse one modification: + // - If is_deletion is true, then we need to delete the entry with given key. + // - Otherwise we need to add back (or overwrite) the saved entry. + struct UndoOperation { + bool is_deletion; + key_type key; + mapped_type value; + }; + + // TODO(user): We could merge the operations with the same key from the same + // level. Investigate and implement if this is worth the effort for our use + // case. + std::vector operations_; + std::vector first_op_index_of_next_level_; +}; + +template +void RevMap::SetLevel(int level) { + DCHECK_GE(level, 0); + if (level < Level()) { + const int backtrack_level = first_op_index_of_next_level_[level]; + first_op_index_of_next_level_.resize(level); // Shrinks. + while (operations_.size() > backtrack_level) { + const UndoOperation& to_undo = operations_.back(); + if (to_undo.is_deletion) { + map_.erase(to_undo.key); + } else { + map_.insert({to_undo.key, to_undo.value}).first->second = to_undo.value; + } + operations_.pop_back(); + } + return; + } + + // This is ok even if level == Level(). + first_op_index_of_next_level_.resize(level, operations_.size()); // Grows. +} + +template +void RevMap::EraseOrDie(key_type key) { + const auto iter = map_.find(key); + if (iter == map_.end()) LOG(FATAL) << "key not present: '" << key << "'."; + if (Level() > 0) { + operations_.push_back({false, key, iter->second}); + } + map_.erase(iter); +} + +template +void RevMap::Set(key_type key, mapped_type value) { + auto insertion_result = map_.insert({key, value}); + if (Level() > 0) { + if (insertion_result.second) { + // It is an insertion. Undo = delete. + operations_.push_back({true, key}); + } else { + // It is a modification. Undo = change back to old value. + operations_.push_back({false, key, insertion_result.first->second}); + } + } + insertion_result.first->second = value; +} + +// A basic backtrackable multi map that can only grow (except on backtrack). +template +class RevGrowingMultiMap : ReversibleInterface { + public: + void SetLevel(int level) final; + + // Adds a new value at the given key. + void Add(Key key, Value value); + + // Returns the list of values for a given key (can be empty). + const std::vector& Values(Key key) const; + + private: + std::vector empty_values_; + + // TODO(user): use inlined vectors. Another datastructure that may be more + // efficient is to use a linked list inside added_keys_ for the values sharing + // the same key. + std::unordered_map> map_; + + // Backtracking data. + std::vector added_keys_; + std::vector first_added_key_of_next_level_; +}; + +template +void RevGrowingMultiMap::SetLevel(int level) { + DCHECK_GE(level, 0); + if (level < first_added_key_of_next_level_.size()) { + const int backtrack_level = first_added_key_of_next_level_[level]; + first_added_key_of_next_level_.resize(level); // Shrinks. + while (added_keys_.size() > backtrack_level) { + auto it = map_.find(added_keys_.back()); + if (it->second.size() > 1) { + it->second.pop_back(); + } else { + map_.erase(it); + } + added_keys_.pop_back(); + } + return; + } + + // This is ok even if level == Level(). + first_added_key_of_next_level_.resize(level, added_keys_.size()); // Grows. +} + +template +const std::vector& RevGrowingMultiMap::Values( + Key key) const { + const auto it = map_.find(key); + if (it != map_.end()) return it->second; + return empty_values_; +} + +template +void RevGrowingMultiMap::Add(Key key, Value value) { + if (!first_added_key_of_next_level_.empty()) { + added_keys_.push_back(key); + } + map_[key].push_back(value); +} + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_REV_H_ diff --git a/thirdparty/linux/include/ortools/util/running_stat.h b/thirdparty/linux/include/ortools/util/running_stat.h new file mode 100644 index 0000000..feb1d3e --- /dev/null +++ b/thirdparty/linux/include/ortools/util/running_stat.h @@ -0,0 +1,193 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_RUNNING_STAT_H_ +#define OR_TOOLS_UTIL_RUNNING_STAT_H_ + +#include + +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" + +namespace operations_research { + +// Simple class to compute the average over a fixed size window of an integer +// stream. +class RunningAverage { + public: + // Initialize the class with the maximum window size. + // It must be positive (this is CHECKed). + explicit RunningAverage(int window_size = 1); + + // Resets the class to the exact same state as if it was just constructed with + // the given window size. + void Reset(int window_size); + + // Adds the next integer of the stream. + void Add(int value); + + // Returns the average of all the values added so far or zero if no values + // where added. + double GlobalAverage() const; + + // Returns the average of the values in the current window or zero if the + // current window is empty. + double WindowAverage() const; + + // Returns true iff the current window size is equal to the one specified in + // the constructor. + bool IsWindowFull() const; + + // Clears the current window. + void ClearWindow(); + + private: + int window_size_; + int num_adds_; + double global_sum_; + double local_sum_; + std::deque values_; + + DISALLOW_COPY_AND_ASSIGN(RunningAverage); +}; + +// Simple class to compute efficiently the maximum over a fixed size window +// of a numeric stream. This works in constant average amortized time. +template +class RunningMax { + public: + // Takes the size of the running window. The size must be positive. + explicit RunningMax(int window_size); + + // Processes a new element from the stream. + void Add(Number value); + + // Returns the current maximum element in the window. + // An element must have been added before calling this function. + Number GetCurrentMax(); + + private: + const int window_size_; + + // Values in the current window. + std::vector values_; + + // Index of the last added element in the window. + int last_index_; + + // Index of the current maximum element. + int max_index_; + + DISALLOW_COPY_AND_ASSIGN(RunningMax); +}; + +// ################## Implementations below ##################### + +inline RunningAverage::RunningAverage(int window_size) + : window_size_(window_size), + num_adds_(0), + global_sum_(0.0), + local_sum_(0.0) { + CHECK_GT(window_size_, 0); +} + +inline void RunningAverage::Reset(int window_size) { + window_size_ = window_size; + num_adds_ = 0; + global_sum_ = 0.0; + ClearWindow(); +} + +inline void RunningAverage::Add(int value) { + ++num_adds_; + global_sum_ += value; + local_sum_ += value; + values_.push_back(value); + if (values_.size() > window_size_) { + local_sum_ -= values_.front(); + values_.pop_front(); + } +} + +inline double RunningAverage::GlobalAverage() const { + return num_adds_ == 0 ? 0.0 : global_sum_ / static_cast(num_adds_); +} + +inline double RunningAverage::WindowAverage() const { + return values_.empty() ? 0.0 + : local_sum_ / static_cast(values_.size()); +} + +inline void RunningAverage::ClearWindow() { + local_sum_ = 0.0; + values_.clear(); +} + +inline bool RunningAverage::IsWindowFull() const { + return values_.size() == window_size_; +} + +template +RunningMax::RunningMax(int window_size) + : window_size_(window_size), values_(), last_index_(0), max_index_(0) { + DCHECK_GT(window_size, 0); +} + +template +void RunningMax::Add(Number value) { + if (values_.size() < window_size_) { + // Starting phase until values_ reaches its final size. + // Note that last_index_ stays at 0 during this phase. + if (values_.empty() || value >= GetCurrentMax()) { + max_index_ = values_.size(); + } + values_.push_back(value); + return; + } + // We are in the steady state. + DCHECK_EQ(values_.size(), window_size_); + // Note the use of >= instead of > to get the O(1) behavior in presence of + // many identical values. + if (value >= GetCurrentMax()) { + max_index_ = last_index_; + values_[last_index_] = value; + } else { + values_[last_index_] = value; + if (last_index_ == max_index_) { + // We need to recompute the max. + // Note that this happens only if value was strictly lower than + // GetCurrentMax() in the last window_size_ updates. + max_index_ = 0; + Number max_value = values_[max_index_]; + for (int i = 1; i < values_.size(); ++i) { + if (values_[i] > max_value) { + max_value = values_[i]; + max_index_ = i; + } + } + } + } + if (++last_index_ == window_size_) { + last_index_ = 0; + } +} + +template +Number RunningMax::GetCurrentMax() { + DCHECK(!values_.empty()); + return values_[max_index_]; +} + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_RUNNING_STAT_H_ diff --git a/thirdparty/linux/include/ortools/util/saturated_arithmetic.h b/thirdparty/linux/include/ortools/util/saturated_arithmetic.h new file mode 100644 index 0000000..cb4ff64 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/saturated_arithmetic.h @@ -0,0 +1,241 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_SATURATED_ARITHMETIC_H_ +#define OR_TOOLS_UTIL_SATURATED_ARITHMETIC_H_ + +#include "ortools/base/casts.h" +#include "ortools/base/integral_types.h" + +#include "ortools/util/bitset.h" + +namespace operations_research { +// ---------- Overflow utility functions ---------- + +// Implement two's complement addition and subtraction on int64s. +// +// The C and C++ standards specify that the overflow of signed integers is +// undefined. This is because of the different possible representations that may +// be used for signed integers (one's complement, two's complement, sign and +// magnitude). Such overflows are detected by Address Sanitizer with +// -fsanitize=signed-integer-overflow. +// +// Simple, portable overflow detection on current machines relies on +// these two functions. For example, if the sign of the sum of two positive +// integers is negative, there has been an overflow. +// +// Note that the static assert will break if the code is compiled on machines +// which do not use two's complement. +inline int64 TwosComplementAddition(int64 x, int64 y) { + static_assert(static_cast(-1LL) == ~0ULL, + "The target architecture does not use two's complement."); + return bit_cast(static_cast(x) + static_cast(y)); +} + +inline int64 TwosComplementSubtraction(int64 x, int64 y) { + static_assert(static_cast(-1LL) == ~0ULL, + "The target architecture does not use two's complement."); + return bit_cast(static_cast(x) - static_cast(y)); +} + +// Helper function that returns true if an overflow has occured in computing +// sum = x + y. sum is expected to be computed elsewhere. +inline bool AddHadOverflow(int64 x, int64 y, int64 sum) { + // Overflow cannot occur if operands have different signs. + // It can only occur if sign(x) == sign(y) and sign(sum) != sign(x), + // which is equivalent to: sign(x) != sign(sum) && sign(y) != sign(sum). + // This is captured when the expression below is negative. + DCHECK_EQ(sum, TwosComplementAddition(x, y)); + return ((x ^ sum) & (y ^ sum)) < 0; +} + +inline bool SubHadOverflow(int64 x, int64 y, int64 diff) { + // This is the same reasoning as for AddHadOverflow. We have x = diff + y. + // The formula is the same, with 'x' and diff exchanged. + DCHECK_EQ(diff, TwosComplementSubtraction(x, y)); + return AddHadOverflow(diff, y, x); +} + +// A note on overflow treatment. +// kint64min and kint64max are treated as infinity. +// Thus if the computation overflows, the result is always kint64m(ax/in). +// +// Note(user): this is actually wrong: when computing A-B, if A is kint64max +// and B is finite, then A-B won't be kint64max: overflows aren't sticky. +// TODO(user): consider making some operations overflow-sticky, some others +// not, but make an explicit choice throughout. +inline bool AddOverflows(int64 x, int64 y) { + return AddHadOverflow(x, y, TwosComplementAddition(x, y)); +} + +inline int64 SubOverflows(int64 x, int64 y) { + return SubHadOverflow(x, y, TwosComplementSubtraction(x, y)); +} + +// Performs *b += a and returns false iff the addition overflow or underflow. +// This function only works for typed integer type (IntType<>). +template +bool SafeAddInto(IntegerType a, IntegerType* b) { + const int64 x = a.value(); + const int64 y = b->value(); + const int64 sum = TwosComplementAddition(x, y); + if (AddHadOverflow(x, y, sum)) return false; + *b = sum; + return true; +} + +// Returns kint64max if x >= 0 and kint64min if x < 0. +inline int64 CapWithSignOf(int64 x) { + // return kint64max if x >= 0 or kint64max + 1 (== kint64min) if x < 0. + return TwosComplementAddition(kint64max, static_cast(x < 0)); +} + +inline int64 CapAddGeneric(int64 x, int64 y) { + const int64 result = TwosComplementAddition(x, y); + return AddHadOverflow(x, y, result) ? CapWithSignOf(x) : result; +} + +#if defined(__GNUC__) && defined(ARCH_K8) +// TODO(user): port this to other architectures. +inline int64 CapAddFast(int64 x, int64 y) { + const int64 cap = CapWithSignOf(x); + int64 result = x; + // clang-format off + asm volatile( // 'volatile': ask compiler optimizer "keep as is". + "\t" "addq %[y],%[result]" + "\n\t" "cmovoq %[cap],%[result]" // Conditional move if overflow. + : [result] "=r"(result) // Output + : "[result]" (result), [y] "r"(y), [cap] "r"(cap) // Input. + : "cc" /* Clobbered registers */ ); + // clang-format on + return result; +} +#endif + +inline int64 CapAdd(int64 x, int64 y) { +#if defined(__GNUC__) && defined(ARCH_K8) + return CapAddFast(x, y); +#else + return CapAddGeneric(x, y); +#endif +} + +inline int64 CapSubGeneric(int64 x, int64 y) { + const int64 result = TwosComplementSubtraction(x, y); + return SubHadOverflow(x, y, result) ? CapWithSignOf(x) : result; +} + +#if defined(__GNUC__) && defined(ARCH_K8) +// TODO(user): port this to other architectures. +inline int64 CapSubFast(int64 x, int64 y) { + const int64 cap = CapWithSignOf(x); + int64 result = x; + // clang-format off + asm volatile( // 'volatile': ask compiler optimizer "keep as is". + "\t" "subq %[y],%[result]" + "\n\t" "cmovoq %[cap],%[result]" // Conditional move if overflow. + : [result] "=r"(result) // Output + : "[result]" (result), [y] "r"(y), [cap] "r"(cap) // Input. + : "cc" /* Clobbered registers */ ); + // clang-format on + return result; +} +#endif + +inline int64 CapSub(int64 x, int64 y) { +#if defined(__GNUC__) && defined(ARCH_K8) + return CapSubFast(x, y); +#else + return CapSubGeneric(x, y); +#endif +} + +// Note(user): -kint64min != kint64max, but kint64max == ~kint64min. +inline int64 CapOpp(int64 v) { return v == kint64min ? ~v : -v; } + +namespace cap_prod_util { +// Returns an unsigned int equal to the absolute value of n, in a way that +// will not produce overflows. +inline uint64 uint_abs(int64 n) { + return n < 0 ? ~static_cast(n) + 1 : static_cast(n); +} +} // namespace cap_prod_util + +// The generic algorithm computes a bound on the number of bits necessary to +// store the result. For this it uses the position of the most significant bits +// of each of the arguments. +// If the result needs at least 64 bits, then return a capped value. +// If the result needs at most 63 bits, then return the product. +// Otherwise, the result may use 63 or 64 bits: compute the product +// as a uint64, and cap it if necessary. +inline int64 CapProdGeneric(int64 x, int64 y) { + const uint64 a = cap_prod_util::uint_abs(x); + const uint64 b = cap_prod_util::uint_abs(y); + // Let MSB(x) denote the most significant bit of x. We have: + // MSB(x) + MSB(y) <= MSB(x * y) <= MSB(x) + MSB(y) + 1 + const int msb_sum = + MostSignificantBitPosition64(a) + MostSignificantBitPosition64(b); + const int kMaxBitIndexInInt64 = 63; + if (msb_sum <= kMaxBitIndexInInt64 - 2) return x * y; + // Catch a == 0 or b == 0 now, as MostSignificantBitPosition64(0) == 0. + // TODO(user): avoid this by writing function Log2(a) with Log2(0) == -1. + if (a == 0 || b == 0) return 0; + const int64 cap = CapWithSignOf(x ^ y); + if (msb_sum >= kMaxBitIndexInInt64) return cap; + // The corner case is when msb_sum == 62, i.e. at least 63 bits will be + // needed to store the product. The following product will never overflow + // on uint64, since msb_sum == 62. + const uint64 u_prod = a * b; + // The overflow cases are captured by one of the following conditions: + // (cap >= 0 && u_prod >= static_cast(kint64max) or + // (cap < 0 && u_prod >= static_cast(kint64min)). + // These can be optimized as follows (and if the condition is false, it is + // safe to compute x * y. + if (u_prod >= static_cast(cap)) return cap; + const int64 abs_result = bit_cast(u_prod); + return cap < 0 ? -abs_result : abs_result; +} + +#if defined(__GNUC__) && defined(ARCH_K8) +// TODO(user): port this to other architectures. +inline int64 CapProdFast(int64 x, int64 y) { + // cap = kint64max if x and y have the same sign, cap = kint64min + // otherwise. + const int64 cap = CapWithSignOf(x ^ y); + int64 result = x; + // Here, we use the fact that imul of two signed 64-integers returns a 128-bit + // result -- we care about the lower 64 bits. More importantly, imul also sets + // the carry flag if 64 bits were not enough. + // We therefore use cmovc to return cap if the carry was set. + // clang-format off + asm volatile( // 'volatile': ask compiler optimizer "keep as is". + "\n\t" "imulq %[y],%[result]" + "\n\t" "cmovcq %[cap],%[result]" // Conditional move if carry. + : [result] "=r"(result) // Output + : "[result]" (result), [y] "r"(y), [cap] "r"(cap) // Input. + : "cc" /* Clobbered registers */); + // clang-format on + return result; +} +#endif + +inline int64 CapProd(int64 x, int64 y) { +#if defined(__GNUC__) && defined(ARCH_K8) + return CapProdFast(x, y); +#else + return CapProdGeneric(x, y); +#endif +} +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_SATURATED_ARITHMETIC_H_ diff --git a/thirdparty/linux/include/ortools/util/sort.h b/thirdparty/linux/include/ortools/util/sort.h new file mode 100644 index 0000000..c5e8564 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/sort.h @@ -0,0 +1,136 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_SORT_H_ +#define OR_TOOLS_UTIL_SORT_H_ + +#include +#include +#include + +namespace operations_research { + +template +using value_type_t = typename std::iterator_traits::value_type; + +// Sorts the elements in the range [begin, end) in ascending order using the +// comp predicate. +// +// This function performs well if the elements in the range [begin, end) are +// almost sorted. +// +// The algorithm operates as follows: +// 1) Check that the range [begin, end) is already sorted by performing a +// single iteration of bubble-sort. +// 2) Try to sort the range with insertion sort. Insertion sort will stop if it +// uses the comp predicate more than max_comparisons. Note that the algorithm +// may actually use the comp predicate more than max_comparisons in order +// to complete its current insertion. +// 3) If insertion sort exceeds the maximum number of comparisons, the range is +// sorted using std::sort. +// +// The first two steps of this algorithm are inspired by the ones recommended +// in Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. +template >> +void IncrementalSort(int max_comparisons, Iterator begin, Iterator end, + Compare comp = Compare{}) { + // Ranges of at most one element are already sorted. + if (std::distance(begin, end) <= 1) return; + + // Perform a single iteration of bubble-sort to place the smallest unsorted + // element to its correct position. + Iterator last_sorted = std::prev(end); + for (auto it = last_sorted; it != begin; --it) { + if (comp(*it, *std::prev(it))) { + std::iter_swap(it, std::prev(it)); + last_sorted = it; + } + } + + // Perform insertion sort with a limited number of comparisons. + int num_comps = max_comparisons; + // We know that the elements in the range [begin, last_sorted) are the + // smallest elements of [begin, end) and are sorted. + Iterator it = std::next(last_sorted); + for (; it != end && num_comps > 0; ++it) { + const auto inserted = *it; + Iterator j = it; + num_comps--; + while (comp(inserted, *std::prev(j))) { + num_comps--; + *j = *std::prev(j); + j--; + } + *j = inserted; + } + + // Stop if insertion sort was able to sort the range. + if (it == end) return; + + std::sort(last_sorted, end, comp); +} + +// Sorts the elements in the range [begin, end) in ascending order using the +// comp predicate. The order of equal elements is guaranteed to be preserved. +// +// This function performs well if the elements in the range [begin, end) are +// almost sorted. +// +// This algorithm is inspired by the ones recommended in Algorithms, 4th Edition +// by Robert Sedgewick and Kevin Wayne. +template >> +void InsertionSort(Iterator begin, Iterator end, Compare comp = Compare{}) { + // Ranges of at most one element are already sorted. + if (std::distance(begin, end) <= 1) return; + + // Perform a single iteration of bubble-sort to place the smallest unsorted + // element to its correct position. + Iterator last_sorted = std::prev(end); + for (auto it = last_sorted; it != begin; --it) { + if (comp(*it, *std::prev(it))) { + std::iter_swap(it, std::prev(it)); + last_sorted = it; + } + } + + // We know that the elements in the range [begin, last_sorted) are the + // smallest elements of [begin, end) and are sorted. + for (Iterator it = std::next(last_sorted); it != end; ++it) { + const auto inserted = *it; + Iterator j = it; + while (comp(inserted, *std::prev(j))) { + *j = *std::prev(j); + j--; + } + *j = inserted; + } +} + +// Sorts the elements in the range [begin, end) in ascending order using the +// comp predicate. The order of equal elements is guaranteed to be preserved. +// +// This function performs well if the elements in the range [begin, end) are +// almost sorted. +template >> +void IncrementalSort(Iterator begin, Iterator end, Compare comp = Compare{}) { + const int size = std::distance(begin, end); + if (size <= 32) { + InsertionSort(begin, end, comp); + } else { + IncrementalSort(size * 8, begin, end, comp); + } +} + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_SORT_H_ diff --git a/thirdparty/linux/include/ortools/util/sorted_interval_list.h b/thirdparty/linux/include/ortools/util/sorted_interval_list.h new file mode 100644 index 0000000..8f4d06f --- /dev/null +++ b/thirdparty/linux/include/ortools/util/sorted_interval_list.h @@ -0,0 +1,216 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_SORTED_INTERVAL_LIST_H_ +#define OR_TOOLS_UTIL_SORTED_INTERVAL_LIST_H_ + +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" + +namespace operations_research { + +// Represents a closed interval [start, end]. We must have start <= end. +struct ClosedInterval { + int64 start; // Inclusive. + int64 end; // Inclusive. + + std::string DebugString() const; + bool operator==(const ClosedInterval& other) const { + return start == other.start && end == other.end; + } + bool operator<(const ClosedInterval& other) const { + if (start == other.start) return end < other.end; + return start < other.start; + } +}; + +// Returns a compact std::string of a vector of intervals like "[1,4][6][10,20]". +std::string IntervalsAsString(const std::vector& intervals); + +std::ostream& operator<<(std::ostream& out, const ClosedInterval& interval); +std::ostream& operator<<(std::ostream& out, + const std::vector& intervals); + +// TODO(user): Regroup all the functions below in a SortedDisjointIntervalVector +// class, it will lead to shorter/easier to use names. This will also allow to +// use an inlined vector for the most common case of one or two intervals. + +// Converts an unsorted list of integer values to the unique list of +// non-adjacent, disjoint ClosedInterval spanning exactly these values. Eg. for +// values (after sorting): {1, 2, 3, 5, 7, 8, 10, 11}, it returns the list of +// intervals: [1,3] [5] [7,8] [10,11]. Input values may be repeated, with no +// consequence on the output. +// +// The output will satisfy the criteria of IntervalsAreSortedAndDisjoint(). +std::vector SortedDisjointIntervalsFromValues( + std::vector values); + +// Returns true iff we have: +// - The intervals appear in increasing order. +// - for all i: intervals[i].start <= intervals[i].end +// - for all i but the last: intervals[i].end + 1 < intervals[i+1].start +bool IntervalsAreSortedAndDisjoint( + const std::vector& intervals); + +// Returns true iff the given intervals contain the given value. +// +// TODO(user): This works in O(n), but could be made to work in O(log n) for +// long list of intervals. +bool SortedDisjointIntervalsContain( + const std::vector& intervals, int64 value); + +// Returns the intersection of two lists of sorted disjoint intervals in a +// sorted disjoint interval form. +std::vector IntersectionOfSortedDisjointIntervals( + const std::vector& a, const std::vector& b); + +// Returns the union of two lists of sorted disjoint intervals in a +// sorted disjoint interval form. +std::vector UnionOfSortedDisjointIntervals( + const std::vector& a, const std::vector& b); + +// Returns the domain of x + y given that the domain of x is a and the one of y +// is b. +std::vector AdditionOfSortedDisjointIntervals( + const std::vector& a, const std::vector& b); + +// Returns [kint64min, kint64max] minus the given intervals. +std::vector ComplementOfSortedDisjointIntervals( + const std::vector& intervals); + +// For an x in the given intervals, this returns the domain of -x. +// +// Tricky: because the negation of kint64min doesn't fit, we always remove +// kint64min from the given intervals. +std::vector NegationOfSortedDisjointIntervals( + std::vector intervals); + +// Returns the domain of x * coeff given the domain of x. +// To avoid an explosion in the size of the returned vector, the first function +// will actually return a super-set of the domain. For instance [1, 100] * 2 +// will be transformed in [2, 200] not [2][4][6]...[200]. The second version +// will try to be exact as long as the result is not too large, and will set +// success to true when this is the case. +std::vector MultiplicationOfSortedDisjointIntervals( + std::vector intervals, int64 coeff); +std::vector PreciseMultiplicationOfSortedDisjointIntervals( + std::vector intervals, int64 coeff, bool* success); + +// If x * coeff is in the given intervals, this returns the domain of x. Note +// that it is not the same as given the domains of x, return the domain of x / +// coeff because of how the integer division work. +std::vector InverseMultiplicationOfSortedDisjointIntervals( + std::vector intervals, int64 coeff); + +// This class represents a sorted list of disjoint, closed intervals. When an +// interval is inserted, all intervals that overlap it or that are even adjacent +// to it are merged into one. I.e. [0,14] and [15,30] will be merged to [0,30]. +// +// Iterators returned by this class are invalidated by non-const operations. +// +// TODO(user): Templatize the class on the type of the bounds. +class SortedDisjointIntervalList { + public: + struct IntervalComparator { + bool operator()(const ClosedInterval& a, const ClosedInterval& b) const { + return a.start != b.start ? a.start < b.start : a.end < b.end; + } + }; + typedef std::set IntervalSet; + typedef IntervalSet::iterator Iterator; + + SortedDisjointIntervalList(); + explicit SortedDisjointIntervalList( + const std::vector& intervals); + + // Creates a SortedDisjointIntervalList and fills it with intervals + // [starts[i]..ends[i]]. All intervals must be consistent (starts[i] <= + // ends[i]). There's two version, one for int64, one for int. + // + // TODO(user): Explain why we favored this API to the more natural + // input std::vector or std::vector>. + SortedDisjointIntervalList(const std::vector& starts, + const std::vector& ends); + SortedDisjointIntervalList(const std::vector& starts, + const std::vector& ends); + + // Builds the complement of the interval list on the interval [start, end]. + SortedDisjointIntervalList BuildComplementOnInterval(int64 start, int64 end); + + // Adds the interval [start..end] to the list, and merges overlapping or + // immediately adjacent intervals ([2, 5] and [6, 7] are adjacent, but + // [2, 5] and [7, 8] are not). + // + // Returns an iterator to the inserted interval (possibly merged with others). + // + // If start > end, it does LOG(DFATAL) and returns end() (no interval added). + Iterator InsertInterval(int64 start, int64 end); + + // If value is in an interval, increase its end by one, otherwise insert the + // interval [value, value]. In both cases, this returns an iterator to the + // new/modified interval (possibly merged with others) and fills newly_covered + // with the new value that was just added in the union of all the intervals. + // + // If this causes an interval ending at kint64max to grow, it will die with a + // CHECK fail. + Iterator GrowRightByOne(int64 value, int64* newly_covered); + + // Adds all intervals [starts[i]..ends[i]]. Same behavior as InsertInterval() + // upon invalid intervals. There's a version with int64 and int32. + void InsertIntervals(const std::vector& starts, + const std::vector& ends); + void InsertIntervals(const std::vector& starts, + const std::vector& ends); + + // Returns the number of disjoint intervals in the list. + int NumIntervals() const { return intervals_.size(); } + + // Returns an iterator to either: + // - the first interval containing or above the given value, or + // - the last interval containing or below the given value. + // Returns end() if no interval fulfils that condition. + // + // If the value is within an interval, both functions will return it. + Iterator FirstIntervalGreaterOrEqual(int64 value) const; + Iterator LastIntervalLessOrEqual(int64 value) const; + + std::string DebugString() const; + + // This is to use range loops in C++: + // SortedDisjointIntervalList list; + // ... + // for (const ClosedInterval interval : list) { + // ... + // } + const Iterator begin() const { return intervals_.begin(); } + const Iterator end() const { return intervals_.end(); } + + void clear() { intervals_.clear(); } + void swap(SortedDisjointIntervalList& other) { + intervals_.swap(other.intervals_); + } + + private: + template + void InsertAll(const std::vector& starts, const std::vector& ends); + + IntervalSet intervals_; +}; + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_SORTED_INTERVAL_LIST_H_ diff --git a/thirdparty/linux/include/ortools/util/stats.h b/thirdparty/linux/include/ortools/util/stats.h new file mode 100644 index 0000000..3868949 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/stats.h @@ -0,0 +1,358 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Helper classes to track statistics of a program component. +// +// Usage example: +// // Suppose you have a class that contains a factorization of a matrix B and +// // a Solve() function to solve the linear system B.x = a. +// +// // You will hold your stats in a Stats stats_ class member: +// struct Stats : public StatsGroup { +// Stats() : StatsGroup("BasisFactorization"), +// solve_time("solve_time", this), +// input_vector_density("input_vector_density", this), +// estimated_accuracy("estimated_accuracy", this) {} +// +// TimeDistribution solve_time; +// RatioDistribution input_vector_density; +// +// // Values of a few components of B.x - a, updated on each solve. +// DoubleDistribution estimated_accuracy; +// } +// +// // You then add a few lines to your Solve() function: +// void Solve() { +// stats_.solve_time.StartTimer(); +// stats_.input_vector_density.Add(ComputeDensity()); +// ... // Do the work. +// stats_.estimated_accuracy.Add(EstimateAccuracy()); +// stats_.solve_time.StopTimerAndAddElapsedTime(); +// } +// +// // Now, calling stats_.StatString() will give you a summary of your stats: +// BasisFactorization { +// solve_time : num [min, max] average std_deviation total +// input_vector_density : num [min, max] average std_deviation +// estimated_accuracy : num [min, max] average std_deviation +// } +// +// For measuring time, another alternative is to use the SCOPED_TIME_STAT macro. +// In our example above, you don't need to define the solve_time distribution +// and you can just do: +// +// void Solve() { +// SCOPED_TIME_STAT(&stats_); +// ... +// } +// +// This automatically adds a TimeDistribution with name "Solve" to stats_ and +// times your function calls! +// +// IMPORTANT: The SCOPED_TIME_STAT() macro only does something if OR_STATS is +// The idea is that by default the instrumentation is off. You can also use the +// macro IF_STATS_ENABLED() that does nothing if OR_STATS is not defined or just +// translates to its argument otherwise. + +#ifndef OR_TOOLS_UTIL_STATS_H_ +#define OR_TOOLS_UTIL_STATS_H_ + +#include +#include + +#include "ortools/base/timer.h" + +namespace operations_research { + +// Returns the current thread's total memory usage in an human-readable std::string. +std::string MemoryUsage(); + +// Forward declaration. +class StatsGroup; +class TimeDistribution; + +// Base class for a statistic that can be pretty-printed. +class Stat { + public: + explicit Stat(const std::string& name) : name_(name) {} + + // Also add this stat to the given group. + Stat(const std::string& name, StatsGroup* group); + virtual ~Stat() {} + + // Only used for display purposes. + std::string Name() const { return name_; } + + // Returns a human-readable formated line of the form "name: ValueAsString()". + std::string StatString() const; + + // At display, stats are displayed by decreasing priority, then decreasing + // Sum(), then alphabetical order. + // Used to group the stats per category (timing, ratio, etc..,). + virtual int Priority() const { return 0; } + + // By default return 0 for the sum. This makes it possible to sort stats by + // decreasing total time. + virtual double Sum() const { return 0; } + + // Prints information about this statistic. + virtual std::string ValueAsString() const = 0; + + // Is this stat worth printing? Usually false if nothing was measured. + virtual bool WorthPrinting() const = 0; + + // Reset this statistic to the same state as if it was newly created. + virtual void Reset() = 0; + + private: + const std::string name_; +}; + +// Base class to print a nice summary of a group of statistics. +class StatsGroup { + public: + explicit StatsGroup(const std::string& name) + : name_(name), stats_(), time_distributions_() {} + ~StatsGroup(); + + // Registers a Stat, which will appear in the std::string returned by StatString(). + // The Stat object must live as long as this StatsGroup. + void Register(Stat* stat); + + // Returns this group name, followed by one line per Stat registered with this + // group (this includes the ones created by LookupOrCreateTimeDistribution()). + // Note that only the stats WorthPrinting() are printed. + std::string StatString() const; + + // Returns and if needed creates and registers a TimeDistribution with the + // given name. Note that this involve a map lookup and his thus slower than + // directly accessing a TimeDistribution variable. + TimeDistribution* LookupOrCreateTimeDistribution(std::string name); + + // Calls Reset() on all the statistics registered with this group. + void Reset(); + + private: + std::string name_; + std::vector stats_; + std::map time_distributions_; + + DISALLOW_COPY_AND_ASSIGN(StatsGroup); +}; + +// Base class to track and compute statistics about the distribution of a +// sequence of double. We provide a few sub-classes below that differ in the way +// the values are added to the sequence and in the way the stats are printed. +class DistributionStat : public Stat { + public: + explicit DistributionStat(const std::string& name); + DistributionStat(const std::string& name, StatsGroup* group); + ~DistributionStat() override {} + void Reset() override; + bool WorthPrinting() const override { return num_ != 0; } + + // Implemented by the subclasses. + std::string ValueAsString() const override = 0; + + // Trivial statistics on all the values added so far. + double Sum() const override { return sum_; } + double Max() const { return max_; } + double Min() const { return min_; } + int64 Num() const { return num_; } + + // Get the average of the distribution or 0.0 if empty. + double Average() const; + + // Get the standard deviation of the distribution or 0.0 if empty. + // We use the on-line algorithm of Welford described at + // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance + // TODO(user): We could also use on top the Kahan summation algorithm to be + // even more precise but a bit slower too. + double StdDeviation() const; + + protected: + // Adds a value to this sequence and updates the stats. + void AddToDistribution(double value); + double sum_; + double average_; + double sum_squares_from_average_; + double min_; + double max_; + int64 num_; +}; + +// Statistic on the distribution of a sequence of running times. +// Also provides some facility to measure such time with the CPU cycle counter. +// +// TODO(user): Since we inherit from DistributionStat, we currently store the +// sum of CPU cycles as a double internally. A better option is to use int64 +// because with the 53 bits of precision of a double, we will run into an issue +// if the sum of times reaches 52 days for a 2GHz processor. +class TimeDistribution : public DistributionStat { + public: + explicit TimeDistribution(const std::string& name) + : DistributionStat(name), timer_() {} + TimeDistribution(const std::string& name, StatsGroup* group) + : DistributionStat(name, group), timer_() {} + std::string ValueAsString() const override; + + // Time distributions have a high priority to be displayed first. + int Priority() const override { return 100; } + + // Internaly the TimeDistribution stores CPU cycles (to do a bit less work + // on each StopTimerAndAddElapsedTime()). Use this function to convert + // all the statistics of DistributionStat into seconds. + static double CyclesToSeconds(double num_cycles); + + // Adds a time in seconds to this distribution. + void AddTimeInSec(double value); + + // Adds a time in CPU cycles to this distribution. + void AddTimeInCycles(double value); + + // Starts the timer in preparation of a StopTimerAndAddElapsedTime(). + inline void StartTimer() { timer_.Restart(); } + + // Adds the elapsed time since the last StartTimer() to the distribution and + // returns this time in CPU cycles. + inline double StopTimerAndAddElapsedTime() { + const double cycles = static_cast(timer_.GetCycles()); + AddToDistribution(cycles); + return cycles; + } + + private: + // Converts and prints a number of cycles in an human readable way using the + // proper time unit depending on the value (ns, us, ms, s, m or h). + static std::string PrintCyclesAsTime(double cycles); + CycleTimer timer_; +}; + +// Statistic on the distribution of a sequence of ratios, displayed as %. +class RatioDistribution : public DistributionStat { + public: + explicit RatioDistribution(const std::string& name) : DistributionStat(name) {} + RatioDistribution(const std::string& name, StatsGroup* group) + : DistributionStat(name, group) {} + std::string ValueAsString() const override; + void Add(double value); +}; + +// Statistic on the distribution of a sequence of doubles. +class DoubleDistribution : public DistributionStat { + public: + explicit DoubleDistribution(const std::string& name) : DistributionStat(name) {} + DoubleDistribution(const std::string& name, StatsGroup* group) + : DistributionStat(name, group) {} + std::string ValueAsString() const override; + void Add(double value); +}; + +// Statistic on the distribution of a sequence of integers. +class IntegerDistribution : public DistributionStat { + public: + explicit IntegerDistribution(const std::string& name) : DistributionStat(name) {} + IntegerDistribution(const std::string& name, StatsGroup* group) + : DistributionStat(name, group) {} + std::string ValueAsString() const override; + void Add(int64 value); +}; + +// Helper classes to time a block of code and add the result to a +// TimeDistribution. Calls StartTimer() on creation and +// StopTimerAndAddElapsedTime() on destruction. +// +// There are three classes with the same interface: +// * EnabledScopedTimeDistributionUpdater always collects the time stats of the +// scope in which it is defined. This class is used for stats that are always +// collected. +// * ScopedTimeDistributionUpdater collects the time stats only when OR_STATS is +// defined. This symbol should be used for collecting stats in places where +// the overhead of collecting the stats may hurt the performance of the +// algorithm. +// * DisabledScopedTimeDistributionUpdater is used to implement +// ScopedTimeDistributionUpdater when OR_STATS is not defined. +class EnabledScopedTimeDistributionUpdater { + public: + // Note that this does not take ownership of the given stat. + explicit EnabledScopedTimeDistributionUpdater(TimeDistribution* stat) + : stat_(stat), also_update_(nullptr) { + stat->StartTimer(); + } + ~EnabledScopedTimeDistributionUpdater() { + const double cycles = stat_->StopTimerAndAddElapsedTime(); + if (also_update_ != nullptr) { + also_update_->AddTimeInCycles(cycles); + } + } + + // Updates another TimeDistribution on destruction. This is useful to split + // a total time measurement in different categories: + // + // EnabledScopedTimeDistributionUpdater timer(&total_timer); + // ... + // switch (type) { + // case TypeA : timer.AlsoUpdate(&typeA_timer); break; + // case TypeB : timer.AlsoUpdate(&typeB_timer); break; + // } + void AlsoUpdate(TimeDistribution* also_update) { also_update_ = also_update; } + + private: + TimeDistribution* stat_; + TimeDistribution* also_update_; + DISALLOW_COPY_AND_ASSIGN(EnabledScopedTimeDistributionUpdater); +}; + +class DisabledScopedTimeDistributionUpdater { + public: + explicit DisabledScopedTimeDistributionUpdater(TimeDistribution* stat) {} + void AlsoUpdate(TimeDistribution* also_update) {} + + private: + DISALLOW_COPY_AND_ASSIGN(DisabledScopedTimeDistributionUpdater); +}; + +#ifdef OR_STATS + +using ScopedTimeDistributionUpdater = EnabledScopedTimeDistributionUpdater; + +// Simple macro to be used by a client that want to execute costly operations +// only if OR_STATS is defined. +#define IF_STATS_ENABLED(instructions) instructions + +// Measures the time from this macro line to the end of the scope and adds it +// to the distribution (from the given StatsGroup) with the same name as the +// enclosing function. +// +// Note(user): This adds more extra overhead around the measured code compared +// to defining your own TimeDistribution stat in your StatsGroup. About 80ns +// per measurement compared to about 20ns (as of 2012-06, on my workstation). +#define SCOPED_TIME_STAT(stats) \ + operations_research::ScopedTimeDistributionUpdater scoped_time_stat( \ + (stats)->LookupOrCreateTimeDistribution(__FUNCTION__)) + +#else // OR_STATS +// If OR_STATS is not defined, we remove some instructions that may be time +// consuming. + +using ScopedTimeDistributionUpdater = DisabledScopedTimeDistributionUpdater; + +#define IF_STATS_ENABLED(instructions) +#define SCOPED_TIME_STAT(stats) + +#endif // OR_STATS + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_STATS_H_ diff --git a/thirdparty/linux/include/ortools/util/string_array.h b/thirdparty/linux/include/ortools/util/string_array.h new file mode 100644 index 0000000..d2fbc49 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/string_array.h @@ -0,0 +1,64 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_UTIL_STRING_ARRAY_H_ +#define OR_TOOLS_UTIL_STRING_ARRAY_H_ + +#include +#include + +namespace operations_research { +// ---------- Pretty Print Helpers ---------- + +// See the straightforward (and unique) usage of this macro below. +#define RETURN_STRINGIFIED_VECTOR(vector, separator, method) \ + std::string out; \ + for (int i = 0; i < vector.size(); ++i) { \ + if (i > 0) out += separator; \ + out += vector[i] method; \ + } \ + return out + +// Converts a vector into a std::string by calling the given method (or simply +// getting the given std::string member), on all elements, and concatenating +// the obtained strings with the given separator. + +// Join v[i].DebugString(). +template +std::string JoinDebugString(const std::vector& v, const std::string& separator) { + RETURN_STRINGIFIED_VECTOR(v, separator, .DebugString()); +} + +// Join v[i]->DebugString(). +template +std::string JoinDebugStringPtr(const std::vector& v, const std::string& separator) { + RETURN_STRINGIFIED_VECTOR(v, separator, ->DebugString()); +} + +// Join v[i]->name(). +template +std::string JoinNamePtr(const std::vector& v, const std::string& separator) { + RETURN_STRINGIFIED_VECTOR(v, separator, ->name()); +} + +// Join v[i]->name. +template +std::string JoinNameFieldPtr(const std::vector& v, const std::string& separator) { + RETURN_STRINGIFIED_VECTOR(v, separator, ->name); +} + +#undef RETURN_STRINGIFIED_VECTOR + +} // namespace operations_research +#endif // OR_TOOLS_UTIL_STRING_ARRAY_H_ diff --git a/thirdparty/linux/include/ortools/util/time_limit.h b/thirdparty/linux/include/ortools/util/time_limit.h new file mode 100644 index 0000000..4bc582f --- /dev/null +++ b/thirdparty/linux/include/ortools/util/time_limit.h @@ -0,0 +1,360 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_TIME_LIMIT_H_ +#define OR_TOOLS_UTIL_TIME_LIMIT_H_ + +#include +#include +#include +#include +#include +#ifndef NDEBUG +#include +#endif + +#include "ortools/base/commandlineflags.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/port.h" +#include "ortools/base/timer.h" +#include "ortools/base/time_support.h" +#include "ortools/base/sysinfo.h" +#include "ortools/util/running_stat.h" + +// Enables to change the behavior of the TimeLimit class to use "usertime" +// instead of walltime. This is mainly useful for benchmarks. +DECLARE_bool(time_limit_use_usertime); + +namespace operations_research { + +// A simple class to enforce both an elapsed time limit and a deterministic time +// limit in the same thread as a program. +// The idea is to call LimitReached() as often as possible, until it returns +// false. The program should then abort as fast as possible. +// +// The deterministic limit is used to ensure reproductibility, as a consequence +// the deterministic time has to be advanced manually using the method +// AdvanceDeterministicTime(). +// +// The call itself is as fast as CycleClock::Now() + a few trivial instructions. +// +// The limit is very conservative: it returns true (i.e. the limit is reached) +// when current_time + std::max(T, ε) >= limit_time, where ε is a small constant (see +// TimeLimit::kSafetyBufferSeconds), and T is the maximum measured time interval +// between two consecutive calls to LimitReached() over the last kHistorySize +// calls (so that we only consider "recent" history). +// This is made so that the probability of actually exceeding the time limit is +// small, without aborting too early. +// +// The deterministic time limit can be logged at a more granular level: the +// method TimeLimit::AdvanceDeterministicTime takes an optional std::string argument: +// the name of a counter. In debug mode, the time limit object computes also the +// elapsed time for each named counter separately, and these values can be used +// to determine the coefficients for computing the deterministic duration from +// the number of operations. The values of the counters can be printed using +// TimeLimit::DebugString(). There is no API to access the values of the +// counters directly, because they do not exist in optimized mode. +// +// The basic steps for determining coefficients for the deterministic time are: +// 1. Run the code in debug mode to collect the values of the deterministic time +// counters. Unless the algorithm is different in optimized mode, the values +// of the deterministic counters in debug mode will be the same as in +// optimized mode. +// 2. Run the code in optimized mode to measure the real (CPU) time of the whole +// benchmark. +// 3. Determine the coefficients for deterministic time from the real time and +// the values of the deterministic counters, e. g. by solving the equations +// C_1*c_1 + C_2*c_2 + ... + C_N*c_N + Err = T +// where C_1 is the unknown coefficient for counter c_1, Err is the random +// measurement error and T is the measured real time. The equation can be +// solved e.g. using the least squares method. +// +// Note that in optimized mode, the counters are disabled for performance +// reasons, and calling AdvanceDeterministicTime(duration, counter_name) is +// equivalent to calling AdvanceDeterministicTime(duration). +// +// TODO(user): The expression "deterministic time" should be replaced with +// "number of operations" to avoid confusion with "real" time. +class TimeLimit { + public: + static const double kSafetyBufferSeconds; // See the .cc for the value. + static const int kHistorySize; + + // Sets both the elapsed and the deterministic time limits. + // The elapsed time is based on the wall time and the counter starts 'now'. + // The deterministic time has to be manually advanced using the method + // AdvanceDeterministicTime(). + // Use an infinite limit value to ignore a limit. + explicit TimeLimit( + double limit_in_seconds, + double deterministic_limit = std::numeric_limits::infinity()); + + // Creates a time limit object that uses infinite time for both wall time and + // deterministic time. + static std::unique_ptr Infinite() { + return std::unique_ptr( + new TimeLimit(std::numeric_limits::infinity(), + std::numeric_limits::infinity())); + } + + // Creates a time limit object that puts limit only on the deterministic time. + static std::unique_ptr FromDeterministicTime( + double deterministic_limit) { + return std::unique_ptr(new TimeLimit( + std::numeric_limits::infinity(), deterministic_limit)); + } + + // Creates a time limit object initialized from an object that provides + // methods max_time_in_seconds() and max_deterministic_time(). This method is + // designed specifically to work with solver parameter protos, e.g. + // BopParameters, MipParameters and SatParameters. + template + static std::unique_ptr FromParameters( + const Parameters& parameters) { + return std::unique_ptr(new TimeLimit( + parameters.max_time_in_seconds(), parameters.max_deterministic_time())); + } + + // Returns true when the external limit is true, or the deterministic time is + // over the deterministic limit or if the next time LimitReached() is called + // is likely to be over the time limit. See toplevel comment. + // Once it has returned true, it is guaranteed to always return true. + bool LimitReached(); + + // Returns the time left on this limit, or 0 if the limit was reached (it + // never returns a negative value). Note that it might return a positive + // value even though LimitReached() would return true; because the latter is + // conservative (see toplevel comment). + // If LimitReached() was actually called and did return "true", though, this + // will always return 0. + // + // If the TimeLimit was constructed with "infinity" as the limit, this will + // always return infinity. + // + // Note that this function is not optimized for speed as LimitReached() is. + double GetTimeLeft() const; + + // Returns the remaining deterministic time before LimitReached() returns + // true due to the deterministic limit. + // If the TimeLimit was constructed with "infinity" as the deterministic + // limit (default value), this will always return infinity. + double GetDeterministicTimeLeft() const { + return std::max(0.0, deterministic_limit_ - elapsed_deterministic_time_); + } + + // Advances the deterministic time. For reproducibility reasons, the + // deterministic time doesn't advance automatically as the regular elasped + // time does. + inline void AdvanceDeterministicTime(double deterministic_duration) { + DCHECK_LE(0.0, deterministic_duration); + elapsed_deterministic_time_ += deterministic_duration; + } + + // Advances the deterministic time. For reproducibility reasons, the + // deterministic time doesn't advance automatically as the regular elasped + // time does. + // + // In debug mode, this method also updates the deterministic time counter with + // the given name. In optimized mode, this method is equivalent to + // AdvanceDeterministicTime(double). + inline void AdvanceDeterministicTime(double deterministic_duration, + const char* counter_name) { + AdvanceDeterministicTime(deterministic_duration); +#ifndef NDEBUG + deterministic_counters_[counter_name] += deterministic_duration; +#endif + } + + // Returns the time elapsed in seconds since the construction of this object. + double GetElapsedTime() const { +return 1e-9 * (base::GetCurrentTimeNanos() - start_ns_); + } + + // Returns the elapsed deterministic time since the construction of this + // object. That corresponds to the sum of all deterministic durations passed + // as an argument to AdvanceDeterministicTime() calls. + double GetElapsedDeterministicTime() const { + return elapsed_deterministic_time_; + } + + // Registers the external Boolean to check when LimitReached() is called. + // This is used to mark the limit as reached through an external Boolean, + // i.e. LimitReached() returns true when the value of + // external_boolean_as_limit is true whatever the time limits are. + // + // Note that external_boolean_as_limit is not protected by a mutex; This + // should not prevent usage in a mutli-threading environment because the + // change is atomic and it is usually not critical to wrongly return false in + // LimitReached() once in case of race between the change of the Boolean and + // the check of the limit. + void RegisterExternalBooleanAsLimit(const bool* external_boolean_as_limit) { + external_boolean_as_limit_ = external_boolean_as_limit; + } + + // Returns information about the time limit object in a human-readable form. + std::string DebugString() const; + + private: + const int64 start_ns_; + int64 last_ns_; + int64 limit_ns_; // Not const! See the code of LimitReached(). + const int64 safety_buffer_ns_; + RunningMax running_max_; + +// Only used when FLAGS_time_limit_use_usertime is true. + UserTimer user_timer_; + double limit_in_seconds_; + + double deterministic_limit_; + double elapsed_deterministic_time_; + + const bool* external_boolean_as_limit_; + +#ifndef NDEBUG + // Contains the values of the deterministic time counters. + std::unordered_map deterministic_counters_; +#endif + + friend class NestedTimeLimit; + friend class ParallelTimeLimit; + + DISALLOW_COPY_AND_ASSIGN(TimeLimit); +}; + +// Provides a way to nest time limits for algorithms where a certain part of +// the computation is bounded not just by the overall time limit, but also by a +// stricter time limit specific just for this particular part. +// +// This class takes a base time limit object (the overall time limit) and the +// part-specific time limit, and creates a new time limit object for the part. +// This new time limit object will expire when either the overall time limit +// expires or when the part-specific time limit expires. +// +// Example usage: +// TimeLimit overall_time_limit(...); +// NestedTimeLimit subalgorith_time_limit(&overall_time_limit, +// subalgorithm_limit_in_seconds, +// subalgorithm_deterministic_limit); +// RunTheSubalgorithm(subalgorithm_time_limit.GetTimeLimit()); +// +// Note that remaining wall time in the base time limit is decreasing +// "automatically", but the deterministic time needs to be updated manually. +// This update is done only once, during the destruction of the nested time +// limit object. To track the deterministic time properly, the user must avoid +// modifying the base time limit object when a nested time limit exists. +// +// The nested time limits supports the external time limit condition in the +// sense, that if the overall time limit has an external boolean registered, the +// nested time limit object will use the same boolean value as an external time +// limit too. +class NestedTimeLimit { + public: + // Creates the nested time limit. Note that 'base_time_limit' must remain + // valid for the whole lifetime of the nested time limit object. + NestedTimeLimit(TimeLimit* base_time_limit, double limit_in_seconds, + double deterministic_limit); + // Updates elapsed deterministic time in the base time limit object. + ~NestedTimeLimit(); + + // Creates a time limit object initialized from a base time limit and an + // object that provides methods max_time_in_seconds() and + // max_deterministic_time(). This method is designed specifically to work with + // solver parameter protos, e.g. BopParameters, MipParameters and + // SatParameters. + template + static std::unique_ptr FromBaseTimeLimitAndParameters( + TimeLimit* time_limit, const Parameters& parameters) { + return std::unique_ptr( + new NestedTimeLimit(time_limit, parameters.max_time_in_seconds(), + parameters.max_deterministic_time())); + } + + // Returns a time limit object that represents the combination of the overall + // time limit and the part-specific time limit. The returned time limit object + // is owned by the nested time limit object that returns it, and it will + // remain valid until the nested time limit object is destroyed. + TimeLimit* GetTimeLimit() { return &time_limit_; } + + private: + TimeLimit* const base_time_limit_; + TimeLimit time_limit_; + + DISALLOW_COPY_AND_ASSIGN(NestedTimeLimit); +}; + + +// ################## Implementations below ##################### + +inline TimeLimit::TimeLimit(double limit_in_seconds, double deterministic_limit) + : start_ns_(base::GetCurrentTimeNanos()), + last_ns_(start_ns_), + limit_ns_(limit_in_seconds >= 1e-9 * (kint64max - start_ns_) + ? kint64max + : static_cast(limit_in_seconds * 1e9) + start_ns_), + safety_buffer_ns_(static_cast(kSafetyBufferSeconds * 1e9)), + running_max_(kHistorySize), + deterministic_limit_(deterministic_limit), + elapsed_deterministic_time_(0.0), + external_boolean_as_limit_(nullptr) { + if (FLAGS_time_limit_use_usertime) { + user_timer_.Start(); + limit_in_seconds_ = limit_in_seconds; + } +} + +inline bool TimeLimit::LimitReached() { + if (external_boolean_as_limit_ != nullptr && *external_boolean_as_limit_) { + return true; + } + + if (GetDeterministicTimeLeft() <= 0.0) { + return true; + } + + const int64 current_ns = base::GetCurrentTimeNanos(); + running_max_.Add(std::max(safety_buffer_ns_, current_ns - last_ns_)); + last_ns_ = current_ns; + if (current_ns + running_max_.GetCurrentMax() >= limit_ns_) { + if (FLAGS_time_limit_use_usertime) { + // To avoid making many system calls, we only check the user time when + // the "absolute" time limit has been reached. Note that the user time + // should advance more slowly, so this is correct. + const double time_left_s = limit_in_seconds_ - user_timer_.Get(); + if (time_left_s > kSafetyBufferSeconds) { + limit_ns_ = static_cast(time_left_s * 1e9) + last_ns_; + return false; + } + } + + // To ensure that future calls to LimitReached() will return true. + limit_ns_ = 0; + return true; + } + return false; +} + +inline double TimeLimit::GetTimeLeft() const { + if (limit_ns_ == kint64max) return std::numeric_limits::infinity(); + const int64 delta_ns = limit_ns_ - base::GetCurrentTimeNanos(); + if (delta_ns < 0) return 0.0; + if (FLAGS_time_limit_use_usertime) { + return std::max(limit_in_seconds_ - user_timer_.Get(), 0.0); + } else { + return delta_ns * 1e-9; + } +} + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_TIME_LIMIT_H_ diff --git a/thirdparty/linux/include/ortools/util/tuple_set.h b/thirdparty/linux/include/ortools/util/tuple_set.h new file mode 100644 index 0000000..915af73 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/tuple_set.h @@ -0,0 +1,425 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Set of integer tuples (fixed-size arrays, all of the same size) with +// a basic API. +// It supports several types of integer arrays transparently, with an +// inherent storage based on int64 arrays. +// +// The key feature is the "lazy" copy: +// - Copying an IntTupleSet won't actually copy the data right away; we +// will just have several IntTupleSet pointing at the same data. +// - Modifying an IntTupleSet which shares his data with others +// will create a new, modified instance of the data payload, and make +// the IntTupleSet point to that new data. +// - Modifying an IntTupleSet that doesn't share its data with any other +// IntTupleSet will modify the data directly. +// Therefore, you don't need to use const IntTupleSet& in methods. Just do: +// void MyMethod(IntTupleSet tuple_set) { ... } +// +// This class is thread hostile as the copy and reference counter are +// not protected by a mutex. + +#ifndef OR_TOOLS_UTIL_TUPLE_SET_H_ +#define OR_TOOLS_UTIL_TUPLE_SET_H_ + +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" +#include "ortools/base/map_util.h" +#include "ortools/base/hash.h" + +namespace operations_research { +// ----- Main IntTupleSet class ----- +class IntTupleSet { + public: + // Creates an empty tuple set with a fixed length for all tuples. + explicit IntTupleSet(int arity); + // Copy constructor (it actually does a lazy copy, see toplevel comment). + IntTupleSet(const IntTupleSet& set); // NOLINT + ~IntTupleSet(); + + // Clears data. + void Clear(); + + // Inserts the tuple to the set. It does nothing if the tuple is + // already in the set. The size of the tuple must be equal to the + // arity of the set. It returns the index at which the tuple was + // inserted (-1 if it was already present). + int Insert(const std::vector& tuple); + int Insert(const std::vector& tuple); + // Arity fixed version of Insert removing the need for a vector for the user. + int Insert2(int64 v0, int64 v1); + int Insert3(int64 v0, int64 v1, int64 v2); + int Insert4(int64 v0, int64 v1, int64 v2, int64 v3); + // Inserts the tuples. + void InsertAll(const std::vector >& tuples); + void InsertAll(const std::vector >& tuples); + + // Checks if the tuple is in the set. + bool Contains(const std::vector& tuple) const; + bool Contains(const std::vector& tuple) const; + + // Returns the number of tuples. + int NumTuples() const; + // Get the given tuple's value at the given position. The indices + // of the tuples correspond to the order in which they were + // inserted. + int64 Value(int tuple_index, int pos_in_tuple) const; + // Returns the arity of the set. + int Arity() const; + // Access the raw data, see IntTupleSet::Data::flat_tuples_. + const int64* RawData() const; + // Returns the number of different values in the given column. + int NumDifferentValuesInColumn(int col) const; + // Return a copy of the set, sorted by the "col"-th value of each + // tuples. The sort is stable. + IntTupleSet SortedByColumn(int col) const; + // Returns a copy of the tuple set lexicographically sorted. + IntTupleSet SortedLexicographically() const; + + private: + // Class that holds the actual data of an IntTupleSet. It handles + // the reference counters, etc. + class Data { + public: + explicit Data(int arity); + Data(const Data& data); + ~Data(); + void AddSharedOwner(); + bool RemovedSharedOwner(); + Data* CopyIfShared(); + template + int Insert(const std::vector& tuple); + template + bool Contains(const std::vector& candidate) const; + template + int64 Fingerprint(const std::vector& tuple) const; + int NumTuples() const; + int64 Value(int index, int pos) const; + int Arity() const; + const int64* RawData() const; + void Clear(); + + private: + const int arity_; + int num_owners_; + // Concatenation of all tuples ever added. + std::vector flat_tuples_; + // Maps a tuple's fingerprint to the list of tuples with this + // fingerprint, represented by their start index in the + // flat_tuples_ vector. + std::unordered_map > tuple_fprint_to_index_; + }; + + // Used to represent a light representation of a tuple. + struct IndexData { + int index; + IntTupleSet::Data* data; + IndexData(int i, IntTupleSet::Data* const d) : index(i), data(d) {} + static bool Compare(const IndexData& tuple1, const IndexData& tuple2); + }; + + struct IndexValue { + int index; + int64 value; + IndexValue(int i, int64 v) : index(i), value(v) {} + static bool Compare(const IndexValue& tuple1, const IndexValue& tuple2); + }; + + mutable Data* data_; +}; + +// ----- Data ----- +inline IntTupleSet::Data::Data(int arity) : arity_(arity), num_owners_(0) {} + +inline IntTupleSet::Data::Data(const Data& data) + : arity_(data.arity_), + num_owners_(0), + flat_tuples_(data.flat_tuples_), + tuple_fprint_to_index_(data.tuple_fprint_to_index_) {} + +inline IntTupleSet::Data::~Data() {} + +inline void IntTupleSet::Data::AddSharedOwner() { num_owners_++; } + +inline bool IntTupleSet::Data::RemovedSharedOwner() { + return (--num_owners_ == 0); +} + +inline IntTupleSet::Data* IntTupleSet::Data::CopyIfShared() { + if (num_owners_ > 1) { // Copy on write. + Data* const new_data = new Data(*this); + RemovedSharedOwner(); + new_data->AddSharedOwner(); + return new_data; + } + return this; +} + +template +int IntTupleSet::Data::Insert(const std::vector& tuple) { + DCHECK(arity_ == 0 || flat_tuples_.size() % arity_ == 0); + CHECK_EQ(arity_, tuple.size()); + DCHECK_EQ(1, num_owners_); + if (!Contains(tuple)) { + const int index = NumTuples(); + const int offset = flat_tuples_.size(); + flat_tuples_.resize(offset + arity_); + // On mac os X, using this instead of push_back gives a 10x speedup! + for (int i = 0; i < arity_; ++i) { + flat_tuples_[offset + i] = tuple[i]; + } + const int64 fingerprint = Fingerprint(tuple); + tuple_fprint_to_index_[fingerprint].push_back(index); + return index; + } else { + return -1; + } +} + +template +bool IntTupleSet::Data::Contains(const std::vector& candidate) const { + if (candidate.size() != arity_) { + return false; + } + const int64 fingerprint = Fingerprint(candidate); + if (ContainsKey(tuple_fprint_to_index_, fingerprint)) { + const std::vector& indices = + FindOrDie(tuple_fprint_to_index_, fingerprint); + for (int i = 0; i < indices.size(); ++i) { + const int tuple_index = indices[i]; + for (int j = 0; j < arity_; ++j) { + if (candidate[j] != flat_tuples_[tuple_index * arity_ + j]) { + return false; + } + } + return true; + } + } + return false; +} + +template +int64 IntTupleSet::Data::Fingerprint(const std::vector& tuple) const { + switch (arity_) { + case 0: + return 0; + case 1: + return tuple[0]; + case 2: { + uint64 x = tuple[0]; + uint64 y = GG_ULONGLONG(0xe08c1d668b756f82); + uint64 z = tuple[1]; + mix(x, y, z); + return z; + } + default: { + uint64 x = tuple[0]; + uint64 y = GG_ULONGLONG(0xe08c1d668b756f82); + for (int i = 1; i < tuple.size(); ++i) { + uint64 z = tuple[i]; + mix(x, y, z); + x = z; + } + return x; + } + } +} + +inline int IntTupleSet::Data::NumTuples() const { + return tuple_fprint_to_index_.size(); +} + +inline int64 IntTupleSet::Data::Value(int index, int pos) const { + DCHECK_GE(index, 0); + DCHECK_LT(index, flat_tuples_.size() / arity_); + DCHECK_GE(pos, 0); + DCHECK_LT(pos, arity_); + return flat_tuples_[index * arity_ + pos]; +} + +inline int IntTupleSet::Data::Arity() const { return arity_; } + +inline const int64* IntTupleSet::Data::RawData() const { + return flat_tuples_.data(); +} + +inline void IntTupleSet::Data::Clear() { + flat_tuples_.clear(); + tuple_fprint_to_index_.clear(); +} + +inline IntTupleSet::IntTupleSet(int arity) : data_(new Data(arity)) { + CHECK_GE(arity, 0); + data_->AddSharedOwner(); +} + +inline IntTupleSet::IntTupleSet(const IntTupleSet& set) : data_(set.data_) { + data_->AddSharedOwner(); +} + +inline IntTupleSet::~IntTupleSet() { + CHECK_NOTNULL(data_); + if (data_->RemovedSharedOwner()) { + delete data_; + } +} + +inline void IntTupleSet::Clear() { + data_ = data_->CopyIfShared(); + data_->Clear(); +} + +inline int IntTupleSet::Insert(const std::vector& tuple) { + data_ = data_->CopyIfShared(); + return data_->Insert(tuple); +} + +inline int IntTupleSet::Insert(const std::vector& tuple) { + data_ = data_->CopyIfShared(); + return data_->Insert(tuple); +} + +inline int IntTupleSet::Insert2(int64 v0, int64 v1) { + std::vector tuple(2); + tuple[0] = v0; + tuple[1] = v1; + return Insert(tuple); +} + +inline int IntTupleSet::Insert3(int64 v0, int64 v1, int64 v2) { + std::vector tuple(3); + tuple[0] = v0; + tuple[1] = v1; + tuple[2] = v2; + return Insert(tuple); +} + +inline int IntTupleSet::Insert4(int64 v0, int64 v1, int64 v2, int64 v3) { + std::vector tuple(4); + tuple[0] = v0; + tuple[1] = v1; + tuple[2] = v2; + tuple[3] = v3; + return Insert(tuple); +} + +inline bool IntTupleSet::Contains(const std::vector& tuple) const { + return data_->Contains(tuple); +} + +inline bool IntTupleSet::Contains(const std::vector& tuple) const { + return data_->Contains(tuple); +} + +inline void IntTupleSet::InsertAll( + const std::vector >& tuples) { + data_ = data_->CopyIfShared(); + for (int i = 0; i < tuples.size(); ++i) { + Insert(tuples[i]); + } +} + +inline void IntTupleSet::InsertAll( + const std::vector >& tuples) { + data_ = data_->CopyIfShared(); + for (int i = 0; i < tuples.size(); ++i) { + Insert(tuples[i]); + } +} + +inline int IntTupleSet::NumTuples() const { return data_->NumTuples(); } + +inline int64 IntTupleSet::Value(int index, int pos) const { + return data_->Value(index, pos); +} + +inline int IntTupleSet::Arity() const { return data_->Arity(); } + +inline const int64* IntTupleSet::RawData() const { return data_->RawData(); } + +inline int IntTupleSet::NumDifferentValuesInColumn(int col) const { + if (col < 0 || col >= data_->Arity()) { + return 0; + } + std::unordered_set values; + for (int i = 0; i < data_->NumTuples(); ++i) { + values.insert(data_->Value(i, col)); + } + return values.size(); +} + +inline bool IntTupleSet::IndexValue::Compare(const IndexValue& a, + const IndexValue& b) { + return a.value < b.value || (a.value == b.value && a.index < b.index); +} + +inline IntTupleSet IntTupleSet::SortedByColumn(int col) const { + std::vector keys; + keys.reserve(data_->NumTuples()); + for (int index = 0; index < data_->NumTuples(); ++index) { + keys.push_back(IndexValue(index, data_->Value(index, col))); + } + std::sort(keys.begin(), keys.end(), IntTupleSet::IndexValue::Compare); + const int arity = data_->Arity(); + IntTupleSet sorted(arity); + for (int i = 0; i < keys.size(); ++i) { + const int64* tuple_ptr = data_->RawData() + keys[i].index * arity; + sorted.Insert(std::vector(tuple_ptr, tuple_ptr + arity)); + } + return sorted; +} + +inline bool IntTupleSet::IndexData::Compare(const IndexData& a, + const IndexData& b) { + const IntTupleSet::Data* const data = a.data; + const int arity = data->Arity(); + for (int i = 0; i < arity; ++i) { + const int64 value1 = data->Value(a.index, i); + const int64 value2 = data->Value(b.index, i); + if (value1 < value2) { + return true; + } + if (value1 > value2) { + return false; + } + } + return false; +} + +inline IntTupleSet IntTupleSet::SortedLexicographically() const { + std::vector keys; + keys.reserve(data_->NumTuples()); + for (int index = 0; index < data_->NumTuples(); ++index) { + keys.push_back(IndexData(index, data_)); + } + std::sort(keys.begin(), keys.end(), IntTupleSet::IndexData::Compare); + const int arity = data_->Arity(); + IntTupleSet sorted(arity); + for (int i = 0; i < keys.size(); ++i) { + std::vector tuple(arity); + const int64* tuple_ptr = data_->RawData() + keys[i].index * arity; + sorted.Insert(std::vector(tuple_ptr, tuple_ptr + arity)); + } + return sorted; +} +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_TUPLE_SET_H_ diff --git a/thirdparty/linux/include/ortools/util/vector_map.h b/thirdparty/linux/include/ortools/util/vector_map.h new file mode 100644 index 0000000..2ff346c --- /dev/null +++ b/thirdparty/linux/include/ortools/util/vector_map.h @@ -0,0 +1,113 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Vector with map from element to index in the vector. + +#ifndef OR_TOOLS_UTIL_VECTOR_MAP_H_ +#define OR_TOOLS_UTIL_VECTOR_MAP_H_ + +#include +#include +#include "ortools/base/map_util.h" + +namespace operations_research { + +// This class stores a vector of distinct elements, as well as a map +// from elements to index to find the index in the vector. +// This is useful to store mapping between objects and indices. +template +class VectorMap { + public: + // Adds an element if not already present, and returns its index in + // the vector-map. + int Add(const T& element) { + int current_index = Index(element); + if (current_index != -1) { + return current_index; + } + const int index = list_.size(); + CHECK_EQ(index, map_.size()); + list_.push_back(element); + map_[element] = index; + return index; + } + // TODO(user): Use ArraySlice. + + // Adds all elements of the vector. + void Add(const std::vector& elements) { + for (int i = 0; i < elements.size(); ++i) { + Add(elements[i]); + } + } + + // Will return the index of the element if present, or die otherwise. + int IndexOrDie(const T& element) const { return FindOrDie(map_, element); } + + // Returns -1 if the element is not in the vector, or its unique + // index if it is. + int Index(const T& element) const { + return FindWithDefault(map_, element, -1); + } + // TODO(user): explore a int-type version. + + // Returns wether the element has already been added to the vector-map. + bool Contains(const T& element) const { return ContainsKey(map_, element); } + + // Returns the element at position index. + const T& Element(int index) const { + CHECK_GE(index, 0); + CHECK_LT(index, list_.size()); + return list_[index]; + } + + const T& operator[](int index) const { return Element(index); } + + // Returns the number of distinct elements added to the vector-map. + int size() const { return list_.size(); } + + // Clears all the elements added to the vector-map. + void clear() { + list_.clear(); + map_.clear(); + } + + // Returns a read-only access to the vector of elements. + const std::vector& list() const { return list_; } + + // Standard STL container boilerplate. + typedef T value_type; + typedef const T* pointer; + typedef const T& reference; + typedef const T& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static const size_type npos; + typedef const T* const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + const_iterator begin() const { return list_.data(); } + const_iterator end() const { return list_.data() + list_.size(); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(list_.data() + list_.size()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(list_.data()); + } + + private: + std::vector list_; + std::unordered_map map_; +}; + +} // namespace operations_research +#endif // OR_TOOLS_UTIL_VECTOR_MAP_H_ diff --git a/thirdparty/linux/include/ortools/util/vector_or_function.h b/thirdparty/linux/include/ortools/util/vector_or_function.h new file mode 100644 index 0000000..d87930b --- /dev/null +++ b/thirdparty/linux/include/ortools/util/vector_or_function.h @@ -0,0 +1,96 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OR_TOOLS_UTIL_VECTOR_OR_FUNCTION_H_ +#define OR_TOOLS_UTIL_VECTOR_OR_FUNCTION_H_ + +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" + +namespace operations_research { + +// Template to abstract the access to STL functions or vector values. +template +class VectorOrFunction { + public: + explicit VectorOrFunction(Evaluator evaluator) + : evaluator_(std::move(evaluator)) {} + void Reset(Evaluator evaluator) { evaluator_ = std::move(evaluator); } + ScalarType operator()(int i) const { return evaluator_(i); } + + private: + Evaluator evaluator_; +}; + +// Specialization for vectors. +template +class VectorOrFunction> { + public: + explicit VectorOrFunction(std::vector values) + : values_(std::move(values)) {} + void Reset(std::vector values) { values_ = std::move(values); } + ScalarType operator()(int i) const { return values_[i]; } + + private: + std::vector values_; +}; + +// Template to abstract the access to STL functions or vector-base matrix +// values. +template +class MatrixOrFunction { + public: + explicit MatrixOrFunction(Evaluator evaluator) + : evaluator_(std::move(evaluator)) {} + void Reset(Evaluator evaluator) { evaluator_ = std::move(evaluator); } + ScalarType operator()(int i, int j) const { return evaluator_(i, j); } + bool Check() const { return true; } + + private: + Evaluator evaluator_; +}; + +// Specialization for vector-based matrices. +template +class MatrixOrFunction>, + square> { + public: + explicit MatrixOrFunction(std::vector> matrix) + : matrix_(std::move(matrix)) {} + void Reset(std::vector> matrix) { + matrix_ = std::move(matrix); + } + ScalarType operator()(int i, int j) const { return matrix_[i][j]; } + // Returns true if the matrix is square or rectangular. + // Intended to be used in a CHECK. + bool Check() const { + if (matrix_.empty()) return true; + const int size = square ? matrix_.size() : matrix_[0].size(); + const char* msg = + square ? "Matrix must be square." : "Matrix must be rectangular."; + for (const std::vector& row : matrix_) { + CHECK_EQ(size, row.size()) << msg; + } + return true; + } + + private: + std::vector> matrix_; +}; + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_VECTOR_OR_FUNCTION_H_ diff --git a/thirdparty/linux/include/ortools/util/xml_helper.h b/thirdparty/linux/include/ortools/util/xml_helper.h new file mode 100644 index 0000000..c887928 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/xml_helper.h @@ -0,0 +1,62 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_UTIL_XML_HELPER_H_ +#define OR_TOOLS_UTIL_XML_HELPER_H_ + +#include +#include +#include +#include "ortools/base/macros.h" + +namespace operations_research { + +// Lightweight XML writer optimized for CPViz output. As it supports only +// the features required by CPViz, it should not be used to generate +// general-purpose XML data. +class XmlHelper { + public: + XmlHelper(); + + // Starts a new XML document. + void StartDocument(); + + // Starts a new element. + void StartElement(const std::string& name); + + // Adds a key-value pair to the current element. + void AddAttribute(const std::string& key, int value); + + // Adds a key-value pair to the current element. + void AddAttribute(const std::string& key, const std::string& value); + + // Ends the current element and goes back to the previous element. + void EndElement(); + + // Ends the document. + void EndDocument(); + + // Returns the XML content written so far. + const std::string& GetContent() const; + + private: + typedef std::pair EscapePair; + std::string content_; + std::stack tags_; + bool direction_down_; + + DISALLOW_COPY_AND_ASSIGN(XmlHelper); +}; +} // namespace operations_research +#endif // OR_TOOLS_UTIL_XML_HELPER_H_ diff --git a/thirdparty/linux/include/ortools/util/zvector.h b/thirdparty/linux/include/ortools/util/zvector.h new file mode 100644 index 0000000..3a3ac89 --- /dev/null +++ b/thirdparty/linux/include/ortools/util/zvector.h @@ -0,0 +1,171 @@ +// Copyright 2010-2014 Google +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifndef OR_TOOLS_UTIL_ZVECTOR_H_ +#define OR_TOOLS_UTIL_ZVECTOR_H_ + +#if defined(__APPLE__) && defined(__GNUC__) +#include +#elif !defined(_MSC_VER) +#include +#endif +#include +#include +#include +#include +#include + +#include "ortools/base/integral_types.h" +#include "ortools/base/logging.h" +#include "ortools/base/macros.h" + +// An array class for storing arrays of integers. +// +// The range of indices is specified at the construction of the object. +// The minimum and maximum indices are inclusive. +// Think of the Pascal syntax array[min_index..max_index] of ... +// +// For example, ZVector(-100000,100000) will store 200001 +// signed integers of 32 bits each, and the possible range of indices +// will be -100000..100000. + +namespace operations_research { + +template +class ZVector { + public: + ZVector() + : base_(nullptr), min_index_(0), max_index_(-1), size_(0), storage_() {} + + ZVector(int64 min_index, int64 max_index) + : base_(nullptr), min_index_(0), max_index_(-1), size_(0), storage_() { + if (!Reserve(min_index, max_index)) { + LOG(DFATAL) << "Could not reserve memory for indices ranging from " + << min_index << " to " << max_index; + } + } + + int64 min_index() const { return min_index_; } + + int64 max_index() const { return max_index_; } + + // Returns the value stored at index. + T Value(int64 index) const { + DCHECK_LE(min_index_, index); + DCHECK_GE(max_index_, index); + DCHECK(base_ != nullptr); + return base_[index]; + } + +#if !defined(SWIG) + // Shortcut for returning the value stored at index. + T& operator[](int64 index) { + DCHECK_LE(min_index_, index); + DCHECK_GE(max_index_, index); + DCHECK(base_ != nullptr); + return base_[index]; + } + + const T operator[](int64 index) const { + DCHECK_LE(min_index_, index); + DCHECK_GE(max_index_, index); + DCHECK(base_ != nullptr); + return base_[index]; + } +#endif + + // Sets to value the content of the array at index. + void Set(int64 index, T value) { + DCHECK_LE(min_index_, index); + DCHECK_GE(max_index_, index); + DCHECK(base_ != nullptr); + base_[index] = value; + } + + // Reserves memory for new minimum and new maximum indices. + // Returns true if the memory could be reserved. + // Never shrinks the memory allocated. + bool Reserve(int64 new_min_index, int64 new_max_index) { + if (new_min_index > new_max_index) { + return false; + } + const uint64 new_size = new_max_index - new_min_index + 1; + if (base_ != nullptr) { + if (new_min_index >= min_index_ && new_max_index <= max_index_) { + min_index_ = new_min_index; + max_index_ = new_max_index; + size_ = new_size; + return true; + } else if (new_min_index > min_index_ || new_max_index < max_index_) { + return false; + } + } + T* new_storage = new T[new_size]; + if (new_storage == nullptr) { + return false; + } + + T* const new_base = new_storage - new_min_index; + if (base_ != nullptr) { + T* const destination = new_base + min_index_; + memcpy(destination, storage_.get(), size_ * sizeof(*base_)); + } + + base_ = new_base; + size_ = new_size; + min_index_ = new_min_index; + max_index_ = new_max_index; + storage_.reset(new_storage); + return true; + } + + // Sets all the elements in the array to value. + void SetAll(T value) { + DLOG_IF(WARNING, base_ == nullptr || size_ <= 0) + << "Trying to set values to uninitialized vector."; + for (int64 i = 0; i < size_; ++i) { + base_[min_index_ + i] = value; + } + } + + private: + // Pointer to the element indexed by zero in the array. + T* base_; + + // Minimum index for the array. + int64 min_index_; + + // Maximum index for the array. + int64 max_index_; + + // The number of elements in the array. + int64 size_; + + // Storage memory for the array. + std::unique_ptr storage_; +}; + +// Shorthands for all the types of ZVector's. +typedef ZVector Int8ZVector; +typedef ZVector Int16ZVector; +typedef ZVector Int32ZVector; +typedef ZVector Int64ZVector; +typedef ZVector UInt8ZVector; +typedef ZVector UInt16ZVector; +typedef ZVector UInt32ZVector; +typedef ZVector UInt64ZVector; + +} // namespace operations_research + +#endif // OR_TOOLS_UTIL_ZVECTOR_H_ diff --git a/thirdparty/linux/lib/x64/libClp.so b/thirdparty/linux/lib/x64/libClp.so new file mode 120000 index 0000000..430b84d --- /dev/null +++ b/thirdparty/linux/lib/x64/libClp.so @@ -0,0 +1 @@ +libClp.so.1.13.9 \ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libClp.so.1 b/thirdparty/linux/lib/x64/libClp.so.1 new file mode 120000 index 0000000..430b84d --- /dev/null +++ b/thirdparty/linux/lib/x64/libClp.so.1 @@ -0,0 +1 @@ +libClp.so.1.13.9 \ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libClp.so.1.13.9 b/thirdparty/linux/lib/x64/libClp.so.1.13.9 new file mode 100755 index 0000000000000000000000000000000000000000..8a2c1a979e563a2016606933ef86edb4dcd54fa6 GIT binary patch literal 1942800 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�iT0U!lzMxC;Ta>KLx)Y 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 z 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 z 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
    p#50A)Gu7wh(KNxM0WVO7HIuihN3azIe=jJ(# za4Iter=U%Zm)E-AD4!PA$(QXDbuL1u_yhUf)Qmc*+__2YVd!|1z)fbqYy*r1{ADkH z$(+BD{B4r4uBP_h-%hzNYZaKLRRfK|F?@W3)BFrgL(Q+g1iq8P7no|4FQ z_zrqMIrREG`LHkzD-VqAG1DAapt6HZ*6Qz<212hQ}kx7`&zCl6h1-!YB<6? zG3s;9O@~oDPXAIk7A0b@(!Z+!Qvd!vCx5CkC<6XO8=KmV2u#t}Q|_O04PcH>viV~( zkkxXyTXF{ry#~R3x^4GB`OWAYgvQ$F;De0FX>F+v0m9ZR8G zaw#PW^?)Cjz+uPh{h+?Cr-Eyl+vZn44wh&9>Qp zidNbCWeN9l+2?p2q|-55qIPoan<8wSR_iVa$0y-^3;g?{bCV3?dB3*jul+=JL!szn zzxnmN@UJ50&(^MfTg}>80}A$@2Zo!|*hhqt(P_Svro_FGc|W%ouFd(m_4D&HKev%g z9QKm!@lMXqjmLQUy_Ox4htD2`WYoHClB{BEj z@`r$hx&Bo_f4-O)^{oQurk@HvXXE!b8oximM<=B36F!TWpRYBwr(!SnCP7AjfJ^WN zr}+w44sTRgD^89@UB~Xl?{N`+k5q)Qw_kDm9#_k$nuq51_*roS2 zo~`qLhFBfoS;GBRLH2Y2VXjiJ(CF5(cUVoUv%|yt_rP!@8y2}QqCc8csMUidE_(~5 z*sqiQz^>c;`<4Z~f#^;aFRoxx;kP%%zm-RtQCfKK;;~5391fV%6j$DVcNN}yP2ACb z^0nFH^vq&q`oDZtwQlyWMBnAtF;)A-qw5{do(*ef$K{@=b8@vPC*4OY=s_>7y~5b* z2s*E-G&!p1p)aG&ZgE*hyx9+^RUqmplVR>J2KyDaviTaG67i>`*7Ks=BM_FwIP?BE zk{qGduD^zmzxs;IkAU=mPhX;=)69n@<+A(oxX9DajR#Y!)8g=pV)eL^C!8BUX?G3? z??je4H!ARi)AAa>32*4l=E9@siHT0_42j47s{_R$`Q<8ow1mdoGG`Cu1crmAM~tH zuttMC_fCNeVo%us47Uc*F?6{Mm!BsvtthC|u~c|^L*mhbWWKfWi{cj}lD4P;$ylFe z{&tBL5`!g3p|4snOSJ;N-mk~wJ6L=sykd(FZr}d?B)wY=AYwun=&d^KYuJt#tnG48 zJC;b{6%0%u?dP>d*dK5&w>_G{^IG@5R+^@I6lxbNtXbc1^}%{ZLTkgs*`YNd=m{VQ-Hdu3ja%wYbW4pv;BCb;pX;D$BFUKtkLu&&sRq1>QJD5C>3vpA(d zR_K(>%oi^C_c0!9(-g`yA&Umca~Obw0Av;K#Qfg3b$4d3V!a9awO6v6jo6B_+23s{ zu9`b)z3b*bMr)aGA!(|)E1dUvw6}p|M@BE5+=2>TA*gWDdrZT{lUlES#zIxpIFLZ5 zLNP!|IUXJ-X$e*@4~4}6{qD>FpL11k>E=60#F6NF1(2$1*wwQsJsDfpd%bz=@!spw(tWN=w^1&) zE_t@dOX018U*oiyJ)?zXpvllI08VAA0i#{>$RB$)3~J)E0|6pQKO&$ zilpv)Pw8&W9btzb<~I4dyEH}OoJ|YRRHyXMZboPw#E7o-ECZ@*){De@#zyb~jR(jZ zpV+;?TJtH0sX`a44NtY|YlcwX+zJ~pr==8}6K8a4yztKi((ZDY*S6VnX(S%|bK@{x zm`t73-q7J#H~)fM?r!F}A4Mso&5jgmS_>0sJXlaUy%8lzWp2%{N?sMhV~2k}EeO`8 z&uq+-mqSPf{WjxFNf3XqPWFk@8J#VT=RX-z6nMI{&_}IvjbSM zl#hFLtU&jbg3Rt3EeZR-2!9~sZa`N@tOYs~!7%?{)-akuwC-O#ujD%a@=f8bZT|R2 zgIgDHON1_a7#~0~%Gp0t?z=iH-~$#5G0Vv5+jY6OdQ_bH$$YD6hr6rz2Kvc^EB zVt?ko@{I?^DfkUiZd$)mA}6u`SR8kM;L|jnJN3GwUi)uDx%EZ`8FMPZj>a=}gy68c zba2!*XOr;Pk$yd&^23yy)|;w9q4zq{QsAiU-n;LnRZ69Yb458Y+V zOtx%f_cEkozD!1$^jx*Yqu!6ukdgk0`)EUDK!^IaW_n;2D!dN52d+Zrf)53WEY6hJc*D&-x+l4ald*ue;QNNnSZNg#6&_Z?1 z9dL5V%yn#By9@|iN4GIKwTV=e))r=+=5On{M7V#of?s*;DW||s!LRhJ*L}yX!=jjJ zkoE~YMy{8oOy3Ge@of_!_Z-D9h|c$g-y6^TwQ*d=)Bo`}esdqK*y}i6^jF(arKb?H zs1OQ%VSg+M7XW_Qqf(6RG$@Il8Mq{VuH=FI6^au)<NO%4x5O`I~EQ%%F(dbm| z_B(K^=AWdplT@9ktO|t%R#HIk%?;k05#IhIw<)N*J)crJn>0b)w}-E4K2f&Ulk56@ z^^w4GOC!da#!%g3aH=OKOte!N_E#y=9?-a8$z*~b`KfA z0z`KDA0YCj(vOrE3vd+FGpBhNHF(!d8Fffw$-zNy24b`o|seb!)_jXS4quF*u$*qY}}L zB#-k%*dyhzFv@{&Po1H;I{*;b`7h+c&Ft!IIm>K=xJ&$*BQap&@@a65%rh-w#0z>sq}|V zt$VLwtuyB$n#mo2_Z%s6H~bcfTK8MU)k`DCgEU6yL>{rBlqFru1|Gmg$$`PL;*InN z!Nta79SNs;dmOKLgdz?h@|~NWHa$F}2&Rqn*FS5N79kf(D-TvEtmr8!!C%eiv%Tr5 zEfS-CbqBZE>&34S;G6rVrHzL`N1KM=Bl4YP(9j}gg2^Gd{%Vdnb0j|p{e72|_4iQ{ zz5A<%&|h>Z)?a0N`Wq}=BmG0b$i4Mfu7U~ok4aw2{tFDQ#t-)>omPT=P!h7%)f(U$ zEHR|%JPzZS%ls?gIkdWJ#B_j&2_3dj2Jhd{_kH!K&-)|7_w9k+A0}oB_?9{k7R;@Q zW``lf^v=r-*499*E&j91gJm##B&B+pnddxi0thW3) zNC}TmVlDI!c~ZFhK*)t6ye#owlkVC5)g*!HGIqr0<+4YD&FkR3%_aXb@yD)B_3Y>K za)*eEW`EE8sHR*O%BDq~VnB(*GP&^!ir+CKh0jL1t1Rh_3PKa^$NFlAw5Uwe>)HSS zdg3j>%I@EL9}jJf7u8abl<(Ue7+=5j4LyS?_8$yWBmH|N>Ts{h|A`4b&@bf89{9mQ zWOveP$Xt#MvlTgHgGdA2j;@FN&zT+s$5;`>309Y%6+WqUyBXKb%>9Og3JB3i^oau~ z(DhOmHtqYT0ZHAg%9l}r4UAUTD_!e!q#@_eAipi67T523s_V(W(k9z*_}8AlD_q)l zpR%nyH~Eox1u3^%N5VWVJ&VPCTs^0d$OHLJh*+t)!FkP_t!*YsMg7mBgG^>ZJGG|G zB8^bezw!5Ck2nGl0rP7MdeZIp3dbIA6;f!?`w>b)i8xF!hKy5({mEdV#@57yu@xNU zEFlFZ9pf6}bo>FyGiMNSQJkylks*4SUGFtd8F}dm=~|w+{`4HaHYDzZ*?9a8ZexQ< zdADo&#l4e$gbuP~oxU9<6Eq z!kocnyM?GU2z~$>6Ub)jh>e^pv(lN@%p2&bQr?_}r1OSL|Dw7!os>^A=o z&;z$%a*--pN*$5zjLm{9Gfj9A;X|0VOSQ5R3WzCvZY{ihz>(ao7p zS?h;+c@kT4;ln$+!*VlME0XSHk++|ifGBE?#Uis%aPlt#qOY^4CrtfI{CC8}K8vRn_4HM_p&C-XDI<=Q3 z}$_<9M;p0lCHz%2cPTg|NYK>-ygP0%CyVFF`*4F&Ac;23q$5RMbo^44?Ge_ ze(&TsAsl4B5)Wl67oxYQ*$nX3AkkrD#Ig**hVKa+^XYd!Yh;QhWTLLEdtf1WJ9TcisorJG{l3sh)@;} z-!;212ws2^)rN{GwUD7J@X!4ND@*J(Cljom$RqK}KgSXGQ|ZNpwV7k?Q1y6sMpg%d zT$XitEu3Fq@i%m|$#KKZdJNAowkT}nA@d*3A(&c3XyWlEXSVh;_&;Qss?9uLydUpM zSj!wx`yLy@+*ZRE+rP{-2-^1OLV7|)rPhAwqYr~~(A2~q!fBRMEN2tmSrFTF?OSRl z>V)Xf)sPHUr^d6%Twq^6;@6Kl1va;jKLEdd1%j(_l@Kk%~BUR&2jO@z~X#TW{(xbFtnKq~@Hn>)fZ}?sM)t?pD;J z)65k7VXvhJJ=%y?+@?Ai=)M;@QR%Lt;%N;~w_3USztk#{UR-9o>a^J#N0S;aGMkz5 z2XZ*#WStt;*4Lzuy{sTUfv&_SCfrvI^Zdi^30@D*Wc$$iAX7Eu-9HT|d*@7*O4ofe zJef(}qF4xs!Fr$SGp z6&%XqedRNyClvS>1T7h+1|uWq8eC&7IlG<)!+LD?PY#L=R57S)uGo=5v3&OrR9=jy zb%EUv)`g@jE5GBdS=Wp#XuQsO>?&*eXYQsjO{4ii>#}FCT8DI#e*CeWj}7594bTIK z^+3=XM84~LVL7=U-XoFUi%)j;qn#hhU9uUIV?LM0cn2*cLl<82`F;{tT;Y zVDI8hR{RoCK6hPE{9Iw-0Uf=WVen1nTb&t|jJ@DAA4kH1pAq|v6Jvn)yd`Qv=H^+t z#Fi&BH!2m+pS%|@Ugk7QuD1;b+jypv^344uJo;cPN1?FUAmYT)&9euRc&ou-cN~Jd zLdWUVW+D!e%M=A?OpWtkaboU%T#|)}xv4@W29Ow_#6S`Qm57jtC{aYBNQprt29c;5 zoR}LQ%(e;CA+4-n7Al296_SPRxxitCOBKm_DUqzFS0^(?%Qk_s4JG)TE|bq`f%D+l zL367IaVeTxUBo3aw>rXQ;N0qgTn5ao9>Aq=Zgrva;NZCf-dPlmoBX%k6}A?P?*IkZ z{V7Nl;H@VwQ~ulNS!z4^gsDK9OBGwlOtla)x*?wNn2jq{he3JaRluG@DR# zrHZi*_Ogl|Jp(*Ov@Ysd%tCw_n!}g<_rw>m3W7ht00?!2A!XQ!ibOB;)}f&O+Pb!uZN3s{iaKqxD|c*4IMd+hty{OHJl-s z?SXd7q(D?#G8u33?~wFI^H?~qE9kn#_)kogHBw4-H3$4?7yE#cd) z`6Fug2!@o5?dFIWLE9sQj&~%6>00l2MW(J?4c9BthTCI_NwBj>k;yD5S*P^+a7MaZG3u&-z3(UV^faFrS> z0&QL^JQ!>-+GL0nr(W!TTEisSU5pJiQU}WdH8)<$cZ9!Z1!~;}L*H8Oi(qeU;rhm* z!d?gLz32B}?}^COYFBy}`s;6$mrZXXiQ-!EZN=lY+@LXY|5b|XFF^7a86u}*>zaNj z*rvQAld+c?kB}Bn;RLK#-BLNIWbCD;H&Whlc_YIcdI01II5J3)#0WVvCYrrLIxp#0 z0)4FP-@P!tOv+f?%Z2ejXR6709?V1!E4C=dU+3^XdnPx#juStX{Ur6)xf`-SR{b4( zm7V~+spX~FC%NSpBS8C$eqvwqyMC&s5eo&hX*{$~cZP@E>3ZG2RV*6Q;5yT&t@9Vy zTN(sHbpYoMe;|eZZ->PugvB1iud8Rar9H3JgWf^xf2qz6NV(|n7@ zo#R-%v0&*$s1@?+dq`s1g~W_Wa-_lRI}A5YN&W#4=x=b+U7oDmVpEA?9KjWJ=IF%2 zWDK3(nxs=raBuD}pT1v`&DXP~M-&K(1+0qo)F4c&NLCUUY_-(_dX4n|OW+_?mK@0T zZlPXMV**t&WMrR_;osWEbLza~gd_0(JRAl35jnT}Tw|z46xG@4?&S^LTrlRZN%b+)KgP!NT2&lnb>2 znTZB;VkGo)Hga^sVhv~?iov}9k~Dfae2IJ`dv8q*oWS79xuuiycI&)LX)zR;GY{%2 zH<@WfVHp=WX~p|Xxi4u0kNaw>?Jq@yyQ{725*42CI}OFl$u9y3_O;a&(!a|03IBG~ z^@NNux{rn)XfcVPOKpj<`?XZ%l12)F25TD+Hwq(9erhH*J3vehRILA-f41A` zO)9;yu<3atk16+JpvyA(hCjj#4G^2ULa-vXo>-bfZ8zYPgZ{pxdCbULf3y4ZJi8re z^vu~>x2xAY(A;DyG#zR)#o)%2DN`c*hO81oJSHyCeIffKH~b$mX}UfI*5CUISbrp+ z^J6BIuGWlWcsl%l`!Q{xn{k0it5+jxRD2uqULf~Klf%l=^_l=%mM1y$x$l2~lbve$ zoN6(qfZ2(ra%%Z-wgqEU)K{o;ao;+}_tc5Y@yM=6fJ@ius%XuRRFPh1uJmikk@>g$ zG~ewy-k)j|Z=L@ff+p}PnQ#|c5c8)oJc`?jG$PyT*uylIORVV1cqg3I0sn|w_tMSM^=J%ykonM#g zG}{7+DSkoxLaA!Bu2*uF4kFK1+2-Dq)+C)%QuGp_us>$1p}>n$ZC$4kZYs6n19oyd znUf({DcFXi3hD^UN=&Z(*lb=j4#}7^lcVFEEp?f3+HWPz>WVsN>in z7o1gm-S8BSzjbaqry{2~t(tS>_?p$dK5|Jl^$ouI0J2>RfO-UR^Atp<0@}*70**SD zmeX9%$c#TIm<@$HYrSgB2nF6*+ueF-U8layhb_3c`t}fe-ckTQynPTD)YINLy!4j% z1ffB)a=W2HY4R%$@J6Qoh7JrW7AM%k`LVlGE;;~Ob*K+! zK;zAD$yZlQKUN)@&UroN&PQJ+utFRNKE>UysRsoN0-qYQC3`Y}R#&ahDQ|+zc%0Km ze|gDv>js@xSrLCLrx&t+fmSCu%ByXAq&71JafONSAu)qfZEr^E3b%Cu?v0p1IK0+7 zL)2Jr4kp;3RF~Trim3lQ%Rl^p_A)iC#CVLjbqHSTEJIzU{qX9FYb)OwL3lj`wsWu< z1Z$>138(9xQw%!5$+Yc^_%~7&qSsLuT|DzaCT(fo^*1jM(%!R^l^-VCKIE`X^ebXC zW^b~2yE%{n)%ukCyv%eDs(G<@=~!?iS>rMJ^)B6BECPHWEveq_aojc#ogwuQ7N1rk zRj+FL^Vc#bjbgENns-O#O3ophcv?_anY z1C_a7`nlZq`7HdB&Xyl2By(o36`H!+6JijNsQ3cSyZ)$L`D8i^v%-(^lymT=9>JqH zSRc2?Ngac81qa}iPJczHOWpgq|6VLm{El15`Npe;kPrL+a2-Au>Tb=sqtLAkcXqh7q&jbm7e zZ<+pzwdKs>tRnvg?az~S?c-aN%v{Boq4PPL0)ShZq5}!b%f;Y(^%+d^1UTOdwm}?+ zzX4Z``qHStOU(DC|IX@oFwp}l=KKq=IrFukKl^o^XLRE4>IVbe^$V?2fEoCPkY;}+ zwP)wstOPXxKVANeWr-Xl0%LbBqmRM)h#iX52=F?_M#F0$BXx`|3-cA>b$ECk8D6Wx zYcjmnhu2Brb#i!}5?+gS?X`kJ!KKA~FPMYZM+>~KdSfE)D0ehLx1@h2XjzY=KjHOq z;j}VCTdYbp;5cJ;`iYw`?Tj)W)2oZ7aTCg%f%N()W!R(RG|SGAnOa8qwv(1Yu* zU?bWrE3hJ&`L0rdBD|BhjPc@5zJCzk-z~bJ#3nX?u&6VRcA{dyCn)aD5PpKA);WVQ z5oMIyVX;>AJAd(Q!XQ|@g`?Uw=|J%jI`3ku&iptGW5RQ*rDs!^nN{6yh|ld99SlYK zx>5`U@6ouw6B1wcLP)@?)s^NUvB)|KB(#yZKO`>yTadVu#uy~Nr$j$U2wy)AID8H` zY|=t*Ux<=r@c6S5|3G-`VwYV%yeMM;^YlNN zzOLe>`-vd8}_rnhvWo2>hML)19^`@jU3W`h`CEYnYga_w+o-;BJkJl)I zwF;XhiOj^1lCEgmIZ)nGH|pk<*fJ5BkQ8!65*;gNF-Q(zor42xuL|u%AKy83TV*He zr0VdTx|K;zOm~;J?L4aOts~-vE8^)_2FEM8>=-=#v&qcC`#8afG9ALB9(dG$Oz=212aoc9Fg#9O zu?IZr`@v(Yf@BVP=Q_w(8VR9rgaX9r) zQX(1K9{3Msu3&v>jXS9=L3pxx?bMmf+&)W}SZBzsI=8gR&4nQ99JT((T#tWGLZQ7m zMqp)spA}XKq)kcZoYu5rdROSOLMUTgR@&l7@6BC$-Ffg601eL-Qsc~XMG5mr!}tD(rvH396{G4>*4BS(vkeEQ#9$PTiK2c+U~8Dl2so zN4S#I0YnAa`?eEN=I?Fqvmdd&uW=mUN9o^dwg=)P!{hI6|2ueEew6lLv;RotuL77K zrT&2mH22`dL38VIewtV`w;t!GiIKVW5iSGg*5mv%alqVqoS!BZ&aKD!>Cn08h5F!{ z@okCBMX2`BWG=1icf4nyZ%KFunYf!?T9$AptWS7nz0UP@u0B_v>jthHxFY;cKy`A~ zyIkMpx}7U(sy#e85cxXcNUx!^Jr>TJD;oV>H`R%`@_#~Wiz(}uEVh=|8 zW6^s`|2rPX{l0p>8Z@o6Jblea)&Dl-;D7@7^d1GUvCvY5YZt{whQrjHg0Eq(3cim8 z4$}Wl)s}-kdhnWl`rm8HKAL=WbYl)4Wx%6H0sOy%$Gtgt{PZ6Sk89av&<`GE!iyYz z1V28i{`aaJJWv3i-lG8i-@)U#oWk?Ty(&CEHvG7$Z4Y=<^n=Go)&E|Zg9i%W(|Z)a z|2ug6U*^sPKFadi|CwZfpuu-igQ7;oHnyQfN+ejOqRo&AnUM)#jS_3DX~%_IwNgnG zH;7IGyuKa8rAlkJTf2B~?`>^st!vE!Nx-TsvbfZO>x|K|s4R-||Nfr$olFwoUcGJo z{PAPvU7q(@&U2pgoO7PD6lV?y4nN=l!9NWiKWy6%9)tA1__TaH{qLL%JWv3il~n-0 z1elEi_*pLYQvl0P;2;X%|G)IV&f|mhzg2_uzt>fKJo>WgiVVCez@MxF_#eZcNAVRh z3Yz~k_LEj<1U-_Swu zhzx?q$JPH{o`DAn;AvR}@IMBR>oW%ga}Rhx@K2*Jk3PB|JO=51uluEd6vUjFjPe()Hi|Glo^M*)0YRspQ^x+SzVq;pslWWV`p%cJe*QT6 z%g?y_TBBJ0C+VX{Bj$f(_$5B3e);f^slSeY%=x+fW6sYy_5Wk)e~sCl!L>en{DbKY zGxA6HpQ-j_i5CC#wIwaFG7DHmm=Q#EJPoYm^(s#;LA|IWrnUj{l~RjaV=&)a}0! zqggW36KHWmG+DcJZ*RVlZ)Hy%Kcsc#HCXGv;csoTyPDpV|9H%~pp?vOc9m1?gzck4 zPSMS+Yv*;4H48J+kX_W=`-cJfYh<4ueOx=gGNBl6m+me#X$)nf_FrOndE&`zA8F6> z%jgLYpxJT|97Xb8MQ+9+MggOelfS1bVnG}Ru#m^8XvuoAIvZlK$Lr)H7MQQ6DU*~`-G<@oI7B+k*tZs4Pe?6ZhnaHn0c zlpH|RUDxej>egG?kiDGUjX1j3l@fEE@K3KWh-1IhXd)Yp)NgO8!Sj$^epkqzd|$}^GK;~qt^9(fu{Oe6 zJvIL#FGKtjAqSg&=lUVCDd_NrN#a}E)4KLz>+Ft;t#jJv<6B!Rw@v(g5x8@W&>e65 z9v)Lge~834@=>9GgI#`WG=6gH&TAIY+FcrHZ>!r6$NvY!hYD|@RyN>_8PB6ovkJNE zGm@;mYrpk5F1tRpcJP}18}ldoihiE==^=M`{su8rq^#e?RZf8&whv+bI;`KHx$D<1 zTBJZP75)4JL$ze+_~0xY{675~9Q=MHW7`@6+ReM5?0HgIfe%fHc~z54bSDgc0ukrz z@lN@1fZJc^6dc97QRh&olxOFJor0s0u|`o-*zu1d#*vAt6(X(|?rZ+k)_O($x(NS} z8-68c3FwWXANEeqr8xc^v|^G{UenHke1hj;=byTFHWAjx&goUo7p;~fc`9H8 z2uOzGPkuB`D8pUqQU?g=FG=l0M`{YlR|PMnh_h%n-#A6fQs-qV3proZ7bRq&G5*6; z=MZ<3YN#O=e>e5JOeNEklm93RV2a0_ia_P5#rKi@OrOPjV_vS`C?1(kMLrqEzL=AE zP{F-FyuOfp2VNAdL#$hN=X%|C@=1r)SfU_kEr(J|G`_s|Fjro}akfR}qH%w7u)Qgh zo+%W3QssNCmTOJ<^?l{nVXR~x6)g>}Y1*bRt1W+_0y=x_)88>EPY6;(gnWFbooIzZ zzhU_>#%c-hm3bjg$I+ooo|I#MU_RRVO2qjNLD**bdyf>xs6Q-E9P(y$20I%kgzS~j z?5a($)30SP6H3TVJjl<1LSFKTTiaw!F0H_u0Y~M?vBK7 zAdj$LvA=MRT2+%Q9!gzyQ%=Y}waSh?MwrLRq=u~jV@@Q`UlMkXuWEfh5+85b7tp>4 zaW@}E;xE#7P)KX`RK&YQP^kOhVH5iu5)rF)tp1QZQzaOZ!U1nKQ}cSxCn+ zUz!5$yLlCT??tt!>vQQ6$}P>n!=-N7-bEv)HhB`JK|V)UJolox8fyF8>+53RF2IcW56j+8*f!RHCBKV9`iLb+Yiw z1q2lYmCkKld(AD;gxoye-)pu0o4P?LyR(NtHL28}j>HddZHsjKH@a|}TtdWzCN>d& zNmoU&R9yYTs!QZ(U2BJ+!;V zT6hs(g+;{R9vhLS3X8zb4FAy+wYT?vsgIscix>I8#4j04B#s*q2H2Ox2PVrm z;z${z1tm@Qs9(K5io_L# zLr`%;uL*YGq(ZU2t2*>;{)}YF7+v^FvS7UiGJ8g{;EN2j0f+buz=}##P&lqn3t5%^ zKWL__f}5^C!CLZfz%pz$y8xHAUXfV11Bp+IFw#G|W2h$e?4dW5l_yM{5{5sj}?^F=U2 z&?~N>Gj+phcsP|jpieCQseKn-AVP18?$?(vA63EZhiasd2yX6&P0e7MJr~$QhN#KE zF#-<*1xhD)<}P6oCYG?s>So9)bYlPYJMTLgx_W>GDZ1Lhf(-RvkOj|#oUts(O~6?2 z)oLtww$dK^g9ESrKAP&T{%dZ}F4oIgtb%6xcc_6usJ66H@M>W1iouKHoUClK>_(!h z-4(`mDE$M0>v+wIi`vf$&r8E&QZQ(&qxY>A<3%3t@g|lKEKDak z>>HIS9p5RNwcmTK;K6!2BGL^lr0QfbOTXj~%q=thM?H!$i{ap_QF|>@!gMe%OlIIv zZw@tgdNvbo=o|jVuTP7YpYBx#V&F&Hj$d@~F6{D|%tIO8p^X*#R22z}cnMM!8S03D zcDw2evnZ)D5VnVtzcvFl!~AJ=x(p$hkiqW^GGIMs;CVAh5w_o`BC1k+7ugk!kgA2n zN;;2~RLM$$^_~{cbTAfTay(PkrVbTvLpuCJh)@S+O|3Arg)Tiy$ImBVL~Y4lr|5T@ zq+QUwNPLG@D1;vgsm>7o1rLRTW=)+>x3zTRo7Kp)a_& zAXxxg5qYA3%0Sa9JbPP}eI|yaW4)%FlG~&4cL9@@1q}flQ^#SZqScwNc30Wo*bCy_ zssck*HEFH&g~}Bk)|5zhi|Q+~fQSp51(9%f11!<+TQ=*RI^P%*Oa!X3HUUeJN>5-s zRl)b69gQc!c!;8#B9ZtSL+;DkG)`%;5L4%3tq7i_ZxDMZ#1@zfiv}QeJBmY^|FQYe zDv%~I{Vt>^6W^gP-rK9w|Rb|hI9;KsX zoL;LC1ua709K~x1S5d~WP1l^!&5izrle2wV&;Dnt?4pJ2Lk%(eMf?hLkVN4Ew?y*h z&Tc+ErwPtuOK!~G6t>qIx)QOUj^tejKbZE1ov+v^LC%61oP1N)Pw1imj7rwBa?$pGeiFS7~e!xOJm)ySnj@T=a zytCjB59!X;;Lt=|?$R+@NKQ5~Ru@jY(PX*wRztmko~F)7F9a&1dbpWe!($ZDouZq; z8RR7K|13hdV>SyoXt7}#zHk~GOhFKJ=v`4b-x{KlwO&c<8cVl-jmpCH;n1RpJ0|c# zSzGU`>KD=+DwMNg@a-|@2n0K;c26cK7ZSR2qCg2f6%Sc{Kh>)pDNjiyyEUF>JxW2O4yd0yw1&Y!1nT@~EyuM3 z@}bv0()3W-&i-{=^C`?O!IXO*MEWQWKn_~MP4|P@LNVg3t@WD0fmF=i1xXrpnVKGBkFemu{ z1ZabyUKEWtna;p>2@m)0M+-X5Og~Ec_2Y~E`msHhH;sM-bD9o|#kaWK_*JOO*RK~F zg{Fk_g!uMce>3|M3}+uk-f|cW5VKu1=DF#~S_#?0$dY~-*^eHxHB75>$~=e$~% z-$Xqhi9f}>_rj>s#G`_$#n7GPdBJ-F7$9YIB-bUA$2j+clg;Tx+ zZTauCc4~qzH7(^Nsw!Z$P6k=Js*J47zTJ=R8Vov#x56O!-v0Q*eET`6D*s((paXEH zybpJt2s>Z!aL3@g%NLfT7-Uxjcd|IL0veGrsA8zZ!Ej_kR{s(ap6rO_oyGio+00KC zO>+CskB21-7BWFMEHKznzKDEW@l)JxWYA+!7Y>FV#IE$#)8O{A_%Wb;7eAD&ID;R5 zg~YaNOuxcMQamU%OcHLetFzu$o>5gHoYA>MnC^w3^2odv7ipOr(eIdO_^sdjEMEciZ`+ho`9mVsvG57Pb_ikvnv(IW? zFpqUjZm$@62Dr$2vYI$PtM$9|$QeW8nCnqpqp(}69SQhMaVCGtM>qD>#K%5L?z~6+ zBx{*>EGRtknscq3SbQ6cq}m>P-;{*^H$Fk5=`YT2MS)6t^1TWFpUwN? zUc0;U3zG{g?Qo%=?TB}W6V1*a9JAoI%mV6M8g>e+TG!71yLv-iLkg%X5=Wj5jM!7h zWpeEM9B4gQ_Iw#6m41eu@-M@)8&0kxzdGqZr6%4sBR;leMm*etI{jO_-3}5+=&_tC zd&*vJ7fSMuJ%*qh4*EIbI+f)LQ`7Aa9<|`NeO>YB8JT^2&|qoIbTmS}BD3kDpieXFpY$JV=jYCn#=d#1x9CKtYgmukrR7fvzdVKD>-tcuxw{ zDdNI%yk`|uHt*1~o#wEkY+vu=yjCgm8l5fpWcovApd*VTaknc0qb9^d0U)Ydo*_3~)Wx4;*x(M+6THsc`R&wkl_kf0a3a>!;5r&e~YW{o2ev9_HY{nbpW?z4K$`nU6U? zZU!I#^z&^>gTQ%{? zzlp{#`;Ambdkx)rpHbHPd+E>$C{XuRU*HWVTC?}rBp)5uVJ%G1QfOyYPKDK4MBR37 z*kP|MT@Am+KGZnZY_T2ay?Yuj;ZUr%hUj~FzsYADgoV94C-LeqI+km-&Vu3$=+c1h zhy?a^g}949SL1FstVK77hpKV8qW?{ao=!_%T4%3(MCqv&%eLrHuG+7KU zUJCs%Cuf=Wx}Qx;nS1CP?vv0%D%5^LrjS{U{Q~3>Os~6}juO1kJ^WFY7i;S7)Mrk^ z5@A{+whj$C^3t&h8ivG6R;2xn+{muy5-;T;V^^<9>=|m^@)~dLRf+d}-8tH8td>{# zn|Lp`yTb3@n|M<1<#ksm+A8m**iO9X@2)6t@7J6AAt)lh`U<9DIdHGaF78Jx0Ntt3EqD>0frSb;XcdmsptB7(GZ^ zAY_fH*cRM)^|r8Y1Jto`EcRH~qo{%8Ilkbk8;(hIu?MaVZug$fKZI}`-F{^x#A&vV z-k}6)RWQi1o$1RozeYYxpUf$r^ z>^qOJ$sWz>x1V|b&&FYQsF<^vh@IDY9=l(Wy;FCkad_ajfvSMzfc?~s=cs_H&X8rl zDN|?A=dpV)IB=D3eqD#x*LhCBFX|3f(**xa&%v{bp>vbE$Xsqs-GDRAfcDhi)GolJ zPtr?jWwuk%-yR2hI`^3<-9rW%wy^GhE%qiO$wYwFNmZMmL&!)Ci?*WYn7pt3RxCx;tZEW2)|D>pl^pdk! zlZ~r6O4GWH#Nnwq`$+ijLLD=6FBf-`NO4=!YjCj-39#yBw0ni=Cc)bJdeMWK+y|*z zdOv-_coJL`qkPsWIAZ10VcghlG)mukQRrzzi2`uUoiuF7JcQlQO)F#i>8#w#r|7idD?w#k!9%6nwgbmKZ|z=tg!zn_+T#T{9SBqg?<7dW52g? z0aia5U1=xPZjYi6@~U0hzrI-9e1ra2BX5Ft@@6N<6|5>K&nN!Xo zEvkw{13%eBYgWtO=!r~Lh*N!fg!t#Ig6HQSZ`LavEa*Zw zHrO8Qq$3hs3RW$6t@(y|n3CKk07oii)4Ds2C=gzc98~D7dm&KYf8lQsM zS7|#ejG6TvnOR4}Sc<(@Egbf^bysl~(2gp~U_v{lOwA!rXbcC>Z(Q&vdUj-4+ft*i zVZ~sL*6mm7PUQ90l_BOVV72^K;{o@xK=^QB(ErH1igGiuy;sc0Or9zxyiu zQ)RODB!e~ag;tL6Wi<~~uw%Y{arLlO?FdErTbAh4_v3Tt;$y2L!D`?guCZC(40M~<{>h-1) zsHz_>WcvX7-1WamzXKFFCA%K(GDKPm_e}V1x(4q2y=-OrG2WkjmJiXKqZ4yR26s7I z8iRVHF+l$v7;(rW5hX|j>MATh5pRG>ztk}`ie1jUyC*Itzie*i6Gckv>UY* z&$*EKM-=tCPQQP2T9+UAEqhz=Be z=n;oi>}=)%t5?*b4pm2CL5H^Z5H=(oZxb)6nws0@e?^@)^lUPREYxSJiNvpOch`ee z&!>GA52&YY!K$}A^`GdKfk$;?)77GFtLZIkZmj`Ifk_^jfs5Ke;bSbCWJy)7_SryT z#$rAo)Hd%^$Q>Qp9M}fypVjgj#b{7d70?scv_uO(7VK&IeO6z^P|n-0N$A($_P!t} z0<#=H2TVC?%2Yg{x&F;WFR#{FyDYbyCik^mtsjvjyMQw-72DPeoYHq#R{hf~f17 zseofFjhBkdJf&V3tB=Xs@se`)99OA3tn|pccUj5kNb=GKRI&l`+rIOYvYe)GqHqW& z{RHqL#qn8l=wIEp_I+#L*~md9lg`oK$T>#fjwMN;o~o#$Hq^R8&vcm0iFJdRV%mrC zPA`Bzki1^Z7RL59j~^%_>2PT#WViJ$d&mgubv!pF#p&s~G6H&7SKvZU`pddvR&&zh zxk?onl8Wiv*3_9(HJHDpjzY@q+rP9UnjJE$NUx13Ax8Wu?dB}nr@{9^F{DbKE)0fT zz{SZ<@<`g@YUHje3!UffT}uAk`WI6qaN?Ik(h3%y;L?2vPE*9Wl6rf*dd2X#_2xE? zffRUkKF{Z>^B(FXZEs7P)w0;sSXc-F)GO3XPq~GL%+EI5h^%!b+t-)F$*EZJO$pfk zKheBTqzieJ#zt^B0w$Fwh9n*_ulW0SI-INmU-TlmIaYpe#mC`c?ZKw7t^Tdy2|&s z&wB*Q^cY@1360*}^>+b9B)_bS-1z1)#vh3mh5Oe zJQC04!1@Kdnl;e1oGibPpY$J- zp~`(EQsrFD%YJI2>M`_Q@-MPG+xq-a#7+;>%r@xr<<9=ZNzcG*q7-}$+KqTic!*Nwa#Uj zB%v4V`w1K#KZdP)`WdFU?D_O|ev|{R!N~G4t}0T$D5vt|#O7;Ee)9;a&XmQI5ziK6 zkO}5M`GHd^2I~`pa6oG&#wjiRz$6)VB`03MZ3NcNem(VBo`g*L!zj5f?Q~3eyk1k{ zyEnh6QQ*Up=nlk!isSdSDSCph0Vl{j+Qp-4?@ClGwE=}i`1tBw_&8&H>7OWssjL^Wy5>~{8s)%j&8P?~v+oaO_Ir#k)wEI}+D z@>^9K%!48xtmQ^Vqp{%1rVZLDq;N(HYAunHL7GsO^`9Xepir2V-3I@22wr)KJ?y%- zEf4vYvs|mX)HP0Cqd{z`H#hwil}o9*qdq`Y@;w>LDR3}cj>IE-&DCDXvRlmlafT*) z&_W5@7tOI+7aVYjsE4p7C*zTeC`DP37<;vr0BWGR&sVD%q9l(k^dSNgw`yMNiBs zSm*h!@Ngea3^`B{zj?yPuGVdFI;9;N%AhOl3l4PltY;Yq(wDrY&At| zh+a9cnTO3&lYFvYOF!pn%zjm6`!%-2Jl&PL^Gj3@37b9(T2JQl|3duheGFR9ayeQ& z%OJphcD$ZV^x?GoKLhqjc!LaJ<>D*AKEyLV#)c^a*kAGFz<|B{3*^iE83ZtW1@oQW zqpS0Dr9ax|w0=o&*O%px#dhPH_kz91!3C_=a>K?)?E6bZXUld<%=s}_MgU!h`4&m6 zJMy#pl@iz@va<1?YTPN1UM1F}pbI5F!0e>7$NFA-$Oki1JL106%ziwgVv?0}?I}&= zl#3wFmSRs*JMwn-<;c(IcUha98(;f;rS>oa8ZA)PG2_nTOeEbJ#(gJ$=0 z_r3R_R=PdlzK1+r5F)2)pG>mr;9N*ARjHE5;7p;KAEMk^w`I=0{xgF~atkq2`1Z&gpG#xGG} z?|+;9!Aw_}IV%YHa4Bvv=-kIvRDtbq6b_w+qY(NJ;3(K%!X%}PC>!D?a$+jUBv#Ml z{CqC#9KsBZ))a*8$mXzf2Jx38ukf4Vm-x$P5PvyB{N*#Y@w<&*;x9*tzf5Rh$T`2n zUykgJ1y?uSpPtO}q=l%xCtb;9>Ti%2QQ|p$oXgBqFDshW-!*42=Q598=XAA{H0xK) z%be6L=ZSh?)Wio{_&}8KI`d2py2*)~%(H!|OL&%{A0GRHZd>bzhJX2i zj(2!8KFhx>@*d61@-L0vqd8e({SEVIc2Re?QidlfcAdsE^Wcika_f~yHXjlq^EFYo9@a6Zgp=s|L)2;=9W|B?#f18c2!~+ zXy=(DeCU9?Q$Bh2S@yfsjCZFwn>)pA;7E-=d*bP`ya#L198~8e!zUf!9R9Uq&^^C} z?Zj+4#7@1>zO<2!_~u8;RvNQMn6?)64r!|VyFtQM^jI|;?6c-T=8`$wH}?2>An_{r zB##$tf@1M2CAv%5IFand=g}N?&(jiwds)hCnRpWK8mMiVV4ybTma-h{ftq>F*)Z`3 zh8h$Q&M=P?9@ny0i(`rlHSNN~N;ShgL-1SN~iGZKzV zLH2>fO~Q*9ZL9dZFo~Jv;6qr0{`=Od4E~t?3--a})0pnz)Yr408P51V%>E8Y| z-P^yWd;8aPWS6zdQPyDYzhplD_lf~leA1^HUiA-qLu zoU2Qt&K2WpoJ%IvI9H5rg1M;W_a#`# z7R8g-9FLg{K$55ZV78T$`fm}Qfwaq`TiK;<{GBrO>wqErE^4q+&Xen(hSP=>AD6Zk zYMq7LU>fw{f#9?`_ET2P+&TEY`t7-M9v2k~Ny~(=Dlgh_a9X2viwu=mnm=hvRL=1& zuADchRp!g95=$=C(EBHkkM;V2KJ#4~&h+Om^ydlsv*xM=rof1N6p_n$D08;e*1``! zFgy_-2nWxaLoOw&X4;%87*czh2;T$#;8PeGTQyH{pPor;M!#3r&G&fAk4sq#ALILw z*Oft|%x944BlswzFYMoLE8q2XsJ>r^E;~?%0{#0l2SRK*^f*P$iC}s)R~~YIAlV({ z9vSs4LHdw7qI?ST#V^?JrWT5uL7UxAWtUaHA0=H)pGni9+&NWqtOw4Xcd)f!SI&V{ zFFq?nr$>EMIz40L$E4GSI!A)rJ&NtpY1F85>IpGLA$$bFtYNYnI)JUUX8FJO412HI79!pf^ zu|!o3Ob7H?n|f7FWfH5K{Zzo=!#ORpFQ0?4&76Kayn^hyn-vPE#;z)&o(-}KJ(Lg8 zvO#9&aCUi&(IY(l=Y480V=b6}f+-?%!cm#?Q{>czw*OX1!&2vM!%A`f^-*WR>?+?Y z#;KreExw4o#2Pyr{c!l?y;G9mLu8y5_b)>8%yGv=tfpogopUF_eEel>c@VLe8q1tK zUt5Uq8Kx|zp{DpX4}@r{_aQ#e1w1}S_2z@7r_ls9P2Nw2v|6v%YTZwKWMk6`KO6%+ zF|A)fVwOfHBhxjO%uF459Pg47cYISD#tKXeN>E4dk~;bTLfymY#ZkH#p>A?qO#i;r zFQqF-$0VWd%REyclrlsLN{2R!FLJg}RKK_j~UVLS05r z{S)ue92|K(rQCPTqml2n7{32Fe$>JSPkY_h0y*Om`%_;xrMc>Bt4}JZ+`qZ;`!{zi zkJP}4CFr$&0UhoAqa*6Qon`!Ily|UvAbQio%Mo<7s6H3{vgYPL|Gd(_MR$x z8=8A!o@M!w-UZ!@gCMw!T>sz+z<^1Z4L)N&0l51yT zep8ZfrbjBq#uIx__s;op&H6@(siVxBPaS5?J3Fk_GOmIv?DnSTIdsBaV__T3CFYeM zW-VE0x)r!{nT#8{kr4S8;Y_(a(w%754ga{z0PJC%=Tpv`ugVI&r{e^B;i)%cm1f5J z?b&92Xg0^s$IhSI_$KBoOu0>t=1x_XnqL;zXl_QC8)sNdiw)larU+3C1GgBuIasLx z4O%U0sG&QNnL;N0TluNRDt=9D^t|%65pHnRbF}YdO!vtfEXdE7Yfu4S2_-=jEMhDBQ3VR zmBAC$BTXP*SWAXuGr_&_vimaDp*$aQ^QYy4rnq-j%Ws&sq~BP8YEGvn%kRtBAZ)hO zSFi1w_=nM8x3y?G<)iJd=ZVICm7er#jNZ&dL3wB!Q%D@cMf(JDv z#sWMj6C-cn0c+vQ0+1JJ$=fpfbs+W1p(1oU%&1vB-Kn=B+Jw27WNfA1>Q`0BjfRqe zhqYvhFa$qn${afp+gJgi^#m)25u=vBZYFNKb(}RbT8_E2zs~9m^R5*0HV_5fPg-aG z9-oeth8W)h9n$w$i(Zu)JH94lcNn|XP?Bt=7zAQgT~Z#6ci|~6qZCbu0qGOI((D&l8`UT7{?)p<7ZAf6Lr%<%!5w>O5}Y#6aeG85Em8 z73I+(E}iKBmXI$fl#A|DRJi!4$;GmrH;pMlvNWoAH5-?5=37$&- zjXCh-1y)rlBes^vMn>*_?BYN9CEQZ`YkBH?@3HFq4kEDB5jbTgtFfK7=~d-yUY|G_ z>g6K8Tc6!c&;+|at$aY3$vq2c_YYWU;_WqFAz$Dk@-`eY?$t;=7tfuRi42K^F9VAGny_zl(F} zTU_Jk7FC*~x9Kg}c-L8bst?n}K(`O~T=T9Eh8m-N$fD?}nTqr;nLP&U)+e9r(IQj* z^acg1lM!s#phwm1{1k8CmP@JZ*!hF&7d)3fjyf54yr zDVuf0pTLxquJ{v}0@@T-2zRFJ*46Gvu)FE!80V{oS)SVFC6n#h#Ur6?xMaL48}DA1>blgu9r>#9Ws+xaw;Gcxs?*549DckNxe}6A5RfQ z$O(=zyYu;5&>c>G<3lVVp!ShvA*8XebP4U-0@80l7HtC z0w!`5;iM%JY>y;E0ghxvE^lwk?{Mwi5+9DT7Al^irn!Cd5}44X~8L+SBAhwZ0d-wr!PTx@o@IHQvatw7rKU=)Io;uJy*XG3ciiN zo!2;hU&c(4g|Xvyk!c}z4W`rl+j&38Gbza7=7no+wrc3 z$#e8dyg5&tx#6{(b7l|V&@qpeFHS_HbEZ9OyfgK(0c^O>t}f@~*zV$eiSTe)P5iYC zpBOWqZ6BnH^AN6rZ?d{4S&J;#von%of1!>bIz{a_Q+sno)8YS+q_%PGS^ZSf>PxA8 z0TJ|R4U&ZG%ty{cKjjx-AC(CL=jqLHVGr11$I;Q6lC9EzBG z!qNy-X%8naJR*0&`e=N4_J|<^k>F|<9@e5DBr(I!N#y>j4^r)dM6}ukODM4%4tT5g zwU(Xxd8&lcnc6X`fE8AAs$J0Z>ai9sXU1rxm7!(W61Of<9SWvi$Z>I^a(2vqgQ0UE zno1oev@kM9UtPpihdgzw9!UTtvO!Qh0mBH>>l43#fv}oA>DnVCan7B2ag|lN+^CN9 zDIOP-mf zk@(X_!9jVyxtgRYz=aJ)5^oaw6#PkauuzhgV#3^A#e>B;qUA=(7P&XZ?xCApmPCdU=!aL zPM(n)w%2ChSI0N8t9QGgw9Ykg6jq9(FTf$xKx>%VD8)6UY%iQmSrxYDNn0Jobs?e_ zn|4Rzt8guVL91UL^*sTA0u$7UE^DEJC8+M1Rby7i;;W*R3i(!-warLQKCB9kF%Owo zbJZ5{J>C16rRq%6ZdK5jXC{*>IprwrP<2mT)nKm@^vj7JTE7BeisA)an_d?d=(b3= zazO03YFJl7>K0->v^V{V%^%Swg9GVZhUQn$HE%-F-vXG#FTtq~6{gK_Tx>}{DR!+d zLXOHq_9ysVJFko`N zhf77$kBc8<8)$zeH}%fm-DV$1zfD}skiAwQ#2j)}`Z&6q+Q50ZyYFT8Gj=f<`A;41 ze7oFPBGO3xBR?zzsk_nJh?-RA>ld`1C2g0t6;zMbL+(rUOV|b!Bv+ue8K_I+KH`;| z>HXGuzYX5+Z2fk-iZhDOb005i)-V71smttJ)ID$Ov>v!qywT#j^w(-x3O4!hXPDZs z6W2=ur@@?xFSV;1oT+o@JF_2{Dz>OP->&9VXQ41a&jNbJpTJa+%4+@urjFJXe*#lW z7aPr-?n|wf6KN%!yu6>DCo?}NZwBe-FMWTvC+|&?-|r-=#V4^$iJW&+P4et~q(QrT0@tnVjQdx!HuX+PFegxD%wfGl;wd%KYf zaM0Jjm5Rg5VCxyP|6r=2y2T&4x+_%O+CBZND{`x=aV{*GN1bk6uQV1DT12eWFHB)f z0!-VlTWXslqWItg+NB@WULls%BoHP*nuJ^tLU-(`Q)o_HoG_*W^~xO`#IFTs8uMG$ zS}mjUrA2!+*Hbu1$uPwIAfgW<2Dy%5j8(XOw917ldG;`B$>7*`{#P7Rj1O~=_(v`V zAf!QUr*IQa6JJH#8>x40NQw2MFH`Z>_JuC8TFBm0j@d<;xo z+J^M%_hhrTxbnnD#h1+baFJ!v2Xvln2Q}n=_+Y^P^O5U=-&E;xcZZemfbh+7FZq{YWT&8rXm`|=a zAKGm$k>^)6{V+@JXm0( zakm5od3Co5It9)JYCm<#=CktDq3h-KsX0sOiV0-4f2DWv^n%dYoe=JK3+r?5FWr#qN3wcGrYaaOqLlLA{o- zUz>{k+7#@sr((Z01^er%*so2&{(36*Yg4elo{Ih26zs33V!t*8`|GLLuT8=JdMfs7 zYp`D{FiK^C6L#sq?fz5StIz7GKauuOX=e1|pGbR?v-u<;)gmhHkwbb9;nQ8Zn%O_o zub7;OON~vRvtW|zym2}PN2m-d+`IAaUBtcnw0k$xy(@C>jD^&Y)KK@%^CaBOxT$5H zTk;Ka_lRcMeekUNKrECVj5sgd%@a>wa~{T+6$gm#l(EwqW$d)hWe-9Y!Bh*0!kJo* zW{e0_-XN}VoA(BBse9)Q;(Yhc8^jFv&KpF?z4Hb!!M*baaiY2FH;5wlL1qv`Qh7WG zJMr;Os~B5!VUzgLZ-w{k2{x`puY!JgW`z8D!pwn=vTbwDWVI+RTR1OX&WTgYXSEIB zrtp#Ei$k|&2pl@C8pMmQQInx>XL2Dm*gyf}vj3GsIw2!qj5>gT@$vY+gVMJ@GDPUx zxACF=Kgt*G`5e0ERlq;y{IQuI2@_vdj-v-PCrVN2kxRUJGQz~w96oPNt$(XO^M9nj zzbrvzF8lvcD_cCEvQ=nkC73vuX9bD38jDe%%htZ$l+F0x|JalzS>L7ey!C;jVgq|$ z6`Hcj2J8;m?{utHr5&&`A4@~)fmTmst| z0lagwAl1kJrT2$cx7E_kA%g($IKP8=TWiU8sQ``@B{Z&g(f+A6y84YD2CzMIz8cc_ z&H1W;;GVAv2=4i+fZ(353JC7`s(|30uL=n6`D%#qKc##dtFt1@{~|X$bLxPx=TOx@ zEH`9ihRqggbAxv{vbgIx8hk27kgD{LjA$N)UUHr*+3%l_;^X6pE2q7l+08lHtwCCW z>u{wN?3ebJR<8J8r4=_I4z4>oA{i{LK=%($FL!(#ec|Pk-!H73m* zUW`%!4i-l17ye8qk=yiv%t7_R9VN{=-{kR9JvMfs+$__L%vqoXSLoma<*SOB3U)iy zd`gAaR%5?R*pZQD zUWeD@{XoGZW4O|9uCg9DCcL=5WGi+n#BChc!-I94nU#ft!+Az z?64B`V2n;kH$}k!x=6q1YsB}QAhrw_?|gHbx>>hNH3Z%I&FzCR&Lgz(vM0CYYd6|0 z1bq-_oqN&laPY#CpL1DvNj`rIFTr4U2p|GQ8dRz+{WQDTy}34|xod#R$-Y2%>;>{2?iG+9#j;Agv^%kCNNDll8u`(*)=BJrtTmNqoC99) zvT%Y9#Rx6np7|#_^Mj2pxKJnZQ8nOt8G;veW;Kvwv?g!HJe@-;#AzUxZVh+)>pU)D z(0-D;l3|HgEvw}Ov|1{;Ovwy1PF@ucvs(2$JLD(8TMfB*SUTUR!CI(>u{7@g^~&xsFPWloyR4f&1QUShdsmInU=I*RBln1x#y7cUy_khE&w=F@5?Wu9una)S8~tr#o3BUZ37qpZ0lu zsvXd$qrE5o;VY(MmiceW+FXw&r=kXg~~`sxYl}9|}-B(eqI|tP2z+m$?OT z_1swOeT9LPYEjfr2qmiL_=x_`&AF~S)O-Sa%U#VtPhAw2JOLm|H>FQC zxKLs85?(lg@Tc=d=$4CK-v`~LIgwLey4k2QE5Mic!IwKlzmg-5EW^*$df@pP@!}uU z_?`>xdub`FZ`=+mv6q(Aw@yvUX~QU|PPS`i-lItEa+T}07KQ)_ZEVu4ykL3-w(PNP zIu2q6$W~pYR1Ae^AD|O$F`HaQi$y!F2YiXmyAwURi+v()>67~GdZ`yeN97Q@1)BE0 zPTVx!?L=E&Cpx`OD8MqEcvhWwo=$WMJ$73+U29Mo!;DX<`OWG{4Nd1P4wr0oDXn?# zQQExlV&Xj0nV$kG_8r#Rh&!*vw?6sr)N_W88XpAM9zO9lmp1Wxt;K(J95nU(_K;QG z<~pNw1o>7Z(E5f$s7wEQ7vuzaZnGlqY!(?1rb;I*n{|UXPJy``qIR;ofvKyRATi>wy@b{yS}rGs6Q95y9~Q45pi5+cNt(k)_p{ zs~JI^N$AU!?$vwU2fm^%UOkGwu*mA(6+HT{ENH8imh#>8Ev?UJrZeOzH?+7gyT*#O z#)MI&Po_75ouQqE8$&<1PrM{FK8+U%a2WTVwQvnrY8{*V()M&`-}8sKO8;87AS3}a zkB9uI9P7dN92bG%=?Jx%x9&=*VWqIMGY@80e-2DZpGXm)`#%3;PF;K2QSTha+NvE= zXnx77)1o>LK>hGE)`#s{7lxM08XK<}JXPH84kY3tn8SDl>RQP*)|6Jqed4Typ&SE> z5u*m532dqNKF)BudkL`&{Q-{+7u+GvB0A>p6l8Xdb=psvXzXZ%yPDXy10zCLm$@s+ ze5ab}WT!f*{tZ}3;@iBHbp3kJrjPA}tAwiwgeStC%mQobOIGu3ctnovKU(|>EQxjV zqoOpe5AZjVx6~y&xgOcc)k-&O+GX>&hnF%_qcwmR$%OQOBQ1G!V98aY12?1m1=hdtAK7!Wz7lF%VT2a;3Zk+XQ8Jacz{azLX#NJ3u^+}Tfmo-R=Pv()^Y zwQw_d$eqC)906U1??I5gQ{Qpq2`qKod4YS+m7!7aJML=MA`Wok2_2{WFx?GLcfSkw z0e44wgdH%@=>qOG5NqM*&Biva(^~jLu6m2yr*0^9JzY!Z%vS3c<~+%rsYjLc($oDZ ztUp6xPgk1<-VyxXj&O{M44k#RbQS9-(%rEQ@JG7aSr+>q zGIpomqsMN(62hGJC_))Y=wzXh)0Fby*Em6u^uw&YxPOVl+)%1Hk~eFf^#DuIO7v8O zf-4v2F4#s3mUEX5&5%#UD=(Ft9dqte z=XZ9%&nx?;Tn7&27b&?S<~-=m*A+8kl4+G~Z8I+>#k6@50#c%M)ZP%))iMeEH7Ii_ z^dPsI@QBl_nbsqi7!z~8$KIAOQRWkf#FFtmew)OHa*0`u?Z-l0Y|a=Ekj-96@7D`V zv?_wpDOEhF&k#Y8guyC`W(43% zMTe8&A^BnZx!%uSEO`$)EWZ;{iGK$pcJ0g=fwx+P?d{0R#EouxCK6vol}}>7%<>P} zXDjSDhybUCHXsnot1an~1O7N=3P#TN+&vQ3J*(&XMN<0tfFz6$h(B?K*oHv(NrZA7 z@=vWVNeS;WohGH8*2L3#M%p&T+3@g1PJFB7+_=eVsfEmn!x=K_J0uR-DQOZS7nt~s zlydSi1=^K&8%dVCcNF%2HzFkL^{gFALf>p)<@{E^j9;ux;Ib7tZr|#a32mK~xSvKe z1`2GV@)-dxRUnCvpo0tphu0(vNbr4^);VnoQY9T~lj!AE%NdZZ=J(9%KFVq- zp?`D<6-0fC9VFH-Yw9n-Ygp;DL(QYNWxK2l#iiY8)th)} zpw#Z6d1hf81l5JuJ)pxo80+66bLHMg$=3p+8GELBsvoz>y6Ml5O?$PHCL0WK{0l)4 zEAcBHhm`00$6Uy;$V0aD67IA5*Ji0c9-wZ)f&QY`fq!S#T)N2|q;1~z@teF7ySc(d z4W=Jl0AH)IzozfuCK`W&v6&T-PGj(5 zA{9i?C3qp|q#xu=yaLzgSq<{Y*$pv4(qi?yG&AblCK{wZ+$NfIFGoYHA*FPHy584hxFv zkdAgY!J_TWy`v3XrWK;fqU_+yew1V+WyRuzf~lq#B2Wq}cXF|Nw^|fUjHJmm@f4m! zuc~hfF`0Kkov0^h0-FWn=I=E;8!4Y_@_sAg%;Z5hMK7eRdR~{C!^t{%FDFR&YxmUT z-6c{S&HIx`F{oxA5^-kDjx2NhH(B@eWGGUbhlDplklJ_%L1NdKY1-V(h~d2%Qn=I* zJ!2Dy7zfFWPU_Adsn3k;o_0I zKS1vd<@)+%WgIuOQS-!KzYMo7f|Vgr={8`}htDzRmS%Hbs@?_0u2GMHH5oHYdjX2K z_+=r^9U}I)7p=rT_s&IR5UGmbD#14z&x_#PusH@jOwsaDls95s{ad))6)#H8_E`@M zO>Ev48r}{s6JC6n)w+a=A}+@w&IBI1l;BCFuM1EmC6V|FU7(#U9FAQjkO>2sCEw?x zY4Nd(k>=p9QIjk=4EFFajW`eS z+p20=i5?NS+;(?Y1k?|6-BnTCKa^K1z>3xvY3||JK?#5@Lnl0gID1SdyZP?zDK2vn9 zf4n!Ba**5O>QblCzk7vVz!=lNyQXr z>}~jdHb4G7fi~n6Gk5a2g^R1ir(Sp^w$Fx%_U!oIFd-X7m z;Huafl{2CC89lod_i=O)F9Xw;tc6eL8}fDqH&xmG67oDk1Q0m}EqkcGy(#m|x@VJ1 z38L|~fjy~7UUqnXZzc6bAONOwnF4@eHNB8$&l)$bf+?&*XVaZJy;x-}`V07_`2Z#c zyKC}pm82Q9J8Sa3?-GdiXx@!Nn`oXbOrnOuJXizOBw|G7Wtd{!9d5TLwn%N=VclG7 zKr@}c%>Hp#0nEAbN8bvpXYsKTucc$00En#Z7lum{w~ipJZ3y7QL9f-Q%TDGmm@0N?gLX zfUDc%r{1G$muN3vO@*JLxw_>sUmFimvdgl%zAdo|<_e`;hPj%Ix-@Xwm`loXma4{)E2*PreJD#aKz7+aru;eyq^>)MH^D*i0#k ziO!#DwcO2w(YGxC?IqLwo1SI9+$VvPKKQG2D=2fVdImS^T}r%W-SjKB9jirJ5e>>4 z4<)IibfXy*7ke{I%cs)itUcjH^B&Z#7ja`&YGmC@iI>L0;_`sr-hmUR zymT19^>6T;bZI8(+jCZ;*zN8bM##&Jyl{J+_zW)+J^sZ*)5A<Fp|mIj}+l4}773zv?p)8f^X`#Ur10?@KD zwI+rO&y%%>?fSZ~7;uWY{c# z?JkaO;{~d$T5%q)UWusATFp(j&`IGlD5u*dZVi9zQlPW$g^Sl}ggmiD%xEy_a7tnF zX4PrOKnt)~L-}`|p);;G!Hk#X%)!|&LUC>+S(nfI!q3xoN*A%bd=Rugm%sICJ*dqK zAm-)qa*fOq1THuShu1SUqa0Ol!w)gZNzEq({Rb3=s@Bhw6hNWKF^cq>2 zt(KA62jg$hzA^$ctg0Yd$HK;wmHrIJXqQtW^ygw&r8OC*p0F7*8t@)(w{DV#C))mU zo&my}G5gs_o}(SC#(p-Icegg%Se~QJE#`&f1s4n*W5WfRBzX@Pln6-wZLZ~TeNx8@ zeWZUoU_hNv`vGNMw-Nzr=7|*WaPhTUdHU*=M+h^}wW2*JJi2#mhMpM&w(5H+^LH!p zIl5plsL$Sr((K_g%pRUc;mwjv3VbfwP*fXi;i33BA~hN^yi7 zhB^7ZU>*3OH*SSe#E!0+Y98BCMJ7N&vx0i8T(8t^+kV zHAfL4zD;^Yt7WU%e8z3M_K+qmM;(i!eh`tYhf0jwVBPcqWz7@mYuYvdL5^KGV5)zc zv$&g${>nv^thh+jMd z`W7AD@h7P9r&I==x23E@8=7Y?bLKg?~k+eLxtP5eM`$#3%ZTlI`>iv zYWLs6-G>(I$wewY%}qC$VM3P?8;#b&qxcGp;mci1|}i@cAlug~ohQE1g^0qt=Df#Lz~vFf_{fgNu zlqFW>mpnpwfQvWaljt<^W5^5oyzj$x8ibk4o0d`ZApN+3S5?7{R%;^{syiL$B8yKb z1hV+_V)`93aBnfyeb@)lz=-eEmucl}6LdptmsN}NGAImmi+L`k1DC_olf{F0e1b;F z`MThDH;-L_79Ns*kzPoKXDdRG2O#Nn?ArX2^=h9l{Y&O!;OoPfkY{Qe-kLRO^To+)lXc~1D)yVr z)q21`9x~H7HR9YRsx_JA6)4)#INfVW%lO1o=mM>-qE%ELwZw1hcwz__?H5~T^YEN@ zWvSD;*WRsPK33oT+j<{#;hTL9ItPlj_5L*T9AhSD=}-BF=aD+rcBFx;DG<0i40)_` zdH!{lWqn1dPEuSIkgsVNT%Fdt@hc(-4%x6_6&eUlo_9q#-!C@Sfp9-2vweI$^QyRv zoQ=q+EVX{+Zek+N|9{NA3w%`7wa1?!69^hO6AhKt(57wdO%!d?Vr6QqnJ^&}nJ8AQ z38HWtYO%E~)dbM;h$ev?j}vHpl-}A~+uGJ!?X7+IXlpg$kpvV7_&|$F#Mg`w2|ggG zkpK6$&zWQr(BAvM?f>)7=aV`6>~qfEYp=cb+H0@9_F8qGTa=7jx2u7;ugQ#E49$IS z0TMWot-@=D_E$0;9A|G$+4$dj4dyD>0CBc|YwYSHawer&(U{Whzb1f7oN8I4;{=Vm zx8r`PjWDil_4ny~2JYIE?aw%LI^NA1?`{?-bU{?wxlEYo~kXox_im}V7)p0jZew^c#p$bT ztK6q+22(oPqrZl)FYIT?l$v-_mC5*sCJ@|vxTWsml`vjl!_IPrW*^_YiQnlG8w1l~ z;d9cQ->LAhU9pq_(vB)Db5Qdzy`XcIpb@-!Xj-hFJgZqJbHc&B5$FCi1jUdQ-5U<} zbLq5Ad9DZ8M}!X9ni8KSeiVf;uR0-<5*}&#QDEjvL51^V^P7TmrS7cA5tDnfIK^UfibmGI4_DHe4)Q zO?U8u8&dn%I|P~v#65OA!5t^iiYlE&OPt0guXnk9_(9Sj=Uy(&ZMwnFZG$fS$&iSy zc{py;I2GhY#Q=<0<&c3;V>jjNOD7}iVkAap8hkNv7;>V%)-C;`%XH2s4)AUZ*@`-q z2Qd;u8;(9rF=I5Tk@KhgyLg^FN(q_KcDeB)#lh}yegq*XqoSM9PEl*Uq6+kQp&l1e zL{q++psXdzD%G0}-kURZa|bsetiAO)x9Th1-tOLNkXo%1ax{7E8z5#8jg&!mXH$N1 z)P})HW~KdxX+de?MWKTN8u*ggYTCrA+QW@Ro#8QFI#9u~Uk&)&PMgSt*k0!N9|XFB z_(A%dO4wBad`9*u-`+evtyxaA`0h>X)aSGa$>|404BzS(nE+9|)^yi>O10fVZHE1o zS*Q9RTdS|hgf!~% z3ou?<{dLlf59JHPqpa11+)+3pci@!zCDl}uU6r6@`b!T!qpNU z_mnwV51xIKAt#>J=F!gDJnN>vVtcyWFVGN+=H!F-=&pZ4h|aX1@4d5fg=d zw;3@^7ru?|vF4G2L+7+2V1NNCZtEY!ng-9J-|60Y0>o|ZohKx;a0houP92%@H+&yN zVtn(M$zmVD@Y3UHf1t!+Q^=RP#OS6?O`b0Doc7+JkKKb`5!Z2Je8ca}n=pla@drsa zGSQ%inHI5{HjR^_XBx3>&R+tn;y~-VD!HNg3af3M5NNI<5sIzgJSz_?2igbH6$Nz_ zEsZUPv##Sn!;p)n(NSNA*^if>j&-FvYe(mowb3)7E~WT!&l$>@se8^)&P?5NhGjiU z#q}OP?m5FUD9Al$SjIWKH%FW^+|E%$R6R+*CplKqlc}}pR`I9UxP(9Ds2%-i-E3klfu9&U0wp))x)vd8gvP= zi}-z|Tqhb&;Rducb0-0%;G!ln(2v`b)gWIm| z4Wpq&HpewuHg05C0o9eWDLE$GGKx!uFWgdw!^it8Mv*W%7zmf8D+fEaGQScTBr=p3 zO=7fl|B5lCE!T~~-E5?`GlC~Q$O0qD_K2^8(Uobh^MX`$b2y=}yRjdaMNc9jac=#o zbfL_DL&UdkV2>uTP!Yf0S;0_&N$WQd$}?&G211(dJlC(GfJy5&5RzukbNwo%S2ok& z!z~7V{Z`Y7bbz6<<4A;v+~rc48@tPDEo1l|`$*>zZ{4c1BkPiM_Rl-d`P9+pIoU`( zk~~hGbrxG=h5H*1jWPa^HjWa)vRWg)tpl$>uI4Ofnb>4Sfry!(00xny_;G!}lucAB zpgev8TI*$N)hCO{Y5m!JJol?Sf@BIxVt){PoD&t4ua)YyS&pFXXk3ySy zDHee-5Wu6a((aO>1*>8F=T8`7t=4L`6uy zuD}%(my3TgOLM|Xk=El68-DuDqM`Lm(ccg>qhty?!T zT`}KKXZY;9CFw1n8$Ym3cyZ%LWyIs$Rn{I3+vYLesz=4^@8*TtoAo-A$jlTe|Jdj$ z=Y0k??^Z9bilS)GlNlW`J79jKM7%gKKHQDSxDUoCh{2E&j$ z2rU%sT(ONnYRx;WmPw2RaqK4P=nw`3S3p2Ik?%(te z*moOtL^wfU99jaftTD1jYa4|r;PvOOSQA#5_Ji>Wnoet7H}=jo3u4#$Y~x%dZ0EOD zHf}&K_^Q=v3p>s=Q_IjXeWq+`_>{CdWLcI8sA>?D=+8AApscZhTRZCkYxQDD zN!M@a;y%Ux!q8n(a56%a7H#iAt^nySCP-wRA)(1Hp^117k78Awc-j!H7E;V|FNgsk zM79t^?GYJCd!A#8_ey4wxKa6E0E@G~L<6Kqi5lVA8tVa#a2!r5rD3kI?)n{*)p$T7 z9BqYC8s-}7#_!me#MhtQE8dL4PC3Qtanz_BOEm}& z!1k}xrPs%-5E|nVGM_*~USfIZ)6C;w&lW{LAQTB;Gz?-WK8}%z4+)mnRu|i2J_`=1OO! z7H&gaH;R_8D1z2O+4|FroyTiQ?FM4|N~4J(Kag1VhMC_q!#4dVbEa_(bt{RH?m-j> z_TC1SHyB@Vr0dz|;C;sR-4i56I+Jkq)gSCn;@JLYJ;$KlP*S1BZuixiT{HHsujEm1Tdf;Xc# z4IZ(Ye#X>hkhPYC;K6VPjD@Yrw!u;SeURpk;y&YlCROlG$~W*Dopn#j-=%Hh(Oodw zQhxp~@jXV$-<=<_%6sB%k>7+q9fnV?@`mOy{~65n?)-19`a8ob@hT(+VQIg^YWgFz z>loKt5RCmx?ou>_#e2~hCLS^Zg2o#7sP|SU?- zM`&D^r`3gg3iS>7;^Z9``p0r`YOVUEY0$WHO@q9+C7q=c5qkzYOLN>yz`e+4Bbhq0 z&cy_obwkc3=21vW%X?^aV(;rZ$(6W2ZZ20Q%w;T>)NvMOIA9bbqQN%_6m$nXDXd>y^8O&MSR-_4UBz?U>n zzWvs4y#1er-jucNXSM&4t+nlhNhg@K?IQfCnze059cHX%N7HKRh4SJzv4O?hNK~}s z($s2NydU}{=w8#eNgOpmzZr?$prLCb+gz`dJ58>`5~VZ~A6$=8F7XqsmFq~vmJ>HA zVjuD17-eXF^zjq+$v^uj+-8iz{IV@i0f_L=o@DGA@F4f}tncv~~KJ(+K)cG;z z70R;LCC-JDeUR6mq51Ql>QCu)n4`3BoEPcm98WuHhAz}|B2b)mtjk18*Ux?FArgm_ zc$dVxO1wwnJtf{J@xBs=NgP(<2#F&~43HRzV#0b)A{RDgG#W;`5&yL|>{8Skuj-y1 zu*92a)^*_Yp|^yS{=_a=9*afN-K=V&c888tRJQlvF}FMHSf=9|JM+SJq$liLfT!FD zo^mgUbH!8c1$fGh;3@ZlKCYa%xd2bO5j^EyfZQFyQ|<+L%8lSDw++urqoi?l1KZws zpMcpN|FSkHQAHrktdG}wndg{Y%k@!~jbHV$P9>|Cy<&I0shuD8z)v4AE*NAtW>0PV6>pbteK-YizMtI_Q zEHTy$(Vx!4(!Q#33~$dSB6iNJedE*OZ*J@#h@W$p-cEg=Q|z4h?8hGZoacCLW_+{W zo1pi!zb<=-!zz?RwO0`iRI(mtTCLVzS$x{{vtMo8V{Xlt-ha! zVSAIkt$0`Q4l^G$O!a;AfR4>UAi>SCIiL5{zs`|aVnt||z}_5+g$C@cp+XX0?kntS zf6dR!A^Y)A`-}d@{_)mIS@F?%J1S%TqT)@Y_VWMI71npowCO{x&mm%RVPLccxV|66 zu%>Ry71r*pS6K6(AqNRz9yV%(yS2WC6#5vU?_im8WII>vg1&~a z(ZBQVmAtFGBi)OC!jpAjA0J%vbS60%Wa-Uoo?*}I2t_Y%^Q|ur{@p$9$%;GFP?AQB z*w~zOUkv3t8zQkUf;+<4q&^rG;*44ACy#!RZXTE|o#9{j&4YblV?wXN|}lr_4`{$Q-Xs zVv?mG>+GLMC%0mJq;c8Iv^p94yhT$y0U*`|3^+bF-gEXJ#y2IG>1m=G3 zMrtEww5wN>z}Z8AlykQ~tg`>+Sy|MfE1j@utWlev#{~q?^ZH1z0~sTfN#Na4D3Q!c{18g>*z6<4ZRN$gw)fJcaBT9)+CCc{Qv0wy6H6i% z-ma^O#jQ|#81Uz^3CU6M*Xqv2*!1LALz`s{OiV zv{Yy4I=ZELG#1L2vhP+sCLEiM=KFE>&Rp*>zK%*?yZx@aZx-{PG_g2YX=m8#t^<-=2VAKiWNj!v2A* z0!D`lHz*=uIev`2kc1r5Wm|`cgs;gswIY^#!WHPQ1MFg6fqwWztI&TUG7VdqJFmvJ z{#l|D9$$B&0zv1XwKhh}ewhKNA!Y}sy1W4MiE>TLY`o zLcKekV;&(tS5CNuQ1DLY6i5gS?{rLuLp~0YhFW~+cyqA{7>lkW;?ysZ{~p&t^ZLr* zeyb^uE-KdvN5x(X#llGk%^SRJv-7}^E3KjAtz`3zrYSUM)VFPDex@n^n)OA$_Rr+3 z#_XR#W)UB9)vN6TpJ?AV3HQw<+Sh(p5js(Oob%4BqO+VIMtnO5%%L18EMt1aKoo^g@vi2! z6;l$|;LJ(8TAA0gBpa|a&(%H!*8Sb_C)Z+bPPJT_fFR6>e9mf{!Md027m# zKy0p=n0B|nmo9gvMkjL(z0(!N^NRhJ7jz5;fC%cXKdAO!(?5OEdk)dFZ~d`nn#Esb zmbv7mRAPpoPAk&%;LbABH1fS!22c4)8wP;?e5DNsn3kkyeVZg{(lVIO#>MDQq?ch< zk3@sdCz${^6B7uV*&My+PNI*q<3q6CPx5j(@lOoa`l{^BUfh+@l|I?i{VVvTmc6O` zlF;$gw*DAXvq9K&oE{8nI%%V4&tlLPFcUJ-15Ca_m_eIo&tlLPFcY$Z5$IckFoQOH zrhqUUMf^>h{!BRYnps8N!hCbcYI+WmHN5i)jrvqZu$%~GKWrcuH^G&z0TJ>K{@{1= z8_L8f>*a_|#(?Nz$xk!Uu~gbSm|mG2_GCz&d@E!WE&RHgmN95r#(0{R?)n#orV^I& zOeLN6=A_V)J;)c&g_NS4@*TuXNII5^iCl8*iX1Kh&h2x_vMaK<5K%Cbi{GyBha8_h z#$$Wu$8ugV4DVCyx|jxkltk=W!}$(*)?&7BAZszk){bG;Vq25*#J_M{4eg)0eD7#v zSgYonJ(&rYzL0_tb@xA4f=e7`2R+4~ir5(PQH_y}h@Z;*9|~?*5l=kHd-!N$X4TR7 z*i{|K-F;WAvF@M9J4SodGP~cpzxq(i>_c4MZJGTpm-kv`zsKeMmf7!fIovY)Fqb1O zvyX5YXhE0_ZmfSOQHXv%99y8mQ5{s-ufcaw`@9UT9QNiR=VMfpCsn*%-Q&!D$*z9M znH{&Q@*#+lKoK`+#YOvGLKi#xCFb0~HHLTer3i>W46XTWGIq>^ao^ zT5Q${qnND5cDGb49DI&$W&gWH2%Uk9nxC69FXQ&#M~{1svyp+!`G^9@RhdQRI#QE_ z5=k%W>_n;eV#K?CsP>5W7kck4ajz*yC?t33uXB|Qj`Y`QTs*odt)1P}+QF0zxAoV# z>JEOj((GJyr!x5KTy>Y5Aa&1RO3PUNb*|Ft!TmyuSfz9Zr4+$AWBVb4AJ6ClGC*9! z7{eUTF{?I%B;^SKd3-KRxfruegPfIWLJ~zT4wHvcJe1j{mCnjF?$;lRKKERPV?voy z(*m!?VW=EBcw(DKrp`*?$zG*jXQeT5U!`AX~wprK#lcLFgUA?9l`i|HdykI)@JW zd-IlmwK4AFphWDP>6>A6u_?yDw)f-0L;Ta|rxXzB#~3B(fWeCmgNoO!HY;RoE_bmInd2Jdc7VErq)lcZtM!wxgn?d4jPDk)jTd~cH7Yv+NY(+1p(uVkj;|?LlP7^4n2aJEogK~akuxs2vZi(t- zu}*ld$cx(keEeF?bMaN>0p#KOOWv)A>(6?(9$iT{KTxIp z{+x730Uek~f48vPf3wji% z&A5_{n&V*cac)78#*%#e6JTiMdfPv`sFzGplZO@6Kv5BA3WL@}Np3e9=ypg*B@vnK zNxnI{q#KV>(iaR+l%g|g@g-hC=&xoPs7l>H-$$2qhH8inhw8Nzf{O69Uhw8qhf1q9 zrE$cg@|ciy3*RG3yWK0T+AHl@meO=#^Deb<=JHFcSifU{wKTu9coSmmnvj#z(7dCL zBTDSc*;^~qIVpzL;=mwpAqElk0_ncj?#AlIeQtuTEAbGFA^YtU{Pv#zDkJ~7Q z%hT>Y*$GOtR(Y~fl^n144yr&CeDtKC@rN?1x`BE`GZ;;BP#N4⪼J%$V?Cqqy_UFDL&5)U*`p$}g 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 es%4vIVyfb8S z%jP54x+nGEYEz!~lx+ua4B|BXg4J9?FWAD0*vrP#WegXk#1qjg3ZM!uZz?c)V5{Xt znzA-{uikM{8L2(APRIpDQ4CE3^|o2E!-*K>lskD1`VuI2{0$r}2BDa>68H1|vG{A$ z9CUK9|{2*U_M;Z@iC+0wxt{>3s z*8XNwy=MNz9CDGA3}{x`-|Sqk+2F(+a;gm(&@2V6dxLJ{s|GzTA&s^<==Z(DpZc3U z?lxOCgd~P0$O?T6bEwd%8Psq}TRAf)@w-3qu^ z3=Vbj)o#vB_?9UUNs*N%T->J zZ}c~r&ez6egM8~k!S(acKz>t`jn?8K?wdunn$J`(n~Di#B_|?zu^tIEhMTi+W+Pt5 zTJj6nzNGnrs<F@L z4}^T1n7%LAF>e*CrzM>?QX~h>6G|1Y7&zWg(QJIHBr+E;#RaBdc(UnzpzlP0Y`8Gm zp*J)nri?66Nxm~f;T(r#`)on%O1Ey4zCcdqL<+*W$J{p{WJaM$&>hyXP!6Yb_#B^3i2c)A6>ptDXrFX9MHROHDeLiN*-*rF^QKC%90TF^qk2;lIRY*n)!WD4nhUsL zA4*-$M<2bTorK8D>qn2ezGcAm{#40;>kX;b2lTfpwcx1h?+&=$pL#y?`H=5LmylYI zuMYXvr5+&Jj^M;0SN$v{d(JO;-TwJ)NX;5>-I^K>7wZ4LHTCvUzdw1@b^TG-?+kc; zRqFRgUDsz`i}Dnecle(Wf6G{tsfe+uTal%`^Sa$VYC~!fBYD>ze&E%bxJE_@;t*8y z*Z;(*R`A5Niy8a?Jvu;-4$$Ls8R$_Ne-;0g2HCYU@FN%eK*}T;dk5sX3^(n7tHo>w zTkLTrgtrKy$uDR~nfC7oOgn7PT>w7)2$-jS&0C^RM673gor{?2w#g*` z3mqKu?d;cYkZA-E7Fff|y5;86Eguenv~36Nl0Yrr-rIKY?6%aIiM*3IK;!LjXo$7& zX2vAsXAWW3WJtb0>RaFYW=GiwNPbpFS)Th5a6jBbMj4WaeuD$?p+8xv)9K`S-H41r zX5XLMPBJ3|_tcXnb=Ui;E4ViPZR8hn?wBdZ(u|so8}4QbeQpMIHzbE`lt8p6dHSvc zz56R>1nN#nyHbfj$Ry9YxNZisWqHHxtv?x2;l2aCI2Ul}`^HSu+{0V^HJ|dF1=_mQ z|MsLUkEOJIKk5vAGmO8$4Y`0VfU7_>K0e33G5460RN7_fn6pz3z6OX?$GLu@p0U_- z7C`Vb&H`i8ZZp%5W0kB0?JzW~k`3Oes8x;o-L%hkIrzm)4}`M|H1V+%Ur&p=o>h7gsB^R!arg9G;Hjpm1q6fZfK>mL6zj**xotmuL ziS8~7xYMigCN+u^KEKbz4i&Gdz07U1D`j4R&21+B+fTH7aV|~9s^v?~18HZTx;5z? z-S<2GJU0UFKK{owbb&=v)!5`oni5-f6V6LrU0o^He@TY!K4Q`*?UuRi(vWJzL!BlwGn|{m zKV$K?(zK$_$(}=ji>twxjjH9b7Z3DKOyrq+p0CBbZ<$eMCPQ!PtfOdg`X%VTe~9HzAne95}UdF|K=bB zpuP_Oc&GM@Y1%1HgwLAtbHj-q$mB%P)q;Q8M`rO3EwSrh_M%}%tr^Uy&n3vC=~F+2 zarCTGe`#j)1^WBnF{2Tm(&tYH^!Xm5hu7!-l^HD;HXY>^ccmF5?R|7FgZxWoba^H- z>Rl<&r5)EoJnu21Oa~!XuF2#_9WFn5K*|*3yJp1lCMKveUfO@{aOx*6|MB?N;ne#B zu8*X~vE|eLLG0Vc6%En&1iXKz1sr)rn(CO82a}$>8ou4wjM)cGiPf?Yt(hV|V$QSz zDpD7r--wyP`5B7d3b!YJx*C_ol$u5+1~e!5J1{_xGc6~iXy^QeruZi6FpcmdH*zWA zH_20~^)L>{6Ao)&v#-L1lbj(``QZn&bX`7c(GSct!i6)DFFos0)b3_{SE*cyW(T_C zL)A97u*ci?m2v7``y1uU-k>Rm$P%F^l%iqDJ%f3#_!wD}u7LCR;4(uxp}MX5G2v%4 z%E3!X#ku*EXnYir7n3ie-QINKp}LF6LvYGr%`Osr+iH51{wm{_#Hb*j_|jo@Ynr>= z)@}~lxc75P58F_h$0;!QAulC86e(T)0W_Xrn~!ryO{iby2V zNft#BI-_mxWedyHV2AEL7PHq8Sg8Em7?3&($aPAWQft{!->J%)qOv)rX^S<_yt=}DAOW-?d~n$0v-Vx3-- z%tXUxiT1tWI^ne+I1M|Wn#sCb#2D5aXGoIa4EkGl`U;Rujp{HYOB&c_H~Dz zsJ}bZLXTgQ2k4iqH9|p(P$L!TEX7Oxy)OSRX1QCzu=1O(= zn6Q$^fHdefSJ&%s9Aqw!fU9^Eu11f=G3Qxy4jkkIxlvSkdCVnTh_gTbNYTKD)*bog z1{$rvj4G0)yO)n~IkhTa4J*7F&zr0Hl9xk#>_i;RCI--a1cXzwe#|6vWPb#={?XJ9 z$%9X!24f2;SsME{*DR7|)CpP1*24TKiqaab({ zrcbah1{qFrabgfBwNP-A)$%(b1tX*SBT7s?dgEva1uparK;LGRz5!B<;S`5(Yf*f8 z;Mg(dPe!8%9cS*I+P`f_w&wpMHulNttTT!g1%3KvB}-h&w4G4|9>sjGhMhs6x$s74 z;?CK!FA+A2UWyKjW+rYzHKHY`F%jEv5KPlC)RWVddo2&0WK5K%jAV=V{R{;f_RfZW z{UGNFW@k1Td8wtY1T%9_(_GkOFKMQm32Mc8lt~$VK^Qx7n8YzmO69Ktxy!;f8C_XS ze0%)d_VTa-l=_V+`LI~clO-xM6T+ldpkHl-u!je;|Fg%TV=og^JU*XBrb! zVPC2Y10Txf=ads9Hem*AWYU;&C-=uz^Ee(0R^>oooa;-it0Rhuk?CbL)|K}LK~ydY zIiWzXjfyUb$(QU}S}DEJ&OE2QFxXbNuQGnEKk8KB#*ce&T@h)7mR33s%59_EdOGj3 zF5|MA&S&h9b8T)oQBMA+P;M-~EDYRpV)3ol5LsRo_f4?<->a~vHfLFnlcgvavQNb% z)7%=1FQ1smH#Gn1G*Jah6C+(x=gBS-2M{3$9=BSiz{svnj2se6T%&A{&mn>xp^Fbd zaw<;e=Uko0JAt%adZdOd7^g|{h*tSl;u!gc+UR=H)roxT>O`)2NX27(8)FIoa~zSj z@ymA=j98#{W6}>P(PbGZ{-}DW^nIuwOKJLBUF*l`5D(p~uJo1`i4gN5DEd!pC=r=M;osWU;aI60#m@jU10v`h*ZHEppDv z&^bLq=u+`0#F7WwqGOqv_*wXPgUw~(b2{YeSsKH{itW+SgKc!Ak;c%6?lIzn z9hJe2v}xnvP*ac9q@o_`UsHv%A)jelWVjp@3sMC~^9|>8SWUm6U8UU_g2h#0Q>i?# znXlPoM+jRJs3D{xh9+D}eFd&cN z)JbAY!=Pn1z?g1;F)a&3g0IZ_6|}3AUdH&g2f;e4=_7$XjwcXKq%!-!<6YKdxKg5a zI9arEt*CEH%=a4QoLIw{Z-15V&9E~p;%F@mr-<0YfLk9sy3xn^F`=Mj7*S(~gyueQ z#0-3Vul03Hhi_K-y4^m5J>*Id?nqmIg1Y5pa_muBmHAgGSTd3KSNhE|J1h}HR!{g( z6WjtZ-`<#S2aoxj(wOfpm`>ORqwo!h`g&r%Zhn!(bG*xVIP%<`!91j2QMn)7NPZlK z>4pg|Ot|GNW)_fKMWQT1E=05)87*B5898)9TjN1&ux;80t`{^h%9sXx7-FA;_V>yV zi!1snFh7jTg4J{`h+2iIubgPZb;q{C#bP4cp%=pYPg-Tu3PbFcf8L7Bd=qgcdFr3H z8cZuZNfQ6O)p4}Kk>u8Y+6p%kXvSSI=a7AnErh|49IWObSlpoq@&dw<{h_uLd#BCU z*gI&vcd9Xa3!^M_A|T7`h*2_aU~t*96&2SeEaq8=YKQ@#e^HdE%a<_CF2^XlY)zKc z-nIz0kQ3B`v4;TEkbP}#YArvc^~a-HX-TGgZZrs`$>8)eV;^iy&1Du#!}e;ErYzlF(rqAW zzuMawBWhNgHIO=Zpuaz}hp$Qa$05{}kaapS8Y34w8u{!j^^1{hY1qkoh>hUKu{@Bw zo+N@x*%G<0BKUB7nBN$Zf}Qm*r(T!EOHcLNlMq$V7`N75=nT5zbbhYA#Tgdttj$MZ z7q!=3=Ug-0t-wI_vynu_2DH6C%<#8G)iu*bcBfvlu9rNx@KdURpVIQv^~74%qkt%uWRFb8d6V*7Vg^4@(x#9z&96jw*Mq6p zmPX)bLTF1>7Mrz2zgJ>wB1;>EsDxp~>)6vvDxG_Z6a^1*t%lscL@K8EI9q@^1Ob}j zU+LPa_u@{ev|?pZ%HtMTtVF!@a$T4A+3K-Y<@kOauIC4Gl7ke$1VR&0NymjuEL z=vuVXbv0-k?@S$oRZ;RY2EiXo%!+G~e8v5a5N(4c~YsB+nBTLbdG4k_F>SsyR6-ulY#mnG88YA}krN;OM%$xfPLh4L>9Qko}J3ajd3! z^btu^^eS>JG4);|r(1njCkmU@_r%0VBUVPV>i2O&U?QJ>I)9*ngJQJFp4)0x(7*xV zBROC-(>1=R3^kPJIr+ zb4z|~9$*lSkkPjpxWi3|)wNKdHyG&-NJcy8&L}zOrOu@TH-BMex?ajh>>^aw_wJJ1 zg;%iO%lM6tILTxZ+kxaziXb!oq`-${Xjp`A%_&$Eize!zl}O`%3=h zDyRCe*ehA}Z=h+MNg7J4Y4Y(J8cV_!*AALog6Y7i2*_`@raY1NN2Zn~kI#$QhU&j4 zl(+$5A@&`}zZb8K%AAp2pg3i!vV&@_`mb)MaiF)Ft8q5P(sMqTir6K0dJnK#&szD{ zvpfK2M)Xn_R95pBc;r(uR%iJ8PQb25s{BbsUU`E89Uu_8RMJ;qnYfZ&g4sgm3e?Be z;;%A$tNAAW0(v~;m@w2!DWGyFp2-SR2qDUDMRenU_G+kD&fRa2u<=0|B}Q#9=h}4L z2UAOAir>_Ih>3Ly4FIbRd-hstMnbzNVJP}`#WhS#NLpmF zDlnebYsxmVSN<$VR+HLypJSR1hmNdQLZ z8@MrD?NSmy-MQ=#D&ZD{pgd$N++9~bp^m?iEI#bD22-uWdMeEK zLy5_Sz6g~?NO|qUS3CrumdJ@-o3%*OWqNM|Xp*aM2NUUR@Le6emstLdn^V^a+T;bs zeQrN{C2{Q#zE-YpJCu!=;T?%tSSAR~KOjQO3HrF0Z?}PO)JpZHZiE3sR)MW--L@NFj8XE%*k^n( zrZFviF-|%@!xsbWwp!!}#On-wtet?nR#(5kwST~V;w9UFg5T^X5WfD6)UVy=`cR9X zyMN#TDh;`XZjlG7cgPERDRQhq8ve{>WaBDQj9B<=`j+3{P?Qh28P}m~fmMxCB_5f9vavQ4> z{thB}PIi<2n*G&Z=ST0+D&|016<74qm>N&iU8*+Ga}^$dkA{P9SxaiX-CwE+SqoAw zB^`Y4a+jJRV=>hm;WEQ=2dvO|yYPppDPof>$5YFOvJ7XytE}eX{1rbb1rS5OKsOSz znzV-nnorqpyt201TWQwS9MNeABCohCSXs;WSlB9}aH4$D#T5}otE6tGPLBXAK$Tm@ zWQOQu7`ckzGsS38x=*bwTJw3?AmZCp*uZPjV6MhZgOuA6sn9Q!5-MnZP>f*6zA;cYIMhBNpMU`u z8NjyQ)PK{qvLjN;hdztE&jRn$xZQC-;9VPz!?iB6Qe~X}`p;*`zhV0(GLVku_A#{P zi)ss;Q|B3?!aOX-p|< zVKDFX)35vJ?jO*vt6aJT%`$WaMA_`ps|=okYSN`wTB@&LkD#DLCcXLwaQjD9JSO|0q6d%Y%42}9D)I`uTOL-aV(08$j<<#9S zhrjLoTbtU1L1oki-k+s8_X>zt>V2(T`p$*Aa~T~%+-a0rNppG82oZz;0c{TO+eL(- ze<5+6viEx<>M*l5^;G73ZULp;zBJ&Akf>C?c~L~_OuqL!yhD?pv>#B`seb&``MxiI zv-0Pg{LN8&4cU;`s!;&qFHCOwtDIlzriVz_Ozx~2Eb(^`G*8K1IRMCLeeaR7aw}_g zsb^A1j6Th`KiEw?8B0mSp)Y0;>QCsPKD$2CKfZo@#QUxFFR;9(59&BQC_VKaJoEPe z#S1t~Ua*BVBPyv#DXZ7t6{39SN_v({&t-VT|S4?yYpjAyHjl&HSoJge|)GbDj38oR%GWAx;CF^!O9C)o>1n zcXAByrBq)y&d(X6FG&7#3iJia^PjvfbqUe*T&PDg41Mn@iQE9Xp+pu0pK5^!)-Cp^T7PDq$R!QHQo1t^Qm$BnB!NcgU3s(TPUcYwCv1$86)L)u3)Bp8 zfhAG5gO_Ow+oKnRI8RXKhiKxu>DH3jECy4D$uQNh^)&CMSKxh^sbHlNcoI6Ghj|M% zYOsy^Ag>B?^}AB1@vApKQxNi8t_ATu&$$r4lob&ChVUuCjS;{EIeZOf=yV4dXAtB~ ztabkLLs|R33B*tXiP<9rS=?osG??J^ZE7`s2Z3&*2eTe})jI|N99qW(+7(7smKaSL z2X9_@ksE)y+)e_dYcjP3OI~zq7a`sm5K`v~O+}#& zmwBBbRJ5v=6pR4H=|Ir{Z;XI9Lhn=rKa2=7tftR^)n4)}!@vF=RwN*;e%1xj*E}G- z1@QFV1!=6peFg+agXb;@5R^HOTG_W)U8e7}~ z`3(9B4b`5@z#p^U(7|ngv=(3*rS^= zH(7mi>U*p>Z?@z-pcFz9Hu98*pN2GNrM4Q@RF>7m)xA0i6<}FWMF;KbAKEvGL*U7egZ;!WP9LlL;vg2oulArRQU8QQtcuTMcn%L7;n8cbD!l7 z*k|?krXDtsvs!)&z6g5fGADOO9RoZAws*ZKFC&w!=}Iv4##Ekx+nx{lY#LzlE1Wjq z8X@@YT-QskN6tc>g3zB$(2cTmZeQ+&;ch;tX( z{fN%3R!a@kNZ{R}N6zeg3a04%+*m4kZmn(({xf9I(71a7Zn_7ZGvOcXlSf4O#YKM< zwcpUZR;sU+6P(Ej|HOE{ga1ozex<$DBxS<5sp=LXZSUuyH(?x1h=htd^NLIz<#$O% z45lwY)!!j{C=L;(`}nv8kn})4St_O=@|yELoM7tPb<#Odpl$MYz_ZO-AUR8~OHo<) zp?Qu&W`56r=fYNXSKZrsk$pM@jo}rie1wPNX5BhMii#<__2&rZ%A)N&xdpth=J;7X zg08W}P(`IAX@0a8o^0NN{4G-pwHY_J9UP2HrjzT0t)FbUbFiM=%AaY7@FnE688%|h z5FJ<7*Pg=@j|i<=(M!VoSwb#ZM;aAk3C(Ym!WOMXgb3dykFhH>S5^>6>rv10az2Zl zHl3LD3;cd4)gSQr(*_zNSgaLhbXO+u-er)aSNZ)2y>%0l!ICtm(U>R*~N|p0~)XI~JoU`RiO0 z+e`iH9`$XG`J}@2R$qdN>zF7H)QB_8phDDVEMG1j-787L#RpH$=l~$X2VU)T^~R#V zrsob~ZDZKiF^*Dl9hW@aR7K1ws+BqALxUpxsotXwih*Lu3$w=wHLQiJnFz7mnu|$( z(j98+9Za5p@y@vC1n%7t>nE>*9X#E|pJ_?8e8iv#DT9jBIC6$oyR|aDR!$yZ(Xc}N zdhmP1D!W8{y(;)3Ifo5uuzed@Pao?=Q3%#D&sd)>;YX#-dL(RjX)Sx~>VWbd^`96} z(3k9 z2`WH#b83%|Hj_?jo`|iSe%J6t8j=n3&+j|0nFP6P!hEu1P06P!k&Ir({Fnb~{aYbt zQUJRfPh6yI)rq-FDU#km_iQ~SEXHirgWuj-$sC_C8wOJHnL6~09ImO3hn=h!J86#g zSIMh$M%)s!<}X(PsGg`5AvOiEnfLM+!rKa6#n&OUT&?OKdQeblCu8VcO{I{^I@Lj`Fg+&;!}$6X+y?J}$R%i1nlfGapJ z_Jj0-evp>^OL&4=>64~2ZMtx`K(%{iUT!&0<}%=T*`6mQ^*t>{im0Mn=hkwI7+1|i zL?duT{5L4v*(T61@j0}pd8bC~S0*^IZ~N2!loJeE%`Ge-zF)*}Bwi)AqA$ex!$>7Y zM1CIuCkpUkoSXnna5W`AjC=z+ZDc=A$@lb5Izb7+V4h-b?-~Y5jp41VYRMLBfzFNG zJ7DbN$VYgMy`mF%W(UUCh_O(uaEcX#nL+;WQk?dCO2VbJQG%)NSK zCyh(qHDt1fW?k08HkKi5LjeC`^04wuvaM%u^byCu5Eh!WzV$`kUvy_zdI(`Joedk= z>C(wpYR?x&j1e?S^+O>dYKMZw!}dr{LtuZ{sh*BJ5K4T>90)7pZDFdX-*=xOouCc5 zhr;&VoC6>9h)+=ldL4^TY~-fvX_+V=!q>`WZ9Umkm%T%VSBk0HE~9FD6MNu6v##kJ zAsuCGKCrp56? zikj;X`JFQKbh(A>^>AU>YWX?iX=j{S$$TkV>FypZN<{}?6$OF>2zk+k&|dAEx7Bud zGgr7E`_G`1X@xWQ`+m;~Q4Zz=Un1qDc?k$PDKJ*j)%#>GGIjBC7et-W&^k=4=6Ds0 z+IHLn2V7z7cVLuWVZPDI1 zth)!`LsRzX&jD?;ZTvyrWWVG~Z0wqS1%G?A*S1*;?>Ae&HHtmx2?GsePItd7V867c zMNVrPt`Y8*Oz)Tc&2x_9`=;89bhMJhF$RP})dY{@622(W69tqXu&`-Z8ZC+}lqx?k zmhbjK>%Ip-qSR>|;Pl7{(Y>&9J9elKtd9Zz zwC+;{(^Nj2tg>T5DesB-$j#lxXMuO^nUCDc2HZCUsiqUMV?#6Rh3H!^y?L+KjVDEDIzTN*`~ZoQK8svg*j;gq2K_52w$tT zN!r+;7ZF~KJsPjBbn%L*2Sy&TTE5FAh!u76sgXzOs0<7n4H={6y8OlR?^SzKpZqBL z0Gy6trLQwKz<`yybkRHyd3a+WdReej>GgICg55m8ak7t_ek4#x9yF{}jv7>1mTe z8oW~}ms4HRK+sEWqla;m#7{HvZG&~6QYwbA1`+$ts_6WgliE!ZOopu9nks-{GVwF- z_z9dyI&Jk7@USEG85yd;tb^8q&(lzlFa&dFs#)iWPe;OqYlPwI3(AF|+u#NMuUrv^ z!C$Ph{KbJD)Zrqk57-Db7C|M+nYO4GGuE|!*IjA6%!3p|r4#JWHK{X&5L2#E(-7=Fkmj6q=!(S;~w-#xi5Cg0|<42Px2m zmu!^VpfV~Dn_MHG3SynI$2<8{!`(u`Mt+DSt^(QaxSO!5h`laUypDjxpHW>tHX3yW zk^X(>5$_xoBVAo0m&1SHco3G)VaM0KQ|`pFsc5xk-sh#|aIU$VV(a1JEjSRKh{LJ> zyExt0-t)wd_CG(>dmb+w&g-34^Oc~hIey>#;c}9ab^W~GzUaZjJkZ9fvQ;jQ8USRA4B>D78!&*SKcDi*_x~ zP{AbOIb$MYPq7k*xEpnDyjx9o$YB@tz@i^u+rV|a@LPzQSVR&dd1xxpREd0&{b*_7 z$8mq21>#v*guSazRplETlG{KpY-Nq{h_hhR${Rk>l$|~0!A5Y zXdz>P3Ji8X`Hl$>PmFvpJ=jL*G<7rbSc!6*Jje{R)R)NfnFYE|R>tCeq2MX?TkVw< z7y66!SXqTlP_XPH<+lGqk?9_t(!;@0Ye@=^OeOkoWl^n+00;e}TipWoST4T#>PzTQFAxv8k zslZ7mJCqoGy!0HQ;3XluyZ%k8K%5IuE}8dlNIZf=zUkq%W{y5>#Nz;Ic4eb*#)Y?2 zOC+YrA(pESeYlkkQHRAO0llRDO?yt@ruOoDpUK#<-1N>&=UJL%#9m2}yNB(Uy0&zb z2Q;~^jY|nL056rW8z|%WqlAe#3|2@4W%?>Q>)mZXVsfCbOQN_4Gm!>^}Sj=W9NV zhNJ1KJyA#aZ@GD`*qSC%#3O8vYc-lbm`^azt)RypGdVmOH}pTVE78e}EA-^Hh=U*& z3Ld1OeUm?IU9*wzVJo(kHS+~usNWH3+FE<5Hrwa^iw)3(mU!54{2Np^>ZWLi`pWuB zWrsepObJtCF%sNq>ea;cJaub1@CAmy^1Y#1H}U+iufWfS1G9X2h#di*ck& zaF8{{pG1?xHWhC+isB@lhxMjXLhisTWP>d+4t6j_E=oghWwd?PNS14)Om~46IrTvl z*TW>P?nXp@%#UMHZQ;wPA4l-jBt_L$bQUz2UTX=zxU_jcO+LDNIQw3&Fz1JKDk~kf zzsa4%kG>poo_@sbsM|`EN>3KYS{Jx%5-m~Q|B>IAM&P1SJ&AnX11+gageYtiIQKTD zD1J+XXt&jL5)iGl_f=(^a~(4E$?2Txf1z7z!O!_?@~XctvwwICI4^fetPLgBqey zfx(FKGK+O+^{)#D*IS7T7%_y0xhJ@U>;s|VmnJ4A8^L89B!I}DX#52Cz4i$nE9>?^ zG|qr%te#gQLmEV*D*jrynB*Ez9zgm75e@i3-*ezhwVpFHUL1iqCdmDcusxxajWD4g z?2Nc6Y)>2MB{8Bpg5LXItf@HozgkmoUH)HN&l~aDEorkB{2PGR;$^I*wQvkKL-xj0 zj8DzK3H{v+WZ2YLbK_sV&$kU4|8pGur|)BtR+b3Ae}tnM^5;=_nmV87`td((pOIR` zyzQ>kAoJ1n1HQ@t6e1F^ms@(f{`Stq04^^WJ>rHCIpb?M9GS4)dk+~8xDrwb8<{4A zMBv*He0BZ|w&>8`yl!a0;2B$n9^?Pk;Qcm+-za=pEB`l?YO1@dz^)5g4Uyyvo(NO0 zpqF&sbz-#9IKX9D-){X71VS=@ss3|`ye!81jm8Umefl-tulnb&-$r=9b#CT2kT>)F z7;=A~z{gOV5I8W7JEvEX)J{g8&7!@S$C2t{4iQS&KcU2dzsW={z*viIzUlBcc=NYq z&QZQyl}oPYGweLy#LA-^wp#WLcAH)FB+V##WHehwsXu%OL=pjpKF<91ca2rmC~kGs zc~3fukNe*TnmNeRO|D{(xWfE|nIR`X&lw#EerP53L5{8)LTz;yKV7DUGkeK`y(0t!o@Hu9wY5j_6C2prTLt<(4ULTqD z8#0^LZ}iQF{t7qO?G6XG&AU`7JUE=)9gXh}6@NG}QG2E&m|tW1eJcH2sXGrD7zyxW z9-KFmB1L6_<3UiVOJCOV$f2hZRU5 zU=_+5!4Vc9KQkk>lXCjLJa!~c(*;43sJ5v`-J~?y>T+|2J}g6!HvLdXmX};+HQmcr zcFGaUj2-@D4lO3N72%LqQ7tS&SDt?Z@lVo6wE;d%h08_4^ViqE@1Cf2l)jm^!p)0% z?sv6n@9ApzmmU@x8}+)u+}9ogiT4|HxEIU6YtRybpiBlZn5CleqX>4*sqOe_x3>lShNUugtqNlK9&H9Dfb^imzv) zZ=ukaS?%C6@$dfxef#XF$Kvk>;V2yC=?{}6*`rZHH0JkSq;rB9E?rH9MPV$KySyzGLfhnhRkWRU_j}sS_zF&wQSseW9_;W_ZjVJpXrcw*OI^jx zZFJ~G@1+{(?wHZ-o~~~x#3D75XZp6uk}WcuX=Z7CWQ38HX5L8~o-_AvY7DK?nUFhDjbRtgnoxv^tUE)mJBCF6NV0$I+X{-1DdKUdF1`b-S@#k7W0* zns*s#91zLTiNv>riYWr(s>!~`fqXHWrb$zP|CsYD`ZDBK9@qZm;4uaLwA`|=j-j(c zu)tbwO(Ci$(+TTh?UlQ#ht@wZC~)?Iq4E|Am)O*ugF}RcP=uo0W6n zEI$Pt?3sSIV&_TDtlSG{<=8WGOu@8}y^};eqgI8ASKF&1iE{EP=9+W_%EpE^hf@YQ zIbbm;IZnWxDqS;y3~0GyMLdAn9e#YD4z+QF2x5aGl}y{L9bw-#w2}lp#Me1<7yB<9 zx7Z%HC~>tfxOVD>-~%n$R2s$DJZMlZHUFVgaOaF()D@b3RnJ`TaP^}D;a z42TaQKWzVkusS4YzAhHO{WcEdVP|%Yw-i)bFHzbnFH4zMoMcIzY7ns;FU-HL3jC`X zwI9p$6D0F}!XI2e@84hoignq@4Vfu2 zb3qeG0ZOWV^u^yL?4_fk+DxRQV!A$WLVJ_pFQteX3Zm~qL>`>={>5@c2t>(ReoU7& zZkMk=LYL&^aIe<6SKe@~?$zDyZ@<@7;|e6~?KgcT75*hx%ACDD88lz_B(MDiu{;_+ zd4O+fmb$$~$vraV`LrxgF>*6i@_Iz=SKQ#95y>Mq3*=NG6XhJ@7(O^+q!jbhF(=Tu_DgfFM8+gJ2`Lf3Kzd=)a5+Vu;F(QK^QO;fS=z27B{RE#%6ana1EA35b5XFFW2_kv5g_ z8*iia@P`z0jDxO{4|?atv(T6-wo{s-;k%J2%M*DeoEu52pfFg@V=_y~;q`*G`tv$u zxjztUjA-YjQHK>|lJY0BNytcwvc*YJzs40sl%?;7L8$l5wEebWzP!G079(ALj9kX_ z9e7xWxJoLTGzWOvc}grr?##X1jydcWPeQh?3i=i-63N&c`fd!714p*ga&@ZB&vpW6tm``_?VbR6iX+sxO@UJI z4YItEzzWBFk`a>p3Y(M1-+}Ly!M#@ELb@{Weba?6fjdPj!gdM~!G&)uSMXiz$pexn z-2H_<>x+I>I6BOmOCb4Qz}LUe$P?%$CX*nbWOW~G1y(<9E}e6#Ai(yP!shc@jI5EVquSc%{|ZIaJT z#N><2{`q_xx=VIWJ2%y&gzMCETwtTrdkaXs`+a`qWbaLt>SJGOl@vcpclBawK3^#j z6XOx5(JULG6_w1wiv~_9aSzLrD(6#_R`kQO(Nx;6h<+WE$4)Kv&%0nLx6Sjl$3B0p`+N=0kKy^o6*(CoOpmYmR{h^->}}IQLPyeOFwtaXw$ov;((*_2zwS7KAe2!hl;Xw zs4E4dO zSg}4u#Qi|T0MH0;bxacP5po?8FbRgPg+QLG!0{Vx%pN+DZ)kOvs_g z{k)3I^XnHmk9;B25X`C@hRrb4?(-p7+Snjzi)i9e+OvGIcpLqd+suw;NCO{Ah{hDb6ZCiz zY(PDpH1`ElQqA@1k;Dw z{U<|?Hz84OS244FX0;F)MZTA@-K+C-6p!Y#2_Ghq^DWTJow ziK5cRD)*Ka3IVAv5J*Be9tW`0>g^l$*0$ch+}dh=qiPaf!b{bFio93>1)U)%0Tn@! z{6F7)&SWNm_Sg3I{_{MUbIv~d?3cCIUVH7e)?SO#Ti8<#4_*Y59L${bNBJ> z6e$Y&W$e}mp`Dk09wA7$syGi1>L_>B5@I%FLr*|1=}hw4bz7kEMpOStqzb(u`<4_Y zplBHswqe_ImV*SX3obYK9l&trE zO2!MT=qC$3Ru9f_Hm&qqQ}6YK+h|hJw!5yP#e*B}f|seOa-5zf|pZpshx9n2+#j2w6v(_!X4&pYc!KdOw-Xo;mOOvqjFw8 zRY5)jeO_CH$i|w)zzp4NH8f_4E7}&V!X)YF)$Aoh_R-pRS$wL8!wuy;5vdwhGkSOi z&X}u4JR#aa5l{?cAaIszPPAd}&Y<0>sf7>Qvj}K=*JRaG-KCxiplYNsRa-HC8i$AU zVBxlLICxeq^tfNm=v-4v-u)g0=?z{&pK{svuSYxZ!rYyRqUzqJ9F^XW(uZ$F>csrL z^S%tIBSyZw@W12{p6&7`3{-r+lX!~Uslyf{_||v={sBTc;j!|saiEJZQfojcAuOPu zge!%iFU_;k5LSfFWx5&{ZcJPW&y$9r+DL?}H~}I*0ze%c$1hDy8km<9P@|3@XG6~o zLBP70+2g~iV0aMM2(gbChcr}TkJy8@YqDSmlO@y%a&DU@z=bR@WiQ-orXUnK zalZ^^t3JYCHI(ZaO)^3Y7%2>^&0w@PiVsnH5T@c?Khth74TGYP7{rgQLlg$kO;arB zoMq#28_qRU*c>c;K3MdMbx(i56Sa3T-8uOVAuhLHirDOdj+7Hjzq%RIxACPQIwNb+}-H=KzTwDX3U(qeg|gn@;df<#THa}w z1;TB*{gt^dnW2mVz*<~(8MmMq3}gW<0z*0=;g`&cG~aIn4HZtCe7Xu(Lx_T6Z%Vq zTfhpoJ{TE3$MLRnDIw>6kH2&GqhZ+_nx$V8R}4k(x%*tf(|gwPDX1F*al z@R+`ufrH0E``}x+^}nP|#n5Kr6%N+g!L)oyePBu=h+qw2N*?#tkdN)^XGBVU%=)>dirgvLT2hkV}1h>40-A^%5jbB3@`f7irs7mqa{hi*^!WFcn#IH$ZpA*&XR7S^+YIHlTbOtrbI#!N2 zL>w#0FDE9_@o3e0oZ2@)gxhd1fD?2#f+?#k%@7K)tjjV)GJ~MicU=f0 zB{ziL8euSc`&?F*MjHC(67e%MjFQ{di;(xj)*1{j%w+`P)z&Xu^&-%cGg)_7tz}!V z+YVPnA-x=Da*-2zT#v78^{lJf(D4WQmeET2^{p~YHjQj;`#c6N1{Q!mZ*!SFDJI{- z`KHnhFp9_uFZqQ)$G0=D+WH%+IFh=w=gh{!Lwl^1E5Cd-Q8N&SXl=u;i zwKpVoX>Hk^sJc;^H53l`#%u z$UbIbHWGb?D2^X~#%E|#kSOzPdFuX0Tb?SI1ML4}Im_A#IFE8=pfvVXSeUOtcrGAr z!ab@481!U3g#p@mOkngQHV3>%UKmP+b9>t^PSU?|Ntsr7mvMJDIJediQcQ1ZS%0-MlI4+4rj}#Tro4o;C)-=%b8^Hg8$5P!oR#E%DKkoF(k_%zNs*e7xHp7FHR= zZL;e2QW%O{+9V2|-X^5C9)LfiHa*Kc2O8^(>yB3c5fBF2R(FNd`nG+-p0xe7(+l6E zpWmVhRWn~G!1Sn3fKY$i()|zQaE)WqE!}Tfk+O4_@$kRG&VAzFvU7*O_4JdCK;m!O zw<~6%yBqFm-~RoMJ!$$E^oOqft*oFz7)Xch{YjmN;=L4jU-6*286Z3 zjy^ZdHFFp_dC4rEvtE2$yg&^VYTD|P`D zvA_k1`C%YINZr2!5+fao@*r_(D0Ur?_&u{A1&I+r;yNJl!(^&~gh>Sw^~qEN36lyW zW+qb&BupxhsPs~s4J1bF5+tJk5G2ZykT@bpi2on>=WhauDy;f)2jH|z%BmCA^4+YR z2y#(T_c>u^HnLMpl{B+6X#~DpHt4v9hss^f_JoBcH3B8J;fw6jwR}k^oxTt4p-7#L z*#`2NvN?N-vdF4yCBcNdMY9lpW{zSgVx~*wC^17$>Dq|BBV_MIRTH&4tj8abb-Gk! z>pNym@0c||{=-Tm8%6Z9yWCz-5kK=zi7Xd*D$GyrFfwZMx1l$WTGF$ zL0};~t%UedXYPjN3?}fUJ9~pQ&#LjTNzZD|ms+7`Yq%1Byt~!F+mkh?0Yn*Q1AC}0 zg2RQsZZDj^#KgGCZRG;NsnRC&V*>*VlDTo6!_#=YGK7x`VSoo36$@9@> z=ZfL-2`0*A;o3ufV%{N?y^PRb@WRlmCmFvdu{$*m*@t($hv`7hSHvtDBZ4n`Mg*)+ zEdhi*x9uh}N-5;bDSgDMJ1pF*I_%u}2aE~+V2^$z_HB^zL&7$g7e{NGuqZI^f<-U# z8ZSfU#m1E7Ktf)bT1wZ__>9DzddtXoaVQcKMc*eD$s%y6^0Vsla0#^DtO!zVi*&cCUl@u7(vPB3XhIZfZ)LU$=4Y<&vM2n=@4I&a^ah#u+C{FB-B4O-Jt&j-oZxt?~;|T=6s^ z=_PjR5iDA}@M&=h8al$%A4HZ@UqF=+XW_J9;cKP7wVwWez9!bf3QiDDqlXzObp;-- zL;1e2cw+v9?`zaY0&$bq7%P-ly(4Q34<1Evy8m(9H%VcNNB>+OMT!n;*EP(%h+kt~ z7%g<9i19&nU|zh)3n^wgjk=b7lODkl4Sxp{tpXLqR5DUa@5mRz1b@EcFM!b0p9H%j z90-#!(J&{kK;>c^5sze!o#mkQVACgG!UaX(J9`7XG}cS!TI!rlsGwkMo^Pz3_ak>%nax)$E8(i6 z=v2l!10E=iP3}=@4|vR7U&gqv%d58XS*G6CHfN5t2Yip%JA^9gp<{5d2`4b^F)o#w zXx#8!-2+$=F30~Vc_Lyv-5({C2^Vz$8=sJGXKB%n>dS#atc-1D&Qc6{kdEF%G^3&y z7YvrEPje5feGr8$4L?xyDpIhz1!pM)VHGwu{uM#n|5(s>GIUWj@RE#5qc8|BMg=|@ z3osJSodtf~j4JvF&_7^dM8tS?f}Vlx2Ks0^*pYdj9_%`B1F^&n6;i@Lj?+vNdWuL1fPfF80p7p@W5L$PZF^Qdn-3J$_k3GRYA z>UO}-Zn?~h5=JN}U@v{EV2`P0AXv2XwnWJHZpe2aMAXwj3i^32^z;59=$8@-lOui# zph^VreQ1;owyTlSG7^QBlX4u)if^no6WucqTJ1i~($FaMbi^Jz9aE%-+~oOY#N6ar zB*#c5Bf`g9=Lc;=3Uv@&v@tDc#--v97OfQ-P17$Kez_$BfM+DGV}oy=2_7}Pv5*yV z3LaQP45gE^*mhO)P}8~XiNR1Bk2t4`hogsT$;s(}KcfZ84 zKi++)qh8tLnhY&~$J8gj;AtMDV?Th{V0dGa(m-JnYxp!A`%V6XeEHl8exf|oaE*tq zXAy~wJV!oG@LU`#Mc8yG+)|hSFmLs@zRo!JK=@K;K9BzwHe%6OH3!FIBaiFkmi=LT znMosfGHLB5ts{OrX>L?8V_uWMpavrwse5Z+8#I)~M5hTvi)1nO&U80v8pUF)SjNGfOov!~SmF{ypeZ8l~^#Z6zNRd2_SEljINi>9e+@u^kK zJZ)8#r>$xXsVaQjS1BB;vdl%gu4(&?exBCP=J<;wFchnwp;zA!SwsTM$f4iJR5*W{<05Lq0?3%#gG2gwro*mvhMT)w@D;p}gu<*zq;8?8kQm<_j^g>Q}m8X`ma%v^#pIS){Nh&t)2I1)L_@CMSiCFwWKaKi%A^rfQCApsyy|CMp?EJ@2h$jIb zG$F@}eRYqa&}^1;>K0#u=z^?eFXHh{W-0b7!{32MH)oqjC|Zvq&RvXqua1CjI7d_J zJ7H#!{Eb=5inY+;ai-}F1S$s*sC>ju>{a$^J+0-7Vc0@8?oJhvGLZGNDkDkmd+Cjx z>Xl7$d+`mjnXQ`dd1M?`-E^MGA4V{1w9F>cE$NvMHdJ|;5cQ=peKkE3vIlc+h>}os zq%uuS&x9zV(kp3DdZsDqnUG9O@-h{WNpkOIHGE%*_ARJWUVFvL&Os|?>Ou?cJ_UtMsO zk*DBASy}&_mUUWsRyJO*F8Ew})}N+j)#74KS^6*=S(ja2^nq2c5R$mys{e-Zb(XXV zKkplwo_ADW7e0+vq;Jc@RmRd2(mWt3K-BRA&wxA@8t!w3+?`rHPqml7sSGM-tZub6 z#o)H~WJd`8->Q3AbghUG!kf8?T_ro!pcUEBbUagL+7C0{;aEcr&50CYH@8H0*2?BE z%Hoxc+08g}$znns_gPEs;|3ACjCHkw5eREfmR5M3J2;o0(76g{o70b6eV=L7|Cin~ z1u_zur@rUl{4e$1ulEY$)vf$2tmE_^;AAA$bbX)Dn^gX-iP|pZZ%zE9%X4GmDW08R zf4ii=6U?(q@`(R!mjs+(j$M+&Sz5a!+X?#Z62IfKduVk#Gu{HhbjO`FZa^A_xExf} zo->{J#BAvE>S>@v{)nPKiVq9%nL#-hU1mwTV9NR=rrfgP|A{A^d65bCA_6dW z5W%Kn;7NR72`8fQZ-5O2an^1dg|zcsyo(@Yzc=jL(y`Z>+}|GG-+S*OCvKSl?Gv^8+pUpUqT`)VdN~qv`BL<7E|jvjSapX$aRa2cbmIakZ90WAy3eOP%_m|> zr{+^pxH)J3dmeZDjW z<9+*GEr%nx6&;8;S0I~~4WPVxAv7 z>U;nH^Lt~V4d+BNubGa%LH>0@oJboGe!!lwm`ShDQ<_pflT-YnIKwo4u^oy6zbKw0 zjbC(4zbTZ4G4Jdli`!P3P;fQ@X7)twCQQYA5h!Q555iW%#~IEg%#lGFUwhUbXZAjO z);?!;+@2M8W*@X?9du^5+q2r8+3(x4-gjmnvu7Q1W}mQUogg^s+_i~!p%}&#A5o)? zd!;Qp`b=2(tcdR;ul$fBy_u;XWM8=_h?oOt@ifb6i>zYHB@KZ0tIMz98ea$3 ztId5epG{fea^}A`X?Xo5%|}s^J^z@r({tuOV=WeEJ}AYR2c-HSiT!?ZbN@+&o5X%U zxwAiDlHC1%iaCGTr1ri14~99v<@YXg{u%a!ot1Pl=MQ^@rqy%bsr4*AZ9Owc6@Okm zfs*0RhkRStHEqAs&olbj96vU-D}Nq&7Lf7Rc)r=sx2$8D|2EYNp4 zx8?T!a4gg!50(Y0he!&XT-3I0n4wRK!vu-LirNr5M52b!jm{5>^KvO20hqAU*FzxW z!@>_SgrRp*^+wi<0{|>BWBx~70~#qV>)xbb%vgH4tnT)vk2C9cE%;U>_SmB}yty*=r;)mb zi;lPq%rP!FgFb21Z4~43F&s=IH?cd|@0%l<>}HzY&JzD}iTK=00!%c5yg?&4b+lTD+Zh+XJ7MDG}f`wd;^}6lKaBSf0`}$;DSv8_I?0dcA ztxo<>KC%<rOxOa+kYltI|HNI-u^MM>XA&64?TDpKmoKf0GbQ0odyWNYYR936ugGB1{!!3 zaP#-W>%)HlUhsMYzlNKaPI&$O&;bT$EdoA3#4HquP;KNG(;qVjs%k_iind$JwO=!k z4A;Md)XzQ?pD7_lS}suxCK6V?h?jLd39HCJ*6^!fuxz;+oB|UuWHBEY8nc;l%k8%! zHf-Z-$^D2aPO^uPz0NR7{X@)?K<2|W88l$=FCQDF_7K~m#z z$9Ojh4kXExOgBj`2a@7TCVHt43Q^%!T#dtMliK&^|84k^7an%`k|k`eI_m*{U7=y% z)T%zYS{b`n^|qJVwW=+o3i)<~`37XXmtC(Il5~y34U=?oF3r9x%^rY*9WW)G0z|*Z zk+?kl@W%S1PD2fSvzCTgGmF++_uODkNF246mXHv1IhJ72>()IZkmv+GYZ@#dSlCMK zCqzc{cG+V*7m#+d>nsYfo8%d#>X`V2p6@pLq8s0 zHsZsM+K=hwIyCvyt-5!p!)(s?aTA+^80Q_tI3F~f%+xXK2ej75YHCcT7EhpK_MPh_ z#%aQym8L0z{F0w@6T1rSSSmCEVw{k>@9d@ZtrzQCG%JGzE{g>YP99GD4bD_>Z-hQr z)b|SeVCLWTR=8MnWCjtX3J=#F?{(W)FnbHGQJ^==!oC+e-b&KHpcCnDhdB`u$+N?p zBZ>q#>BI$3y*XTD#lpppaSKjiZ5@tBdjB@|#-&B?;si&mk4PZ8_`=swD4R2I93u&3 z`Mc=mIYcsceeKDfR+%xc{yr-?F?-l@b0#{L5gXT|dYn|?$9j0rnblu5&zat{zxpEc z?Dw9ts?RgeS>AI`oM~3+fVB$iRkXhP&Y*pmlR}su6*d*F55~T80(&0T^4gQgNb?M< zI&V1n^9MwHFUi{PTT}A~;CD-|!)C2XF01 z7p}kaT#RYL4+M*_!6xy}>|_%nRWF>1Z83igL;zh5M{Ha@T4l%LS6t#Au@yGW;`ESt zjSxdJpV*vU7_UU$^KeNb;=heco3!i;mzuQfmm!f$7xW~@Tl|tGeBxL~ZWI|oZm19V z)C4{?oerPu*IjgqT9FyJvKeM9zP{6zZ>gzeU@XtM!> zj@sj(O%rAv-!S-cfmL@aXjfjf4s?ml=}{)wTXhB%W!oW?`6J*%Lf;{PDotpkGz9W( z$uyyk(vZI^o{RFW>1oo6nyMGtFLLreXg3wM6gI_fJK+h~kApn^Kax9R-oKGmXW%g` zFzADxgJXLjPcyu1^tYbTI2aUcFKQPCt>KK2FlY@QfM*1I*K>ybUgBa{hE9H#J&(QKvY%yL zEOiWx43XtI9z8z5P9&OGL6i7GP^`p3)M}m2#EcKy2_x3n)crtbfOUb9dQ$!V?MxhXm-E2e^bC!xLcst(Hq|Gp*icN-7I21qfA1ST?Cydx3 zyrID1s2q=t)U+_7ilh+Y>sn)7Mqw=$2X8}!CwfWKQj7l;CdpmBWqlMb+D*nnliK&Y zKQ%1D>IcOVd>Ef|(`ozr=OWYJpF$e`&i-CVKa%~eHGO+K-p{1D{q5oPx5r=YZ#Ml+ zoC%h8b{Z2_*R0~3V-Y3TpLFZ`6q8D{BNX$g-UmsIA|~+ImlOaB%!?1>!wB`RZA4sM zx7W43g5|h=^Ayev%Kpx zbFIZqP|FyjQ*NoPQ4)V)JF~?|D)q3wRw(1^=5I*;vFs0w*Pq`b{-@Tvf5O@D$79Ou z+*iZzU#;7%a~fHc$J9-Y;i`H~MSEopze^pJgMUTS3|AY9h5PiBC?UxVxu)^=k((uI zlWZupLjCw6&pLh#+o^H{?fcAobbGtF3C1Snv!CAw&+~HAN123O`&KyiNR7$D5%%Bf zPTP3cCvEDBvp=-zu3;gQB6f*_>EgUs`iKv85|6OsS*|`JSL;)*_VfIQ0#Fobt+r`@ zirWiMYvtP#_O*uWH<~^=zv;lhpzq~i?LPMNTu$`5Er`YR1xw8S^uNNsBOUna^z={8 z1f!IgV3ZOQj8bBPQA$iON{IoN~aVzy4v+swZZLDp&k9Yky_o7iohp0C|3>I=Rdj;*LM8McID_v#L-N3;^H=x%~iOUTaOEa}U1 z^DerZ2(AH=uz*J!yU2RE3Na=BUi>lBubwd1U(c@2DzD!+w=Z)vo35I@H-}q1KtBs>Q#(01+{-#5UZm0eGrl|d5Qv4tBZPc-6O&>Pz zA$IP_@sazNd2;_UPwrpl$^ALsVC4Q~p4`98llzykK5s$pf2Uy#YScF4fma?2)|cBm zi&RKcOQ?-@h6$y2~GMz9L>Op@ID_L&DBC zzUpG0YS-e~W&8Cv5NgAe^eb=GnQclU5{Ee-X@889F>!PD2l2QHkqJUd<||_XcdvEF zmFA`AVD6jllaU-}#cy(-JO^_Vcyj7BI@aU&iR_qG z|C{x~3^@lV|8Dx=YB0N#&eN_h{qxi4=f84&xh=WANHX|;yuK{_zgu69U62N!&hkBvk7wZcFkVR}_ea~BvzQ!OQJv|*y;`_gpp1+n(&+$lY){idq zbyLVu`~;7lUj==Iw%X8G2OYHyjdjpb+t64C9kmUObGjB`Y{y{cei)OF`8(&e0=uzM26w2->FTGi2z{LC729I`!Q#^;s@H36uT$) z+DIk{Yt;e7hWPt?iv0>vayfu^4=)`5!}X0O$y#S2d%5OaJI~<>j!UK>V!GF&Z}tZ6{d-2y06d&bbW=m<3Wn$ ztDNqykb2zbzT&u8*RK$M-0i-~>;4K8M7j8S~fLE5rT^12uJnfWR03~HM=_QBhkINF){<}KDO7!mG*``^uV zX0w~#ww839=}9S>1Ri`7swtt@w6bfylUeZ$G;TkP|*#Xmb$uChtKD*7n=kt z(jV6Tzd0!X95DBkJ{-ijb)XCeYDn@Bee(S&M6de{vxb9uz!yfSqt!lu0c4IRJISb7 zEjA&;-5znY&?+@dL{a;~dsUsQS4xZjBg6c2C=k2$L@%a)(6#B4M%Cwny-a_Eja{U|q|uzQNaBq3M~%rS zErgwivSLII@jb8|iTN)@X%xGNM##a=Ao-vApd1$tdMd!f(xTywZJZR$4HcQa8kC)o zdm*d*hbmB}XAqQ-ZJwge^@KOe`*qM6;+9?(n>0{|QZO9Lmh+lm(UAq!@>2sPD%gN4 z1Uv#6pQ>AK`!Q}Spg5B_C_S`w-W90|(`rK_p50kj)poeRGCOZoXKigOI^`F#M`&A= zvd55Pv;N3;^3JmA#xgacRhzW-$S;;mIij%}+pmu0^^bmeQvNV@&zz~mIP^nT8uJ12 z2|lSk#+gbPBvX`p$5~_B<&W$Sq_FEkV?xUyx*_LW4pS}-y62uRjaHH7%=871e{7Jg6gi%54f^<`ibFeQ( zeXrA6`PCg`&Gdg7V?!P7`;3nEeHm5%Y?u#nia3?}wuF4!LPZo=J*K>B2f}0At`1p6 zTshjsk;6*N2)8dN;P@wpRCLUe;Fqg7bqE3Fi06t0XVG930A)_jat>ua;%jC={P>Y{ znRLdNTKwp+mfr^*A;fbj9;Vrhf=J-pqWG($-7`%_C?KzA zcXN81yrn!nC#hrnGyUOg(O!q_Q6a2Mn2|C+H?+u}kDIeD{v{3l)JTcet}v`tu_Bh3 z^pN9!0{>2bkc{v zSFIuVK9N1>TXiM`&D}_P0#2Fd?2hN1Pxh|u^Y+76n$u8+;$LICihn%n%XW1a!;daq zuEiy4Up+l)kDYHDek^Q{ot0Ss8S=X81LseYr%ygf^9SPUibJkS1G?a!n`5JCY1eHK zPx4h<4Sy?zugpXF(}D8!R>K3VAowf#qmpQP#QsbC7yUS`q&@xa_z$_ov6*q7AcB(} z|8KTq3Y3}cCAY-yCk4d{Znv?R;>7|k*Wy{5c*wyo`=7q+3zD7UJPjIpZ*twO>aD#V zXWEE1xg1@P|LKKo!7t-WuKWT!k~gEj znDi~-y{1HjLkHA^ha#$z%DWn(AuP$}q`mPA$vM&nI}h()c@4fTI8CYHG}t2kYoxdK zZNkGQkyrs4;48873an*6rpl;u!z>_(i+Y_#tx+q0<7)flT_ZYSlLI7?$AznM4IG>N zQ1tuDt3HbwrNkcbGiZ0v&IPQi7rqA2p7t-eEbY@Y`kDUyic`PmOX7<{bc01Ft>ucN zjG3u{ZhY@37Z3Ww=*M5?!H9+8mkkq?aYnEUlHqAIEDG_u%0>sbCbMX?01(FW>6O*AyIOY1ICagR#ydD42 zP&Hw9yaSup?)x9+Pr2QqDTJHoYp=0CU@wFxeQk$CJL12V!pq6>FZrT;(&l*j5Bt{| zh0xNUX@YjLN3cJob^C0?TUeo2qjRqkMEZVR>(eXzDwUm ze42#XB*QCDD6YRENbfZuN#}Y^MAS`^N0WXB=^hO%Ln9^W;*F(Z#EaAXL8aNp5HOQ) z&h|PYWiC3nR1*tYZTQIk81Saf+sSK`l>OED1q$ev9iM(7r8`-{x-Tl6eTBf!)o`+0 z&FaB*nwReCjTp-MUBQ-y8m00Vv3ucvdWnXcR99Bb?NSrn6i-QTXBfL!%dX%?6TW|4 zW5_l!UF=mge5AAj#aJdp<#fC>Db1tK>PEn-dm6F}fiAV*3ULS&BE2?f|HXKcmjMIx zz*_bsH<7B7*m?GdpOY()t<#BN-T}O4jdtIQ5b`9=$Ov0kwZ_k6;fYjzV!qiO&^K#1 zUfihm3~KvKsOZRD1-OX3FT?3=_o&}EKU4AAp&-Gcbqg>l$!loAmkWROTfc)ppGF_c zC9f9lH^&(VS@mPtp1`$YPUfyhhIlcVud2#vjsW4-Ae4ws$vH$R+ z@vpMd%jQD!DeXwfQO&$XYc&DW39|;k00)%CTpH#A1TzeRwfqVwvWyJn{G{{P!>sr$ z(Tv#0E2ek1FsvY-{;(yOrrR*b9`tSe1$ZP`7>?(&>Myw#hEJO`98Qq-S&GuJhhLC( zdJDtfXeFnEoIXxk7=B8$j3iDUCoK$ndP%cV=7sNlLAm~9+L6++|HY*CEn8%431-%~ z=7nFlqEns#GWluPL$~TA(jFsr7~TjsJ;)b7oC5+TG1yw(jPNlr5=cF#xf{Q0E5&FWCLc4C7!}$$v7z z1WEo51!_QFA^G$Jx{K9O5UaFd$8re^IspHj>PQ%emliGL2 zLNl`WEpSJ+TxU1ZYU>BehHr2` zNI|v@-d-J5=_$y*;-#v|DabzOrFMm^_6uRB@7aKqSVCXE%Z04FpGwu%3EA6ETj9;8 zR%q3q%j`+$Ck?VC?qfnyJS=a;Pk8*EiDweD-`CF7{v@Ttv>CK=?P)nVmcXJSO`rK$ zT3+kvGm{?Ql6uXppW`K@^at!#Q~b2+T1rmg>HrOEli?^*&-izopC%rZz0F7Po`H}v zc19?3?DX2_Mu3)ABQolf_~jRMs&Vk|Kf`Hpf_~zTxpMDr-KCxPupZCx9c|)( z@@&40I^TT|>cmEBojM}{Paaa_p&wZd=dipRiOyMirpRWiL5j+wO^Cp?Qu6HvzBS(v z&hWdB@PPleDXqk14UAAqfPU!pfXhf9x@+DATnZG|bxNGB(u1LG^C-Pwvy$ZQ_r@30 z*pK+MMkNy;^Mt-1av8}(Kbd#I5$nbSe06cJ>-uEe7T{II>w2@MO+ z(7Ld5ccaRnLq*(+f5KDkHi2q{68fucG_6QY+c|HL+cbdJ*|I*SW!97zIva-PhP&r` z4U=DnAw_PxE=sm*W@Yzw?WZYfS0}!>ycj`x=0G7R;|C8j$~vc2`6kCR{wtf}t)=qs z$h*E{2N*vBZ_MMwYVLRSj(jGPk+tM%lPCAP0n@VryyHFnAeE6ZCtpIB@rpq2j2v>i zW@X=XT;%Ut@xkJwL<;L0sez~JFL2G_Y}pNtDgeBFS_k#Xn8&G)Tt|iLsy9rO!1Zf1 zR4)@65kY@JbK($_(B%{PuI~!Ivl{xqf>7kZonJJK-)Yr;EMn-~T|rL;=2wnb&3Q#x zhzwC&TuZ2^$!{d~lg02sDkp5px!48J!0&dJa~>(+hRP9Ijllq_L6! zCu$=xTujURfiauM`@wDGsXf`>TJkM!qIM$|{P+inUtz4whj(BqYzY9a)`M1;B6|FA zIPNl9?8egA)odvCWa1D#1AF=4mINX}-`k4`=&_IC;W!aXsn})-$U&YtUY;_wd8K@q9`7{K8A|g@qx15 z^zs}vq%_%0MRv%=`uPZlp$ePrMpVfs+0qYkdwXXV!eC<5__lX;IqwW!4?&rx?wk{3 zx5Hhf|J-EH@!>K1O?p1W*TUhWLGrw0x=yb_2R|XFbNwIVflv{3`mFBn;*zeobc$EO z&j~h-8b=$;?$?EB_vtMsFjq`xdIs5`OxF@}e@}_`hGsSJ)@nFzD64$A7oZ_4z=5dA zM*K}Gq(AX&uV{f?i>eU(WT~t<8ZMS}izc@M3fDUE>Y08QKWWMl`hEU?XeC z0P+Rv`;BKD)5zWpE-=;TmD` z7=y{2`~aH?FcJ1`2yTgM9LL5+ic{}@dIKRd<`a=UKT4TMG$LZ!c` zW8b~FQmCHdVh`IUr0^`V1&SfTp zCGmox*(!Hnm@ierAh*0Vvs?A_UF?hb8YNYrPfy;=e%h=DgyR9pm~cba%zl`=&Zjy1 z+8#*Nud@!4yQ*eCHRgua(MJ<1>0qKAgL+S13-znp%VTVEFK#2-jA5s>>>B2_v2clp zF&>mSplNTVx(?RpBo2K>2Ks-8$`>O}hyM{f?cpjeEZmzl2`NNny4NG|f|C_8O zubiXzHxP>!hHzN83a?L|+B@Ay_Z0(J&yW0^6Gv$Vo>XehvQ%})3}?>t+WFb%gkt$$ zv3}Bg*?1U(#=crT_Jtis+X`!$@HOhxKA?plHUTxt$`#y--{ClxjKL!^28SmgRLF_5 zg4X>_p}GxL-GFnINgl<$Ok2qm)Pcetyh&q-LPdLE7S^Ieg}f?0S0E!OhpvXI_n>#E zcHclm*_=#`65;juYfO2Sg>B2_paukiF%t)7Ns-l=MDb)@+2p zj5vNC36$ilR$q|omfIg7(e5NYye>8+X2<{V$x%6iU~iCh+ZPOB210Xt@>T*=7j1+u zNnCl3=zw5j)@%!=Xvsr7(WQYicp`PXwfJl_#H92oQOfDohwZEnR^W$P-N0^Qz#Di2 z9*>b??IKVNc20*H1t4{_svZEQ04+9hE^S$xvIv}QA8Ax19T#m_`<0C1I*CaF9W&jO$z?F~B zJ@6*cq=G^jl-77h57dz3$iC9U53-Ag>jkhp6mshdyM0oN&e6x>Ks`>bvo2L`E%Pxu z$n7%hVa8>(J2@va*;>6*2-f$TLuWLLhhs)IhQ!p}$6(-NHxS&`Q`Tu`#uV8 zIUv`^Y+BCdZGW?A3HWoo*;wg6Q;c43O-V6&XUZy$kkUF=JHJycQw;JBcb*qUwj%Ezt;#*DqaV>t0DTme< zKFrj+neeWdbyC{MZ(c3*zu|pa@s?HhrCtUGBl4-^eQSv#jgm2wf_^xS0*P};2HxF_ zBbgwDTka-PwuQ-oMWFRGU|p&JL5WASxt zB2sYo5a(9!Fhx(}n@W&%nXcNVV%iaGB%yeN?)V85!$IZ-#YPry*Bw8B;yt?KCr}*M z9Y2BMcHQw4C_bjUV>*BNP&!Y>Y4s?(Z~I7)lQ-A^$(dX~sBWlmD@T&7hF<`_Xsquu z6A%Me<$X8e+Zyb61AZC69YgeR`TM;E$eTXqd3WMAmVS@#MR z*a>a?L!-7^OP++s5|xrr(cU4l2+aE6DZlPJAMKsdvwQ7 zpd_w4egY-!y5lEMa!hxO_lCI-5eqT75TYG~ZN@#&;iQvE##_92$aRc&eKgkRFmr>k zzBlUI)bWPc1&xY^Mz;mJEiku(bUVo0GB6q)WeDh2GS7g9M&rY626q{?-!YPzQNbLm z_A=;D+6t3gQF>;JuCb#07A`KeqG&BSAG2j(-UvRXts>9&@@Sm9iV*(X4ea7B9PWC= zSMJ(ThTP{$mWJle^+Qq~@Wxv|upwV`CdJF7F`0?=1CEY2x9W}Eni3Lt99<(Eoz{<@ zo$CkuoLN755Mhh;qZAVg!uzDJ6xnu@*txx0OL}8Ja#k2r08F7Qu-I^NmHtev9lqq+ zk;wp>wPQPLN4AaE*TzuM-s(@8Ly+)s$)zK?a;zY!I)4;2Yh>>;5%$6%cKE9CjI+7| zEDgt2KFHq3I0kz9%g0CErvg2_$dhq67XLYh zFj$vVXG@1xAsr_|i$NLHy|wus6faW>f~Bv>PHE1J%sJDwc*CDEW;l~?%;wlEa03=5dFmL#L|o5*<$k_h z`+36qCgl&U$^E?VaMFo})o{JSN5)2;Hx3{qy|VnXdtr;Rl5hzO9-nD&t4{$};Jnsa z{Qi4pF#3G|o|NpTH*c-QJ9*>De>C1wo{)d7$zR!-GG|ZX_avFEs~Io+ZD{K*vAAp~ z>#}%a=0&lQs_$6vjWEHfiwT{3i|B#JPnh+k1Y~ge2`w@%KcPj&)qU4yol{}Y9Aa0L-)Jcw`(|o0lPMEzdy6Z-#EMn?gW(qq{~%V;p3fTb=b_6yOBb;974%3 z(+1xESkCO>_1_nM#xvgG|%SdH2l;S zNNCW=0>wB-?Bo%0$j3)r_$d$H|E2u1oOY-4Q=Ye{)5= z3uDf2BL5&6TFN}>W0@y?EF0uDu*{P_mU+_0GPl7kI**i*NB{)Q@U@@hWKi6{Q)Xb~ z6Yj&efo|a9UwLmp#=ylt_8vgTz{nL|HeehWS?fK3l7WloxetYjKhkz2Xi;zZ<1|;9 z93>Si(*!a>-IDYAAEP4>>G8NXuo_0YZ8lxYUxZhynV*ABO7;z@ZB_kIw!z+pn9G{d>@`;X%}2Ux zBbLA4E^}@;kK>8ihcTjVH0za-hDb>1N<;ick)SYdZzevYspZs4NSoX`tofMHK))Fq zeJnn+9T{-vUO~A$k;pHUDJc?37XZHrG+=?m5lH~d$L6aTTLvTBZN%@15ddquAOSGq zCN>4-bT@3a3lad633u=AcHvUJ!4*cQw%FS)Y-GCt>&SM&oZq2y5;ftB@+~68C^X@E z$(V+tXPbPIok2f#25VXQY1s4s@+b_Ag_zYJ>YUEPx zh8c_yE+7l3$Vt5St_sdR}ZV-;Q^V#j>K}^8TyvAe{c^My3P%qnKLr+_~tzK zAPvHF+uzO8A?7G7xu^y(L>XP-+TTr)Jxct4B$lmjcX+_?*TTRN302TCM$0mt-GJ42_D{$+uVyo^G(}}>~fu^-L zzFAsNK&boq8ZgDVAjPNA7yp9S?)Z(X3jGnY?Yu`N7ai~+^}ZI%2@pbj5?%nxWB!In zEKi$g>{!isN2+paggP&hQ|z)|=3%XL+21^m6T(w)DjP7pH@ktNcEnE`k^q_8EOS^w z$u6{$x$581%kjXIC?IrSje80bEdzF=8v;z?Y6t#^MD9OGs59_kysj{U{=ntKKZMvM zx2?{~rDkw)M{{c3aCcN-?z7$OkT+-LAns{59SGz!TT3KAH)FNrV(x0r$WCEfO>Ybc zv_&{*g^?-yh`1~PG?yg&7w3)Pa!JjCt@Sk@gk$7S>BOEdU?u0d0v0A2B(+jE|kg+`|;)Z2OR3$@L_H%LJoG-)%9uGiQ}XTz36j^Ozc%g)Kn``p?ZP$>Sb z-KGta_L~qUMjS?fJ#}S#0F5nm033pOB05hJ^zbmr*?xk!5@8NSi6+&H@HwkfY6H)_ zY82*GwIxQqL$Jk1)dy^U(jq2!&vb`6hXUySeg#hN9)lQH8LRQ7kMEdpG)L!{Ex0SoCh9Oe_ zkoxOJUf1KB*)Tqs##VBuD97zgmId@xg0M|q@A#J?)oj<5@an~FP!p|4v@o*{)Y8u9o(gH1+jUWG)4z zG8$=J>TzlMcdD+aeeQi`@y5E1uIJ8R5Y1Tj*9Fy*H;mVqVa%=7h=Yh(&J_ersNd&~ ztYD_BW*GEgK*ebM21(7<$ZggEWEJYRY@`d|F)wF?%<4*{0#?>ptgQ1#;SFVwPP#x# z(OT;O*fqeD(Gy++(jzLn&y>SC8N=PUG2$cbEgU7wd>A3=SIE^lnua(%oDH}63L|JZ zwft7zx@aF5uuVfYL@A@xCyifgHG7H*=MkPC4(NWWxu>7iHy4eYvEU}ozH)>p=YHI@ z;vuE+uF)ZaW9ftwr}P_roGM>r4sEl2W)T-3#rnON-uq?6jMa-~Rl-i{?98zxnN^W<&(g?YEYF2e^5dU1B}%|H8vP@IdLZ2oGmp6&teOV6D{WZ;))TmWLcY zm}Q)Y5pP)aw=+@?V|9N!+Fcj4fq~l~Ujo~bcML>#co1z+4*^Y_1_>Spe4xjbE&c*k zrjf7~OA)ND2@?&t1R(Xn0Eo}`vt!ev_RA1zeJ5noWZt@LhAG&W|5pU zZKYU`*(e*}4HIt}k&)U$A5uyWEos%x%CJ*T+{oxb-D{=5)xc&^o^lM>GGW}5S zR;D*I%H0LceO_jd!JxRAL`LnfHWWq(iu9Ft>NFRrRs}~9p8092Bu5%|W_~^e7 zSi#zO^R$AhZ`@#}oo4c;#4V^1Tzu4q=TFJ#UZc&18M!;-e>(TqW*pE{F)11o6Hy7J z_$!JP+zus%A{S7<*{?SxhOy;$^@77$9So|%E;a&?J|8E{BoGt&;OpXMSBlA$K2=R} zgw^ne59(s?{*R3R$cWpo9_^^Oj&J!U@w$-<=H^_IID))M5Zpx{cd(I$2V@WJ{L)N0 z_(N82PD1E1BY(OsQ}d?*K;(0Jz<;zZL_`W%h1D$mV%&!DTb;(f&7hIvVEf4#aLZy{ zS6MJylm$oS!A5ReW0Zw6+h0W<^hVgvF~{N8N9Z;V9wBE>xm{C`GD$yZpBt7yS@gC5=T z83xJ+@McWh@_8EX4g(c13{=1XF}@7OFn&!1X+!b@qv13Q-%FHyqgJ&E5;8C%_X*YM zaI@N7m%r5O+;2=;*-R~`^mQHT-A+56DI)`K=ddL_kYo-r)0hJ> z4We@DBnwV~EOjqQyvp~6G)btNX%X;;m{QEWhDoE5a5y={y!k<|C`TU#MCc1wKK8=c$d_@zgIxG5~LA2GFO z89E9p;@Y)P7G7n|Iv`S2c?=*_?%`%n;#cNPu9E?IViMqOV5N9x`(4lEGh5`BPGcVB z3Fk!i;!o@_b^Xx&%#-1{l~W4que)?5rlK(ErcnPGy@}1I^(fR&%1;Wu1<;7Sn&b!m zCHkHg>3cYrVw{9aU4L4A&nUozzUNnLEj#VwIq~a`QT(NMH9)7VpQ=(g~A#bi8&RJ*0Nm|+12FeQyA z9tGhg8E>JB6w@h`73TFp{^RyI@i_$Y@oyeJ+7W;F;8CVw9iL}pNRADIc4(g*#JIXI z_XGjwbvdppL$gc4ZF0O*i&qQh3GH?$aparuQEao^-T6Caf4&aP+b^=9o0EzEqt;sHGFK!uh@&!ALF7uf$C6g51+(1Z%`Zs z7>+nun&Ik`rJ-RurL_CJ(%hXr{@ie*Sf?}XM|=9`9;nUqnQD$UW>>FttEn4@w9jj2 z)VW{mfSQ}9svq$l2J~=yK$7Vj2P*^as|wS{2fc>@`bdK-n818a-N|=T2LQgxRoTj8 zRmd84bK)=~=g~#JP^YNcY&eotKj{`3NUPcaqI=a|d#Qwi)DE|5uUZ<=z3R25>f(%g z+L!CkpBo_-TPe|WWygg^Lt>|A#{zlYqP>g9o~%QZaYLAqZ#FtJbXnwxddwiW3pi8o+~Jem7~=dEQwFoJS3 zFEmRi_3|(6L9SH-8ZAHOj-|}Aa6x7!OT>OJY#(OAfE2G%#0R=D=ha_KJO`{?{#c2x zLHMU`M=3${ZmXg{Ke_$ESD&VZRkzrk55kPF^Sd|~G6c-PyQm?vKP??Q^>rsg2nGGZ z4xt&{6IWe<*oqk_4tCwVGg(rHwsCw4!*&w(SWAwfWa-kL9;x=Y6N__R9F43~h$7R# zqm4c0?hi7pth%e+`J}l+GtJaUHq)Ivr#7=)ElW1j5R6lrx!!H&dsf4*)i^b?VIx?? z-5NC&ai1_-w{Plamq57(c5%vfF;qtSU@~qut}0Ud2~2CF&Z<4MfGMb*fmQceFu1(v zC9AGKH^Er37vZwe3qRe!IAC%XwRc4ET;CbLp=Z>$4Z06Hfc>5JGr>j@WP1C*w7146 zOZFm0o~1Kz5npqJ2t+oGI-f%?L1MU@@RwW&fBCg=ENkUpxj)A*n{PwM9-te*wg#KO zF-hYZ-6ySUbU(=Ck?n2n7-NBpeU0vopcMlf-Fp@`+!7naTDHQ73X>~D-)|#Z>N*9? zDzTFZkb-xby=60i>@>~CO+!z_uXDeJq_-NcaLZjh2sCIOv!ld@l|&bVDmIf)nd1}f zP`mtCOy=~|PJ0-6Ts-ggp*uq=Hg)^Zm;zuDwfyVS`8dn7HE*2;sVT&u1!V_*SuqE_ z_K?Cz4vZQ7!S5abQM7$rwUistmQHyIlF<>E<941m@HZ77U7uZD6m_0c6{7i8p!#w?Qx8~<&AcaTPVflB0m^@zx15ed_LHx|?R^3EpD)JUz!Is7A13ufWgTz>LgH5T*vVW_~a;xHZ#* ziNURz9n1@E&E#NOaBJp9CU@Y&A!G!B<=Kl+j$$+$leVPuHy@4X_mBP$zYt9ZY z*-a7+%3%pgaj6&ocDvT@z~KEz&%OB^b$+KQ=TWBNjZx>9nnYl?R%sC@t3aC1_g(pV z${u{JT9cg0krt+p{<;&eqyC;KLJAl_$bsanua9PW6Zdzm)JZMONDk&k z2|1g&Y6VFQ$0p+8(k~2nnE3P;dPeG*?$qUhgPzRkD2sb~s`dDgp2bJkWmi{3F{;Y^ zokvLmy`U0oIDp{`b}5C?fn#II{i%`<8{p}%Mp7+G}GNBu^^qv+s^fw6;00%8VuKLb>Dli zs)S-Dmu~Y))0#9R@&)7F%C#B92xFB&KFeLu-723n#kxgyuI$~a^iY)3lFlj*#+4cl zcMhOI;&ZQBuPL3(KwOCVu901(Nc3`piH1a%YkN8g#0z8BhefqWwh8nFeKuiWuLE77 z%eVwFp2JR|%kKH@^Qb;>fp>np8)bIsaDsT@h7Pk=&U?qu;Wmzpo`na#HBjL#u_5Pi zx+k9v0*8G>U?ISMtdtCy_4{2ayZN?Vp`vvqvCu$PosDYs1L}7U{!HLHEE&Zca_UR` zhL=f(`Y+a!Oyp?drQ13g>Ns~(cB>X?MsM;M>Rm>y#D&N{RFL)yr!6P>$?nAK z(v=wh0md7)oCpN%mnHv@i(JGXVJZ&gvrjdOg3C8;kzL88{1IUsG{Om7*igU>g^4%sP1ukReVbvYC+Yn0Two zynJifUNb|D@ra}>DWiuKt`&k+FORrlg(v=h)V&LMmBqFHpFo1KP5SOAD78@28fs8M zXvLB$HIX1Y8Wrn>q@vJ+wcdK9mRoNan*`YIZlJX&J(kL;rH39%>#5RG6`P=vfVY4a zP+N`F%DcrXTE&PK{-5ufdH3FlK)wE-=g0GqJ?~uB%v!T%&6+i9X4tXpaO{qoLGn&F z{u-K!{18ywtro8D5LNZi}9OMH#TkRu2}%+T0t+l>w_bH_9AX zeY=sC1q;RU|oJ(6Qzp zIb*o_M=p3=KEm1vZKM!x0OlzgG+*MH+9b8Kb`44V>k7E4=wAw*UingO`#Nfr9XQ01 zX*Vqksp^XISa{1F0?9K5c&z$s-|8wYQ@DsEc8&0CYS}qwA}w_jNOBRijoh^T80|mc ztzbe7b}PV^7*VLcU?Ut@T40xaRBoR0@tp;S_L(koL(hb(x7i6#8Eu2+0f>d#N^qAy z%wA3;EF_msc-G;-o!Hg$glA;GqXy1*uC4OtGi-fn=R2#_{U_5zcb->AZ`^s_le-k+ zk2~L~LmKXUrw(bj^PSb*dJm5EWzHFhEp_?3qT>kp4>dh^z|e=9b{{b794xZ4b$Qa% zM##boBpV;^^h4>R2FQr-MHe%yr3h^g4zDObd#N@Ty2hz9F zk9C}~I}^yXC6J zU7+K;c0$zG!##g-9WEbJosOv*9V~c>iV*?N`tIj~qE@)*g^1p)EDzY(RuHuOfqV=| z(jJ)pX@AO4La4Zu4?p7E{c&2pl`_c4df)W2%s`59L(|&_Q7PUnjVvNu`Ja!*bYwu5_Ixnv?d zQ>2rA$1qB;i-)g1VRpMAk0SMedt;*w&e(PH`9)MbKC_sPxzT-9=t8g?yIc<2V!RN; zV(hxm#gud(rt@i&m22>;gem`|%EwA(J|O6m9)c7yManVj{IZ#2mGRC_B{k66hDV4- zK+Zf`OKP^2xUBa$zeC&%)iEZ|_F zFdFQd`EebejpcELK+UH@4zkbF#l6nIfs&CGbjX=1!$f|AB7Q{GJtI#oC0fQG<(U`k?agvHPrngUaXElpm><&9jL|O%z-T&^fUo zcRZ;MpR7*$TQKh~pwUl9YF$ha6Kh)*>IGW?Q))JIO50i0n+&GacPaHXw^CU}&~gc7 z*^9CFim9Zye0y2M9}Oijun{0@h6NlD2&m^^5|8uvro%$_LDCCV)YcXr2z)LB=^HFO zoY}Iu)!+s#2f2xT*w2wb;EGj!Q2+n zK%c5Sn5)xNUVphs!wcvovkWA|OvH2JtU>cj!$h#rwEYx?G&m-e#~B=h{NN}PyYzgM zV-al%n$Jan^&}BinO@7_J4pC)O-?xYUQf#-X~&@Qp!r0K5}a;ZyyPI?bhhLB5iQUy zy6w{Z?2%Z_xTlO7iur&a1gFo{ggowaGsyo92Gq za8O(MvU}vcCN-J2V!7(zsp_^jx$58v9vULwxYXGQst!!&rzakX?zA{PpVO9&3}}(< z!#JmC_ge6*jDG>O->IpBPhz-Ayy5N}%YRt!$v&+2WI4ZBvQW1dO+E3C9J{xP&}>Jg zI+v#l4&c0MO@(GVDy=S4P`0B|oy*e&2MTI7G}}?B&gI$le5LtNv=tob?ty(Lx%u$8 zcFl+Wnj6vRPDsnVwH|6qZLtF{gMULVczEOXfzkZMh+})Pf{7i=-#v4x%s=@R`a)e) zn_PG+Kh!I2d{RLh5nk&nkiyt8vz2M}p6z#J?YG2k4Ca23%4vRVo^(2*3TH65gLw;G z#}sZ^r=cDzx#@oWUg#SjiDZQ|5N2?l4K7ae9`}&kScv$a7BidVj)9q<;Ct{d`!yE7QSbw1yaibYhcWc+<5syc#sDJC|=Z3SAW&Q+(!P?xuNy|>%i zK4So?)Xm5WM1$n96Ba>B$ZBmn8+kP%oZmF3OS{u2W&GFFyvFs8Thm>3bxXtG_JewN z@7#X07R(C!|D`x@=20NlVP6IX}WrB(DJ`{b%ZScIJ`^_ZH`EXV*^cU`W+V z>bRZGyWC!G8Ip+vat&wp(6 zNgB-7Pw6XRGA&g*X!+i2<<=(Z*6~NAb1WR{>TZ-Up|+!X)cxz#RzZJX_uBAAB3#|y zaCO@;N`a&WHnXRHEk@$}-SyBTyybzNT8SN*Zx71!x=-(#7j%{ki)bT1h;mN0u?Z|O zt^QfP)`qd^+PuAz|5|wAA5fsj%1fYS>S1(l@;YsmNPQ;%$t0d^ibaO6jYc^|4@*pz3ILn_JI!n+?U&Wm<=QJG`s zm-#Zzbq}>{2D)`@*uuh`x`-%Tu&J2FjwCqvx;C|EGS%aqHNm>HV$QKmyQY%Zv;x$E zg>lI^u8Hdo1SU4P!hv(yEsq@UfBOj$^iFB}(6xgf)}D*>l{%9h0bMw=LGQfP@|fiH zZ3jNo^skR_f8eJcs!egNncf<`ZtdxKJ6zvZbKu6R=7)mjkpejN!FcL6jTEds8@RSM zp0Y)X08t35RaFsL`zb4{&bFtycR77hWjYv-^T~QvA&A|WSp}kVrVVDM7U}y`+m%SR z45=RaZ~~9YP2*CNcVnyCBwJPWMvPU*1*fNu;dt*o`SJXXV^ha{B5_YfrBgI&DvCY-A zV1qkPWoNB)wz7j`0pKJf-078%qL&d!#SegKYdhNB=!;&m;D2D=np7G{8okd6C2;95PxFhLxuPg8^1##{=~+2 zE5toY>$T3lUp~Xos9$aB#Nyig4T(0dUv%iWdxsr&|1X9lI>zO?$|$-X^x{R=?9zn9 zI_~3+rv`0t!{Jq1X<_jY3mQ+Q|3}^wZea0R(Jv7SYKOMBGK+NuD->I1v1JOHAc@xN z$`Dhmwzr}cJE14Iequ(B_Yb zcXbsQH-UNogMV@*DCDf;^rid{-iXL)PI`GCE-0s03$U3BpzGg zexoC68R82E-Ib#k6JaL879Mk|pkjGZ;>I+M_;ReS4Tq>~Y;eaTOiUQI-{ND~_EznV z+$cfouS>BqEZ+IO0@Y@uj__XOU1~3}@NE8?t1|K864TKM55(&Pb*KXUgNt+gfmR;j z_7{%s%x5=6_eav}(z`JnIc+<3om675GbVud1|h~eY27hwCAu>qxb^7PnZC}r%hIra z8xQ0iOyyTd@2Wo>0@XvbQUyw5at*>oz{_r;VwL=nR#=Y;GrSA>F!TP2Gn#yr9BP-^ zVJ(>=vrWUWKk-^6zdXo!_7(cx#y2mb1`EDO0jzGfsuMu9;1E8fd{R;IArk64)C``e z9KJi4`!Wa4MCOe&X3}Ot!?$qZft(%J1#{1lw-HgD!Q5JciQaFYE$#Q z0WJ11QLEn!_EIWzeDGz}p+A#^O~WhDOh%BWN#?Zsbu<#1jB1kM3?KuplFbA(p9IR< z$F<#k&OdQHI`?rx=lxSDTSWk-h{^gI{ukgpIrAhSJ}^_Saa35Ir>){~!DL)XhCdg~ z8-%AR;2VZCVacQ!YhRV3@(}sYWyAVB=o0%pIa&4ubGb#w@~)$Ro~G4}WThYT0ArsN zCX^A>yIs!MMNAU_m-FWEr?0wPjSSVu?ZD^g*t~Tdp_Q-w->*7TI1YJowISPZvor}} zE*SDt#o)F5G=J(prDFHaJfhBXFyt&hROSCRGibU~n%zf&g(n{b%tf>#9en?jbPNS! zpH$6yKxL9nl*ukMNi`FEKKT9{czVU1iz+=@ZP&n@7ClTU4y-vpJxo?(W_DQL59cu27z4GRM9t;`FU3bJb3Uo}kx?$NbRXjEF)o}=tT`u?GJ*S7uMb?pNp#DT)6VOHfe;WQS5)|pr1J-K3~TveqhLGMu2ha%dt}hwzmDwpFaZ1aj-I{8yFMyBqj&3)*FCS%kZb7yK${8ia8d z#FQL;J6svW3iWIEEo@q0hbvmGzF6T$6`zdmU2x_7yCf7VDR9O8sVds!sidA4b6mn- z4V|E&Mid_Y0#t)Qw#h($%{GLI^W9(oY}>q`Jh=8yBvsH-DtSfo>4yi{!IVY;0B66W zYiZmi5jv$ecCjXmw>Rm9Dg6^hQ2fr&X@P~~ZWFdrFT&^lCxfR4!Nli*7Y-m_=3WVE z!wBPvzz3BY@fvK=%UXxHi|lNeQ&@a$r8m2^b?J?Mhqh@6tqA|-%=+c!ybDUfJM#=5 zoNDDxD?lS4Ry&PsT157sWfMctZfmg11hnlrf$g>BxC4@VRDWw|QWUTawnqhq|C$Y7 z(4dooP@(6oDjwQCqKCba0e1$LZaSsMrO@LLB*u~J=A59*o~fm{Z90boC1w6)W(fq> z$N1JQ(rv*!UJ?^)HxxS$B*sep#;e8797~8Lg)@1#GHv3cRchbC+!AX(-9@SqP#XN| zn~Z;lc>5I=CIpqKnDdq%AaqM@SBj{n3E)fe+L?z@PvO^)toDVL}v|D}B$ z;|)mngPvo&Z~$?D*G@y%@_G`~r44F%b&pY#Ul%#16Xl&AZC??PxS_Y#r_bo0zb z6nJRP=Ty-VuA(7#?pB2t8i<)6hsq`Snv{d#$v7kn<~;)dXAd+=+KVV0JHa~<6@lxC zDj2nmciIzlZrTZ&w^Fe2&QavZi=xH}mbVKOcH6CPv4|Kb(l0s*Z)b$5nwSC!gX}dP z(;U)H&$nyU&5CjN1lNP^_KtJZ)f~zQ5B;fiOo93={NG>L2Z_%7xHeqkVsh^Dm`jZ7 z(@AS~?rCbW9Vt%M%DTsqp`6{*S{4n+4>#kuWtClsvyPnVmIIOXtsqO#F3oWowoP!_ zZ>4onid1yZzJr)=(BOE=?5nI4g1Haqd?u>#mfxvwbm#?+84l!nM}}c%uxca2pi)w{ z&+N}8!{C4ZMp2U|NfI;5@pqDz3LU}RIX1~eWeZe>JB==}Iwsdxe*UH>5^*v6Uo0fv z#Qg{)eG7N6aME%LUCHLmfEB+b9E!bevkK>ON_ADY}diCnwcl=xTpKDU!;{5)pY z(vh^@(W11ND~Y1T9j)x(Fui7T_E9^4WGbjzPx{rGU&8t2+JV`^(K@B2UdPr)?nIx3 zplrIvN`}aCk1V{G3#;v{y)D`FI$&wO+C89v48dGZ+?vk|IuJA*_FIs#Nj*l3aefJ! zmBDwn-T~o^KWkvkJjf|b3~qCy@xVUWMsc9uDj%Q0O=nVc(Zg|8Vua(FCF7k`-U|`Hv@i=+Q36j=&%K^@GU+ysIR1d&*gD8Uh7NB zu-`)?D3dO=6ZJLZLh%@I014^8iY|*ptku8PfS=fr9${r00cON&qX#GIEG>7Spk}tF zcf%rn|B#4@*q0|uc0HE9UA$xC+lZcCt;VCcdM2vA0|iG7d~fT~^yS%h)y%(5f+c-B zy91&J?H<#83+UVk4@iH;!>(kTA~qO)`W~`H-${oroj;_VZz1q%`dA~Y=)xR(tD=L6 zFQ+GE>l6GXD&FPb^W?i^ofmIG^A+q?m;SG^kDP+fEU6YB#^c&_T z=>7fZ9Hj5_IVH~&sWgNo%$Se(drWy)11Q?aw`AI8H-nPL$+UaIdtFR+n!1e$C(;t^ zcz6lT{nf}AbHswas74i2*d=m_}0|BNHFaY8FoLWzJxSNtCL4F1e0H71( zPyZ}x%^$RlqW3tYj-`JA44AK(vW{=jK{Csg^hKU8=*P}q(T{C@e8308{zQcM;I;Hd z&ZkEFJ8{_mDC42x;YH$~VK?ae7>?62Uc^81RF1LnX!?glX3CXZseF@FE_0t%4svx4 zITWB-i+6Ip`-|$y6VcgSH~sDRhO5^TF}S5)gky8cpXSO-r#&73Ac@!(j1CkQ2jgcB z23gX-vk{M_6T?0BGAWKhZMR)X%aa%jVss0a($*!`_BevIF78gV@{AUmn-s*gRfIb& z+OmDF)DJ+p9neus>ln{BVQMe2KMz;G@` z;td2Ii@(-hIjHq-U)?S7%14FZ@muD92m0Tbep~jCVy*OY*lX@{PD2iS0C+T|^JlEK z)}He$9g!+owu8AY^4oi_4~-Q8OL7V|Tf9_w!v8oP><;FhYO~Ss=PdpRAI}7SBJuS0 zkeH$*wT>nt>&H>j{Y#5)ORsw-6YnhnlH2BH{Al{;usHW6IfIakXQ7q8g{wMkzK9K( zf}CR*vnogC@Hc%xZatF=8(%f8W7ufR#{@Znd~UDgJBAfx0W0o|eOY%VL$^0XK5)d>Z5Wj{eG!8g(C;w{O09QF7K5eP`M04bPIm z+W-rfF|tRtp3RAfTM5OJH?8J};}7y`VQ0A&;tkvU3vr0_Z_d~C2cCPp!BmDeo@ba| z%^?x3iFIa;AIeO+&oqku9CGF8FH?8_wIoU+IC{dt1o1}Sx9#x^^V_j`4SXHv1^okmz+{1FnlR$Z13A$)UIq(!a(R+$*`U26{+$-QYYXOWD%ap&RHJ)fLmuw80i$(~*fR=o7L3}b# zE{KxRul|~jbr}~~#zzIxUEyn2Ha9OGotO8gD$>FtEIRSz?e`-t=;2F>4I( zOtV13tkk8(Cw-$5t}SF24fCdditNh>;L|ysqnTWl$xV@t!108Ue6>0^eKt;YWR(kr zY_}DjfPm!9-NfKkIy*e}ww*kd z9L)dNsK^x4NHZ|S(7me(@xuIPsmqzzG+b)$CYFC)xKG>trkZA{tnj{NOclD-^a}Nv z$KDyR(1}%4xo%J{kwffewjX=xitIdQtgoC@_WGca?Wh72|PCE!j@5WI09L z65=@GeoS88ss5t3c;cmS;k9B&StYqHwT{=O=Y0kyj*bb0(|j^2>r3HO`{4ds?1SNX z*^jEQ);@T4Rw$CQl5a2>JEbOhiv}{`kH!-+&5o^CPYfi^Y-(JU6_oynK~L933vlGVv*c zOu|(EsF2Hv6tlxcSgMAi{t3Bh{!K*7SsxF^ceZfzNprcWN|xuxll0&7(==r;!LAi6x}#Hvn)u5&Bn+$Mi0qyQoQAQT|=cSjC6x5tWS^ZW1l| z)v0s$R3{!x{J8u?N`9PixHi9O+nai+wW<9h+!hnJmn`op?@zLXod{p6=-bQ7h=NE{ z;`x8B&ELY7csy}ec?FTAHIr>oJo#fsJ>-*UBFT!GP6l}p$7gX9mp2TE=xqgH} zs0fdPNosgl64CmGQ+j2(8_7bzzL6-gH)!jaZ^lZlOYxvm2ld-PsdJDC}4a>4hTiXCb74=DxS)kV}iWY$lMBO4r-N?=RN zEKk>HrzLnvmwMmmR${~1%B;|;osE?~Lk-e(ix3njq-@m{R9I+3FfZmp+Lgo2)P33Z zu8uB@`Rk2RD0J>syDs>GJVVFX?G+!J;$iu&Lox6{Fpqf&BE$1{W|%%$9p3}$F1&dDt@yb;X(C>1kdXyEv6 zrp6!G07ppGt@DFQBPOIdc}bfN{Gj8s)UiZ;=Ms5Z>n;niys~KyTCHEb0V9EsIupn1 zp!Q+!6m<%Gk@^M#@#XBzOh~QBKWA+fjric+``MxQ1KXq~SetZ2MQ=N&iu=X;I%$*G z?H^6<|9L&%`U>v|>iE&9k3XwrO#kbV1bd#NeUYOMAqJiNbO=Fkx#F*_ z4?nHxJ)q`+&|lP&T;#&up!onI^kU9;^## z*eOK{@kfX2OMhCv44xps|Ck?16%2xxn8VBh+a1hXJw!QTm&?I3B;W^iY}gmK;gwrV zW?gtNYy@A7pptMY9pt6CA_iDmtD%(fMc;ckj@UKJi3dE zR9k(?H9wd6?=G8TR?`z2;vK>G?yC7Nj*?@(YNo&8Z_XOTSIGg?L#F#@+E+E@Rb=MJ zA}JR%w}09&ajzPv89#l_GPMOwGpyQ%Uzo1oMiiyHg1MUxF#0rG0)tEwS!L4*=H4Ln zFA90dU{d1llSmwwc%g<_`Mcqn&5YK5JXCv-5Kc1Sa`rJ2>=CT!^{ZgP`NJhFkPHt;ev3R-o>?br7cS!e z4^BRa|EIQVdbbv4<--Az4{B}Vb^l0E|1U~D?26<=W!DERA25VVQOPf2(@hXv?&@%&fpF*V7J%y|_;6^tTD&CF>PLP!uDRv{$eA-NG9Rbek8>Ywlz zH;akA$Yec*aBL43`bg=TEFN9tw|%5$piJafiL?d8+0%3rO}}!&Dq*6fcoR) z*5U4+*&N+H^DVAsTF>L)(MweyIf`Pb@i6KR+^XI>cM+@e~^V|1qlNm$DXVnu5(hKSe1$|#AC`oR9k}-MY zsy7ttyMtgKB6Zxl6=Ks-g}Z)47181hGtp>Ml3r?sMQ4+4JIXx!ot)<>??k{zOwnd@ zvGnlkq)J+~taP$wE5NZ5y!9FJdhbOpP)+?6A1EV2+M3BX!*C&}X|C3cHxLu$maBIv>h%Kv*B{v0fpp-^ zXK;Afv9R%`VE$i-=rL<(x5CgAR&2S41Hi|%CFwRs3eUbCd%#`g%?_6BJy+gkDx#>? zMdw294#IB79%U2NRenE7t+T&ZMrhdQG3PO-rDw8_7aO*Iv3)%s%q#ySDz}?d>D+DR zS{^I>l}l$c`#HLsavVhb3n98L@^47)Fs9Om_gYKIs0QX&(@>IHy1U0%6X3*wnOVQ#yPg+qLAD(o0HyWss5@fKI&5~XV}FNrG`-9A zj{xL>M)1t37q%}mE}sw)WAU3+%rIa*Z=Q?4g&I$6Q)Q!Xw+CFm>>}MXJuQ&xV zveKKCi5wj>4@Uf`V^6SEQSgH~q@zhLmWx7?{-O}PAh@DhH&kC+=Fo68kazGP_Uri_by3Rj!t7j{ z^!BaWWWOWL)ZV{3R5EYp)u>-0X^k;S?!d2M!y`hAcL^Nejhst8Yr^2C_3|;8qCc7fV=xdBzF|&wY`%eC#ypg(F z*3XeJ!f77d7@NVoBDNG<@ns0)c&fQv9T896Wqo6>-RTu5y)Mnua#Sd*)s*m?W^;_0 zwL*K+3`r#WQ@}P33H$!sMrFw(NF4*ugwhuN!&wo{S17Y&q0E@O9<=_lm3zY*I0|ed z|Gm?3^?Sr~}#a>Jojp95~88km0amhvkvW;N%cy`WZu!!4d z{cz|Idj8-A#|(c2;QB%H2aCDY@P^Q>GIXDa(A{L{dLz%}hHjPQ@`r(MT_xw!{CMcj z;Cm9sN&l<`I0@Ttu-_v5QLbBF`K{IJ4s6Gt*;~D(5SWu-I zB7B*HH6H>IT0IeDI$_k|8V7bJ44)!U!;?}FVf`HJfNmGz!|i`P1Lpc)_-of9ga5ZX zh5w7W%k=kc;k2_enn6;joqIALBTy=tl59H8PRww8$syO;#A5e&+ueX|xGMSz4 z*x6-FdA71}tB%P`9mCs#xk(PTI5*wfP`dbtrmDKsFKlA;dXsw>!QvA4cOg?< ztmKM>YSy6zH|@D8auRmvdZt9>iBzo3PF=rl8ZC2EF6B0kc@jC>T;G&89W&xo%C+5!5EWIhXHf7)&O73qe&bym6C!^vi56L#^D9!v_npDZ~ z_#Z%4pDBFo+c_V9v4yGD2U_h;k%6e5MiidNPbVt?UIoCFP~$Aj0a!Q5AIOeVxC3GX$+ z&ScosJt0_dAD>S1x;PoBaK#|w;tm3nEDl}|dn$aBwTNpS)%HX~dfba>_Nx z7B2k08hK$CJ;iZ-Vvm7FR8Kb?Lhrdk0;jA*RMz@)?mtA69Ggs3*tN>E)!=2aOuJ?Qy>(3uJ ztX-3Mo=uD!Oz&~?>iZt$7|?LmmF6P@?+^((DL%Ejs{K&DQfJsf;)ncxk2YIV-$LVA z%SFvP{hv9P{Zw{+N2h)`c1z8F?EiSXE|;0d`_k6LE9?xjDV)DKjrJV&#o`PLh5fX z;2^obyda+dhEjL*_ijYD#5&(M#^3;c&AX}V<%!|SGtyvj6@27UVPL1Jqo4`2oQ3Zr$Y72k;JuFan zRv~Tjo6T6M#W}moiM#OAv_>qmDoa_krmuW5>+gv#n!ssC3{cV0?CIvCX}!bHB;hvA zx19O~h;gXNb8M;$WW&iFqW?dv+v*Z8XSBA9+9OuYY_7b2d45_(p0oGyi5~L2MDqMw z2e2uU+5JdD6LX2?rhwOTw(ui=)(=OH+x`=ZfmYal0*U8$*XF;O*x*I^Msx4cwfpRR z3^<>=!E*PnO@8ZH3ig(?=b=|AY!gaBMzy~)O_%p*8%nW^YwbfR$iQ}Yrm>mOYZ1lH7SUG%Y)_Oj|*T#m1#OcN{+L3g#mOM`Z^kK+vvtw{?t)V=XZoZu(I=S-|^}g@% zFtRmWVjkV}AK`q$i-23Q^-fze;1tA-XonyjiMcTIJs`lw--bhpagX~hRH`0g6a7wwu&3QA&a$jwwaq%h( zCtf7O#@9D*O~ofA5I^`GhRY+EZZ01lW607 z40zI6ll@XgmuSRk7Wl1ApQQFh&KJ`UZ0hbGEIg946jH`*G8h=loyvFmApQu}VNTF* znDt30X6~27Cf(BRLfM@$S^kZY>cv`u(53 zlZQA~hoSS4FS(HmP>6vT!Q4lQW4YZ3<=iqPbzWg*=hZa&qF})vDbXf{8ZzrZgv81jdEM4?i*wn-n(NuIZ38!SAO9uvk3 zKSqFJX3mX``oat&Z?ut>yFHe^{x6~p%;&um?>EB7qY3=I$g~(x3ERGs zaXFmpjOB)4dlO!9phiE_*rk>EF?erd|2L!Yv%1NQZp6 z6|&p4jg>6?flxTAHT;aDZpmkiASgIU^U3g5MO*qZ&Nu)ra)Z0QybDxdke7qGXV4E= zNA~6hM+wMOxdQ|pVX|Iv>EoVoLqV>>OQ##RaR_Di7R3(dwv38-_M>CZO*aQo7Hzh) z-$(cE2|uBDzyCtvc=(Z?5mn(E7YMF1*QIZH1g7ahgIo{5^cxP3l2zXno;|d4oPqc)T|xu)+*rM0DGvIYfNvF(KM)9=UW#Ui#EdB9JTQH|$0$Z5&M( z@fs#)tXX_&)p;xtGHIF1N3L7ZAtdx#fPNb1PFsLxmY%pn(5Rzw9EvV!CE~IU`uP(6 z#4hVph(EE*wkpJ**kxS`@h5g!s1Sc*mx(hj;ZN+cZiTv?!BGx}clCBSG>0O!cW(|w zJf$_N=x$qmMh=JGWiI`|R%47yN2mh+#4fE+h(EDQ%M{{I>{2+r^b-EWE{!R~pV*~E z3h^g4lt6`SkFr^0yj(8PVhb9Yhm1^>6N#un!@@$@I)@_x>*9TFR+lyI!y#5=oz#3D z%-e!IV@@wy^R_wteIpN=%_6;H@$}56at7N2+j*X}r_EwL3vpwa&K!e<+`QYxqzpcH zpw1Ymy{gm4X_26`F8?djufC0!`R%rEOwv3{x<0%2voXUE1z*%2Ot;<3cM;+Rruf`l zVv2&fxOnY(F5X@}!ojSr@V{mLccA}``QIY<%V=Ow4HPWNaWA{G+y4{b4D;b&7OD^X zO)|MmP?Oyfr(XO>E#UJFY`QYhwTF{ge8Cbm<^f@)8w&5C(}?4+8{%y1%#Xp@!H7hlkwzx*==^E z`hQHGd>ioO3+A2spy*t({SF&^Kg5%5&(rjkr?Wd+$#11tt7w(SF|FMU3djD#+7e#V+lmxXS1eg{wQH{cl)}60=$vzwc**Y`p=V-DqvuPUnIR^7Chm#Ri zuW`XwuCHUy(_Q1`SioGiLc9|+|K|pcLUWwck*$56@LH`2JiWBTMAX=LdbH-q9LI{T zz)$Qpb~S=gm~gWAv#N=lEIx4_b<@owAgyM3$)d0ykx#Ao_@PPfRFzdMD}JE&)d ztLKxDIX%RLn7af@vh40EfbXSk)vnB^Rpw=sk#GunCrV34dJ~#s&mLONvM8sA9)RZW zq=(WsDEJrKSnTZyM-r>bWOht{g_Q7NThR@ky>2+_$*A9RBhVcs0Fk}* z7gy0-et&>=9d4VVw!7w~AAQro)N5C9-r-BU6mDTTuFN-y>ri^P0!07P=c2P`jst$> zOUi|vD?OB@bEM~=mWkbrQ`I6iD=y`hCmsVS3d`oeBdxs9P_*y!zwtyjH*Q}7{kXW8 z2XE?50g{47@J^kGQcGXZ6|l=iK+X_5vVph3n;#e(m%xV_Q3&C_h)DigGM( zTc2>}Ob(v%D1mLRCpb$T#M_?l6My~jroZ*&1&Euab?MZ|&hV?dsQF)nDQ*Xx_u$_Nsws z%Xxo1fIoV~w}s#8#MabzI8(T(dT3{LYT8>vx3s<3hZjJa_VlSq6|W*k-pr~*U3oDt zN-fd_Hvf4}Ij35#EE#^WmQ~Z%@@IEpDIc0~n%ZN*(D6HnYOCBl>mN1w>&I1g@X*iH zjfvt#sk8DcADMG-Q(K?-)K@C+PxQZaPCu6tPmF^t?j2}vV)Hb0(DDivN~AxR{T3zCM`XW6x%9!=Zy}%VoBbB0(*L9;&p%oIFs^`0V4;C~ zo{sn-n=WRo#&+0~e|n|kVcjGB+<4;e(V6zz#A|0WF2BLJtW7X<9*JM`Ldcpgo>pmR|3IubLjm$F6yT_QJ1)=^*K@JTGW`G zw_`N>2}ZMOy&;}Flh=4!cD$}}&w=!oDOACeaEZky(i+~;sDieMhpH0~B~p#5y$Y_T zKprBB)Htc`#3n_j0VFJQ=`oi+!P2FNldgN0!aSE==F;nP%P$iAt{L_SkgAp5Q5a5^ z&`P$5IPv6aRjBylaD0z=RpjE2?GdjET>PQg_~c^4x4lud=wH0OQGk6=uzXO(^{+0m zLgGjUMDy>WGm1`41cErTxr)Xk17E8xkR4Fl@60P_zKiN!sb-4p@M;#3IJ}6S0&TmV3FWSE_xUd>^4En*LgrgzpL~Uty=Kkil`#ZGLdrlr&Yz;cQ>F1No(=5k#C?gDA_9gcvCEh6!SB)~ zz$0&I%Q7EGtrh~rEH3jgOIIi_G0R622%oAoN*d`v`zKs!=O`%Rhixu3rCLed^nZ@d zf}TU?8$Ar)8<+Ql@jVYiZ3M>eJq$H02gXE~tMDa8D!In=gi%Q zw1vQ>ZjbQXvuMvivpSo2)oPbQE zif9~dtXD%2Sjx*};=Tlx2PKJELat|m;sk$E)#HX_R-CDplD3|@~K3SYhE^HAn3ip}Ol{B_xiW3O2iUVQ2*c(LK z-a+7+m{Kc1hdZjc(DvH(=(bUt6-$*N-zI)&y(D}~j3&6;PoiLwYGmVgjVR!>1In!< z&x^wJLhfU2Xp!*Y_eCJAS>cdaxz+u)RPl>PlnshhHyPs~(ALGnG2ux(SuuVs8ho(u z2h_%$n?WqUsT-}qE(+$2yvto9s*9Ssp^(K^b5Z|jA07LXl#nPPR@piI;-PD+6RoMM zc5i%93j3~n6!zn%^AEMfmW znCjhw?*uvDgI3n}AV`*iV5EBe$ss7!Yp)2-yru_&QIDNVbPi%sj~(ZuGl*q+?8_fq zj|G_?bL_|@&`9$ox|6GTub7S0t8=b?9}d$mK4vtasuHC7$6DNAymduf&lqvC1b#WQi$l0BJSJ zRZd@Rnc%ayYL_8&YnY*4ZZHx|$pH6jz4@evkGjNZy@1y%ZMD*pEwgjdT3Sg^FB9i# z8Leh4a5?7_Ta$QM-Ot;TEJvp)ccSGIS7=eDP#&xiHn>7X#MUKOYFsnH8uurcYPM>( z34uX@`qENC1Z`PCF1`l3uYm@zr3+}umM-F?3@oQW@^gOf4{v9!8lQS_Mito1X{Elk zsk#B&p1gPjMHo6ri^{9%iYJ#&p;Q)G;c#<=gDFxwaMy4+ z=#xi7a&Zu091a%<2eq5_=ZAN?LL_NDr)b|!Awv5m)%+Q;k!i9riH_Ft&2m9F>>Q~i zSqwTO45S(c3oj4`wg`SF!g=U-drYgbHLa>EGri`KOiO!DuYG)UMuusvR=t1WY|2aS z%=2!hSG6j4dW|PnO#@r65{93bf`@>D?ZhKnNpfON9Ph_E5W=g^(^__=ibhM?n zi4K$h9f-YEOwn^DyjP6DHSyo>L2SiJm-(%aj@{80`1Fk>#45K={~F5wx}oi<@w+#M zC@D>Qq|D@Hl^Ncxdl^-R=kX$C=CirV%xCp5UUg-wl$i}Rl@Cjq;lPShgmS4(oEaow z#nq5Tmm;s7ifs^Rw)Ij=r;UCIY;^<;=BTT#fGAz=Mkf{?b;c{_$i@py zqgOJum14mH+d)lD;B@82cxTfQwZ(*Q)^JBr>`v|CG+qR)6zI0OM zQ^EK*M{dHnH9!cc9(TpIQ^)d$z8OWQzPY2 z8zq-769Hakv%?6mLIg{uI^F>RM$GaAIFi7=2_X1;A%LPkKmrI{4+12Y3gf!e$}W$1 zUE(G5ha!*YVqwV8RZoL&$WO4qwx?4k^CD$6o!&-=x7V?QeqHN<=$xl0ikB$c>bL;) zy4IQlJF1#Fb$i-OPlb~Sa1}pSvYc4Ua-q6%YYl@91)j@cO6iV1W=>#5uA8ayYlhx4 zF40QnzNzo*K7*UV&PWaFv+*UojO!AqCGZS!459uf)g_iL;}b3+K_Z&BE9;VGz^Uc} z=ZnWOi}WQznfR!;59J#R8}zNUHNqQLJy?_9SyTDQ^wRheno_{fs@L4ZoP*r*QYRe5 zSb$1l|1aELUSaVDl%EV4i(F$F}@%iF<%_d=v6|I-uc z&jdaoA_?Q3L>fViBa+hgLL_B)7eoSc5rh$MqyJm7@4N9Cem!nsF;(~#7j9JeT*6N6 zfwql3XzLkJ`#p}fCa_mYSV7zQ@0qsCzwT-KQvx3lZH0DE+6ue@8TN&xGAKdaX?vq?BTQ=4b-cG~pi>=Y8+HHo9%SG* zPw>>ejKDjg?z_}Odnur+gmp#%mGl$2odViJ{yn-M%`+O>M%kY^YAzF%e^j&6d1BrK zB}QstR!_9o6_Up-3G;Ci);>;@kczu>=>T{xOUXTktq-ZVD-B}jRHwh{gB>I6G8Mis z;4-=XHzyZ1ko@Y(zoIEuup2~{ieTY4F=%)NhAaJp1y^1|Kikq0@i7I^O<{gKaeq8j zb4>xdk7#6Orr89-(*bT@Y9x&hPb9)@HmNFN>kspoa)p#)72*cmDbdyuDGTkLUH?nf>Bqwefmk(mQJan0Aw_nwd{z({6BSct2P%;4BvnXS5}kZsk|DhR;&9)&{C?B)8?3uGARYUMvb$ zTCO=?g4m)DT_{?p3%{6Csq)Y4e0!e5$diRa9WkJreeLSs@MZjyY?;6~L&;+GJK5&o z7A^2CH0MGlP_JGHQ@Y1xj18V#t^MPgwKxGi45&|YOA+23Jj-TJH{#(jk(=1ori7Ec zJKAu*Ao9F6D(Rf@5NZfe^JLX82O_KB=1OgIiI`z+jzPk3-kFB%G)5 z(BcH3oFvxXt3*6nERjWFY0ES#6&ur4%ax2~h(y7cH4lw-&1{(#(Q|}jYozM0(Zo=f zY+1q&uNkgcZ4gS=%fr*f#8N@vFw z3!Kxs*_?JiKPMz;}yBd-bvcU z-86U3fB3$UbJqQS2xlstT6_%^BLkpRtQaO~DAwDwPy33OYjj)1)T{HCs@Ec~Ud7j2 zzGBK+SJb%iLW}>!|NFS4D{3Z|t8RrCfoZT{&3__A9(J_7EE;u-?m`t zkTtd#`Q*-=&3MjmHtq}-oB%KyU`&@mRm~hB_-yz)sl}P)TvX-3WSisUwBM_FY9Qiw z+g2yRez5^``q}MnIp=9z^~-8`4=XeYQ)n`!(TOiAXsqWBBKC-FK&Gm}&&Gukat0zh zel`#xH^aETW5)JO-DfcfhqngTj{l0VD(&m{-d_*@$!0ph-d2(3*7s9U=afjit2#~W z|4j_-R=+@3+j>W)km{x~$$foT_rXz#mQFe~D@;#SL$&YVcs*7|=H-n53rCOwL^Hx$ zj@4F$w#@3i?a~>O!+sGAmm^jIjFkrC1>6iG7!ud<6PBuaC}~h6w#jP}K4|$GQ(0y$ z{5vaomQ^Gg(_g{0H&6CtF7Q431D{KPGPzbj5m*kueS-ya9C@aY!B0ZQdeIDIGY2D0 zSc^m%QiLM`o%sTX(PUX;NFADk)cy(c4{aWbxSlXs;yyx3E@7Dd_D+<`MHHE~#lB0e zR4<}j8xcjmtjaaZ=juU}FOds@#?TO5jP=buqGc;lp6?Ncj`eXhbaMbMw3-8u!~10Y z3jj>5KyA5%t_?3e!7y9pott)XDAhcZMz*%Mya0u1Bz-@5RNGn3cSQNZ{^iW7sZp;g@CXu{{NhUa=lVuRo3P3ardN%ya{Dj9#Z=D#dsb z_a^fV7)`5+9txUQ0@zIEzaYTNr9DmN>m!qSjAqy!Oc0_EsOCA7xuW-Ov^dP0%ur>4kh)&NEiBVZvH|&CqHuj%u7K)hSg6a* zW*S^O064Op-BT$t#vl}AEbBqW*(Z834s>L!cn4&BY@#P)CxLyFQHH3!kWtYeAQ=U& z7a4`2$aub*mr;IT_Pvm?6Z*f6j9rlNS;%PeBDl63I3nYB;ZKIKi4OSp=W|VsF#X<` zo>}(+GqMw4&X!k)9EIcp*HHM>@ycD_GJ*E;-J(4Zs_-K3rPgqFnG+Jz$PivLOdsAo z60t0uDZIiWV<`=F>OYbCb36#|_T`r-YqifRDM!{pJ+oftvn~?tQlmbSNzK=wn?Wke z#tHK3^Ukj9E+twfXza$1HorkV8e{r4N6=R_0tSk`MuS(4kk&P~?Nk%pD?9m0w!mT% zIDh$E1FiWrZAGL$8w_2!gEWGhXiWvdVCeEL z`&sO$8e6%{)iLHPqvQzOU(>>xDzfPJR?E5)>{vsY8=Ac*7&Dy{2~uYHV#`HqE@nb( zd0iv6Sa{I%QKz1S#^`qb>C46Qt+vTsK=)Z1^d#04np=UQ7+X~aC{(mpfMp_*#8n-@ zn)9E!FC;#dn^lY~Od73ZtxFwei$*l6FRI1rz3}>THLcj1(JepJ{b3`q)L@gTy*|u* zTT^MKaP&FjG?lg$+SS+BBvaC%b!N zLZ?~A|KT3CEY+-S#EuYN)~qzKduf(a;CnY~9_*C|Tp%lUn)+<&Q^--sesyLO_wW84rk_3bsHS2v&wI+wAT?UcyA%jY=P)Cj; z_vT>1i(lwDU>%>Vph);_z!_4r`4Sy2b?{vl5l3D!uZ}R~%SaH8&uM`boo{tV^r(m+ ziqQn|&?v(5S5^Z23!!Te)D+Oqa^5qfWa%LZu`hc3(dW#ihsKV>zNRwt6gf~7Nlh^w zWsTPVh>q3#NTA(zvL>6@kYOis`}ihAo9BVSZyjr=L1c|st~rWKW>49U3bi)Ba^sw1 zh$+C4h>Pw2;S3(J@+~fnMxX`g=J5+;59z#`?K1-`#{5C0*2sCbo{yIG6?~~RyQ{Gn zGI_+7`YMOapc&a#?Y9L~7ds}~g3u`vdgruaYo-Os)G|j089tyxho{56QOzk|^RPFE z=hkdXp||7SWw^`6a9p-#3^qD+bO9^gijJ!v)#IdweXw9OwVn3g*ysYpcb?O zDI)i%Z&?eX<)YC&s$JtC&Ag5?kr!;sy>W4S${vH%T1K`>)T7HyW^<4NnL2X4w}G=P;}cyPW_x$ma7T$c7?*Ijd#W&;9-Na+Pi2pXhq*|sGedlOH57bwA~3_>b5;z)SC79 zg!ir9n8v9of8-`v!Q=TmM(!D(8g!r>b_x!{jRQCBHdYnb_14C4Xu9gTakdXwmoOmH z4~^UO zR1RDlPmRxdt+YF@m1c-i@L5lkH%E#nJ2F1*@(*)FIfw@KiwIJG00hY&dQSp(^z}8V zvv-RCoEBL^N1`Coa+46%6p~{aP*L8$`%s}Y_y%Lu$rhFK|5_p%6OBWN$0 z0S>{_4_16{&+Dzzuc}TwmRMUow5>Yz4R^Sy+R^U#=~cKYN+{N)3N||0$%2rj9ae(| zyex+n$QT-{eC4X=YVx-*S>Oh#V)6?%wp;<8_yw~I!L|r0B=&QcBX$i|To#9{Rad!Sy5*x_=@(Pdo3ODDi z{I+fWzI*ikz@>P|r#aipK`ge>Dg-OUuSm7idN zoA1W=P>`ezNkMwMTdx$PZ&rAMTt;Bu^W6avF`P3+F9j*Fw2=ETNb=^D{+R2|dpb6K&3EIDFipwkluE+dwHV27#*MctLrG~&&kgb1 zv)XY_Xe4wRlM(A}14pktn^}MNXZFiIU3=jk1V~Epk&69ZHKu(H9>MO#LGoA?cchl? z@Q8CDm*ZLC3lL1Zr}&F19oy@_Mg9IE_PPnD0NM!Uj2xEE)xr4tauyi5Vx!&`7}Z1X zOSF#MG%j_z6B%fVy+sB}lKO2ga-%-8x`$aDM%&Ke;jl2(X;!T&itU@66(jga6=e1G3B+4ZtPp)zrDrbGqDlZ5v;k z)okxX2ZwjyFDqjr{<3}@Nx2=A3%_-^@n#;t!mkr%3e*fn-I~vOd-J~eapm5tH*Xh7 z^xd2WD6BD(ogLdi2XtrG$$K5il@3sOp)4N6Siu0A9Fuz4kS^$F}=LnFC#2beOi z#Co7Fo&x;`U=g9es#}@xPB8mNYM@bJD`eDi)1RHNMdg&g$|vd5 z5g?TnsuHJ@qU9%C0glW$BRpB$oO4&1r-vw@p=Cd*(fkAp{`Riv(N*T@v4z09qDRj~ zc^Qc8Yf&yF-Rde!l>)96?@5%WlD6{#Q3Oj1^R4@!j338ZUOhS3O*fkdWv81BF0A1b z-c2~;mb=4yjr7o4u0Q}7e>uHnjpPn(=q7Kl;NA1rl*2teClYv9^xPMJ36J;8Un;y0 zDl+WA5&p{S!C#X;8I3nmq4WwzkD~X;Ux%|svT6Dd0`H0*J^4#Kv@iY=lJAJWl+h2m zf5Tsz8^m98KH>Ol=3!a>x{RD%Ub(a51HFVg^c`q2lg`rSk@G>Vb_DXURxpEnam`zlgU7qY7&6zIUS^Uf~w9&vgFV=B+S6_o;?GmEQvGy3~ znz8dtA=Ww8)}^LjgZ0_pCzsiI319g<*l2fBO{2Zx(?sA}OM@`#*o88-Q#z@DyOr4) z_B)7ol8Y=+n{bQ$Cq%PdpmBLKmSyQPpAqA}pn_;bDKqE0W&v=y;VnZ`C+RPs2wS$2L&t<0v;kKUGFG?JTDER3z+I+vkX&qa z3th*I^$bX2R+g!S&I&_Ai`?SS$g)PEb#2{yU5h~U9n|wE^*9I2ykNo9!^9{iqH<3GL=KoM zHLRTjrU_~%H%xMBn1=uRSuaQRMfJ9&+^CdAq!6)p|I}rc+Y8l;BN(e440G!+7)}FR%b_5~X%P8eI+xpTS&fb? zWEaZL>%cPATZ4s{C=}Ki2usQF{5?Jg#D1yr^&G0mR2{xG!l5hR4&99dg<+N|a#9Wd z?6axwUABiIL~^kPhX?~FwsL#d7-VLgC@7@f@8$R?KP8a&&X1k++uOYMGR}``PjGF$ zQQO)Qu8kS@6rSAQgx2!;Hf(XiBPRpDOPqCyi(|jpO^rd*ZHG#q(_Sz`InV2JJyr}~ zIM}Im(ROf=>2v#AkUw#dSAsVY*x!PjmhE*xPW*?qAP4r_7UZ(xvoeTf)LHHBoqUj2 zXPt#+jqs-51{(VBe&zYqQcsjg1m4HWpb-T2wK5R*y`z{hO7+G*!pS;G)2- z3?_XnyE2$S*lh{JJ7u1DJ$Pp~JZZ)pzcXB6#M>Y5>Y7Ij++MdvQ!B zSnwcHG`lsNeLvRi56@&cLUOA_vu`|Wgd?338`-{QC@ysH)-%8)K z*H1efa#QpzcT~Ucy)FEiw#VgQsuujvK4|F**8-c=tp&4kT0reKb7t`Bu-ub&sP5y# zx(JA(1@(j|V!nf#T`hhp2dc-*6c$a8(i!mWbo<7W%tLLs!>egcC*7JqL%u8K@y1;8 zY;f&LG$c)O#Fm65nt_fohaysWJnJ_QfRr(J7b&H|oPL=W?Kl06C#)OCBrLJiE|yec zEA^yj{n~4}J?>MHbJaapr_+PEU*GFjcH4O*`F8^HIZf5(qLKlQZwr!{>kzrno6A7{*_M*Z{r%yEzKq*q?!_AYsK=VyF~ zs(K9k64+V-Z?T&+TH-e1*Qx(Gs-ZVLQm6V88y(S!jcaJ4jqcgfx8D1S4X;Y!3d5Z@ z{-UGIsSWVj&%uqF%5}526>5ETd?x6T0?NV<7jtP+``v z`KKMUzD1f$yfmHAgQ%-N;)&{{X-oY(AnLVfX-3p*q^|9gs8t}i-}4(E0#Q|GuhSgD zS46!ZZEWwl;lCkjmqsCjX1Qke;M()pEfi6I)6Ybgo!`V>7vma#04>uZ^OHA zOF?m-B2i)OV2B(qSL$FZnQVqrVpy!d3G-dQR$BGm#(zkvpNaQuDu5C6`c1IL9JmsYT?Z#xr`=_>#kHw5zS9Ohrzk2;|w}sx%djl85&w>4>E4 z4#4aGdQFE8B)CBNFV_}VlH=@rm2*@ zJ2!tEWdfF(?JC`%X&fo!H>OqV)jOmP`O*PmwhLO8z!l#_2XM9+SomJI+9@^L4Doha zx~CNgQ-+MXy~?ouno$ zExQlr@~E|73lp;46vy-#lpeEr#$Q+@d*cqZIpa=bB=4ruIp;uC$x~=Ng&#BS*q!m5 z)W)uJ4Hdjh1!mWg%coX|R1+}w2c^ety!r|7$oMcncrdH-)aj_5i`971mS=@dO?~&; ztQAYGb}jCv#X9%x4>)hjHZ@rApFkqn+ZwHfoaN>YZUbBKpzT8UpBuF-i1pW*@r|^0 z!`08xGUJr2MbRHPa)+By`9{E%YMr+qJr%Amh^$6eYrj0_aI*|YIft7mC5sV9nc;03 z1KZQicVNyLpv_R0@NRs%GtS{bR+-F3?j&_o*;ZmW;QXE|`>#($wj&PjPU8as@7T$1 zkl3$z#GeNea^Y2F(iLg8zQEJe!$zgllS0Hhup14JV61j9Oc^v7{c~XK*FqB6ji8;g z8$HgBq6|XI0Li$7%Q)A3R9R07o9XCQpL0oW&KKE*aMmNpbFa2~dRUKoo^4i1f3{iG z;m6*?esm@knEhz9vmd$B&6QT|JG37a8;IWaqn+#$MikyJbt3zbsAKk{yR2j{>fEo* z!5scG6Vi`-&K}gcTALz^r#UN<4modfcfi|Q1wAwcMndNJtUu%|`OwM~yf@3~8$CM6 z9dvGFo^k3u2b9OsC{QkZCf_DV6T3mvFc-U~1EDJ+Sw=6AYw-v-x!VcBVBR&nWR;%8 zWd(XK$_tF_K7^bxwe4@NR9=(k#$2&=dfm%(uqy&sI~bsQBji-l%ye%}vRl_>Kre77 zDek%Yc`sekUq|=PsgZRSQ1(~fVK4P4P!;8uSNz`ESNcdM|9ffQ5C4%VKC(5kbMLQx zQ&^hhAe3p}zUX%dOP6<(f7w&-F8_H?X7U^U@cFyxpS-{JC_a!bcg2VI>R)?O!}TwB zgIt}CI`}3n%Ch{?^)BoG>SLMWIrOKiGrPFG__1_rroemY?|ba=zRU>7^5eevYt}>W ztG-Y3PH7H#mSxD(o4)oy{M*M*-_1SB@4J8YQNBa31ZGFP$9F&UUB^3%(lz$B*%d6P z&bI+P>exc5dNF_I%k4m+UTjXk$SZy%*d8Ijb|(_!cGWZxXD)g%n78{G%dz}cVo1qs zXDUbfX_shIu!>11PtRt^0m~*HmC!_!-p;r}g={3O&BBFe^PM#^+=20fB8w-GOc7fz zrOyM-#fyj@)r|;66x*q2RU@I9UWeZ!iJ7`3_LXSWeQTQ~W&rv`)5+7PJePa6Jbe`+ z3}UQh(@kZ=Q(tF+;7|d%&be`TJbDmH*@4q193ydsVJDGetO;6#^eA9b0D!@%vMX^AeBeob%s| z!+Nw}Xny#gmT4K8q7}yPNzdNYp8gW+3qQa3WsVUfRZ>ft>>?0XOt-|@w&S%u>EVFQ zrQ1O{D8=+TWIhq}h~bsK-Xp1=h=|bjT9ycI5@fIqj{XkT=*R2fd9D2s&1yt zGr`>7YbO39e^VqqN0E%f-i{f2Dn}psGy?tfvvXMYHRDGh@we&B%oq~3Me8GU-$A5 zM0twj|NWksyN@KGwf_2-&xh>XGw(BV&YU@O=FCNVcZ%Lh9Daiudm+}CS%U>Pd{F1y z7eQGeDwYVf7O>%L-8uJkG)B8e<>h#~*M&!JEw{l*26a{WY;IP@zV;b(&fV}iJaa=~ z1sC0-vw{{tymJSQ5%AO9iih1aofYd7N2w!PI@*00LrT5Ky%;&`c^hL%i=3zDAxq`1 z$)^Uba>`|SfZLg!;H_n`r#QOQ8xSYF`u*xD?^$s=d*D6TqmQ8+r}iG!Lz4hSVO1Dx zC|)5FLtf({bp=vUIm_o87iXiuY&Z?dL#pz1`RnvP8Kp2E25(UTi%~ZiG0{dU(QnZh z{2H@1wPA%1)gcM(iXZus6EHp>InnGr0)0Eck!o~>Qh#+yQFt-52j9= z0Wef;*oL_SN8W2OjJPBU)G`!`)5q*`I+BfKWyod8zPLu(hIW~>>d$bU$*xzt^AIj& zpFzK&^%^+?s9)4eio&y@t&?}DsIn>C z6L@I6YDz{qP;yTRKA`THEd4F=+VHsf~Mt4Zr?pmsNcuOASqOK zTmhll>5ea)4*?yyN0%BSuQXPc6?5(ie@kQx1e8X$ z2TK+RU^XhZcS1na#9-eK*#u!(mDek{tX~Z(OuDg`s&FqL%YIRXNw)UWDm+FLDFl&g=smhmPXFDk)4Sol{whY!p!l13o;3fr2ZWCZC-!0JcABuho%k z3(bL70T6`9M*UbQAi@>qf|h)yz>V

    ^TRRjmbf$l|?25ud^Tx5{m0$BXJT2o=c>o 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

    D>adVJjTqfc-LBupv_ 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�rNg$4v2bBEsLH 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�eVnL8SgyEtaWIkHyfN!q<^C<$@Ils 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%0A( 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

    Hbht0LOpi9Jo=MH`g)K!thm1N>6c72V}u5f~B zHKVLa_82oM_>~nFCWcL!=n|&})7le(`{293)joy1$V5an>gFU(AiE|ic)G7zW`%{S zUOuxVvRMA$_hd=^5D_IQUu6&@U7trU$4xzp;V)Zt_RCiQeXXodSp z<-t3K5l)Xf7@=Ki3+WeL5c5BY#owA3^S8(RSFcR32{FH{2+>ebsoj*1c^+k;O$6=2n`|EhwjevX~^sI=?hgaCH}!K%tN`>E+yX4HM3r9 zV!gmUwG$Gb(G7v>dTx^xI_Fgnx@x|TlQvTeTcy$*J(_U*)>L|ksAHt5^drK1`Tv;z zPp~fBF!||$TM)=rCT=Rq^XB$|LYDc}MLk;wg#0c}fuI@{@#aXd?wj17_`Kco{BA71 zGCP=`&v}!Q7rnVJP!D8e2an1`(IysmOo<=>_-ej)hU9yL7ff?5o3{tY2zGeP{4I(1 zPq)OWB*LH!TpN7)Et7Ebq6)0mp*@L8Ru`25We#fvd--1PSMW}!bAmS^P*H#62W9>a z5GE(S71udCqjN^K5z+8w4!+B`;Z}0=4ichsF8+j+JxU2WS;WYX>?PN|?6sH9?&V|k zZC(*`wTvVGJ@JtlGY=uUVkJEs$(#iOa;)SD6WagbD_ksDw+kV?SGP^D1gt#{`YM{7 zk{zqs2%K}+dhJ)h53K+&Y9&>o+<2S98J=kaqsdWB2nH!UjDxDGEtb7!zVlZO=H%Q? znPWbP=iCM_xn}bAvJyBzoabhh4XqYNbtaeqx8O|6WOMi|n*!h*d|PTAUD7(Cs84XN z>3FCmD09)l2_lNr8pkG%BbvK0^sotJFoT6o}W8XX*o7BtSa{g~ZFN zyBgI{Z00J>hHqaQoe;e=dRg@HmFSyb{8HT@=V^JAnwT78r;#wo+hoU)rVWX|nJs=d z=C2ce<7Oc@mi@fZTdubTv-@zP+76ETPTqmFqVWL@TgkFX;P>}9^Uh?Um$vWpW-rzX zlI+(1FDM?;CySa(d(b@QjTCD z^V6~TugcEEM$)mlUhNT?*g_ZkFxZlX!&a~MaRTN3d*vJv(j^rA8luVTKE@xF^D`>1 zRN)OiHJ5-O>qjSZZWp(R|IlL*=tGZnh6u{XR{h%29VMtkuEK<23;&mN=8?!l8 z_~T7^iqNZGa@@ zR<#y&e*E-X^+9%{&A;l)u?zSQN!;qD!1~As!n_|5&;CC>d zHUp8zcAS8X1+X|e#Ax#XwZ(s!M6dQzP4uxvJ;Y|e7*6_!p+#AUR!6U4PVG1B92gzh z5Z}X?|A{>Qnt|)%Lut1gaCwaxxGVmXoa|EXZhWTNcyrIHMdoE98ScU`GCvc^Xn#nF z`aF_}WUx1ek%eKT^Gnv?)vl$9Wl-=Q46@&tyaBId(TrEJwNWFzcqMBnOZI$>tXZK~ zvYLxE@c0+I%?@g_IyCGX)or)n4eFi(G|!=QV$4_cofLgm@}%1hq$>TZFPwZWfBK!Y!RbY}3M z(TffKY8M?mXqyYD>;Z#c2OF14P(~dFqcP~vKxFYLU8gPrO60s;!nXWa)t`8E9=Tg@ zb!2>RaIbL=GK+jUSaT=~`|8vPGGx%GZYwII)Ojp^s^NWPBlnXb; zQ4U8kWbPj;l<3x0r+>BpgQUiUYo6giM^0EcY?j zi{!3^=hEhP+RZkPV^z<@Z%SsdmKP=_pBGK!-(I(Nas~UMoR%BUnp`??ZR^qZ{D33h)vL&^Fkk!~a?<#gN{VR*|uE$<7GNGskzugY)B>)w_ zN_cEh1Y0x|-($HE>vAs27}u@#D2Z^#OANbt%HfGFOntes?!w6^DDukr?$RVvM8R(C z$Dgw)+%@}WU_@zU;?G5k2vjC+FOoc?GI4KFJeOB{s`JFJ5UL0pRXA!k#H^tix6xm>M_)BFXtCzbwcSj#~% z|E8kiO1>&(>s?kfWR(9*WmV}lhylysoBMFGwv+#!Kd6X9pRvwUCW>)N7OtkB95y`x zN9y^rVic1%aM!5pAm&#VMJjzR4Pm|ofp$#Hyy8ktKhf+y3=UOPvhI||62NVKJ>|p_ zC&v;am}t3o{aDjRJX9=kmS#t>HY`I(1(k9aU9Z%aOkJVW7_)5zXq5YmaIEg9nS|0I z`m9F`tHTzR-z@sUTw0qxl}^GYOHe#|-a=}OvW!&vZa@dFhkxy(G^X5ZFyD2eMId%- zVOqYAY__sw8=h=PfYs@qwQq8(4G-&#oE=0eF9hMnJCM6f-5gLAUPP))FU+>p zoAq1qyHIla*%GHp*w^B9vCbnW5;w>n;t%2TXK(COJzquVpRcSvxRSR3RDL2c=qM`q zN_JBT0+oWV;9QT{h&lE&fL;yIIQCPS>^Un2($>>Ru7qtGSf3t$?wg5QnZ^dIIL-lA zBnNTEYTRKIci7|?C4N>H>v~ac8r2gyMRoPw-1~tCK`9=(9e1>8M+UDgly%NuixyLv zDqX@8@V(7W!n7!_+(UW@N{)RNucNP@a(hw{`PgAIVDS0Em%Lb_ut<&L2E{^Va`7t= zojGC%@CE>6d;NlvDw7jdXH{0^yQ>1sg!y=Y^_Dj~%8rF;|9nMNSsj51uW~!)aBqCk zQxsW%SEX^U+;EZ|r`0^CWtVTMtm-+_PXKg(iKEbSOq2dn}9Vc*^|>;ftvDqSk#0F zJsH1^sQ#~Be+y*1Sk+$k9QA{4ix8dw+op~_pfr8;f_iO5b{NO!!*R56oA9@as}>)f}Ddd6RDbFVz{>jJ|Q>gFRzlMA>aeIwF0t1^rlPbCh(3!LodX*{i4{-eH zRSM8R;L=M}>JoVA^jewvnYt$?0v+7gqA_J~12M4#rQ!$r#QeYSYXKr88?_e~Fh*QK zOcGp}EAph|)zXR>qatD|BJ*{Om>#k*<)JI5c*d+eE5#K6FOhl!DgQrL2E2tUz{*lv z+Dn;DDVd(-(#`omEptBzpLH8>I15@cT!&4k?kSA-n@3K9G--C_UING2JhGa_h}VMA zk>-&%G1Ib|XV2jGN*8-^kLKC)3BrDmFo$3L@pZ4;-J;s}g@*HIJMaelhHK`KoWKEaB9+-_Ozqx3+)K{W=H~Eg7kaba^R1-|xfEwZ)1Xz|Rzb zSulMJKcmO-bMX~w$CcFIJo|Q4!XMF>4>A52RS9EoYI}cseU0KX{f+e9GFq?JWy(2m z72B7NU5^azWF>cOVDXX4lZFRh4O_<6sv}$qE|0VWp}q43-|rFjJXR;8fNRyeDfBMV z>os;!Jo`?dIci7kSL`|XR<3I%({%Oz;ynEb1eb#j1>YAOt`!`n0Efu15-Xx$`W4lu zX#<8b{oIK=z4MR_^{>BiAS+w9-PXBuSM~$fX!x*IJyy=Apl-487>ID6QgMTLZdICJ z6ui%-T62rnNPbc45_UGy53vzNA$374(Iw`;Z>K`LdbM4(!o;UdWLxwxqk$avnuCPK zEa7QMafSb^Nt;VQe3KmV~KMndbQ2^7>Q2p3Ie+564B&qh$f$PqRH!Uo;$;` zycbLUuR^8XZJgfU!2>nHZm;$Z8Y1z;tR#Wt_0lb%+Qsu^tl^DZYybP+wfP17ltD-f z^7$`|aA9U+A2isLUyW7$yclP*BcKWO%Vc{6vNi zP>7$%aE*C6Kat_33h@&e9#e>)$nY@=@e>(7P9c6G!>{nmCnbhg>z!bAV)#_Qd}?C& zO@8@JiMZf}Z8N`#xaKR@KwDU|+pp7a!kpLpbwZd#T=!Aq3jHyKiSr`U8RwZ>vOx9>z*`J7v~huQm&=FP4}-QJO7e2)RLT6HOvcsY5i6 z6i~+TvG~ox;|~=4C-Hdd&Jd4fMLP;Smekkqco~8JKjZPy;PEy*<7e;~|7gS0_*J|uzBSPH*A#p^gTOcHk2z3jD#1Wxxfsi;N)GZJa zM})csLgI)}w?If70cnR%N|XzKhZC$$luz}CPfe8HW)8%Ns|osTSr zD}Q&`{?&_|-xf<=0_WWSiJ1T5l)R@RP$BJ;l5qB2P_Q> z1eSTN4`H_=Id30WUdFGo-_~^hUZoLo4KPWkXZw>(1?#5BuA^njFxMot5k4G#oa)l; zwA=WUZX7zxopQ0kw=Aju(EcWqxL*fTU$r)T2;@3fCMTj>URkm3lh&My_}j?D-pbR~ zIOnaa(N4XC#9IRLU%m4t)?#muzijfBSp4lgm78A_^IMf0Crte$7lZ=&?1l?QWnGQ6 z+DD!BT@~NOxcXq+CDYsGm{-m3sGt7?{k%N7cF@Sz7Of!yrTj=ha(mGZ20C%^)R_P0 zqKO3k+9KVto)}r}Z*Z3z{JQ8$B8Z2VApRyox{}P_#BBiFci;}y_v7({db{?Z5k|(p zc&b-B{#^2pn3x=6>VR40-C20svX9<^+FQ^1IZpDpyM=p#!$Rrk_wo`pM+yEg(p+1V zPh<5*-|sEjN`SaUVI0AG3DO#pBj4+xM)E?|Yl^OL(_6*#A>U&1&9HnFBLS#B7_fK- z+`Y)m14RSehxZnVDCnyp%28}-L+H8Hzc5TIC9Urucp6LYk^XcC$&=ZEMNaGkKWJ%+ zikUcmM!kX8Y%PhgFE~T2%K5EA#*R<3wJLJdyB?hGH0gC)dMk+89u^uj5q8=t@2)rtNNJZ5uHIufM zX*ad<0Edg)4p$95UnD#EUk)y4ebcOHDGa90yS=t(Jdnj&T448WJDo;BDNjU zb&jK|seS2CUL%PhWBF_9@yg!TbC zo7~D1VYE~RG6`OSQ>+k4+}jOgMNitCeeK`V7CSoA&{cU+d+>E1%}xmjdb%P-Y z=qbE9-#}!mB%kU*zVori@3^56&aUxhAQh7axgd*I9*z zSHSrO

    P(1ZEoA$`dcjAB%|aW%HXoLzLsVzxVW!{ALTq7yONVf~ zi)@rw!)&UN+uptfKhq#viR;DMpi9!K`<%N7Yn|W0tpt(WCAR2cr85=g%wHBmMyYnr z;6z0cf8wPVSSzJPH$DEz3e$P|dpp!h{q5)+@Afx@^yGXCS}~I&V7f3dv`%uu2~oRt z>sTI@08v|(KP28_f=`jsX9L4l^*#>aaOQE6tkpOQP6fm-L2*$IN6Idhg~KU0 zznuQyuw^qYh->bVB-E+fiz5}h^F-@oy%;$m71_BGh1WW zi0rovGpOQ+HJ@lL^9qfSWAJ_C2m^}IVC;_jQ&Ky31WcH zfPxTmrrKF4MUF8aFgZ|6BJt<}D#L*1{#e=*bXlW1T>DxKR~$f%09 zD^P)^=L@x0RI{zD+PN%J?bMB}bWV3F^G?5|G8y+(o`2O!e;7hJ$7=jCarGMNz+7TsN}R=%%|mV zAzQQk2~9XU=1T~NHFAU1^bt*j0GDeMi_x8b@ojiHkZe*J}LnDcm-tC_<4k?$Om> zr=@S`9!MhB{I|_@=JUk+5II_BHMNinA~pE?ywTE*%KcRC<(6G8wf!2z0QwHVv|cp) zxeR2Ys&&ALDVNXbn%K6l4Oor+QSxc-T8+z3GO0Xk)z2xMXFhA?{8LRTmqrZkZbag3 z+{6<>fd3acwteCperED>xitP;t>p>i4(0w~hmm!+vTcbk9#<$C?42K-ap+wWL?&c5 zCbu2QwRa5LyR>@??Xsp2)X#*iJoGM}eZ&i}pA8S&z&Qr7y`J7LanNH~t>#mJVZ`}f zm%tl`z{B0d$1RIG7i;|4KGQ{WzL0S)-&160Bxi>m6Jv6q_H?P+@D4x1+KIaD4(r~v zW@F8mPtr+I?GgsPhb<9uu-Mgs6lSS9+Q7Jkt;?bA#)c7gX3nK-B8*Kh6`_}75Prxp zXHEe-U1G_ywbsf}pt=j_gC%NnpE_6|46Q0pUD+rC1=BCg%Tl%S<9Nn`%q+tMXmV7QLh@IR_f}EUhE|of}=<3r9<`6=rY#uo`!By2( zCoc*>=@%*+n6x?niub=gZhyr3LaS{)qUijMrox#lw1J`(%ha^t5{KsTf72QkWDe6k z<_|gF;lILKH5=ruIA*PU6?9hM$M~*c$0jFB?nH$Bk`G(%L!F;*0S7wleIPA?^UVBs z2QBP+K0su}?T~YF9?(tvi;$UsA7unEc#*B?rMf@;13rJ9hRO80egS63pK3yf4*Ew2 zYk%Ib!Poha$oAcchk}P8-9Ip-I~gNj7%IeP^}|+-@{cn9aq%J0>sMm-3%%&|&RCpX zp6)iwPkP%dua6{0ypOcPHcQ-9k~nrg+5N`VEhu72sI$3*Nc|eXN1Mz5vP?oT(2tB9 zd>#rkYxy5I=SSK+)+6=VpDE*CMxSn|XB1DSge-yScEt6ojsMWlDk@P&b~6(o zO;|tw4h0|i`htg}ZLjBP;0`3rF3K|~u7Z1G{%q46qF0^wdF#u9WnT7H_D-HbF(ZA8 zUa5Nt)MwM=%mUH>sq_uHcHGtCPJvKhgRZ3p$SSQWR^hwSLy|I zbdH;h840?pB?%m8%`Qv8)pD+ub|KDBcD?575nYrjaI#F#ObePj)SYJ+JR(T`N@Pi{ zpIU#3Juh8xs{mqbv`Ns9M#|1esV-c1FZi0Llx|gi<;`96LLD3ArsKG9q2~E8!7rs= zz5;E6Ion_W%GQ6^mubWZHAy>P*oQiwXW8~vI(PTt2G;qsM!!{irOORm93cYJ3L-Gw z!u{CF^Gj~A8b3vNyGkM+h<}<>X@3B}05d?0j`*G`r|cJ6bmzbkd|)kmk9x!mRO7a# z&ceC`hCd?)X6`dYGUv(~;%k9wj`?;G8=D>h9mWcxue=77siy9bn7j+s| zR=X6Yi76$VwY{-Y{P*j0Ip%y%Olip8dTy)7jSk?R!;P$!r$R$w@ttOHV)iSzD@c6J ziR2l!W=gW~Zrw%?y%_T0KRxc$smYQTRM%{?a-K=ek}zrv-Q`Rmpd0X??2)&TFrwu< z4S7Rab)vo}Ts~B?8|DH{B|zr$7`xM?I@M`74Fnx-SX&TnX!CP)Qr#~#BWr|Hvkjj^ zmN2I!av-afIF0FUSUhb?n}MN} z#H}eQE%siS>2b!eUoR*!qAAd2Mv8LMR?`7+85m$on3?}Whz(CK5Fr2_H-aMl({hV5 zlAfV^iy;f5Az}<$4NY~yNaM`ZH*;Wzp~vpj$5gS;#itQpbc>fMe_i@b9-8r@!nOtY zIhiJCC@xsEye{F5jw#j}xz}28xAG_M;Fm1zR?}h+)i*5Zh3Xg3*6R3Ws8p^cM9QU{ z^Lklef*rowC83{DSF`>~A?KDdLvX11Ag64A$Gd80Mj1k+4=nsq8GeX`HfU1b>4Q|* zg!5+=!P2fO!m#>swWtf8iS8!A-&ps)Y%QzfjlPG@ylDC}iG}^e{gV(oUMy&M)ss2` zT7A%EG7cvcJ8of8WN~w3h2>m@4laEqKQ3QU>D-lVcjzE=(kkCud$DPE6da9kZ1#W& zd4+@YWbB0V3kmb~t`6JzCSl%av)$PfvCg`;(^|HTm!{P?AG@Ov7>=%D*4!st(rDr< z&y{yBHL0yUl1mqiY0@pLaf5A+l;q&&zmQB;h7f=VEhZA57) zrIdGsbD3hbnZ^Z2z3hz#oPxXP?4-BB>}9IonxE|;huGES5tZgNJ91x(qEy+L$FEicXo@pE4ROV-%4n|DHa@gOkH)qyGLv^YU(ez|Hw$Oq&)Z3 z-MYF|BcR=adreQKw}UJ2&4t{IXHirb3SzZzO;679Y8d1;ni{A##okNRx%K7>^<^1w zONxbvDhs~%t*j8ze3*rwdd_~i(a4t-?pfJL}x+$xf zT%|srZ}3V5FWuBzS!xE<=<)f>;q%{s&wmp>AN;;2u%0hkr9YvwGY!nFBtG{f0|Eno z(NSma#@nQzFqp%9Xnh{tm|dUGGNr5v&>atg+nGOQF<}RA$|@Z4D|Xy+P`F@k;=DS* z__HF}x<6710U;$-<4V>CfiurEWLsHdN**N~O9H?FYl(3gxVH50qYhOJFzLwipU#uVf_tl^uc>wzEq8lIQAdA%hk7xJC(&?HLqjYzU zaYZOtc%z{P_PG7*WC?p$&Wy&xxPf?w0yDFhX&Swwniy(!WUWP&H|e@EZJ-gZwYPH% zz!aQ9^?mI)%MqrGI!4BsLpPZHwbv7)jAnkz-QD1)FWv9-gr9;9aEUBkrGCroB%D*U zo2^UK&%kfx8v#G~O&!5+zGrrl?#qUj4V=+3OJ9?a(O9Qi&||Z-U=jvFjeCZGA#M9r zM%QYT<5ITEU{&XhJ~L&ZP|8%zW;G=LxyI?Y!C zfs69x2-Oc~&0`ya(%=bQ!z9Bex)d3V>Q?hFP2z$1?-;Jkfkw^IB4Y|nIK^C(QXj2y zThzIlE{nH#o-%0U#WX#bS0M^?zHXS8%E^93wD0vve+-xwOChL{tBnE>n< zpESxRov~W~4ImlV{m1p5wHyA7p^A80WD9zggS(@O69J*%$N2x0A3;6~ys}&-1#V90 z3rRvi>meEG1V;~spCe_X7lg&Y5M8Gqf`t=n2m72@li`kW4_1EpJFXXrqQrFTdbBo( z4>KX_t(H@@rrhDOejGz#q7^}lp35RkM@$FsX<7%9axde<)FZ2Vlff${7TjVGBd%fv zBQc9Xtkb`LosUnPV>a=4YSTgC61c##syIZnU*TDv$?`X&&EN&cm~S;g)Q@3m*{B|% zQuZh_T+Ta393r17R0L*(3bxRenRPrCW6p^Q9WX$w{mKrE0Xk@X83&xF-6DJ+@#v$5 z-cLXDO?9std=JDBr8t(INCyWc0<=1ybGtPexz1sQRLGItM|G|pZ6oT_Z0COFz7BY2 zt$=^BWVu86Vc@3jmeXCjPF|C8&kDv$Qq8U&MXR`6W;sg^&zaMD{z6#JybZhe7W&+x z1a#8;fwy_?bFcgLngdX@WW`X;=il;?k&#+=u-d!d&Ui9n6?~9t*u|bf73PJ(hHF=7Kd2MOYE_@ zhZTR!J^ZG}mJymAFj4JI6^f@9c?>s6&GdWp&EN3p<3#wa*>7Rf_L;37$eyn^*vIe7aH>5 zC5ZB8#*5+(;u3WJz5l!7eo=evPJN6*~_~1>%EQv7vdx zd#W;2@ba}Ffl>1o=rN;4Tz0!|3i+0L?94~LTe$2$A@t_;v#-yD#{J1&zI=KAz1;pC~62WTSjbE)7S!z;liB19bac4`I5KG!C*^UoZAgSTlxtVIpl>s=6WmdtU# zzfDTe$ZSb2v%y(`pyPsi=2$YTvk;OCb) z<8n{Jt|Iu&4h7QoypJj@SR) z#;%L&m?wWE>hmT!MYob&KIckC28XrS%vR1T0w#cJ1{7Y`Wla5@R7s`b1C6-UZZ`sg z6Kvsy?XvOK4gH5%6746HLecEr%U_{_5x2qChzq`*atLZigqq2)W-u(CAi2gg@Gt^oJ;$|_Fm($qLMEB7%XM!2-sbXiYwFS`Td(etv8yU?uAt33WaG~;RTEShi`x{ zN`fQgnK4JmqhJsw1&*Kp2JIZ&)tL(sN;e;PGjog4#5YzpV~@q5-8qAd#-`twloBV{ zUk{XPhHj3SLpLu-k9?m8@)SDeR8F%j)A+{I?aJi#{INbkWM%f1$`e-=SO_8;is2@~ypcdc=9j@dQU#0s)f`_KmK00l|kUnlAN zIzLVHfAR`xC85c-n7zlCS=!$$hy^+%|6*!nDJ(^Gusarhw{bV>XdwtjIG$*a+HbZW zKCS(o5oC-Vg`ZKyyUBw?7F_-W2$L`4#YZ4`k9A!C?gvHG*wd zUwDz|3w^h~*qiDL$&W9gDU4{PJJ#s2SGuG0t&B%=$GFd$Ywhkr13++w(9fCLuK_>+ zIczC;71jSNy~OSJv%xNgCl9jcSO91GnJ{irB4R(AjvX>Nuxrt=k@wEIZgv#*nQ$Hy zcd}BS;xj$|kP^h+jd_X4R(G`>*G-|ox@%>sts_{5&xqp1a|vIXPkALYswG|tXCG~4 zoT+u%Zh=_KUuV41QOIBPLXi73Vu!_OMSDs7NvziAuvk{Lt>DN+5=kHwY=`p%_eAVb zOSOdyuW5QiDzvt$w#OJh>09N}A2s{S7GjB=KUJII;Cd^nI3ee>Ntg(>qf9>`&dw0o zrp7M2)30b`dK~qD zPZ=B@jFY(sH=sqQ+NweJY9KwHH6~QeX0Ld>c6`;{D)AAj-l`HGp=wr;;_-ZhsxvC_ z5voSSgi=&GpwfX@xSf4y{XUzRmv?>2F6qZHiHq17_64U4G8fWpG zTIY`*Ht%Co7kQMX@|0@|B{=V7?FYcWJkxolnBe3>Ow69}VEe{rG80sbTHw3ug&}U+ojx9Y@g}ui9=`agSWE! z9%4gLzRtsAQgY<~Tns#7uS}$i*3ePa6YRjwy*SVQz}S)TbNdG4uv#wRbLj_=*DxAlgH{cyjM`U9%bzwh zFa7mEK_Rd=8hQ3ZIc$V+9l2ED>NzeE0#PzZ)Nm z*S87%y)$eCM((tCdu%MwL8Qovj^trj*o`0wEbI>iq-Fhoz_2jrL*zvKd=N_-MYD7X zT#5X6p{Vc_tx{X9+g<`NR`V8t$LLd96ugXg3mRY_)g)`LPO%~^P&M^8;dogQO)tRZ zhQw*u7{uDvJh^QmPV>FswLRgg+U7QBOFY49E?^($NxF%vM9;pYd;QfSYGmH=>4tF# zG84+VmH9avHg}^eeGFXvD>hvXMd)9#>1s&*D>hvXsei?$tDy+}D>hvXsei?$tJ)D2 z50O~m+o>X*riY?-XS#d^n;mE*mb|%K*;&Fbsti%X1Ig^!+J8=Agg!q| z#NOYs^>p*0MQR=CS`2TIalI-S!&mFL6KlWZG6+%jEn4EJr*E58;X;^mTf% z&kUbuVNbnC)owns=GDJ-!F7>76kTm78cH@44K+vdONvC;k@HK6NcfljIxZA9;A*zB zkDD1DW>EC?^ukc|{JP`wAZSwLVbBMRhJwXET5hLp(QXbSvjlAX=(>=Y7W1@sCb-RN z`3#T|I=%sm@ErrwK$HO%oJkv+3O7uZIeIinl!x%vUlbn)EYI$*(FXR)Up^UJ&-$iz zze&45aE*yn+^t!t|2kyw8O0}#+FyqZN`7TJ@dxfn{xwqVtITm`{Hy^fl|Ie(K)F&* znaMUGUH18G_N?uepBM(0JvPd32xYPfwEiXH=QRbHOEXtW4IpF>mSvJx2-kxIfSZ7x zP{z0ZQs9?CLbJOYTNZdH^Y7Q`&25>duGL%FbWZ>JRsEWW0JyIq+?y39j;*3a@x^os z%kNvv9#xjH=uONSr9+A$tSQq~X@{saX3rZFd6ZZ3gxKIW8DK#~62U6n1qWjn4jrGK zHZCvRZQcF_FfZ$o^*PE_=o<4P+-bd3Qz3tIji+9__tS5`6uxFZBdi)){ZEu})r{qv zoiw*cpM9CP%Hgj#U52iYdM?hci?7lddHvs}?_lE@JU;9lYTzlv$r;MQahqWk;+B@goTZPxMk|{yQ(V&&TvjEDIZ3pO`B4C}Sal!4z|Q zlh&b+0S#0QQcsfH>JiqMo-Y!A5dW9?|2*(zd}r!sn0>!_e~aG#9dG#Wvy9zreuaj; z$79sdEfv*`T$8`UXMk`vkGYZMpG4K4x$zR%UOOdEo;7)E$GV;7LbXBe`=@y_>^81F zj2Lyq{i2xw?Q42_SYXqn8KQRBW`ryi-JH)5*qRj)-6xvk=?{G?7{d#wSXb7F+5D3E zPt+@T`0xlafjwJpmv>SR-n@#x?(;q1SWwD)CPX**aLo0+LvWFPMJ%F?raCxe1N9r8 z^E~`OLO`2*YBzG#AGgVkjLQfVJ&^PtVYu1$VN}7@R5Y{0TN+!^jK+wjgJ`JTh^8&q z@xsx37;rqNo_(1nm@(r#ji@9U3A`B*QOC5}qAFd+HBa7l(%zm1u~@NZT<(fMl2Mlr;tN7w@+c@KH;zu@`F`oK+H=eQ1cjweaMZOh1u&5ymT%z ztm*mQbn#MIV4BZo9aR@!zSvVbo#Ngue20%2%=1KoW>7=#U2Wbov0=wCaiXW6`tKFH ztIcv^@Cs~|=0o=<@(QnZ3me?GxhVXH8a7kxd0Fl7n@RjO+|x|rFukBj6w`HE3{zdo zKs~sc1uiT^RX8dGM;0c+Np8?O6MUA>nbBttxVISZ9P=KMskyHW$R;gLGozad-PS&M z{;>oe^eO4o?RUK0YibXq8%y7+3gY38c)CR;K&FgdceWL_W4PxD9ph{ydz&6S@yp8eth*$8zC89^EQ7& z(TXm!`F>80!RcY={YsLnAALcqhx-}b=$u$-I?y?>-2X21zl}PJ`$o3n+v}*8c-xhe zmlGLok00(tO6>6^q{p?-iH{E_53efa!E`+UQj zmC`D+`9dwEQ_(z4D0jxsalXYVy~02zQQ%r-MZ<$AmVcYs{$=&9)`P`nBUaFGe5`&m z%FKuz{I)g+>`B6%joX{|MeMmDz(?m6)47PUd+DcpJ-_-1qID3^5%*`2kGte!=Enj^zFC@WYujHh)s3^&gW)y1zG1dP=}wGa^s$-Z)K*zbA|AXQ`1aqMenw zHlaN81;if>+O=pc;vcGVzse6kRj_*<)a{|T!vf?^GQ8DfTXzrX7TgCedcE$Q#l0il zZUsGIqei>koF~M~Ar1rx;a)(BASY~yE7@LZFWm0j^t!$9b?2sxy)fh4w9{U=)46H4 zy>Pd4(|h*9_ney!*b5IhHyyGU9*X1Fy4r-(p+?tibfgcLZu5qVHNtI~u$1Y}SR}1g znallar*qB2gc1kF8O!8OhwrF5!s{(K)_3Fngv%~15x`4|3u%k@8)6ed1BtV90uG2j~`^%5GGFgF6F2gKI2L{nqtN9Qk;y1o9?^5F3 zVZXQ^{l8aLjXjncibJ>n721k#PkioZbDo@)e#hu>xMrSR+ z0|RWJSpo;bk*r!^#n(1lE%X(`(A@WISyoOP_ajYP)u=HY8Xr?bC&p=1c6$67Nuv^TR0xm~fmo}B+# zaGD23+;s2pc_#JZi0gl<&d-oRkt8e^nfW=gutM7j9-OS|mX_1?Sp5o*f)rp=W}_>* z=s*$Kt5=uz+JQ_yRby{#cr)@RUdwY8xYe7_WRqgFeFWVz(@GICy?Tk_HL-ZF;J7vf z^K$P*LohGTBUUdn?X{Oh)$ClZ1zFr{0oe+#-s!X>`lM!&DBe;lf=j~UFNylX3C^hH z_Pf30X#M!zc_ko8C}?&gy@cS=TX*A=kht4s7Pvf9f9ecqj_!B>b}_;n3&5z4=n;>N zIQbp~b7{I~tzgls1FrG(cNJ~*vCjb&KzEG}Mi@(V(P-l<#bj%T_``AL7q|IE8>=(7 zbES&tP@S2tT%ZKvN(AG&p6g>!^aIaz(v->}<{U5?A zBG~B6%wAa?OV4~DsOc5_L)gn#V2jO7@9&x3rOKz4q!-H;`EYvU7rx&aNTAJ(l6 zT7?(!VaDwd>|mew{pQC2{CM^-l9%C$hkZi6Ti3^VNSFfjLS+I%Fh}DanP`SIw%sl7 zs}ITD|9kk+cNbJrL|U-t> zipK2fbASJe$M+i*<75))oVKu3h$d10h&S=dR)GJBSUoXYGyyzTaHxg@D#mqobg}7a zmPB}R)Oss56WKNq-fE?$Qm9Esus5x(vEuDnadtsGedkiaBitQJuTY5{L`OWlk)20% z;btnJWsE+of)}flo(ti|39g}K?By^_&R8Z#@q5kWC=bdpCg;Y#HaXJ3 zdy{jzN=Hvl-rrwPIJuW$7RV>RT%@QQs z9&zOav)<^S>XV#B}l3ASK_%OAW!zn-uk_6olKM7 z`l6@r)1{!MYp62dLZb%7pt%I*nS&t4B(25uewLfjymd# zfl?^QXE>IQwzD`(@55V0`Nb~PMtG;_XrAQe>`+U*{V?*NZcJ@8o+Y-@EzV z&G&nJzsEPBD=t33_aVLy#ljmK|KQI5KW^`b3>G$~@fI;&u`~BPxU7He01K$Orcm%a zH1zWkfbs({z>61#3EX%4x@G59U}56kA{thz!o4s)0)~w>heKlaqh(z@QFX+5sM=ej zmnu|*0tL+`UNT1$77-i>_8EFW;eOKhbn^81D-?sm_o&hN8o~kLct009eOd9y7Jbn; zCcT5~>U=q2nC#FO5y4DIilMJU(PGZ?3z35~>8icp8oEVG$mr!;&D)Ra?TZu58yZe@ zmTzaBV&Q21NPW}!1sXJ&NBB0bHP2_hFiE>69QU1@(fz^EjOVm&l8DurIEQYQ$DEd> zf(K=sAeuSB!Rg{96(@ettMVl++0GjyYqlZOI1S;3VBj`>wLP^d^%kcdGKh!SwQMxQ+D$D89B$Av#P1 z4%@s4m?bLU3^x*ic2}E;%KP>uWs7No}&i73T5rant=V zxZPIsZXO}wtb5wlf57jN`VHzu;XCK?pw*)66^;i)rc3}X)d9%*_Neo#)C!)~7>3KK zn<;dT@*FPgw7ssm}_YC@qFXU zcMCH$Y{?gem7E)%(sQ%NudEhnY^3M^j=qD97f23EJSB;C6|oKKik<;DmWcQn0%UQpdl7zHetz zjqlPV`0N6d3)474Zc3k#`4o#61D`4e#|I6n2drjtOSTIy%%P{9&W3WUc&n z)?s%iAF^M3Sw9s07yQbOKT$tN2YoQSu(>Ez@WMq3Nk670{ndc#yldxu)DC7b=9Rke ztJigb$ETTnCOK$1k2L(qic-*mUQ*_hdxjD4(nr#}aEaRCFPs3I3;#P4DEm(LjOZEX z!jTYYySQ!zT-92>geIK3%mhWkn>mQjZ}?zph#Fy={wvcfbtmO_XJ)~za2E!hxv>PW zSEJ-_{xw4tnF+#%`dk@FJUobUDr%A2!h)0i{k*%q&;A4$EVR2Ty3)a=fi~39>2HE- zewV0o5mjPK+uX3wjK47R;sl=!3pcRV1fWH6-hc=3;bJBeWkzAOiv&YEi`tWP*4y7Zt{Eu%4&?4iSv zTJCa(BYmFIcm?MpwNm!kjQ0|V$097doQ|lw@QZ#uzWo9Q;vUakHWwi$KGr>srI>{< z%|U-{CMH!?TLPv5$Xeu~ zwe%t19qWtmu;gQYBry5m0Dz&Vz^tOqh2-^{R33F6yU$#{yjAOYB>6!wMj{5twp9=z zjg5EpIIC5q91e2+D1-yCmIZh!Co9Q0HwMU&Hj*Z|sU1zLVxK5}TI6BgWsB-3;X+%6 zBRQ$du-9^UQwJL%0#%tAhDR=Edhld6*Hn|whon7hR%=eH0<0NTT`tBN%di(K4=3M% z$Lvy{z85LR=nz;bKYVCtL^3<$1#Y&cUlcuWz8H!E8Yzsv=UoZI4zRn5>6F> z%cJB44QufPwn*WkVaDud)10#~kvwv|b;o(I1+-utu~#e+kVt20LL9^UuTcV@8Eb3PQxz1foC%f@^~`7cLTQn{}9RA08J_8%-whu5>8*%eyxk)`BK7a#SEbLmTSyUIR#~v37 zeh4nK&woj4+^L6n3u$G>t6W<>ABTfhv*7LvhN~NX!{XfYdyqG!G37-b2FQ6eXVp&g zX{Zm@|CfYhD8W$E42Z~36Nu;2lGQv4uQDX;HY)c>$dF=)&XfMpP@>hmn_1Lq+>h#f zg8RwmJ%aQ4=e^ZfO#d1hnTbaV)|enAHeC=Yj|5%7T=NOV2kM$9L&V*5CijrcC0_x z%f8lI7j#AK-C|t(3EDA8OzR0NvEFdqhk2jn>*`Q{|0*?d0Hl;BvDfri)B<`#y^ZBx zM6bOV9Z^qRP_Xh56Xj!&`voqnkduQL6$es~ZpUD3ga%yY*~rQ}M|IisEX#5S^f^D< zXLk})C_M7>4g5(bX>mwjjW_2wbNKecZufe608C7{COt`3SGvZ19 zb6MuUe}~7_Ie^Q9FnRwh=^dZqLDQ0}ld9UcN}kO_#Bd{g&>x_I+Ve#t-}PVTtlK`J zN199c6#N7`p!*5lFwt+mYN*&8U*ve>eXup|6udY(cXaS)RLTqEK3yfU<>=rBR6{tE zn3J%tP^(~Voc{&u^MUnNbV=SwOfFca@@=Z44yrccPYc$tJ4W5iUuB-^? zpmm^A#!9nvdp!o~?td`Ah*MLiy7zY{>L1g79G6(S1=)4;BY6Obj?pmxN>7_k&s=@l z(Y^dgt_RLdA*X4qdmXK1fqZc25pVciUK^M;kWRUQfT5!5~5Xu2AI z&j>pCvCHVvAa@q`jGjtjx4&MPzGBfZQi2nk9d+iCD`p51Q0T~t;Q$=jAVlQY*(PSM z_@#0*i^B(2rh^eFk|NIXt)MZ*?ks11$3SMd@>0X0cZa*++7flSJgj46mY9YaVhRnr z{k-e~kYv{EE`x^qci?y<51a$}6c^Qmzp!iI;=GD`TAV$KmW&Z)BiJiv$RG7j zh$MOLX8{0$;ekHqjeBDa@Al3cyEv1no726JchJ1lZvHBH3&k83XvVXvE z&pi@$XBFuvYD#%rYz`1+rXwf`19CGCKk(Pgh*`G`$U^St@g2cm-~&P<3w#><$*`!LeXno~Tg?Xw?qZ!j-C)<%!}JbIMeXv`O2ev(hqm2+r6>NHi#38Qtm>5M|zgvPyDfl5nf zQu8L)2Y)-kDf(U1e&571-7V!y*}HV`o%EG~@LR&DtV`igt%Zf+ec+DK5+?THUB4Ia;c=g^T4@8`hp7d51*7vy#X+QaQjuB~V%v^G5(xeCzvAUj3; zj&=vatKobOO{VB{Vhti)hk;e2@-_%Un|jd1g$hQPu3n*#54+t`x|ZFq#Tigd_#Nwx zc~GMUd^aOlGEE;PQ8HW%zcWE8M<#B$|Ib z0+I%Q^QaLUd9WimIM5M1DWIn!`N8jmyP95AGtL5j03U(>P!HHEuBUH${h*Wz0 z=oJRduHOmx_$f0eO0nxd3?H0jHLRXxZ3BC+$#4ZF)>WHkS+lV!e3g6Gb2#tnU9+rf z!TH0uCSBjdH+pV8_f?+1nrE-&SzSBawcua4(;iV8;CWkF{13AczrKqf&!NxKk0mQP z=ouzr@mJs@-S#nO>1o^42#xXhYk1q}t6%h0^|&b|Dq^?n%%mc-gaj!co_289su1>9=s z;>mQ2Pw8k=+?9E$nsf7<3d!lyQ9yr~Sx~G8w_WDG^SQsAUj{e%ay-^{vasH*#al6f z3TvfOyPv%x9;LIR`4`NIJi@%Q46!#yi*%J-Y;b9TgA{Y-{SIv^bw(7%)ur@c@OM_c z5^>H`#Vv5Sn^9tzMMVApbx-0zU-v}Q^HEN^VN$YEk|A=7y{F3agbM<0i>l4Kzp#=B z+zDa`U|B7V+t0-n9AO@}D0LnA2tCR14hC^U->l~K(H0xW$y28Y_-BH^N zP5cu*hKHbe3YJ-|H=zcl>(E*GZq;@A)4Tz;aj1IM}F)Yz`c zgVH0WI(Emq1Sbx<>9Lg@9hmVFTqM1gzR1Too<22&1C;owJbrqqL_ZYA$&s|uTz3{qe)@yBJz>r(n7Zo_29z^}Ap8J@O%f_inq((a2V{ze&o9QNBG1Bo z)w4?pCXV>6cJ=nkKJtywV*P1G8o0F1y6p!LtJSP**3@;9b=&Rcx2$Jb%{kp1 zy=pM%l|V^8~5yZ@CKjtdr{+h7?F#$~J@Uj4_dZE^Sw$^?sJ3i#xeS?) zeU5Vt2Nut$=&Ti7$e6G?n!eD$g>d7<+sKZ_0}2SiSoj#ps7$xA#Iu(sw{cA-ff*TK z@g)D78XuFdQTU~%7Ty{0^ax4B(4uhyF6Vq7F^Gi99=`IT(i<5&LdO6+)nn`UC@!>; z%FRx7r*By#Of%KERQU?q?l<{nGR(xiNL~F=nb<<0^3Xo0+&En$t2wGK#OzN^ z687NLa}c)NOW7}CFod(NZMZDQRbK{Ib4=R(0nccjF@==B$Uk9@M&EnW@p+H)RNg~i zvKXms;Pj-dEc4M|^d?M&xezKVbFY(_4R(nPSq2z%w_XUjC$WLek%WxqRNhMxji(-q zBs{))EP8;WikV7G5EbM|!Y7AXh$+QAT7jSDaF%`v;|)I*^1|qJTmAJI8<#{eS(Nbj z={3DLq{)3rWC0S1Dn@?L_`|;mRs0}F6(;~d_YHuhdI#{q9rSIhnH>r)0NgzQ$#hT5 zkhpaoGjw(CQde^rsIAPyN`UJ&3xQG;@PVeVkfzCwsXbo7^%NG!9jXC zT#(9Rc1c-3yS0)~IxUr;2W~yc2_?#PhE#&zPUgJNymy3z7~IG-A-!PGFA2mIo|RqL zH3Yn6(Ws24FGS_`-8L$S80U{u_C?bdkksp)Bcvqnj62PeK$>5Odm&HacAM%RZngfJ zbw+Z#Y6YWq;VY5iQm?#&hir@88Q!t@Q_Ni`hzNa-!sdix_3MS9!PSWR5qs?2;tt_e zP2J6F>3+49x`tXzzIhzdWmlE20r?~MWgaPg?}$3Ggan9+H%!x7eb+G+%jgcWMI_$Re1&8IoRhupfa+))iA1qt%G8BSp%$i`8 z2T6~%GN5xE7^2!jk?<2YW&#JphZ`(JR#UA)&K3vBGeGUt=a3%z53^9K7NFgOt@B0~ryM}6}a1P8F zMD=2s)%>1@njDa{aVZy#{2GLB{a09IwLU0D>|x%fCF|$~nAh`!A)v71UpKxqR zWCtf)CD^PprAR<34*@mo(qHM#qZqnYGZZ3M|ZlPGK!F;YEK9$ zEEPVwgN?8TEOg{-N0HeKWPXQAFOvql`|TGHhEZ~*UKVA-8hT?2cpT!;B~$J9E7sV1 z;SPO8I|}5MNo-(ai1cn?M&RKcNO=E{SfE(+g}|_ zHtUlUfrGt)pVCEnL@=soPku0D!F0~ruD%iHr~0Dhu|U_6?W|)|It`Z-i ziKQy>5t=w$B|btELn`qRnpmh3AECh%24yZRBeH`-;@MibaA`E$vt&fn&Q$H&-yPVR zWj}a1qVVg?yasN^mHiI2;az|-J0HC>=+9Mlg1&QPubCjC4s@6a5&<7$f=v28P0-L| zPS8u@iJG8y2Tl;`)M~-u|89QX{mb(cB~0+&e186erOuz9hO+YiYJNI06CgX$gSPTG zrWjbiWVOn^8L45p@pF!%QE!+FL9zYM zCtuA+Ycr`^r=BNvYuh}L$2h%4VxGM8^ zoM3n90dv~`vVtspJ2Kx#BK069;Buwn<;;SU6d7e##`-k(IOkd!vEe%~_~E@iFc`dO5vWKgzR);?7R1R^l5_X?sQ?PZ?^ZM%{fh%+I{HojNsaSe(H6J0d^x|qh zLSpH~3hEaUOD|SXzmQmZaWx+yh4L$|<|8!zfJ(&k+uit+-a}V|YXd851MNBkd|G>E zM4&y#)4u{wul%NXMhQH<`^a`J>M(QGW=;zA!^q_Y0M!Ivc;xe%|v z04%(;oYTEHAQBNUNF>KDp-%+{vX6<);q#X|j)FlKu*H`EmVqkQAjB-O0@ zoGceEREJbFC}PCaNd`k0SMd<2mQ#LLz`dY&=y3x4f{3k|dr{}=o){XJF5_CSMcqN} z0xseb_J=hPxDl>NM%+kVJ5bY#R=$F<7P+Uj4H#UCP1`Q;3J*w zZ;Z}XDqH0oEae7UPi*rPjG9+J2&)ShGR+O5CMp;NnC6s~6O>8qaQ<_Y_GYiSyUUp5b zIe;*;HgCK$)|%*?dLokx2VQB16vPpdA#wZP&_u@{~!+=;%Afpjy6 zS&Zb(d)g4p2wvLwJ!*flU+uEjq2MwtsP+@6=>*jtG_?m~i+-UkB<8zdO?X;arFF+3 zX?Cnoe$Ppg;|ws3+FwHZc&1q)ET~W?D)PaqF}+LcsyK&;DESA0~6id$yaRQg4x1F)@)5PvQ?jYgTkFU1w zA&}rf4-Mn#OR~?z$zO3N$8)z>shfq5M2l^Im0k9ZFGZ0ntVx^Eis63>@nQTjh71O< zMlds;lL%sD;4R-&!)6YN!oj(X(KiAM-h5QXL;`s*jpjo!3XlGjO_d z1b)P5P9mkE?Syj^rle~z^xiNg*2#2eLZDwORpAq_H%ooV_ETol2-(&MCdMK(6EuvV z?!g_Rc@K5ephWWgA;xOQZ)fh|Cwikk72T9G&4WSiv)IKQMc0n%3aTA zrhYTYrSCyfSzom_Ylq?4#3r4(l#X(vHknX@vBduc!h|j*Qs|>jY-rHp2xkmW5LpJl z97Rz3wV}bj6`^oH1`R@jswjA1(c|gqG~0=V&x@{AzMN_Iw;LTA}SwNmqK*@o1o0l~V@q5PGx@9m_pz7&l^*XO!s6 zi&il9=u_b0jNlfDf5Zu=sjkM?RfTs$wmSK;Y*pii8+CbxelCVS*>oH4j`-1F>B@^g z>HY!?t~xfVt9nioHNEN%;UP2gy`roy$jUbf5C8sx>>IoHn$%dxpwjEuo$eoSNEHJg zm2j3CWg!W1%d`q;tNKX_C=|U2tWQS>l#UMEYJD8^H0P70>uQgax5!`KV}S#`{8>Et zZ?8}2Zv4qWdE$V*#}8vwa-xpQy^!YCt9@S!40S}`9g zma5n*P#{(4sssu?R4i06Cs06t2i!e!>gC(zy9Qz&RV$8bR5525@DYPsp0r1+Vr-Z` zf*9L;6NbBwD(2~4{S^3sJeGrBq>T$kZkJNVliQ_~@#JPR3qU0HEC5ZIRu6!Y zkggg4BCclvsHN8c@M`2G0dNN2A}DtgT(|}x%Fbe?*7|UTN1?uYgkL&4T$(_Q6RM)@ zrL;P|Azz|K+X_&49Q>;2i;Q*VVwlw)Y`9kXhsS1CH7j`RSbR#$`>_QG_|!tWt`DD2 z)%5Zy-dckPNaN4@@hVmJ7kQN`3ocyrNW|>sJCPPx>#aLRiCrnSS-d{MR{JsW;=H_E zC{htMeh%o=q3ox0D;C~k^n@q8Ej1L2RhF{le~84zqwa5^af71n(k`T>El5iTtJbpVkcz<9 z-b+@Z!AJ#8O66-J=^GE*BrZVXQ__a=Du4YuiS()G;TJiEg{6wXYDNEGUX)m zJ110{pI99_Cyes0l$a}ae#e9{dHD56I_~9vm&EKhvJSGO+?g6jKV*McYj<)eREi?| zl69HcUi06cIWo_=gnGRm&;(Hx?R=+Zojsw_T7D2Fe11*HO4Nkx38UbBvd8e3qbX^C zbwQJBO*~kOk7(*CUdlY=?!_8$GaIN0rP;lX%u%URxSO6nglq9FoIMemJgQ4KqKM%b z*vj7cHK1}wRuA*{Sr5^#$9whb@xZeXkA2u9oOIDYX6a_ZY-nZ@QIm5t5b0lLWa#{eNp+P7l$EA92LtLD7SNjsQ<Lq~uAQz7%oIif{H2bGa^k zi@}hh3dB4h!5A(BVs`#r?Fw54;N^O>f5(#3&OlCkh5*AkIgKMw4-ne4lz#W&2MK5K z{qbaz6n**s9WWhwL(p%0AV#baXFkH&g(%{zloBTyNIgMe0Hj)U>04kzJ91ecNF@T# z%vvGt{dbYa{=0BG6*zSgv3MYy40{D;_v6Ip`Sve|5z8k}2MCfMl8~nkaa|fBT$9hnE6W^7sbtsOo1PeeU#3f%flQV?W`6X#M@U#!`aJDd zJ0SDYd_8Ng%64z*!a`!7SKEz`k_=q4$W%L1M!`RuKSO7onn$a2IIi^`BxEN1zJ&cv ztlRsfZI9S%3_bHo7h>L{5&J`D)I;Ob!4tzBi>DE`H)6kAn+`7P8R^k|GMGdwR@22Y zmJB`;&?`}=?QblYM4pu@YDoEoo3@w2sQL&HM?RD=UD<$i9Z@FXq%j@13$uI5!N>+-0b~@d3;x346)#%(Fv`mAF5rav$TW z*H6<&I%r}*`kizyWrm#Us9p1DFN9Jr!=2m@nF#Gj{zh`R`|k(^f5ZCdZVnHd6`(@> zhnPKCpg*_vKv;HIAiO*W!g<3p7wt4q1%x-@GSQF2r*9-;vK4>V&t|j$q(M^kyl5A9 z#RzcK8|^t3cn&>|1UrH|Bl3~At4n#io`ySTQ-+Yc>p6R~zgPy(RSe|aCI<2iM#vmC z{}K_L9|O52J?etm`h7(5{-fw2^SxL09^r>!*GzxL=C{-MC@TmD&-6r|bfOu9=e4-; zqA9SS$?6xJqGV?_ z6QXp$oKonRWS1;6tF4}|33PeSv_w~>JB=)vd|g3ERsJq8GdHT zJm-r@x=puR&HETnlt7B8hnw?MUo_AusWn#5!OWoCBa4HF$<6S1&u{*x>CapRl<$=f z6Aoh*$Z8(7?$`opc<8hVL!Bs6E=>|HqE5|22p2}QFjTtQxo8wpcl%V7^V9A1nQ4e7 zW}Prn1~fZsc%~HjL_)xDzGZg_neYAXKWc-DihmHz#q8(Yl|F)ZRFBEaJPF}<);y#c zbrsQ_7v&|g8cPtsdm!^diC1Y7FDD5(+`FH9J!EWH)$zWnO-nJHP6A zq<6gXcmL?|YHHW8GH+w&5Y>$QcQeYr3m|zs_ZA9`yx?za}D_DhmG6GHh?d+`NO^esB6spU9hSY}6=IDGw3uHgbOflktmurX) z8Ozzn7_i_CvqtbeYLeo__p~M+$fREEGcP!fEtdUrIH>xU=0lrQ=7Tw6 zJ}UNTMy%8pnlK8;rv-PJy^peEn(R+7%50)WrlP~s_y2w7p`)MP(ab~JG3=P7%)?Rw zG3M-;J|7pYc%oWz@o<2t(@q}C`pkY2S|fU!=W6T>e1*74hE;WBwiIZ~fu<|wcyyWb zx3ijU&B86KMZSG3M!8uxnvh9SZ%WAtE=av8C8wf`nxd2;#$GBN9Yv`(QF1cb!^OHy z(kE;M)8S?6yjj9sod$&8Xg_p($YW@~!(l3uhSjiN5-Zy99=z-2Sb9#`+{YDFPVTQ$ zGPl3UDAS|APbd=!j_Ddsfb5S^??N8Q>qwO?)wc{Ab2AT|42w(?hmjZVM!zQ>`~$8L z?iY<#dh~lkfG_-cIoBe|wQSHbChR<}ZMd@R%5<|3%VjZy3py&BZJhrZN2heDGLF_H z5kA7DGyO|bIGV|&{aiZPzciQQoV>V;OF?sK*f(oAV&sgzJ28^p?8;nl0=?G>ly^spyg)$?pWe`C%o z#>LC!IMa7!*hq&Hwo8uU-qoS$IJ%o%9kgH0t`KLa2Q>E%BJ5Y%^F~QS zlTsv@zq;=|YpY(KXZG(2r`GIy#U{*d&ajDN?t725oAdX*f1mx_!T;vI_fzcW7MO_l zzJ0>q4|Gl_HI(4-T=@$ARnUaCAb1+cu*It}``nidWZ1MkOJTr1SNZddMxfnj1U~4a z5$KgS-~fLgeU*XFdM(H(V9+UdOD{mw^wZjRj0kL2{=CiP&s%UB8AukIDE39aiv^xI z@~Y2Avsxg-rW$VcSm?Gr!nj8K8rX-e&V;s$1ke~s7>dj^dLfwG|I+&7F-EF^I~M0P zHs_GuZ^fHGwez>yoE?yS=`q{IyF^9XGBx-z9Yg=LS?X9gLEL@@@o;#@By?ktX~M2S zj;~!Orx*X!qX)3xUjN6sDb2BX?9HUMRPZ*W3 zzd=rm`bsPP1;jg&>6NmUEfJEUgFITX+TZv%`&s6telk9ptKkpW%1}+qvCX(GTNDVb zulV7F2U_oIuX?n@yOE)Ts|Wk3RS)~{HgeZW^cw|{bjV` ziL7$YG|dJ%|u+X?yt_o%NsQRtDOlPZ@;-*E)1vfYCL=hH#!RGDMPpx@AfC* zGF|d@+ec4=CvP*#zYjm{KMx3s_>aG8`<9_ThM@&lAsMs~qCThK_Vn&qy7$!E#_H>7 zw~f`;Q*IkKGEcWHS;$vy8>_FU*%rwU(sUGN^4Tx~H)exuKuktCP5|qSdyem#^CQx> z8Qa6C0m=*0ABbn*bz-`pZFI|xXoYj$VfVXP!rzri^>~DzU=P}F{hx*g`lG3$a+yX3 z68KZd4+;BCe|LD~c~x?`aahYP{b!kqcV+hCNrYub3}oQS?yu^X!9ep&8rJN7Xvy{I zDO7kMX6G1rEO5}%&vk0`!tV3G$y3$c_z;l``s{g*vEivj(B48+ECg+D!;@V(C@4!N&ZQOMDl4*NNDam*;yi_pX2a$9pB?1;Y#8dHp!q36C*utqI!y z@ofyE#ujSKpvD4fjGxBtDc{-dMs_=YWqflP-^oXhk6w(PO)qF?fmqAgmw7*~mymz@ z1>TRZmGWam#QSlj1pQ&7ydTp+@6gcCc|R`1bQ3E0g!f~}-c|kZi$g2&U#zj$NM9i1 zo2(msGzBK=s`X&1Y&r15B3*7=3w7F^5KfPlN%WtRy^Z{jjH0He(ON8>RDy3cUi(et z>ds_0Y+ip{8vUKuj?3#zZs!W(FS@JPXjV_Ld8ljXg4E3By z;8i-N_qFQmYup`9nM$YRE`>(ty=~?xsrn=ru*p%$Dt;u-`~GE}|9zGJJ=_1D>wW*e z)ca2AJt|+$mp6#exF7FS<)PCbc@uzkCRgNc6+d#X_w;@KCGOted-ul=cy}|scX#&| z5A+uEP;={#*9&`#q28kLQS}}u?Y&y=7wHluX7EU7@~&Lz-dyPixzc^P(oZP;Kx~j6 zQ`8^D2YQPS^%iyJ(SM+;x7h6$JCj>;r5AIh?Ub(JB@oKLrVXdaXjsWB2ApS)^1yk( zzdz#&rt8kxU@INbc}Bm%BSLFLowNDY1BRTQP|B2ij5cz%r7Ox=QEEUkbBIdWf_`|+8-tC-<#Vq>;INZF=yB>#+ohu&ErPqRjth= zWc!z3bSHNo*V2)>NhU?@Fgh|zUe)sYdsX)MT;02zd&+3;H<-DcU3g7O&+O(I<`*mw zA`t0|PdV((iJ&K#eUzjIK8|F=w~42ai!noPF>1B5*HT|IGFu1UoA4nMAfcQZ`(fKt*vGX-H$;O2nAmKn)~}`2ipoBWD6xQolG1U1+cG-JPbtTMTVhq-;t1sYPQZW z{#{(6X%spv0^L2I?3EAVok1DfXfcC(+c@V!a zW4Pf^edqRB!44(=0HapUw-RK59#76zxw~@6mH`Iw#3zRX{_tdSHCK&*6YgwUEe+E; zJUO%m8n07;GZUC*PDZEWU5xQH1OE{ck{b_{x(Ve3b&%`ygqVqJA4yMQYj}jMVW+Q> zmpU4;Oh=`A#n43H-K-qQs2JY=N)BDwPYzAs0BwJe^OUr*o|4wG>o5$l2V72!$DDcI z*H=KEBQ^d<3AyOj%5cQZ?+N(O^9@ZPyF66Ib&Mv#H`~+(5=Xosi>}%p=C~nte zPGRFBy=7_UG_zmWmib3nmFWC4Y(aaT>)Fz?iRXG=(1+&*(@PJYw0KF}ewLlY`<}EI za$2+sC!9+cf*>uDUI-B`agm-Z(@%Su9`Hh?>k&yY_A)KgjtRxC=X8yGgY9Lbm~rB^ z^9e0YjM>XnjFPjasx9hVHyh_h@M2 zl&XCR=Z`8Ff1-b1Zy4W_OU%)is962jyPOGgoLVA|npy(~0_$Oz`AO4K{aWk6q7$tL z<=>cm^T2U?mZLgOsyfrr%^tf@Sc>3*rr$f0X?5z{=CzI0&}|z}RWW1p;AU&Z&2V@S z>9>y->7T#|h?rXkZwzG(1n$1)_KGFauK`AtL)4XC$Yg^zhkF%*gnh``(>xsf-_g?n z(NiBU&u(SwlZR(uPu5S(TBfY&Y~?Q_3qWow|34)fpJLq25P;7QyucbIglu>Q;(#o% zmEy8dQszD{sCl`iFCDqfZcMry;@*I&^) z&uZd-NNWzE=x9IFwM;^j#LO6FiBxKqpHni|vL%W;%c^^?)nzU**BVM_ z(w^%q)=l2ME^}|2xi=e&hq-q-_p~xji93(C(fz6oCQt-nDhRj)N|l@Nq}{@a<~B87 z9dV}5wo>P7iN}3W(kp#AK;49Kk30X_rdHC46)ez8sZa8RBnJ6N`YT`KP99Td6h}np zzH39z>Am<;&#{r>pp3lsv_G5m-mHAnXD=BkCQ}VqgHUK)aIjXCZ#~oa6cqzlI)G{z z@gNeOKD+5zGbn##oYnC6-w*KDP>N_*tx!x}N?d2c_kj%!wGy^#h)HxXyS zY%H2*)H?qvUCRama*UQP>u7o+40V0 zg$91+VRO!fBsxeluOqwAC^gUtt5tDc;?6zZ%;n}w?1oH5nh@fAEAreljbeo6yIRyKayf*OQHF5j)E?gdQA;ma32)z)vVAfjRMlcE|0Pp)kPzxWI4S zuH#-l?#mZ%a-r2c8X3TuiZ6!MT1PSF<~sb;-)hptxPSYnk$Fm)OcN5L?ncZ)kUsO+Z1dRs(&x>FEt4@w zG~b85@9ma$@p%#TuOAckUpN~RNvjglW(gMbF^u-JLU7I%_Qjr6*zQ*v?6F$q+E1Sm zpncpi{ME3B9(-h~O;8$qmZjn|R$dk>EW3~2Cp2mb1saAD-|b-qTX^wX@=JB*c$xiD@%34k<;gmb56G~qbI z&6g30pb#8BL5}Bp&X*kpGAL3gpHPtWGc&cx5P=hi%8T!lz?(B-mn02Mw+F*hXIrh? z1=jlD@sWMOyiy!W)-Zy+#y>(k9V$`xlRdvSJEc4C7e?V3{W1YToq2@onu?relurpy z3~Sz}unbnJlsaqWVy!qk=_STF=y3ayd?3`Crcy%ZCG3^NVL-m1vptiAckR|BM(5%ol!8wQVEyDS48Ekvxv&2=DI#ZCIo}d&Zw-@ zT)k(yRF>OFh%^dD|K0EOvUBrnL1#H~rjwd!Pgr1@+j{p8oS!UKO+i*3Gs7Rp zQ&Y7Dr8XsG0H98dHJQrq8V$q2@zZBb)hGqFrDVUa2Z+TW;ko?3M;ia_4 z_T&4~x}m@d`HL?Hgso;p^YK~)qoPJ`M+!?mWGV*VIM+UsaJ|>S;bI;YNd3^(b3#`B zbZ(yGoEtv8_{4ZU0hikX_Na$djSqonxNFf%{*Y^J*JK6IXpgLTKzQ1`FX~)|bT^$Y zsXML8hX+Dy4xD*&P;(sVneOpVW~P*@b~~F>X}yt% z9F3DXYM)=kJu_+u3L!vxkc~^e1mUd+?_T^fDlQlF>Yu@n+SIEsrbc7Xr{bP}XCh3M zK0M8e5VDfL05Xyx!bVkVwVp|rilbXg3l- zz+_;URgxEmeK?lW&AssmxP&yo@~W&RifmVs#kZirH%|Ww;SfdtA9L>lUsZMHf9E78 zB+%$S(O^+=q%F3=3nNxrQnk$qCvYMMMF9;Jl{VC&EmKj$rB(qwxgEC$_?KFpab{#{ zr#ho;?cWw{t(t^OfLaVtytay$>N!RQQ89QS@AvnteNGZY=0ERS-}lYule70;d+l|3 z*0Y}VtYgO$&BWC>8jYEG^?Ni(SfwqY&h#9>2xU?YXR+uJ z8p5}LyLYg;4tjuKU?8^sGSA;w1FHu#aI&V=-X5e42EU+vV>ZTbHRNx%#)&-%rqieX z&zkj`L`!Pc#_R40rc|O~11M^xcA&yN3%0%IPNPzq^+ucmjC;mmT!N_pvAEa9%2)Fe z>F?oi*dUllUxZHG`H?B<*^xxm)~Gope9!xFdvs_=UDcye@5fyUykz~jJvOvA`k9U? z__LBb#t(S0E;e*0Nzvr{vUgg-6Kc2<TQQ`k7?V`kM-#J<=6VD4&<>A74d zqq!FN{!TuxOJ##O$5dQK0z;eOq8S+508gofVHu#z{)$wVq1o2x2y!XJ`^)bU4fRd( z#fL(C(M;OZb9(=LgF1qA7zNzO1jl zPMww;%4AuV{zZ5SGVj!j>)%(mD0CT5-ip_0=64GE?o<0S_doDf-=&xN6XqsTckCpg zxqZp-WF{o@z5e~dX|T!xJeDn;TF`i;?~jIpG;dlwH2I(;g!>zh0s_$ofSdMTXw5&H zr#L9SknB&MS2URx8RO?Qm60?BR~Jo1+@!y6+Q<6>UQcHs=|z&C!tNu;s9Z1GvP5dJY_49?q@ z4Ixig&u?Y~WBrFU?0D*BcFyi5uY~i0GOW2Te6DC!E|R_?WbZ$6K5tfyvZej!W*8jH9`|%cSl~ zi+8o&MUwvDGG6eOZ{<#$3Nw!#qObu^Nwzl!VM=+_p0qOCGu7$U<EFM?_Vm;d_28 zOWrK}jo07iwh0Y;DnMeb-k`6mI zT08R~i;)cfZWGA{Z@cwYrwx&c(fm+?bCm*b%}2%zDOS3Qwo)_CZkP5;{RBir?0`v| z5YPDqHl`fm3$TpPdjKu3PJC(7SF57u0@(!_IRkmJjTXI;iUU^MpQG1|e zw`ntBYnRF*q4*NWow;f_dz$V*rOvg*fbAt|Pza0p1BcnKF$ZQyh3O8d0dWPRF83}( zuuy;7Vp3>-52>?c)<5%;jq_T*A+V9- zE&c41^ZR#c>GWQH#_so8zd}uHBBEaGHSp$nuXQ2``TYV(k9sXFYQGm*)9)cHc>Q!FLd%*kO z_2YSmcYx}mO&YTM4Ew+^$(M4MsYj_Synm(UU z`*ZWf5X);>ukH8%s*oK`g2~f~cETXkdhs0tu&L!YFr?~;V)hIGyw{qfzu6E_$jMvy z9v?z|F)!9Vkczadh2uL&2@972ipK9}-wxoWSv&OsY0f?g>H{Fqzx=*{9M~wbB#+9S zaI9S^roX9`Y^l42FKh}|+czJ(ocDhl@U=4!>xLxIw6R;fmcP&p2)ja0D;DFd$Au_{ zNdXb_TK*SVXyx!d_iM-C&?kE>i4SS9K;LjB?HIQ=a|60###_N7t(e2B>`ZQFaA_innJNFlW`KPFlC2y}IW=1J>$h^_squDdyKXDP8r^PeCIGX@Ddnc;6!A-$ zVARdz+6h$PoKnx~+u>I~Xll?@ravXwx-AHv`d)6F?Ui@gqbl?*@^C7t^?Z+R-Epfa z1_Pt#l?B&Oj?;#1c(hm#!4M^dC@>ArE6wJ0)SJQS+=V2#z1<$~GK&hald|5-l{IJd zC`#G_12SD{_Jxi$>))agpg{TQu*W*U>V)0rs>b+kMSgUbAYIFvJIrfQ z3T$3aG1L_Z#LwG|3nSX2>$oA7y5k_Z-2Plp zYG=Kr@qh4IN<=P!M2C{mnNa&tx2Vt0N6pKH!_{{{Q-7PLB;B*CK7ryM1u%iZtSthB zJHn>Wh{4QBBx&TP# z8s^|>^$XV4#?LS`k8{L;Bj6;WBrmp)+^d3h$F9-j2TFfFdxX})+DFnpyVW?CDax+V#T{>XD>f|ZN_fTe(!;RnnijyUOCCI_nsH)@Iq3q;C zomE?}{d_>xP_cF7EbcFpIEU4t^x{ht!(e zS`O^bYxn*S`Xj~g1Nsy9XRvH7C>_JJixfZmOIy>2q=t3XMu2p|hT4&^tAYTeNbRD3 zX0Jx)w$stfJk?)259dom3A_#@x2t~-wexN2Db6!5meyOYf2u#|UmY5Ia&uWahWQdH z{+6palsZN}NUZ9Mqr?Up8Is}e0Q{J?xAg)V79!Fu@!v0+=QUr$oJ#mBc2YJaT`_8k z%u#>N09QA0%&164c4T*dFL&PZmt3~9|7E-c{kPxCqwRXmNYa9YfBOR@#Qhc8IwEe< z))G?uE(ITV4GTHf6YR=jQe6IP+b8YX)N^q^y@e2I4MA>GeuS6&1x+PIB#kXwCCC{$ z0wmqctevg{^6XU}w_~?@H|ThUTxid0f6&44pHx6PmwcH|Dg>fQv&k>s9WkW#!D|=& zh=k|)<}|NG@lJB}^!#3YEPH%!`4~%%oc+r$xFvnZ_v0PT6uk5nJHlhDkZ z*-k3uE<{p^%p|qfw_pqqg+ZD4V};dN=$%SWT{RADzGOy<^lw22dhB&RQw=4~u@n?@qor!t|{} zJ)0%}X1;dz)5~Cf{o$kYYY&Gn)_HlwROhp&9nksi|NL({-}M{UdAq9fmqPbk=j-$9 z`ONb~Ssf6rgtknY{qc|}7bOD{U$gNjA9wl6!E~&1$r%U2;NS8v;H)GlyhqNan&_6n zv#RHJMy-Fq&R6{mxqjxU_3+GHA5X1qke_2E(jePa{apC-TtDX=w4dM4HzlCh2aNd9 zK|g)aP$S+yUW5A!-8K!y1IGP_`94EubA5JxA8q_ye|-j6{VgA7+kfSzxg5k-p7w-4zCq`Nxl3iUemw7;&c1JG401|`d2Qz&dc{)|M)G; zj^nJ<(EI9d9I$lgywAOvdBB^Wi?`O2b9MZHHw{{D?9Ipn-h3OPXcf+-Si89>mvSk^ zS;`4~ZT?1b{^N4zjFp2d!AFd15BRHi!=$-hbBm)pB}8jZDH8Xj`arjo)6K>cP27R} zLq}Yg1rD~plXH-U33C}HW$+)|36MEfkUoH^PTZ#@(!cL6d&Z;dcUd{bv%F^cOr<5B zz7TbmIH5z)Rq06J2Oe#dt#K4xNI}7+Gr{7psxvlpn-o+w)7E4!o7N7|5;h1ys1r8j zle#&2CeX>JY0cqLv#6jm8`&IsT5d|mz{*rU8B5piPi?D}I# zm_K0gqSf%*)qvn{r_Xz!o`>o4ek5L&*ZMwl71rQSg<_~GTx>P?T2pa!e1Ysv4Oz>c z5Vn?e>-?aqd+AF;ou>6n@$4E3ar-lk?cY`#I6Ko7?$#@W=5ETe$`Q<%RQT!-LdpkW~Pfj zVE0Y5W=&c}-iO@cCJU zy4Hs5?~Q@1Hr)-=Q_&oRnW2NsHBMaBPZvD56Frr*We2aI$fGoM0-yQPtraED+;gk> z_uw}BO-bUV6LLVg0}9M$&&t&g)wFz6kC@NF*TUz3sjp^N3ClmG%Bub<=aDTl^grL~ zx8IvFt=e1jEb`^lhbF%%TWtdSQl;#=_>$~dKSlB~Kt8~_U)+8-_I~W^%3DW4O$Pfz z(fif;_qTrJeRBWMMMF~eOS$$f8#{RNNwi%e%}iZQoSPvy+w~ zg{fZBgeC`mzkAU4)q}t1%phqQ27E6sHG!!d)eg-*O8>>DAcrwu3P_sp1oTekr@%of z%JR@>&eK-iFLkCnq$V#h5}C}~;|D(heyH)Td(f4GF{9bxrS8{d?aH9CY&dwIZqZ)$ z>;&x=TuvsF;F9Nea^L%SoMZ|_{AEHbsKU+dwx1r?E-3crM<~A-hui2K&hB&~sWA4M&?HtO2dHVG_4k&))aELAw&=jAZW}d#l|9e{6?Pw&^bJ|Lq z(%ZqBEmwn4LhJhHEe(7ho3%8^N&SYwlB9Kd1-A@H|+sA%S2i?=j*^50JSGxJ< zt=X1+@<$rmCV{aad*&U3;5BYrHg(&8`IUYDUkAPKmtQ((842*EE)|x{vfc>y`mSU( zH~K>am#U2C+$5T{>KoE_*W_zCHwS`Z6c9 zfUc939b}BBYJ;%%2z4{Bg5dzMh}T>uGbw6IQ5}__QUkz=kG8)dDP()ICRajDi<>tk z(uu-SWGtQdV?xY=FE0^!{>uwpY{S|noYNmoOAauY9wcuWAUjBeK6!b|0Qo^(Nb;70 z=z%KU$M7dOD9lS+`swlCR^}pgL;!1HM+GQ@m?W_WKum|tCT$^R*g^gFeq#L8f$_o) z7JpQ6YB%l^xbnQzG8$~6iE2$JM1(An=06S@p>9Vh)dW=LKhE6hM$jZRF`+Ur@yn4D za;w#}#K>uGesR$K+a%5!3Sc3OE(iX$a{H_CerqK#O!!~oWCIy&yA}Ys0><{J(r?vq z)0DJRQvJJ>W!27$Y9ME+^`Sp{KZ=bmk+S}pYe$#3XbaMvXjUNXSb9oH^Xmi>{$oC( z+doDmRQx`ae_JB8p^nf`@DmCXk_bJKTc2@;&F)zNo+$FAej)6XuD zn~nDr(G3^ZXV>=H5Zw|FJ<<1yiqWX#oh<6MQmGmh1+L-NWQPj>r1|>=17fWM;`%5eSQErZ9zbAk z31J6^4>5UjL68M)i{F~TLLd`~SNJ!}7;Ry*{JUk(xi-#v9bn)+w{y~oqeADVryo^*9{#fG(q&r`RhWnn z%Q2Du;W9FLt8mGcAeQeaZ%tzK$&w$%O1IYHddO?KkVw1HWN*l8!LK>ICtt;|I6AqG z?Ii(ki`m}=eCb;?-W6pb{l-EOg&{8FCss&EsP<7)h#dG_g17{HXEV4s5$Zx}lncuk z+L(7WJ03Sf9d8My;p@%StUqZ)ss^S1id0R7KPi%`iTIPsQZ;3;$f=rAe^NMA6ZT6| zg_5bk8Ko<#Lz{HMgtJoo(7+9$YYC+4($`)ePK0*ZvB^0k1jzR_ZqqX$bY9(#z#FWb zZpTA}K{@^3xFpiCQ;XvKe6B7XZaI&COp@d2>jgROOn zCWc~d)gj#!a#N_AB5sOw6XqtYn__N?b;C#1L%cN$ORC%Emq_IvAmD0^*3h9Yz?phA zu&2R9EPrhEH5jSy?J-XuBt~YkD3ild#JOL@rZw3+!fQE^n}dsU52xKja`K|`l4xp!Btl~zM~Iug zaK8ja1YkT0@ernj&W^C`2na&NNpHiSlB@{W2J+g@MOo&31bJ<&>di(k5ZH#dAgnD9 zKgPgnAe-CWK`x~I1UhGjl8S(pUTmJ0djsn-aS&!*#wjlLJ_ALL`SX}h$S*s7mf2wC z7LmHp2X&!+IRZ2=EbOg?^I`z2t<hyt?&)oa~pG zgg8Hwsefi?Gm@HtO9i5+3^i!cXubgqWm(V%r3hw{55}l4gc{5!+^{rq&oZ{&Yk8GB z%tN(2;JP%$lPe(Gt}H8QfqTw$-u_l!Q#-{S8B`CkVQpHj^I5AhYO7uLIuiQjgHdy< zn4L?a(GRf;sV%8)_?@m&1|NO`SuM*Y4jN)@=ju7WkDGnEd5@d-bn`wp@9X9RZa&b> zhunOqoBiDE*G(TceXvOj?#X_axX%F|^|O(wZgG-CV`k?+sxCy#V9CpI_LuA!CGIhr zs@~~GU*htTAI)&d_|ez6yyi!DbJ^`j-{$hRAMNGR>qkG}@$u$5|lq2hCa{n;Kas7gdAn|0KW0R2T zBxqXGwgs8&;iLrpL&}gnYPTFwzLG^g%e61tvd5Lu_&GNuu8QnSK*e8W^>1773k6_X z%&D}iB*@ZXfI}-KFJJc7&^bX&HxinR$c{mN3GkZ0uYv-}Sro5z1U_UMN0&8z8EG+R z1&x1?SK85KcocmY%qlRKZJE^^EZ}SI0T2t!e=pQn1OCgrQF!mNKV>=X8}ty_n!z-E zTc2rjaC5uzdu!V56IXv67r<2W)WgPorgmk{RBlV;Wb5X3a`*hx0D1M`^LIFd^ckD9 zjlcf2Ug{cf7~eEntRMm0PW&MS!f-V`N>6}O5pFxxTFq}pE}p)njf}iNjY=tyfC$=E zx*erkkpvSdOBYMG5D}?p>2|zsdFHlSw>)zj*DcT7PSq{X+}3lO)PagU&DPW6+|yh= zIhA>G&ev00?%iTN1#0w7qnEk1CUx>cK~3g$9`SCf$vn-&H*)tQGT~g_C=^g^`m$(5 z@>G6#xtf=LQi3xc{>2`Yk%wD(;Bt?p#Yu~&vi>T08-2Ljy%G!O>>*P>8vRo}tP+pP zN58f=QX1#YT|5{f@ItJMZwAdg{N5gPIK)G{Jrua_*V%&%KzXy#9;UiCkMe+7jt++W z>IiSu77}#Q;}R6xhlF-6e)Z|(c#^x!9<~^Uc1>{}qray#a@}NT!GU?%36&(oQaioo zhmpM#LQDwMZ^RPl>-q-8>|Z%pGkQZka-aZY`Y}D8dZjM)*LW&CI&)o6>4Ft;|8%@A zqCsn30Ix>={)74GMrUqgIS~8*UFNRYNyFZg+!Q2Fw`6jgQ&qkBPVh$hlFqQYO+Dew z)Zopi{5LCuH(v_g49UOI*y@{+!JF6If#PbCF)5m7DkVLD2%QvZqm&+?jl!q6S&S3i z^O;4i{dZGbs?}@$x@(cfPA66) z@S{e1L^qngVmF*bNUn~*EU3_{nG1qKKdbMO50>%@amVS*3noF)gt-8D`R94U$?U+v zl1n{})OHU1;%q3r=D@v<3XmUEa@#_f`IT~GAaR!cfl!)1zYJI{?ozqpi6D#=TNlIEA0+?-|{`Y$dmu;XeCmtnPu!R~EVf z8m4?N8pJsydNuReAbk%f&e=bZjxUT81iOZA*Ec$j-^uiRy!#?LZv}h}S&Js(3eZ&kDXzKB#jOM)QX% z6oUe~~Af-pZ(p@uN`a0)+QdPq=X;f~I2m2wf zd1?O#mibfz^{ZBwGEWLJd(AV*351gH<{H!p=iKfXUd3E_P~1KQ{r-!P<*^&H-ySncua-F6H?t7US0WP?h8(7R-b5V?38#+FEJL@rf(`h2ep* z-)O3Gt>Z0qR>uH)8hsznC3CVL_)9RGkmPIgvB($%kGUwuZ1b8v4=LcZSnEa)(xSNE zyc%dH7e_cb9>zOLZFcNKpkw901FeTG7zC*cslg-NiD(3a+2_diTPt0uT5PUhgwvgOMpjBLnzT8C{ zNSq}Vg0WqTzL;7oE3L=88-7e~${4%vni8da*f;{-=hG^6Pc$jRtjG}oKTW5%djE`+ zskQ@ywG(+9e*Lwmvy7t2XcA3d$2G&I?vl0qT=uGpcv3$*RQ#L$UskFK&o2Colo@af zGW}0{_o}|zp8xJ?`wpQkyASq1Y=@Gar7>btHz_tXZE{1x1~TFb7`xqT{eZclHqsF) z*wJ`YuH0^fg}YRu^qoF5&{$Ikz(%eQ9Bg)ZEiX`z*;>DZ%<%ban5Dqhjr8=d{q~~{v%+2acn|r1ZZiZB?gr1^5cuC%bZRWMT^O~+yI~luA?w&T9ge+Y z>S%cMVidXqBnx+;B{H_d`{z!tc5BnN#?SLq{Ml>r3n zFPNu8;gQDmZH?>8*`aPQn`jMubP6l;?LGglGTi{_4!zf4KiT|DaXA^@`1|<%&iTs{(;TBBxsY^W`ka5=A45x^Go?= zmeEXBBJeU{yJyz`9yC@O1>OMo?4RLg93N~Rg5ZMUZ1#xiuy*@NkdTMyN8F!O?^oN_ zz6XIy_FaC^zsuv<@LXRF4Gz{fdZOM}jLy9C%{&tR4i40TbaoRRRznB3Ef@n`Tmc|M z_Bun#T_{o+k>j)D$`{I^Pq1RTg_2EW<-TkIee3JaPT)5)Yw2M9OE@Ls4?bd>5q3dW zv(YG;Hjnl+Y|Bjjo*kOWJp*TBm5$FzZHX7%r|iv=?nVU_7vXtFBP(?Qg4^PJ3^fN^y8h-82qk zEq1JX4QV5%yuFx(&a3=u5B}rC&(@_jCS0r(K?H+!4rVpVQOR)mOzM_#^4#<@UfcKKC+P+p2CupTTiO4o{Qfc5|1GZ>-_)CR{znB zo%H+<*6Q`V?)H)ssUtg!A7ra@$tv;vNxD^%W9G|ECK!Y)Mp^nHed*4mwdbrK zs4wk5D1n$HCmeCYY?pdRfvpDa;ZQonw)e2t(w&9C3A=y<85e*Ib`SGZqeGG&3qZ6$Vsub&hyG`&)_xBAy?qidOT^``UcKgC#TC!oRaDR=uq)2y|t-za!Y*qN@fDKOdLs`g$vvtb;vrHc@qn5j#X_~ z@B&|YO$xFZP3=ohf-UK&9n%p_U%5LrroH10=Mj5vwBzNlSz8uUC zeYtn_lcl7lZem7Z)I+V3k@C|Eg@~k@)moj5JY6T zOip5^uYz1J-|#QQSdUv!A~hw=W)hj@Q@Ro9YFf6V);Ct~R< zLXC%yc~#O_P<{tH$qWK+GiV452TD-Ty=(bfeS4E{f->O+Wx-6%Ty287bwokWgtk*l?Kmt1+aYnsUGR@A^cU7PJ+naD&tw7f z8{Kp*!nWE>fX6PH z3UXbj%A|U)y>q1^IS5>G44vyq+dO)5iCd@DpXh-8Xg#(5Xgl`BLH*I%saj?cxLz>d|XwtCAS<2l~&Ze1F+PmX2_A*z55;dArZ zNR4XKHGOrV-BUuDo}-|rSJBGOP|ky4^ReVepvd>KlU(Kmrtt7=Ytwy)OPUyS6;s0-Ecd_uN}~yfsIm$So#}BYiP#sQIng7TN*Vw&2Cust&JdAM-4hdaM>L^jNAhHl{1R zXm{GJ4gqH~63%=bgK$z9I1?a73+yZnl;Aa)cFF*{Yc~Fc*Z3%+& zX=GRO4F7XjPp$x1vsq`{5~SrrvN*Q{@oGQIjV(d=L{nB+r0w3Z+WT+$iZ5v|(qHI-|bO=AwrLyBs075KRd_#kbS+F$33CYJ~ zDvVWa_R{MPovFw&-G1my1d5`%YYv^M*fPyHbfzJeN$0JHXn2WbQh35cWMcNyrk6EG zJ{|-^EmOy#GYzv$I*d9*NuMIqk{=u*Lzyys{SX-rQ--QTWH?+IMtod`uA~l!fk{DD zab0C!j3H|F8FtJ8eU%J+EZ*8heP7B>=Poy8|DD}xKrA$6HA`14GBE=4T6?P!NK=j~ z{poT?m2P5su-(kd_aO|M7tN7cnA>eF8-@L#ZH~_A3hQu3r;EYFg$GDyNrBw>0Ywr8 z&go){?1(b$f%X`!ca*7Ok5Q%{*QNF(T%1j?|A=S`A)`^*qQ=S4S`IsZB>p|n$$OCL+jq!e1 zN_w`6*Rbjhx#lwqj;HY(sn{A1ZG;hJQ(N3tNIz5=fR=C_Bi?KOO(VDi4H-r4=^rmn zD}sG7P&_qPYm|zDq1d4@(=aH`sT&5xCq8}we$fmx4sd+!_LjwLQFB9#nRwT=|C$A_ z^7~N(JKNZSV6QN+zoI?j$^r1MDD`eUOIz8dM|qVU$F1-=a$Nl!TxF%t=vZ$KpU1s! z#2a_YlBnX2+V=Ya2a^cB$^v{M@=@2dVz2cD`cv(#*<06e`Wm7w^u28P(XSPl6UbDH z%r&R6HAgdj@bvA_ld{<*T!h$}y>5$acYuI~0|-RIBS_xpwcbP_%RVcd*SLr&fFS|( zB{*ay+nVa_!6iyH?1T9x9$a6U>XTNnadTE+%iVlOX>O^$Xuawxv$_`Es?51DFUqba z8iaL<|zyi;QbnM(Ya17fQ0F@m>5)jqfS@aOfRP zy{7g*5G%k-33ub+j!3GP-;YeYP4!l`DH4d+<7_HjKcFFTca z8H`dCsvzDt`wh1kG^zC((U0b3eg=8Z$kG2yawc+|t9Rwr5gHQE?4T`nz7(bv7s=;; zr`ICi%l%;JhhYWKh)Cd1*hYTjPkomBNzZE6LDELAMaP^PkgP~8YP}o zr>fy}&Ul~H{(X)t&fP5!kv)^=jnhM#%Hdn_ypv)4jG`e7Ls4ApN3w3}RwVS`q7 zAB0A-#O4-M8bw`R&)&nG!yoLI!>AWRyZZ^bx8h4W+F$&JjlZ)~POs8g9Zu^xt9f#A zPB3wmiG$G`;Cz;F5d7GhJWwQjwNLH<$;-$w zKpcGIpyrh3>M3k1F*mccsecq0rlV<izJT!%?sb^GruJj5SzgL#zqE- zWfeDZD}{o4usY^SRsUwcP0Lc6cqzL}mPGi&bQ>)03`~ zBX>IF6zQ2ZuWIvB=5GjfmjKR@#Wb*7-`s@2s$VFb4KSMm2Y{D^8JhUZ|9*qN}wV}Gu9&D~A zq)$E;0i|~Dr|GyECng;{%?zK;26Y^47_M0Ua@BLuP`2vT#$#k%qgpweP<=JzdrYfZ zcq0e&cpHt*ib^fFnlYKaR%5_*d;cKFy<9iGb3|0!=}`^|3fqp#?j^Z@JfF#Ka<$naIYP;7|3L&U#kb*#%`Bxt9&h8c8 zC4ASc(3N+OV}rpuK5yU6eC7KDob?|X55A)A9i9Sb(zN6-7J7f8QO&Ek zXX}JK;u+K}2+>xWNWC9TbtO`ny4355)H|pz_8gTP|ETSC)`nwM*UejUyniIRRZ+dfnoi^53wSpY09IQo0DsGKTYrl0_47udwg8C|Wg?J%AY}&V1L@42haKW(_-!YRaua z3|LJ)HHhu1ska7hrkZxtgt*c!ouLVY0_7C{+{Hw`_I`wOv#e*P`L*(HFdQhx%vj)$-g6Ig}+0#Y>#Wi@l8rk#Xpri}A%P|Ygn{2Tm_nppt^20<7tY6{Ly;mHC(efX`qA1ch>)5_0W+kx zPCA;NXpxOK1lD4TY>c%XO0dkbjWOm`-pRle(AUw8PXcZU>|wA+q&}^epzILboYY|w zy(bs(Zg6DdzYtU+Z#G8X17BtaJ~{RUFa|%l_SL<9gUH4PLAm!;x_%?LG|;_%U1Z}z zrfnObm{PUVYdYTG1+pDw$aX$H<3P5pQD&_j>nGtIYnc}o4tgj1oSbiqDWT{4`5Q*& zlYtxdc2gR*1qSFtCa1#{Q$pQ22Qi_or~{1In%rmDHoOZbugu6B)=-w$u=qsO2@t; zN%bsX6rYY(?wEUE? z>tOXM(&`hd>Kw5AATU*k;qYgm6u+Hj(<_h8D^&I3i&3*V`9H|yVODXtyzXq4 z*OTeMtdH;zAbw!)9oUl^nE>x00-_RTO`5}c(gLIpNQ9Y^1}LwczrSQ|ykWx>f8u-= zqxF&^*&;qg2SHlI)02!9>I&8&pJ4?`=G`3MQJZs6G6EqaEfDSbMAmQULtR5>|0+b> z)sEDAxmD=X!mV!M77nC_zxyl0E$1debJh`5XBO`$YE*PJAgQ(%1vC}sI!ZU98r5$= zRimPG(D>Wp;kk3!Ilm2{ zmI+YocRk=!r^z}*fQk6@t+ucb_@SH2Ea!Q_DB4|ig_%4 z02l3m$N7TQl>8g5Pvdf1tS8Xt8ob47EE7wv6Q{e7u4x-~WG#}h!#Fu``%fhmC`net z$oU*&gi>ERv6i*&$sB%hh(RCW_BubsyLFxW32reXj3w{ebHSTtDRc zA=mv}_jB#z+Lx%>xZu~>Z<|5!&TKJe!I*$$m%pv+(^(XG`?OZ1p0);oYfyPr?!DtE|oM=X3cj^R8LB%rgdN9_W8Fr|-s2 z{QB2qxiG+7r)jiKQ^vI?AE{=}gc`@heU~)AKl6p;z}8e>4&YqkcxQE?Q2P~~pZ=K? zosU=koT78%FHq`hXYyIDsg?0FhreyPo`!P8{fp}3{?|v@mOk!d=XU1s&)eHO``;p3 z7>U6e+JR>dKmRUOurPR;@V_}873)(`vF^67&bJrxSYBNjXUBtg&>5I}UN=9``R$CN zja)nTBb2y!HKz+7CC68P5!kAP)LMy-pTj-WNYfp@hH_&5B`66!gZdVgCj9FbC;ZM1M*AzBh5%7`+$kNxK(J^B_rd>!b5cYK_6`^7HdgfzYLwKdiEZZs(F(RVPk`Lep zs}Kea?`Txc;a2@q$k7y=M)&af<)sU7MX>=zg}1yF-)0%Y91ZvKW<^7*3%bmbMt6K~ z_9y6(ESDYvJnTpV=C-*1n_FFmGx`!HusvbXWkU!1I_jy*(Ff{9&!X~uYb3@%geNAc zYvHlTou5itb+o?zUsnQ1+Gkgr&*CVgj7CE$5JF-gf;<~3kg7x-=cakI55UNN1HVaimUM%PCX+BM>6{1LqeDKI5C65_iL#{RgiLz?@7QLZ|F%POB2> zIc6|m@P+&!VVI0VtVpR?WrV%AII@ zcluj>J^y4SQ{rz}N;tdgFVsrZcI3Y5gBN=DY579$#je90lN?2%+0Tei>9(nqy_eSa zG4wW@(@8k*Xz3AZ%f(7MuS zhjW>kd}KTvwniVhzkiE>#4xm0+tsDX0844(2c+E3bx;? zQ`&Qxe?YFf(&0rs@MDZ`Wai6MoEdLJ>{%0MvuEW)og#kq__YrRxNAB8>Cayg4|Euh z%(hHnjWD`_H*34{E&?R`W{)r_d0zh`xj&>O=;*!gKAwDeSmq&44V&8+mvOxBZd<oV2nn;QItQT~LpXr^_Fk0+F- zOdH)-56S~5MT$~EAIk$cI!7Dop!2@btgfq%bg*BZWaEkw{1-Ac@c-GX!HWENXD(xI znyO!ael>nX&tLQWfCm3}Z2BqrwTL{TXs=szznQ?`7olv~;cy*9>&#gt^{v!e?A@$IdB?V{4C4sLiq!d+hLm4b7FAG9GEkc{Em>a|#vhjB(132z}H z0i->Qe&E>dg(XRUs@hles@F7u+96dhk?Xb*lthL*i*K%G zeQ&u4Q3@*&VcW`+`UVmG05c_=C8#Z&K{|@X86@}W3+s_uGm@WK%=5A92)oHxl9Zh7 zUT@@$-m(Toj$2u46_aziw2V8vRt3Ed6u)v6Vzv`+Smi1-kFFB(Yh)<_X2D;jq0H4F zcoYKIcHYw%CXfs48fTQqGXZAGj@P+w#K%Tz9le||TjPfj`EKQivv?EN)ZF|117G=f zt7;C4qmN9W(5m&}tYM<3QJiY;+f zuSw_GB7gVLy(Sm2*lT*%(C#Mlxii2c0d5;OSb?k8uJ3~!CekMjfQ7`Vax1$UGZV8wjMCr^Ci#%f*WQkOzm zE@f>d;Zmr>rF3S#LW<*pB5(mrUXh`IP*Iw-DMI_Ad&31KkUOtwD$_rhSlMx=z*B8~ z2`JBTPewIw35`pnR+!yc7060NAehIR%iEdD==HO?>N@& z_cRjGlfO#rh=0y}HuBB;VXblyq}1YXTCHP?Yo-n@Sai7aiv-u&{J1u=e!SElbLO|h zUegcMc=;ZYb~bu}?x4aG6E~<{08^s z{6e=f{DfZxPN*wwrXYxp{2@f9zYbuf9rzndl-VQ79W8hAgd&EVvP74ibs{qJo9+F~ z3Zi99m%l5}2?UE2zy1|OFVGpBk1((}38N6mVcAboNQ=x1}iiQ(;DGA|IfUY z>L{IGcGg(>o+3eg4Ow5OkA@*IPhc{pR=1g5^__H`IguEReGIcF=<(OsxbS7rW7cMU zOpgJb>v1JL9u<`f9(v5oq_b$GO&|X9R}JHBiM)z?%-c}m&^|aG^mloL{^kbzAmh9c zXLf_ec;Wi&2!Y6{Ip z-K_WROYYck6V80LD3vct74wruy;8gA@+=0jKC>38+uWX7zoZ-lUQMCSo5?J`p%!tE zh&{w9drkG4lv5M_+&DTkdz0srrP^!0k@;P9S>^P3h}Jrsa;| zSL!+HN!HfW5BFBA=I-0cIpja=@}rqJCZag(cX*{JzU-~j=Zr?X=HH^dFiB}u4lQYW&nEKV-oH+oU!9>P<=EQCMZ=^_}1F=u5*Lyyx=;YApl0_m-4Pr_gohT*J~-;0j8^I^fK=C%&po*7a>{O z9I(8mi+JTv&_36)*+H`_2^GIkR{gK^^yaC%4CMJ!xLkY}<}u%5-ifb+?Av zHk;Y0oc-nKf?NAp9UnfPBAJl$Z0UoG$n<_Tx86Mr_PDibPE3T^n7d%Da@-bk(moW& zlKm0#)S!IFZKcbqeRCKWYOm^udbh97ex21ph*lQfi%kE;HnFY;2?jwK5(1$AXWZ%|VFZHi^*i z`ti}w`smgV(J&hpOMN?xYpHY6;n%4RVgC+Wk~SaD#6)w4&~kjW{jUvDz#5kGh37Ik8oBm@$@8u6|S#K*P_lh;MCOz;gTPgc`Y|^!(n;y1ux$5YGM3c z^rwreUX6Q`cF1#5<0*a#ia}8VoAgyqJspivIuc`AKC*ceS^YGqgQ zOmqy+)?X-u5`UoRh3H>*yiw@%iL^4xoZ^b`QBvNM&fO7c8E~%q?4k??Tqy2`8pp;P zI{njIqp8N`f^x@JhSv&bSU7vklX$>g8UD0}I zKkpgK-GZ!I^pt8ASFO70?VZ~mlsD^1sk1GQQr#M@ z@06x@bM0DgZkhBv-}2hF(^hTeRhr(l**mS}EZY30n)T}^wOvy_y;r`KmQSgHyHFG5 z`pG|&Tlw63Jq5l&P3nuSfRz(TuI76v>B6)XpaGT=f9uqJaJk{Nj{`SvPZ>f9=iTSo)$q)6IPrv(R(WWq(oaQyP$m zm*Y`bO1sYzDK%uw_*TN40AqIkJ&B^27%EO(~VjYVif8|E+ z7CQqC{Q(V>1uy8VB8rcf>z$bOIhr~pwKHMP-*chtx-uKbOCQjBKMc(8GIwN(k~>2Oi4Q1-qTh!FdxBc1`>wvJ@X|?pN5kPcFTRA`Wwx91 z)WCn9M^aZPPjYs1zXS_5)(9T6Kb{`oMw`U7Zd)?R)~LfsVS(-X@Gy- z+~&R|-{iEUSJ*veo>{veHfJm{)z8X4EUlfJIQ1|GCNsklzLkg9aY}-**^(3M8Y-4m zZN8R03PHff;5ief@1hR!TpHdsFz3?88Kc|)W`$gXJlcCFU=ACX_8D_lV4FsHR567!^qemf4>OvaFX-#?If|s%d za6dbj?i|?qxu^8U+hd}| zs&+3qvcDgj;exVD*q$>iR8f2tRgA$U=X05roa$5Qr7|ap_9nE02dr?WQMyVr9l{RB_|pOVnlNuBQ8D=BQBsH zJ;(Or!%XnuBdB0#Abb!O7&`oSsBkQexBY9RIDQiT@h02Yf!`W8Y#;}Z+bLwxxE;s! ze>`sYo&=oIXPona4o61Ly;~>YA5qo394yF%;I3ehYO(PMcm9W-{%XL?ojG zCn7aUbRtuCT5@GPy?mMF*c?yas5?vzy5fpsji~`KwdCbU4uV^L#toV~(r3>Fb0~K6 z0rk7GLVgG_gw5X&WL-mq=%WTD| zqG*-ekRDoaPD9x;Q`@HSChBB@*NjL_9O2hgq$XBy#FCmA@oUOb6U#XANlh&EYr?6C zVZSgnBzNvaC|+>vO?)mTb75XWzRDp$z9Wndev%Gbb{i2F#D?Gg9va zN*ALzPgqT#1{_QvmjS3!OWV#1cJ(?KjpU-;!v2lh<~&6cr=<@uhlzC?-XXg1JLH!z zDZHCA`Ngc|t5twX`gh&{gEFwH`05pe={pSZPzJ_{LwIMCwIo6}0M{T<1pV z@NV)IP~Hq$Q{cCr#T=kJlQiWn;Jf6`T`J-{K26z63gCDj=Z=MqCs5E%6@*NB49%D{ zo0+rQ7@e8n-Ga{^BFU1;rInZM*18*H%q51EIB@+{bvrKwAN*EHtJRRL_nxHI?(sS| z7P}@-$7#b1+HoOQYku9J=AWrTZsV)u&gXK?wkDrApvfHZxF$;{hWmVzbNi51_u_zd z2Z^-XMIX)g`wHh2#|<_iwq$It-4g-K7HQ!k!;SKaJ=rhxuh+D)AEXXH)XH2UNRw;dKm-G~vT`uXdAg|c zVwz1ePq_0JClyS?(}`NY>I9_J{_Te9{_O!SopIeP4b??|W*beWQx@7|V1G3f zClUrQV|P;3{Dhl_=-5utnsp-|+Gz0OxOn6edm1l94=5aOnD_xD@Uh~Qkx_X2B!%1+ z6haA&r`y*QmoH#IegCoG4oXuiMt3f_=kk>oE248OS0l;c0htRMx4V`oy)(OjVW;JX z^?rRIeR}nCZoa&FPo6#r5b=gBaC+=1#un1PnE-77ex5@y!+*tx%U)Qj5`V$BdHi$) zYV3lO{nnQNKUkW9Dk(TwdD-U0UTAkw>rSQLs)Wv<{h*vEvxpf~6I^3>kzrn1wz1~{ zQ7CFTZ#FMB_WUPW2L0=kYCo0!@V$0hYS(9I46P67mAWv9Ua31%26yMHD&^I?PbygU z^8Q>mAXr~qFfQK(i6B3|3;pdmL_h8u+>f6cC!_|?ojH(xef_g;JibnQ0{WGsTaHv| zbTlm9jVrh#rjP4)@feDMT;;%U4BrET4owYUFoWrFp@#Eg=vdEx(fyb9=jru8Iu?w~ zU^*s}U4)|7Ut8AVJU6{X@_*4aGs|*`@y@dZt1Spl3k=14z{WQ+j6dKF1`o zuZ@}%7hV>8l3jA-iV<;+7$UU94y7U_T{h}t*jQ-7JjBh$d5#<%Fq#o!nBcr2QoQ!> zm|a~axKe45r`=r^wnk6QdwJCcO!e25d=en*kLBqiSa1up{yC~1Ihs1Ij&nyv-ttLM zLCSdtHktL%GWUErC)e?2ZA@DEAssbx9OO$T#`kvB!o_ll`=>o#`aPh!v^~0`ATXZmT&mMZ9Es}6=RJEj6=3b zGg*me;gke-`>jv7l=oSN>M?y7yU%NVl*Xae{Zwj;;}?>z^rrR=eY0(tx(^H~;C(vL z>k9ZgCaz4j_XTC{^IBdMFi65NT4yNedC)^LfibgC_o>eXIL~yCg&rJ-(hQ^Ks{%yq@2#6behBpb1>Ml<)aZeYV*=h0XNRK+5|qJ z*Ik#|7WiY~@htRvCJW8N+*tfdtxz=c&D=Ok1IQ1EMa5PeU<^xb!B!3}!p2HKvANp2 zt&3O$?-O&p@zcrYdml!GRFK?+sjmUf`X(*O_m38Y~ARO$2yts~I~)t&5aJL78N76eVcFUirL8s~T|8Jf&<5$lS(3wzC< zBQFgWbJel%6n^(C`~pyTa54Cmw28%h$VI=ZM<01s7qGUuXV^mz^euV|PubbWSo};p z#vK_~4JxC4mF6qo+BJJOd9*$&))TWxzuED$CAmLLb3gD}U*;j+koXN|bJ@POhyp=;rZLbky*MO;k`;1f)kSunn?PMYe}%35xuYzp}hml&@5gS%V*V9->% zW@lOMeEpH)yC6+;emb*hCjR=y_IfR9de0j8Rcn>kq98!jXXWPLmj`D*2(ty`Gk(&- z`b8fELr!WX;S=P^qN30CU|JXbq-oV&*$X?c_G1sIDSwToCo>A583D9 z{?&`2vCMy@>APNnMaW{r`ATD7=Q1&(gjPR{w>u^Z~0#^ z3(x4@);&zG(#B)!{8o3O!meo@mH5^3wSki9Uewvh4D*`G_?C>TN#yh)mYQ9WnOjU9 zPnrr$UdzsFK5R&i{^UJ$u&FL)vE63&ujh)B@XtdM?n@3G;-Jl6zjGgV~dZ1dGuODatC~# zJ%Q)F>ngnFE|EX~mN+$OAKI=*SIsc0$<^#ND=HVDRf~W{is(^(Ydx9$>bc}s@*MJ` zUsIZyKJu-;z{;VoEjGF&v;CO2`fB}Kq`gw>-(RVV>iV_nO5Y%xoG3~xD}K*&oqu~f z<>;jA)VM!<=+*3}{4?I;qL?wyDdc8ZW*R5*xlxLtwNvIb>4228gXr}ubU0c-Npc*E zSGZer5GtjhiiBK)Jm-|6?+T^R|2>v$xrS!GN}*uS^>?a(KK1rpJ29e^B6_G|^w&7D z&VS@dZgdn>oVgXTa$Q%e67|Q&Khuglw;o6AxcrlVSjS zYZ^zF)TRtNI_kRp=>9(X7!9Qi#$MACt`-A*Bf$Q2-=4ngMIy^9?;7Pb%adPz(3-wR zdbT`ASIr~Kf}{J9D0{lT%kMvsD{2YMuP<0Q(U65m(g~ZRXl((181*M%s6J^fa_Er3 zB|DLq_=BN>Xu7E;0}Atg9&OfGXDjW~Y7_+Wz}||6fK63_B>S#q(8SaH2p!%2Za3^F zpWEBRK~-B9YR|l1DC8~gCV#De9^P7(a`cHQyewyPK^p!q_TB|N%Iezx&yWEk4Zafv zh1N^j#vZ6jiA75))C^2uqJzcODkv&#tmRZ%IT|3+%B7P5rqe-Myq(%sTWhtY7h9@T zshV&LpwfU&-4HNo_`*gz2AMmtiATyYp=c5 zIYS_}KI`xy)(B{;3?4L=FR4)8z@h}Qu9lfXOsNzGV(T_}+06`YHe6SlJeuAX<)L*H zwYbfHHJMGb&CuOgK5PH`0!8nI1v|(YFdfUtXh%$<4Nf%8+DLb1L&5xTBv+&Y> zjhTrpjhR2`kXjfJm_&|;Muo_zEAEbXV}nJI(- z9vvtcdI?Y$9!OQ9Yi@w)D)_xTMac%pVs0H?)O=AZNt7GDt)*g`15 z0qM2=$bovneeO&ayy$ZTvt(=J^h3DyJBdl~t3i3e)kWk3Xb9nk!S72!lx*}(w$Xdb zbcSNHZ)1H(+D;q3K+SFSw&^>fLi_zz(G%E`J%E&8cOO5U9UlS-Df`)t5Eb?mBnApM zGNqP%zO?vyl`lKPQ^Q4irE|ecUAN@vPc@|LTK{A)mGP6JXQR96OJ5A0n0l%2TbqC9 zkR__T7xB%Ve4H1stqbw9G{GVVJ<>e*edZ%??}q-pbOtT7!qOdjme&3}=5k+3gr4`y zBV6_&*DUe4*K8u%``dL$-`t^`oJpjYbUXZ0k;&nWZ*a*1qYiU10zUqVqR@3~;@P7f zRoGn0-{GI5%4Lafos(Mdul0(h9Ka9MeEYX?#XEK*xtlA_=QJRG49a2`z3u&5S=s!P z7rlKGyWN6Gi*gaZ?>#ovbruiB-#+%Om)iIC8@@UF2dQ77*7I}whlre7sCJ|`T0%>v zxc0qal3spB?kP)CwkW49w6w6h1^DfIQ4f**!=r3mi}oqN`+RrTEhYR*(Yo*H@@>zO zFHmi$`3N|Ox;7Rk^dta8&zFF+2PV@9|Cm9#f#!YOT0dDM?~g4hsoX=ZOP0HIdk!z8 zJ74KC-y(ra3*iLJ|H5_w|4>budyCbzB934kWBu8~l=n5i4|`5mmk7stw8T{yLvPul70f=;2C&07qbqEV>Bi2g(nw> zdK&)rqW0;8wdcy;h_8&NA5T9?28HNv_+CDi1|Qk)3M7Jr9m!6PSo$Ny_PjT}gRh!r z2=z^@0QGI}dV$1UuZfB+(rdv%ng_ilxbQPQ4j0~3VUSmf3$OWpZ(R7ZGyXX)ytjXE zTsWO4EDUl*u+oJKAFi^XNFnH7;lgRhT87cZ4F8|Ng~xr!n)UzVLR(b-bGYyueH|{$ zf)fQg!J1=7`o9+!w!;SaKNT0Qe{FYw@lG9ZAjVq_{dNGx`*5!WABOZN!N0@1=L`4eutr;iX|3Hf;9MZBad zl8>YrdjW64izK87N&huE)vzM&G;)wsBZDBkC75-kh(dzuiy2nVa6ywxf@a}Y3tIwrp>vHICEQ3& zN?BUS5;^fP(4~gxRhBnV%L`FeD{sJ0(9J;*-rI|@tL|{IelfPY==i|C zr05+|^i~(W!vgRBc_bvv(qV##F=aNQWd%eT8GM!-ckU0D;?52J z0@%rk^r|AY_;jxXPjgO2Au?$WM4w*k3TkO=Lg@efR9H2n-vw?4!C5mNMZ9ivBW4A> z2|fOA{N3120Ksm64Gb2_45~q_dLC>oU2G+NmCN+hRlAnb=&MZsfYW0B{Kv+X;{hC)ZetOlj}z3CH>KI>i8YC z+q!-y%C#|b-_3NTwyiPqjTW8!j}*5HR(y4@8#7w%E&B$=siBh2t5TbXbxPHDjIrnl zKV}2Zty#40@%f+CMG1CtUX(lNvDrIled19Qj}s4(n{t>|1h^L{T!u}ll<-4k&4LXv z9x)F(h~w1Q^mxg5+F(w9(FPN~gqQj&bUb}&qYd-|+u01RdXgzaA=z6~rK#*D3tGUN zV|Yz_{FCxOsnO}naSLMQ`<%hA_=kPXzAe4A%;{3%3V%Cc!M5UFfnW9 zc!{RXh)_(6JuFPkTMS|)^SW`)hhX8w=&uCs;#|4cbu554^_pM#A(&q9q8oVF&X`OK z*Z5O)I#5uY->D56qiGEwoheeZaiP0%%zY%_&qvYd$y6ZZp4aL5B0WbaJb}rnv?(8h zxrWBy-EN)(D=md}BGud-^_}!mYi4`k?hIT%aJvJy$K1Nk*>}f_x)T#2M91HDT48yu zi0whA;?!F*LcH$mz=tGCn^!MMEhB@{h6QeQ;0_7gNZN*Pr^b`Q)9tRyn7{m~-gs^|Mmvq?IQyh{W~EE=ir%*IzFT}j+!3m>!(PN&7wsG^ ziA|Q0dnXTV~T0hGrL9cxvzmQq1>m=6IggE0cF`hOB zMw!LBb#ix4nZ+^l>o=a6Fe6?!afX-rC10&**Z3)J{!E_Nvz5sFLibE)hW1*&XStky zCh5Frh7rMq6So)WY3G_Lga%VtBx$Vs2h4F5mW>CmOyCKdj%VFR$FqwU;xyK+Ys|LR z$ZOAyHv~$a&!JRP@;nJo_Da+7y!AC+>0w~tv^SzW1`Y#g;0jbyV_@L%xp@NvjoCrr zc&Izd#aHW<kkztu;~+-@u+v4)FLE!&6-IFVYPmg1Pz+)A$WSJJYGsh(>1#pwdjpfJmz%GCPEtm zc?@1N7VH(&w*hM7HqyL$ej?-8rK)7KATn;deEdYl?Uaw7$T(jMzZu1CI} zIM$%iH_KA8=Ry5U>weq&={uf*zTpm)_|G5W2upse;B{g5G{YT`Sly< z-eq~heH<};$5M_?xJhLq)oD^{JR{SPn1<;8#<=Z1c-+{#3*+`bXXnAjZB239 zOi%Q|hA{pe*xZE%G4>e@VHj*Kq+5CTWUOrT1fcTUxB;Q^+ql_?RsC1AMJEuGOk^6+ z=>xpAPvRwe0B?wh7`z>*+qeL4DEn=TgP9M4xBs1SL%(tHIU4ZBxUI>XE69ec3i`DL zZx14d{66qzkXGevJ-BgmwjSKLIa?2I+?=fkgS0AV>%kx`u=SuxsFE5p%?R*j4hrvE z2e5~k0pSpyUOJ(JaYGk_til6d~ z?t6FOOT1!iBgpN@_&7%j_&i*lpD!O|Nc{o&69c`I@dKDsqfKlzbrc*5L}QSCTSyg+ z52&KDvbJLzJ2vP-CL6BTmG_vGLKAg8jo!q4{>~?NbCO%flVhOfpx8CUO0!dh!(Jw( zev7WcYdOG=n7pvP4^(J=n$o253H=$b;R3B;{mmPGB+s77ORTgR(x=X4~oT{lu z#${vGq1i8z6X7l@iJ@0U*46#c@HZ2flNu5o-W|(c&>d~>3M*Sf`ft(pU3hyiS$(U9 zzx?c)A$AJg(-@L@>B|Pt%fIvgU2rY-s2`R-6;vu;;_X1%{9<%2UxqT`>B!;EK%n-k zC_TRH$xFO{$4=vycVJYS6R`|SU&h<8%SiiG(tcU-yi>Bc_PI9_voRKW7BkdOR1nG$ z?=qgsT=7KMeazn=676NL^$f-*ICnMeUO476p`m-Sv5}$d<)OOQy;jMe^V+a9ypO_V zsG(PQxx(M0v%SK@3V;6K@V*Lv_~7t<3cvH<@cs(_@xkF03Kx*~s`rq(*PH*NSJ(i; zF6b5ZA;KDag;f%Ea<8y~gnhISmRxga-Bt}$^FSUOEF5!WXy~?VEP~#h2a(IIk2h`P z^e;+=bGFQeWyUPi7Q^{EJ?1)6OeVnjs=)(co_3)sgYeOX@OY+jS-SE%nGlNAp@tRx zZaTVQZwyxTr;jp0UgMp3sV?slj3X9JMi=3Gqr6s`0*-Ui!vmVu^_(DP|Dmwf>bnV87!mVOi$I~fQUK-H24hQESz5%o8E6ZZL`19FciH^@GbzEuTK@$Ih0e^Nl(UrXED z#}zOsbEkOZl%oQ&gFZ5e-E*AY*c96Vjk$P*@NXdGl<&`FRv-dYPig>u4_`Ck+97RQ zO%3b;*J>OR>3kJ;yDzcd8lke)%EFX z#rr4T4O&*00#Mt8i{;NKR^T)yO|uCT`csB6o^f(Sc{MoabJ&;IQ2DEHVJDNozmmJG z#>|~!D4-b3Nh^J|52>7PiM$|^t+T(srL;fpQEgKGPpPBx1BEs)4b+E$B1~akt2xXM z)PzU0lcGQeODrA!QpgaoHPTj2WA?`*DK3${bvn+Z?0s@T+N~;pm49kk^U)7fjWBT3P^RSNcYf22`>TRX)`4y;-gVs~?1QO;}882=jW1{jLPdoiiZYKDR90nU5 zwxE>4R^g-M2qwdFADoPGl`?fLDRaM2awlH)6w5@crCVUdcXcssYUu_G+~F^?!1ud< zgmGn$7jDzsS`#D|63;A|q2bE>ZnT{AJJ5HUZg4Fec_wpEV;a@dF=Vtq4l`Nxegsz( z_~H77n^xf;A|EF7U(&6kAU*FO)xKTra_6hMbVy;G^A zdh(~P+Q!UmH1l}Ne1&HxV8QnDNVBf);S)@T-P*QPJ%ngohA&ls#mOR35H(XwYtv@L{r4>kSV_ z;I(3-cH`wccr9?0n6IJEI*MZ%XdJ~{pBnB^h2aixrq^oPlCEGUy{dxGWu4Z4)cs}8 zLFFH0>58^^-Q(8Dw&cD;qu3XSsjtEp@oco1W~&CLf*6h^biTXL>29>7(l7cgmFE53 z<55~+{FHvfH>BHYx5cvOV0Ct9IkYv{8ucbeh2W0|mS-ns$Iv_LY`g31;Rkkh>*YHe zLOrp%ea(X>HMQw6COwof-gXpyai1WX;JdpVV15TzfH_a!0!)Y$9@FJld+sZQ%YH$i z!32QIEn|TO=eOFnfUneRB*kc{TeHB={n9QNxcexk<1CdQajcY(ZUgCLr38BD)bTR~ zpC>+7QRZboK|T69lCRuQK8o}TqS1{^P$Iq84{Zg(XyQIW5hZ|}`V3X`1XL5r-tIrq z$!m!|N|POXGHT@g8Bj(3s;73#en6hSu=QTSa(3$-$>moyuSKn0nLlZRVZfs4x1_vl zJp63!L#N8kT&o4#*wmo~jOs4n8#RmMPu{l^Fw%PMd-}5#sCU%f=mNrPOn3PXe=2*D zQ{pAmbi6i~%$>?+N|W`@5@kschqfw>Cbw0olVIICR1Y;`K>WJ4L)zVHTnC^M)I(70 zkd3WaS;1zD0BfHwFn(NN^wjP9{bs%s7Y_t0dL#z_B2cJEQ3lYLoV}9;5uk$ z0VK^BawIVrN*bVqrXI}hSGoeXUj8&E!138|d4B036H%goOTxqj)nU<#aybs;#r-pr zRkJmKRnLICgs9drzr)2u?YnO$L9FHr!|l1>5_-wh# z*#dk>R|W7f7-2a-&V=|Yo+!Wvhugw?wsm4e7s#tMf^(^(bZ%gpm@mi^8qq6${sH?SU!1ZkY<61t37eY%JmP zVVGO=KfMK-{ulV82lDx_t&aU~ATzL}7tMx?rt~h1X9rhHPCCz87XO}`6fu;==EG~; zQMi0~#TJ!8SG?jTSHa`MYb<40e0VD?v;waIT%X3K9oTy_`n&x(h{`A8JVa?dlF?fD z?HZJPr}Q-M;QPu4&~?wi!RTY)8lmL_2B{64+V{W6k1z0*Ve+Aeiv``j@7VTNkLDWl zGrGpyElZ74;@OiA8E*Aru_P-F!CpR8&;5BSqco;7pALCV}n~w?#G9XMX??+<2-*WkBN zZeIds2LCo*aN!vTjTbz4d>XH4VZ7kK2jdkjj2AZ-ZoDK5Q8Ti3o5}YI)mHB{Uf+ou z|Hhd&{Z_PN@lIARLx=Ri;=Ev!fb_Q#d@|4Nc>G~-;-ZU|i3P{I()??}w;D6Qy_o?2 z30R2HMZZw={{3&ERJb9Sm9R$(0Vtu?WhqJcfkS>M-DsX*6YnRuG@`rX zg-^w#{{oe(LOC$M2nqb!X^@f=_i`u`2^@Y}v9zU(i4AFKryoH>2O~QC9iFdcFWo0T zri_HM`PN0ZzJj`J2;gZamJwdvm_4e_@Xs5Uh~R?~W)LCz*oZYkM~Zvdz&JhwcdA;F zD4`v76xTd7v^RkeOcSy<%PCn*b#@fNyGWG=M$D0lc1R!pd`F-Cn0u z(FWND@G4?3y*s8jg1OVM9yf7gYE$!(S_R=JN`}wvB^dQX8T3=bA53p@qjv%&aEdtL zPy@OA(1~F;Bp!M&5!#vvJ!mk91$K=egK;W@SBL6bRB8Wx?sGPHC|M6Zaq6_16Pkx& zxjnR%>u+m-lvjlJ;jIeqMNcDoB@X2<)pZ&4W%Attv(Eq=b*TGgSy?q`KysSF;ty87 zu+a}TfHpGMY4Nj6TmKDell?Wo9V*6aeU~yo47R+vt0wS6-ZgE9bc(7Ns3R|@oC=J5 z8xfLenPOJHWkovJKy_3(cmrL`1fs0c-IT>Sze2~!)G-QqOn<@u&VGRXUMvmk7yuRl z7j$q{7E1>gvklqG{`T5*IFC*-ihglC+qWO~3XmLdH)W;!75f4MpWjI34R!{3gRMc{ zU~iB&*c{|_y8}KA((z??U(9Gky%_Q%rMz4(RfV*~L2TT5fQ8v^O+tH?E|vF~#QakE z8gatCli<$An|vg^SRStk7cf)8zKz-Q5Q3S8EOYiE)(VT1Q{OSCXODVViQ?Hax)ULo zO&H){MjC@PbSj_-7K#-XQA}8<7RUk%1&b&Fq$*Lp(9jWz`hZoWkqN(ASVZFiW^FW8 z=%q(}B=!Yr_eY0sN^jC#PxjwIgTlB}0Yu3o zu3JGBfNjr>X(JM(3P9$^O%=dBcpw;rA*6#qS^&{n&bC~dRpl}%gF#Wd1 zABdr*A7qpJKDK`$+;eT%t|$(y5aLh&ZgZr5=l*I7?3|Wp1_Roe`?YL*6c+B!y@y2t zAmm?@NUONv4qD8Cp)C4m{pPmqamE5f-9^IEUKnUS-e&4rIv2c{yG*=)F^lTsZ=f^9`x<(fH7u?4-mM@b865ITTy}POclTcN{ zgi&rPmh~sDn2Ho>EI;D_aze4qUJWxTNi$vqNX~nd)+#{)$OLd7A7`W zp<0hxeU8ATLHmPc5Uj_NwHm8?iKqUL>V3a0+S+aYd8~as=2!mw0`Aein9IfAs}CcwDxb}}Pz{Pz)(IDX(rFvi=GGER7{pM{Ry(;jXfxW|+a zhrE<-Q&`G}gH=x35UxRebPe3JRt0C0Q^1D=mSIOI5W|e7J7mX?t(LuI5Lc?1)gl~X znN=?Xf*5%71&I=V{maiCJ{AUnB03Bdb8Oj_pD(@ zoCPwYz?*44AX8rZ3NVAYLGa-x=onB&+jJhA)k`d##EOA;pE2fmB6EwcAy6|SGy}GqAEd!9PBra^;)G{A8RpnVvBHdJ+a5b)QzCn21nE8(_82Vd*dd!+ zw|cGT9V0Y6z*~G4o_KmU;<*s$FP+9+(8NwSU|d@sNvjTx3Qf})DO|hI6ZBUM?_`l} z$9lp(CTvK0+a=zhr=*G?y0r^Z^T^sw+Wa8o;eCBXmjVc!ACU;bxF1$oA+>W*nMQP; zJrI`Jg_{vqAD}Z&L){~DpAsUEhT2c1;O3!|pfjZ^pPOi^ABPsqzlfn*xe?ZO!UjG( zgt3r*C~w)D8n4XiVT?s1av+cuFz_AczOnA1JOg_`fr0(@U=3PBJ`L{x@(k=9is9}c zf6OZ~u!k}tlgbJlY*7nSP2k=e&JzQT$vOMP#K%sAhGZv0@=_u@voH5!M&qC1so`~Y zZ0SIgv6ng?z+*)2(`0$A4II9-pB`R6dQ{Dv%aI}$qgJ{OfUypL3%EfK0VHzEU%?&_ z6LqZucxhoT119__co|^Xy=8Mg406D(#{K)1h%3kJpld0&%pben9swj+fnKX#DJNIk zzRd#(`!9xSV?mpu2xkAnd&dY=NBy@(dy*9 z8GXEEYY*p3tL}#%0kZzoL*(5ck}~0nK+tuvKv z+_1XwGrZO@ws2Rskv*Qx=mGk@%n}3VtdVMjkTWtA<+Yv<-LY^?4U=~kzRaaF%P*Y~ z^5acCe%qa(;HDMAWbvl=AV)Yfq}ThK)(SIQe-Uv@zv^$luMi-F)7O6y3M!FasS$CA zFt;Z!?*`J?NmBslORG(t@^f5N*@{|=2O&AcTy^!uNSFaL5{?~t_VFN_8}A_4Hu;l} zd=LgwW`!=?!A}uJoa+ePbaO@b7C8nV0TqCITtB%e?CX2$Ul5^czOUD2t9*n`JxtU-L zPVpAM30&qY>_UOE#`bf$+eDQgyO8O{exUezn(4AVu&%s@oqO6BdZ`AEYIM4dU|Td# z*O18QOxqjp_lQ7U>9m@Pd)c-rH8QZzqc$4jCpWY{<;6PhK9q2;p_|=t(KC3bawE}#a_n>)?K* z&L^wT133D;yTLNSHkY~?s?Z^a@r-!BS*cUp@EhO5R{WdDO|V}a{Orp~Rt{Qk-K^UP zcHisI_`Tr^kEA{+sfSJXsZ*lxPRn$hO6TPgH$h+lPZ)}DUR(AmB`3ZwWOWeyQYO^7T60**H zu5ivn`;(iGN0bKe5^~OrbA~dHWev119c!8Q)4;z@u92Y z7)aeUJWPA&)>1h<49nAzx_D0R zE%&b81PV&C{X~vT_Jj%qw)UeVn@=S8+zPDUxf23dS>fkaNMC>C+(`5umX>g}g+{m^ zXo{vENpFY_U)zu!zc0GgmqZBaeqofKP}cluQKd+byoDZDj-G>_V&51xNH!FqGare1 z!_i;OQ>kcO_uS{Bp&TsV=EI@7u^9Oms*42mM5K6dlk3#NUY*+LO>9rTO{aE&4bto{ z{{x+BZ@vhb)&IAhLNxmFe5brZr>1JnqxrCk2dke%kz$*j=X3xnUm;4#5fY(=AA6Cx zXI`^osvrb*;RlM~5O96C(NjG^W2G0KQla`PJj5 z@ro(lGTD+e!eGnkYz*6KB?L0|UM{bUz!==gJF|ekV)oAMA@=BL8vsOfQ}cEidmtpp zJxzHhBQWOC2!EusxejG;@uo*G=4x)-L zWek&=!lQq&&irq7jRLWahH%Xq@bQe)0M^eV}<$pKF}%d^R@u^y}M3wb5_5U z$EqtTtT@*`-&;Hpv`9yDQ*iTiAxAqM`cjiVCNd4~L=2AvguctYPI|p~HWvTQ*L6>` z+8sl|)4T_rM^NFA>Md#F6JqUf(CViFIAbVY%U;CIO>p4M4ocCWGXF1k8I_aBWy#|3 zG~Ah3dbKfd((id!ce5SG(tc=t=oSANF>ae)$s4~d$R~5yHG&}?7~GwDyU`m5kwZT< z#%~EZv|IrP(k}05`_GprQC!}mA7bUPF$d((+qYTyx6_3pIn-R^M-MJ;*8#E&Z?jij+;3uCZy0;<9J22ds@|HfCr&DO^Dlv*A-n(b$9t z35+{?{nIP);f2JpOt^-`JRxcbZJ2~vFB(})e0p|FxBtQ~ZHTQYMh`y^O#rD6I?D4p z3f+vSS1R56_V&zQ1ie+xlHP8BgW)Ka+g)!bW}8ne^Dk4iO;$}~)59ca2))Szw0!d{ zt+>DwN#|N)BNIG#a(yTy`dA?m1qJV=ib?3E@9%ezYFVtC`!=b)D-~djP;o(XQ@d<& zv}&rbd#$-HUui>;XLusF%fgT;#dh?IW(R%BzqPmq6s({hxS%q?HXpPgsJ|p=rVA2q z=2O{v3PgQ5IK67z8FxfV9m3at2mJ2)Im9GS#2omIa^SbeOYJ&>nGHCm>1Vm#X>39% z>htCP-vqA?3b_c1mm5=6@!3J^{0E2(YIk{w5b#;#&x(Z~#hcEU znFlx*ja?~V?h%r>l8RXi3(dc?5Uc#^BlqBib!FwKkY%bTv)aB5;IbW7v9B&WxWjSD zVNTLTQ8&4dzg*ZS(v>y)xvw{@nW?Oad9j_j;l83o^?TEp|ae?VkI^ z9?0GES{~1{lRg6+;@t0-(%@FL9;X`R{@I)`CS$CIQwbs9&zsczj0_3&n`F7 z+Qjbc_6>H@1l&}|6q#DNj?J^uUDj<_@LcX^FXiinmZ%CJk?U*6k(h}7VH*yxYabkg z2mOqJIq(=9Qcz~~fq36bg=uI0@ci^oElDrb-q-)chC*q%QR-Jg-}R)-2{k-k)LG~? z|FvH`k>(dy=g&eHh!v=_(0cznT;NPfpHM@>+%tv!5=NcX)-;~yuts<3hJn>9rgc2M zO4L$3)Q)BYqBrUzlQ9lKdX;Dl0*3`D(wS-(Z5ti zau2^y+8`zdm7@dcB$rAzZfFvt$I&0zZZGpfK zIGuyV;d|Zt&PO*DG&SZ}>vjenK{H=1DR%W*$sOV{N``mqwFEz8MXP2Kgl(?$ADSNYSo>u0BaeEoFm z2b~RTW_Mzjfi<1w{hHLeJz8hPv-jY?&b|`(BFw{gI7XfYiS=y14htdEFx_l%b zCsw+TuMbnx_OG&-uT=9fcDMVOCn1g#pLZW$k0{ypAX$ZyJ?K6@o72U6asBk_|49t8 z>;KpvlHq;(KRW1ti~8T9{{<3Ejyz#Ej-eEgm_TAJrJ(b!+=fAhcR>m zO0N05szZl!${p4j%f|Ob(`(aw4BF-{_;Q@2`{>S-gKMa}cK^g|%^~8lR1V-6TY8%p zt$Ta!3k`LD<61O~{+}DDqY`}Jj*=TViHUXed)EWQuDo}M*R9tbrCsQn797M;Z-%-z zan$QY=9k=479Td~q0IsJl7(nNqKy0c7Rwj7oxylCvP79VQZmt!LHmX&lcxXP<02OmuqJ4 zxMaEi6kOcgU9L#*w*R2Mw>XlPZ|>e0h+V9pOnoF%e?l&U-;Rt+*&5cS3Ol@mP zM6+}Eqx3(Xofs}ZV+KZ3v9$iDaMw|JelL$mTF+M&n8op?$?uY9NZsbEUStCZxEO}GD96+f@`(v5A2KCPD^v6Q}8i>AQU8*l3!?*3Q^^{z_ksRC(eCb6`k8D(5TDUtle1M{(Ryqrq>1 z(ZCg5JUg?O%u76-Gv=s}-de~ZvDuR^g~)5OlO4r9q4E60r3nr?)D_Mngugrdx zywi#BFCzf|4EdX!zl}mZNM^z0Eu7ebU8hM9Bln{xh5bjIF~$4t36$fdKEba7rhDK0 zhy@JhSChR*r?O4PI0K$#qD$Xd|BBj6_y$Wz(Ywx5K_Ep_? z*P-rGs@^iImfDC!%rDGr;a)avQ+@?cKEk?@AsD3=R8izt|5oSS@>Rn0-d#roVuqLo zSrM^PB4HU>hV%J#aX!B|GxsfA?NmpAosja$og=KxcP+?3-~WM2<^6Iqcaq^-GlbDE z`J27!9Q*o7hS8VP5O=KD{!7E?T4(e@ha%2Qf#850D<0>dLYt54kSmOS$!{4VJ61FW z`xhW{#&p_f=ZY(?6Qo^tX72u&36d*NI$ z2RbvTsB3)zKD+J>dfcqc>|y(Bd-eE*+y6z6pEq(pa@?bG)#K*hOU)l=x|H$S+S zhX=hpHRz?$o4xwC6>zn+TiU;$QM%~*q3R#UrOl=5v+8qQ_vX**BYxoUrKT)x7CGE* zG6%+VkS5ps3=nX}Oo$F$o;}1DLozr_$G91g|LAULd*8|d|2D$vu`$kkIh z=4|z@WdK2Kf<`@R5lN}7m=}V}a!}WC-p&`mH=6E@a=eNz>`aq--6_0EMa>)UXo{ zA$q-+tWw)JxzYmya^82|V$~%#_gQ*`>qM@RH6!|Ct+!YYIS%NKsZJ46c*s^o?H-NM zPL3>$iy?*PmF9o5>+InCTSN^53aH@I$kv)^Js`kOSq9kag&?EO9gSlM){V|y9->ea^J*dcs7`Pw0T;&0HbB0 z+&oqkhN*NFpyQXiZNjdy6?V*z?ZqK-dbx3r**>w=TYRt0S^>5z2jq_Bt%K7~4FBMZ z($gl|3o_Z4gMGDtK+63Dl&TYBySI3fj`i%wo#0ND4xAO% z&mnwE9_H=)_U+Gku)OrL;bnci#z%0Ff1739>ma{Xj5Ehpd*$HR5A7|)Za+A7Ah;#S zd;7t$zf)dsMBh)bV|$Ay0}~}(3L{7FcGB`f7i5q&SQHO3w)sWzmbSBCp=WLj7KL{I zgO`F9wPp{@~bd4?I@@M$$8xm>83&f&Rc zN@Ln5@?t6UuWGKThPub|?V2I`muqp+SyEH&*)>!6jn#lp&whme+xa3nH1gRs!g7>O zh0|(g;U_oE6*cdQwG>svi9fr`l`5^^17F4<53Ga^Qg8H3RU)B%U--EOdIb8eq+?hi zmA6(nxne#}{MxIUj|&-#s_|1u_q?}Q^Puv6?#g?Js57S1a|uNej>vv?#m)Hd|AHl~ zLXkU35K8yI@Vx++4FLi8yRNY>qWPlh?fy1GWSp$vO3EtmnG<%p6Q=Ug(;fi(5+Y@3SBSni$Ge0ixy^ z2FK4lr*+E{8Ti0YDiEn82%^08MDfK3klW}gBw2Jq%UueioTMj?q7_sO>R;tXs_%D< zRM!}PCK%&3_B1<{Yix5ju@NLUhYM@|3)YOt!1HdglD2qDd`e2LmfkbOD+fRd(8J^n zpcg9I;4P7S5da}JTYFG!fV_o#^|ipXI^g*`O2m zK}i>yO!eI)8+(JHp%MGMB~P&d6*m0AN+D?`Xek}}Bgts#+g1|I1+XsMkoyUt zh4rfHC;wQqo<{Qpw9Dn@Tdv61;X!qCFAA!f|5egh@yhiDH5x?F4jP!+rj@&4?#a}j zACrq9vw|8=pv2%D;NQpbJUo zLS|#my(;9weT9zYHnI6oxt)}~CBI@1%{^?;NUS9DC&5MB1n7H zQG4q1=X{&8=W`v*eY-pcL?c9Ph>`G{6iKhCP3= zUfnhGm0l|mo{uy8NrVO3{XX%xwkLO%!zi4%A-S)=cl9h-8tBsR33ULwI&1GB0D--Z z@nJIY{e*p&cZ{z9$oYQ6zQY~kE0qBSllI-WW4un8e0SJ)zmD;PY;Cl*^W8Ci2rM@D z=29v?SMU){cW3ACkEYi|hqs|W{oUam?YTZ2gp>RGpa4Bfin2LpG9VR539JwY;+rUB zLC5C6&)uknFlz%p`}%&=J}&EoKK6#AJ-j1Q$Gy0q0J3-?L2R2 zT9Y1>M5#|*_f>}{*YrV$WZh%waAtl#7ZcB<+NicM-C84;PwfHvl#41lbKt!l%Qk^N zE=Z{`&*S$mZ)2!}@wO}^RRPgOKd%|1QA8lMn4G*W2MXGhO0YUWB$!jQcM_H3l%BY}GqbbWBpV)JzVIW+&ty#_UjH&8=Uk`~YdZzfX_Kc&$gf&_1L}Zs^0K z+I++d@UBQ+ZV~0Y-pNNi?jph#K?QyD5x;T~eJvsg6)(C>in{N|ji$H8vf~)#wNYND zXaD0}fUx~lNs>lsQ7k*?P7;;Pxe%%um;>^{iO>!_(y)~svs&Od>oGxL2S1k$TzP{) za$nyS=3cfPXyg+`DIF1S_{47fPtE(dmAzE+M2H$PNPu zItmx1!Zhy+kv1z)_Uy`b7hd;x02uZnYSedxRKPi!dT@mm(wO<9Wd#iA>Z2NmM$!No z-`1n{L8Cc^KZd?8rhii1W~L2KLv{k1koGiqjT@q4LkYSz@l|Egyrk7|1{J^N9pH>YPm+9@B@R#j9a*SMYX@#FODN1@%E zp8cpcKhv`x<<9c)*+1uXStHZXh+cw8q4r5qhxB^EJjtPX^CWY>!lmWbceo_Yn^q(3=&4Z}(;J!;=0*caUJKsSWQ@`Rq_2l-x&*avnI0tK>$h( z5K^X;nP+Chnc*r0_B5rw#VpuGn#f(KmI>L%V zbIX3#*`%hFKDayxMu*PUlHhO<%*)ezOM?3b!F|2fTZ+MJ z`Y9OJfN3(0rr%7yifZ7^(cupd-_nq6csI&kC*g6PxlPC(rG}Qx`5N0vWKw9WE(}@9 z5ga%eMb5tgKdZ=#W{3C6vc|G)YT_=loeg&INXfGR)Q`mKX}Y&x#!nt)he}s26(AlVc=DOEvzpsz~qY1S0**2 zSADHD7V^IJR2Aw`8dr~e|CM@fKd2rHdEa_|c~!nYO5^I0@4r${+d=hM$otk4&DX=} zNBb{Xy=A}QcT(opH7;Abr05rFGC&GRt>aRgO+4>k@S+f6ffOqWVHQn$8G3#6+YoX} zX(uS2a_CvHzXS44YY>V36SQP8!p$R8j;1Rx@zttosTaMM+~C%2Z0w+J{mt&u#w+3b zZwzb9e9vZ#*`0~0Dwe+(CY;yNjX8TX}V3xoc2DnFk-gBCjcZvNqs-}ebA<8nOPtY;f)z;nC&{5 zYYZ5L^%g3FG>Rl>{}6XqFo?SXN*FxoIymU?u0mT97$Qb}Px{G3Xxk;ri9@p|ov4(l zv$b*dOsW zpXU}uVfDEeF1=UVhrY#}*<9HGr1sDMm~E4kfNa3>gV!6&?Il*47_C-;>eGkcJ`W;p z8+Yyip8^&P=&C_J#ieA~s#wRKtvqyTC17Bd(-!<)N!am&rpwzrU9XHQiijhR9!yy& zJ$TH3a55DJ)sbob@m2vo+FiJ>JGlJ;zDSKM)+ujuz4gX_=gNGc3gzX=wypufI~kWD z=!fFGyAJG!AU_~CK@{%n7eJps`!YyEc@NtxtpZGkpq5zILN zG|+DCkjk}p1JXw0gw~*nS`0MQbh;INZKu90e4`6@2=Cfqh45+@Zd6pD;99z_|GAQD zR0;JmqSp#U=w5qG?kjfL>ArQT)&mogJGCUYp3C(O761@(7&zU3593sp`!X^194dFN ze6*)5H%UIAq%1dHJ{`bvb@=kgDt85ERV{qh@$3B%d|x4Efl2%W_eC%!goLn1628#2@_2 ze#lHPBmH&P>eMx#pc|!hR~K(z*LFSCm5ZKjYBVyxlh}4FbDM7W{p%qfp>QgR+s-p4p=o-R5-k?Slv|yoBfG z$=L=U$P`7+&z*m@Y>seY%*WbGmZPzw(mz+y2za_WmVfDs!q6(R!k~Ag>X%Yv$ZHhl9d4dr6Il+zVTWKpUV;?zx!bypnug$= zE2%V_8c!rXieBAATd0YTT<3DwQb4psv(6tmDvDk^(<{_+TxQ?V&t0n75YN?vna+J9ohU_}n1cSJaQwLvre5VnbLE9auG;oU_kJWWH)@{*gC+(OLB#Y*&`vF_E`cQWKcb8dWMv?Q8*FGM>OsK4fKl42tsr6@k{Zb-dCB8BVEYyB0! z$~phE5-8?k&Y;+99Zyf3uBwkFZJK-NhpV$w@<9mmH9QP~N;9Vu@mh}q zDe4q-G;YS;9kV)NbIdu4W^Sh$ZiYsLmk4ci% zcaR1nMX1Lh6lubxsyDOhZX6MEZ>*pvl5p594_xTYv>>;TSffWdI~m~yWj6Ied{Zmi z_^m=5gFG46xyUG~ai8+K*ynRNi;c*rpRw#bOk+(%HYRck(bE*&J!c4?$$T`5DRhC- zu4E$kOlgFfJ9=2H<3%J7Asj6U`+2jxMjJ<(*O$%hZ!GCK7pfsE)DQ$x?EUDpCl#}O zZj6{IkLj*y&D_!AWbcH!?55Od&nW3bL|-5|_hGMFUuI}-V%|l1u344Qm(KfQc=KP) zs0vGuhlwEIR>EvYOy1-AXUXHnGoErvEPEv<%@G^u&tG!u3FHke`@7`*V;RVICP5d; z(k;7erOn_wgU9?p5-iO%L)7-Z zr|?DS*h3dHcbeb=|6lXxO6e}ns4I+sX0iHvU}m-Lz@*f{YXV&sY&U@hY)`tHB5g+Uct~BK_eYm+M z(bb=LHJh;|XIlmRkcG@OvtNR%Zcp@2)egn+IYQQjRzJ68gF54NkHoWItS}++PBeg3 zp#JM{N$KoA#9KT7kEBZS>c94a6lxKjZbm{f;$&*6kV>l<(U{J{kq?>p_@?Oa&h)lu zcGf=Fo1L}Ww!X@^z}h-RYa2_6;{Hqp#|*b;+>yF1b6<#s9&Zpoc?FXjZ-N{Q_o$M5 z`KDMf*e{*NjM`1?9w4qrAF8hO6768^%G??|D5!%B`hnDD49Y|M@!z=4$xjcvTz*IP zQs+>0W<@qZ zH0+NMuM@@mVR2r?8&hE$k02difphm(`WNskkw=27fJu_6SlX*PBcAKvrpx5hGAp#( z#c5RQc)~RQg1XP(2mSbpv*!S7;;5)T;5ooc?4>r7&)|udXs7P+CU!8BZ8npAOgfs1 zrJA}=42Y?$m10wv`6w*QMomdIYL@%ROs-QRF)=#`goemeUYF^>GH*D_s^LAOt8M$- z=WIIRXa9gxl$*}I!E{PjVpUo0N+R5Rs$XB^%e~%Wb(ZB~F0vKB=CP#zM9}|;^&h`@ zAw$&d#yYInY**(|Ss|lEE7~e}4^f#Pfb#bnfIY$b?_<=UaFSq|5nz@z0^7L9NOPUm z5?FdTs!yB?pCJXa!odijwN8o!J|uYlkVYVedEw`O3*>FWiJS=I4A2T>2L_~e?ADM^?pD`k& z8_p15%dRE51Hc#6A@bu!(H)pqZ9#V1(H-ntqB=x=7zzpK4kK`=eDItMm1_f=Ee{*m zBwEuo7yJ^?9a5z^Rhkg0j%q8SZrgp?t=L;fwA*fVqa!IU7sUZ=M-C;+G(~SLr8q7J z6Bxy@R>|@dhp7(zBXdu_X|Ued48!Zl`lNi7YaOA{KIcn?`n3-|qCIGY4QXk_#oxqXjF!G(G$!^;GZhaSe10NMs5t~DWff< z$O78p4VF8L^_UopenQmpExBh1G}>ah?&nzdPkGCJ=;lNO1#{vE3g*NS6f$}H&k2gI zv?Dwt>So{P`JzE%??c)-x0tcX^B;_!fcS9)g=9Y}1A3yABxK;2FJ_2-!vrj$2@5lH z4AIjRz5RV>NHpPrGbBFWKcAuVKX8VkB{OugW(aieX6PNw(2jpLLk@2MhP~%W(9uRY z!9+d#eiPM6py6Nk0O5Kz_*Y=-KtrT%b*R7f?|heFqb+;_|M|_99tV4@p^IRj%{@sf zP?aq}p|l(Lj=`m6i-4zm8x^tiv@V%;I}Nm%h$&>hfrlLeEIs89?uO#WJ48e#4~nIyW`Rm*bh6PM{whOZ0m&ImDxk>%OvfkFjeL=}MHZpg;Zq z#>8lCnZK@CNQMMA2cobOT-)f>=YIkQYbK=@Br=sX(vI7jAsp_-k5$QRED-APdB5iR zG)h_EeNIa6RLh_^ql{~!W^^26FcR21!JkJ58O>^OMql%P1fM7quIV}=paWd!VnU5? zYkARrT6x?s>hs*)M)CmTsR3P_el0pRr_es#eYOnSC)WCG59M*_rt3g++*1l(PKAKa>o(FQRN-5Mv(ORlHHIJ(KEO+;X zR|P86itz5jTw}g<59{_P7)TOoBvW^RlRGSo21rKjRzuRQ`s!6xwf`e=5Y^tU+x)f# z@CX^@N!+!6DS9?m$P5Imb%7Mv`+Nxx1rM)Cem z^}E}PujpDV;E@_T{r3{_;T;_dUd+{l8Kli0&#Y8~?uXj|!je~iy0d7Yu(U-6b>{J7 zU`Q?fW>7849PK9LVlb^H&8I9X>r|2a5j60gD=H{`Cn1a{iK>!H)REj3guwU3$3La+ zyW-tX5|>x>PRMaTMPL_hJ*0O#C0DSX^+(Ln4_wYQbVo8$3>thfZ&C;vRt!3M>$fdv zWFe^PmNNXL8XW}TtuMqzj+_2n%P_eRRJCF|&7N{MlUySW8dV7jq z+l8ow>>}p%hgVcx;2l!*Ru{d)0&hohIX-3%D)X9x?}mc!M+M)_1>eu{{fHcDG2Wn_ zJBnVBkwIu%(Yvwe?F_sf$?XN--wM8+_%0?tKoo>gQ%~R(%>8(l4W?F^{sZA$j!o7)X9iFry8XUx5#0k%f}p@Dg)nK^b~&aOd@TiE{*Hr+7Y2cNmj+({1>u71>d}k{(iPbi zGw{G3=5DGuTvPJi~{qe zK|+>03=92{Vtd|;5E`pK|HaKu(c4}0_7uG%iybK|di|hA3hNHM{%vU?VPlvTbO#*{ znIauRE4kYyZGJjTl3<7b{3W}YkI~GeCez_GU5g>tyFX`{I?Y#li6Yb2%b&SU_$__Ce!bQ+ zSeVh!x_HyXnR}LeL3tapW5UfJ$y~1+avTIA~LIK3Ot z)eC#U?30|2iD3Am3&zYibyc$?Wzk!}$Ata8DB#{{?MoOUMiV|^zCmOQ= zAeEFczP$Ap7ExUj4zBB%_o?fpb4%+w;h?%)>FJd!oeCpzGQSz(>Z-u`fVzGLU%7X` z<{wa3n<&!*`<1!#c9kFUsYzAf46~Zdw1iokJ)S-s+_M_1?SunHF=Dm7lt6(Tg#H(T z+JbkoX}ibPn8N+VjN9y?4-U|DC(Ea?>90ir@Vq2YF9Qe-)WNlp-W@7`CM(BlT}*aF z&AisD@I-kSg(&YXjGF$neQ$Yc+x%Ja?C%!}tm@D;)9!O?1O z$Xk3dp6ul?m5QcM`-+Zy!@I1qil10j1Xd6KV-ZO{1!pVa@FeS1qlM*Rrgr+DL1u04tPTHunOiGlQ;vCiEh`O}VYYG+hmPv_1 zQ@(&ALUdmF^Py$n5T$i)Bvlc7J2#Sw1mDh$q=p3F&W+fqP5G-WJdzp~#5*^V8X0^$ zH-M8%f3a&ZM+wsZ@Qb?UQlSM&4vnB5f3>FvU%=xO}L-GN~IZO(Zql z(o`j#n?HdTcvh)dmRG4WDUnAiS79o*#o`p2N!`qE+AMrzQX-ksN&PbZ{3?&qD$hc5 ztCDh=2aAoQmIk46GpX%_a&Gp6$mNz)fti%(CKczx^aTv?%XIT=!Vp*)GtrEAdP;>m zwYe8578xf}d#@rhsR%HoM%_RSz~c};^_Mm}DwC?_JDt>TCMA+7ZG=-MC88;v)Ndvw zvPlh65h`ki#VM4ttoikuNr`^qZq)p7^XoU05)G9$N-C2Q6_rlvHC^(+IbGbQAYOIHIV{UtUMpCy2-_DJs?g+l+ zA}|9H;>0sMc~nV9RZh^ypTIt#j|$;I5(zng&XALSI&IVzl-7{E91fy+MMr%Cx?>Ac-F{Oc6}Ab*>ogeo5=n~ zj=h9g-q?YX7ycTPS25*BJB|BqeO)5Yvt6$?_#4lXrpZw?NMP5D3=)qlYd*#$-s}>O zv?18w-)M=OYeqJ5IB!HYEOF|^H5Ie3Ph@T#X&u_-wf;Nr%qKN5Qv3ZspQ&cQkVs?g zy2IaREKrB9({vUV5S zYVm~IyesKc&fl4{hNLGC$(%JPJ$X>(tVnutBy(0}dU9pvtcvvHip*Kz^yF}+DjmsP zN@A6pe+QJ_m%9}nbMgDV+*9JXm&9Mt>-!nfGp|}Zn%B=1<(1K;wO-B3Q!90yZc=|T zsdQ3z!c$;UnN1auTgVmaa@4-Dz_xJFpGg0uk=vxk_GkJwhT8M|iCCtekr&Ag)v@%r zow3Y>UAVh&(W^bq$9)<1Wn7e1jqAq!2kt*`dvJSj-^G2mv2N?^Kjx=6NH&=;dm#Tq2A7Q3(&SwPpyRC@K3ETqfWW7FI~; zfiu+977K}ThB_0ku18y+2V2_tsu*_?UbGELFW}%U521kJn)YaVgKa)cD@~^GpTIQa zZoBSH((H9<8q$7{2KBB=Gp{5~zlW_Hw}TdLM zL6aL?F;5>@%tgH`mdVnf$>n(SO@6H;n``oMF6SuK*Q~nM(b}NN(z8yJUnGjvy>=QzoA#T>9y=V63k~BxTH2E=dGrNEU z!im@GXqIsx36nY;Tt4hlLl>qjy+5HMirvxxqMdy`DzOhUsk@`$mf5}@C-5~FZ$oJEa7YZx4wd|Wus$W2i*n)j0`u42QuIAj}y;jdxQ53X45)uAeXSpK&nA1zmy-% zw5Q+Uk*dk`ORT;Q>_^)BMH~5lzT7_0X1(5D7{^bsX`h0F`@}rIr7``FeA9x^jRqwEZt%B;;WXeAgJ-`y1HzwR<}3{*UGe zh4{m15@J$Ie<*S%l~EzVbAsR{!J#0xe?YV4gW0&(Q;sujmp^(Jo`Pk=x~wd-ht})O z7nrGPpJ3ZrHueoFFeTJTg5MDJuG!F-{q}ke*?;j`2Ln#BK9Q=#lWpjqdc|v8&$C+E zx2%qqWoI#zkPaKA02DE`c>4?ectcejf0i_~URynzU_E$ZTpI!P8|C9CQr{^bKau+F z^6?X?-zgtIk$PV~ej@cqpj3_HCsN-dAJTc(wK7Jw- zD&*q_)4*O;|5#?Va0^?1G`YXYyE@ItV)+Q!$Wi|fb8iD5RdwxuXJ7&mh-c8CSf$1q z+n`9H1x*y&3`}666OC0cDkwG7OO;mC1S0YhIy1oWIFMGYwpz=r+H%|4YEep6Gzl*W zST#_s_zJ#q#;AZ+c~Qvo{q1umZ{WT6x&Q0`dGdid`|Q2Xep!3%wbx#2?X`hav-uUU zIa*hu^Fo+oW4~m)(dcBH6obJ4Uc$ZthblpUY|(%x#SiF9+JHW@anLERGp#kxH^)`g zS(FBPL}aPwe!}p}f&g2_m4o>l=fKJnu}#Hg#h;YhGYTrL#8)!or_1T#p?b8`KM%U%ver@M_`FB*~=zmf)8XwF4z5WREJ8bt40vrnT zMDJX*tUg+FU%T-Lj{p#y*-#c(Z@busHo8Ls>*MeA9lAb#pzrL-(Ny*cPigS-Rv?gR zSGf!x7DlBb6f88sLIv|pFkivJCg=~K^79zB#8O3THA zS_QB)u0AvT1g)ljj})litfHgLDjKo3Tgh)}!f=Nv30(%yz?IQYn4-(PJ5HIa7)ubh zg3@>yr{PZ&JmkL#FA@c-{Wl?u=Wjzfg-M>f4ZR7)5(R3f-h_LJg022rk$Kzhzm=Fb z$?23cYTkBvZyEVfqCmnnk~1O|&R5eJMR>9m3eWK)mUv_#!QJ*=j`~c*U_U}!8Qexb zulBgTeJ`La}lE@-oc4=$9AeLKfn^h<*WesS!XVF4-+8@~8?K zi%iB6e%-gGvf?BP6vpGMH;N1kqqx(KM~Nj-HXXK6nDL@GJ8q;siGrAUk+_Ex@r|As ziINlqRDMeBq*icPg$7x;BiS(l`_ju`L~X5>iv|-eoA>q%3XenBKgEOA_1%4hMp1w{yIjB}GG*t=wH|KA ze4Gy(nBE6GsVqUoC=s3zo0oos(%ja`6rk<#4tG$cg4^8J*oAt)(Oeb?9C&vP+g#P} z-2&{HoPG3tK0##-lIbtgaQ~e8PWK}*y#@whKF#2yq-c(r4-}f1N28sKrWao{!z#aM z2C%SSwEnyo6K{9aIW%OY=7@1>W~U9u8!5;UQ&sh;d%H@P7f4iW$?eEknA|hT9ZSu{ zdmK15)ijF0^h{u;0x|qri+7G-V3Y+iA@hl)9x13J$<5MAQpJP;oAS%Bf|q`-Iblq< zNYC1U<0n0%oEWd;={|=7DvC{)UX-6(z_|^1Bf1v$zDbj~+I7PSpG4nwgE-*Br z#e4WFtgjf;BbZkn$USG5p0kP6OasT5b`bJ`DLCH6c?aOQL~sO7UkpVbgoE8R;Elv) z>$Tsgf~d$a{l5dc+YOL0H3G?fWvdnV|` zD@-uUr}yI|gz;boxI%&Q)ZD&-w$rPZR@E6!x~k{&~+%8iwzMsbr47`CW8!)h8G) zxV3x(lau#kPKRIlt;KBlggNd(BT0hHHM_kpGOd-IKW2LeNjnNIq2Osf3yyjPzp|#Y z-~}B8KhRn5sRoH3Z=gO3HhKgK?s6Vhm+f68A|vY4DI+Y4Khs_&n#Lb4&r)O7D+GgH zW=%NYR#TObGwOYn8k1CNtaz76o#dxhutg9B#OYP{45R%Fm7Zp`d*Wava{34($hlNt zr-2jJT@>7+nqU>UIok3gg9)yZ%w_EeC*h(bj5X5et@x`-28NS-1)Z(&(gYk6wSmh#l7pN`xTalRT(jR}F@^!}IBc+A#-|frbc({xn4e3FJI)^Si?$X+?-6H+Bvb5Zc?;R5 z2HDXB>`9-u*wQdMGMdN5AzpR~r9HRJ$38q#yb z8F=#CX>1(y*)V-pb@L3j_n8VXUMRXWqZv)jO9sN7u2M2I?hy*Yy>9vnmf)wNN)$IWBeOW#VK^d<;~=jCmtmr*mVGvl=so_<0Z|DBBKd-#Dt>CK|n zY9%L7nU?pf&rl15v0O^kqjj5L96K>~kox(G=nVH?*6>W{OW9zn-|m%DsB0+iX?fLc zOC#BtXatN=`<=|j3BimpIZT~%^-s*cDazFCvTrJF8QJjhZ>{81%q*f#_PQ0P@_=*L zfbm7l=8}>cC8UydbOio8xz)g2BnY=CExfpC1{5aVq(FT|{>L*KqRPX~v)z3+Y(yy( zlTR@y7ho9DIAH?S4Y67YG2X&CB)c)8%Xcqh~ z)*itSvJJNU!8|BKsQ9_rZTLkgZ z7tdZid-LqgGsrW@Gn;2N&ptf+SgXqVE;+X^Uccbfkn((D$aA2zEbx59{z%T=j15U( zbNr3ILpR6w^_`t>Z_@opsX^bzXDKdkZixmqwZGYAZ54DM2B~~5FPgd|ivdSZq6Yv# zQHDb8|~6;TCUdI44%>qwZ<{1mlyA-dE0NjdT98U3N^&=uWQs_x1NOv@~sm?qZtBb<5X%X9r;1& zNa6WiYN_Unom{P8Dp^7@Zw;LZtpq*!j5i6mE#AGUlxpOs2_#Lis8YXs$`~np8B>aJMssVJ!%)loJUn9ge(@=UVRiattJ-I z9isE>x$-iyJ`gFs7O_~1+GLpGHD;)@So)ap(1WGlS6@2DgI)>dB9cVzB}k0M1o>Mh z+#8|(8MxmepaJ&>&k}m>Fra^QD)kBc?w!O6;6Ai?s7!0I{DOKwPa5#AQ8%H(kXJU8 z0`7E*@S$GsLH(|-Q2&!RR@FEAP*--K4!~5mPIud8}0g77gh; zeE4UP-CDeivOV~pLVFDS|3lRs3V+j>ZtyoT&KlM0ZFj!M#>t2M3~SjswI>6+$F+}i z2eOxz4~8i%NY762bx@L}L{mT5db#I>C4A)++>u1ohBamyq#hN%j@;s&tR0S_B_*b4 zgU58YLJg30;Ja=s2u9oW0obf;X$d?0@*dTI`o&V-KeV!#^3(-B(-85QhJ<2gnquE| z=Xz!OiOQOu$WO<9o&wDmsYivh)=QZ^W#k4{W47+%KVnsRN%=i?Rf=D?hv&6nVvot zrm5bK_qzL0`X-7q@FE_;kAcRLv7z)2$?L<>BQ0K%wJJ-gPn)mm48?a=dgNlIAs3EE z+L{ewD}953tWaIB#3iQi4R@*#+>>mKJX^aN=+R29aY16pqbL8ek<{SS20}E7ggK^!~KdClRlDaJM|I3$l$4C zNIuuJxTmriPG1Fo@53vTE)t~leoAlZfT#Up`WyqkgqlZ-_b`pq68TxHD*A+%TwK6< zUXiT;3w%XT0apBq-U`41RP<5+o}eP208Bzwm~&$3bKzat*FO2CIUJJVB;8xJfZ1{e zXlSg@bS52Rx-xna7d?PY#)W{p`BeXKQ#wj(vC-O2qi}lzU-fgt^xdHdMlxR@w(l6h z!(h04)4AisEnr8dEY2Oul3qh4;MK&eC4SzI(!W=|&K-A|T;8hro|ZRnywk_1&&hr4z13VA%Jjk=1Cmc#^%_A^q>EE->GT|uBN5!X|@<`8~k>&f*SuzunOrS#6s?UhV?ak zw%LMZSnZl+Z9gM|#`r+&QmB>G?G)r_mmcCT6@0o3j{hW?1MXXin zi5IbdiE?7fet~0;(?OHp<*?@P{B?+Dmwim6pmJnGVk3w(&72Lyb%T}s6zL-SZ5SNg z3WE`b`OVLqq~^$jvr-1y?hD`+Cu*(4B}^$@+vwfuBi}F53`UC&SP5;^dR*W7C^vv+ zRJ?9C74L_geiv9`JM@G9d-~lCJ@mU+O-jMr;%f-;1>ARNqj+i5yV+;mXV~Z^+=gs4 zg!oHFSt}(C-jWIN6B?VZ5I-S2B@>de2S3S#_zB@9nGip^{AXZaw$F$~9~bPqCo8?4ja%Qwuj*hSh3RMp#$7+q0Q@0Dkr8CFY(sdv} zX#%o*J2iZ24zATzAMb0S@z7Ia!GQH1H{IS~CEp=$J?pmS#~sWWKf9G^p*ZJp>3wKo zQho`z#aRdKy_lsdh@nM;>gcI=@51X3dME5ZERlQSLY-5`DyQwVtLy9b_aXwn`gc$p z@RD+x4g|SbqY}?e1LZmzN2v2J3D=Fm;BhxugmA%J<_rgDT{kInVl~0J7RxsFrlOUv#`rfgA*b=i#8^{=2#Na(qj51c@BuNh zRx;G-9jFsgGC-00mTZf|tHvF%b$5dmX$38nVlBE-ZR|YyD!B!<>(A2!q`yN3k3Xas zqtbTQBCkvz3m-vD?(64yotO_rq5GLDV7Phcbq|~^9@V^#&rhO$X2EZ3}?DxFBDB@%aHVXIzuax`_C@b#MUM z#|==!-?SFL;GtaZjI%Y5bb$&Ewaodlcj0E>awDh<^4-(n<|N0?XKjess5ys;onK29 ziX^(T;7hZ^6vg}LN0{fOZB*t`**miyXj@FTGInkTbDl(UN#5+5o6I*CXpS(Naz*71 zWv%h1b6T~LZII+M6vu5_g`3g?nF&6n&XC-%f=YNspvMs068Frn`2@E_M0F!;E&78I zgzabDw(~Q@_NQ#g(mTb5JCAGGaYtOhU2grozGa{MJ3RlqBF4I74PnGXT9__f4`hLO zVPpDSKleK^(+_8bnN^kX)#gcKSOYwSrh_pVqRNj2_-G}6LV!rJSc{HXj`Z7Fy!4f=<~c<``@>ek)FfY+_ia}^K9=GQUWR9B>up|m;7ae~ zfq(Em9(bQV1lZ4z=Wg?%HRbOJP!pdBcsQKeYu&P608ReO0ICwQin~Oxgqj8|H{`XF zk1KK16gs8eykC)Of)Z`z#ArD)tQJMsCetx0@11zzFGZqTObjjHvVj5fow z;x}D~$1NLzw}V56K+vBLnW1Jw(L6}c>bKAlWYG!IhLAxRQVeRef{UEHgchdPD`?g= zGY;t+!Flse-&)c$7`P68`qJFhhAK{JNk@qH?y?G4%ldgRA2R1mX80{*;R(>4<-5dM z$x*x+mQ}XUYRie4lMFr1T|RRHbLYnClC0xnLzTc8JBM)_U#+f@VZl%8$C zKg&`BM3u$F9fA89oFrXrd{72)YsHNr|6K5VgpCC`avwUwOr9YX--2JuZirYH zG{|V71VU&fo~Lcl1yOmX#oKgZ$Z1eL<0#0m4uz^k;}@$M@X)zcV{VDr8_VqdvEGJz zrHw~=SGSQ$VtI zRx$3bvPdvc+DDW-`)fpLw85BXyy%atrWSp|P)z(gxGq0c@;Ms_bEnp_?}@#$n?1Te z8oiUD`{~`_yyKJ@^56*rM-TqBT%|c%sgIq5=D+XLFm(5FDqKy3aQn6;yzumiV#u7| zbC3TDRCfbn1uAF9lm79?-V*;bSCP@~P1d4+=hO<*vx$X*uXE3ZP0i3-D>+?9TAbRD zSw++WiV>4C4Lav9GJNDSDd|b%_V@~4*}2W_&x(f7UpphQs)@^K3Wsv~Cb!702d81` zl~uMW+_;a+fKUuQZ7qG32^&t`^m%FO!uH0Uy-*x;FK_QiD!4{CYAqelH#Qp@?3(f9 z$dxRt=XhDWZuGsTQ!|@%k=%8s*L{;N5;)~|*Q&1vv#(P!5knUFfk8w3EV&8u<#nyx z(ZV8nU5j!37`6^>x!StsJygDRMCu;NgU=Ay%KyDrTUWiw^9BB=m9S4guaX`2v{!Lk z#&x^+|Cy>g=S&q&>c_kt+^eYUQC`$ly2JIFZHhXm#0I_YQr->to4v~9T}PQaNW6;O z%XRyCfu*?WGs3Sa^G<%QG6jH!*F39y2Z^Hgh;_|ca(+xsH4CSTSG{HpoLOfLtXxjq zHhrz?uiAzK;*xrz8;E|HtgQQ2y<`oX`j9oSww3tp*1(Egk>YLE;+LR{@Fk4W*wh#< zDcPP~I&>|&di+6J38@MrsR<0$X92q?VwVJYUP&dq4WuNsAwu{lo>87h^NjJ#<5|IT5YLNw9>cSe=dnB|^Bi1#7NMzxj^jCv z=T~@gN!oXcU_&#=caB6(E9nMRQ58B}nhgj|K zfYkV2b~q7C?i+)X+qe$b29g$>omuPUyx%h8ctM#ss42@ zDZ7%rBLrqbjyoJiF>MhI*OYGM>d&ZCLF>qS3%#Uu-^)q=RX0aCC2Dl_HC}@UK(j=I zc*|b-W3zZ&5TY_T*q>0C+xK{iy+*})#Z`X`BFwoH_#Z>8{>paYP-68Ts>p7!_oOGl z0;udg!{I@H?ZGK~(TZ_&H(4=ye2dQojI`zzY zifg(%yX=UoEvIfZU8Qe>E=RM&sx~&{l$0O|+U3hbIScbQmWFn72E`pF9V)Kbp?D5o z)lQK1+%sJNDZGLg`nN&K)OF{bsYi9xQJ<;jaw^KadmmoGveWip*Yh~W(U>8#SvU;w ztlpc~t37i2h8GeHay`qcSg{+GWz|>mJPQKja-w@u`_Z(^Na~D~6UAVZGq;k~jh4Jq zCNLRM-A)tzRYe!`qD&K_|bkDmEFsj+P#eFnKHa@XYz_Z{gHwqild+I%+rA+4b!{gOU(0$0^yIl z5(Y`FH;EX57V@?JBF?1<2m-idosVtXh;j_E_wrqN)vczPrDqR#2p1dGSB6tJ!b?{K zW2uWD3bqZ-;AgbzTX1W^(qb=LQLK1NO`EQB8bKlM`Gu*#6Jxo|v*i)Vq z<3KRLJmrzoatv^zd`>q*L2iP&CMRq^QLvmC=17azc{Lx_DEHQ3W|qA%+hOr9uX@A` znzclqm+Hp0F$BWE;vSxG#Y-O1u9|XhEikYqbWef6%pFD6PK4}}UsCEH{ozC8&PM(U z*6ZP~tKNIeSx)QDrqsnpVdipsf&4XuQx};|3O{10$@Sc=RRRef0l^N&ino?kEa}Mx za`1wWZ)%WTf3l50n8r#N9WG83+)s&}-!kIa;h`)=iDr0b6@NVPN4cxlBDsUOksmy+ z#;P%0)+5g^g;NsaMpSFrH_4a4Rq!`>W~RM!0p#UOIn3S7=V7z+K+tGh%$jk^TVzxQ zjb)kp=N2G|GCc_)J43SVcO|)z@6B1o9Hfk}h*sjy;B86b16-RYRuBgb)a_237g(hQ zExxWWL+8U+aQMsMMQ4{OcJvwA3)A)Sz>==+vKEy>pja*0ilzq=tS_(H9R}{2=W?r_ z0tPDL9*>|Cdcr3alef`ojKxXy$wc}sBMnto=&(EXWFuS9s6Zd69gF%>jxKAHM$5y{ zWCaCe2*q0WTOoRHd+F&QZ87cF5Sqp?fzS3ECr@Zkcf)*d7xWI!5Os8tpA$d4Vo&_F$@No`D&oIJb>1E8P~QH-@x zv7cw?5bme64rtxd?T#!5KhtNy)|$66ya0Te$_)h@l;RQgLnhiPK*~e|m68pQYZDLi|`qs`n{5kXlYRwL6kkn<^9s>x*`8jSm3i|AGJF3+0EqF?w zgFW~aEg`g)TN0(6>(W?njW?s2IW2G|&@x)_%$S5}bf$Uk$);geVuD1rsdHXLKJK;? z=bj7wGA4cLtqgr;JThct{z)T0@Q8@13uvStCR=7)!$ttDDd)$yPoKy%GJ+l=(@E01 zogc^XL|7Ka@u#)}8^-Q{^J~pPE76PNpIt7C<36>LkJ=M#gia#4H1W2Ts7Jz9I`VBZ zFU1ePfr zs0ADSJwfK;z`jm78ti1NrkgXbR(1~3wU!m{wGz39LQq2dFMwc&T=vU6$KC-)fCwlL zW94u;aD3z^UEs*T8Ym4Ez(NK}0|l^QfQ9-3uYm@O zJ^Z})NQ0k3IUoB3xx5VI`X358`#*zR#L&er$3CPx{{5$LyJz8-12=PTgaQRHAj{OM_RJ^Y$QFS)j?@c2NH=W@wQ2Yu57Gtl}!pO;T+71y${qc_v? zj_m+zBp&lcE)i)ZH^Pp1e)cY(!cua30~EBL?B+9fCEs{?Jr4(nYPIk2<>ouxwFm=P ziqf|u`P06{StCOb4jL@y@njw_cN>Bz4P-CW>?TKMw5+EgnAdlcz3-YAt2z2Js@D#A zi6lG5KkdTz_mbGW=zfz47G+r>A9OKn^KL)pR>Q^8qoMU3WjCFYh3!IoQx5#;aSfiQ zTIZ4(y)T)5%3c&{sYfbWS$y58Nc-Z(??n|*zfmhdbwQ!Ew20+1;ymyWHEKCc+`zjt zZhGh8y)sYYgqN#2@}z<#haSkgKOl(^`XNpwU_!<6cF38%g=BFauMpJ8i1iQH@_r7x zFAm7C@oL=JhjSD-ecB$Vh@}z*GTL(2KwuF(>H`k)HEQ3%#q%i7W6qBXz3Uh`J!CHw zD7df+ZYt_5lpPkP2u^s0x$ZH?T6!u8@Yo+9Pal2RV6oOa-=^Y`4X7*3VF#=Oz40Db zH|9u6dWZ6&x>{$fGr)-yzhotD_G1Q@SN$W5o@3}%l!2=0+|&uj>VCC7ugBlDI2FUi zHM_#`y+?pm#)}mhnqF8V29<+bJl|^8`Gz}QI zpo*}r`y96BYODI0GLG;>in-^08`l+1dx;eE2~$y8Oy}mBAE3aHj^T$dUTuAU8%i1Q z{vbNF>re(?N8TTh_xnmmL2S|*Z@8P3mPi0)%Z)GP5Q{qPIz${dz7+Ic=5OHUuHsj% zM5%_l>Z7_bX9kY@G!+>UNZk-9-fbmh0>sImuJOGTFXuTu;(IIp0Nv~nA5{E1hsI|s zUJ{BP`THpT(L>|=D*ji8#^)$rd}5Dsjws&Ek&^Ch??>E}9&!DNE9((AfVj~;;&O>Q zsUt4lbY$^n0jfF|eQ4d7V*|%+Nku||u>Ew@sTmQiYQeRlShmPBTshkuaK z;iQObQDe?6D$80r@mP_CYPKqfEW(eg*sJR?n;e)`omXBJ{CTPUGBe`*RIsk}v{0$d zK2jI7zp&ud_|AZ}kNP%d?3t>k1LvJ+!-*5Ub~P$1qAnmbf*U7dRhT>9Q|=EZo7xei$3F-A*KH_0-3z?ajP8WBQ5 z<17A)`+<;J;?fa`O=!@0#~9_3WS*FyRpzc8WZnlojYx=hL>!kkx*Kv?DLYr3og$ z3v$7gx|o(4~3MbK&kz{wdC&rC5khv ze9o`h&(x2rn>!l2;j48cBu&VkY~^H~pBl4UR0OF*rEDOW{q7@ZdPpaT4S;68C`w5NHVLI!WJ0<&EYx`HXjS1?!9EF_I;dvz}F5uCSayp~E_ z6LoH^ji$oLMUA;&%y`<^!2O~z&gI|Ma0FLXPT+hbEAwrQk_p__5ILeH!M5n};{2!w|3usZmF;9EXCv!fg5pT^j5Syd+)V*2d1z_B2pw9Q)3daw+rsRpBo|CICG}NFIFFd#qj6^)rnoUZiz{(&@`}r1 z3Y+3)atPya#l3>*bc;fRs&V~ArR^Qfh!S=v8Fg-%{dxL&W_p?Znwie90QUN^ z-fWJQITOunUfSQx=8t;L=65}-M`p7(gEf~mjWu(BA2Ool+_QLg&e@L_+!wQ1Q<<~O zT{CUX#i%1Urf*{l0fo_a2fUo_i6gFV^1v0pyv z1Me?rF&VLYs??`KPyH#}U_vSeeOhhC%LT|c*lrUrVG2!c|10nMQjjz|n`viHJBqgyoBIr;K8j6O7O^%NPk(ah?}2Qy9ltpzK1 z_xN=d+v;l#c`mD3r`r);$HQ0S-ZEz%{(zA5vc?Whw$G22Ii-|fZdErb8CDu~FIrVn zt;yY_%Nayq2W-HAavN5^>}HI0tK08iySts&W9oO#`Y;65-7DKJZ*`nvma7>BIo<_( zk=}oh{)yB45lB8f+$*`FXb1DSU!2;*KinXQ7mJK8Q=d4d@Yp}fuL|vXkC09V?e84#04iQ(c6HCGb*i#>A-W+b=N4E!{{o9zg0IqNv)uz6a+4DV!&wi;pU&zJz8+5qX# zKKbUHtl38^79>1%gQ5l#H7nQq9+lZ&ICGJ?4-h5Odo)=4qL;NLeULq&*=H}rLU%b6 z)LL4}^588CV80BPi;^3wM;K0%mk?vgB`CNvZp@MVM+1Q^obLt9IPfkney7Iun4cdX z3*=BY)zNqN`+D)f*axP_?_YIpc;P|o8`Qk)cz~xX_&gGaDQbW0`*lZO1E2c?ijkcB zQe-ptiBV2tHur=f^%O5<%+q5Lx4*=MOTX9I-f}Q6UZVUVoM)-#C#XAO>U;n zaw;H;W){2si2bM#!A|~>U*`@@Rb(Se&g`!qLh9LUS7XQ5?0(xcN!#vB%t?MsNk@$3 z$IK+gN*pQEM84dIvM?RsMdL%6gVFOI1J+-HaW@x)nCT&Z%)57sm1R4nVP$r8PAu66 zl{w|2DIDX=3?KxIHNNV?YA5ebq1oRcV6(mf=1F~v^BFMmRzrJONV5}AMzNn4_tEo; zMlSHixxh|$E(jNnzmHAa=M3<@X3LYQepq80mZ$Fr%Hkhz)wI&*lWwN^dIo@FFmITb zC_}1ycR8P6EKITWD8UPC^lT`OmDmeNOXLD}CxHkGpd~!bwXA<(A{iT6^~jJM8+Q0h zl3(t{Uuf@JJqkx7R2}@KXrO$&PGXTtWgk65g19lO(d2g?0}M+(ZjJ$BU_vM##0m4` z9RmyxR!Dk;uw>)r7+_dvr(=K+-ME%vv9B}5UnD-JJ_C&R2t<6V0-0qj{Z)?g`3>y! z|E`i)B}>?xl~CgUuK!f36Y>Ln1BZ6tfb{nCYjd*jW>z)oFXmbrS|AX3dIEvKQxgaT zo|Zr$@RS4s!9b%U5C}XKf%rq67{&V7EC7I_!ic&X@JVkaj%6yAqV-D3m3QhURx_(? zUt@c3?Tn39Wj4H5OE)?9v%Z}B%Yh4e0m->p$0{<)DQs%`;*#Hfw(;PJjUQqaIa1Q@ zUBVmGDx-&7W2D`S@Il+oL5mQFN8v9rXrrKyHwyZQqo9vD3i_y{pocqzK%U1%PlY_u zXz`1l{i=bLT;23g3oIq4IceM4?U*fA?EB4nLc6|1Id_BC$PQ+r>F~-t9ksQ7C}<7% z-#cn6nt6`MNXYOMVh*Pwbj9;lD{IUFg2ET%7AzH#OUBpdxRZ{6<1Ri>gKIzKCe0l5 zBiTKhBw4x-#)fJB7>|uH>zdETtnA9hh0Uc z2Oi-;uBmRx`!E6ch@*nizz#P+vm@T!XP;sNfNLJD&TS?rCztMaSq8vNG`ow~^P~qO zF`JN@ThOnpsy*7cqqp0dHY>E1_?;@1Gzo)6HqtLfQXe*_y+f|;Fyz@d^hKKkFR!F7Fgxk8z!rRtZ%#`B zmk&;!Jy)f52Ni!dve!Y30!j6Nnsia(f4e`*lc5mLdyWL#K-gV<# zu&etkr< z+q8eeYQFm05wH=i5D9F=KIm>|{*dZ%MBMhQxW5y}I7(uJ+h=4ro%;%XSKvOVHFXokw^MiwsPQ=crjr-M!2#1}=_iD|fjpGbuJ@Ghm9 z`TtK6Xq{r8Cg>4`>mkkQli+}{33|y@Z4Vq;n_tnBmzzpw6co9SffAk;v@~$Qo!eRR z^(JWQyP6=B%4{?)Gtq`NT|m&Q`;#2%o=F!mHQq|mEM=JqF7f|A7wk$Oh3S#;uFy?# z2F2t`ngwop_4^Esx7!=6eL7>;oD}y59{by$^xO0*>ReQ70BvN4?l1tBp3Ao$sHH?m z*Xkq#J1O;Ef9ZT}8<0X&n719OiMN^Ntx=~ax(GDV^6;z(%`lVWmx}P5TRy1?2Q69z zy>Y)U;Wp)zm|Ulta@c>Fw`Zt>JAO*CGWPWy`eOX?cq-$=sEFNzy|m@siKL^2V%%@C zqN2cwI;B&+?x}1L;@X_JIh2VV^V=elVsH^B%*QEIBZ|~;DpG*+u^Ejy@;CP#ZMTm_ z88ls=GKgfJ9m2U;BMTY=;GFW}PinS0DfO2XGx4oMwaM#5>5u@{k>xPjtnZwW4} zd|#wZ{@nexp9Qy(8yvFfpQds1 z^~%yy8@=*)C+L(GV`y9N$Dmh!E9Ts$;?ey^hQ4xMD(`C?nThV%7T;lU)@#CN@z0L7 z#($=@{6kql~!i{eQ&w zD0tQxT~y4+X&xS`U;d}`%g6T6FaJ~e<;evjjDFcD*Q}+tm{PF`(E;s^o`PBWicd@9qKRBuB{o zm=HqBL)6Pw@;JfqFuLVBl@PICN{>gs>@VG^fku;?Y)7ZlsRsVWJ0jyE@NNul1L0%x zEXa7~`h|Ynr9ghiF|u(?_7U(|iR*|`&aWA!Yo$wN=8oMv2NHmNCT;0!MEZyOqt4B> zWo&n1DGpp9jkpa{#YXGrO-JB{c9LSyCZb?`mfy$`TM~$N-he0@vz)C2WL)g;fgnQ@ zTEQ3?#G_d;`-Ht6EDAvu(1Cr!?AAtZ37c(D>PoW-;*1OR4m&0q*dN~9Ch9&eHQ;!< zk;4fRnSbQ6+iLQ3ibrZ+g!?#jivO7XCR@myNb$b0+=E(uG_#%hjLVfvgRRsRd=Xy; zF~@A_N%>JIAg|6O{LwI3_9KQ#u@XlMB;B_v|6-}@xrun_6@L>Uo=$7(boT>a8CtvQ-<68GKu@pKv`Cq9Ef5NxEx^M~Y=a9o00$UeV;Xv#P z(GyAxCnmR1gb5wt`yGZScmit_Ve)iww;DKGuCWh>03DizM2ZKPVgz|gp z;GW1_$-`a)rc|;6eMs={JVbXuhZzMkDY1wM2^I>uc$rY6n+-3uBvLRzatR~2ME%w- z_1gv*%sOTEz0LXRx51wJZI=ugD$(1ZgG-Q0{qygz>eRtK;t9mbS*yFPs@5xMg>vh5 z_LOJx5d}jV6vtGMyomjSr{BQSUqd8yJ)F@c(hEZ8BSw>%`Zwe9)f4778XZTB`zNZ_ z$5LY&+gK2oN74nXN9Nz`%lv;yHoQE$Tacz8@_$|7NpDKxe~*WFhY0;Et;G2N(a5<= z2}tN)M>CDkf3L4uF=~vvOyf6EFN5^u$R`gk_ZQsFsrCm57}@`w7k82UXN+W$`)I9^ zTe(NSyW7~gcG(s8*N%&GowAFi{oM$QG1Y2i-}Os~H;KlhU`8g4nAaBx6UtYrb{H9f zFd<(aOvn=lcUL9U8dbtBT5dqRgMd^Cbv%tKA%$kRn<~L;-Ot>sE>+SK8wk+qx7@S0hB80{y zy+xE3zi$z&9?+q7>J>i7aSyWi#n|o}y+S^evO}%#wuDO{L!s0PXO}sBeQo&{X%!Nc z68iPfD(u{XI6YO`UW!y&g7AE670VAx&&W8tbg_5gEW1)R;Q} zb#e znANx!&_0jp#Pkl^`|59s!ED5ehwr{f{ZU~pl2chuyj4pp9==p7_5O@j{PWF{xqI$C zs%v9aEa93{gU?S*b93bE-~A<=d6_eyz;7BuCU&BWa{T8~j^DGpZ>MrRd)E7X$$@%Y z>pfyqgjG_GpSeTPoyzemS>{a7xDhEQkZ8~nYnIjIgV+GkEGuzB5U!}BRi50uvu)=i z_*El~=E>duA>iSLD(N=GKbAQ`mhJz{M&=R$&X~wNF$rwXn8@sC-QB){QO`;T5zLzP zC&TM=^Vt&O(hr)15_z9xSMV-1)7Wwu1?us>$e;yp!(6IzR&Do?4}!8gAW< zywP2+WEiKe`F*_-a79WzGg7=p6KQ^J-CUYobA2bs&P@f~m{TauWi>gBNc|Lm3UZm6 zI#dzv$ab*bsGV?Jgh6pRg#L}W?u*2k)nNrmm(gtc*BCf zMV*N=BmVI!l%XH8J@Dc3G%Y|5GF{^WWI;xBGUyjQ)dt=rBT$thYgKi@1aGoW_EdRh z{s6Ml)YZu2?l*#0>-=4y%DR#zWHz3sry=NX+AcZyBZlvm6>m{`p^=XG5Rip}4}k*! zuLlIato~~=b7-f3_xbL2NJ3G-S`{mp068kc;Xw-xG@Z51Z&^Zgx(Uv&-kYXVAb}pA z*ppBX%jzK1KYcMnJv+&@fT~kWR-zB3nZjfk`9PQQ#9(A}Q%e~yqvGp`nd`??cEntx z7_L~X&8qGv(L}9VY4SW_=%#xfFDPWR`{5wAHt621r5+&}BB7KgY1o3INnP*I0Nt+< zLZj&0Qh8;h`%ATCZ%%JBzMd{Fs7%k3k_c@w*z-D;L+Paqv!@pRuF=ly^QIk}L8*oB z?xKT>*@fwe1}VyG(-$(az0YzE^Vzf>pRJV)r3>%=t8N;x1L={{X>>_{PU(kO$IoXv zceRfH<%eIiv;nt_b$kt(4r3i3N-rV-d(!*RWn?B9AnY>1d?*zON_U!mchk+(Kg(bs zsY#z<{Aq1W-%m*%NIqe=0wwAO$qSjP<@T_G^lt?Vuv#N9S?a=q3``Fwg{^Ka?cml; z!GO0)^Y(%UlDDbmt;T$qcC?C@80~%=!3%c z^Aj)fP7uc5$KkXSG#8jiD#QJ8@i%)}iG5V(EH?MlVkplGhX_vT1#LS=KODwgZ%FSu zq~J8hxcoXhd)k;&v#jKkIf|Q5>7X@fs2PX^VmZ0uwV{Bu^ie`uPV>D@B+jyzL$TGN z=6JmyV%;!4K%3)tb)@OCTm9)Q=JNNjxf|8}JrqO+R4*F> zjZB-9E2B(j&B>L&$;d9guCm*)l@eN?>9RVRJf7w`j!Y+`80LC zjuUUdapGmm=}mXXiDPk`cv%C{99qmcPP_`oiF0tAco~ipzsK3ceb!Gr$BC~+?B?+} z6JocT9T~bFg`D=RRzk7{99{2WM9POab@z=oDn>7?Kz`(9BI!f;$hiy z#_$ML-(b%vAuuq0fcheYj4Bb0+f`Ts_*J zGnK$`_MB-vzGBar&f|D{&I}$W*mGv`7-G+<=J8b&7AHpRbLZM~@Qb*`_lw9mg~m7W zi`beu@80Dmwlgr8e08kZiF%i?r6%>UD+Z?~W!n{bsYyY*B9xlc+pZXpn$*j#$Vp8K z*cCxr=G*z+{KcvRPTr17NKR}46MqTw$u@pe)2Bh14SxrT*-MUy!^}0Vv)M<=@4B^Q z6QDJOY9WGrXYmX^MoR;o1MH2YITH$t$4&Rn>sUz*1lHHNz9EXW^hQdJ#*OE5xZhJK z1EqJfndPEc9$jJFIi(AI4DWd!D$uXfzpt@u*ycXEQ)&l9_tui1P@t7C?Ao~Lu$A1k z(Hxjcbd9wyXmz)Xr@R((2Dv67dJ zL0KO0?*8>!N{v0nQKqN23hi z-P4~o`wQdb-MgPbo83DhemIdsq^@0Y_7Yw_9gBZ61BY_vik)OtN5dg=(Waqz@Jt~`9 z9WPWH-hQz!I-vdH4E6y~&SSB1ES32iy%%P)Rv7D*+`qiq7f?v0D7iH|nZ?B)%`3;7 zvz*zOt&9A;R0i=jdvW#$WTqF5vxb#dy(DepI6LoNZVxZpksq!VY+26<{o#R^X3Vlq6rVdTh&#|j3x_pTMcM`*PXhb-J@9@hDdTIOy6 zDi{a6V%((-I{OV^&V7hgqn65Ax%cBzKv=7e_53<7ITmKJL4ZohPhY5)8b88oeABG6 zfk76DvYj9?xQ8yevri&c^+6$USx#(Mf6W|KH~yLt>NW<7TNW(#ymBWs?{Hwvycyuu zp%#Rs3zoPAh8EF!4NU`&&KcV=UDNG` zFqLHdLBQ`}@oKg|=^H>1CUb%>)s}YCmbZ5vFl|X+Nh)yi+>&#=hAUo0r9s8D_W$5`hzA|`n!Cl{(1B+-G;%EM?dYRu)RBd zrtvxv(KrNCRN0|6>o~0)E#7QSXutK8!BTE66n2Wui82S%1-?D6vr^8~q+EYS(Nj&Y zC|6|UtKt=z%?t_rGAs>8j%E&np{rtC?}780G7DQPL!y?v&TX z=o-fQH;5dR=^BVoC;jz2pvK?F0M|-LcpGu9oX!CZTo|JHkpWIDHRy6(ydxRU=?9+g z%Wx7JwDKiQGX;kfA`OFkD*U^C*6ZhOaPAWYaLinIK!N9dy}W!`wBXC4x4D-W-{i2R zO=fy!b3Y-FVur~DSuC)n{Y}Q1iH=3tOyHM%7=Up?q=80`gfwtQm4i&o3k==4t}^>u zBgI+I?W0ULRk}C60IkK_UWVIsn>b5EYsXeulMnw={b2>bIGJG|tJ* zt|GaSJBN4w`w1O_?L7`DR*19Cg^dEmZf+}> zEFai~obK}dt@oqa98ZxglLwS%a*}cDv+PkhnX7}jE)&WhjmN(cmY1!TGdd76P}p7W_8R*fOi+4 zQBOPz+QM_dS;R@9X;yKvZsOggC9>pgPTf8|AlwNF#_xhV@c%~%A!}VGju`czkb*8Zbn&(1~=Z6 zQ@qo<^;$~d{GsILMYucs96ISAQFC{(@O2t(+`!tBt}^5px&a9^a=I?#f-QGk5;_lj zcME?sF7Y?auz3EZ7tbX+yrjS1Y;dh}R7#*p^@l6hEATfI-BH6O&E1PV<#5G%qmibA zo%E-3JiNAM#v{Z~_~W7F&2+9y6%55Z>OZ9A-bl#&ID=0eAIR=2~}WF=3=I{+9Iu`d2d*>+irW-~~XLATTv zFwY-Ct@v5#d7y{K7k89@mMPy_bU7b()?v{63oH3HdFf1V<$vZdJ^H#?H0u};^#3ir z(|yVB!@q}mFbH0xYRxEM9-Yx^1~7lj+|SXhQZR%nG3y?jRte!&KW?l4-0nYJ|Ec|@ zzS(P@#d~X3N2@l7OY`g^S~Dus0Kn`!bT`-bS&JW*kBrplKXVlj=ZTg^1JAa3;)C^%J{XC2#JLU-@=<5;a?%W&lN)hL^4P;!$&(;S@p-HJ zTTAl^A)A`Fx=MnRUpLVI_`xi@bh)+kZj5iBXdX}5OGF-#@Nx#jDP1j71CDbxw+#Xh ztyOS@O#wg0d~%3C++DN7p10a(5gUp0IXffQsu&SHd(h`Ywfdf5s<{N)j2qC%JUX2o z;4i#vn-jrN$E0Hj_o%oY(o0A$I8Et)>`X5rT}PMUg$h~SXPEMJ-J0ZPL?T{F zR*)Xyz7t~@k^(d_=ki(>$t_$ z1#cbaT%5|{F81P$<* z3;PzbmKJYX@GCJ}2Ud#_kTcrQZS`ioJaydkkE{#v958&Nb<1yo7lnv04%)xTY(+L( zi|YY!WmD%Rr`#0?^clEeq`DTqm_dAx^>b?0Ig3uQj zZxEtw1?G4&-DPhdXitxXVj+_rChp4K)*M%08nARPgz@pu7j47J-QA4v+LJ?PMn6@) z&UZ*aiysT}5fWQF{x9&*aQfPyuIN>LgtvLlufCSvczS?4o<|&LZ}6`Wdmh1 zQ01$+lqq`_m+WvCjJ$-zmBTIf)RN_^X&jN}v-Bj@TDtnN6O(NhX3WyITN>85+s|&^ z^Paueoc+%p+H`HxG;L*v;(X*(ju3X-?Pjl;NgDY11GL_A6v=pgB>%b z`80ImYAN_H3#UrN;?9KMy^9{P>sv2^GqRy=D8R2LNZw#yu&8mij%R4=6fWg8^`ZSquVRGXKQ?WZ|+E$pes?WWhXN-GIUs@yr`d=*-L=a zi3IU@`);0~b%6IJ=Dm0Ggd9+Y_aB@0VDp3l3x&$B<1~7 z-kT>3hUd?EOjYQXmS6J3p}|D`T5Z1#t(bp`XS!lE0P)@347M8^X-YN zqmJnfg5sLhh&XdUq@jq3H{gVBOubxyAIyH*L|xYkF|~#Q+~!a*7vCJ*d}ALzXli?# zyOv6e8>_$JcQ#tpgvnuQtjrBD7~N$D|C$=xiQC%9XnztglTD|fd(KK6&T0xgsYSaNm zWsbsCs0{l6*Q{*ZDx;jX=J*K(2KxSu>k zVa}ua%rE}i9mPlOl;Wwvc~rANJI#US=>8h@!`{_g`jDClI${;m%zC+I1o2UO-d(gr zT&VVe1|xfyK2(e|o_Q;*^8q9CBT2EV@oEJ+IrAPWp10asDtS!AnfOrD8CNUHZ~tgX z)Sgnu3Lw%Sb$&ISM|suDoJy%bKQ(GAIG{zMtnsa0vB1_??_X8wO;@Q(FV5V0dxD)e zz^oVNGm-x8uNT%hC$GP^T%4ojA{C66rRJ_@ifXOs;Ahy&)@cqliyQIR3uf~_JJ$gyN=jXRzH=+JaRwXB)L^7 zcK4+Z=@<|fTv5L!bGiM-HCfjLp!51c!@9veLTW^(^e#5Q`7wKhp+9Gvaf{lecX`Lo z!7`1%7N3XGx;UIM#E%SSukBV@Gd8c#^QAe=<5UGnt8r0|&R2{G;=n$*5$J%Ye;LC6 z8GqO${;*LT4fx%`CGN8KHSRmHF+C)eXUWobQ+$8l*%Qzk{*kLDkR#rS`FQ)A|3enh z$IfL}!I7s=1^`+n{87+pPhA?5wNBIiA}q?yMDhoa>yS+9o9y?baea?v83~>Hrg^rz zFY^S4HD$nYO_!)sG;#|gV-|1sR0OTuF0NtWN}HND4Hq~6It(DpboUTJ9FiGd@My@2 zzZ-lSRP-EAFlRuEkv0Um_zQXOo!Y@Z4TZxBpHQnpX8&M?vqr1U1x|2JBvsHiQe4HY6_vFS>-?%2;o^1H z(i#?nSXJwuR#Z#*P-c0BVxEc7s@HKtwK2H%T#Wpqy;q9G70#bk=G1%a?tos_s$<~$ zk)$56X~{7ox0tK^nl$hMmH=cec)zb%#o~6JGinbr?p$Z$>N01wz8;BA;va2Cb?#U7 z71aFXuv0N3(8P%VZjMGq+qZ6ipysV`Jd(`vol-487dB-zCnC5w8+oo>^N^cmMA|hE z@$TkrkY&sUOj-<0l&W>vzcepOSI3+mtbqMsK@q6j{bIXxW#atPMsAGQdyE8)u6GF0 ztW_ajNE{+x@v{qF3)=@FvPoTwfuIHU7;)b1z%0VHA_l-9i_kT=^j`QlsYGz6}GF-VFlD@va5SGfW1IH)qsy8g)9$L(EQ>rK*!b+R__bYz!XKoqD6e)!vjJ-%ODVfteVHrtto7unAA zr;!XK->~=Z9R*VC;QAQr12(`07*ZqkQnXsI)%i7ryo;D%ys%9g$#gyOGtZ_ zhukZkFf#Os57GIS^jO(ENx87cE%k-vxg5%IUCAjMn40N%bW+-sF7&fghQYZ)>WMf} zkr*na*rzb@_n%?;s zpOAzH^R@LJKgfL?T*mQ!$ZMbmP^V7C(yINqgZsCuufCccq2~>**U+X^@Mrc%frgSGD%V1#_uDhplIJkwJNG193HWC(}p+K_2&VXm=+3-2G5U z=cxwDG8P3_3?d-YC+TN?cB~{k5fdc|4h|fmaF3V6)?~iX)mozK8P6PLRhM*}1KVzC zng6wv4*q^7hN<=ns**>!<*E{ZjL@gvY}6$yx>cR8uFO|jQD#3*KXqi5UATLWT3odN zr;`|_l{tUa#Fpk<9+H^&Rzic2y1=lh&vApR7N7)qBB?N_|51$d{4fM%jobThqXF26 z@a%ux*H)~!K|ZA##d>7UdG)5bhhtaqkd!;*B*U)$G#c34{swItKY|XI@Dmzes1QG) z@%akz6B<8QA$~&RLkjT|8lR&OKOy7?13UM7U5+rm*hQA%?)i{GvUFfeG06{U7 zfnwi7p?DvsR{w88v8*Q)bvOhtM#J{rFpF`x(H(*dfW9z_k)e`e%$^uaW$!+b>;CXI zRTgLoce->lz%(x13^0vLHv>#_4$A=3xO6kXG%no?FeM;ll7&tvV2K#=SPAptmcN3} zs5bc}A^VI*z3yrzudFHZ`iqnCCgfR2T&__?%WQ5$v@;z?EGMaoeO4` zJB#ayEO(ZPtB2sdRi2cJFne6KOxz0F&_7d-YS)dAp*)tULbN55|H0ej0SξDsSX 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